[llvm-dwp] Fix endianness issues (#203424)
llvm-dwp fails on SystemZ, which is big-endian, as follows:
$ cat min.c
int main() {}
$ clang -g -O0 -gsplit-dwarf min.c -o min
$ llvm-dwp -e min -o min.dwp
error: compile unit exceeds .debug_info section range: 905969668 >= 58
This is because it hardcodes IsLittleEndian=true in multiple places. Fix
by forwarding endianness of the current object file.
Add a SystemZ-specific test.
Add proper big-endian support to X86/compress.test and add an
explanation regarding what the hardcoded blobs are and how they are
generated.
This commit is contained in:
parent
b74a97cae9
commit
5b46dcf593
4 changed files with 329 additions and 36 deletions
|
|
@ -102,6 +102,7 @@ class LLVM_ABI DWPWriter {
|
|||
uint16_t ELFMachine = 0;
|
||||
uint8_t ELFOSABI = 0;
|
||||
bool IsWASM = false;
|
||||
bool IsLittleEndian = true;
|
||||
|
||||
public:
|
||||
DWPWriter() = default;
|
||||
|
|
@ -109,6 +110,7 @@ public:
|
|||
void setMachine(uint16_t Machine) { ELFMachine = Machine; }
|
||||
void setOSABI(uint8_t OSABI) { ELFOSABI = OSABI; }
|
||||
void setIsWASM(bool V) { IsWASM = V; }
|
||||
void setIsLittleEndian(bool V) { IsLittleEndian = V; }
|
||||
|
||||
SmallVectorImpl<char> &getSectionBuffer(DWPSectionId Id) {
|
||||
return Sections[Id].Buffer;
|
||||
|
|
@ -128,9 +130,16 @@ public:
|
|||
|
||||
void emitIntValue(uint64_t Value, unsigned Size) {
|
||||
auto &Buf = Sections[CurrentSection].Buffer;
|
||||
for (unsigned I = 0; I < Size; ++I) {
|
||||
Buf.push_back(static_cast<char>(Value & 0xff));
|
||||
Value >>= 8;
|
||||
if (IsLittleEndian) {
|
||||
for (unsigned I = 0; I < Size; ++I) {
|
||||
Buf.push_back(static_cast<char>(Value & 0xff));
|
||||
Value >>= 8;
|
||||
}
|
||||
} else {
|
||||
for (unsigned I = 0; I < Size; ++I) {
|
||||
Buf.push_back(
|
||||
static_cast<char>((Value >> (8 * (Size - 1 - I))) & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +225,7 @@ LLVM_ABI Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
typedef std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLengths;
|
||||
|
||||
LLVM_ABI Expected<InfoSectionUnitHeader>
|
||||
parseInfoSectionUnitHeader(StringRef Info);
|
||||
parseInfoSectionUnitHeader(StringRef Info, bool IsLittleEndian);
|
||||
|
||||
} // namespace llvm
|
||||
#endif // LLVM_DWP_DWP_H
|
||||
|
|
|
|||
|
|
@ -41,9 +41,10 @@ static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData,
|
|||
return 8; // unit length: 4 bytes, version: 2 bytes, padding: 2 bytes.
|
||||
}
|
||||
|
||||
static Expected<uint64_t> getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
|
||||
static Expected<uint64_t> getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode,
|
||||
bool IsLittleEndian) {
|
||||
uint64_t Offset = 0;
|
||||
DataExtractor AbbrevData(Abbrev, true);
|
||||
DataExtractor AbbrevData(Abbrev, IsLittleEndian);
|
||||
while (AbbrevData.isValidOffset(Offset)) {
|
||||
uint64_t Code = AbbrevData.getULEB128(&Offset);
|
||||
if (Code == AbbrCode)
|
||||
|
|
@ -95,19 +96,20 @@ getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset,
|
|||
"DW_FORM_string, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, "
|
||||
"DW_FORM_strx3, DW_FORM_strx4, or DW_FORM_GNU_str_index.");
|
||||
}
|
||||
DataExtractor StrOffsetsData(StrOffsets, true);
|
||||
DataExtractor StrOffsetsData(StrOffsets, InfoData.isLittleEndian());
|
||||
uint64_t StrOffsetsOffset = 4 * StrIndex;
|
||||
StrOffsetsOffset += debugStrOffsetsHeaderSize(StrOffsetsData, Version);
|
||||
|
||||
uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
|
||||
DataExtractor StrData(Str, true);
|
||||
DataExtractor StrData(Str, InfoData.isLittleEndian());
|
||||
return StrData.getCStr(&StrOffset);
|
||||
}
|
||||
|
||||
static Expected<CompileUnitIdentifiers>
|
||||
getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev,
|
||||
StringRef Info, StringRef StrOffsets, StringRef Str) {
|
||||
DataExtractor InfoData(Info, true);
|
||||
StringRef Info, StringRef StrOffsets, StringRef Str,
|
||||
bool IsLittleEndian) {
|
||||
DataExtractor InfoData(Info, IsLittleEndian);
|
||||
uint64_t Offset = Header.HeaderSize;
|
||||
if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
|
||||
return make_error<DWPError>(
|
||||
|
|
@ -118,8 +120,9 @@ getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev,
|
|||
CompileUnitIdentifiers ID;
|
||||
|
||||
uint32_t AbbrCode = InfoData.getULEB128(&Offset);
|
||||
DataExtractor AbbrevData(Abbrev, true);
|
||||
Expected<uint64_t> AbbrevOffsetOrErr = getCUAbbrev(Abbrev, AbbrCode);
|
||||
DataExtractor AbbrevData(Abbrev, IsLittleEndian);
|
||||
Expected<uint64_t> AbbrevOffsetOrErr =
|
||||
getCUAbbrev(Abbrev, AbbrCode, IsLittleEndian);
|
||||
if (!AbbrevOffsetOrErr)
|
||||
return AbbrevOffsetOrErr.takeError();
|
||||
uint64_t AbbrevOffset = *AbbrevOffsetOrErr;
|
||||
|
|
@ -269,11 +272,12 @@ static Error addAllTypesFromTypesSection(
|
|||
DWPWriter &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
|
||||
DWPSectionId OutputSection, const std::vector<StringRef> &TypesSections,
|
||||
const UnitIndexEntry &CUEntry, uint32_t &TypesOffset,
|
||||
OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow) {
|
||||
OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow,
|
||||
bool IsLittleEndian) {
|
||||
for (StringRef Types : TypesSections) {
|
||||
Out.switchSection(OutputSection);
|
||||
uint64_t Offset = 0;
|
||||
DataExtractor Data(Types, true);
|
||||
DataExtractor Data(Types, IsLittleEndian);
|
||||
while (Data.isValidOffset(Offset)) {
|
||||
UnitIndexEntry Entry = CUEntry;
|
||||
// Zero out the debug_info contribution
|
||||
|
|
@ -396,11 +400,12 @@ static void writeNewOffsetsTo(DWPWriter &Out, DataExtractor &Data,
|
|||
|
||||
namespace llvm {
|
||||
// Parse and return the header of an info section compile/type unit.
|
||||
Expected<InfoSectionUnitHeader> parseInfoSectionUnitHeader(StringRef Info) {
|
||||
Expected<InfoSectionUnitHeader>
|
||||
parseInfoSectionUnitHeader(StringRef Info, bool IsLittleEndian) {
|
||||
InfoSectionUnitHeader Header;
|
||||
Error Err = Error::success();
|
||||
uint64_t Offset = 0;
|
||||
DWARFDataExtractor InfoData(Info, true, 0);
|
||||
DWARFDataExtractor InfoData(Info, IsLittleEndian, 0);
|
||||
std::tie(Header.Length, Header.Format) =
|
||||
InfoData.getInitialLength(&Offset, &Err);
|
||||
if (Err)
|
||||
|
|
@ -460,7 +465,7 @@ writeStringsAndOffsets(DWPWriter &Out, DWPStringPool &Strings,
|
|||
StringRef CurStrSection, StringRef CurStrOffsetSection,
|
||||
uint16_t Version, SectionLengths &SectionLength,
|
||||
const Dwarf64StrOffsetsPromotion StrOffsetsOptValue,
|
||||
bool SingleInput) {
|
||||
bool SingleInput, bool IsLittleEndian) {
|
||||
// Could possibly produce an error or warning if one of these was non-null but
|
||||
// the other was null.
|
||||
if (CurStrSection.empty() || CurStrOffsetSection.empty())
|
||||
|
|
@ -480,7 +485,7 @@ writeStringsAndOffsets(DWPWriter &Out, DWPStringPool &Strings,
|
|||
// Pre-reserve based on estimated string count to avoid rehashing.
|
||||
OffsetRemapping.reserve(CurStrSection.size() / 20);
|
||||
|
||||
DataExtractor Data(CurStrSection, true);
|
||||
DataExtractor Data(CurStrSection, IsLittleEndian);
|
||||
uint64_t LocalOffset = 0;
|
||||
uint64_t PrevOffset = 0;
|
||||
|
||||
|
|
@ -503,7 +508,7 @@ writeStringsAndOffsets(DWPWriter &Out, DWPStringPool &Strings,
|
|||
PrevOffset = LocalOffset;
|
||||
}
|
||||
|
||||
Data = DataExtractor(CurStrOffsetSection, true);
|
||||
Data = DataExtractor(CurStrOffsetSection, IsLittleEndian);
|
||||
|
||||
Out.switchSection(DS_StrOffsets);
|
||||
|
||||
|
|
@ -614,7 +619,13 @@ static void writeIndex(DWPWriter &Out, DWPSectionId Section,
|
|||
}
|
||||
|
||||
Out.switchSection(Section);
|
||||
Out.emitIntValue(IndexVersion, 4); // Version
|
||||
// Header layout differs between v2 and v5; see DWARFUnitIndex::Header::parse.
|
||||
if (IndexVersion >= 5) {
|
||||
Out.emitIntValue(IndexVersion, 2); // Version
|
||||
Out.emitIntValue(0, 2); // Padding
|
||||
} else {
|
||||
Out.emitIntValue(IndexVersion, 4); // Version
|
||||
}
|
||||
Out.emitIntValue(Columns, 4); // Columns
|
||||
Out.emitIntValue(IndexEntries.size(), 4); // Num Units
|
||||
Out.emitIntValue(Buckets.size(), 4); // Num Buckets
|
||||
|
|
@ -777,6 +788,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
} else if (Obj.isWasm()) {
|
||||
Out.setIsWASM(true);
|
||||
}
|
||||
Out.setIsLittleEndian(Obj.isLittleEndian());
|
||||
MachineSet = true;
|
||||
}
|
||||
|
||||
|
|
@ -806,8 +818,8 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
if (CurInfoSection.empty())
|
||||
continue;
|
||||
|
||||
Expected<InfoSectionUnitHeader> HeaderOrErr =
|
||||
parseInfoSectionUnitHeader(CurInfoSection.front());
|
||||
Expected<InfoSectionUnitHeader> HeaderOrErr = parseInfoSectionUnitHeader(
|
||||
CurInfoSection.front(), Obj.isLittleEndian());
|
||||
if (!HeaderOrErr)
|
||||
return HeaderOrErr.takeError();
|
||||
InfoSectionUnitHeader &Header = *HeaderOrErr;
|
||||
|
|
@ -825,7 +837,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
|
||||
writeStringsAndOffsets(Out, Strings, CurStrSection, CurStrOffsetSection,
|
||||
Header.Version, SectionLength, StrOffsetsOptValue,
|
||||
Inputs.size() == 1);
|
||||
Inputs.size() == 1, Obj.isLittleEndian());
|
||||
|
||||
for (auto Pair : SectionLength) {
|
||||
auto Index = getContributionIndex(Pair.first, IndexVersion);
|
||||
|
|
@ -858,7 +870,8 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
uint64_t UnitOffset = 0;
|
||||
while (Info.size() > UnitOffset) {
|
||||
Expected<InfoSectionUnitHeader> HeaderOrError =
|
||||
parseInfoSectionUnitHeader(Info.substr(UnitOffset, Info.size()));
|
||||
parseInfoSectionUnitHeader(Info.substr(UnitOffset, Info.size()),
|
||||
Obj.isLittleEndian());
|
||||
if (!HeaderOrError)
|
||||
return HeaderOrError.takeError();
|
||||
InfoSectionUnitHeader &Header = *HeaderOrError;
|
||||
|
|
@ -887,7 +900,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
|
||||
Header, AbbrevSection,
|
||||
Info.substr(UnitOffset - C.getLength32(), C.getLength32()),
|
||||
CurStrOffsetSection, CurStrSection);
|
||||
CurStrOffsetSection, CurStrSection, Obj.isLittleEndian());
|
||||
|
||||
if (!EID)
|
||||
return createFileError(Input, EID.takeError());
|
||||
|
|
@ -921,7 +934,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
if (Error Err = addAllTypesFromTypesSection(
|
||||
Out, TypeIndexEntries, DS_Types, CurTypesSection, CurEntry,
|
||||
ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)],
|
||||
OverflowOptValue, AnySectionOverflow))
|
||||
OverflowOptValue, AnySectionOverflow, Obj.isLittleEndian()))
|
||||
return Err;
|
||||
}
|
||||
if (AnySectionOverflow)
|
||||
|
|
@ -952,7 +965,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
StringRef CUInfoSection =
|
||||
getSubsection(DwpSingleInfoSection, E, DW_SECT_INFO);
|
||||
Expected<InfoSectionUnitHeader> HeaderOrError =
|
||||
parseInfoSectionUnitHeader(CUInfoSection);
|
||||
parseInfoSectionUnitHeader(CUInfoSection, Obj.isLittleEndian());
|
||||
if (!HeaderOrError)
|
||||
return HeaderOrError.takeError();
|
||||
InfoSectionUnitHeader &Header = *HeaderOrError;
|
||||
|
|
@ -961,7 +974,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
Header, getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
|
||||
CUInfoSection,
|
||||
getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
|
||||
CurStrSection);
|
||||
CurStrSection, Obj.isLittleEndian());
|
||||
if (!EID)
|
||||
return createFileError(Input, EID.takeError());
|
||||
const auto &ID = *EID;
|
||||
|
|
@ -1060,7 +1073,8 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Error DWPWriter::writeELF(raw_pwrite_stream &OS) {
|
||||
support::endian::Writer Wr(OS, llvm::endianness::little);
|
||||
support::endian::Writer Wr(OS, IsLittleEndian ? llvm::endianness::little
|
||||
: llvm::endianness::big);
|
||||
|
||||
// Section metadata table.
|
||||
struct SectionMeta {
|
||||
|
|
|
|||
206
llvm/test/tools/llvm-dwp/SystemZ/big_endian_info_v5.s
Normal file
206
llvm/test/tools/llvm-dwp/SystemZ/big_endian_info_v5.s
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
# REQUIRES: systemz-registered-target
|
||||
|
||||
## This assembly was produced by:
|
||||
## echo 'int integer;' > int.c
|
||||
## clang -target s390x-ibm-linux -gdwarf-5 -gsplit-dwarf -O0 -S int.c -o -
|
||||
|
||||
# RUN: llvm-mc --triple=s390x-ibm-linux --filetype=obj --split-dwarf-file=%t.dwo -dwarf-version=5 %s -o %t.o
|
||||
# RUN: llvm-dwp %t.dwo -o %t.dwp
|
||||
# RUN: llvm-dwarfdump -v %t.dwp | FileCheck %s
|
||||
|
||||
# CHECK-DAG: .debug_info.dwo contents:
|
||||
# CHECK: 0x00000000: Compile Unit: length = 0x00000026, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = [[DWOID:.*]] (next unit at 0x0000002a)
|
||||
|
||||
# CHECK-DAG: .debug_cu_index contents:
|
||||
# CHECK: version = 5, units = 1, slots = 2
|
||||
# CHECK: Index Signature INFO ABBREV STR_OFFSETS
|
||||
# CHECK: 1 [[DWOID]] [0x0000000000000000, 0x000000000000002a) [0x00000000, 0x0000002a) [0x00000000, 0x0000001c)
|
||||
|
||||
.text
|
||||
.file "int.c"
|
||||
.file 0 "/tmp" "int.c" md5 0xdb9c8bb799b289960d8139be0d914773
|
||||
.type integer,@object # @integer
|
||||
.section .bss,"aw",@nobits
|
||||
.globl integer
|
||||
.p2align 2, 0x0
|
||||
integer:
|
||||
.long 0 # 0x0
|
||||
.size integer, 4
|
||||
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 74 # DW_TAG_skeleton_unit
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 16 # DW_AT_stmt_list
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 114 # DW_AT_str_offsets_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 27 # DW_AT_comp_dir
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.ascii "\264B" # DW_AT_GNU_pubnames
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 118 # DW_AT_dwo_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 4 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.quad -1173350285159172090
|
||||
.byte 1 # Abbrev [1] 0x14:0xf DW_TAG_skeleton_unit
|
||||
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||
.byte 0 # DW_AT_comp_dir
|
||||
# DW_AT_GNU_pubnames
|
||||
.byte 1 # DW_AT_dwo_name
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 12 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Lskel_string0:
|
||||
.asciz "/tmp" # string offset=0
|
||||
.Lskel_string1:
|
||||
.asciz "int.dwo" # string offset=5
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Lskel_string0
|
||||
.long .Lskel_string1
|
||||
.section .debug_str_offsets.dwo,"e",@progbits
|
||||
.long 24 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.section .debug_str.dwo,"eMS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "integer" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "int" # string offset=8
|
||||
.Linfo_string2:
|
||||
.asciz "Ubuntu clang version 19.1.1 (1ubuntu1~24.04.2)" # string offset=12
|
||||
.Linfo_string3:
|
||||
.asciz "int.c" # string offset=59
|
||||
.Linfo_string4:
|
||||
.asciz "int.dwo" # string offset=65
|
||||
.section .debug_str_offsets.dwo,"e",@progbits
|
||||
.long 0
|
||||
.long 8
|
||||
.long 12
|
||||
.long 59
|
||||
.long 65
|
||||
.section .debug_info.dwo,"e",@progbits
|
||||
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
|
||||
.Ldebug_info_dwo_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 5 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long 0 # Offset Into Abbrev. Section
|
||||
.quad -1173350285159172090
|
||||
.byte 1 # Abbrev [1] 0x14:0x16 DW_TAG_compile_unit
|
||||
.byte 2 # DW_AT_producer
|
||||
.short 29 # DW_AT_language
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 4 # DW_AT_dwo_name
|
||||
.byte 2 # Abbrev [2] 0x1a:0xb DW_TAG_variable
|
||||
.byte 0 # DW_AT_name
|
||||
.long 37 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 1 # DW_AT_decl_line
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 161
|
||||
.byte 0
|
||||
.byte 3 # Abbrev [3] 0x25:0x4 DW_TAG_base_type
|
||||
.byte 1 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_dwo_end0:
|
||||
.section .debug_abbrev.dwo,"e",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 118 # DW_AT_dwo_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad integer
|
||||
.Ldebug_addr_end0:
|
||||
.section .debug_gnu_pubnames,"",@progbits
|
||||
.long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
|
||||
.LpubNames_start0:
|
||||
.short 2 # DWARF Version
|
||||
.long .Lcu_begin0 # Offset of Compilation Unit Info
|
||||
.long 35 # Compilation Unit Length
|
||||
.long 26 # DIE offset
|
||||
.byte 32 # Attributes: VARIABLE, EXTERNAL
|
||||
.asciz "integer" # External Name
|
||||
.long 0 # End Mark
|
||||
.LpubNames_end0:
|
||||
.section .debug_gnu_pubtypes,"",@progbits
|
||||
.long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
|
||||
.LpubTypes_start0:
|
||||
.short 2 # DWARF Version
|
||||
.long .Lcu_begin0 # Offset of Compilation Unit Info
|
||||
.long 35 # Compilation Unit Length
|
||||
.long 37 # DIE offset
|
||||
.byte 144 # Attributes: TYPE, STATIC
|
||||
.asciz "int" # External Name
|
||||
.long 0 # End Mark
|
||||
.LpubTypes_end0:
|
||||
.ident "Ubuntu clang version 19.1.1 (1ubuntu1~24.04.2)"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
||||
|
|
@ -1,17 +1,81 @@
|
|||
# REQUIRES: zlib
|
||||
# RUN: yaml2obj -DCLASS=32 -DENDIAN=LSB -DINFO_CHDR=010000005600000001000000 %s -o %t.o
|
||||
|
||||
## INFO_DATA / STR_OFFSETS / LINE in the DEFINE lines below are reproduced by
|
||||
## this snippet.
|
||||
##
|
||||
## import struct, zlib
|
||||
## for end in ('<', '>'):
|
||||
## # .debug_info.dwo DIE stream. Each abbrev code selects an entry in
|
||||
## # .debug_abbrev.dwo below; that entry dictates which DW_AT_* values
|
||||
## # follow and in what order.
|
||||
## die = b'\x01' # .debug_abbrev code (DW_TAG_compile_unit)
|
||||
## die += b'\x00' # DW_AT_producer="clang version 3.9.0 ..."
|
||||
## die += struct.pack(end+'H', 4) # DW_AT_language=DW_LANG_C_plus_plus
|
||||
## die += b'\x01' # DW_AT_name="a.cpp"
|
||||
## die += struct.pack(end+'Q', 0x5d2ca3800efeebd9) # DW_AT_GNU_dwo_id
|
||||
## die += b'\x02' # .debug_abbrev code (DW_TAG_subprogram)
|
||||
## die += b'\x00' # DW_AT_low_pc (addr idx)
|
||||
## die += struct.pack(end+'I', 0x12) # DW_AT_high_pc
|
||||
## die += b'\x01\x56' # DW_AT_frame_base (exprloc: DW_OP_reg6)
|
||||
## die += b'\x02' # DW_AT_linkage_name="_Z1fiiii"
|
||||
## die += b'\x03' # DW_AT_name="f"
|
||||
## die += b'\x01' # DW_AT_decl_file
|
||||
## die += b'\x01' # DW_AT_decl_line
|
||||
## for name, off in [(4, 0x7c), (6, 0x78), (7, 0x74), (8, 0x70)]: # params a,b,c,d
|
||||
## die += b'\x03' # .debug_abbrev code (DW_TAG_formal_parameter)
|
||||
## die += b'\x02\x91' + bytes([off]) # DW_AT_location (exprloc: DW_OP_breg6, sleb)
|
||||
## die += bytes([name]) # DW_AT_name="a"/"b"/"c"/"d"
|
||||
## die += b'\x01' # DW_AT_decl_file
|
||||
## die += b'\x01' # DW_AT_decl_line
|
||||
## die += struct.pack(end+'I', 0x51) # DW_AT_type (ref4)
|
||||
## die += b'\x00' # end of DW_TAG_subprogram children
|
||||
## die += b'\x04' # .debug_abbrev code (DW_TAG_base_type)
|
||||
## die += b'\x05' # DW_AT_name="int"
|
||||
## die += b'\x05' # DW_AT_encoding=DW_ATE_signed
|
||||
## die += b'\x04' # DW_AT_byte_size
|
||||
## die += b'\x00' # end of DW_TAG_compile_unit children
|
||||
## # CU header (unit_length excludes itself) + DIE stream, zlib-compressed
|
||||
## info = struct.pack(end+'IHIB',
|
||||
## 7 + len(die), # unit_length
|
||||
## 4, # version
|
||||
## 0, # debug_abbrev_offset
|
||||
## 8) # address_size
|
||||
## info += die
|
||||
## print(end, 'INFO_DATA ', zlib.compress(info).hex())
|
||||
## # .debug_str_offsets.dwo: u32 offsets into .debug_str.dwo
|
||||
## str_off = b''
|
||||
## for o in (0, 0x37, 0x3D, 0x46, 0x48, 0x4A, 0x4E, 0x50, 0x52):
|
||||
## str_off += struct.pack(end+'I', o)
|
||||
## print(end, 'STR_OFFSETS', str_off.hex())
|
||||
## # .debug_line.dwo: minimal v2 line-table header, empty dirs + files
|
||||
## line = struct.pack(end+'IHIBBbBB',
|
||||
## 13, # unit_length
|
||||
## 2, # version
|
||||
## 7, # header_length
|
||||
## 1, # minimum_instruction_length
|
||||
## 1, # default_is_stmt
|
||||
## -5, # line_base
|
||||
## 14, # line_range
|
||||
## 1) # opcode_base
|
||||
## line += b'\x00\x00' # empty include_directories, file_names
|
||||
## print(end, 'LINE ', line.hex())
|
||||
|
||||
# DEFINE: %{LE_OPTS} = -DINFO_DATA=789c0b626060606100010e462083f1e6eb7f7c0d8b756299188480628c614ccc8c8ccc4c136b5818190381024066051b9c59c20e67167040980c2cacac2c0c00109a0afa -DSTR_OFFSETS=00000000370000003D00000046000000480000004A0000004E0000005000000052000000 -DLINE=0D0000000200070000000101FB0E010000
|
||||
# DEFINE: %{BE_OPTS} = -DINFO_DATA=789c6360600862606100020e46060616c6589dc50d7cff5edf6402090931863131333232334dac6161044a33040299156c7066093b9c59c0016132b0b0b2b230000003dc0afa -DSTR_OFFSETS=00000000000000370000003D00000046000000480000004A0000004E0000005000000052 -DLINE=0000000D0002000000070101FB0E010000
|
||||
|
||||
# RUN: yaml2obj -DCLASS=32 -DENDIAN=LSB -DINFO_CHDR=010000005600000001000000 %{LE_OPTS} %s -o %t.o
|
||||
# RUN: llvm-dwp %t.o -o %t
|
||||
# RUN: llvm-dwarfdump -v %t | FileCheck %s
|
||||
|
||||
# RUN: yaml2obj -DCLASS=32 -DENDIAN=MSB -DINFO_CHDR=000000010000005600000001 %s -o %t.o
|
||||
# RUN: yaml2obj -DCLASS=32 -DENDIAN=MSB -DINFO_CHDR=000000010000005600000001 %{BE_OPTS} %s -o %t.o
|
||||
# RUN: llvm-dwp %t.o -o %t
|
||||
# RUN: llvm-dwarfdump -v %t | FileCheck %s
|
||||
|
||||
# RUN: yaml2obj -DCLASS=64 -DENDIAN=LSB -DINFO_CHDR=01000000fd7f000056000000000000000100000000000000 %s -o %t.o
|
||||
# RUN: yaml2obj -DCLASS=64 -DENDIAN=LSB -DINFO_CHDR=01000000fd7f000056000000000000000100000000000000 %{LE_OPTS} %s -o %t.o
|
||||
# RUN: llvm-dwp %t.o -o %t
|
||||
# RUN: llvm-dwarfdump -v %t | FileCheck %s
|
||||
|
||||
# RUN: yaml2obj -DCLASS=64 -DENDIAN=MSB -DINFO_CHDR=0000000100007ffd00000000000000560000000000000001 %s -o %t.o
|
||||
# RUN: yaml2obj -DCLASS=64 -DENDIAN=MSB -DINFO_CHDR=0000000100007ffd00000000000000560000000000000001 %{BE_OPTS} %s -o %t.o
|
||||
# RUN: llvm-dwp %t.o -o %t
|
||||
# RUN: llvm-dwarfdump -v %t | FileCheck %s
|
||||
|
||||
|
|
@ -49,12 +113,12 @@ Sections:
|
|||
- Name: .debug_str_offsets.dwo
|
||||
Type: SHT_PROGBITS
|
||||
AddressAlign: 0x1
|
||||
Content: 00000000370000003D00000046000000480000004A0000004E0000005000000052000000
|
||||
Content: [[STR_OFFSETS]]
|
||||
- Name: .debug_info.dwo
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_COMPRESSED ]
|
||||
AddressAlign: 0x8
|
||||
Content: [[INFO_CHDR]]789c0b626060606100010e462083f1e6eb7f7c0d8b756299188480628c614ccc8c8ccc4c136b5818190381024066051b9c59c20e67167040980c2cacac2c0c00109a0afa
|
||||
Content: [[INFO_CHDR]][[INFO_DATA]]
|
||||
- Name: .debug_abbrev.dwo
|
||||
Type: SHT_PROGBITS
|
||||
AddressAlign: 0x1
|
||||
|
|
@ -62,4 +126,4 @@ Sections:
|
|||
- Name: .debug_line.dwo
|
||||
Type: SHT_PROGBITS
|
||||
AddressAlign: 0x1
|
||||
Content: 0D0000000200070000000101FB0E010000
|
||||
Content: [[LINE]]
|
||||
|
|
|
|||
Loading…
Reference in a new issue