Index: ubsan.c =================================================================== RCS file: /cvsroot/src/common/lib/libc/misc/ubsan.c,v retrieving revision 1.5 diff -u -r1.5 ubsan.c --- ubsan.c 13 Feb 2019 17:17:02 -0000 1.5 +++ ubsan.c 13 Apr 2019 14:52:17 -0000 @@ -232,6 +232,13 @@ struct CTypeDescriptor *mToType; }; +struct CImplicitConversionData { + struct CSourceLocation mLocation; + struct CTypeDescriptor *mFromType; + struct CTypeDescriptor *mToType; + uint8_t mKind; +}; + /* Local utility functions */ static void Report(bool isFatal, const char *pFormat, ...) __printflike(2, 3); static bool isAlreadyReported(struct CSourceLocation *pLocation); @@ -255,6 +262,7 @@ static const char *DeserializeTypeCheckKind(uint8_t hhuTypeCheckKind); static const char *DeserializeBuiltinCheckKind(uint8_t hhuBuiltinCheckKind); static const char *DeserializeCFICheckKind(uint8_t hhuCFICheckKind); +static const char *DeserializeImplicitConversionCheckKind(uint8_t hhuImplicitConversionCheckKind); static bool isNegativeNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber); static bool isShiftExponentTooLarge(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber, size_t zWidth); @@ -307,6 +315,8 @@ void __ubsan_handle_type_mismatch_v1_abort(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer); void __ubsan_handle_vla_bound_not_positive(struct CVLABoundData *pData, unsigned long ulBound); void __ubsan_handle_vla_bound_not_positive_abort(struct CVLABoundData *pData, unsigned long ulBound); +void __ubsan_handle_implicit_conversion(struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo); +void __ubsan_handle_implicit_conversion_abort(struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo); void __ubsan_get_current_report_data(const char **ppOutIssueKind, const char **ppOutMessage, const char **ppOutFilename, uint32_t *pOutLine, uint32_t *pOutCol, char **ppOutMemoryAddr); static void HandleOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS, const char *szOperation); @@ -678,6 +688,26 @@ szLocation, ulBase, ulResult); } +static void +HandleImplicitConversion(bool isFatal, struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo) +{ + char szLocation[LOCATION_MAXLEN]; + char szFrom[NUMBER_MAXLEN]; + char szTo[NUMBER_MAXLEN]; + + ASSERT(pData); + + if (isAlreadyReported(&pData->mLocation)) + return; + + DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); + DeserializeNumber(szLocation, szFrom, NUMBER_MAXLEN, pData->mFromType, ulFrom); + DeserializeNumber(szLocation, szTo, NUMBER_MAXLEN, pData->mToType, ulTo); + + Report(isFatal, "UBSan: Undefined Behavior in %s, %s from %s %zu-bit %s (%s) to %s changed the value to %s %zu-bit %s\n", + szLocation, DeserializeImplicitConversionCheckKind(pData->mKind), szFrom, zDeserializeTypeWidth(pData->mFromType), ISSET(pData->mFromType->mTypeInfo, NUMBER_SIGNED_BIT) ? "signed" : "unsigned", pData->mFromType->mTypeName, pData->mToType->mTypeName, szTo, zDeserializeTypeWidth(pData->mToType), ISSET(pData->mToType->mTypeInfo, NUMBER_SIGNED_BIT) ? "signed" : "unsigned"); +} + /* Definions of public symbols emitted by the instrumentation code */ void __ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS) @@ -1089,6 +1119,23 @@ } void +__ubsan_handle_implicit_conversion(struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo) +{ + + ASSERT(pData); + + HandleImplicitConversion(false, pData, ulFrom, ulTo); +} + +void +__ubsan_handle_implicit_conversion_abort(struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo) +{ + ASSERT(pData); + + HandleImplicitConversion(true, pData, ulFrom, ulTo); +} + +void __ubsan_get_current_report_data(const char **ppOutIssueKind, const char **ppOutMessage, const char **ppOutFilename, uint32_t *pOutLine, uint32_t *pOutCol, char **ppOutMemoryAddr) { /* @@ -1634,6 +1681,22 @@ return rgczCFICheckKinds[hhuCFICheckKind]; } +static const char * +DeserializeImplicitConversionCheckKind(uint8_t hhuImplicitConversionCheckKind) +{ + const char *rgczImplicitConversionCheckKind[] = { + "integer truncation", /* Not used since 2018 October 11th */ + "unsigned integer truncation", + "signed integer truncation", + "integer sign change", + "signed integer trunctation or sign change", + }; + + ASSERT(__arraycount(rgczImplicitConversionCheckKind) > hhuImplicitConversionCheckKind); + + return rgczImplicitConversionCheckKind[hhuImplicitConversionCheckKind]; +} + static bool isNegativeNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber) {