-
-
Notifications
You must be signed in to change notification settings - Fork 443
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ELF] Create canonical PLTs only when needed
Previously, we make all PLT entries canonical if we are creating a position dependent executable, because I was thinking that promoting usual PLT entries to canonical ones is harmless; symbol equality still holds. However, it looks like Qt depends on the usual linker's behavior not to make PLT canonical if not necessary. I believe they are maintaining some hidden symbol as aliases for exported symbols and compare their addresses at runtime. Of course this doesn't work if your program is not compiled with -fPIC, but qt5/QtCore/qglobal.h has a macro to abort compilation if PIC is disabled. (They check for __PIC__ and __PIE__ macros.) So, all object files are guaranteed to be compiled with -fPIC if they are using QT functions, and they assume that the linker doesn't create a canonical PLT for Qt functions. This commit makes mold to create canonical PLTs only when needed. That is, if an address of a function is directly taken (i.e. not via GOT), then mold makes its PLT canonical. Fixes #352
- Loading branch information
Showing
10 changed files
with
82 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#!/bin/bash | ||
export LC_ALL=C | ||
set -e | ||
CC="${CC:-cc}" | ||
CXX="${CXX:-c++}" | ||
GCC="${GCC:-gcc}" | ||
GXX="${GXX:-g++}" | ||
OBJDUMP="${OBJDUMP:-objdump}" | ||
MACHINE="${MACHINE:-$(uname -m)}" | ||
testname=$(basename "$0" .sh) | ||
echo -n "Testing $testname ... " | ||
cd "$(dirname "$0")"/../.. | ||
mold="$(pwd)/mold" | ||
t=out/test/elf/$testname | ||
mkdir -p $t | ||
|
||
cat <<EOF | $CC -o $t/a.so -fPIC -shared -xc - | ||
void *foo() { | ||
return foo; | ||
} | ||
void *bar() { | ||
return bar; | ||
} | ||
EOF | ||
|
||
cat <<EOF | $CC -o $t/b.o -c -xc - -fPIC | ||
void *bar(); | ||
void *baz() { | ||
return bar; | ||
} | ||
EOF | ||
|
||
cat <<EOF | $CC -o $t/c.o -c -xc - -fPIC | ||
#include <stdio.h> | ||
void *foo(); | ||
void *bar(); | ||
void *baz(); | ||
int main() { | ||
printf("%d %d %d\n", foo == foo(), bar == bar(), bar == baz()); | ||
} | ||
EOF | ||
|
||
$CC -B. -no-pie -o $t/exe $t/a.so $t/b.o $t/c.o | ||
$QEMU $t/exe | grep -q '^1 1 1$' | ||
|
||
readelf --dyn-syms $t/exe | grep -q '00000000 .* foo' | ||
readelf --dyn-syms $t/exe | grep -q '00000000 .* bar' | ||
|
||
echo OK |