mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[yaml2obj][obj2yaml] - Support SHT_GNU_versym (.gnu.version) section.
This patch adds support for parsing dumping the .gnu.version section. Description of the section is: https://refspecs.linuxfoundation.org/LSB_1.3.0/gLSB/gLSB/symversion.html#SYMVERTBL Differential revision: https://reviews.llvm.org/D58280 llvm-svn: 354338
This commit is contained in:
parent
028b8cf90b
commit
efc720024f
@ -122,6 +122,7 @@ struct Section {
|
||||
Relocation,
|
||||
NoBits,
|
||||
Verneed,
|
||||
Symver,
|
||||
MipsABIFlags
|
||||
};
|
||||
SectionKind Kind;
|
||||
@ -192,6 +193,16 @@ struct VerneedSection : Section {
|
||||
}
|
||||
};
|
||||
|
||||
struct SymverSection : Section {
|
||||
std::vector<uint16_t> Entries;
|
||||
|
||||
SymverSection() : Section(SectionKind::Symver) {}
|
||||
|
||||
static bool classof(const Section *S) {
|
||||
return S->Kind == SectionKind::Symver;
|
||||
}
|
||||
};
|
||||
|
||||
struct Group : Section {
|
||||
// Members of a group contain a flag and a list of section indices
|
||||
// that are part of the group.
|
||||
|
@ -872,6 +872,11 @@ static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
|
||||
IO.mapOptional("Size", Section.Size, Hex64(0));
|
||||
}
|
||||
|
||||
static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
|
||||
commonSectionMapping(IO, Section);
|
||||
IO.mapRequired("Entries", Section.Entries);
|
||||
}
|
||||
|
||||
static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
|
||||
commonSectionMapping(IO, Section);
|
||||
IO.mapRequired("Info", Section.Info);
|
||||
@ -955,6 +960,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
|
||||
Section.reset(new ELFYAML::MipsABIFlags());
|
||||
sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
|
||||
break;
|
||||
case ELF::SHT_GNU_versym:
|
||||
if (!IO.outputting())
|
||||
Section.reset(new ELFYAML::SymverSection());
|
||||
sectionMapping(IO, *cast<ELFYAML::SymverSection>(Section.get()));
|
||||
break;
|
||||
case ELF::SHT_GNU_verneed:
|
||||
if (!IO.outputting())
|
||||
Section.reset(new ELFYAML::VerneedSection());
|
||||
|
48
test/tools/obj2yaml/versym-section.yaml
Normal file
48
test/tools/obj2yaml/versym-section.yaml
Normal file
@ -0,0 +1,48 @@
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: obj2yaml %t | FileCheck %s
|
||||
|
||||
## Check we are able to yamalize the SHT_GNU_versym section.
|
||||
|
||||
# CHECK: --- !ELF
|
||||
# CHECK-NEXT: FileHeader:
|
||||
# CHECK-NEXT: Class: ELFCLASS64
|
||||
# CHECK-NEXT: Data: ELFDATA2LSB
|
||||
# CHECK-NEXT: Type: ET_EXEC
|
||||
# CHECK-NEXT: Machine: EM_X86_64
|
||||
# CHECK-NEXT: Entry: 0x0000000000201000
|
||||
# CHECK-NEXT: Sections:
|
||||
# CHECK-NEXT: - Name: .gnu.version
|
||||
# CHECK-NEXT: Type: SHT_GNU_versym
|
||||
# CHECK-NEXT: Flags: [ SHF_ALLOC ]
|
||||
# CHECK-NEXT: Address: 0x0000000000200210
|
||||
# CHECK-NEXT: Link: .dynsym
|
||||
# CHECK-NEXT: AddressAlign: 0x0000000000000002
|
||||
# CHECK-NEXT: EntSize: 0x0000000000000002
|
||||
# CHECK-NEXT: Entries: [ 0, 3, 4 ]
|
||||
# CHECK-NEXT: Symbols: {}
|
||||
# CHECK-NEXT: DynamicSymbols:
|
||||
# CHECK-NEXT: Global:
|
||||
# CHECK-NEXT: - Name: f1
|
||||
# CHECK-NEXT: - Name: f2
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
Entry: 0x0000000000201000
|
||||
Sections:
|
||||
- Name: .gnu.version
|
||||
Type: SHT_GNU_versym
|
||||
Flags: [ SHF_ALLOC ]
|
||||
Address: 0x0000000000200210
|
||||
Link: .dynsym
|
||||
AddressAlign: 0x0000000000000002
|
||||
EntSize: 0x0000000000000002
|
||||
Entries: [ 0, 3, 4 ]
|
||||
DynamicSymbols:
|
||||
Global:
|
||||
- Name: f1
|
||||
- Name: f2
|
||||
...
|
88
test/tools/yaml2obj/versym-section.yaml
Normal file
88
test/tools/yaml2obj/versym-section.yaml
Normal file
@ -0,0 +1,88 @@
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-readelf -V %t | FileCheck %s
|
||||
|
||||
## Check we are able to produce a valid SHT_GNU_versym
|
||||
## section from its description.
|
||||
|
||||
# CHECK: Version symbols {
|
||||
# CHECK-NEXT: Section Name: .gnu.version
|
||||
# CHECK-NEXT: Address: 0x200210
|
||||
# CHECK-NEXT: Offset: 0x240
|
||||
# CHECK-NEXT: Link: 6
|
||||
# CHECK-NEXT: Symbols [
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Version: 0
|
||||
# CHECK-NEXT: Name:
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Version: 3
|
||||
# CHECK-NEXT: Name: f1@v1
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Version: 4
|
||||
# CHECK-NEXT: Name: f2@v2
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: SHT_GNU_verdef {
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: SHT_GNU_verneed {
|
||||
# CHECK-NEXT: Dependency {
|
||||
# CHECK-NEXT: Version: 1
|
||||
# CHECK-NEXT: Count: 2
|
||||
# CHECK-NEXT: FileName: dso.so.0
|
||||
# CHECK-NEXT: Entry {
|
||||
# CHECK-NEXT: Hash: 1937
|
||||
# CHECK-NEXT: Flags: 0x0
|
||||
# CHECK-NEXT: Index: 3
|
||||
# CHECK-NEXT: Name: v1
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Entry {
|
||||
# CHECK-NEXT: Hash: 1938
|
||||
# CHECK-NEXT: Flags: 0x0
|
||||
# CHECK-NEXT: Index: 4
|
||||
# CHECK-NEXT: Name: v2
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: }
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
Entry: 0x0000000000201000
|
||||
Sections:
|
||||
- Name: .gnu.version
|
||||
Type: SHT_GNU_versym
|
||||
Flags: [ SHF_ALLOC ]
|
||||
Address: 0x0000000000200210
|
||||
Link: .dynsym
|
||||
AddressAlign: 0x0000000000000002
|
||||
EntSize: 0x0000000000000002
|
||||
Entries: [ 0, 3, 4 ]
|
||||
- Name: .gnu.version_r
|
||||
Type: SHT_GNU_verneed
|
||||
Flags: [ SHF_ALLOC ]
|
||||
Address: 0x0000000000200250
|
||||
Link: .dynstr
|
||||
AddressAlign: 0x0000000000000004
|
||||
Info: 0x0000000000000001
|
||||
Dependencies:
|
||||
- Version: 1
|
||||
File: dso.so.0
|
||||
Entries:
|
||||
- Name: v1
|
||||
Hash: 1937
|
||||
Flags: 0
|
||||
Other: 3
|
||||
- Name: v2
|
||||
Hash: 1938
|
||||
Flags: 0
|
||||
Other: 4
|
||||
DynamicSymbols:
|
||||
Global:
|
||||
- Name: f1
|
||||
- Name: f2
|
||||
...
|
@ -57,6 +57,7 @@ class ELFDumper {
|
||||
ErrorOr<ELFYAML::RawContentSection *>
|
||||
dumpContentSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
|
||||
@ -185,6 +186,13 @@ template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_GNU_versym: {
|
||||
ErrorOr<ELFYAML::SymverSection *> S = dumpSymverSection(&Sec);
|
||||
if (std::error_code EC = S.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_GNU_verneed: {
|
||||
ErrorOr<ELFYAML::VerneedSection *> S = dumpVerneedSection(&Sec);
|
||||
if (std::error_code EC = S.getError())
|
||||
@ -451,6 +459,24 @@ ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
|
||||
return S.release();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::SymverSection *>
|
||||
ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
|
||||
typedef typename ELFT::Half Elf_Half;
|
||||
|
||||
auto S = make_unique<ELFYAML::SymverSection>();
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
|
||||
auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(Shdr);
|
||||
if (!VersionsOrErr)
|
||||
return errorToErrorCode(VersionsOrErr.takeError());
|
||||
for (const Elf_Half &E : *VersionsOrErr)
|
||||
S->Entries.push_back(E);
|
||||
|
||||
return S.release();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::VerneedSection *>
|
||||
ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
|
||||
|
@ -156,6 +156,9 @@ class ELFState {
|
||||
ContiguousBlobAccumulator &CBA);
|
||||
bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group,
|
||||
ContiguousBlobAccumulator &CBA);
|
||||
bool writeSectionContent(Elf_Shdr &SHeader,
|
||||
const ELFYAML::SymverSection &Section,
|
||||
ContiguousBlobAccumulator &CBA);
|
||||
bool writeSectionContent(Elf_Shdr &SHeader,
|
||||
const ELFYAML::VerneedSection &Section,
|
||||
ContiguousBlobAccumulator &CBA);
|
||||
@ -303,6 +306,8 @@ bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
|
||||
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
|
||||
} else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec.get())) {
|
||||
writeSectionContent(SHeader, *S, CBA);
|
||||
} else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec.get())) {
|
||||
writeSectionContent(SHeader, *S, CBA);
|
||||
} else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
|
||||
writeSectionContent(SHeader, *S, CBA);
|
||||
} else
|
||||
@ -567,6 +572,24 @@ bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
|
||||
const ELFYAML::SymverSection &Section,
|
||||
ContiguousBlobAccumulator &CBA) {
|
||||
typedef typename ELFT::Half Elf_Half;
|
||||
|
||||
raw_ostream &OS =
|
||||
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
|
||||
for (uint16_t V : Section.Entries) {
|
||||
Elf_Half Version = (Elf_Half)V;
|
||||
OS.write((const char *)&Version, sizeof(Elf_Half));
|
||||
}
|
||||
|
||||
SHeader.sh_size = Section.Entries.size() * sizeof(Elf_Half);
|
||||
SHeader.sh_entsize = sizeof(Elf_Half);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
|
||||
const ELFYAML::VerneedSection &Section,
|
||||
|
Loading…
Reference in New Issue
Block a user