NameToIdxMap SN2I;
NameToIdxMap SymN2I;
+ NameToIdxMap DynSymN2I;
ELFYAML::Object &Doc;
bool buildSectionIndex();
- bool buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols);
+ bool buildSymbolIndexes();
void initELFHeader(Elf_Ehdr &Header);
void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders);
bool initImplicitHeader(ELFState<ELFT> &State, ContiguousBlobAccumulator &CBA,
auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+ const NameToIdxMap &SymMap = Section.Link == ".dynsym" ? DynSymN2I : SymN2I;
for (const auto &Rel : Section.Relocations) {
unsigned SymIdx = 0;
// If a relocation references a symbol, try to look one up in the symbol
// table. If it is not there, treat the value as a symbol index.
- if (Rel.Symbol && !SymN2I.lookup(*Rel.Symbol, SymIdx) &&
+ if (Rel.Symbol && !SymMap.lookup(*Rel.Symbol, SymIdx) &&
!to_integer(*Rel.Symbol, SymIdx)) {
WithColor::error() << "Unknown symbol referenced: '" << *Rel.Symbol
<< "' at YAML section '" << Section.Name << "'.\n";
return true;
}
-template <class ELFT>
-bool ELFState<ELFT>::buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols) {
+static bool buildSymbolsMap(ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) {
bool GlobalSymbolSeen = false;
std::size_t I = 0;
- for (const auto &Sym : Symbols) {
+ for (const ELFYAML::Symbol &Sym : V) {
++I;
StringRef Name = Sym.Name;
if (Sym.Binding.value != ELF::STB_LOCAL)
GlobalSymbolSeen = true;
- if (!Name.empty() && !SymN2I.addName(Name, I)) {
+ if (!Name.empty() && !Map.addName(Name, I)) {
WithColor::error() << "Repeated symbol name: '" << Name << "'.\n";
return false;
}
return true;
}
+template <class ELFT> bool ELFState<ELFT>::buildSymbolIndexes() {
+ return buildSymbolsMap(Doc.Symbols, SymN2I) &&
+ buildSymbolsMap(Doc.DynamicSymbols, DynSymN2I);
+}
+
template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
// Add the regular symbol names to .strtab section.
for (const ELFYAML::Symbol &Sym : Doc.Symbols)
// sections that might want to use them.
State.finalizeStrings();
- if (!State.buildSectionIndex())
- return 1;
-
- if (!State.buildSymbolIndex(Doc.Symbols))
+ if (!State.buildSectionIndex() || !State.buildSymbolIndexes())
return 1;
Elf_Ehdr Header;
--- /dev/null
+## Show that yaml2obj uses the correct set of symbols for relocation sections
+## referencing the dynamic symbol table.
+
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readelf -r %t | FileCheck %s
+
+# CHECK: Relocation section '.rela.dyn' at offset {{.*}} contains 2 entries:
+# CHECK-NEXT: Offset Info Type Symbol's Value Symbol's Name
+# CHECK-NEXT: 0000000000000000 0000000100000000 R_X86_64_NONE 0000000012345678 dynamic
+# CHECK-NEXT: 0000000000000008 0000000200000000 R_X86_64_NONE 0000000087654321 both
+# CHECK-EMPTY:
+# CHECK-NEXT: Relocation section '.rela.data' at offset {{.*}} contains 2 entries:
+# CHECK-NEXT: Offset Info Type Symbol's Value Symbol's Name
+# CHECK-NEXT: 0000000000000010 0000000200000000 R_X86_64_NONE 0000000011223344 static
+# CHECK-NEXT: 0000000000000018 0000000100000000 R_X86_64_NONE 0000000088776655 both
+
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+Sections:
+ - Name: .data
+ Type: SHT_PROGBITS
+ - Name: .rela.dyn
+ Type: SHT_REL
+ Link: .dynsym
+ Info: .data
+ Relocations:
+ - Offset: 0
+ Type: R_X86_64_NONE
+ Symbol: dynamic
+ - Offset: 8
+ Type: R_X86_64_NONE
+ Symbol: both
+ - Name: .rela.data
+ Type: SHT_REL
+ Link: .symtab
+ Info: .data
+ Relocations:
+ - Offset: 16
+ Type: R_X86_64_NONE
+ Symbol: static
+ - Offset: 24
+ Type: R_X86_64_NONE
+ Symbol: both
+Symbols:
+ - Name: both
+ Section: .data
+ Value: 0x88776655
+ Binding: STB_GLOBAL
+ - Name: static
+ Section: .data
+ Value: 0x11223344
+ Binding: STB_GLOBAL
+DynamicSymbols:
+ - Name: dynamic
+ Section: .data
+ Value: 0x12345678
+ Binding: STB_GLOBAL
+ - Name: both
+ Section: .data
+ Value: 0x87654321
+ Binding: STB_GLOBAL