diff options
author | George Rimar <grimar@accesssoftek.com> | 2019-10-03 14:52:33 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2019-10-03 14:52:33 +0000 |
commit | fc9104d42a777540984c7f43f5f12f635ebc5098 (patch) | |
tree | bae019618dcd2cb1b90398f54e8138edf65e071e /llvm | |
parent | 2c9c7d680974d4d6f39a7df52268b8e308a5b50c (diff) | |
download | bcm5719-llvm-fc9104d42a777540984c7f43f5f12f635ebc5098.tar.gz bcm5719-llvm-fc9104d42a777540984c7f43f5f12f635ebc5098.zip |
Recommit r373598 "[yaml2obj/obj2yaml] - Add support for SHT_LLVM_ADDRSIG sections."
Fix: call `consumeError()` for a case missed.
Original commit message:
SHT_LLVM_ADDRSIG is described here:
https://llvm.org/docs/Extensions.html#sht-llvm-addrsig-section-address-significance-table
This patch teaches tools to dump them and to parse the YAML declarations of such sections.
Differential revision: https://reviews.llvm.org/D68333
llvm-svn: 373606
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/ObjectYAML/ELFYAML.h | 27 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/ELFEmitter.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/ELFYAML.cpp | 37 | ||||
-rw-r--r-- | llvm/test/tools/llvm-readobj/elf-section-types.test | 1 | ||||
-rw-r--r-- | llvm/test/tools/obj2yaml/elf-llvm-addrsig-section.yaml | 98 | ||||
-rw-r--r-- | llvm/test/tools/yaml2obj/elf-llvm-addrsig-section.yaml | 213 | ||||
-rw-r--r-- | llvm/tools/obj2yaml/elf2yaml.cpp | 75 |
7 files changed, 470 insertions, 11 deletions
diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 1662d06bf91..592b5021bd6 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -137,7 +137,8 @@ struct Section { StackSizes, SymtabShndxSection, Symver, - MipsABIFlags + MipsABIFlags, + Addrsig }; SectionKind Kind; StringRef Name; @@ -256,6 +257,25 @@ struct VerneedSection : Section { } }; +struct AddrsigSymbol { + AddrsigSymbol(StringRef N) : Name(N), Index(None) {} + AddrsigSymbol(llvm::yaml::Hex32 Ndx) : Name(None), Index(Ndx) {} + AddrsigSymbol() : Name(None), Index(None) {} + + Optional<StringRef> Name; + Optional<llvm::yaml::Hex32> Index; +}; + +struct AddrsigSection : Section { + Optional<yaml::BinaryRef> Content; + Optional<std::vector<AddrsigSymbol>> Symbols; + + AddrsigSection() : Section(SectionKind::Addrsig) {} + static bool classof(const Section *S) { + return S->Kind == SectionKind::Addrsig; + } +}; + struct SymverSection : Section { std::vector<uint16_t> Entries; @@ -362,6 +382,7 @@ struct Object { } // end namespace ELFYAML } // end namespace llvm +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::AddrsigSymbol) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader) @@ -518,6 +539,10 @@ template <> struct MappingTraits<ELFYAML::VernauxEntry> { static void mapping(IO &IO, ELFYAML::VernauxEntry &E); }; +template <> struct MappingTraits<ELFYAML::AddrsigSymbol> { + static void mapping(IO &IO, ELFYAML::AddrsigSymbol &Sym); +}; + template <> struct MappingTraits<ELFYAML::Relocation> { static void mapping(IO &IO, ELFYAML::Relocation &Rel); }; diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index c85cf4c924f..3f3b27c5bfa 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -174,6 +174,10 @@ template <class ELFT> class ELFState { void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::HashSection &Section, ContiguousBlobAccumulator &CBA); + void writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::AddrsigSection &Section, + ContiguousBlobAccumulator &CBA); + ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH); public: @@ -423,6 +427,8 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) { writeSectionContent(SHeader, *S, CBA); + } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) { + writeSectionContent(SHeader, *S, CBA); } else { llvm_unreachable("Unknown section type"); } @@ -990,6 +996,30 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, Section.Content->writeAsBinary(OS); } +template <class ELFT> +void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::AddrsigSection &Section, + ContiguousBlobAccumulator &CBA) { + raw_ostream &OS = + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + + unsigned Link = 0; + if (Section.Link.empty() && SN2I.lookup(".symtab", Link)) + SHeader.sh_link = Link; + + if (Section.Content) { + SHeader.sh_size = writeContent(OS, Section.Content, None); + return; + } + + for (const ELFYAML::AddrsigSymbol &Sym : *Section.Symbols) { + uint64_t Val = + Sym.Name ? toSymbolIndex(*Sym.Name, Section.Name, /*IsDynamic=*/false) + : (uint32_t)*Sym.Index; + SHeader.sh_size += encodeULEB128(Val, OS); + } +} + template <class ELFT> void ELFState<ELFT>::buildSectionIndex() { for (unsigned I = 0, E = Doc.Sections.size(); I != E; ++I) { StringRef Name = Doc.Sections[I]->Name; diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 0dd6854cfee..e295a000ef8 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1071,6 +1071,12 @@ static void sectionMapping(IO &IO, ELFYAML::SymtabShndxSection &Section) { IO.mapRequired("Entries", Section.Entries); } +static void sectionMapping(IO &IO, ELFYAML::AddrsigSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Content", Section.Content); + IO.mapOptional("Symbols", Section.Symbols); +} + void MappingTraits<ELFYAML::SectionOrType>::mapping( IO &IO, ELFYAML::SectionOrType §ionOrType) { IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType); @@ -1161,6 +1167,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping( Section.reset(new ELFYAML::SymtabShndxSection()); sectionMapping(IO, *cast<ELFYAML::SymtabShndxSection>(Section.get())); break; + case ELF::SHT_LLVM_ADDRSIG: + if (!IO.outputting()) + Section.reset(new ELFYAML::AddrsigSection()); + sectionMapping(IO, *cast<ELFYAML::AddrsigSection>(Section.get())); + break; default: if (!IO.outputting()) { StringRef Name; @@ -1233,6 +1244,26 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate( return {}; } + if (const auto *Sec = dyn_cast<ELFYAML::AddrsigSection>(Section.get())) { + if (!Sec->Symbols && !Sec->Content) + return "one of \"Symbols\" or \"Content\" must be specified"; + + if (Sec->Content) { + if (Sec->Symbols) + return "\"Content\" and \"Symbols\" cannot be used together"; + return {}; + } + + if (!Sec->Symbols) + return {}; + + for (const ELFYAML::AddrsigSymbol &AS : *Sec->Symbols) + if (AS.Index && AS.Name) + return "\"Index\" and \"Name\" cannot be used together when defining a " + "symbol"; + return {}; + } + return {}; } @@ -1340,6 +1371,12 @@ void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) { IO.setContext(nullptr); } +void MappingTraits<ELFYAML::AddrsigSymbol>::mapping(IO &IO, ELFYAML::AddrsigSymbol &Sym) { + assert(IO.getContext() && "The IO context is not initialized"); + IO.mapOptional("Name", Sym.Name); + IO.mapOptional("Index", Sym.Index); +} + LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG) LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP) LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT) diff --git a/llvm/test/tools/llvm-readobj/elf-section-types.test b/llvm/test/tools/llvm-readobj/elf-section-types.test index aad9f43c8a3..20b881249c7 100644 --- a/llvm/test/tools/llvm-readobj/elf-section-types.test +++ b/llvm/test/tools/llvm-readobj/elf-section-types.test @@ -196,6 +196,7 @@ Sections: Type: SHT_LLVM_CALL_GRAPH_PROFILE - Name: llvm_addrsig Type: SHT_LLVM_ADDRSIG + Symbols: - Name: .deplibs Type: SHT_LLVM_DEPENDENT_LIBRARIES - Name: .llvm_sympart.f diff --git a/llvm/test/tools/obj2yaml/elf-llvm-addrsig-section.yaml b/llvm/test/tools/obj2yaml/elf-llvm-addrsig-section.yaml new file mode 100644 index 00000000000..6f21c3212bd --- /dev/null +++ b/llvm/test/tools/obj2yaml/elf-llvm-addrsig-section.yaml @@ -0,0 +1,98 @@ +## Check how obj2yaml dumps the SHT_LLVM_ADDRSIG section. + +## Check that when possible obj2yaml tries to produce the "Name" tag when +## dumping entries of the SHT_LLVM_ADDRSIG section. It falls back to producing +## the "Index" tag when it can't match a symbol index with a symbol table entry. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=NAME + +# NAME: - Name: .llvm_addrsig +# NAME-NEXT: Type: SHT_LLVM_ADDRSIG +# NAME-NEXT: Link: .symtab +# NAME-NEXT: Symbols: +# NAME-NEXT: - Name: foo +# NAME-NEXT: - Name: bar +# NAME-NEXT: - Index: 0x00000003 +# NAME-NEXT: - Index: 0xFFFFFFFF +# NAME: - Name: .llvm_addrsig_unlinked +# NAME-NEXT: Type: SHT_LLVM_ADDRSIG +# NAME-NEXT: Symbols: +# NAME-NEXT: - Index: 0x00000001 +# NAME-NEXT: - Index: 0x00000002 +# NAME-NEXT: - Index: 0x00000003 +# NAME-NEXT: - Index: 0xFFFFFFFF + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Symbols: + - Index: 1 + - Index: 2 + - Index: 3 + - Index: 0xFFFFFFFF + - Name: .llvm_addrsig_unlinked + Type: SHT_LLVM_ADDRSIG + Link: 0 + Symbols: + - Index: 1 + - Index: 2 + - Index: 3 + - Index: 0xFFFFFFFF +Symbols: + - Name: foo + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: bar + Type: STT_FUNC + Binding: STB_GLOBAL + +## Check that obj2yaml dumps the SHT_LLVM_ADDRSIG section +## data using the "Content" tag when at least one of the entries is broken, +## e.g. because the entry contains a malformed uleb128 value. + +# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=INVALID-ENTRY + +# INVALID-ENTRY: - Name: .llvm_addrsig +# INVALID-ENTRY-NEXT: Type: SHT_LLVM_ADDRSIG +# INVALID-ENTRY-NEXT: Link: .symtab +# INVALID-ENTRY-NEXT: Content: FFFFFFFFFF + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Content: "FFFFFFFFFF" + +## obj2yaml produces a "Symbols" tag when describing an empty SHT_LLVM_ADDRSIG section. + +# RUN: yaml2obj --docnum=3 %s -o %t3 +# RUN: obj2yaml %t3 | FileCheck %s --check-prefix=EMPTY + +# EMPTY: - Name: .llvm_addrsig +# EMPTY-NEXT: Type: SHT_LLVM_ADDRSIG +# EMPTY-NEXT: Link: .symtab +# EMPTY-NEXT: Symbols: [] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Content: "" diff --git a/llvm/test/tools/yaml2obj/elf-llvm-addrsig-section.yaml b/llvm/test/tools/yaml2obj/elf-llvm-addrsig-section.yaml new file mode 100644 index 00000000000..98496d30fa8 --- /dev/null +++ b/llvm/test/tools/yaml2obj/elf-llvm-addrsig-section.yaml @@ -0,0 +1,213 @@ +## Check how yaml2obj produces SHT_LLVM_ADDRSIG sections. + +## Check we can describe SHT_LLVM_ADDRSIG using the "Symbols" tag. We can define +## symbols either using names or indexes. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: llvm-readobj --sections --section-data %t1 | FileCheck %s --check-prefix=SYMBOLS + +# SYMBOLS: Section { +# SYMBOLS: Index: 1 +# SYMBOLS-NEXT: Name: .llvm_addrsig +# SYMBOLS-NEXT: Type: SHT_LLVM_ADDRSIG +# SYMBOLS-NEXT: Flags [ +# SYMBOLS-NEXT: ] +# SYMBOLS-NEXT: Address: 0x0 +# SYMBOLS-NEXT: Offset: 0x40 +# SYMBOLS-NEXT: Size: 4 +# SYMBOLS-NEXT: Link: 2 +# SYMBOLS-NEXT: Info: 0 +# SYMBOLS-NEXT: AddressAlignment: 0 +# SYMBOLS-NEXT: EntrySize: 0 +# SYMBOLS-NEXT: SectionData ( +# SYMBOLS-NEXT: 0000: 01020102 +# SYMBOLS-NEXT: ) +# SYMBOLS-NEXT: } + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Symbols: + - Name: foo + - Name: bar + - Index: 1 + - Index: 2 +Symbols: + - Name: foo + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: bar + Type: STT_FUNC + Binding: STB_GLOBAL + +## We can't specify both "Index" and "Name" when defining a symbol. + +# RUN: not yaml2obj --docnum=2 %s 2>&1 | FileCheck %s --check-prefix=INDEX-NAME + +# INDEX-NAME: error: "Index" and "Name" cannot be used together when defining a symbol + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Symbols: + - Name: foo + Index: 1 +Symbols: + - Name: foo + Type: STT_FUNC + Binding: STB_GLOBAL + +## Check we report an error if an unknown symbol is referenced in the +## SHT_LLVM_ADDRSIG section description. + +# RUN: not yaml2obj --docnum=3 %s 2>&1 | FileCheck %s --check-prefix=SYMBOL-UNKNOWN + +# SYMBOL-UNKNOWN: error: unknown symbol referenced: 'foo' by YAML section '.llvm_addrsig' +# SYMBOL-UNKNOWN: error: unknown symbol referenced: 'bar' by YAML section '.llvm_addrsig' + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Symbols: + - Name: foo + - Name: bar + +## Check we can specify any arbitrary symbol indices. + +# RUN: yaml2obj --docnum=4 %s -o %t4 +# RUN: llvm-readobj --sections --section-data %t4 | FileCheck %s --check-prefix=SYMBOL-INDEX + +# SYMBOL-INDEX: Type: SHT_LLVM_ADDRSIG +# SYMBOL-INDEX: SectionData ( +# SYMBOL-INDEX-NEXT: 0000: 00FF01C4 E6888901 FFFFFFFF 0F +# SYMBOL-INDEX-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Symbols: + - Index: 0 + - Index: 255 + - Index: 0x11223344 +## 0xFFFFFFFF is a maximum allowed index value. + - Index: 0xFFFFFFFF + +## Check that the maximum symbol index size is 32 bits. + +# RUN: not yaml2obj --docnum=5 %s 2>&1 | FileCheck %s --check-prefix=SYMBOL-INDEX-OVERFLOW + +# SYMBOL-INDEX-OVERFLOW: error: out of range hex32 number + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Symbols: + - Index: 0x1122334455 + +## Check we can use the "Content" tag to specify any data for SHT_LLVM_ADDRSIG sections. + +# RUN: yaml2obj --docnum=6 %s -o %t6 +# RUN: llvm-readobj --sections --section-data %t6 | FileCheck %s --check-prefix=CONTENT + +# CONTENT: Type: SHT_LLVM_ADDRSIG +# CONTENT: Size: +# CONTENT-SAME: 5 +# CONTENT: SectionData ( +# CONTENT-NEXT: 0000: 11223344 55 +# CONTENT-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Content: "1122334455" + +## Either "Content" or "Symbols" must be specifed for SHT_LLVM_ADDRSIG sections. + +# RUN: not yaml2obj --docnum=7 %s 2>&1 | FileCheck %s --check-prefix=NO-TAGS + +# NO-TAGS: error: one of "Symbols" or "Content" must be specified + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + +## "Content" and "Symbols" cannot be used together to describe the SHT_LLVM_ADDRSIG section. + +# RUN: not yaml2obj --docnum=8 %s 2>&1 | FileCheck %s --check-prefix=CONTENT-SYMBOLS + +# CONTENT-SYMBOLS: error: "Content" and "Symbols" cannot be used together + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Content: "" + Symbols: + +## Check we can set an arbitrary sh_link value for SHT_LLVM_ADDRSIG sections. + +# RUN: yaml2obj --docnum=9 %s -o %t9 +# RUN: llvm-readobj --sections %t9 | FileCheck %s --check-prefix=LINK + +# LINK: Name: .llvm_addrsig +# LINK: Link: +# LINK-SAME: 123{{$}} + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Link: 123 + Content: "" diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index c4b6eb79d18..2c17b9570e1 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -41,6 +41,7 @@ class ELFDumper { Expected<StringRef> getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable, const Elf_Shdr *SymTab); + Expected<StringRef> getSymbolName(uint32_t SymtabNdx, uint32_t SymbolNdx); const object::ELFFile<ELFT> &Obj; ArrayRef<Elf_Word> ShndxTable; @@ -56,6 +57,7 @@ class ELFDumper { Error dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab, ELFYAML::Relocation &R); + Expected<ELFYAML::AddrsigSection *> dumpAddrsigSection(const Elf_Shdr *Shdr); Expected<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr); Expected<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr); Expected<ELFYAML::RawContentSection *> @@ -284,6 +286,13 @@ template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() { Y->Sections.emplace_back(*SecOrErr); break; } + case ELF::SHT_LLVM_ADDRSIG: { + Expected<ELFYAML::AddrsigSection *> SecOrErr = dumpAddrsigSection(&Sec); + if (!SecOrErr) + return SecOrErr.takeError(); + Y->Sections.emplace_back(*SecOrErr); + break; + } case ELF::SHT_NULL: { // We only dump the SHT_NULL section at index 0 when it // has at least one non-null field, because yaml2obj @@ -520,6 +529,46 @@ ELFDumper<ELFT>::dumpStackSizesSection(const Elf_Shdr *Shdr) { } template <class ELFT> +Expected<ELFYAML::AddrsigSection *> +ELFDumper<ELFT>::dumpAddrsigSection(const Elf_Shdr *Shdr) { + auto S = std::make_unique<ELFYAML::AddrsigSection>(); + if (Error E = dumpCommonSection(Shdr, *S)) + return std::move(E); + + auto ContentOrErr = Obj.getSectionContents(Shdr); + if (!ContentOrErr) + return ContentOrErr.takeError(); + + ArrayRef<uint8_t> Content = *ContentOrErr; + DataExtractor::Cursor Cur(0); + DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0); + std::vector<ELFYAML::AddrsigSymbol> Symbols; + while (Cur && Cur.tell() < Content.size()) { + uint64_t SymNdx = Data.getULEB128(Cur); + if (!Cur) + break; + + Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, SymNdx); + if (!SymbolName || SymbolName->empty()) { + consumeError(SymbolName.takeError()); + Symbols.emplace_back(SymNdx); + continue; + } + + Symbols.emplace_back(*SymbolName); + } + + if (Cur) { + S->Symbols = std::move(Symbols); + return S.release(); + } + + consumeError(Cur.takeError()); + S->Content = yaml::BinaryRef(Content); + return S.release(); +} + +template <class ELFT> Expected<ELFYAML::DynamicSection *> ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) { auto S = std::make_unique<ELFYAML::DynamicSection>(); @@ -791,25 +840,31 @@ ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) { } template <class ELFT> -Expected<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { - auto S = std::make_unique<ELFYAML::Group>(); - if (Error E = dumpCommonSection(Shdr, *S)) - return std::move(E); - - auto SymtabOrErr = Obj.getSection(Shdr->sh_link); +Expected<StringRef> ELFDumper<ELFT>::getSymbolName(uint32_t SymtabNdx, + uint32_t SymbolNdx) { + auto SymtabOrErr = Obj.getSection(SymtabNdx); if (!SymtabOrErr) return SymtabOrErr.takeError(); - // Get symbol with index sh_info which name is the signature of the group. + const Elf_Shdr *Symtab = *SymtabOrErr; - auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info); + auto SymOrErr = Obj.getSymbol(Symtab, SymbolNdx); if (!SymOrErr) return SymOrErr.takeError(); + auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab); if (!StrTabOrErr) return StrTabOrErr.takeError(); + return getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab); +} + +template <class ELFT> +Expected<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { + auto S = std::make_unique<ELFYAML::Group>(); + if (Error E = dumpCommonSection(Shdr, *S)) + return std::move(E); - Expected<StringRef> SymbolName = - getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab); + // Get symbol with index sh_info. This symbol's name is the signature of the group. + Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, Shdr->sh_info); if (!SymbolName) return SymbolName.takeError(); S->Signature = *SymbolName; |