[llvm] r354574 - [yaml2obj][obj2yaml] - Support SHT_GNU_verdef (.gnu.version_d) section.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 21 04:21:43 PST 2019
Author: grimar
Date: Thu Feb 21 04:21:43 2019
New Revision: 354574
URL: http://llvm.org/viewvc/llvm-project?rev=354574&view=rev
Log:
[yaml2obj][obj2yaml] - Support SHT_GNU_verdef (.gnu.version_d) 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/symverdefs.html
Differential revision: https://reviews.llvm.org/D58437
Added:
llvm/trunk/test/tools/obj2yaml/verdef-section.yaml
llvm/trunk/test/tools/yaml2obj/verdef-section.yaml
Modified:
llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h
llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
llvm/trunk/tools/obj2yaml/elf2yaml.cpp
llvm/trunk/tools/yaml2obj/yaml2elf.cpp
Modified: llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h?rev=354574&r1=354573&r2=354574&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h Thu Feb 21 04:21:43 2019
@@ -121,6 +121,7 @@ struct Section {
RawContent,
Relocation,
NoBits,
+ Verdef,
Verneed,
Symver,
MipsABIFlags
@@ -203,6 +204,25 @@ struct SymverSection : Section {
}
};
+struct VerdefEntry {
+ uint16_t Version;
+ uint16_t Flags;
+ uint16_t VersionNdx;
+ uint32_t Hash;
+ std::vector<StringRef> VerNames;
+};
+
+struct VerdefSection : Section {
+ std::vector<VerdefEntry> Entries;
+ llvm::yaml::Hex64 Info;
+
+ VerdefSection() : Section(SectionKind::Verdef) {}
+
+ static bool classof(const Section *S) {
+ return S->Kind == SectionKind::Verdef;
+ }
+};
+
struct Group : Section {
// Members of a group contain a flag and a list of section indices
// that are part of the group.
@@ -274,6 +294,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYA
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
@@ -419,6 +440,10 @@ template <> struct MappingTraits<ELFYAML
static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
};
+template <> struct MappingTraits<ELFYAML::VerdefEntry> {
+ static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
+};
+
template <> struct MappingTraits<ELFYAML::VerneedEntry> {
static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
};
Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=354574&r1=354573&r2=354574&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Thu Feb 21 04:21:43 2019
@@ -868,6 +868,12 @@ static void sectionMapping(IO &IO, ELFYA
IO.mapOptional("Size", Section.Size, Hex64(0));
}
+static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Info", Section.Info);
+ IO.mapRequired("Entries", Section.Entries);
+}
+
static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
commonSectionMapping(IO, Section);
IO.mapRequired("Entries", Section.Entries);
@@ -956,6 +962,11 @@ void MappingTraits<std::unique_ptr<ELFYA
Section.reset(new ELFYAML::MipsABIFlags());
sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
break;
+ case ELF::SHT_GNU_verdef:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::VerdefSection());
+ sectionMapping(IO, *cast<ELFYAML::VerdefSection>(Section.get()));
+ break;
case ELF::SHT_GNU_versym:
if (!IO.outputting())
Section.reset(new ELFYAML::SymverSection());
@@ -1014,6 +1025,17 @@ void MappingTraits<ELFYAML::DynamicEntry
IO.mapRequired("Value", Rel.Val);
}
+void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
+ ELFYAML::VerdefEntry &E) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapRequired("Version", E.Version);
+ IO.mapRequired("Flags", E.Flags);
+ IO.mapRequired("VersionNdx", E.VersionNdx);
+ IO.mapRequired("Hash", E.Hash);
+ IO.mapRequired("Names", E.VerNames);
+}
+
void MappingTraits<ELFYAML::VerneedEntry>::mapping(IO &IO,
ELFYAML::VerneedEntry &E) {
assert(IO.getContext() && "The IO context is not initialized");
Added: llvm/trunk/test/tools/obj2yaml/verdef-section.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/obj2yaml/verdef-section.yaml?rev=354574&view=auto
==============================================================================
--- llvm/trunk/test/tools/obj2yaml/verdef-section.yaml (added)
+++ llvm/trunk/test/tools/obj2yaml/verdef-section.yaml Thu Feb 21 04:21:43 2019
@@ -0,0 +1,72 @@
+# RUN: yaml2obj %s -o %t
+# RUN: obj2yaml %t | FileCheck %s
+
+## Check we are able to yamalize SHT_GNU_verdef section.
+
+# CHECK: - Name: .gnu.version_d
+# CHECK-NEXT: Type: SHT_GNU_verdef
+# CHECK-NEXT: Flags: [ SHF_ALLOC ]
+# CHECK-NEXT: Address: 0x0000000000000230
+# CHECK-NEXT: Link: .dynstr
+# CHECK-NEXT: AddressAlign: 0x0000000000000004
+# CHECK-NEXT: Info: 0x0000000000000004
+# CHECK-NEXT: Entries:
+# CHECK-NEXT: - Version: 1
+# CHECK-NEXT: Flags: 1
+# CHECK-NEXT: VersionNdx: 1
+# CHECK-NEXT: Hash: 170240160
+# CHECK-NEXT: Names:
+# CHECK-NEXT: - dso.so.0
+# CHECK-NEXT: - Version: 1
+# CHECK-NEXT: Flags: 2
+# CHECK-NEXT: VersionNdx: 2
+# CHECK-NEXT: Hash: 108387921
+# CHECK-NEXT: Names:
+# CHECK-NEXT: - VERSION_1
+# CHECK-NEXT: - Version: 1
+# CHECK-NEXT: Flags: 3
+# CHECK-NEXT: VersionNdx: 3
+# CHECK-NEXT: Hash: 108387922
+# CHECK-NEXT: Names:
+# CHECK-NEXT: - VERSION_2
+# CHECK-NEXT: - VERSION_3
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+ Entry: 0x0000000000001000
+Sections:
+ - Name: .gnu.version_d
+ Type: SHT_GNU_verdef
+ Flags: [ SHF_ALLOC ]
+ Address: 0x0000000000000230
+ Link: .dynstr
+ AddressAlign: 0x0000000000000004
+ Info: 0x0000000000000004
+ Entries:
+ - Version: 1
+ Flags: 1
+ VersionNdx: 1
+ Hash: 170240160
+ Names:
+ - dso.so.0
+ - Version: 1
+ Flags: 2
+ VersionNdx: 2
+ Hash: 108387921
+ Names:
+ - VERSION_1
+ - Version: 1
+ Flags: 3
+ VersionNdx: 3
+ Hash: 108387922
+ Names:
+ - VERSION_2
+ - VERSION_3
+DynamicSymbols:
+ Global:
+ - Name: foo
+...
Added: llvm/trunk/test/tools/yaml2obj/verdef-section.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/verdef-section.yaml?rev=354574&view=auto
==============================================================================
--- llvm/trunk/test/tools/yaml2obj/verdef-section.yaml (added)
+++ llvm/trunk/test/tools/yaml2obj/verdef-section.yaml Thu Feb 21 04:21:43 2019
@@ -0,0 +1,69 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readelf -V %t | FileCheck %s
+
+# Check we are able to handle the SHT_GNU_verdef sections.
+
+# CHECK: SHT_GNU_verdef {
+# CHECK-NEXT: Definition {
+# CHECK-NEXT: Version: 1
+# CHECK-NEXT: Flags: Base
+# CHECK-NEXT: Index: 1
+# CHECK-NEXT: Hash: 170240160
+# CHECK-NEXT: Name: dso.so.0
+# CHECK-NEXT: }
+# CHECK-NEXT: Definition {
+# CHECK-NEXT: Version: 1
+# CHECK-NEXT: Flags: Weak
+# CHECK-NEXT: Index: 2
+# CHECK-NEXT: Hash: 108387921
+# CHECK-NEXT: Name: VERSION_1
+# CHECK-NEXT: }
+# CHECK-NEXT: Definition {
+# CHECK-NEXT: Version: 1
+# CHECK-NEXT: Flags: 0x3
+# CHECK-NEXT: Index: 3
+# CHECK-NEXT: Hash: 108387922
+# CHECK-NEXT: Name: VERSION_2
+# CHECK-NEXT: Predecessor: VERSION_3
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+ Entry: 0x0000000000001000
+Sections:
+ - Name: .gnu.version_d
+ Type: SHT_GNU_verdef
+ Flags: [ SHF_ALLOC ]
+ Address: 0x0000000000000230
+ Link: .dynstr
+ AddressAlign: 0x0000000000000004
+ Info: 0x0000000000000003
+ Entries:
+ - Version: 1
+ Flags: 1
+ VersionNdx: 1
+ Hash: 170240160
+ Names:
+ - dso.so.0
+ - Version: 1
+ Flags: 2
+ VersionNdx: 2
+ Hash: 108387921
+ Names:
+ - VERSION_1
+ - Version: 1
+ Flags: 3
+ VersionNdx: 3
+ Hash: 108387922
+ Names:
+ - VERSION_2
+ - VERSION_3
+DynamicSymbols:
+ Global:
+ - Name: foo
+...
Modified: llvm/trunk/tools/obj2yaml/elf2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/elf2yaml.cpp?rev=354574&r1=354573&r2=354574&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/elf2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/elf2yaml.cpp Thu Feb 21 04:21:43 2019
@@ -57,6 +57,7 @@ class ELFDumper {
ErrorOr<ELFYAML::RawContentSection *>
dumpContentSection(const Elf_Shdr *Shdr);
ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
+ ErrorOr<ELFYAML::VerdefSection *> dumpVerdefSection(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);
@@ -186,6 +187,13 @@ template <class ELFT> ErrorOr<ELFYAML::O
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
break;
}
+ case ELF::SHT_GNU_verdef: {
+ ErrorOr<ELFYAML::VerdefSection *> S = dumpVerdefSection(&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_versym: {
ErrorOr<ELFYAML::SymverSection *> S = dumpSymverSection(&Sec);
if (std::error_code EC = S.getError())
@@ -458,6 +466,56 @@ ELFDumper<ELFT>::dumpNoBitsSection(const
return S.release();
}
+
+template <class ELFT>
+ErrorOr<ELFYAML::VerdefSection *>
+ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
+ typedef typename ELFT::Verdef Elf_Verdef;
+ typedef typename ELFT::Verdaux Elf_Verdaux;
+
+ auto S = make_unique<ELFYAML::VerdefSection>();
+ if (std::error_code EC = dumpCommonSection(Shdr, *S))
+ return EC;
+
+ S->Info = Shdr->sh_info;
+
+ auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
+ if (!StringTableShdrOrErr)
+ return errorToErrorCode(StringTableShdrOrErr.takeError());
+
+ auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
+ if (!StringTableOrErr)
+ return errorToErrorCode(StringTableOrErr.takeError());
+
+ auto Contents = Obj.getSectionContents(Shdr);
+ if (!Contents)
+ return errorToErrorCode(Contents.takeError());
+
+ llvm::ArrayRef<uint8_t> Data = *Contents;
+ const uint8_t *Buf = Data.data();
+ while (Buf) {
+ const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
+ ELFYAML::VerdefEntry Entry;
+ Entry.Version = Verdef->vd_version;
+ Entry.Flags = Verdef->vd_flags;
+ Entry.VersionNdx = Verdef->vd_ndx;
+ Entry.Hash = Verdef->vd_hash;
+
+ const uint8_t *BufAux = Buf + Verdef->vd_aux;
+ while (BufAux) {
+ const Elf_Verdaux *Verdaux =
+ reinterpret_cast<const Elf_Verdaux *>(BufAux);
+ Entry.VerNames.push_back(
+ StringTableOrErr->drop_front(Verdaux->vda_name).data());
+ BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
+ }
+
+ S->Entries.push_back(Entry);
+ Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
+ }
+
+ return S.release();
+}
template <class ELFT>
ErrorOr<ELFYAML::SymverSection *>
Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=354574&r1=354573&r2=354574&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Thu Feb 21 04:21:43 2019
@@ -164,6 +164,9 @@ class ELFState {
const ELFYAML::VerneedSection &Section,
ContiguousBlobAccumulator &CBA);
bool writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::VerdefSection &Section,
+ ContiguousBlobAccumulator &CBA);
+ bool writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::MipsABIFlags &Section,
ContiguousBlobAccumulator &CBA);
void writeSectionContent(Elf_Shdr &SHeader,
@@ -311,6 +314,8 @@ bool ELFState<ELFT>::initSectionHeaders(
writeSectionContent(SHeader, *S, CBA);
} else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
writeSectionContent(SHeader, *S, CBA);
+ } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec.get())) {
+ writeSectionContent(SHeader, *S, CBA);
} else
llvm_unreachable("Unknown section type");
@@ -587,6 +592,51 @@ bool ELFState<ELFT>::writeSectionContent
template <class ELFT>
bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::VerdefSection &Section,
+ ContiguousBlobAccumulator &CBA) {
+ typedef typename ELFT::Verdef Elf_Verdef;
+ typedef typename ELFT::Verdaux Elf_Verdaux;
+ raw_ostream &OS =
+ CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+
+ uint64_t AuxCnt = 0;
+ for (size_t I = 0; I < Section.Entries.size(); ++I) {
+ const ELFYAML::VerdefEntry &E = Section.Entries[I];
+
+ Elf_Verdef VerDef;
+ VerDef.vd_version = E.Version;
+ VerDef.vd_flags = E.Flags;
+ VerDef.vd_ndx = E.VersionNdx;
+ VerDef.vd_hash = E.Hash;
+ VerDef.vd_aux = sizeof(Elf_Verdef);
+ VerDef.vd_cnt = E.VerNames.size();
+ if (I == Section.Entries.size() - 1)
+ VerDef.vd_next = 0;
+ else
+ VerDef.vd_next =
+ sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux);
+ OS.write((const char *)&VerDef, sizeof(Elf_Verdef));
+
+ for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) {
+ Elf_Verdaux VernAux;
+ VernAux.vda_name = DotDynstr.getOffset(E.VerNames[J]);
+ if (J == E.VerNames.size() - 1)
+ VernAux.vda_next = 0;
+ else
+ VernAux.vda_next = sizeof(Elf_Verdaux);
+ OS.write((const char *)&VernAux, sizeof(Elf_Verdaux));
+ }
+ }
+
+ SHeader.sh_size = Section.Entries.size() * sizeof(Elf_Verdef) +
+ AuxCnt * sizeof(Elf_Verdaux);
+ SHeader.sh_info = Section.Info;
+
+ return true;
+}
+
+template <class ELFT>
+bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::VerneedSection &Section,
ContiguousBlobAccumulator &CBA) {
typedef typename ELFT::Verneed Elf_Verneed;
@@ -746,16 +796,19 @@ template <class ELFT> void ELFState<ELFT
// Add the dynamic symbol names to .dynstr section.
AddSymbols(DotDynstr, Doc.DynamicSymbols);
- // SHT_GNU_verneed section also adds strings to .dynstr section.
+ // SHT_GNU_verdef and SHT_GNU_verneed sections might also
+ // add strings to .dynstr section.
for (const std::unique_ptr<ELFYAML::Section> &Sec : Doc.Sections) {
- auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec.get());
- if (!VerNeed)
- continue;
-
- for (const ELFYAML::VerneedEntry &VE : VerNeed->VerneedV) {
- DotDynstr.add(VE.File);
- for (const ELFYAML::VernauxEntry &Aux : VE.AuxV)
- DotDynstr.add(Aux.Name);
+ if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
+ for (const ELFYAML::VerneedEntry &VE : VerNeed->VerneedV) {
+ DotDynstr.add(VE.File);
+ for (const ELFYAML::VernauxEntry &Aux : VE.AuxV)
+ DotDynstr.add(Aux.Name);
+ }
+ } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec.get())) {
+ for (const ELFYAML::VerdefEntry &E : VerDef->Entries)
+ for (StringRef Name : E.VerNames)
+ DotDynstr.add(Name);
}
}
More information about the llvm-commits
mailing list