에듀테크 프로젝트 대시보드
링커와 로더
소스 파일 하나하나는 따로 컴파일되어 목적 파일(.o)이 된다. 이때 다른 파일에 있는 함수·변수의 주소는 아직 알 수 없어 빈칸(????)으로 남는다. 링커는 이 조각들을 이어 붙이고(섹션 병합), 빈칸의 정체를 찾아내고(심볼 해석), 실제 주소로 메워 넣는다(재배치). 로더는 완성된 파일을 메모리에 올려 프로세스로 실행한다.
전처리 → 컴파일 → 어셈블 → 링크 → 로드. 앞 세 단계는 파일마다 독립적이고, 링크에서 처음으로 모든 조각이 만난다.
main.o 는 add() 와 PI 를 쓰지만 정의하지 않는다(UND).
math.o 가 그것들을 정의한다. 링커가 어떻게 연결하는지 버튼으로 따라가 보자.
라이브러리(예: libm, libc) 코드를 실행 파일 안에 복사할지,
실행 시점에 공유 라이브러리에서 빌려 쓸지의 선택.
printf 코드 대신 PLT 스텁만 있고,
실제 주소는 GOT 테이블에 저장된다. 처음 호출 때 딱 한 번만 해석하는 지연 바인딩을 눌러 보자.
printf 주소를 찾고 그 값을 GOT에 덮어쓴다.
두 번째 호출부터는 PLT → GOT(해결됨) → printf 로 곧장 점프한다.
프로그램이 실제로 안 부르는 함수는 영영 해석되지 않아 시작이 빠르다. (LD_BIND_NOW=1 로 끌 수 있음)
| gcc -c main.c | 목적 파일 main.o 만 생성 (링크 안 함) |
| nm main.o | 심볼 목록 — T=정의된 텍스트, U=미해결(undefined) |
| readelf -r main.o | 재배치 항목 표: 어떤 오프셋을 어떤 심볼로 메울지 |
| ld / gcc main.o math.o | 실제 링크 — 여기서 undefined reference 오류가 남 |
| ldd a.out | 이 실행 파일이 실행 시 필요로 하는 .so 목록 |
| gcc -static | 정적 링킹 — 라이브러리를 바이너리에 포함 |
| LD_LIBRARY_PATH=… | 동적 링커가 .so 를 찾는 경로 추가 |