[llvm] 3097427 - [obj2yaml] Add support for dumping the .debug_str section.
Xing GUO via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 7 04:47:15 PDT 2020
Author: Xing GUO
Date: 2020-09-07T19:46:56+08:00
New Revision: 3097427f93dde9a49f729e995b8d52d91cc30d4c
URL: https://github.com/llvm/llvm-project/commit/3097427f93dde9a49f729e995b8d52d91cc30d4c
DIFF: https://github.com/llvm/llvm-project/commit/3097427f93dde9a49f729e995b8d52d91cc30d4c.diff
LOG: [obj2yaml] Add support for dumping the .debug_str section.
This patch adds support for dumping the .debug_str section to obj2yaml.
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D86867
Added:
llvm/test/tools/obj2yaml/ELF/DWARF/debug-str.yaml
Modified:
llvm/tools/obj2yaml/elf2yaml.cpp
Removed:
################################################################################
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
index 000000000000..e05864287724
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/ELF/DWARF/debug-str.yaml
@@ -0,0 +1,101 @@
+## Test how we dump the .debug_str section.
+
+## a) Test dumping a .debug_str section with a default section header.
+
+# RUN: yaml2obj --docnum=1 %s | obj2yaml | \
+# RUN: FileCheck %s --check-prefix=BASIC --implicit-check-not='Name: .debug_str'
+
+## b) Test dumping a .debug_str section whose section header properties are overridden.
+
+## Override the sh_type field.
+# RUN: yaml2obj --docnum=1 -DTYPE=STRTAB %s | obj2yaml | \
+# RUN: FileCheck %s --check-prefixes=BASIC,COMMON \
+# RUN: -DTYPE=STRTAB -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -D#%x,ADDRALIGN=1
+
+## Override the sh_flags field.
+# RUN: yaml2obj --docnum=1 -DFLAGS=[SHF_ALLOC] %s | obj2yaml | \
+# RUN: FileCheck %s --check-prefixes=BASIC,COMMON \
+# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_ALLOC ]" -D#%x,ADDRALIGN=1
+
+## Override the sh_link field.
+# RUN: yaml2obj --docnum=1 -DLINK=.sec %s | obj2yaml | \
+# RUN: FileCheck %s --check-prefixes=BASIC,COMMON,LINK \
+# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -DLINK=.sec -D#%x,ADDRALIGN=1
+
+## Override the sh_addr field.
+# RUN: yaml2obj --docnum=1 -DADDRESS=0x2020 %s | obj2yaml | \
+# RUN: FileCheck %s --check-prefixes=BASIC,COMMON,ADDRESS \
+# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -D#%x,ADDRALIGN=1 -D#%x,ADDRESS=0x2020
+
+## Override the sh_addralign field.
+# RUN: yaml2obj --docnum=1 -DADDRALIGN=3 %s | obj2yaml | \
+# RUN: FileCheck %s --check-prefixes=BASIC,COMMON \
+# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -D#%x,ADDRALIGN=3
+
+## Override the sh_entsize field (sh_entsize=3).
+# RUN: yaml2obj --docnum=1 -DENTSIZE=3 %s | obj2yaml | \
+# RUN: FileCheck %s --check-prefixes=BASIC,COMMON,ENTSIZE \
+# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -D#%x,ADDRALIGN=1 -D#%x,ENTSIZE=3
+
+## Override the sh_entsize field (sh_entsize=0).
+# RUN: yaml2obj --docnum=1 -DENTSIZE=0 %s | obj2yaml | \
+# RUN: FileCheck %s --check-prefixes=BASIC,COMMON,ENTSIZE \
+# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -D#%x,ADDRALIGN=1 -D#%x,ENTSIZE=0
+
+## Override the sh_info field.
+# RUN: yaml2obj --docnum=1 -DINFO=3 %s | obj2yaml | \
+# RUN: FileCheck %s --check-prefixes=BASIC,COMMON,INFO \
+# RUN: -DTYPE=PROGBITS -DFLAGS="[ SHF_MERGE, SHF_STRINGS ]" -D#%x,INFO=3 -D#%x,ADDRALIGN=1 -D#%x,ENTSIZE=1
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+Sections:
+ - Name: .debug_str
+ Type: SHT_[[TYPE=PROGBITS]]
+ Flags: [[FLAGS=<none>]]
+ Link: [[LINK='']]
+ EntSize: [[ENTSIZE=1]]
+ Info: [[INFO=<none>]]
+ AddressAlign: [[ADDRALIGN=1]]
+ Address: [[ADDRESS=<none>]]
+ - Name: .sec
+ Type: SHT_PROGBITS
+DWARF:
+ debug_str:
+ - a
+ - b
+ - abc
+
+# COMMON: - Name: .debug_str
+# COMMON-NEXT: Type: SHT_[[TYPE]]
+# COMMON-NEXT: Flags: [[FLAGS]]
+# LINK-NEXT: Link: .sec
+# ADDRESS-NEXT: Address: 0x[[#%.16x,ADDRESS]]
+# COMMON-NEXT: AddressAlign: 0x[[#%.16x,ADDRALIGN]]
+# ENTSIZE-NEXT: EntSize: 0x[[#%.16x,ENTSIZE]]
+# INFO-NEXT: Info: 0x[[#%.16x,INFO]]
+# BASIC: DWARF:
+# BASIC-NEXT: debug_str:
+# BASIC-NEXT: - a
+# BASIC-NEXT: - b
+# BASIC-NEXT: - abc
+# BASIC-NEXT: ...
+
+## c) Test dumping an empty .debug_str section.
+
+# RUN: yaml2obj --docnum=2 %s | obj2yaml | FileCheck %s --check-prefix=EMPTY --implicit-check-not=Sections
+
+# EMPTY: DWARF:
+# EMPTY-NEXT: debug_str: []
+# EMPTY-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
index 632ec1bc9af4..9f524479bb04 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -197,12 +197,22 @@ bool ELFDumper<ELFT>::shouldPrintSection(const ELFYAML::Section &S,
// 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<const ELFYAML::RawContentSection>(&S))
- return RawSec->Type != ELF::SHT_PROGBITS || RawSec->Flags ||
- !RawSec->Link.empty() || RawSec->Info ||
- RawSec->AddressAlign != 1 || RawSec->EntSize;
+ dyn_cast<const ELFYAML::RawContentSection>(&S)) {
+ if (RawSec->Type != ELF::SHT_PROGBITS || !RawSec->Link.empty() ||
+ RawSec->Info || RawSec->AddressAlign != 1 || RawSec->Address ||
+ RawSec->EntSize)
+ return true;
+
+ ELFYAML::ELF_SHF ShFlags = RawSec->Flags.getValueOr(ELFYAML::ELF_SHF(0));
+
+ if (SecName == "debug_str")
+ return ShFlags != ELFYAML::ELF_SHF(ELF::SHF_MERGE | ELF::SHF_STRINGS);
+
+ return ShFlags != 0;
+ }
}
// Normally we use "Symbols:" and "DynamicSymbols:" to describe contents of
@@ -404,6 +414,8 @@ Optional<DWARFYAML::Data> ELFDumper<ELFT>::dumpDWARFSections(
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.
@@ -622,7 +634,8 @@ Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
}
template <class ELFT>
-static unsigned getDefaultShEntSize(ELFYAML::ELF_SHT SecType) {
+static unsigned getDefaultShEntSize(ELFYAML::ELF_SHT SecType,
+ StringRef SecName) {
switch (SecType) {
case ELF::SHT_REL:
return sizeof(typename ELFT::Rel);
@@ -633,6 +646,8 @@ static unsigned getDefaultShEntSize(ELFYAML::ELF_SHT SecType) {
case ELF::SHT_DYNAMIC:
return sizeof(typename ELFT::Dyn);
default:
+ if (SecName == ".debug_str")
+ return 1;
return 0;
}
}
@@ -649,9 +664,6 @@ Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
S.Address = static_cast<uint64_t>(Shdr->sh_addr);
S.AddressAlign = Shdr->sh_addralign;
- if (Shdr->sh_entsize != getDefaultShEntSize<ELFT>(S.Type))
- S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);
-
S.OriginalSecNdx = Shdr - &Sections[0];
auto NameOrErr = getUniquedSectionName(Shdr);
@@ -659,6 +671,9 @@ Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
return NameOrErr.takeError();
S.Name = NameOrErr.get();
+ if (Shdr->sh_entsize != getDefaultShEntSize<ELFT>(S.Type, S.Name))
+ S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);
+
if (Shdr->sh_link != ELF::SHN_UNDEF) {
auto LinkSection = Obj.getSection(Shdr->sh_link);
if (!LinkSection)
More information about the llvm-commits
mailing list