- 링커에 대한 발표자료는 Keynote에.
- Keynote에 없는 Selectview Loading에 관한 시뮬레이션은 아래 정리하여 올립니다
- 시뮬레이션은 키노트를 학습 후 보는 걸 추천드립니다 ✨
- main.c, muldiv.c, addsub.c 3개의 소스코드가 있다.
// main.c 파일입니다.
#include <stdio.h>
#include "addsub.h"
int main()
{
printf("add: %d\n", add(3,3));
printf("sub: %d\n", sub(3,3));
return 0;
}
// muldiv.c 파일입니다.
#include "muldiv.h"
int mul(int a, int b) {
return a * b;
}
int div(int a, int b) {
return a / b;
}
// addsub.c 파일입니다.
#include "addsub.h"
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
main.c
안에서 쓰는 코드는 add함수과 sub함수 두가지로muldiv.c
파일을 사실상 쓰이지 않는 코드.muldiv.c
,addsub.c
를 합쳐libmint.a
라는Static Library
로 만들어 main 실행파일을 만든다.Selective Loading
이 사실이라면 main mach-O파일에 쓰이지 않는muldiv.o
목적파일은 로드되지 않을 것.
- 우선은
gcc main.c -lmint -o main -L.
로 일반적인 Static Library로 만들어본다. - 그리고 main의 mach-O 파일의 _TEXT를 출력결과
main: file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000100003ecc <_main>:
100003ecc: d100c3ff sub sp, sp, #48
100003ed0: a9027bfd stp x29, x30, [sp, #32]
100003ed4: 910083fd add x29, sp, #32
100003ed8: 52800008 mov w8, #0
100003edc: b81f83a8 stur w8, [x29, #-8]
100003ee0: b81fc3bf stur wzr, [x29, #-4]
100003ee4: 52800061 mov w1, #3
100003ee8: b81f43a1 stur w1, [x29, #-12]
100003eec: aa0103e0 mov x0, x1
100003ef0: 94000014 bl 0x100003f40 <_add>
100003ef4: 910003e9 mov x9, sp
100003ef8: aa0003e8 mov x8, x0
100003efc: f9000128 str x8, [x9]
100003f00: 90000000 adrp x0, 0x100003000 <_main+0x34>
100003f04: 913e3000 add x0, x0, #3980
100003f08: 9400001e bl 0x100003f80 <_printf+0x100003f80>
100003f0c: b85f43a1 ldur w1, [x29, #-12]
100003f10: aa0103e0 mov x0, x1
100003f14: 94000013 bl 0x100003f60 <_sub>
100003f18: 910003e9 mov x9, sp
100003f1c: aa0003e8 mov x8, x0
100003f20: f9000128 str x8, [x9]
100003f24: 90000000 adrp x0, 0x100003000 <_main+0x58>
100003f28: 913e5400 add x0, x0, #3989
100003f2c: 94000015 bl 0x100003f80 <_printf+0x100003f80>
100003f30: b85f83a0 ldur w0, [x29, #-8]
100003f34: a9427bfd ldp x29, x30, [sp, #32]
100003f38: 9100c3ff add sp, sp, #48
100003f3c: d65f03c0 ret
0000000100003f40 <_add>:
100003f40: d10043ff sub sp, sp, #16
100003f44: b9000fe0 str w0, [sp, #12]
100003f48: b9000be1 str w1, [sp, #8]
100003f4c: b9400fe8 ldr w8, [sp, #12]
100003f50: b9400be9 ldr w9, [sp, #8]
100003f54: 0b090100 add w0, w8, w9
100003f58: 910043ff add sp, sp, #16
100003f5c: d65f03c0 ret
0000000100003f60 <_sub>:
100003f60: d10043ff sub sp, sp, #16
100003f64: b9000fe0 str w0, [sp, #12]
100003f68: b9000be1 str w1, [sp, #8]
100003f6c: b9400fe8 ldr w8, [sp, #12]
100003f70: b9400be9 ldr w9, [sp, #8]
100003f74: 6b090100 subs w0, w8, w9
100003f78: 910043ff add sp, sp, #16
100003f7c: d65f03c0 ret
Disassembly of section __TEXT,__stubs:
0000000100003f80 <__stubs>:
100003f80: b0000010 adrp x16, 0x100004000 <__stubs+0x4>
100003f84: f9400210 ldr x16, [x16]
100003f88: d61f0200 br x16
- libmint mach-O 파일의 _TEXT를 출력해본다.
libmint.a(muldiv.o): file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000000000000 <ltmp0>:
0: d10043ff sub sp, sp, #16
4: b9000fe0 str w0, [sp, #12]
8: b9000be1 str w1, [sp, #8]
c: b9400fe8 ldr w8, [sp, #12]
10: b9400be9 ldr w9, [sp, #8]
14: 1b097d00 mul w0, w8, w9
18: 910043ff add sp, sp, #16
1c: d65f03c0 ret
0000000000000020 <_div>:
20: d10043ff sub sp, sp, #16
24: b9000fe0 str w0, [sp, #12]
28: b9000be1 str w1, [sp, #8]
2c: b9400fe8 ldr w8, [sp, #12]
30: b9400be9 ldr w9, [sp, #8]
34: 1ac90d00 sdiv w0, w8, w9
38: 910043ff add sp, sp, #16
3c: d65f03c0 ret
libmint.a(addsub.o): file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000000000000 <ltmp0>:
0: d10043ff sub sp, sp, #16
4: b9000fe0 str w0, [sp, #12]
8: b9000be1 str w1, [sp, #8]
c: b9400fe8 ldr w8, [sp, #12]
10: b9400be9 ldr w9, [sp, #8]
14: 0b090100 add w0, w8, w9
18: 910043ff add sp, sp, #16
1c: d65f03c0 ret
0000000000000020 <_sub>:
20: d10043ff sub sp, sp, #16
24: b9000fe0 str w0, [sp, #12]
28: b9000be1 str w1, [sp, #8]
2c: b9400fe8 ldr w8, [sp, #12]
30: b9400be9 ldr w9, [sp, #8]
34: 6b090100 subs w0, w8, w9
38: 910043ff add sp, sp, #16
3c: d65f03c0 ret
- Selective Loading되어 main 실행파일에는 mulsub.o에 대한 소스코드가 포함되지 않음을 확인하였다 💡
- 다음은
-all_load
옵션을 주고 Static Library로 만들어본다. - main의 mach-O 파일의 _TEXT를 출력결과
main: file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000100003e8c <_main>:
100003e8c: d100c3ff sub sp, sp, #48
100003e90: a9027bfd stp x29, x30, [sp, #32]
100003e94: 910083fd add x29, sp, #32
100003e98: 52800008 mov w8, #0
100003e9c: b81f83a8 stur w8, [x29, #-8]
100003ea0: b81fc3bf stur wzr, [x29, #-4]
100003ea4: 52800061 mov w1, #3
100003ea8: b81f43a1 stur w1, [x29, #-12]
100003eac: aa0103e0 mov x0, x1
100003eb0: 94000024 bl 0x100003f40 <_add>
100003eb4: 910003e9 mov x9, sp
100003eb8: aa0003e8 mov x8, x0
100003ebc: f9000128 str x8, [x9]
100003ec0: 90000000 adrp x0, 0x100003000 <_main+0x34>
100003ec4: 913e3000 add x0, x0, #3980
100003ec8: 9400002e bl 0x100003f80 <_printf+0x100003f80>
100003ecc: b85f43a1 ldur w1, [x29, #-12]
100003ed0: aa0103e0 mov x0, x1
100003ed4: 94000023 bl 0x100003f60 <_sub>
100003ed8: 910003e9 mov x9, sp
100003edc: aa0003e8 mov x8, x0
100003ee0: f9000128 str x8, [x9]
100003ee4: 90000000 adrp x0, 0x100003000 <_main+0x58>
100003ee8: 913e5400 add x0, x0, #3989
100003eec: 94000025 bl 0x100003f80 <_printf+0x100003f80>
100003ef0: b85f83a0 ldur w0, [x29, #-8]
100003ef4: a9427bfd ldp x29, x30, [sp, #32]
100003ef8: 9100c3ff add sp, sp, #48
100003efc: d65f03c0 ret
0000000100003f00 <_mul>:
100003f00: d10043ff sub sp, sp, #16
100003f04: b9000fe0 str w0, [sp, #12]
100003f08: b9000be1 str w1, [sp, #8]
100003f0c: b9400fe8 ldr w8, [sp, #12]
100003f10: b9400be9 ldr w9, [sp, #8]
100003f14: 1b097d00 mul w0, w8, w9
100003f18: 910043ff add sp, sp, #16
100003f1c: d65f03c0 ret
0000000100003f20 <_div>:
100003f20: d10043ff sub sp, sp, #16
100003f24: b9000fe0 str w0, [sp, #12]
100003f28: b9000be1 str w1, [sp, #8]
100003f2c: b9400fe8 ldr w8, [sp, #12]
100003f30: b9400be9 ldr w9, [sp, #8]
100003f34: 1ac90d00 sdiv w0, w8, w9
100003f38: 910043ff add sp, sp, #16
100003f3c: d65f03c0 ret
0000000100003f40 <_add>:
100003f40: d10043ff sub sp, sp, #16
100003f44: b9000fe0 str w0, [sp, #12]
100003f48: b9000be1 str w1, [sp, #8]
100003f4c: b9400fe8 ldr w8, [sp, #12]
100003f50: b9400be9 ldr w9, [sp, #8]
100003f54: 0b090100 add w0, w8, w9
100003f58: 910043ff add sp, sp, #16
100003f5c: d65f03c0 ret
0000000100003f60 <_sub>:
100003f60: d10043ff sub sp, sp, #16
100003f64: b9000fe0 str w0, [sp, #12]
100003f68: b9000be1 str w1, [sp, #8]
100003f6c: b9400fe8 ldr w8, [sp, #12]
100003f70: b9400be9 ldr w9, [sp, #8]
100003f74: 6b090100 subs w0, w8, w9
100003f78: 910043ff add sp, sp, #16
100003f7c: d65f03c0 ret
Disassembly of section __TEXT,__stubs:
0000000100003f80 <__stubs>:
100003f80: b0000010 adrp x16, 0x100004000 <__stubs+0x4>
100003f84: f9400210 ldr x16, [x16]
100003f88: d61f0200 br x16
- libmint mach-O 파일의 _TEXT를 출력해본다.
libmint.a(muldiv.o): file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000000000000 <ltmp0>:
0: d10043ff sub sp, sp, #16
4: b9000fe0 str w0, [sp, #12]
8: b9000be1 str w1, [sp, #8]
c: b9400fe8 ldr w8, [sp, #12]
10: b9400be9 ldr w9, [sp, #8]
14: 1b097d00 mul w0, w8, w9
18: 910043ff add sp, sp, #16
1c: d65f03c0 ret
0000000000000020 <_div>:
20: d10043ff sub sp, sp, #16
24: b9000fe0 str w0, [sp, #12]
28: b9000be1 str w1, [sp, #8]
2c: b9400fe8 ldr w8, [sp, #12]
30: b9400be9 ldr w9, [sp, #8]
34: 1ac90d00 sdiv w0, w8, w9
38: 910043ff add sp, sp, #16
3c: d65f03c0 ret
libmint.a(addsub.o): file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000000000000 <ltmp0>:
0: d10043ff sub sp, sp, #16
4: b9000fe0 str w0, [sp, #12]
8: b9000be1 str w1, [sp, #8]
c: b9400fe8 ldr w8, [sp, #12]
10: b9400be9 ldr w9, [sp, #8]
14: 0b090100 add w0, w8, w9
18: 910043ff add sp, sp, #16
1c: d65f03c0 ret
0000000000000020 <_sub>:
20: d10043ff sub sp, sp, #16
24: b9000fe0 str w0, [sp, #12]
28: b9000be1 str w1, [sp, #8]
2c: b9400fe8 ldr w8, [sp, #12]
30: b9400be9 ldr w9, [sp, #8]
34: 6b090100 subs w0, w8, w9
38: 910043ff add sp, sp, #16
3c: d65f03c0 ret
-all_load
시addsub.o
,muldiv.o
둘다 잘 아카이브되었음을 확인.
- 질문으로 들어온 내용이였다.
- 당시 발표대는 해본적은 없지만 dead_code_stripping이 더 마지막 단계에서 일어나는 연산이라
- 아마 안쓰는 심볼에 대한 내용은 삭제될거라 답은 했었는데, 발표 후에 한번 해보았다.
gcc -o main main.o -Wl,-all_load,libmint.a -Wl,-dead_strip
: -all_load 옵션에 dead_code_stripping 까지 적용하여 아카이브- main 실행파일의 _TEXT출력결과
main: file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000100003ecc <_main>:
100003ecc: d100c3ff sub sp, sp, #48
100003ed0: a9027bfd stp x29, x30, [sp, #32]
100003ed4: 910083fd add x29, sp, #32
100003ed8: 52800008 mov w8, #0
100003edc: b81f83a8 stur w8, [x29, #-8]
100003ee0: b81fc3bf stur wzr, [x29, #-4]
100003ee4: 52800061 mov w1, #3
100003ee8: b81f43a1 stur w1, [x29, #-12]
100003eec: aa0103e0 mov x0, x1
100003ef0: 94000014 bl 0x100003f40 <_add>
100003ef4: 910003e9 mov x9, sp
100003ef8: aa0003e8 mov x8, x0
100003efc: f9000128 str x8, [x9]
100003f00: 90000000 adrp x0, 0x100003000 <_main+0x34>
100003f04: 913e3000 add x0, x0, #3980
100003f08: 9400001e bl 0x100003f80 <_printf+0x100003f80>
100003f0c: b85f43a1 ldur w1, [x29, #-12]
100003f10: aa0103e0 mov x0, x1
100003f14: 94000013 bl 0x100003f60 <_sub>
100003f18: 910003e9 mov x9, sp
100003f1c: aa0003e8 mov x8, x0
100003f20: f9000128 str x8, [x9]
100003f24: 90000000 adrp x0, 0x100003000 <_main+0x58>
100003f28: 913e5400 add x0, x0, #3989
100003f2c: 94000015 bl 0x100003f80 <_printf+0x100003f80>
100003f30: b85f83a0 ldur w0, [x29, #-8]
100003f34: a9427bfd ldp x29, x30, [sp, #32]
100003f38: 9100c3ff add sp, sp, #48
100003f3c: d65f03c0 ret
0000000100003f40 <_add>:
100003f40: d10043ff sub sp, sp, #16
100003f44: b9000fe0 str w0, [sp, #12]
100003f48: b9000be1 str w1, [sp, #8]
100003f4c: b9400fe8 ldr w8, [sp, #12]
100003f50: b9400be9 ldr w9, [sp, #8]
100003f54: 0b090100 add w0, w8, w9
100003f58: 910043ff add sp, sp, #16
100003f5c: d65f03c0 ret
0000000100003f60 <_sub>:
100003f60: d10043ff sub sp, sp, #16
100003f64: b9000fe0 str w0, [sp, #12]
100003f68: b9000be1 str w1, [sp, #8]
100003f6c: b9400fe8 ldr w8, [sp, #12]
100003f70: b9400be9 ldr w9, [sp, #8]
100003f74: 6b090100 subs w0, w8, w9
100003f78: 910043ff add sp, sp, #16
100003f7c: d65f03c0 ret
Disassembly of section __TEXT,__stubs:
0000000100003f80 <__stubs>:
100003f80: b0000010 adrp x16, 0x100004000 <__stubs+0x4>
100003f84: f9400210 ldr x16, [x16]
100003f88: d61f0200 br x16
- 예상대로 안쓰는 mul, sub에 대한 코드는 제거된 _TEXT의 결과임을 확인.
- 하지만, 찾아본바로는 _all_load, dead_code_stripping은 결국 상반되는 행위라서 꼭 필요한지 확인하고 해야함..
- 더 복잡한 코드에서는 예상만큼 성능이 괜찮고 안전하진 않음.