[ELF] - Better diagnostic for relative relocation to an absolute value error.
Patch adds a filename to that error message.
I faced next error when debugged one of FreeBSD port:
error: relocation R_X86_64_PLT32 cannot refer to absolute symbol __tls_get_addr
error message was poor and this patch improves it to show the locations
of symbol declaration and using.
Differential revision: https://reviews.llvm.org/D26508
llvm-svn: 286940
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index e5ec606..406feda 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/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) {
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index c8ca74a..a202dc5 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/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
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 302dc5a..4e9c8a8 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/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() +
+ "' defined in " + 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
@@ -645,7 +649,8 @@
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 + RI.r_offset, C,
+ RI.r_offset);
if (HasError)
continue;
@@ -690,7 +695,8 @@
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, RI.r_offset);
// 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
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 48d7db4..3792d88 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/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;
diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h
index 08e1b4e..1223750 100644
--- a/lld/ELF/SymbolTable.h
+++ b/lld/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);
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 192433e..a3e2027 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/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) {}
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 2117e47..04548c1 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -568,7 +568,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;
}
diff --git a/lld/test/ELF/Inputs/relocation-relative-absolute.s b/lld/test/ELF/Inputs/relocation-relative-absolute.s
new file mode 100644
index 0000000..2341f69
--- /dev/null
+++ b/lld/test/ELF/Inputs/relocation-relative-absolute.s
@@ -0,0 +1,2 @@
+.globl answer
+answer = 42
diff --git a/lld/test/ELF/relocation-relative-absolute.s b/lld/test/ELF/relocation-relative-absolute.s
index 5253191..69f5e41 100644
--- a/lld/test/ELF/relocation-relative-absolute.s
+++ b/lld/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' defined in {{.*}}input2.o
-.globl answer
-answer = 42
+call answer@PLT