Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -477,7 +477,7 @@ /*CanOmitFromDynSym*/ false, this) ->body(); - return elf::Symtab<ELFT>::X->addRegular(Name, *Sym, Sec)->body(); + return elf::Symtab<ELFT>::X->addRegular(Name, *Sym, Sec, this)->body(); } } @@ -805,11 +805,13 @@ Sections.push_back(Section); elf::Symtab<ELFT>::X->addRegular(StartName, STV_DEFAULT, STT_OBJECT, 0, 0, - STB_GLOBAL, Section); + STB_GLOBAL, Section, nullptr); elf::Symtab<ELFT>::X->addRegular(EndName, STV_DEFAULT, STT_OBJECT, - Data.size(), 0, STB_GLOBAL, Section); + Data.size(), 0, STB_GLOBAL, Section, + nullptr); elf::Symtab<ELFT>::X->addRegular(SizeName, STV_DEFAULT, STT_OBJECT, - Data.size(), 0, STB_GLOBAL, nullptr); + Data.size(), 0, STB_GLOBAL, nullptr, + nullptr); } static bool isBitcode(MemoryBufferRef MB) { Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -65,7 +65,7 @@ template <class ELFT> static void addRegular(SymbolAssignment *Cmd) { uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, Visibility, STT_NOTYPE, - 0, 0, STB_GLOBAL, nullptr); + 0, 0, STB_GLOBAL, nullptr, nullptr); Cmd->Sym = Sym->body(); // If we have no SECTIONS then we don't have '.' and don't call Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -306,7 +306,9 @@ template <class ELFT> static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type, - const SymbolBody &Body) { + const SymbolBody &Body, + InputSectionBase<ELFT> &S, + typename ELFT::uint RelOff) { // These expressions always compute a constant if (E == R_SIZE || E == R_GOT_FROM_END || E == R_GOT_OFF || E == R_MIPS_GOT_LOCAL_PAGE || E == R_MIPS_GOT_OFF || @@ -342,8 +344,9 @@ if (AbsVal && RelE) { if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) return true; - error("relocation " + getRelName(Type) + - " cannot refer to absolute symbol " + Body.getName()); + error(getLocation(S, RelOff) + ": relocation " + getRelName(Type) + + " cannot refer to absolute symbol '" + Body.getName() + + "', symbol defined here " + getFilename(Body.File)); return true; } @@ -421,7 +424,8 @@ template <class ELFT> static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body, bool IsWrite, RelExpr Expr, uint32_t Type, - const uint8_t *Data) { + const uint8_t *Data, InputSectionBase<ELFT> &S, + typename ELFT::uint RelOff) { bool Preemptible = isPreemptible(Body, Type); if (Body.isGnuIFunc()) { Expr = toPlt(Expr); @@ -433,7 +437,7 @@ } Expr = Target->getThunkExpr(Expr, Type, File, Body); - if (IsWrite || isStaticLinkTimeConstant<ELFT>(Expr, Type, Body)) + if (IsWrite || isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, S, RelOff)) return Expr; // This relocation would require the dynamic linker to write a value to read @@ -630,41 +634,41 @@ const RelTy &RI = *I; SymbolBody &Body = File.getRelocTargetSym(RI); uint32_t Type = RI.getType(Config->Mips64EL); + uintX_t Off = RI.r_offset; if (Config->MipsN32Abi) { uint32_t Processed; - std::tie(Type, Processed) = - mergeMipsN32RelTypes(Type, RI.r_offset, I + 1, E); + std::tie(Type, Processed) = mergeMipsN32RelTypes(Type, Off, I + 1, E); I += Processed; } // We only report undefined symbols if they are referenced somewhere in the // code. if (!Body.isLocal() && Body.isUndefined() && !Body.symbol()->isWeak()) - reportUndefined(Body, C, RI.r_offset); + reportUndefined(Body, C, Off); RelExpr Expr = Target->getRelExpr(Type, Body); bool Preemptible = isPreemptible(Body, Type); - Expr = adjustExpr(File, Body, IsWrite, Expr, Type, Buf + RI.r_offset); + Expr = adjustExpr(File, Body, IsWrite, Expr, Type, Buf + Off, C, Off); + if (HasError) continue; // Skip a relocation that points to a dead piece // in a eh_frame section. - while (PieceI != PieceE && - (PieceI->InputOff + PieceI->size() <= RI.r_offset)) + while (PieceI != PieceE && (PieceI->InputOff + PieceI->size() <= Off)) ++PieceI; // Compute the offset of this section in the output section. We do it here // to try to compute it only once. uintX_t Offset; if (PieceI != PieceE) { - assert(PieceI->InputOff <= RI.r_offset && "Relocation not in any piece"); + assert(PieceI->InputOff <= Off && "Relocation not in any piece"); if (PieceI->OutputOff == -1) continue; - Offset = PieceI->OutputOff + RI.r_offset - PieceI->InputOff; + Offset = PieceI->OutputOff + Off - PieceI->InputOff; } else { - Offset = RI.r_offset; + Offset = Off; } // This relocation does not require got entry, but it is relative to got and @@ -690,7 +694,7 @@ Expr == R_THUNK_PLT_PC || refersToGotEntry(Expr) || !isPreemptible(Body, Type)) { // If the relocation points to something in the file, we can process it. - bool Constant = isStaticLinkTimeConstant<ELFT>(Expr, Type, Body); + bool Constant = isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, C, Off); // If the output being produced is position independent, the final value // is still not known. In that case we still need some help from the Index: ELF/SymbolTable.h =================================================================== --- ELF/SymbolTable.h +++ ELF/SymbolTable.h @@ -60,9 +60,9 @@ Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type, uintX_t Value, uintX_t Size, uint8_t Binding, - InputSectionBase<ELFT> *Section); + InputSectionBase<ELFT> *Section, InputFile *File); Symbol *addRegular(StringRef Name, const Elf_Sym &Sym, - InputSectionBase<ELFT> *Section); + InputSectionBase<ELFT> *Section, InputFile *File); Symbol *addSynthetic(StringRef N, OutputSectionBase *Section, uintX_t Value, uint8_t StOther); Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -127,8 +127,8 @@ template <class ELFT> DefinedRegular<ELFT> *SymbolTable<ELFT>::addAbsolute(StringRef Name, uint8_t Visibility) { - Symbol *Sym = - addRegular(Name, Visibility, STT_NOTYPE, 0, 0, STB_GLOBAL, nullptr); + Symbol *Sym = addRegular(Name, Visibility, STT_NOTYPE, 0, 0, STB_GLOBAL, + nullptr, nullptr); return cast<DefinedRegular<ELFT>>(Sym->body()); } @@ -397,25 +397,26 @@ template <typename ELFT> Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, const Elf_Sym &Sym, - InputSectionBase<ELFT> *Section) { + InputSectionBase<ELFT> *Section, + InputFile *File) { return addRegular(Name, Sym.st_other, Sym.getType(), Sym.st_value, - Sym.st_size, Sym.getBinding(), Section); + Sym.st_size, Sym.getBinding(), Section, File); } template <typename ELFT> Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther, uint8_t Type, uintX_t Value, uintX_t Size, uint8_t Binding, - InputSectionBase<ELFT> *Section) { + InputSectionBase<ELFT> *Section, + InputFile *File) { Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name, Type, StOther & 3, - /*CanOmitFromDynSym*/ false, - Section ? Section->getFile() : nullptr); + /*CanOmitFromDynSym*/ false, File); int Cmp = compareDefinedNonCommon(S, WasInserted, Binding); if (Cmp > 0) replaceBody<DefinedRegular<ELFT>>(S, Name, StOther, Type, Value, Size, - Section); + Section, File); else if (Cmp == 0) reportDuplicate(S->body(), Section, Value); return S; Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -194,11 +194,6 @@ this->File = File; } - DefinedRegular(StringRef Name, uint8_t StOther, uint8_t Type, uintX_t Value, - uintX_t Size, InputSectionBase<ELFT> *Section) - : DefinedRegular(Name, StOther, Type, Value, Size, Section, - Section ? Section->getFile() : nullptr) {} - DefinedRegular(StringRef Name, uint8_t StOther, uint8_t Type, BitcodeFile *F) : DefinedRegular(Name, StOther, Type, 0, 0, NullInputSection, F) {} Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -563,7 +563,7 @@ typename ELFT::Sym LocalHidden = {}; LocalHidden.setBindingAndType(STB_LOCAL, STT_NOTYPE); LocalHidden.setVisibility(STV_HIDDEN); - Symbol *S = Symtab<ELFT>::X->addRegular(Name, LocalHidden, IS); + Symbol *S = Symtab<ELFT>::X->addRegular(Name, LocalHidden, IS, nullptr); cast<DefinedRegular<ELFT>>(S->body())->Value = Value; return S; } Index: test/ELF/Inputs/relocation-relative-absolute.s =================================================================== --- test/ELF/Inputs/relocation-relative-absolute.s +++ test/ELF/Inputs/relocation-relative-absolute.s @@ -0,0 +1,2 @@ +.globl answer +answer = 42 Index: test/ELF/relocation-relative-absolute.s =================================================================== --- test/ELF/relocation-relative-absolute.s +++ test/ELF/relocation-relative-absolute.s @@ -1,12 +1,12 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %tinput1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \ +# RUN: %S/Inputs/relocation-relative-absolute.s -o %tinput2.o +# RUN: not ld.lld %tinput1.o %tinput2.o -o %t -pie 2>&1 | FileCheck %s .globl _start _start: -# CHECK: relocation R_X86_64_PLT32 cannot refer to absolute symbol answer -call answer@PLT +# CHECK: {{.*}}input1.o (.text+0x1): relocation R_X86_64_PLT32 cannot refer to absolute symbol 'answer', symbol defined here {{.*}}input2.o -.globl answer -answer = 42 +call answer@PLT