From 4b293ebbaa96e75ea5f819e82be284d59ce436ad Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Mon, 31 Mar 2014 17:18:53 +0000 Subject: [PATCH] MS ABI: mangleStringLiteral shouldn't rely on the host's endianness No test case is needed, the one in-tree is sufficient. The build-bot never emailed me because something else had upset it. llvm-svn: 205225 --- clang/lib/AST/MicrosoftMangle.cpp | 54 ++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 7095d2e19780..0fc7d5c8ecc6 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -2385,9 +2385,39 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL, } }; + auto GetLittleEndianByte = [&Mangler, &SL](unsigned Index) { + unsigned CharByteWidth = SL->getCharByteWidth(); + uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth); + if (CharByteWidth == 1) { + return static_cast(CodeUnit); + } else if (CharByteWidth == 2) { + if (Index % 2) + return static_cast((CodeUnit >> 8) & 0xff); + else + return static_cast(CodeUnit & 0xff); + } else { + llvm_unreachable("unsupported CharByteWidth"); + } + }; + + auto GetBigEndianByte = [&Mangler, &SL](unsigned Index) { + unsigned CharByteWidth = SL->getCharByteWidth(); + uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth); + if (CharByteWidth == 1) { + return static_cast(CodeUnit); + } else if (CharByteWidth == 2) { + if (Index % 2) + return static_cast(CodeUnit & 0xff); + else + return static_cast((CodeUnit >> 8) & 0xff); + } else { + llvm_unreachable("unsupported CharByteWidth"); + } + }; + // CRC all the bytes of the StringLiteral. - for (char Byte : SL->getBytes()) - UpdateCRC(Byte); + for (unsigned I = 0, E = SL->getByteLength(); I != E; ++I) + UpdateCRC(GetLittleEndianByte(I)); // The NUL terminator byte(s) were not present earlier, // we need to manually process those bytes into the CRC. @@ -2462,25 +2492,17 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL, } }; - auto MangleChar = [&Mangler, &MangleByte, &SL](uint32_t CodeUnit) { - if (SL->getCharByteWidth() == 1) { - MangleByte(static_cast(CodeUnit)); - } else if (SL->getCharByteWidth() == 2) { - MangleByte(static_cast((CodeUnit >> 16) & 0xff)); - MangleByte(static_cast(CodeUnit & 0xff)); - } else { - llvm_unreachable("unsupported CharByteWidth"); - } - }; - // Enforce our 32 character max. unsigned NumCharsToMangle = std::min(32U, SL->getLength()); - for (unsigned i = 0; i < NumCharsToMangle; ++i) - MangleChar(SL->getCodeUnit(i)); + for (unsigned I = 0, E = NumCharsToMangle * SL->getCharByteWidth(); I != E; + ++I) + MangleByte(GetBigEndianByte(I)); // Encode the NUL terminator if there is room. if (NumCharsToMangle < 32) - MangleChar(0); + for (unsigned NullTerminator = 0; NullTerminator < SL->getCharByteWidth(); + ++NullTerminator) + MangleByte(0); Mangler.getStream() << '@'; } -- 2.34.1