Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -292,7 +292,7 @@ SymbolBody *elf::ObjectFile::createSymbolBody(const Elf_Sym *Sym) { unsigned char Binding = Sym->getBinding(); if (Binding == STB_LOCAL) - return new (Alloc) LocalSymbol(*Sym); + return new (Alloc) LocalSymbol(*Sym, getSection(*Sym)); StringRef Name = check(Sym->getName(this->StringTable)); Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -186,8 +186,6 @@ InputSectionBase *OffsetSec = nullptr; uintX_t OffsetInSec = 0; bool UseSymVA = false; - InputSectionBase *TargetSec = nullptr; - uintX_t OffsetInTargetSec = 0; uintX_t Addend = 0; DynamicReloc(uint32_t Type, OffsetKind OKind, SymbolBody *Sym) @@ -202,13 +200,6 @@ : Type(Type), OKind(Off_Sec), Sym(Sym), OffsetSec(OffsetSec), OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {} - DynamicReloc(uint32_t Type, InputSectionBase *OffsetSec, - uintX_t OffsetInSec, InputSectionBase *TargetSec, - uintX_t OffsetInTargetSec, uintX_t Addend) - : Type(Type), OKind(Off_Sec), OffsetSec(OffsetSec), - OffsetInSec(OffsetInSec), TargetSec(TargetSec), - OffsetInTargetSec(OffsetInTargetSec), Addend(Addend) {} - uintX_t getOffset() const; }; Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -266,12 +266,20 @@ if (IsRela) { uintX_t VA = 0; - if (Rel.UseSymVA) - VA = Sym->getVA(); - else if (Rel.TargetSec) - VA = Rel.TargetSec->getOffset(Rel.OffsetInTargetSec) + - Rel.TargetSec->OutSec->getVA(); - reinterpret_cast(P)->r_addend = Rel.Addend + VA; + uintX_t Addend = Rel.Addend; + if (Rel.UseSymVA) { + if (auto *L = dyn_cast>(Sym)) { + uintX_t Pos = L->Sym.st_value; + if (L->Sym.getType() == STT_SECTION) { + Pos += Addend; + Addend = 0; + } + VA = L->Section->OutSec->getVA() + L->Section->getOffset(Pos); + } else { + VA = Sym->getVA(); + } + } + reinterpret_cast(P)->r_addend = Addend + VA; } P->r_offset = Rel.getOffset(); Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -313,12 +313,15 @@ typedef typename llvm::object::ELFFile::Elf_Sym Elf_Sym; public: - LocalSymbol(const Elf_Sym &Sym) - : DefinedElf(SymbolBody::DefinedLocalKind, "", Sym) {} + LocalSymbol(const Elf_Sym &Sym, InputSectionBase *Section) + : DefinedElf(SymbolBody::DefinedLocalKind, "", Sym), + Section(Section) {} static bool classof(const SymbolBody *S) { return S->kind() == SymbolBody::DefinedLocalKind; } + + InputSectionBase *Section; }; // This class represents a symbol defined in an archive file. It is Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -474,20 +474,8 @@ (uintX_t)getPPC64TocBase() + Addend}); continue; } - if (!Body.isLocal()) { - Out::RelaDyn->addReloc( - {Target->RelativeRel, &C, RI.r_offset, true, &Body, Addend}); - continue; - } - const Elf_Sym &Sym = cast>(Body).Sym; - InputSectionBase *Section = File.getSection(Sym); - uintX_t Offset = Sym.st_value; - if (Sym.getType() == STT_SECTION) { - Offset += Addend; - Addend = 0; - } Out::RelaDyn->addReloc( - {Target->RelativeRel, &C, RI.r_offset, Section, Offset, Addend}); + {Target->RelativeRel, &C, RI.r_offset, true, &Body, Addend}); } }