diff --git a/llvm/test/tools/obj2yaml/ELF/DWARF/debug-str.yaml b/llvm/test/tools/obj2yaml/ELF/DWARF/debug-str.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/obj2yaml/ELF/DWARF/debug-str.yaml @@ -0,0 +1,104 @@ +## Test how we dump the .debug_str section. + +## a) Test that obj2yaml is able to dump the .debug_str section. + +# RUN: yaml2obj --docnum=1 %s | obj2yaml | \ +# RUN: FileCheck %s --check-prefix=BASIC --implicit-check-not=Sections + +# BASIC: DWARF: +# BASIC-NEXT: debug_str: +# BASIC-NEXT: - a +# BASIC-NEXT: - b +# BASIC-NEXT: - abc +# BASIC-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC +DWARF: + debug_str: + - a + - b + - abc + +## b) Test dumping an .debug_str section whose section header properties are overridden. + +# RUN: yaml2obj --docnum=2 -DTYPE=STRTAB %s | obj2yaml | \ +# RUN: FileCheck %s --check-prefixes=SHDR,TYPE,FLAGS,ADDRALIGN,ENTSIZE \ +# RUN: -DTYPE=STRTAB -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -DADDRALIGN=0001 -DENTSIZE=0001 + +# RUN: yaml2obj --docnum=2 -DFLAGS=[SHF_ALLOC] %s | obj2yaml | \ +# RUN: FileCheck %s --check-prefixes=SHDR,TYPE,FLAGS,ADDRALIGN,ENTSIZE \ +# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_ALLOC ]" -DADDRALIGN=0001 -DENTSIZE=0001 + +# RUN: yaml2obj --docnum=2 -DLINK=.sec %s | obj2yaml | \ +# RUN: FileCheck %s --check-prefixes=SHDR,TYPE,FLAGS,LINK,ADDRALIGN,ENTSIZE \ +# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -DLINK=.sec -DADDRALIGN=0001 -DENTSIZE=0001 + +# RUN: yaml2obj --docnum=2 -DADDRESS=0x2020 %s | obj2yaml | \ +# RUN: FileCheck %s --check-prefixes=SHDR,TYPE,FLAGS,ADDRALIGN,ENTSIZE,ADDRESS \ +# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -DADDRALIGN=0001 -DENTSIZE=0001 -DADDRESS=2020 + +# RUN: yaml2obj --docnum=2 -DADDRALIGN=3 %s | obj2yaml | \ +# RUN: FileCheck %s --check-prefixes=SHDR,TYPE,FLAGS,ADDRALIGN,ENTSIZE \ +# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -DADDRALIGN=0003 -DENTSIZE=0001 + +# RUN: yaml2obj --docnum=2 -DENTSIZE=3 %s | obj2yaml | \ +# RUN: FileCheck %s --check-prefixes=SHDR,TYPE,FLAGS,ADDRALIGN,ENTSIZE \ +# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -DADDRALIGN=0001 -DENTSIZE=0003 + +# RUN: yaml2obj --docnum=2 -DINFO=3 %s | obj2yaml | \ +# RUN: FileCheck %s --check-prefixes=SHDR,TYPE,FLAGS,INFO,ADDRALIGN,ENTSIZE \ +# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -DINFO=0003 -DADDRALIGN=0001 -DENTSIZE=0001 + +# SHDR: - Name: .debug_str +# TYPE-NEXT: Type: SHT_[[TYPE]] +# FLAGS-NEXT: Flags: [[FLAGS]] +# LINK-NEXT: Link: .sec +# ADDRESS-NEXT: Address: 0x000000000000[[ADDRESS]] +# ADDRALIGN-NEXT: AddressAlign: 0x000000000000[[ADDRALIGN]] +# ENTSIZE-NEXT: EntSize: 0x000000000000[[ENTSIZE]] +# INFO-NEXT: Info: 0x000000000000[[INFO]] + +# DEBUG-STR: DWARF: +# DEBUG-STR-NEXT: debug_str: +# DEBUG-STR-NEXT: - a +# DEBUG-STR-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC +Sections: + - Name: .debug_str + Type: SHT_[[TYPE=PROGBITS]] + Flags: [[FLAGS=]] + Link: [[LINK='']] + EntSize: [[ENTSIZE=1]] + Info: [[INFO=]] + AddressAlign: [[ADDRALIGN=1]] + Address: [[ADDRESS=]] + - Name: .sec + Type: SHT_PROGBITS +DWARF: + debug_str: + - a + +## b) Test dumping an empty .debug_str section. + +# RU1N: yaml2obj --docnum=2 %s | obj2yaml | FileCheck %s --check-prefix=EMPTY-CONTENT + +# EMPTY-CONTENT: DWARF: +# EMPTY-CONTENT-NEXT: debug_str: [] +# EMPTY-CONTENT-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC +DWARF: + debug_str: [] diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -10,6 +10,7 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/ObjectYAML/DWARFYAML.h" @@ -197,12 +198,21 @@ // entry but their section headers may have special flags, entry size, address // alignment, etc. We will preserve the header for them under such // circumstances. - if (DWARF && DWARF->getNonEmptySectionNames().count(S.Name.substr(1))) { + StringRef SecName = S.Name.substr(1); + if (DWARF && DWARF->getNonEmptySectionNames().count(SecName)) { if (const ELFYAML::RawContentSection *RawSec = - dyn_cast(&S)) - return RawSec->Type != ELF::SHT_PROGBITS || RawSec->Flags || - !RawSec->Link.empty() || RawSec->Info || - RawSec->AddressAlign != 1 || RawSec->EntSize; + dyn_cast(&S)) { + bool CommonProperties = RawSec->Type == ELF::SHT_PROGBITS && + RawSec->Link.empty() && !RawSec->Info && + (uint64_t)RawSec->AddressAlign == 1 && + !RawSec->Address; + if (SecName == "debug_str") + return !CommonProperties || + !(RawSec->EntSize && (uint64_t)*RawSec->EntSize == 1) || + RawSec->Flags.getValueOr(ELFYAML::ELF_SHF(0)) != + ELFYAML::ELF_SHF(ELF::SHF_MERGE | ELF::SHF_STRINGS); + return !CommonProperties || RawSec->EntSize || RawSec->Flags; + } } // Normally we use "Symbols:" and "DynamicSymbols:" to describe contents of @@ -404,6 +414,8 @@ if (RawSec->Name == ".debug_aranges") Err = dumpDebugARanges(*DWARFCtx.get(), DWARF); + else if (RawSec->Name == ".debug_str") + dumpDebugStrings(*DWARFCtx.get(), DWARF); // If the DWARF section cannot be successfully parsed, emit raw content // instead of an entry in the DWARF section of the YAML.