전공/시스템프로그래밍

[13] Linking

vss121 2022. 12. 4. 16:28

Program Translation

 

간단한 방법으로 한 번에 translate하지 않음

○ 문제 :

Efficiency : small change requires complete recompilation 

Modularity : hard to share common functions (e.g. printf) 

 해결 : 

(Static) linker

 

● 

오브젝트 파일 : 기계어로 번역된 상태

relocatable : address가 정해지지 않아서 나중에 정함

 

Compiler driver /coordinates /all steps in the translation and linking process

- Typically included with each compilation system (gcc) : gcc는 a.c -> a.o

• Invokes preprocessor (cpp) - #define AA 100 등 컴파일 들어가기 전 매크로 선언 해결,

compiler (cc1) - 어셈블리언어로,

assembler (as) - 어셈블러를 바이너리 오브젝트 코드로,

and linker (ld)

• Passes command line arguments to appropriate phases

• Example: create executable p from main.c and swap.c

$ gcc -O2 -v -o p main.c swap.c			// gcc -v 옵션 
cpp [args] main.c /tmp/main.i	// [cpp] main.c -> main.i
cc -S /tmp/main.i -O2 [args] -o /tmp/main.s	// [cc] main.i -> main.s
as [args] -o /tmp/main.o /tmp/main.s	// [as] main.s -> main.o 오브젝트코드
<similar process for swap.c>
ld -o p [system obj files] /tmp/main.o /tmp/swap.o	// [ld] 링킹하여 p라는 실행파일
$

 

 

 

Linker

링커 사용 이유? 1. Modularity, 2. Efficiency in time, 3. Efficiency in space

어떤 기능을 하는 함수를 만들었으면 별도의 소스코드 파일로 만들어서 관리

시간적인 측면에서도 (컴파일 시간 등), 메모리에 올라오는 공간

 

 

링커가 하는 일

 Merges object files

: Multiple relocatable (.o) object files -> a single executable object file that can be loaded and executed by the loader

 Resolves external references 외부 references를 해결, 빈칸으로 놔둔

: External reference: reference to a symbol defined in another object file

 Relocates symbols address 정해서 재배치

: Relocates symbols from their relative locations in the .o files to new absolute positions in the executable

- Updates all references to these symbols to reflect their new positions

- References can be in either code or data:

· code: func(); // reference to symbol func

· data: int *xp = &x; // reference to symbol x

여러 개의 relocatable한 오브젝트 파일들을 하나로 묶는 일, 묶는 과정에서 external reference 해결, address 정함, 해결이 안됐던 symbol의 address 정함, elf 포맷 사용

 

ELF : Executable and Linkable Format

Standard library format for object files

a.c에서 a.o로 오브젝트 파일 만들어낼 때 정해진 포맷으로

• Derived from AT&T System V Unix
- Later adopted by BSD Unix variants and Linux
• One unified format for
- Relocatable object files (.o) [예: a.o, b.o] - Executable object files [예: p] - Shared object files (.so) [예: c.so]
• Generic name: ELF binaries 

• Better support for shared libraries than old a.out formats

 

 

>> ELF object file format
• ELF header
- Magic number (\177ELF), type (.o, exec, .so), machine(CPU의 종류), byte ordering, etc.
• Program header table
- Page size, virtual addresses memory segments (sections), segment sizes(뒤에 나오는 거 정보)
• .text section
- Code 코드가 바이너리 형태로 빌드돼서 들어감
• .data section초기화된
- Initialized (static) data 초기화된 글로벌, 스태틱 변수
• .bss section초기화되지않은
- Uninitialized (static) data  - Better for space saving - Has section header but occupies no space

• .symtab section
- Symbol table - Procedures 함수이름 and static variable names - Section names and locations
• .rel.text section
- Relocation info for .text section - Addresses of instructions that will need to be modified in the executable - Instructions for modifying
• .rel.data section
- Relocation info for .data section
- Addresses of pointer data that will need to be modified in the merged executable
• .debug section
- Info for symbolic debugging (gcc -g)

 

프로그램이 돌아가기 시작하면 .text segment로 address가 정해짐

process가 되면 disk에 있던 p가 메모리로 올라옴

각각은 address가 정해짐

 

 

Linking Example
// m.c
int e=7;	// local symbol e의 정의
int main() { 
int r = a();	// a는 external symbol
exit(0);	// exit은 external symbol (libc.so에 정의됨)
}
// a.c 입장에서
extern int e;
int *ep=&e;		// e는 external symbol, local symbol ep 정의
int x=15;	// local symbol x 정의 (초기화됨)
int y;	// local symbol y 정의  (초기화되지않음)
int a() { 	// local symbol a의 정의
  return *ep+x+y;	
}

Relocating symbols and resolving external references
• Symbols are lexical entities that name functions and variables 

• Each symbol has a value (typically a memory address) /int k=0; 했을 때 k는메모리에서 address

• Code consists of symbol definitions and references 

• References는 local 아니면 external 그 파일 내에 선언되었냐 vs 아니냐

local symbol은 위치를 확정할 수 있음, external symobl은 해결이 안되어서 나중에 최종 linking할 때 해결을 해줌

 

 

m.c 파일 컴파일하여 m.o object file

// readelf -r m.o
m.o의 내용이 어떻게 되어있는지 binary 어셈블러로 보여줌

Disassembly of section .text:

00000000 <main>:
0: 55 				pushl %ebp 
1: 89 e5 			movl %esp,%ebp 
3: e8 fc ff ff ff 		call 4 <main+0x4>	//main함수 0번지 시작, 4번지에 a함수	// e8은 opcode
8: 6a 00			pushl $0x0	// argument 넣음
a: e8 f5 ff ff ff 		call b <main+0xb>	// b에 exit함수
f: 90 nop

Disassembly of section .data:	// Initialized (static) data 
00000000 <e>:
0: 07 00 00 00	// 7이라는 값이 little endian으로

Relocation section [.rel.text]:
00000004 R_386_PC32 a 
0000000b R_386_PC32 exit

왜 ff ff ff fc가 4??

Disassembly of section .text:
00000000 <a>:
0: 55 						pushl %ebp 
1: 8b 15 00 00 00 00 				movl 0x0,%edx 	// ep를 edx에, edx=0, 무슨 값인지 몰라서
7: a1 00 00 00 00 				movl 0x0,%eax	// eax(x)=0
c: 89 e5 					movl %esp,%ebp 
e: 03 02 					addl (%edx),%eax 
10: 89 ec 					movl %ebp,%esp 
12: 03 05 00 00 00 00 				addl 0x0,%eax 	// y
18: 5d 						popl %ebp 
19: c3 						ret
Disassembly of section .data:
00000000 <ep>:
0: 00 00 00 00 
00000004 <x>:
4: 0f 00 00 00
Relocation section [.rel.data]:
00000000 R_386_32 e

m.o와 a.o는 결정되지 못 한게 많음, 일단 비워둔 상태로 코드 만듦

 

 

** Merging relocatable object files into an executable object file /ELF포맷으로

** After relocation and external reference resolution

08048530 <main>:
8048530: 55                            pushl %ebp 

8048531: 89 e5                       movl %esp,%ebp 

8048533: e8 08 00 00 00        call 8048540 <a>       // 8048538(다음주소) + 8 은 8048540

8048538: 6a 00                       pushl $0x0 

804853a: e8 35 ff ff ff              call 8048474 <_init+0x94>        // 나중에 shared library로 돌아감

804853f: 90 nop


08048540 <a>:
8048540: 55                          pushl %ebp 

8048541: 8b 15 1c a0 04 08 movl 0x804a01c,%edx        // edx는 ep, ep주소는 804a01c

8048547: a1 20 a0 04 08       movl 0x804a020,%eax         // eax는 x, x주소 804a020, x는 초기화된 global 변수

804854c: 89 e5                      movl %esp,%ebp         //

804854e: 03 02                    addl (%edx),%eax 

8048550: 89 ec                      movl %ebp,%esp 

8048552: 03 05 d0 a3 04 08 addl 0x804a3d0,%eax         // y는 초기화되지 않아서 쓰레기값 적힘, eax를 리턴

8048558: 5d                          popl %ebp 

8048559: c3                          ret

ep는 e의주소 pointing중, e는 7, x는 15

채우진 못 한 부분 채움, linker의 역할, p실행 가능

 

 

Symbol Resolution

Program symbols are either strong or weak
• Strong symbols: procedures 함수이름 and initialized globals  초기화된 global변수

• Weak symbols: uninitialized globals

 

Linker's symbol rules
• Rule 1:
A strong symbol can only appear once

어느 파일에 f1() {  }, 다른 파일에 f1() 안됨
• Rule 2:
A weak symbol can be overridden by a strong symbol of the same name

하나는 foo=5, 하나는 foo이면 왼쪽이 덮어씀
• Rule 3:
If there are multiple weak symbols, the linker can pick an arbitrary one

하나 foo 다른 거 foo 아무거나

 

예제>

 

 

Static Libraries

• How to package functions commonly used by programmers?
- Math, I/O, memory management, string manipulation, etc.
• Option 1: Put all functions in a single source file
- Programmers link big object file into their programs - Space and time inefficient

[print.c, scanf.c]를 lib.c로 만들어 lib.o를 같이 링킹함
• Option 2: Put each function in a separate source file
- Programmers explicitly link appropriate binaries into their programs - More efficient, but burdensome on the programmer

print.o, scanf.o 따로 만들어서 쓴 함수만 같이 링킹함, 귀찮음

 

Solution: Static libraries (.a archive files)

관련있는 relocatable object files을 하나의 파일로 합침 with an index (called an archive)

해결하지 못한 external references을 아카이브에서 찾아 linker 향상시킴

If an archive member file resolves reference, link into executable
Further improves modularity and efficiency by packaging commonly used functions
- e.g. C standard library (libc), math library (libm), etc.

 

 

Archiver (ar) allows incremental updates:
- Recompile function that changes and replace .o file in archive

링커가 libc.a를 뒤져서 필요한 것만 끄집어냄

 

• libc.a (C standard library)
- 8MB archive of 900 object files  900개의 function
- I/O, memory allocation, signal handling, string handling, data and time, random numbers, integer math, etc.
• libm.a (C math library)
- 1MB archive of 226 object files - Floating point math (sin, cos, tan, log, exp, sqrt, etc.)

 

 

external references를 해결하는 링커의 알고리즘

- Scan .o files and .a files in the command line order 어떤 순서로 order을 주어야하는가

 - During the scan, keep a list of unresolved references - As each new .o or .a file is encountered, try to resolve each unresolved reference in the list against the symbols in the object file - If any entries in the unresolved list at end of scan, then error
• Problem: command line order matters!
- Moral: put libraries at the end of the command line

 

libtest.o에는 main함수도 들어있고, lmine.a라는 라이브러리에 libfun라는 함수 정의

main.c에서 libfun부를때

 

bass> gcc -L. -lmine libtest.o   // 오류, libfun이 해결이 되지않은 상태

libtest.o: In function `main':
libtest.o(.text+0x4): undefined reference to `libfun'


bass> gcc -L. libtest.o -lmine  // libtest의 libfun을 나중에 해결하려, lmine에서 찾음

 

 

 

 

Shared Libraries

Static libraries의 단점

- 한 executable 파일에 공통된 코드 복사 가능성

• Potential for duplicating lots of code in the virtual memory space of many processes
• Minor bug fixes of system libraries require each application to explicitly relink

 

Solution: shared libraries
• Dynamic link libraries or DLLs 

• Members are dynamically loaded into memory and linked into an application at run-time 런타임에

• Dynamic linking can occur ...
- When executable is first loaded and run - Common case for Linux, handled automatically by ld-linux.so - Also after program has begun
· In Linux, this is done explicitly by user with dlopen()
• Shared library routines can be shared by multiple processes

 

[.Text]에서 printf.o[DLL]를 부를 때 링킹해서 해결

DLL영역은 똑같이 매핑. 메모리 중복해서 사용x 같은 특정한 메모리 영역에 올려놓음

 

Shared가 더 좋음

 

 

링커가 static하게 링크, p생성, libc.so와 링킹되어 p'생성

 

'전공 > 시스템프로그래밍' 카테고리의 다른 글

[12] BufferOverflow  (0) 2022.12.07
두번째 과제  (0) 2022.11.05
[09] ASM2 : Control Flow  (1) 2022.10.28
[04] Floating Point  (0) 2022.10.28
[03-3] Integer(정수) / Representing and Manipulating Integers  (0) 2022.10.28