[yaml2obj] - Allow setting st_value explicitly for Symbol.

In some cases it is useful to explicitly set symbol's st_name value.
For example, I am using it in a patch for LLD to remove the broken
binary from a test case and replace it with a YAML test.

Differential revision: https://reviews.llvm.org/D61180

llvm-svn: 360137
This commit is contained in:
George Rimar 2019-05-07 12:10:51 +00:00
parent c6e44e02ee
commit 5cd1e134c0
4 changed files with 96 additions and 50 deletions

View File

@ -95,6 +95,7 @@ struct ProgramHeader {
struct Symbol {
StringRef Name;
Optional<uint32_t> NameIndex;
ELF_STT Type;
StringRef Section;
Optional<ELF_SHN> Index;

View File

@ -854,6 +854,7 @@ struct NormalizedOther {
void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
IO.mapOptional("Name", Symbol.Name, StringRef());
IO.mapOptional("NameIndex", Symbol.NameIndex);
IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
IO.mapOptional("Section", Symbol.Section, StringRef());
IO.mapOptional("Index", Symbol.Index);
@ -867,12 +868,12 @@ void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
ELFYAML::Symbol &Symbol) {
if (Symbol.Index && Symbol.Section.data()) {
if (Symbol.Index && Symbol.Section.data())
return "Index and Section cannot both be specified for Symbol";
}
if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX)) {
if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX))
return "Large indexes are not supported";
}
if (Symbol.NameIndex && !Symbol.Name.empty())
return "Name and NameIndex cannot both be specified for Symbol";
return StringRef();
}

View File

@ -0,0 +1,37 @@
## Check we are able to use integers as both
## symbol name indices (st_name values) and symbol names.
# RUN: yaml2obj --docnum=1 %s > %t
# RUN: llvm-readobj --symbols %t | FileCheck %s
# CHECK: Name: test (1)
# CHECK: Name: test (1)
# CHECK: Name: est (2)
# CHECK: Name: 1 (8)
# CHECK: Name: 2 (6)
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Symbols:
- Name: test
- NameIndex: 1
- NameIndex: 2
- Name: 1
- Name: 2
## Check we do not allow specifying both Name and NameIndex at once.
# RUN: not yaml2obj --docnum=2 %s 2>&1 | FileCheck %s --check-prefix=ERR
# ERR: error: Name and NameIndex cannot both be specified for Symbol
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Symbols:
- Name: foo
NameIndex: 0

View File

@ -468,8 +468,15 @@ void ELFState<ELFT>::addSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
for (const auto &Sym : Symbols) {
Elf_Sym Symbol;
zero(Symbol);
if (!Sym.Name.empty())
// If NameIndex, which contains the name offset, is explicitly specified, we
// use it. This is useful for preparing broken objects. Otherwise, we add
// the specified Name to the string table builder to get its offset.
if (Sym.NameIndex)
Symbol.st_name = *Sym.NameIndex;
else if (!Sym.Name.empty())
Symbol.st_name = Strtab.getOffset(Sym.Name);
Symbol.setBindingAndType(Sym.Binding, Sym.Type);
if (!Sym.Section.empty()) {
unsigned Index;