7.5-Symbols_and-Symbol_Tables

각각의 Relocatable Object Module 에는 Symbol Table 이 존재한다.
이 테이블은 해당 Module 에서 정의되고 참조되는 Symbols 에 대한 정보가 포함되어있다.
Linker 의 관점에서는 3가지의 서로 다른 형태가 존재한다.

이하에서 살펴볼 특정 Relocatbale Object Module 1개를 "m" 이라고 지칭한다.


  • m에 의해 정의되어있지만, 다른 module 에서 사용가능하다.
    Global Linker Symbol 은 C언어에서 nonstatic function 과 전역변수에 대응된다.

  • Global Symbol 의 일종이나, 다른 module 에 의해 정의되어 있으며, m은 참조하는 경우이다. 이는 C언어에서 다른 module 에 정의된 nonstaic function 과 전역변수에 대응된다.

  • module m 에서 정의되며, m에서만 참조되는 경우이다.
    이는 C언어의 static function 과 static 으로 정의된 전역변수에 해당한다.
    이 Symbols 는 오직 m에서만 참조 가능하다.

Local Linker Symbols 는 Local Program Variables 와 동일하지 않다.
.symtab 에 있는 Symbol Table 은 local nonstatic program variable 을 가지고 있지 않다.
nonstatic program variable 은 run-time 시, stack 에 의해 관리되며, Linker 의 관심사가 아니다.

그러나 반대로, static 이 붙은 지역변수는 stack 이 아닌 .data 나 .bss 에 공간을 할당한다.
즉 Symbol Table에 들어가기 때문에 각 이름은 Unique 하다.

	int f() {
		static int x = 0;
		return x;
	}

	int g() {
		static int x = 1;
		return x;
	}

위의 두 함수에 정의된 x 는 Symbol Table에 저장되는데, 이름을 구별하기 위해, 컴파일러가 임의로 이름을 변경한다. 예컨데, x.1, x.2 등등으로 변경하여 어셈블러에게 전달한다.

컴파일러에 의해 얻은 .s 파일(어셈블리어 파일)을 이용해 에셈블러는 Symbol Table 을 만든다.
ELF Symbol Table 은 .symtab 영역에 포함되어있다.
Table 은 아래의 entries 배열을 가지며, 각 entry 는 아래와 같은 구조이다.
articles/chapter7/imgs/ELF_Symbol_Table.png
name 은 String Table에서 이름에 해당하는 Symbol 까지의 거리이다.
String Table(.strtab 의 경우) 각 Symbol에 해당하는 이름이 담겨있다.

value 는 Symbol의 주소로,
relocatable 일 때는 Obj가 정의된 Section 의 시작점으로부터의 거리(offset)이며,
executable 일 때는 run-time의 실제 주소이다.(absolute run-time address).

type 은 일반적으로는 data 혹은 function이다.
그러나, Symbol Table 은 각 section 에 대한 entry 나,
원본 소스코드에 대한 경로(Ex. src/foo.c)에 대한 enrty 또한 가진다.

각 Symbol 은 특정 Section 에 존재하는데, 해당하는 Section 의 index 가 section 에 표현되어있다.

section header table 에 entry 가 없는 특별한 3개의 Pseudosections 가 있다.


  • 위치가 바뀌면 안되는(not be relocated) Symbol 이 저장되어있다.

  • 정의되지 않은 Symbol 이 저장되어 있다.
    즉, 이 Obj 에서 참조되지만, 다른 곳에 정의되어있는 Symbol이다.

  • 할당되지 않은 초기화되지 않은 데이터 객체에 대한 Symbol 이 저장되어있다.
    여기에 저장되어 있는 Symbol 의 value 는 alignment requirement 가 담겨있다.
    이는, 어떤 배수의 주소에 놔야하는지를 나타내는 값이다.
    size 는 최소 사이즈를 나타낸다.
    이 pseudoSection은 Relocatable 에서만 존재한다. executable 에서는 존재하지 않는다.

COMMON 과 .bss 그 차이가 미묘하다.
최신 GCC 는 아래의 관례를 따라 할당한다.

  • : Uninitialized gloabal variables
  • : uninitailized static variables, gloabal or static variables that initialized to zero
    위의 관례는 linker 가 symbol resolution 을 하는 과정에 그 뿌리를 두고 있다.(Ch7.6에서 살펴본다.)

GCC의 READELF 는 obj 파일의 내용을 볼 수 있는 도구이다.