Skip to content

Commit

Permalink
Recommit r373598 "[yaml2obj/obj2yaml] - Add support for SHT_LLVM_ADDR…
Browse files Browse the repository at this point in the history
…SIG 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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@373606 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
George Rimar committed Oct 3, 2019
1 parent da186b0 commit ffd82b4
Show file tree
Hide file tree
Showing 7 changed files with 470 additions and 11 deletions.
27 changes: 26 additions & 1 deletion include/llvm/ObjectYAML/ELFYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ struct Section {
StackSizes,
SymtabShndxSection,
Symver,
MipsABIFlags
MipsABIFlags,
Addrsig
};
SectionKind Kind;
StringRef Name;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
};
Expand Down
30 changes: 30 additions & 0 deletions lib/ObjectYAML/ELFEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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;
Expand Down
37 changes: 37 additions & 0 deletions lib/ObjectYAML/ELFYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 &sectionOrType) {
IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {};
}

Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions test/tools/llvm-readobj/elf-section-types.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
98 changes: 98 additions & 0 deletions test/tools/obj2yaml/elf-llvm-addrsig-section.yaml
Original file line number Diff line number Diff line change
@@ -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: ""
Loading

0 comments on commit ffd82b4

Please sign in to comment.