엄범


gcc

공유 라이브러리 제작 / 사용 옵션

```
-fPIC
```
PIC : Position-Independent Code를 생성한다.
shared library같은 경우 메모리의 어느 위치에 로딩되는지가 컴파일 타임에 결정되지 않기 때문에 절대주소 대신 상대주소(offset)를 사용하도록 컴파일하는 옵션이다. 
즉, 다른 바이너리에서 이 라이브러리의 함수를 호출할 때 PLT와 GOT를 사용하도록 하는 옵션이라고 생각하면 된다.
library의 mapping 주소 + offset이 해당 symbol의 주소가 된다. 
mapping 주소는 ldd로, offset은 nm으로 확인 가능하다.

```
-shared
```
shared library(.so)를 생성하겠다는 의미.

```
-llibrary
```
library는 함수 이름이 아니라 파일 이름이다.
파일 이름이 liblibrary.so 이면, 앞의 lib와 뒤의 .so를 제거하고 `` -llibrary``와 같이 사용한다.
Search the library named library when linking.
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. 
`` -l`` 옵션은 해당 라이브러리를 호출하는 파일 뒤에 위치해야 하며 `` -L`` 옵션 앞에 위치해야 한다.
그래야 library를 찾을 dir을 먼저 읽고, library를 읽은 다음 파일에서 라이브러리를 호출하게 된다.

```
-Ldir
```
Add directory dir to the list of directories to be searched for `` -l.`` 
standard system directories 이외에 추가로 `` -l`` 옵션의 library를 찾을 directory를 지정하기 위해 사용한다.

동적 라이브러리를 사용하기 위한 옵션

```
-ldl
```
사실 `` -llibrary`` 옵션인데, `` library``에 `` dl``이 들어간 것.
``c dlopen()`` 사용하려면 꼭 써줘야한다.
`` -ldl`` 옵션이 로딩하는 `` libdl.so``에 ``c dlopen()``이 있기 때문. 

```
-rdynamic
```
Pass the flag -export-dynamic to the ELF linker, on targets that support it. 
링커에게 `` -export-dynamic``을 넘기는 것이므로 `` -Wl,-export-dynamic``과 동일하다.
링커가 dynamic symbol table에 모든 symbol을 추가하도록 하는 옵션이다.
dlopen man page에는 쓰라고 나오던데, `` -ldl``만 써도 되길래 그냥 안썼다. 써본 적이 없다.

공유 라이브러리 컴파일 command

공유 라이브러리를 컴파일
```bash
gcc -shared -fPIC -o lib.o lib.c [-llibrary -Ldir]
```
라이브러리를 사용할 파일과 라이브러리 파일 모두 header파일을 include해야하며, header파일 없으면 컴파일 시 오류난다.

공유 라이브러리를 사용하는 실행파일 컴파일
```bash
gcc -o out out.c -llibrary -Ldir
```

동적 라이브러리를 사용하는 실행파일 컴파일
```bash
gcc -o out out.c -ldl
```

쉘코드 관련 옵션

`` -S``         Compile only; do not assemble or link
어셈블리 파일(.s)을 생성하는 옵션.     2016/12/10 - [System/etc] - .s 파일 수정
``c __volatile__``을 사용했다면 어셈블리야 굳이 .s 생성할 필요 없이 gdb로 확인해도 된다.

`` -static``
static으로 컴파일하면 PLT, GOT 사용 안하고 바로 call libcaddr한다. 
dynamic linking 사용 안하기 때문에 라이브러리 종속성을 제거할 수 있다.

```
gcc -c -o sum.o sum.cpp
```
컴파일만 하고 링크는 진행하지 말라고 알려주는 옵션이 `` -c``
object 파일(.o)이 생성된다.
object 파일을 생성하고 링크를 나중에 진행하는 경우는 프로그램이 여러 소스파일로 이루어진 경우다.
그냥 컴파일 하게 되면 ``bash gcc -o main main.c f2.c f3.c`` 같이 입력하게 될텐데, `` main, f2, f3``이 한꺼번에 컴파일된다. 따라서 그 중 한 파일이라도 소스코드가 변경되었다면 이런 방법으로는 모두 재컴파일 해야한다.
그러나 `` -c``옵션을 이용해 ``bash gcc -c main; gcc -c f2; gcc -c f2`` 해서 object파일을 만들어 놓으면 소스코드가 변경되는 경우 변경된 파일만 재컴파일 후 링크만 진행하면 된다.

gcc compile process



`` -c`` 옵션으로 생성되는 Object 파일은 .s파일을 어셈블러가 해석해서 만든 기계어 코드다. linking이 안되어 있기 때문에 주소 정보가 확정되어있지 않은 상태다.

object 파일을 실행 파일로 링크할 때 symbol 정보를 사용한다. 따라서 symbol 정보는 링크가 끝나면 필요없어진다.

디버거에게 추가적인 정보를 제공하지 않기 위해 링커에 옵션을 지정해 빌드 시 symbol information을 삭제할 수 있다. 또는 빌드 이후 strip tool을 이용해 삭제하는 방법도 있다.