aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Relocations.cpp57
1 files changed, 26 insertions, 31 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 8106868..ae045ee 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -541,35 +541,6 @@ static void errorOrWarn(const Twine &Msg) {
warn(Msg);
}
-// Returns PLT relocation expression.
-//
-// This handles a non PIC program call to function in a shared library. In
-// an ideal world, we could just report an error saying the relocation can
-// overflow at runtime. In the real world with glibc, crt1.o has a
-// R_X86_64_PC32 pointing to libc.so.
-//
-// The general idea on how to handle such cases is to create a PLT entry and
-// use that as the function value.
-//
-// For the static linking part, we just return a plt expr and everything
-// else will use the the PLT entry as the address.
-//
-// The remaining problem is making sure pointer equality still works. We
-// need the help of the dynamic linker for that. We let it know that we have
-// a direct reference to a so symbol by creating an undefined symbol with a
-// non zero st_value. Seeing that, the dynamic linker resolves the symbol to
-// the value of the symbol we created. This is true even for got entries, so
-// pointer equality is maintained. To avoid an infinite loop, the only entry
-// that points to the real function is a dedicated got entry used by the
-// plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT,
-// R_386_JMP_SLOT, etc).
-static RelExpr getPltExpr(Symbol &Sym, RelExpr Expr, bool &IsConstant) {
- Sym.NeedsPltAddr = true;
- Sym.IsPreemptible = false;
- IsConstant = true;
- return toPlt(Expr);
-}
-
// This modifies the expression if we can use a copy relocation or point the
// symbol to the PLT.
template <class ELFT>
@@ -637,8 +608,32 @@ static RelExpr adjustExpr(Symbol &Sym, RelExpr Expr, RelType Type,
return Expr;
}
- if (Sym.isFunc())
- return getPltExpr(Sym, Expr, IsConstant);
+ if (Sym.isFunc()) {
+ // This handles a non PIC program call to function in a shared library. In
+ // an ideal world, we could just report an error saying the relocation can
+ // overflow at runtime. In the real world with glibc, crt1.o has a
+ // R_X86_64_PC32 pointing to libc.so.
+ //
+ // The general idea on how to handle such cases is to create a PLT entry and
+ // use that as the function value.
+ //
+ // For the static linking part, we just return a plt expr and everything
+ // else will use the the PLT entry as the address.
+ //
+ // The remaining problem is making sure pointer equality still works. We
+ // need the help of the dynamic linker for that. We let it know that we have
+ // a direct reference to a so symbol by creating an undefined symbol with a
+ // non zero st_value. Seeing that, the dynamic linker resolves the symbol to
+ // the value of the symbol we created. This is true even for got entries, so
+ // pointer equality is maintained. To avoid an infinite loop, the only entry
+ // that points to the real function is a dedicated got entry used by the
+ // plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT,
+ // R_386_JMP_SLOT, etc).
+ Sym.NeedsPltAddr = true;
+ Sym.IsPreemptible = false;
+ IsConstant = true;
+ return toPlt(Expr);
+ }
errorOrWarn("symbol '" + toString(Sym) + "' has no type" +
getLocation(S, Sym, RelOff));