Skip to content

Commit

Permalink
Fix function pointer equality
Browse files Browse the repository at this point in the history
Previously, a GOT relocation (e.g. R_X86_64_REX_GOTPCRELX) and a
R_X86_64_64 relocation referring the same imported symbols were
resolved to different addresses. Here is why:

 - When we saw a R_X86_64_64 relocation against an imported symbol,
   we created a PLT and resolve the relocation there.

 - GOT relocation is resolved to a GOT entry, which has a true
   address of an imported function at runtime, which is different
   from PLT entries that redirect calls to the real function.

With this patch, we no longer create a PLT entry for R_X86_64_64.
Instead, we emit a dynamic relocation so that it is always resolved
to a real function address.

Fixes GNU MP's `make check` failure, which was reported at
#81
  • Loading branch information
rui314 committed Jul 10, 2021
1 parent faac31f commit 3204bb0
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 3 deletions.
2 changes: 1 addition & 1 deletion arch_aarch64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,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, PLT }, // PDE
{ NONE, NONE, DYNREL, DYNREL }, // PDE
};
dispatch(ctx, table, i);
break;
Expand Down
2 changes: 1 addition & 1 deletion arch_i386.cc
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,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, PLT }, // PDE
{ NONE, NONE, DYNREL, DYNREL }, // PDE
};
dispatch(ctx, table, i);
break;
Expand Down
2 changes: 1 addition & 1 deletion arch_x86_64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,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, PLT }, // PDE
{ NONE, NONE, DYNREL, DYNREL }, // PDE
};
dispatch(ctx, table, i);
break;
Expand Down
26 changes: 26 additions & 0 deletions test/func-addr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
set -e
cd $(dirname $0)
echo -n "Testing $(basename -s .sh $0) ... "
t=$(pwd)/tmp/$(basename -s .sh $0)
mkdir -p $t

cat <<EOF | cc -shared -o $t/a.so -xc -
void fn() {}
EOF

cat <<EOF | cc -o $t/b.o -c -xc -
#include <stdio.h>
void fn();
void (*ptr)() = fn;
int main() {
printf("%d\n", fn == ptr);
}
EOF

clang -fuse-ld=`pwd`/../mold -o $t/exe $t/b.o $t/a.so
$t/exe | grep -q 1

echo OK

0 comments on commit 3204bb0

Please sign in to comment.