Created
February 10, 2021 01:27
-
-
Save rprichard/8775d7844228577e40d2fd0776397f47 to your computer and use it in GitHub Desktop.
Mach-O doesn't have weak aliases
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
The linker seems to delete the weak version of _bar because it's overridden by a strong | |
version, and when it does, it also deletes _foo's instructions, so calling _foo actually | |
calls an unrelated function, _baz. | |
$ ./weak-to-weak-alias.sh | |
=== objdump | |
a.out: file format Mach-O 64-bit x86-64 | |
SYMBOL TABLE: | |
0000000100008010 l O __DATA,__data __dyld_private | |
0000000100000000 g F __TEXT,__text __mh_execute_header | |
0000000100003ef6 g F __TEXT,__text _bar | |
0000000100003ef0 g F __TEXT,__text _baz | |
0000000100003ef0 gw F __TEXT,__text _foo | |
0000000100003f00 g F __TEXT,__text _main | |
0000000000000000 *UND* _printf | |
0000000000000000 *UND* dyld_stub_binder | |
Disassembly of section __TEXT,__text: | |
0000000100003ef0 _foo: | |
100003ef0: b8 14 00 00 00 movl $20, %eax | |
100003ef5: c3 retq | |
0000000100003ef6 _bar: | |
100003ef6: b8 1e 00 00 00 movl $30, %eax | |
100003efb: c3 retq | |
100003efc: 90 nop | |
100003efd: 90 nop | |
100003efe: 90 nop | |
100003eff: 90 nop | |
0000000100003f00 _main: | |
100003f00: 55 pushq %rbp | |
100003f01: 48 89 e5 movq %rsp, %rbp | |
100003f04: 48 83 ec 10 subq $16, %rsp | |
100003f08: c7 45 fc 00 00 00 00 movl $0, -4(%rbp) | |
100003f0f: e8 4e 00 00 00 callq 78 <dyld_stub_binder+0x100003f62> | |
100003f14: 48 8d 3d 6f 00 00 00 leaq 111(%rip), %rdi | |
100003f1b: 89 c6 movl %eax, %esi | |
100003f1d: b0 00 movb $0, %al | |
100003f1f: e8 44 00 00 00 callq 68 <dyld_stub_binder+0x100003f68> | |
100003f24: 89 45 f8 movl %eax, -8(%rbp) | |
100003f27: e8 ca ff ff ff callq -54 <_bar> | |
100003f2c: 48 8d 3d 5f 00 00 00 leaq 95(%rip), %rdi | |
100003f33: 89 c6 movl %eax, %esi | |
100003f35: b0 00 movb $0, %al | |
100003f37: e8 2c 00 00 00 callq 44 <dyld_stub_binder+0x100003f68> | |
100003f3c: 89 45 f4 movl %eax, -12(%rbp) | |
100003f3f: e8 ac ff ff ff callq -84 <_foo> | |
100003f44: 48 8d 3d 4f 00 00 00 leaq 79(%rip), %rdi | |
100003f4b: 89 c6 movl %eax, %esi | |
100003f4d: b0 00 movb $0, %al | |
100003f4f: e8 14 00 00 00 callq 20 <dyld_stub_binder+0x100003f68> | |
100003f54: 31 c9 xorl %ecx, %ecx | |
100003f56: 89 45 f0 movl %eax, -16(%rbp) | |
100003f59: 89 c8 movl %ecx, %eax | |
100003f5b: 48 83 c4 10 addq $16, %rsp | |
100003f5f: 5d popq %rbp | |
100003f60: c3 retq | |
Disassembly of section __TEXT,__stubs: | |
0000000100003f62 __stubs: | |
100003f62: ff 25 98 40 00 00 jmpq *16536(%rip) | |
100003f68: ff 25 9a 40 00 00 jmpq *16538(%rip) | |
Disassembly of section __TEXT,__stub_helper: | |
0000000100003f70 __stub_helper: | |
100003f70: 4c 8d 1d 99 40 00 00 leaq 16537(%rip), %r11 | |
100003f77: 41 53 pushq %r11 | |
100003f79: ff 25 81 00 00 00 jmpq *129(%rip) | |
100003f7f: 90 nop | |
100003f80: 68 00 00 00 00 pushq $0 | |
100003f85: e9 e6 ff ff ff jmp -26 <__stub_helper> | |
=== Program output | |
foo=20 | |
bar=30 | |
baz=20 | |
$ ./weak-to-nonweak-alias.sh | |
=== objdump | |
a.out: file format Mach-O 64-bit x86-64 | |
SYMBOL TABLE: | |
0000000100008008 l O __DATA,__data __dyld_private | |
0000000100000000 g F __TEXT,__text __mh_execute_header | |
0000000100003f06 g F __TEXT,__text _bar | |
0000000100003f00 g F __TEXT,__text _baz | |
0000000100003f00 g F __TEXT,__text _foo | |
0000000100003f10 g F __TEXT,__text _main | |
0000000000000000 *UND* _printf | |
0000000000000000 *UND* dyld_stub_binder | |
Disassembly of section __TEXT,__text: | |
0000000100003f00 _foo: | |
100003f00: b8 14 00 00 00 movl $20, %eax | |
100003f05: c3 retq | |
0000000100003f06 _bar: | |
100003f06: b8 1e 00 00 00 movl $30, %eax | |
100003f0b: c3 retq | |
100003f0c: 90 nop | |
100003f0d: 90 nop | |
100003f0e: 90 nop | |
100003f0f: 90 nop | |
0000000100003f10 _main: | |
100003f10: 55 pushq %rbp | |
100003f11: 48 89 e5 movq %rsp, %rbp | |
100003f14: 48 83 ec 10 subq $16, %rsp | |
100003f18: c7 45 fc 00 00 00 00 movl $0, -4(%rbp) | |
100003f1f: e8 dc ff ff ff callq -36 <_foo> | |
100003f24: 48 8d 3d 67 00 00 00 leaq 103(%rip), %rdi | |
100003f2b: 89 c6 movl %eax, %esi | |
100003f2d: b0 00 movb $0, %al | |
100003f2f: e8 3e 00 00 00 callq 62 <dyld_stub_binder+0x100003f72> | |
100003f34: 89 45 f8 movl %eax, -8(%rbp) | |
100003f37: e8 ca ff ff ff callq -54 <_bar> | |
100003f3c: 48 8d 3d 57 00 00 00 leaq 87(%rip), %rdi | |
100003f43: 89 c6 movl %eax, %esi | |
100003f45: b0 00 movb $0, %al | |
100003f47: e8 26 00 00 00 callq 38 <dyld_stub_binder+0x100003f72> | |
100003f4c: 89 45 f4 movl %eax, -12(%rbp) | |
100003f4f: e8 ac ff ff ff callq -84 <_foo> | |
100003f54: 48 8d 3d 47 00 00 00 leaq 71(%rip), %rdi | |
100003f5b: 89 c6 movl %eax, %esi | |
100003f5d: b0 00 movb $0, %al | |
100003f5f: e8 0e 00 00 00 callq 14 <dyld_stub_binder+0x100003f72> | |
100003f64: 31 c9 xorl %ecx, %ecx | |
100003f66: 89 45 f0 movl %eax, -16(%rbp) | |
100003f69: 89 c8 movl %ecx, %eax | |
100003f6b: 48 83 c4 10 addq $16, %rsp | |
100003f6f: 5d popq %rbp | |
100003f70: c3 retq | |
Disassembly of section __TEXT,__stubs: | |
0000000100003f72 __stubs: | |
100003f72: ff 25 88 40 00 00 jmpq *16520(%rip) | |
Disassembly of section __TEXT,__stub_helper: | |
0000000100003f78 __stub_helper: | |
100003f78: 4c 8d 1d 89 40 00 00 leaq 16521(%rip), %r11 | |
100003f7f: 41 53 pushq %r11 | |
100003f81: ff 25 79 00 00 00 jmpq *121(%rip) | |
100003f87: 90 nop | |
100003f88: 68 00 00 00 00 pushq $0 | |
100003f8d: e9 e6 ff ff ff jmp -26 <__stub_helper> | |
=== Program output | |
foo=20 | |
bar=30 | |
baz=20 |
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
#!/bin/bash -e | |
cat >test1.s <<EOF | |
.text | |
.globl _foo | |
.globl _bar | |
.weak_definition _bar | |
_foo: | |
_bar: | |
movl \$10, %eax | |
retq | |
.globl _baz | |
_baz: | |
movl \$20, %eax | |
retq | |
EOF | |
cat >test2.s <<EOF | |
.globl _bar | |
_bar: | |
movl \$30, %eax | |
retq | |
EOF | |
cat >main.c <<EOF | |
#include <stdio.h> | |
int foo(void); | |
int bar(void); | |
int baz(void); | |
int main() { | |
printf("foo=%d\n", foo()); | |
printf("bar=%d\n", bar()); | |
printf("baz=%d\n", baz()); | |
return 0; | |
} | |
EOF | |
clang test1.s test2.s main.c | |
echo '' | |
echo === objdump | |
objdump -td a.out | |
echo '' | |
echo === Program output | |
./a.out |
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
#!/bin/bash -e | |
cat >test1.s <<EOF | |
.text | |
.globl _foo | |
.weak_definition _foo | |
_foo: | |
movl \$10, %eax | |
retq | |
.globl _bar | |
_bar = _foo | |
.globl _baz | |
_baz: | |
movl \$20, %eax | |
retq | |
EOF | |
cat >test2.s <<EOF | |
.globl _bar | |
_bar: | |
movl \$30, %eax | |
retq | |
EOF | |
cat >main.c <<EOF | |
#include <stdio.h> | |
int foo(void); | |
int bar(void); | |
int baz(void); | |
int main() { | |
printf("foo=%d\n", foo()); | |
printf("bar=%d\n", bar()); | |
printf("baz=%d\n", baz()); | |
return 0; | |
} | |
EOF | |
clang test1.s test2.s main.c | |
echo '' | |
echo === objdump | |
objdump -td a.out | |
echo '' | |
echo === Program output | |
./a.out |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment