mirror of
https://github.com/rui314/mold.git
synced 2024-09-21 18:08:01 +03:00
[ELF] Fix "recompile with -fPIC" error
mold used to emit a spurious "recompile with -fPIC" error when creating a position-dependent executable. This is because we alwyas create dynamic relocations for importe symbols. If the relocated place is read-only, we can't apply a dynamic relocation, and we printed out the error message. This patch fixes the issue by creating copy relocations and PLTs for such symbols. Fixes https://github.com/rui314/mold/issues/116
This commit is contained in:
parent
d11ecda08c
commit
e4861bb3e1
@ -398,7 +398,7 @@ void InputSection<AARCH64>::scan_relocations(Context<AARCH64> &ctx) {
|
||||
// Absolute Local Imported data Imported code
|
||||
{ NONE, BASEREL, DYNREL, DYNREL }, // DSO
|
||||
{ NONE, BASEREL, DYNREL, DYNREL }, // PIE
|
||||
{ NONE, NONE, DYNREL, DYNREL }, // PDE
|
||||
{ NONE, NONE, COPYREL, PLT }, // PDE
|
||||
};
|
||||
dispatch(ctx, table, i);
|
||||
break;
|
||||
|
@ -404,7 +404,7 @@ void InputSection<I386>::scan_relocations(Context<I386> &ctx) {
|
||||
// Absolute Local Imported data Imported code
|
||||
{ NONE, BASEREL, DYNREL, DYNREL }, // DSO
|
||||
{ NONE, BASEREL, DYNREL, DYNREL }, // PIE
|
||||
{ NONE, NONE, DYNREL, DYNREL }, // PDE
|
||||
{ NONE, NONE, COPYREL, PLT }, // PDE
|
||||
};
|
||||
dispatch(ctx, table, i);
|
||||
break;
|
||||
|
@ -556,7 +556,7 @@ void InputSection<X86_64>::scan_relocations(Context<X86_64> &ctx) {
|
||||
// Absolute Local Imported data Imported code
|
||||
{ NONE, BASEREL, DYNREL, DYNREL }, // DSO
|
||||
{ NONE, BASEREL, DYNREL, DYNREL }, // PIE
|
||||
{ NONE, NONE, DYNREL, DYNREL }, // PDE
|
||||
{ NONE, NONE, COPYREL, PLT }, // PDE
|
||||
};
|
||||
dispatch(ctx, table, i);
|
||||
break;
|
||||
|
@ -861,7 +861,6 @@ void GotSection<E>::copy_buf(Context<E> &ctx) {
|
||||
template <typename E>
|
||||
void PltSection<E>::add_symbol(Context<E> &ctx, Symbol<E> *sym) {
|
||||
assert(!sym->has_plt(ctx));
|
||||
assert(!sym->has_got(ctx));
|
||||
|
||||
if (this->shdr.sh_size == 0) {
|
||||
this->shdr.sh_size = E::plt_hdr_size;
|
||||
@ -1005,7 +1004,7 @@ void DynsymSection<E>::copy_buf(Context<E> &ctx) {
|
||||
} else if (sym.file->is_dso || sym.esym().is_undef()) {
|
||||
esym.st_shndx = SHN_UNDEF;
|
||||
esym.st_size = 0;
|
||||
if (!ctx.arg.pic && sym.has_plt(ctx) && !sym.has_got(ctx)) {
|
||||
if (sym.has_plt(ctx) && !ctx.arg.pic) {
|
||||
// Emit an address for a canonical PLT
|
||||
esym.st_value = sym.get_plt_addr(ctx);
|
||||
}
|
||||
|
@ -537,7 +537,10 @@ void scan_rels(Context<E> &ctx) {
|
||||
ctx.got->add_got_symbol(ctx, sym);
|
||||
|
||||
if (sym->flags & NEEDS_PLT) {
|
||||
if (sym->flags & NEEDS_GOT)
|
||||
// If we need to create a canonical PLT (i.e. ctx.arg.pic is true),
|
||||
// we can't use .plt.got because otherwise .plt.got and .plt would
|
||||
// refer each other, resulting in an infinite loop at runtime.
|
||||
if ((sym->flags & NEEDS_GOT) && !ctx.arg.pic)
|
||||
ctx.pltgot->add_symbol(ctx, sym);
|
||||
else
|
||||
ctx.plt->add_symbol(ctx, sym);
|
||||
|
@ -10,11 +10,13 @@ cat <<EOF | cc -shared -o $t/a.so -xc -
|
||||
void fn() {}
|
||||
EOF
|
||||
|
||||
cat <<EOF | cc -o $t/b.o -c -xc -
|
||||
cat <<EOF | cc -o $t/b.o -c -xc -fno-PIC -
|
||||
#include <stdio.h>
|
||||
|
||||
typedef void Func();
|
||||
|
||||
void fn();
|
||||
void (*ptr)() = fn;
|
||||
Func *const ptr = fn;
|
||||
|
||||
int main() {
|
||||
printf("%d\n", fn == ptr);
|
||||
|
Loading…
Reference in New Issue
Block a user