mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[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 llvm-svn: 354574
This commit is contained in:
parent
a13d56908a
commit
b6a05e83ac
@ -121,6 +121,7 @@ struct Section {
|
|||||||
RawContent,
|
RawContent,
|
||||||
Relocation,
|
Relocation,
|
||||||
NoBits,
|
NoBits,
|
||||||
|
Verdef,
|
||||||
Verneed,
|
Verneed,
|
||||||
Symver,
|
Symver,
|
||||||
MipsABIFlags
|
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 {
|
struct Group : Section {
|
||||||
// Members of a group contain a flag and a list of section indices
|
// Members of a group contain a flag and a list of section indices
|
||||||
// that are part of the group.
|
// that are part of the group.
|
||||||
@ -274,6 +294,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
|
|||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
|
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::Symbol)
|
||||||
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
|
||||||
@ -419,6 +440,10 @@ template <> struct MappingTraits<ELFYAML::DynamicEntry> {
|
|||||||
static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
|
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> {
|
template <> struct MappingTraits<ELFYAML::VerneedEntry> {
|
||||||
static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
|
static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
|
||||||
};
|
};
|
||||||
|
@ -868,6 +868,12 @@ static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
|
|||||||
IO.mapOptional("Size", Section.Size, Hex64(0));
|
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) {
|
static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
|
||||||
commonSectionMapping(IO, Section);
|
commonSectionMapping(IO, Section);
|
||||||
IO.mapRequired("Entries", Section.Entries);
|
IO.mapRequired("Entries", Section.Entries);
|
||||||
@ -956,6 +962,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
|
|||||||
Section.reset(new ELFYAML::MipsABIFlags());
|
Section.reset(new ELFYAML::MipsABIFlags());
|
||||||
sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
|
sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
|
||||||
break;
|
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:
|
case ELF::SHT_GNU_versym:
|
||||||
if (!IO.outputting())
|
if (!IO.outputting())
|
||||||
Section.reset(new ELFYAML::SymverSection());
|
Section.reset(new ELFYAML::SymverSection());
|
||||||
@ -1014,6 +1025,17 @@ void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO,
|
|||||||
IO.mapRequired("Value", Rel.Val);
|
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,
|
void MappingTraits<ELFYAML::VerneedEntry>::mapping(IO &IO,
|
||||||
ELFYAML::VerneedEntry &E) {
|
ELFYAML::VerneedEntry &E) {
|
||||||
assert(IO.getContext() && "The IO context is not initialized");
|
assert(IO.getContext() && "The IO context is not initialized");
|
||||||
|
72
test/tools/obj2yaml/verdef-section.yaml
Normal file
72
test/tools/obj2yaml/verdef-section.yaml
Normal file
@ -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
|
||||||
|
...
|
69
test/tools/yaml2obj/verdef-section.yaml
Normal file
69
test/tools/yaml2obj/verdef-section.yaml
Normal file
@ -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
|
||||||
|
...
|
@ -57,6 +57,7 @@ class ELFDumper {
|
|||||||
ErrorOr<ELFYAML::RawContentSection *>
|
ErrorOr<ELFYAML::RawContentSection *>
|
||||||
dumpContentSection(const Elf_Shdr *Shdr);
|
dumpContentSection(const Elf_Shdr *Shdr);
|
||||||
ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(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::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
|
||||||
ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
|
ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
|
||||||
ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
|
ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
|
||||||
@ -186,6 +187,13 @@ template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
|||||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||||
break;
|
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: {
|
case ELF::SHT_GNU_versym: {
|
||||||
ErrorOr<ELFYAML::SymverSection *> S = dumpSymverSection(&Sec);
|
ErrorOr<ELFYAML::SymverSection *> S = dumpSymverSection(&Sec);
|
||||||
if (std::error_code EC = S.getError())
|
if (std::error_code EC = S.getError())
|
||||||
@ -459,6 +467,56 @@ ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
|
|||||||
return S.release();
|
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>
|
template <class ELFT>
|
||||||
ErrorOr<ELFYAML::SymverSection *>
|
ErrorOr<ELFYAML::SymverSection *>
|
||||||
ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
|
ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
|
||||||
|
@ -163,6 +163,9 @@ class ELFState {
|
|||||||
bool writeSectionContent(Elf_Shdr &SHeader,
|
bool writeSectionContent(Elf_Shdr &SHeader,
|
||||||
const ELFYAML::VerneedSection &Section,
|
const ELFYAML::VerneedSection &Section,
|
||||||
ContiguousBlobAccumulator &CBA);
|
ContiguousBlobAccumulator &CBA);
|
||||||
|
bool writeSectionContent(Elf_Shdr &SHeader,
|
||||||
|
const ELFYAML::VerdefSection &Section,
|
||||||
|
ContiguousBlobAccumulator &CBA);
|
||||||
bool writeSectionContent(Elf_Shdr &SHeader,
|
bool writeSectionContent(Elf_Shdr &SHeader,
|
||||||
const ELFYAML::MipsABIFlags &Section,
|
const ELFYAML::MipsABIFlags &Section,
|
||||||
ContiguousBlobAccumulator &CBA);
|
ContiguousBlobAccumulator &CBA);
|
||||||
@ -311,6 +314,8 @@ bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
|
|||||||
writeSectionContent(SHeader, *S, CBA);
|
writeSectionContent(SHeader, *S, CBA);
|
||||||
} else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
|
} else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
|
||||||
writeSectionContent(SHeader, *S, CBA);
|
writeSectionContent(SHeader, *S, CBA);
|
||||||
|
} else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec.get())) {
|
||||||
|
writeSectionContent(SHeader, *S, CBA);
|
||||||
} else
|
} else
|
||||||
llvm_unreachable("Unknown section type");
|
llvm_unreachable("Unknown section type");
|
||||||
|
|
||||||
@ -585,6 +590,51 @@ bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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>
|
template <class ELFT>
|
||||||
bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
|
bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
|
||||||
const ELFYAML::VerneedSection &Section,
|
const ELFYAML::VerneedSection &Section,
|
||||||
@ -746,16 +796,19 @@ template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
|
|||||||
// Add the dynamic symbol names to .dynstr section.
|
// Add the dynamic symbol names to .dynstr section.
|
||||||
AddSymbols(DotDynstr, Doc.DynamicSymbols);
|
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) {
|
for (const std::unique_ptr<ELFYAML::Section> &Sec : Doc.Sections) {
|
||||||
auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec.get());
|
if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
|
||||||
if (!VerNeed)
|
for (const ELFYAML::VerneedEntry &VE : VerNeed->VerneedV) {
|
||||||
continue;
|
DotDynstr.add(VE.File);
|
||||||
|
for (const ELFYAML::VernauxEntry &Aux : VE.AuxV)
|
||||||
for (const ELFYAML::VerneedEntry &VE : VerNeed->VerneedV) {
|
DotDynstr.add(Aux.Name);
|
||||||
DotDynstr.add(VE.File);
|
}
|
||||||
for (const ELFYAML::VernauxEntry &Aux : VE.AuxV)
|
} else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec.get())) {
|
||||||
DotDynstr.add(Aux.Name);
|
for (const ELFYAML::VerdefEntry &E : VerDef->Entries)
|
||||||
|
for (StringRef Name : E.VerNames)
|
||||||
|
DotDynstr.add(Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user