PLT(Procedure Linkage Table) : 외부 프로시저를 연결해주는 테이블. PLT를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있다

GOT(Global Offset Table) : PLT가 참조하는 테이블. 프로시저들의 주소가 들어있다


PLT와 GOT를 사용하는 이유 | Linker

어떤 코드(printf)가 쓰여있는 소스파일을 실행파일로 만들기 위해서는 컴파일이라는 과정을 거쳐야 한다. 컴파일을 통해 오브젝트 파일이 생성된다. 하지만 오브젝트 파일을그 자체로 실행하지 못하고 오브젝트 파일과 printf의 실행 코드를 찾아서 서로 연결시켜야 한다. 이런 오브젝트 파일들이 모여있는 곳을 라이브러리(Library)라고 한다. 이렇게 라이브러리 등 필요한 오브젝트 파이들을 연결시키는 작업을 Linking이라고 한다.

Link를 하는 방법에는 Static과 Dynamic이 있다.

Static Link 방식은 파일 생성시 라이브러리 내용을 포함한 실행파일을 만든다.

실행 파일 안에 모든 코드가 포함되기 때문에 라이브러리 연동 과정이 따로 필요 없고, 한번 생성한 파일에 대해서 필요한 라이브러리를 따로 관리하지 않아도 되기 때문에 편하지만 파일 크키가 커지는 단점이 있다. 또한 동일한 라이브러리를 사용하더라도 해당 라이브러리를 사용하는 모든 프로그래들은 라이브러리의 내용을 메모리에 매핑 시켜야 한다

Dynamic Link 방식은 공유라이브러리를 사용한다. 라이브러리를 하나의 메모리 공간에 매핑하고 여러 프로그램에서 공유하여 사용하는 것이다.

실행파일 안에 라이브러리 코드를 포함하지 않기 때문에 파일 크기도 작아지고 실행시 적은 메모리를 차지한다. 그러나 실행파일이 라이브러리에 의존하기 때문에 라이브러리가 없으면 실행할 수 없다.


PLT와 GOT는 Dynamic Link 방식으로 컴파일 했을때 사용되는데 그 이유는 라이브러리가 프로그램 외부에 있기 때문에 함수의 주소를 알아오는 과정이 필요하기 때문이다.


Dynamic Link 방식으로 프로그램이 만들어지면 함수를 호출 할 때 PLT를 참조하게 된다. PLT는 GOT로 점프를 하고 GOT에는 라이브러에 존재하는 실제 함수의 주소가 쓰여있어서 printf 함수를 호출하게 된다. 

여기서 첫 호출인지 아닌지에 따라 동작 과정이 조금 달라진다.

첫 번째 호출이라면 GOT에 실제 함수의 주소가 쓰여있지 않고 두번째 호출부터 GOT에 실제 함수의 주소가 쓰인다. 그래서 첫 호출 시에는 Linker가 dl_resolve라는 함수를 사용해 필요한 함수의 주소를 알아오고, GOT에 그 주소를 써준 후 해당 함수를 호출한다.


라이브러리란? | 라이브러니는 다른 프로그램들과 링크되기 위하여 존재하는 하나 이상의 서브루틴이나 함수들의 집합 파일 형태를 말한다. 보통 미리 컴파일된 형태인 오브젝트코드 형태로 존재한다. 라이브러리라는 기술이 생긴 이유는 코드의 재사용, 부품화 실현, 소스를 제공하지 않음으로서 중요 기술의 유출 방지, 개발자들의 개발시간 단축들의 장점이 있기 때문이다. 

라이브러리들은 사용자의 프로그램과 링크되어, 실행이 가능한 완전한 프로그램을 이룬다. 링크의 종류는 Static Link가 있고 Dynamic Link가 있다.


공유 라이브러리(.so/.sa) | 공유라이브러리를 사용하여 컴파일을 하면 링커가 실행 파일에다가 "실행될 때 우선 이 라이브러리를 로딩시킬 것"이라는 표시를 해둔다. 그리고 실행할 때 라이브러리에 있는 컴파일된 코드를 가져와 사용한다.

이렇게 하면 정적 라이브러리를 사용하는 것보다 파일 크기가 작아지고, 메모리를 적게 차지하고 메모리 사용에 효율적이다. 그러니 배포할 때 공유 라이브러리를 함께 배포해야 한다. 


공유 라이브러리 구성 | 공유 라이브러리 파일은 확장자가 파일포맷이 ELF이면 .so, a.out이면 .sa이다. (a.out은 과거 유닉스 계통 운영 체제에서 사용하던 실행 파일과 목적 파일 형식)

그리고 그 뒤에 버전 숫자가 붙는데 메이지 넘버와 마이너 넘버이다.(메이지 넘버는 라이브러리 버전들 간 잠재적 비호환성을 나타내고, 마이너 넘버는 버그 픽스들만을 나타낸다) 

Example ) 일반적으로 libexample.so 파일은 libexample.so.N에 링크되고 다시 이것은 libexample.so.N.M에 링크됨. N은 가장 높은 메이저 넘버이고, M은 가장 높은 마이너 넘버이다.


출처 : http://sens.tistory.com/33

        https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/

'@C언어 : Layer7' 카테고리의 다른 글

2018년에 한것..(?)  (0) 2018.12.24
HackerSchool FTZ 풀이  (0) 2018.06.15
Git 사용 보고서  (1) 2018.06.08
너의 타자소리가 들려  (0) 2018.05.23
구조체 예제  (0) 2018.05.15

+ Recent posts