From 9586fa99aae0cbe5cd8d543f6e7b694cbdaa29ca 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205225 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/MicrosoftMangle.cpp | 54 ++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 7095d2e197..0fc7d5c8ec 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/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.40.0