StackSizes,
SymtabShndxSection,
Symver,
- MipsABIFlags,
- Addrsig
+ MipsABIFlags
};
SectionKind Kind;
StringRef Name;
}
};
-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;
} // 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)
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);
};
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:
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");
}
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;
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);
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;
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 {};
}
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)
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
+++ /dev/null
-## 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: ""
+++ /dev/null
-## 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: ""
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;
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 *>
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
}
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();
- }
-
- 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>();
}
template <class ELFT>
-Expected<StringRef> ELFDumper<ELFT>::getSymbolName(uint32_t SymtabNdx,
- uint32_t SymbolNdx) {
- auto SymtabOrErr = Obj.getSection(SymtabNdx);
+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);
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, SymbolNdx);
+ auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
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);
- // 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);
+ Expected<StringRef> SymbolName =
+ getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
if (!SymbolName)
return SymbolName.takeError();
S->Signature = *SymbolName;