Post

gcc options

gcc

공유 라이브러리 제작 / 사용 옵션
1
2
-fPIC

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

1
2
-shared

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

1
2
-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를 읽은 다음 파일에서 라이브러리를 호출하게 된다.

1
2
-Ldir

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

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

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

1
2
-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

공유 라이브러리를 컴파일

1
2
gcc -shared -fPIC -o lib.o lib.c [-llibrary -Ldir]

라이브러리를 사용할 파일과 라이브러리 파일 모두 header파일을 include해야하며, header파일 없으면 컴파일 시 오류난다.

공유 라이브러리를 사용하는 실행파일 컴파일

1
2
gcc -o out out.c -llibrary -Ldir

동적 라이브러리를 사용하는 실행파일 컴파일

1
2
gcc -o out out.c -ldl

쉘코드 관련 옵션

-S Compile only; do not assemble or link 어셈블리 파일(.s)을 생성하는 옵션.2016/12/10 - [System/etc] - .s 파일 수정 \_\_volatile\_\_을 사용했다면 어셈블리야 굳이 .s 생성할 필요 없이 gdb로 확인해도 된다. -static static으로 컴파일하면 PLT, GOT 사용 안하고 바로 call libcaddr한다. dynamic linking 사용 안하기 때문에 라이브러리 종속성을 제거할 수 있다.

1
2
gcc -c -o sum.o sum.cpp

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

gcc compile process

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

object 파일을 실행 파일로 링크할 때 symbol 정보를 사용한다. 따라서 symbol 정보는 링크가 끝나면 필요없어진다. 디버거에게 추가적인 정보를 제공하지 않기 위해 링커에 옵션을 지정해 빌드 시 symbol information을 삭제할 수 있다. 또는 빌드 이후 strip tool을 이용해 삭제하는 방법도 있다.

This post is licensed under CC BY 4.0 by the author.