Dwarf: [PR11022] Fix emitting DW_AT_const_value(>i64), to be host-endian-neutral.

Don't assume APInt::getRawData() would hold target-aware endianness nor host-compliant endianness. rawdata[0] holds most lower i64, even on big endian host.

FIXME: Add a testcase for big endian target.

FIXME: Ditto on CompileUnit::addConstantFPValue() ?

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143194 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
NAKAMURA Takumi 2011-10-28 14:12:22 +00:00
parent 9df3b916cd
commit c3e48c38bf
2 changed files with 10 additions and 8 deletions

View File

@ -534,18 +534,20 @@ bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
// Get the raw data form of the large APInt.
const APInt Val = CI->getValue();
const char *Ptr = (const char*)Val.getRawData();
const uint64_t *Ptr64 = Val.getRawData();
int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
bool LittleEndian = Asm->getTargetData().isLittleEndian();
int Incr = (LittleEndian ? 1 : -1);
int Start = (LittleEndian ? 0 : NumBytes - 1);
int Stop = (LittleEndian ? NumBytes : -1);
// Output the constant to DWARF one byte at a time.
for (; Start != Stop; Start += Incr)
addUInt(Block, 0, dwarf::DW_FORM_data1,
(unsigned char)0xFF & Ptr[Start]);
for (int i = 0; i < NumBytes; i++) {
uint8_t c;
if (LittleEndian)
c = Ptr64[i / 8] >> (8 * (i & 7));
else
c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
addUInt(Block, 0, dwarf::DW_FORM_data1, c);
}
addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
return true;

View File

@ -1,4 +1,4 @@
; RUN: llc < %s | FileCheck %s
; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s
; CHECK: DW_AT_const_value
; CHECK-NEXT: 42