}
}
- if (!canWrite && (config->isPic && !isRelExpr(expr))) {
- error(
- "can't create dynamic relocation " + toString(type) + " against " +
- (sym.getName().empty() ? "local symbol" : "symbol: " + toString(sym)) +
- " in readonly segment; recompile object files with -fPIC "
- "or pass '-Wl,-z,notext' to allow text relocations in the output" +
- getLocation(sec, sym, offset));
- return;
- }
-
- // Copy relocations (for STT_OBJECT) and canonical PLT (for STT_FUNC) are only
- // possible in an executable.
- //
- // Among R_ABS relocatoin types, symbolicRel has the same size as the word
- // size. Others have fewer bits and may cause runtime overflow in -pie/-shared
- // mode. Disallow them.
- if (config->shared ||
- (config->pie && expr == R_ABS && type != target->symbolicRel)) {
- errorOrWarn(
- "relocation " + toString(type) + " cannot be used against " +
- (sym.getName().empty() ? "local symbol" : "symbol " + toString(sym)) +
- "; recompile with -fPIC" + getLocation(sec, sym, offset));
- return;
- }
-
- // If the symbol is undefined we already reported any relevant errors.
- if (sym.isUndefined())
- return;
-
- if (!canDefineSymbolInExecutable(sym)) {
- error("cannot preempt symbol: " + toString(sym) +
- getLocation(sec, sym, offset));
- return;
- }
+ // When producing an executable, we can perform copy relocations (for
+ // STT_OBJECT) and canonical PLT (for STT_FUNC).
+ if (!config->shared) {
+ if (!canDefineSymbolInExecutable(sym)) {
+ errorOrWarn("cannot preempt symbol: " + toString(sym) +
+ getLocation(sec, sym, offset));
+ return;
+ }
- if (sym.isObject()) {
- // Produce a copy relocation.
- if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
- if (!config->zCopyreloc)
- error("unresolvable relocation " + toString(type) +
- " against symbol '" + toString(*ss) +
- "'; recompile with -fPIC or remove '-z nocopyreloc'" +
- getLocation(sec, sym, offset));
- addCopyRelSymbol<ELFT>(*ss);
+ if (sym.isObject()) {
+ // Produce a copy relocation.
+ if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
+ if (!config->zCopyreloc)
+ error("unresolvable relocation " + toString(type) +
+ " against symbol '" + toString(*ss) +
+ "'; recompile with -fPIC or remove '-z nocopyreloc'" +
+ getLocation(sec, sym, offset));
+ addCopyRelSymbol<ELFT>(*ss);
+ }
+ sec.relocations.push_back({expr, type, offset, addend, &sym});
+ return;
}
- sec.relocations.push_back({expr, type, offset, addend, &sym});
- return;
- }
- 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
// compiled without -fPIE/-fPIC and doesn't maintain ebx.
// * If a library definition gets preempted to the executable, it will have
// the wrong ebx value.
- if (config->pie && config->emachine == EM_386)
- errorOrWarn("symbol '" + toString(sym) +
- "' cannot be preempted; recompile with -fPIE" +
- getLocation(sec, sym, offset));
- if (!sym.isInPlt())
- addPltEntry<ELFT>(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
- if (!sym.isDefined())
- replaceWithDefined(
- sym, in.plt,
- target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
- sym.needsPltAddr = true;
- sec.relocations.push_back({expr, type, offset, addend, &sym});
+ if (sym.isFunc()) {
+ if (config->pie && config->emachine == EM_386)
+ errorOrWarn("symbol '" + toString(sym) +
+ "' cannot be preempted; recompile with -fPIE" +
+ getLocation(sec, sym, offset));
+ if (!sym.isInPlt())
+ addPltEntry<ELFT>(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
+ if (!sym.isDefined())
+ replaceWithDefined(
+ sym, in.plt,
+ target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
+ sym.needsPltAddr = true;
+ sec.relocations.push_back({expr, type, offset, addend, &sym});
+ return;
+ }
+ }
+
+ if (config->isPic) {
+ if (!canWrite && !isRelExpr(expr))
+ errorOrWarn(
+ "can't create dynamic relocation " + toString(type) + " against " +
+ (sym.getName().empty() ? "local symbol"
+ : "symbol: " + toString(sym)) +
+ " in readonly segment; recompile object files with -fPIC "
+ "or pass '-Wl,-z,notext' to allow text relocations in the output" +
+ getLocation(sec, sym, offset));
+ else
+ errorOrWarn(
+ "relocation " + toString(type) + " cannot be used against " +
+ (sym.getName().empty() ? "local symbol" : "symbol " + toString(sym)) +
+ "; recompile with -fPIC" + getLocation(sec, sym, offset));
return;
}
+ // If the symbol is undefined we already reported any relevant errors.
+ if (sym.isUndefined())
+ return;
+
errorOrWarn("symbol '" + toString(sym) + "' has no type" +
getLocation(sec, sym, offset));
}