IT_Programming/System Programming

[펌] 링커 스크립트

JJun ™ 2013. 5. 8. 12:52

 


 출처:  http://blog.naver.com/lovecid/40013285363


 

 

 

링커 스크립트

Every link is controlled by a linker script. This script is written in the linker command language.

모든 링크 과정은 링커 스크립트가 조정한다. 이 스크립트는 링커 명령 언어로 쓰여진다.

The main purpose of the linker script is to describe how the sections in the input files should be mapped into the output file, and to control the memory layout of the output file. Most linker scripts do nothing more than this. However, when necessary, the linker script can also direct the linker to perform many other operations, using the commands described below.

링커 스크립트의 주목적은 입력파일의 섹션이 어떻게 출력파일로 대응하는지와 출력파일의 메모리 상태를 어떻게 조정하는지를 지정하는 것이다. 대부분 링커 스크립트는 이것으로 충분하다. 그러나 필요하다는 아래 명령어들을 사용하여 링커에 다른 작업을 지시할 수도 있다.

The linker always uses a linker script. If you do not supply one yourself, the linker will use a default script that is compiled into the linker executable. You can use the `--verbose' command line option to display the default linker script. Certain command line options, such as `-r' or `-N', will affect the default linker script.

링커는 항상 링커 스크립트를 사용한다. 직접 제공하지 않으면 링커는 링커 실행파일에 컴파일된 기본 스크립트를 사용한다. `--verbose' 옵션을 사용하여 기본 링커 스크립트를 볼 수 있다. `-r'`-N' 같은 옵션으로 기본 링커 스크립트에 영향을 줄 수 있다.

 

You may supply your own linker script by using the `-T' command line option. When you do this, your linker script will replace the default linker script.

`-T' 옵션으로 자신의 링커 스크립트을 사용할 수 있다. 이 옵션을 사용하면 이 스크립트가 기본 링커 스크립트를 대체한다.

You may also use linker scripts implicitly by naming them as input files to the linker, as though they were files to be linked. See section Implicit Linker Scripts.

또 링커 스크립트를 링크될 파일은 아니지만 링커에 입력파일로 사용할 수도 있다. Implicit Linker Scripts를 참조하라.

 

 

링커 스크립트 기본 개념

We need to define some basic concepts and vocabulary in order to describe the linker script language.

링커 스크립트 언어를 설명하기 위해서 기본 개념과 단어를 설명해야 한다.

 

The linker combines input files into a single output file. The output file and each input file are in a special data format known as an object file format. Each file is called an object file. The output file is often called an executable, but for our purposes we will also call it an object file. Each object file has, among other things, a list of sections. We sometimes refer to a section in an input file as an input section; similarly, a section in the output file is an output section.
링커는 입력파일을 합쳐서 하나의 출력파일을 만든다. 출력파일과 각 입력파일은 오브젝트 파일 형식이라는 특수한 형식으로 쓰여진다. 각 파일을 오브젝트 파일이라 한다. 출력 파일이 종종 실행파일이라고도 불리지만 이도 또한 오브젝트 파일이라 부를 것이다. 각 오브젝트 파일은 우선 섹션 목록을 포함한다. 입력파일의 섹션을 입력 섹션이라고 한다. 비슷하게 출력파일의 섹션을 출력 섹션이라 한다.

 

Each section in an object file has a name and a size. Most sections also have an associated block of data, known as the section contents. A section may be marked as loadable, which mean that the contents should be loaded into memory when the output file is run. A section with no contents may be allocatable, which means that an area in memory should be set aside, but nothing in particular should be loaded there (in some cases this memory must be zeroed out). A section which is neither loadable nor allocatable typically contains some sort of debugging information.

오브젝트 파일의 각 섹션의 이름과 크기를 가진다. 섹션은 대부분 섹션 내용이라는 연관된 자료를 가진다. 로드가능한 표시가 된 섹션은 출력파일이 실행될 때 그 내용이 메모리로 읽혀져야한다는 것을 의미한다. 내용이 없는 섹션도 할당가능할 수 있다. 다른 말로 메모리의 일부가 할당되지만 특별히 어떤 것도 그곳에 읽혀지지 않을 수 있다. (보통 이 메모리는 0으로 채워진다.) 로드가능하지도 할당가능하지도 않은 섹션은 보통 일종의 디버그 정보를 가진다.

Every loadable or allocatable output section has two addresses. The first is the VMA, or virtual memory address. This is the address the section will have when the output file is run. The second is the LMA, or load memory address. This is the address at which the section will be loaded. In most cases the two addresses will be the same. An example of when they might be different is when a data section is loaded into ROM, and then copied into RAM when the program starts up (this technique is often used to initialize global variables in a ROM based system). In this case the ROM address would be the LMA, and the RAM address would be the VMA.

모든 로드가능하고 할당가능한 출력 섹션은 두 주소를 가진다. 첫째는 가상 메모리 주소(virtual memory address)인 VMA이다. 이는 출력파일이 실행될 때 섹션이 위치하는 주소이다. 두번째는 로드 메모리 주소(load memory address)인 LMA이다. 대부분 이 두 주소는 같다. 다른 경우의 예는 프로그램이 시작될 때 자료 섹션을 ROM에서 읽어서 RAM에 복사하는 경우이다. (이 기법은 ROM 기반 시스템에서 전역 변수를 초기화하기 위해 사용된다.) 이 경우 ROM 주소가 LMA이고, RAM 주소가 VMA이 된다.

You can see the sections in an object file by using the objdump program with the `-h' option.

objdump 프로그램의 `-h' 옵션으로 오브젝트 파일의 섹션을 확인할 수 있다.

 

Every object file also has a list of symbols, known as the symbol table. A symbol may be defined or undefined. Each symbol has a name, and each defined symbol has an address, among other information. If you compile a C or C++ program into an object file, you will get a defined symbol for every defined function and global or static variable. Every undefined function or global variable which is referenced in the input file will become an undefined symbol.

모든 오브젝트 파일은 또한 심볼표라는 심볼 목록을 가진다. 심볼은 정의되거나 정의되지 않을 수 있다. 각 심볼은 우선 이름을 가지고, 정의된 심볼은 주소를 가진다. C나 C++ 프로그램을 오브젝트 파일로 컴파일하면 모든 정의된 함수와 전역 또는 정적 변수의 정의된 심볼을 얻는다. 입력파일에서 참조하는 모든 정의되지 않은 함수나 전역 변수는 정의되지 않은 심볼이 된다.

 

You can see the symbols in an object file by using the nm program, or by using the objdump program with the `-t' option.

오브젝트 파일의 심볼들을 nm 프로그램이나, objdump 프로그램의 `-t' 옵션으로 볼 수 있다.

 

링커 스크립트 형식

Linker scripts are text files.

링커 스크립트는 일반 텍스트 파일이다.

 

You write a linker script as a series of commands. Each command is either a keyword, possibly followed by arguments, or an assignment to a symbol. You may separate commands using semicolons. Whitespace is generally ignored.

스크립트는 일련의 명령어로 이루어져 있다. 각 명령어는 키워드로 뒤에 아규먼트를 가지거나, 심볼에 할당될 수 있다. `;'으로 각 명령어를 구분한다. 공백은 일반적으로 무시된다.

 

Strings such as file or format names can normally be entered directly. If the file name contains a character such as a comma which would otherwise serve to separate file names, you may put the file name in double quotes. There is no way to use a double quote character in a file name.

파일이나 형식 이름과 같은 문자열은 보통 직접 입력한다. 파일명이 보통 파일명을 구분하는 `,' 같은 문자를 포함한다면 파일명을 쌍따옴표 안에 두어라. 파일명에 쌍따옴표를 사용할 수 없다.

 

You may include comments in linker scripts just as in C, delimited by `/*' and `*/'. As in C, comments are syntactically equivalent to whitespace.

링커 스크립트에 C와 같이 `/*'`*/'로 둘려싸인 주석을 포함할 수 있다. C와 같이, 주석은 공백과 같이 취급된다.

 

 

링커 스크립트의 간단한 예

Many linker scripts are fairly simple.

많은 링커 스크립트는 매우 간단하다.

The simplest possible linker script has just one command: `SECTIONS'. You use the `SECTIONS' command to describe the memory layout of the output file.

가장 간단한 링커 스크립트는 `SECTIONS'이라는 단 하나의 명령어를 가진다. `SECTIONS' 명령어는 출력파일의 메모리 구조를 기술한다.

 

The `SECTIONS' command is a powerful command. Here we will describe a simple use of it. Let's assume your program consists only of code, initialized data, and uninitialized data. These will be in the `.text', `.data', and `.bss' sections, respectively. Let's assume further that these are the only sections which appear in your input files.

`SECTIONS' 명령어는 강력한 명령어다. 여기서는 간단한 사용을 보여준다. 프로그램이 코드, 초기화된 자료, 초기화되지 않은 자료로만 이루어진다고 가정하자. 이는 각각 `.text', `.data', `.bss' 섹션이다. 또, 입력파일에 이 섹션들만 나온다고 가정하자.

For this example, let's say that the code should be loaded at address 0x10000, and that the data should start at address 0x8000000. Here is a linker script which will do that:

이 예에서 코드가 주소 0x10000에 로드되고 자료는 0x8000000에서 시작한다고 하자. 다음은 이에 대한 링커 스크립트이다.

SECTIONS
{
  . = 0x10000;
  .text : { *(.text) }
  . = 0x8000000;
  .data : { *(.data) }
  .bss : { *(.bss) }
}

You write the `SECTIONS' command as the keyword `SECTIONS', followed by a series of symbol assignments and output section descriptions enclosed in curly braces.

`SECTIONS' 명령어는 `SECTIONS' 키워드 다음에 대괄호로 묶인 일련의 심볼 할당과 출력 섹션 명이 나온다.

The first line inside the `SECTIONS' command of the above example sets the value of the special symbol `.', which is the location counter. If you do not specify the address of an output section in some other way (other ways are described later), the address is set from the current value of the location counter. The location counter is then incremented by the size of the output section. At the start of the `SECTIONS' command, the location counter has the value `0'.

위의 예에서 `SECTIONS' 명령어 안의 첫 줄은 위치 카운터인 특별 심볼 `.'의 값을 설정한다. (아래에서 설명할) 다른 방법으로 출력 섹션의 주소를 설정하지 않으면 위치 카운터의 현재 값이 사용된다. 위치 카운터는 출력 섹션의 크기만큼 증가한다. `SECTIONS' 명령 처음에는 위치 카운터는 `0'이다.

 

The second line defines an output section, `.text'. The colon is required syntax which may be ignored for now. Within the curly braces after the output section name, you list the names of the input sections which should be placed into this output section. The `*' is a wildcard which matches any file name. The expression `*(.text)' means all `.text' input sections in all input files.

두번째 줄은 출력 섹션 `.text'을 정의한다. `:'은 현재는 넘어가지만 필요하다. 그 뒤에 나오는 대괄호 안에 출력 섹션에 추가할 입력 섹션 이름을 열거한다. The `*'는 어떤 파일명에도 대응한다. `*(.text)'는 모든 입력파일의 모든 입력 섹션 `.text'을 의미한다.

Since the location counter is `0x10000' when the output section `.text' is defined, the linker will set the address of the `.text' section in the output file to be `0x10000'.

출력 섹션 `.text'이 정의될 때 위치 카운터가 `0x10000'이므로 링커는 출력파일에서 `.text' 섹션의 주소를 `0x10000'로 한다.

 

The remaining lines define the `.data' and `.bss' sections in the output file. The linker will place the `.data' output section at address `0x8000000'. After the linker places the `.data' output section, the value of the location counter will be `0x8000000' plus the size of the `.data' output section. The effect is that the linker will place the `.bss' output section immediately after the `.data' output section in memory

나머지 줄은 출력파일의 `.data', `.bss' 섹션을 정의한다. 링커는 출력 섹션 `.data'을 주소 `0x8000000'에 위치한다. 그 후 위치 카운터는 `0x8000000' 더하기 출력 섹션 `.data'의 크기가 된다. 그 결과 링커는 출력 섹션 `.bss'을 메모리에서 출력 섹션 `.data' 바로 뒤에 위치시킨다.

 

The linker will ensure that each output section has the required alignment, by increasing the location counter if necessary. In this example, the specified addresses for the `.text' and `.data' sections will probably satisfy any alignment constraints, but the linker may have to create a small gap between the `.data' and `.bss' sections.

링커는 필요하다면 위치 카운터를 증가하여 각 출력 섹션이 올바로 정렬되게 한다. 이 경우 `.text' 섹션과 `.data' 셕션의 지정된 주소는 어떤 정렬 제약에도 만족할 것이다. 그러나 `.data'`.bss' 사이에 작은 공간이 빌 것이다.

That's it! That's a simple and complete linker script.

이게 모두다! 완전하고 간단한 링커 스크립트이다.

 

 

간단한 링커 스크립트 명령어

In this section we describe the simple linker script commands.

여기서 간단한 링커 스크립트 명령을 설명한다.

진입점을 설정하기

The first instruction to execute in a program is called the entry point. You can use the ENTRY linker script command to set the entry point. The argument is a symbol name:

프로그램에서 처음으로 실행되는 명령이 진입점이다. ENTRY 명령어로 진입점을 설정한다. 아규먼트는 심볼이름이다.

ENTRY(symbol)

There are several ways to set the entry point. The linker will set the entry point by trying each of the following methods in order, and stopping when one of them succeeds:

  • the `-e' entry command-line option;
  • the ENTRY(symbol) command in a linker script;
  • the value of the symbol start, if defined;
  • the address of the first byte of the `.text' section, if present;
  • The address 0.

 

진입점을 설정하는 방법은 많다. 링커는 다음 방법을 성공할 때까지 순서대로 시도한다.

  • `-e' entry 옵션
  • 링커 스크립트의 ENTRY(symbol) 명령어
  • start 심볼이 정의되있다면 심볼 값
  • `.text' 섹션이 있다면 첫 바이트 주소
  • 주소 0

 

 


파일을 다루는 명령어

 

Several linker script commands deal with files.

많은 링커 스크립트 명령어는 파일을 다룬다.

INCLUDE filename
Include the linker script filename at this point. The file will be searched for in the current directory, and in any directory specified with the -L option. You can nest calls to INCLUDE up to 10 levels deep.
이 지점에서 링커 스크립트 filename를 포함한다. 파일은 현재 디렉토리와 -L 옵션으로 주어진 디렉토리에서 검색한다. INCLUDE를 10 단계까지 사용할 수 있다.
INPUT(file, file, ...)
INPUT(file file ...)
The INPUT command directs the linker to include the named files in the link, as though they were named on the command line. For example, if you always want to include `subr.o' any time you do a link, but you can't be bothered to put it on every link command line, then you can put `INPUT (subr.o)' in your linker script. In fact, if you like, you can list all of your input files in the linker script, and then invoke the linker with nothing but a `-T' option. The linker will first try to open the file in the current directory. If it is not found, the linker will search through the archive library search path. See the description of `-L' in section Command Line Options. If you use `INPUT (-lfile)', ld will transform the name to libfile.a, as with the command line argument `-l'. When you use the INPUT command in an implicit linker script, the files will be included in the link at the point at which the linker script file is included. This can affect archive searching.
INPUT 명령어는 링커가 파일들을 마치 명령행에 있는 것 처럼 포함하게 한다. 예를 들면 링크할 때마다 `subr.o'를 포함하고 싶다면, 매번 명령행에 이를 적어주지 않고 링크 스크립트에 `INPUT (subr.o)'를 포함하면 된다. 원한다면 모든 입력파일을 링커 스크립트에 적어주고 아무것도 없이 `-T' 옵션만으로 링커를 실행해도 된다. 링커는 먼저 현재 디렉토리에서 파일을 찾으려 시도한다. 발견되지 않으면 링커는 아카이브 라이브러리 검색 패스에서 검색한다. Command Line Options`-L' 옵션 설명을 참조하라. `INPUT (-lfile)'을 사용하면 명령행 옵션 `-l'과 같이 libfile.a를 찾는다. INPUT 명령어를 사용하면 링커 스크립트가 포함된는 시점에서 파일을 링크에 포함한다. 이는 아카이브 검색에 영향을 준다.
GROUP(file, file, ...)
GROUP(file file ...)
The GROUP command is like INPUT, except that the named files should all be archives, and they are searched repeatedly until no new undefined references are created. See the description of `-(' in section Command Line Options.
GROUP 명령어는 INPUT와 같지만, 파일이 모두 아카이브 파일이어야 하며, 정의되지 않은 참조가 새로 만들어지지 않을 때까지 반복해서 검색된다. Command Line Options`-(' 옵션 설명을 참고하라.
OUTPUT(filename)
The OUTPUT command names the output file. Using OUTPUT(filename) in the linker script is exactly like using `-o filename' on the command line (see section Command Line Options). If both are used, the command line option takes precedence. You can use the OUTPUT command to define a default name for the output file other than the usual default of `a.out'.
OUTPUT 명령어는 출력파일의 이름을 지정한다. 링커 스크립트의 OUTPUT(filename)는 명령행 옵션인 (Command Line Options를 참조) `-o filename'과 동일하다. 둘 다 사용하면 명령행 옵션이 우선순위를 가진다. OUTPUT 명령어를 사용하지 않으면 기본값으로 `a.out'이 사용된다.
SEARCH_DIR(path)
The SEARCH_DIR command adds path to the list of paths where ld looks for archive libraries. Using SEARCH_DIR(path) is exactly like using `-L path' on the command line (see section Command Line Options). If both are used, then the linker will search both paths. Paths specified using the command line option are searched first.
SEARCH_DIR 명령어는 아카이브 라이브러리를 검색하는 패스에 path를 추가한다. SEARCH_DIR(path)는 명령행 옵션 (Command Line Options 참조) `-L path'와 동일하다. 둘 다 사용하면 링커는 모두를 패스에 추가한다. 명령행 옵션으로 지정된 패스가 먼저 검색된다.
STARTUP(filename)
The STARTUP command is just like the INPUT command, except that filename will become the first input file to be linked, as though it were specified first on the command line. This may be useful when using a system in which the entry point is always the start of the first file.
STARTUP 명령어는 filename이 명령행 처음에 나온 것 처럼 가장 먼저 링크하는 것을 제외하고는 INPUT 명령어와 같다. 이 명령어는 진입점이 항상 첫 파일의 시작인 시스템에서 유용하다.


오브젝트 파일 형식을 다루는 명령어

 

A couple of linker script commands deal with object file formats.

다음은 오브젝트 파일 형식을 다루는 링커 스크립트 명령어들이다.

OUTPUT_FORMAT(bfdname)
OUTPUT_FORMAT(default, big, little)
The OUTPUT_FORMAT command names the BFD format to use for the output file (see section BFD). Using OUTPUT_FORMAT(bfdname) is exactly like using `-oformat bfdname' on the command line (see section Command Line Options). If both are used, the command line option takes precedence. You can use OUTPUT_FORMAT with three arguments to use different formats based on the `-EB' and `-EL' command line options. This permits the linker script to set the output format based on the desired endianness. If neither `-EB' nor `-EL' are used, then the output format will be the first argument, default. If `-EB' is used, the output format will be the second argument, big. If `-EL' is used, the output format will be the third argument, little. For example, the default linker script for the MIPS ELF target uses this command:
OUTPUT_FORMAT 명령어는 출력파일에 사용할 BFD 형식 이름을 (BFD 참조) 지정한다. OUTPUT_FORMAT(bfdname)는 명령행 옵션 (Command Line Options 참조) `-oformat bfdname'과 동일하다. 둘 다 사용하면 명령행 옵션이 우선순위를 가진다. OUTPUT_FORMAT을 세 아규먼트와 사용하여 명령행 옵션 `-EB'`-EL'로 다른 형식을 지정할 수도 있다. 그래서 원하는 endian에 따라 출력 형식을 지정한다. `-EB'`-EL' 둘 다 사용하지 않으면 출력 형식은 첫 아규먼트인 default이다. `-EB'를 사용하면 출력 형식은 두번째 아규먼트인 big이다. `-EL'를 사용하면 출력 형식은 세번째 아규먼트인 little이다. 예를 들어 MIPS ELF의 기본 링커 스크립트는 다음 명령어를 사용한다.
OUTPUT_FORMAT(elf32-bigmips, elf32-bigmips, elf32-littlemips)
This says that the default format for the output file is `elf32-bigmips', but if the user uses the `-EL' command line option, the output file will be created in the `elf32-littlemips' format.
이는 출력파일 기본 형식으로 `elf32-bigmips'을 사용하지만, `-EL' 옵션을 사용하면 `elf32-littlemips' 형식을 사용한다.
TARGET(bfdname)
The TARGET command names the BFD format to use when reading input files. It affects subsequent INPUT and GROUP commands. This command is like using `-b bfdname' on the command line (see section Command Line Options). If the TARGET command is used but OUTPUT_FORMAT is not, then the last TARGET command is also used to set the format for the output file. See section BFD.
TARGET 명령어는 입력파일의 BFD 형식을 지정한다. 이 명령어는 뒤에 나오는 INPUTGROUP 명령어에 영향을 준다. 이 명령어는 명령행 옵션 (Command Line Options 참조) `-b bfdname'과 동일하다. OUTPUT_FORMAT을 사용하지 않고 TARGET만 사용한다면, 마지막 TARGET 명령어가 출력파일 형식도 지정한다. BFD를 참조하라.


기타 링커 스크립트 명령어들

 

There are a few other linker scripts commands.
다음은 기타 명령어들이다.

ASSERT(exp, message)
Ensure that exp is non-zero. If it is zero, then exit the linker with an error code, and print message.
exp가 0이 아닌지를 확인한다. 만약 0이라면 message를 출력하고 오류코드로 링커를 종료한다.
 
EXTERN(symbol symbol ...)
Force symbol to be entered in the output file as an undefined symbol. Doing this may, for example, trigger linking of additional modules from standard libraries. You may list several symbols for each EXTERN, and you may use EXTERN multiple times. This command has the same effect as the `-u' command-line option.
symbol을 출력파일에 정의되지 않은 심볼로 포함시킨다. 그래서 표준 라이브러리에서 추가로 모듈이 링크되게 만든다. 각 EXTERN에 여러 symbol를 열거하거나, EXTERN를 여려번 사용할 수 있다. 이 명령어는 명령행 옵션 `-u'과 동일하다.
FORCE_COMMON_ALLOCATION
This command has the same effect as the `-d' command-line option: to make ld assign space to common symbols even if a relocatable output file is specified (`-r').
이 명령어는 출력을 재배치가능하게 (`-r') 지정하였어도 공통 심볼에 공간을 할당하게하는, 명령행 옵션 `-d'과 동일하다.
NOCROSSREFS(section section ...)
This command may be used to tell ld to issue an error about any references among certain output sections. In certain types of programs, particularly on embedded systems when using overlays, when one section is loaded into memory, another section will not be. Any direct references between the two sections would be errors. For example, it would be an error if code in one section called a function defined in the other section. The NOCROSSREFS command takes a list of output section names. If ld detects any cross references between the sections, it reports an error and returns a non-zero exit status. Note that the NOCROSSREFS command uses output section names, not input section names.
이 명령어는 어떤 출력 섹션들 간의 참조를 오류로 보고한다. 오버레이를 사용하는 임베디드 시스템에서와 같이 특정 종류의 프로그램에서 한 섹션은 메모리에 로드되고, 다른 섹션은 로드안될 경우가 있다. 이 경우 두 섹션간의 직접 참조는 오류이다. 예를 들어 한 섹션이 다른 섹션에서 정의된 함수를 호출하면 오류가 발생한다. NOCROSSREFS 명령어는 출력 섹션 이름의 목록을 받는다. 이 섹션들 간의 교차참조를 발견하면 오류를 알리고 0이 아닌 오류값으로 프로그램을 종료한다. 주의! NOCROSSREFS는 입력 섹션 이름이 아니라 출력 섹션 이릉을 사용한다.
OUTPUT_ARCH(bfdarch)
Specify a particular output machine architecture. The argument is one of the names used by the BFD library (see section BFD). You can see the architecture of an object file by using the objdump program with the `-f' option.
출력 아키텍쳐를 정한다. 아규먼트는 BFD 라이브러리에서 (BFD 참조) 사용하는 이름 중 하나이다. 가능한 아키텍쳐는 objdump 프로그램의 `-f' 옵션으로 알 수 있다.


심볼에 값을 대입하기

 

You may assign a value to a symbol in a linker script. This will define the symbol as a global symbol.

링커 스크립트에서 심볼에 값을 대입할 수 있다. 그러면 심볼을 전역 심볼로 정의한다.

간단한 대입

You may assign to a symbol using any of the C assignment operators:

C 대입 연산자를 사용하여 심볼에 값을 대입한다.

symbol = expression ;
 
symbol += expression ;
symbol -= expression ;
symbol *= expression ;
symbol /= expression ;
symbol <<= expression ;
symbol >>= expression ;
symbol &= expression ;
symbol |= expression ;

The first case will define symbol to the value of expression. In the other cases, symbol must already be defined, and the value will be adjusted accordingly.

The special symbol name `.' indicates the location counter. You may only use this within a SECTIONS command. The semicolon after expression is required.

expressions are defined below; see section expressions in Linker Scripts.

첫번째 경우는 표현식 expression 값을 symbol에 대입한다. 다른 경우는 이미 정의되있는 symbol의 값을 변경한다. 특별히 `.'는 위치 카운터를 나타낸다. 위치 카운터는 SECTIONS 명령어에서 설명되었다.

expression 뒤의 `;'는 필수이다. 표현식은 expressions in Linker Scripts에서 설명된다.

 

You may write symbol assignments as commands in their own right, or as statements within a SECTIONS command, or as part of an output section description in a SECTIONS command.

The section of the symbol will be set from the section of the expression; for more information, see section The Section of an expression.

Here is an example showing the three different places that symbol assignments may be used:

심볼 대입을 SECTIONS 명령어 안에서, 혹은 SECTIONS의 출력 섹션 기술의 일부로, 아니면 별도로 사용할 수 있다. 표현식으로 섹션에 상대적인 심볼을 설정한다. 자세한 내용은 The Section of an expression을 참고하라. 아래는 심볼 대입이 사용되는 세 다른 경우의 예이다.

floating_point = 0;
SECTIONS
{
  .text :
    {
      *(.text)
      _etext = .;
    }
  _bdata = (. + 3) & ~ 4;
  .data : { *(.data) }
}

In this example, the symbol `floating_point' will be defined as zero. The symbol `_etext' will be defined as the address following the last `.text' input section. The symbol `_bdata' will be defined as the address following the `.text' output section aligned upward to a 4 byte boundary.
위에서 `floating_point' 심볼은 0으로 정의된다. `_etext' 심볼은 마지막 `.text' 입력 섹션 뒤의 주소로 정의된다. `_bdata' 심볼은 `.text' 출력 섹션 뒤에서 4 바이트 경계로 정렬된 주소로 정의된다.

PROVIDE

In some cases, it is desirable for a linker script to define a symbol only if it is referenced and is not defined by any object included in the link. For example, traditional linkers defined the symbol `etext'. However, ANSI C requires that the user be able to use `etext' as a function name without encountering an error. The PROVIDE keyword may be used to define a symbol, such as `etext', only if it is referenced but not defined. The syntax is PROVIDE(symbol = expression).

Here is an example of using PROVIDE to define `etext':

참조는 되지만 링크에 포함된 어떤 객체에서도 정의되지 않은 심볼을 정의할 필요가 있을 수 있다. 예를 들면 전통적인 링커는 심볼 `etext'를 정의한다. 그러나 ANSI C에서는 사용자가 `etext'을 함수이름으로 아무 문제없이 사용할 수 있다. 키워드 PROVIDE`etext' 같이 참조는 되지만 정의되지 않은 심볼을 정의할 때 쓰인다. 문법은 PROVIDE(symbol = expression)과 같다.

SECTIONS
{
  .text :
    {
      *(.text)
      _etext = .;
      PROVIDE(etext = .);
    }
}

In this example, if the program defines `_etext' (with a leading underscore), the linker will give a multiple definition error. If, on the other hand, the program defines `etext' (with no leading underscore), the linker will silently use the definition in the program. If the program references `etext' but does not define it, the linker will use the definition in the linker script.

이 경우 프로그램이 (`_'으로 시작하는) `_etext'을 정의하면 링커는 중복 정의 오류를 낸다. 그러나 (`_'으로 시작하지 않는) `etext'을 정의하면 링커는 프로그램의 정의를 사용한다. 프로그램이 `etext'을 정의하지 않고 참조만 한다면 링커는 링커 스크립트의 정의를 사용한다.

SECTIONS 명령어

The SECTIONS command tells the linker how to map input sections into output sections, and how to place the output sections in memory.

The format of the SECTIONS command is:

SECTIONS 명령어는 링커가 어떻게 입력 섹션을 출력 섹션으로 대응하고, 출력 섹션을 메모리에 위치하는지를 결정한다.

SECTIONS의 형식은 다음과 같다.

SECTIONS
{
  sections-command
  sections-command
  ...
}

Each sections-command may of be one of the following:

 

sections-command는 다음 중 하나이다.

The ENTRY command and symbol assignments are permitted inside the SECTIONS command for convenience in using the location counter in those commands. This can also make the linker script easier to understand because you can use those commands at meaningful points in the layout of the output file.

Output section descriptions and overlay descriptions are described below.

If you do not use a SECTIONS command in your linker script, the linker will place each input section into an identically named output section in the order that the sections are first encountered in the input files. If all input sections are present in the first file, for example, the order of sections in the output file will match the order in the first input file. The first section will be at address zero.
위치 카운터를 편리하게 사용하기 위해서 ENTRY 명령어와 심볼 대입은 SECTIONS 명령어 안에서 허용된다. 또 명령어를 의미있는 장소에 사용하여 링커 스크립트가 읽기 쉽게 된다.

출력 섹션 기술과 오버레이 기술은 아래에서 설명된다.

링커 스크립트에 SECTIONS 명령어가 없다면 링커는 입력 파일의 순서대로 각 입력 섹션을 같은 이름의 출력 섹션으로 대응시킨다. 예를 들어 첫째 파일에 모든 입력 섹션이 있다면 출력파일의 섹션 순서는 첫째 파일의 순서와 같다. 첫번째 섹션은 주소 0에서 시작한다.

 

출력 섹션 기술

The full description of an output section looks like this:

출력 섹션 기술은 다음과 같다.

section [address] [(type)] : [AT(lma)]
  {
    output-section-command
    output-section-command
    ...
  } [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp]

Most output sections do not use most of the optional section attributes.

The whitespace around section is required, so that the section name is unambiguous. The colon and the curly braces are also required. The line breaks and other white space are optional.

대부분 출력 섹션은 선택적인 섹션 속성을 사용하지 않는다.

섹션 이름을 구별하기 위해서 section 주위에 공백이 필요하다. `:'과 대괄호도 필요하다. 줄바꿈과 기타 공백은 선택적이다.

Each output-section-command may be one of the following:

 

output-section-command는 다음 중 하나이다.

 

 


출력 섹션 이름

 

 

The name of the output section is section. section must meet the constraints of your output format. In formats which only support a limited number of sections, such as a.out, the name must be one of the names supported by the format (a.out, for example, allows only `.text', `.data' or `.bss'). If the output format supports any number of sections, but with numbers and not names (as is the case for Oasys), the name should be supplied as a quoted numeric string. A section name may consist of any sequence of characters, but a name which contains any unusual characters such as commas must be quoted.

The output section name `/DISCARD/' is special; section Output section discarding.

출력 섹션 이름은 section이다. section은 출력 형식의 제약을 만족해야 한다. a.out과 같이 제한된 수의 섹션만을 지원하는 형식에서 이름은 형식이 지원하는 이름 중 하나이어야 한다. (예를 들어 a.out`.text', `.data', `.bss'만이 가능하다.) (Oasys와 같이) 섹션의 수에는 제한이 없지만 섹션 이름이 숫자이어야 하는 형식에서 이름은 따옴표로 둘러싼 숫자 문자열이어야 한다. 섹션 이름으로 어떤 문자도 가능하나 `,'와 같은 문자를 포함한 경우에는 따옴표를 해야 한다.

출력 섹션 이름으로 `/DISCARD/'은 특별하다. Output section discarding를 참고하라.

 

출력 섹션 주소

The address is an expression for the VMA (the virtual memory address) of the output section. If you do not provide address, the linker will set it based on region if present, or otherwise based on the current value of the location counter.

If you provide address, the address of the output section will be set to precisely that. If you provide neither address nor region, then the address of the output section will be set to the current value of the location counter aligned to the alignment requirements of the output section. The alignment requirement of the output section is the strictest alignment of any input section contained within the output section.

address는 출력 섹션의 VMA로 쓰일 표현식이다. address를 사용하지 않은 경우 링커는 출력 섹션의 VMA로 region이 있다면 이에 기초하여 설정하고, 그렇지 않다면 위치 카운터의 현재 값에 기초하여 결정한다.

address가 주어지면 출력 섹션 주소로 정확히 그 값을 사용한다. addressregion이 주어지지 않으면 출력 섹션 주소로 위치 카운터의 현재 값을 출력 섹션의 정렬 요구에 따라 정렬하여 사용한다. 출력 섹션의 정렬 요구는 출력 섹션에 포함된 입력 섹션 중 가장 엄격한 정렬을 따른다.

 

For example,

예를 들어,

.text . : { *(.text) }

 

.text : { *(.text) }

 

are subtly different. The first will set the address of the `.text' output section to the current value of the location counter. The second will set it to the current value of the location counter aligned to the strictest alignment of a `.text' input section.

The address may be an arbitrary expression; section expressions in Linker Scripts. For example, if you want to align the section on a 0x10 byte boundary, so that the lowest four bits of the section address are zero, you could do something like this:
는 다소 다르다. 첫번째는 `.text' 주소를 현재 위치 카운터로 설정한다. 두번째는 현재 위치 카운터를 입력 섹션 `.text'의 가장 엄격한 정렬에 정렬하여 사용한다.

address는 임의의 표현식이다. expressions in Linker Scripts를 참고하라. 예를 들어 섹션을 0x10 바이트 경계로 정렬하여 섹션 주소 하위 4 비트가 0이게 하려면 다음과 같이 하면 된다.

.text ALIGN(0x10) : { *(.text) }

This works because ALIGN returns the current location counter aligned upward to the specified value. Specifying address for a section will change the value of the location counter.

ALIGN는 현재 위치 카운터를 지정한 값으로 (큰 쪽으로) 정렬한다.

섹션의 address을 주면 위치 카운터값도 변경된다.

 

입력 섹션 기술

The most common output section command is an input section description.

The input section description is the most basic linker script operation. You use output sections to tell the linker how to lay out your program in memory. You use input section descriptions to tell the linker how to map the input files into your memory layout.

대부분의 출력 섹션 명령어는 입력 섹션 기술에도 사용된다.

입력 섹션 기술은 가장 기본적인 스크립트 기능이다. 링커에게 프로그램을 메모리에 어떻게 배치할지를 알려주기 위해서 출력 섹션을 사용한다. 링커에게 입력파일을 어떻게 메모리에 배치할지를 알려주기 위해서 입력 섹션 기술을 사용한다.

 

입력 섹션 기본

An input section description consists of a file name optionally followed by a list of section names in parentheses.

The file name and the section name may be wildcard patterns, which we describe further below (see section Input section wildcard patterns).

The most common input section description is to include all input sections with a particular name in the output section. For example, to include all input `.text' sections, you would write:

입력 섹션 기술은 파일명과 괄호안에 선택적인 섹션 이름 목록으로 이루어진다.

파일명과 섹션 이름으로 아래 (Input section wildcard patterns 참고) 설명할 와일드카드 패턴을 사용할 수 있다. 대부분 입력 섹션 기술은 모든 입력 섹션과 출력 섹션에서 사용할 이름을 포함한다. 예를 들어 모든 입력 섹션 `.text'을 포함하려면,

*(.text)

Here the `*' is a wildcard which matches any file name. To exclude a list of files from matching the file name wildcard, EXCLUDE_FILE may be used to match all files except the ones specified in the EXCLUDE_FILE list. For example:
여기서 `*'는 어떤 파일명에도 대응하는 와일드카드이다. 특정 목록의 파일을 제외하고 모든 파일에 대응하기 위해서 EXCLUDE_FILE를 사용한다. 예를 들면,

(*(EXCLUDE_FILE (*crtend.o *otherfile.o) .ctors))

 

will cause all .ctors sections from all files except `crtend.o' and `otherfile.o' to be included.

There are two ways to include more than one section:

`crtend.o'`otherfile.o'가 포함되지 않은 모든 파일에서 모든 .ctors 섹션을 포함한다.

한 섹션 이상을 포함하는 방법은 두가지가 있다.

*(.text .rdata)
*(.text) *(.rdata)

The difference between these is the order in which the `.text' and `.rdata' input sections will appear in the output section. In the first example, they will be intermingled. In the second example, all `.text' input sections will appear first, followed by all `.rdata' input sections.

You can specify a file name to include sections from a particular file. You would do this if one or more of your files contain special data that needs to be at a particular location in memory. For example:

위의 차이는 입력 섹션 `.text'`.rdata'이 출력 섹션에 나타날 순서이다. 두번째 예에서 모든 `.text' 입력 섹션이 먼저 나오고, 그 뒤에 모든 `.rdata' 입력 섹션이 위치한다.

data.o(.data)

If you use a file name without a list of sections, then all sections in the input file will be included in the output section. This is not commonly done, but it may by useful on occasion. For example:

섹션 목록 없이 파일명을 사용하면 입력파일에 있는 모든 섹션이 출력 섹션에 포함된다. 이는 흔한 경우는 아니지만 때로는 유용할 수 있다. 예를 들면,

data.o

 

When you use a file name which does not contain any wild card characters, the linker will first see if you also specified the file name on the linker command line or in an INPUT command. If you did not, the linker will attempt to open the file as an input file, as though it appeared on the command line. Note that this differs from an INPUT command, because the linker will not search for the file in the archive search path.
와일드카드를 사용하지 않고 파일명을 주면 링커는 먼저 명령행이나 INPUT 명령어에 파일명이 있는지 확안한다. 그렇지 않으면 링커는 마치 명령행에 있었던 것 처럼 입력파일로 취급한다. 주의! 이는 링커가 아카이브 검색 패스에서 파일을 찾지 않기 때문에 INPUT 명령어와 다르다.

 

 

입력 섹션 와일드카드 패턴

In an input section description, either the file name or the section name or both may be wildcard patterns. The file name of `*' seen in many examples is a simple wildcard pattern for the file name.

The wildcard patterns are like those used by the Unix shell.

입력 섹션 기술에서 파일명이나 섹션 이름에 와일드카드 섹션을 사용할 수 있다.

많은 예에서 파일명으로 `*'를 사용한 것이 간단한 와일드카드 패턴의 예이다.

와일드카드 패턴은 유닉스 쉘에서 사용하는 것과 동일하다.

`*'
matches any number of characters
`?'
matches any single character
`[chars]'
matches a single instance of any of the chars; the `-' character may be used to specify a range of characters, as in `[a-z]' to match any lower case letter
`\'
quotes the following character
 

 

`*'
어떤 문자들과도 대응한다
`?'
어떤 한 문자와 대응한다
`[chars]'
chars 중 한 문자와 대응한다. `-' 문자는 문자들의 범위를 나타낸다. 그래서 `[a-z]'는 어떤 한 소문자와 대응한다.
`\'
다음 문자를 그대로 사용한다

 

When a file name is matched with a wildcard, the wildcard characters will not match a `/' character (used to separate directory names on Unix). A pattern consisting of a single `*' character is an exception; it will always match any file name, whether it contains a `/' or not. In a section name, the wildcard characters will match a `/' character.

File name wildcard patterns only match files which are explicitly specified on the command line or in an INPUT command. The linker does not search directories to expand wildcards.

파일명에 사용한 와일드카드 문자는 (유닉스에서 디렉토리 이름을 구분하는데 사용하는) `/' 문자와 대응하지 않는다. 한 `*'로만 이루어진 패턴은 예외이다. 이는 `/'이 포함된 것과 관계없이 어떤 파일명에도 대응한다. 섹션 이름으로 사용한 와일드카드 문자도 `/'를 포함한다.

파일명 와일드카드 패턴은 명령행이나 INPUT 명령어에 직접 주어진 파일에만 대응한다. 링커는 와일드카드 때문에 디렉토리를 검색하지 않는다.

If a file name matches more than one wildcard pattern, or if a file name appears explicitly and is also matched by a wildcard pattern, the linker will use the first match in the linker script. For example, this sequence of input section descriptions is probably in error, because the `data.o' rule will not be used:
파일명이 여러 와일드카드 패턴에 대응하거나, 파일명이 명시적으로 주어지고 와일드카드 패턴에도 대응하는 경우 링커는 링커 스크립트에서 처음 대응한 것을 사용한다. 예를 들어 다음 입력 섹션 기술은 `data.o'에 대한 규칙이 사용되지 않기 때문에 아마도 의도한 바가 아닐 것이다.

.data : { *(.data) }
.data1 : { data.o(.data) }

Normally, the linker will place files and sections matched by wildcards in the order in which they are seen during the link. You can change this by using the SORT keyword, which appears before a wildcard pattern in parentheses (e.g., SORT(.text*)). When the SORT keyword is used, the linker will sort the files or sections into ascending order by name before placing them in the output file.

If you ever get confused about where input sections are going, use the `-M' linker option to generate a map file. The map file shows precisely how input sections are mapped to output sections.

보통 링커는 링크 중 와일드카드에 대응하는 파일과 섹션을 발견하는 순서대로 배치한다. 이 순서를 (SORT(.text*) 같이) 괄호안의 와일드카드 패턴에 선행하는 SORT 키워드로 변경할 수 있다. SORT 키워드가 사용되면 출력파일에 파일이나 섹션을 이름이 증가하는 순서로 정렬한다.

입력 섹션이 어디로 가는지 궁금하다면 `-M' 옵션으로 맵파일을 만들면 된다. 맵파일은 입력 섹션이 어떻게 출력 섹션으로 대응되는지 알려준다.

This example shows how wildcard patterns might be used to partition files. This linker script directs the linker to place all `.text' sections in `.text' and all `.bss' sections in `.bss'. The linker will place the `.data' section from all files beginning with an upper case character in `.DATA'; for all other files, the linker will place the `.data' section in `.data'.
아래 예는 와일드카드 패턴으로 어떻게 파일을 나누는지 보여준다. 이 링커 스크립트는 모든 `.text' 섹션을 `.text'에, 모든 `.bss' 섹션을 `.bss'에 둔다. 링커는 대문자로 시작하는 파일의 `.data' 섹션을 `.DATA'에, 다른 파일의 `.data' 섹션은 `.data'에 둔다.

SECTIONS {
  .text : { *(.text) }
  .DATA : { [A-Z]*(.data) }
  .data : { *(.data) }
  .bss : { *(.bss) }
}


공통 심볼을 위한 입력 섹션

 

A special notation is needed for common symbols, because in many object file formats common symbols do not have a particular input section. The linker treats common symbols as though they are in an input section named `COMMON'.

You may use file names with the `COMMON' section just as with any other input sections. You can use this to place common symbols from a particular input file in one section while common symbols from other input files are placed in another section.
많은 오브젝트 파일 형식에서 공통 심볼은 특정한 입력 섹션을 가지지 않기 때문에 공통 심볼에는 특별한 표시가 필요하다. 링커는 공통 심볼을 마치 `COMMON'란 입력 섹션에 있는 것 처럼 취급한다.

다른 입력 섹션과 같이, 파일명과 함께 `COMMON' 섹션을 사용할 수 있다. 그래서 한 입력파일의 공통 심볼을 한 섹션으로 담고, 다른 파일의 공통 심볼은 다른 섹션에 저장할 수 있다.

 

In most cases, common symbols in input files will be placed in the `.bss' section in the output file. For example:
대부분의 경우 입력파일의 공통 심볼은 다음과 같이 출력파일의 `.bss' 섹션에 위치한다. (역주; 그리고 보통 `.bss' 섹션 뒷 부분에 위치한다.)

.bss { *(.bss) *(COMMON) }

Some object file formats have more than one type of common symbol. For example, the MIPS ELF object file format distinguishes standard common symbols and small common symbols. In this case, the linker will use a different special section name for other types of common symbols. In the case of MIPS ELF, the linker uses `COMMON' for standard common symbols and `.scommon' for small common symbols. This permits you to map the different types of common symbols into memory at different locations.

You will sometimes see `[COMMON]' in old linker scripts. This notation is now considered obsolete. It is equivalent to `*(COMMON)'.
어떤 오브젝트 파일 형식에는 공통 심볼 형식이 많다. 예를 들어 MIPS ELF 형식은 표준 공통 심볼과 작은 공통 심볼을 구분한다. 이 경우 링커는 각 공통 심볼 형식에 다른 섹션 이름을 사용한다. MIP ELF의 경우 표준 공통 심볼로 `COMMON', 작은 공통 심볼로 `.scommon'을 사용한다. 그래서 다른 형식의 공통 심볼을 메모리의 다른 위치에 대응시킬 수 있다.

 

입력 섹션과 가비지 컬렉션

When link-time garbage collection is in use (`--gc-sections'), it is often useful to mark sections that should not be eliminated. This is accomplished by surrounding an input section's wildcard entry with KEEP(), as in KEEP(*(.init)) or KEEP(SORT(*)(.ctors)).
링크 시 가비지 컬랙션을 (`--gc-sections') (역주; 참조되지 않는 섹션을 자동으로 출력파일에서 제거) 한다면, 제거되면 안되는 섹션을 표시하는 것이 필요할 수 있다. KEEP(*(.init))KEEP(SORT(*)(.ctors))와 같이 입력 섹션의 와일드카드를 KEEP()으로 둘러싸면 된다.

입력 섹션 예

The following example is a complete linker script. It tells the linker to read all of the sections from file `all.o' and place them at the start of output section `outputa' which starts at location `0x10000'. All of section `.input1' from file `foo.o' follows immediately, in the same output section. All of section `.input2' from `foo.o' goes into output section `outputb', followed by section `.input1' from `foo1.o'. All of the remaining `.input1' and `.input2' sections from any files are written to output section `outputc'.

다음은 완전한 링커 스크립트 예이다. 이 스크립트는 `all.o'에서 모든 섹션을 읽어서 `0x10000'에서 시작하는 출력 섹션 `outputa'의 시작에 둔다. `foo.o'의 섹션 `.input1'이 다음에 온다. `foo.o'의 섹션 `.input2'은 출력 섹션 `outputb'에 오고, 다음에 `foo1.o'의 섹션 `.input1'이 나온다. 다른 파일의 남은 `.input1'`.input2' 섹션은 출력 섹션 `outputc'에 쓰여진다.

SECTIONS {
  outputa 0x10000 :
    {
    all.o
    foo.o (.input1)
    }
  outputb :
    {
    foo.o (.input2)
    foo1.o (.input1)
    }
  outputc :
    {
    *(.input1)
    *(.input2)
    }
}


출력 섹션 자료

 

 

You can include explicit bytes of data in an output section by using BYTE, SHORT, LONG, QUAD, or SQUAD as an output section command. Each keyword is followed by an expression in parentheses providing the value to store (see section expressions in Linker Scripts). The value of the expression is stored at the current value of the location counter.

The BYTE, SHORT, LONG, and QUAD commands store one, two, four, and eight bytes (respectively). After storing the bytes, the location counter is incremented by the number of bytes stored.

출력 섹션 명령어인 BYTE, SHORT, LONG, QUAD, SQUAD를 사용하여 출력 섹션에 직접 자료를 쓸 수 있다. 각 키워드 다음에 저장될 값을 나타내는 표현식을 (expressions in Linker Scripts 참고) 괄호안에 적어준다. 표현식의 값은 현재 위치 카운터에 저장된다.

BYTE, SHORT, LONG, QUAD 명령어는 각각 1, 2, 4, 8 바이트를 저장한다. 바이트를 저장한 후 위치 카운터가 그 만큼 증가한다.

 

For example, this will store the byte 1 followed by the four byte value of the symbol `addr':
예를 들어 아래는 1을 한 바이트에 저장하고, 그 뒤에 심볼 `addr'의 세 바이트를 저장한다.

BYTE(1)
LONG(addr)

When using a 64 bit host or target, QUAD and SQUAD are the same; they both store an 8 byte, or 64 bit, value. When both host and target are 32 bits, an expression is computed as 32 bits. In this case QUAD stores a 32 bit value zero extended to 64 bits, and SQUAD stores a 32 bit value sign extended to 64 bits.

If the object file format of the output file has an explicit endianness, which is the normal case, the value will be stored in that endianness. When the object file format does not have an explicit endianness, as is true of, for example, S-records, the value will be stored in the endianness of the first input object file.

64 비트 호스트에서 QUADSQUAD는 동일하게 8 바이트(= 32 비트)로 저장한다. 호스트가 32 비트이면 표현식을 32 비트로 계산된다. 이 경우 QUAD는 32 비트 값을 64 비트로 확장해서 저장하고, SQUAD는 32 비트 값을 64 비트로 부호확장하여 저장한다.

보통 경우처럼 출력파일의 오브젝트 파일 형식이 명시적인 endian을 가지고 있다면, 값은 그 endian으로 저장된다. S-record와 같이 오브젝트 파일 형식이 명시적인 endian을 가지고 있지 않다면 첫 입력파일의 endian을 사용한다.

 

Note - these commands only work inside a section description and not between them, so the following will produce an error from the linker:
주의! 이 명령어는 섹션 기술 안에서만 가능하다. 다음과 같이 섹션 기술 사이에서 사용하면 오류이다.

SECTIONS { .text : { *(.text) } LONG(1) .data : { *(.data) } }

whereas this will work:
대신 이렇게 해야 한다.

SECTIONS { .text : { *(.text) ; LONG(1) } .data : { *(.data) } }

You may use the FILL command to set the fill pattern for the current section. It is followed by an expression in parentheses. Any otherwise unspecified regions of memory within the section (for example, gaps left due to the required alignment of input sections) are filled with the two least significant bytes of the expression, repeated as necessary. A FILL statement covers memory locations after the point at which it occurs in the section definition; by including more than one FILL statement, you can have different fill patterns in different parts of an output section.

This example shows how to fill unspecified regions of memory with the value `0x9090':

현재 섹션을 패턴으로 채우려면 FILL 명령어를 사용하면 된다. 명령어 뒤에 표현식이 괄호 안에 나온다. 섹션에서 (입력 섹션의 정렬 필요 때문에 남겨진 공간과 같은) 지정되지 않은 메모리는 표현식 값의 마지막 2 바이트로 반복해서 채워진다. FILL 명령어는 섹션 정의에 나온 다음부터 메모리를 채우는데 사용된다. 여러 FILL 명령어로 출력 섹션의 다른 지점을 다른 패턴으로 채울 수 있다.

예를 들어 지정하지 않은 메모리 영역을 `0x9090'으로 채우려면,

FILL(0x9090)

The FILL command is similar to the `=fillexp' output section attribute (see section Output section fill), but it only affects the part of the section following the FILL command, rather than the entire section. If both are used, the FILL command takes precedence.
FILL 명령어는 출력 섹션 속성 `=fillexp'과 (Output section fill 참고) 유사하지만 전체 섹션이 아니라 FILL 뒤의 섹션에만 영향을 준다. 둘 다 사용하면 FILL 명령어가 우선순위를 가진다.

 

출력 섹션 키워드

There are a couple of keywords which can appear as output section commands.
출력 섹션 명령어에 다음 두 키워드를 사용할 수 있다.

CREATE_OBJECT_SYMBOLS
The command tells the linker to create a symbol for each input file. The name of each symbol will be the name of the corresponding input file. The section of each symbol will be the output section in which the CREATE_OBJECT_SYMBOLS command appears. This is conventional for the a.out object file format. It is not normally used for any other object file format.
이 명령어는 각 입력파일 마다 심볼을 만들게 한다. 각 심볼의 이름은 대응하는 입력파일의 이름이다. 각 심볼은 CREATE_OBJECT_SYMBOLS가 나온 출력 섹션에 저장된다. 이 명령어는 a.out 오브젝트 파일 형식에서 주로 사용된다. 다른 형식에는 보통 사용되지 않는다.
CONSTRUCTORS
When linking using the a.out object file format, the linker uses an unusual set construct to support C++ global constructors and destructors. When linking object file formats which do not support arbitrary sections, such as ECOFF and XCOFF, the linker will automatically recognize C++ global constructors and destructors by name. For these object file formats, the CONSTRUCTORS command tells the linker to place constructor information in the output section where the CONSTRUCTORS command appears. The CONSTRUCTORS command is ignored for other object file formats. The symbol __CTOR_LIST__ marks the start of the global constructors, and the symbol __DTOR_LIST marks the end. The first word in the list is the number of entries, followed by the address of each constructor or destructor, followed by a zero word. The compiler must arrange to actually run the code. For these object file formats GNU C++ normally calls constructors from a subroutine __main; a call to __main is automatically inserted into the startup code for main. GNU C++ normally runs destructors either by using atexit, or directly from the function exit. For object file formats such as COFF or ELF which support arbitrary section names, GNU C++ will normally arrange to put the addresses of global constructors and destructors into the .ctors and .dtors sections. Placing the following sequence into your linker script will build the sort of table which the GNU C++ runtime code expects to see.
a.out 오브젝트 파일 형식으로 링크할 때 링커는 C++ 전역 생성자와 파괴자를 지원하기 위해서 특별한 구성을 사용한다. ECOFF나 XCOFF와 같이 임의의 섹션을 지원하지 않는 형식에서 링커는 자동으로 C++ 전역 생성자와 파괴자를 이름을 구별한다. 이 형식에서 CONSTRUCTORS 명령어는 이 명령어가 있는 출력 섹션에 생성자 정보를 저장하게 한다. 다른 오브젝트 파일 형식에서 CONSTRUCTORS 명령어는 무시한다. 심볼 __CTOR_LIST__는 전역 생성자의 시작을 표시하고, 심볼 __DTOR_LIST는 끝을 표시한다. 목록의 첫 워드는 항목의 수이고 다음에 각 생성자와 파괴자의 주소가 나온 후, 마지막에 0 워드가 온다. 컴파일러는 이를 실행할 준비를 해야 한다. 이 오브젝트 파일 형식에서 GNU C++은 보통 함수 __main에서 생성자를 호출한다. __main 호출은 main을 위한 시작코드에 자동으로 삽입된다. GNU C++은 보통 atexit이나 직접 함수 exit를 사용하여 파괴자를 호출한다. COFFELF와 같이 임의의 섹션 이름을 지원하는 형식에서 GNU C++은 전역 생성자와 파괴자 주소를 .ctors.dtors 섹션에 저장한다. 다음 스크립트는 GNU C++이 실행 중에 요구하는 정렬표를 생성한다.
      __CTOR_LIST__ = .;
      LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
      *(.ctors)
      LONG(0)
      __CTOR_END__ = .;
      __DTOR_LIST__ = .;
      LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
      *(.dtors)
      LONG(0)
      __DTOR_END__ = .;
If you are using the GNU C++ support for initialization priority, which provides some control over the order in which global constructors are run, you must sort the constructors at link time to ensure that they are executed in the correct order. When using the CONSTRUCTORS command, use `SORT(CONSTRUCTORS)' instead. When using the .ctors and .dtors sections, use `*(SORT(.ctors))' and `*(SORT(.dtors))' instead of just `*(.ctors)' and `*(.dtors)'. Normally the compiler and linker will handle these issues automatically, and you will not need to concern yourself with them. However, you may need to consider this if you are using C++ and writing your own linker scripts.
GNU C++에서 전역 생성자가 불릴 순서를 조정하는 초기화 우선순위를 사용하면 링크 시 생성자가 정확한 순서로 실행도록 생성자를 정렬해야 한다. 이는 CONSTRUCTORS 명령어 대신 `SORT(CONSTRUCTORS)'를 사용하면 된다. .ctors.dtors 섹션을 사용한다면 `*(.ctors)'`*(.dtors)' 대신 `*(SORT(.ctors))'`*(SORT(.dtors))'를 사용하라. 보통 컴파일러와 링커는 이를 자동으로 처리하기 때문에 직접 신경쓸 필요는 없다. 그러나 C++을 사용하고 집접 링커 스크립트를 작성한다면 이를 고려해야 한다.


출력 섹션 버리기

 

The linker will not create output section which do not have any contents. This is for convenience when referring to input sections that may or may not be present in any of the input files. For example:

링커는 내용이 없는 출력 섹션을 만들지 않는다. 이는 입력파일에 있거나 없거나 상관없이 입력 섹션을 참조할 때 유용하다. 예를 들면,

.foo { *(.foo) }

will only create a `.foo' section in the output file if there is a `.foo' section in at least one input file.

If you use anything other than an input section description as an output section command, such as a symbol assignment, then the output section will always be created, even if there are no matching input sections.

The special output section name `/DISCARD/' may be used to discard input sections. Any input sections which are assigned to an output section named `/DISCARD/' are not included in the output file.

는 최소한 한 입력파일에 `.foo' 섹션이 있을 때만 출력파일에 `.foo' 섹션을 만든다.

심볼 대입과 같은 입력 섹션 기술 외의 출력 섹션 명령어를 사용하면, 대응하는 입력 섹션이 없어도 출력 섹션은 생성된다.

특별한 출력 섹션 이름인 `/DISCARD/'는 입력 섹션을 버리기 위해 사용한다. 이름이 `/DISCARD/'인 출력 섹션에 입력 섹션을 대입하면 출력파일에 포함되지 않는다.

 

 

출력 섹션 속성

We showed above that the full description of an output section looked like this:

위에서 출력 섹션 기술이 다음과 같았다.

section [address] [(type)] : [AT(lma)]
  {
    output-section-command
    output-section-command
    ...
  } [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp]

We've already described section, address, and output-section-command. In this section we will describe the remaining section attributes.
이미 section, address, output-section-command는 설명했다. 이제 나머지 섹션 속성을 설명한다.

출력 섹션 타입

Each output section may have a type. The type is a keyword in parentheses. The following types are defined:

각 출력 섹션을 타입을 가진다. 타입은 괄호 안에 키워드로 다음과 같다.

NOLOAD
The section should be marked as not loadable, so that it will not be loaded into memory when the program is run.
DSECT
COPY
INFO
OVERLAY
These type names are supported for backward compatibility, and are rarely used. They all have the same effect: the section should be marked as not allocatable, so that no memory is allocated for the section when the program is run.

 

NOLOAD
이 섹션을 로드가능하지 않게 한다. 그래서 프로그램이 실행될 때 메모리로 읽어들이지 않는다.
DSECT
COPY
INFO
OVERLAY
이 타입은 호환성을 위해 지원되며 거의 사용되지 않는다. 이들은 모두 섹션을 할당하지 않게 하여, 프로그램 실행 시 섹션에 대한 메모리가 할당되지 않게 한다.

 

The linker normally sets the attributes of an output section based on the input sections which map into it. You can override this by using the section type. For example, in the script sample below, the `ROM' section is addressed at memory location `0' and does not need to be loaded when the program is run. The contents of the `ROM' section will appear in the linker output file as usual.
링커는 보통 대응하는 입력 섹션에 기반하여 출력 섹션의 속성을 정한다. 이를 섹션 타입으로 대체할 수 있다. 예로 아래 스크립트에서 주소가 0인 `ROM' 섹션은 프로그램 실행 시 로드할 필요가 앖다. `ROM' 섹션 내용은 보통과 같이 링커 출력파일에 나타난다.

SECTIONS {
  ROM 0 (NOLOAD) : { ... }
  ...
}


출력 섹션 LMA

 

Every section has a virtual address (VMA) and a load address (LMA); see section Basic Linker Script Concepts. The address expression which may appear in an output section description sets the VMA (see section Output section address).

The linker will normally set the LMA equal to the VMA. You can change that by using the AT keyword. The expression lma that follows the AT keyword specifies the load address of the section. Alternatively, with `AT>lma_region' expression, you may specify a memory region for the section's load address. See section MEMORY command.

모든 섹션은 가상 주소(VMA)와 로드 주소(LMA)를 가진다. Basic Linker Script Concepts를 참고하라. 출력 섹션 기술에 나오는 주소 표현식은 (Output section address를 참고) VMA를 정한다.

링커는 보통 LMA를 VMA와 같게 한다. 그러나 AT 키워드로 LMA를 변경할 수 있다. AT 다음에 나오는 표현식 lma은 섹션의 로드 주소를 정한다. 이 외에 `AT>lma_region'으로 섹션 로드 주소를 위한 메모리 영역을 지정할 수 있다. MEMORY command를 참고하라.

This feature is designed to make it easy to build a ROM image. For example, the following linker script creates three output sections: one called `.text', which starts at 0x1000, one called `.mdata', which is loaded at the end of the `.text' section even though its VMA is 0x2000, and one called `.bss' to hold uninitialized data at address 0x3000. The symbol _data is defined with the value 0x2000, which shows that the location counter holds the VMA value, not the LMA value.
이 기능은 ROM 이미지를 만들기 쉽게하기 위해서 만들어졌다. 예로 다음 스크립트는 세 섹션을 만든다. `.text'0x1000에서 시작한다. `.mdata'`.text' 섹션 뒤에서 로드되나 VMA는 0x2000이다. `.bss' 섹션은 0x3000에서 초기화안된 자료를 저장한다. 위치 카운터는 LMA가 아니라 VMA 값을 저장하기 때문에 심볼 _data는 값 0x2000으로 정의된다.

SECTIONS
  {
  .text 0x1000 : { *(.text) _etext = . ; }
  .mdata 0x2000 :
    AT ( ADDR (.text) + SIZEOF (.text) )
    { _data = . ; *(.data); _edata = . ;  }
  .bss 0x3000 :
    { _bstart = . ;  *(.bss) *(COMMON) ; _bend = . ;}
}

The run-time initialization code for use with a program generated with this linker script would include something like the following, to copy the initialized data from the ROM image to its runtime address. Notice how this code takes advantage of the symbols defined by the linker script.
이 스크립트로 생성한 프로그램의 초기화 코드는 다음과 같이 초기화된 자료를 ROM에서 실행 주소로 복사하는 코드를 포함한다. 코드가 링커 스크립트가 정의한 심볼을 어떻게 이용하는지 살펴봐라.

extern char _etext, _data, _edata, _bstart, _bend;
char *src = &_etext;
char *dst = &_data;
/* ROM has data at end of text; copy it. */
while (dst < &_edata) {
  *dst++ = *src++;
}
/* Zero bss */
for (dst = &_bstart; dst< &_bend; dst++)
  *dst = 0;


출력 섹션 영역

 

You can assign a section to a previously defined region of memory by using `>region'. See section MEMORY command.

Here is a simple example:

섹션을 전에 정의한 메모리 영역에 `>region'으로 할당할 수 있다. MEMORY command를 참고하라.

간단한 예로,

MEMORY { rom : ORIGIN = 0x1000, LENGTH = 0x1000 }
SECTIONS { ROM : { *(.text) } >rom }


출력 섹션 phdr

 

You can assign a section to a previously defined program segment by using `:phdr'. See section PHDRS Command. If a section is assigned to one or more segments, then all subsequent allocated sections will be assigned to those segments as well, unless they use an explicitly :phdr modifier. You can use :NONE to tell the linker to not put the section in any segment at all.

Here is a simple example:

(역주, phdr는 프로그램 헤더의 준말이다.) 섹션을 전에 `:phdr'로 정의한 세그먼트에 할당할 수 있다. PHDRS Command를 참고하라. 섹션이 여러 세그먼트에 할당되면 `:phdr'이 없어도 다음으로 할당된 모든 섹션들은 같은 세그먼트들에 할당된다. 섹션을 어떤 세그먼트에도 집어넣지 않기 위해서는 :NONE을 사용해야 한다. 다음은 간단한 예다.

PHDRS { text PT_LOAD ; }
SECTIONS { .text : { *(.text) } :text }


 

출력 섹션 채우기

You can set the fill pattern for an entire section by using `=fillexp'. fillexp is an expression (see section expressions in Linker Scripts). Any otherwise unspecified regions of memory within the output section (for example, gaps left due to the required alignment of input sections) will be filled with the two least significant bytes of the value, repeated as necessary.

You can also change the fill value with a FILL command in the output section commands; see section Output section data.

Here is a simple example:

`=fillexp'로 전체 섹션에 대한 채우기 패턴을 지정할 수 있다. fillexp는 표현식이다. (expressions in Linker Scripts 참고) 출력 섹션에서 (입력 섹션에 정렬 필요로 남겨진 공간과 같은) 메모리의 지정하지 않은 부분은 값의 마지막 2 바이트로 반복해서 채워진다.

출력 섹션 명령어 FILL로 채우기 값을 변경 할 수 있다. Output section data를 참고하라.

다음은 간단한 예이다.

SECTIONS { .text : { *(.text) } =0x9090 }


오버레이 기술

 

An overlay description provides an easy way to describe sections which are to be loaded as part of a single memory image but are to be run at the same memory address. At run time, some sort of overlay manager will copy the overlaid sections in and out of the runtime memory address as required, perhaps by simply manipulating addressing bits. This approach can be useful, for example, when a certain region of memory is faster than another.

Overlays are described using the OVERLAY command. The OVERLAY command is used within a SECTIONS command, like an output section description. The full syntax of the OVERLAY command is as follows:

오버레이 기술은 쉽게 같은 메모리 주소에 로드되야 하는 섹션들을 지시하는 방법이다. 실행 중에 일종의 오버레이 매니저가 필요하면 주소를 조정하여 섹션을 메모리에 복사한다. 이 방식은 메모리의 어떤 영역이 다른 곳보다 빠르다면 유용하다.

OVERLAY 명령어를 사용하여 오버레이를 기술한다. OVERLAY 명령어는 출력 섹션 기술과 같이 SECTIONS 명령어 안에서 쓰인다. 명령어의 문법은 다음과 같다.

OVERLAY [start] : [NOCROSSREFS] [AT ( ldaddr )]
  {
    secname1
      {
        output-section-command
        output-section-command
        ...
      } [:phdr...] [=fill]
    secname2
      {
        output-section-command
        output-section-command
        ...
      } [:phdr...] [=fill]
    ...
  } [>region] [:phdr...] [=fill]

Everything is optional except OVERLAY (a keyword), and each section must have a name (secname1 and secname2 above). The section definitions within the OVERLAY construct are identical to those within the general SECTIONS contruct (see section SECTIONS command), except that no addresses and no memory regions may be defined for sections within an OVERLAY.

The sections are all defined with the same starting address. The load addresses of the sections are arranged such that they are consecutive in memory starting at the load address used for the OVERLAY as a whole (as with normal section definitions, the load address is optional, and defaults to the start address; the start address is also optional, and defaults to the current value of the location counter).

OVERLAY 키워드를 제외하고 모두 선택적이고, 각 섹션은 (위에서 secname1secname2) 이름을 가져야 한다. OVERLAY에서 섹션 정의는 섹션을 위해 어떤 주소나 메모리 영역이 정의될 수 없다는 것을 제외하고는 일반 SECTIONS과 (SECTIONS command 참고) 동일하다.

섹션은 모두 같은 시작 주소를 가진다. 섹션의 로드 주소는 OVERLAY의 로드 주소부터 연속적으로 배치된다. (보통 섹션 정의와 같이 로드 주소는 선택적으로, 기본값은 start 주소이다. start 주소도 선택적으로, 기본값은 현재 위치 카운터이다.)

If the NOCROSSREFS keyword is used, and there any references among the sections, the linker will report an error. Since the sections all run at the same address, it normally does not make sense for one section to refer directly to another. See section Other linker script commands.

For each section within the OVERLAY, the linker automatically defines two symbols. The symbol __load_start_secname is defined as the starting load address of the section. The symbol __load_stop_secname is defined as the final load address of the section. Any characters within secname which are not legal within C identifiers are removed. C (or assembler) code may use these symbols to move the overlaid sections around as necessary.

NOCROSSREFS 키워드를 사용하고 섹션들 사이에 참조가 있다면 링커는 오류를 출력한다. 섹션이 모두 동일한 주소에서 실행되기 때문에 한 섹션이 다른 섹션을 직접 참조하는 것은 불가능하다. Other linker script commands를 참고하라.

OVERLAY의 각 섹션 마다 링커는 자동으로 두 심볼을 정의한다. 심볼 __load_start_secname은 섹션의 시작 로드 주소로 정의된다. 심볼 __load_stop_secname은 로드 주소 끝으로 정의된다. secname 이름에서 C 인식자로 허용되지 않은 문자는 제거된다. 필요하다면 C (혹은 어셈블러) 코드는 섹션을 옮기기 위해서 이 심볼을 사용할 수 있다.

At the end of the overlay, the value of the location counter is set to the start address of the overlay plus the size of the largest section.

Here is an example. Remember that this would appear inside a SECTIONS construct.

오버레이 후에 위치 카운터 값은 오버레이 시작 주소와 가장 큰 섹션의 크기의 합으로 설정된다.

다음은 예이다. 이것이 SECTIONS 안에 나올 수 있다는 것을 기억하자.

  OVERLAY 0x1000 : AT (0x4000)
   {
     .text0 { o1/*.o(.text) }
     .text1 { o2/*.o(.text) }
   }

This will define both `.text0' and `.text1' to start at address 0x1000. `.text0' will be loaded at address 0x4000, and `.text1' will be loaded immediately after `.text0'. The following symbols will be defined: __load_start_text0, __load_stop_text0, __load_start_text1, __load_stop_text1.

C code to copy overlay .text1 into the overlay area might look like the following.

이는 주소 0x1000에서 시작하는 `.text0'`.text1'을 정의한다. `.text0'은 주소 0x4000에서 읽어들이고, `.text1'`.text0' 바로 뒤에서 읽어들일 수 있다. 심볼 __load_start_text0, __load_stop_text0, __load_start_text1, __load_stop_text1이 정의된다.

.text1를 오버레이 영역에 복사하는 C 코드는 다음과 같다.

  extern char __load_start_text1, __load_stop_text1;
  memcpy ((char *) 0x1000, &__load_start_text1,
          &__load_stop_text1 - &__load_start_text1);

Note that the OVERLAY command is just syntactic sugar, since everything it does can be done using the more basic commands. The above example could have been written identically as follows.
모든 것이 기본적인 명령어로도 가능하므로 OVERLAY 명령어는 단지 오버레이를 편리하게 사용하기 위한 것이다. 위의 예는 다음과 정확히 일치한다.

  .text0 0x1000 : AT (0x4000) { o1/*.o(.text) }
  __load_start_text0 = LOADADDR (.text0);
  __load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0);
  .text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) { o2/*.o(.text) }
  __load_start_text1 = LOADADDR (.text1);
  __load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1);
  . = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1));


MEMORY 명령어

 

The linker's default configuration permits allocation of all available memory. You can override this by using the MEMORY command.

The MEMORY command describes the location and size of blocks of memory in the target. You can use it to describe which memory regions may be used by the linker, and which memory regions it must avoid. You can then assign sections to particular memory regions. The linker will set section addresses based on the memory regions, and will warn about regions that become too full. The linker will not shuffle sections around to fit into the available regions.

링커의 기본 설정은 가능한 어떤 메모리도 사용할 수 있다. 이를 MEMORY로 제한할 수 있다.

MEMORY 명령어는 플래폼에서 메모리 블록의 위치와 크기를 알려준다. 그래서 링커가 사용거나 피해야하는 메모리 영역을 지정할 수 있다. 또 섹션을 특정 메모리 영역에 할당할 수 있다. 링커는 메모리 영역에 기반하여 섹션 주소를 정하고 영역이 다 차면 경고를 한다. 링커는 주어진 크기에 적합하게 섹션을 재배치하지 못한다.

A linker script may contain at most one use of the MEMORY command. However, you can define as many blocks of memory within it as you wish. The syntax is:

링커 스크립트는 MEMORY 명령어를 최대 한번 사용할 수 있다. 그러나 그 안에 원하는 만큼 블록을 정의할 수 있다. 문법은 다음과 같다.

MEMORY
  {
    name [(attr)] : ORIGIN = origin, LENGTH = len
    ...
  }

The name is a name used in the linker script to refer to the region. The region name has no meaning outside of the linker script. Region names are stored in a separate name space, and will not conflict with symbol names, file names, or section names. Each memory region must have a distinct name.

The attr string is an optional list of attributes that specify whether to use a particular memory region for an input section which is not explicitly mapped in the linker script. As described in section SECTIONS command, if you do not specify an output section for some input section, the linker will create an output section with the same name as the input section. If you define region attributes, the linker will use them to select the memory region for the output section that it creates.

name는 링커 스크립트가 영역을 지칭하는 이름이다. 영역 이름은 스크립트 밖에서는 아무 의미가 없다. 영역 이름은 독립된 네임스페이스에 저장되기 때문에 심볼 이름, 파일명, 섹션 이름과 같은 이름을 사용해도 된다. 각 메모리 영역끼리는 서로 다른 이름을 가져야한다.

attr은 스크립트에서 명시적으로 대응하지 않는 입력 섹션의 메모리 영역을 지정하기위한 선택적인 속성들이다. SECTIONS command에서 설명한대로 입력 섹션에 대한 출력 섹션을 지정하지 않으면 입력 섹션과 같은 이름의 출력 섹션을 만든다. 이 경우 링커는 출력 섹션의 메모리 영역을 선택하기 위해서 영역 속성을 사용한다.

The attr string must consist only of the following characters:

`R'
Read-only section
`W'
Read/write section
`X'
Executable section
`A'
Allocatable section
`I'
Initialized section
`L'
Same as `I'
`!'
Invert the sense of any of the preceding attributes

 

attr은 다음 문자들로 구성된다.

`R'
읽기전용 섹션
`W'
읽기쓰기 섹션
`X'
실행가능 섹션
`A'
할당가능 섹션
`I'
초기화된 섹션
`L'
`I'와 동일
`!'
위의 속성들의 의미를 역으로 함

If a unmapped section matches any of the listed attributes other than `!', it will be placed in the memory region. The `!' attribute reverses this test, so that an unmapped section will be placed in the memory region only if it does not match any of the listed attributes.

The origin is an expression for the start address of the memory region. The expression must evaluate to a constant before memory allocation is performed, which means that you may not use any section relative symbols. The keyword ORIGIN may be abbreviated to org or o (but not, for example, ORG).

대응시키지 않은 섹션이 `!'를 제외한 위의 속성과 일치하면 그 메모리 영역에 위치한다. `!'은 이 검사를 역으로 하여 어떤 속성과도 일치하지 않으면 메모리 영역에 할당한다.

origin은 메모리 영역의 시작주소를 나타내는 표현식이다. 표현식은 메모리 할당 전에 상수로 알 수 있어야 하므로 어느 섹션에 상대적인 심볼을 사용할 수 없다. ORIGIN 키워드는 orgo로 줄여쓸 수 있다. (그러나 ORG은 안된다.)

The len is an expression for the size in bytes of the memory region. As with the origin expression, the expression must evaluate to a constant before memory allocation is performed. The keyword LENGTH may be abbreviated to len or l.

In the following example, we specify that there are two memory regions available for allocation: one starting at `0' for 256 kilobytes, and the other starting at `0x40000000' for four megabytes. The linker will place into the `rom' memory region every section which is not explicitly mapped into a memory region, and is either read-only or executable. The linker will place other sections which are not explicitly mapped into a memory region into the `ram' memory region.

len은 바이트로 메모리 영역의 크기를 나타내는 표현식이다. origin 표현식과 같이 메모리 할당 전에 값을 알 수 있어야 한다. LENGTH 키워드는 lenl로 줄여 사용할 수 있다.

아래 예에서 할당을 위해 두 메모리 영역을 지정한다. 하나는 `0'에서 256 kb 만큼이고, 다른 하나는 `0x40000000'에서 4 mb 만큼이다. 링커는 일기전용이거나 실행가능한 명시적으로 대응시키지 않은 섹션을 `rom' 메모리 영역에 위치시킨다. 다른 명시적으로 대응시키지 않은 섹션은 `ram' 메모리 영역에 위치시킨다.

MEMORY
  {
    rom (rx)  : ORIGIN = 0, LENGTH = 256K
    ram (!rx) : org = 0x40000000, l = 4M
  }

Once you define a memory region, you can direct the linker to place specific output sections into that memory region by using the `>region' output section attribute. For example, if you have a memory region named `mem', you would use `>mem' in the output section definition. See section Output section region. If no address was specified for the output section, the linker will set the address to the next available address within the memory region. If the combined output sections directed to a memory region are too large for the region, the linker will issue an error message.

메모리 영역을 정의하였으면 출력 섹션 속성 `>region'을 사용하여 특정 출력 섹션을 메모리 영역으로 위치시킬 수 있다. 예를 들어 `mem'이라는 메모리 영역이 있다면 출력 섹션 정의에서 `>mem'을 사용할 수 있다. Output section region를 참고하라. 출력 섹션에 주소가 지정되지 않으면 링커는 메모리 영역에서 남은 주소를 사용한다. 메모리 영역에 위치할 출력 섹션들이 영역 보다 크다면 링커는 오류를 낸다.

 

 

PHDRS 명령어

The ELF object file format uses program headers, also knows as segments. The program headers describe how the program should be loaded into memory. You can print them out by using the objdump program with the `-p' option.

When you run an ELF program on a native ELF system, the system loader reads the program headers in order to figure out how to load the program. This will only work if the program headers are set correctly. This manual does not describe the details of how the system loader interprets program headers; for more information, see the ELF ABI.

ELF 오브젝트 파일 형식은 세그먼트로도 불리는 프로그램 헤더를 가진다. 프로그램 헤더는 프로그램이 어떻게 메모리에 로드될지를 지시한다. objdump 프로그램의 `-p' 옵션으로 확인할 수 있다.

ELF 시스템에서 ELF 프로그램을 수행하면 시스템 로더가 어떻게 프로그램을 로드할지 알기 위해서 프로그램 헤더를 읽는다. 이는 프로그램 헤더가 올바로 있어야만 가능하다. 이 글은 시스템 로더가 정확히 어떻게 프로그램 헤더를 해석하는지를 다루지 않는다. 자세한 정보는 ELF ABI를 참고하라.

 

The linker will create reasonable program headers by default. However, in some cases, you may need to specify the program headers more precisely. You may use the PHDRS command for this purpose. When the linker sees the PHDRS command in the linker script, it will not create any program headers other than the ones specified.

The linker only pays attention to the PHDRS command when generating an ELF output file. In other cases, the linker will simply ignore PHDRS.

링커는 기본적으로 올바른 프로그램 헤더를 만든다. 그러나 어떤 경우에 프로그램 헤더를 더 자세히 작성할 필요가 있다. 이 경우 PHDRS 명령어를 사용한다. 링커는 스크립트에 PHDRS 명령어가 있다면 지시한 프로그램 헤더 외에는 만들지 않는다. 링커는 ELF 출력파일을 만들 때만 PHDRS 명령어를 사용한다. 다른 경우 PHDRS를 무시한다.

 

This is the syntax of the PHDRS command. The words PHDRS, FILEHDR, AT, and FLAGS are keywords.

PHDRS 명령어 문법은 다음과 같다. PHDRS, FILEHDR, AT, FLAGS는 모두 키워드이다.

PHDRS
{
  name type [ FILEHDR ] [ PHDRS ] [ AT ( address ) ]
        [ FLAGS ( flags ) ] ;
}

The name is used only for reference in the SECTIONS command of the linker script. It is not put into the output file. Program header names are stored in a separate name space, and will not conflict with symbol names, file names, or section names. Each program header must have a distinct name.

Certain program header types describe segments of memory which the system loader will load from the file. In the linker script, you specify the contents of these segments by placing allocatable output sections in the segments. You use the `:phdr' output section attribute to place a section in a particular segment. See section Output section phdr.

nameSECTIONS 명령어에서 참조로만 쓰인다. 이는 출력파일에 포함되지 않는다. 프로그램 헤더는 별로의 네임스페이스에 저장되기 때문에 심볼 이름, 파일명, 섹션 이름과 겹쳐도 된다. 각 프로그램 헤더는 서로 다른 이름을 가져야한다.

어떤 프로그램 헤더는 시스템 로더가 파일에서 로드할 메모리 세그먼트를 기술한다. 스크립트에서 할당가능한 출력 섹션을 세그먼트에 위치하여 각 세그먼트의 내용을 정한다. 섹션을 특정 세그먼트에 위치하기 위해서 출력 섹션 속성 `:phdr'를 사용한다. Output section phdr를 참고하라.

 

It is normal to put certain sections in more than one segment. This merely implies that one segment of memory contains another. You may repeat `:phdr', using it once for each segment which should contain the section.

If you place a section in one or more segments using `:phdr', then the linker will place all subsequent allocatable sections which do not specify `:phdr' in the same segments. This is for convenience, since generally a whole set of contiguous sections will be placed in a single segment. You can use :NONE to override the default segment and tell the linker to not put the section in any segment at all.

여러 세그먼트에 섹션을 두는 것은 흔하다. 이는 단지 메모리 세그먼트가 다른 메모리 세그먼트를 포함할 수 있다는 것을 뜻한다. 섹션을 포함할 각 세그먼트에 한번씩 `:phdr'을 반복할 수 있다.

`:phdr'를 사용하여 섹션을 여러 세그먼트에 위치한 후 `:phdr'를 사용하지 않으면 다음 할당가능한 섹션도 같은 세그먼트에 위치한다. 이는 편리하게 일반적으로 연속된 섹션을 같은 세그먼트에 저장하기 위한 것이다. :NONE로 이를 무시하고 섹션을 세그먼트에 저장하지 않을 수 있다.

 

You may use the FILEHDR and PHDRS keywords appear after the program header type to further describe the contents of the segment. The FILEHDR keyword means that the segment should include the ELF file header. The PHDRS keyword means that the segment should include the ELF program headers themselves.

The type may be one of the following. The numbers indicate the value of the keyword.

세그먼트 내용을 더 설명하기 위해 프로그램 헤더 타입 뒤에 FILEHDRPHDRS 키워드를 사용할 수 있다. FILEHDR 키워드는 세그먼트가 ELF 파일 헤더를 포함하게 한다. PHDRS 키워드는 세그먼트가 ELF 프로그램 헤더 자체를 포함하게 한다. type는 다음 중 하나이다. 숫자는 키워드의 값을 나타낸다.

PT_NULL (0)
Indicates an unused program header.
PT_LOAD (1)
Indicates that this program header describes a segment to be loaded from the file.
PT_DYNAMIC (2)
Indicates a segment where dynamic linking information can be found.
PT_INTERP (3)
Indicates a segment where the name of the program interpreter may be found.
PT_NOTE (4)
Indicates a segment holding note information.
PT_SHLIB (5)
A reserved program header type, defined but not specified by the ELF ABI.
PT_PHDR (6)
Indicates a segment where the program headers may be found.
expression
An expression giving the numeric type of the program header. This may be used for types not defined above.

 

PT_NULL (0)
사용되지 않는 프로그램 헤더를 나타낸다.
PT_LOAD (1)
이 프로그램 헤더는 파일에서 로드되는 세그먼트를 나타낸다.
PT_DYNAMIC (2)
동적 링크 자료를 포함한 세그먼트를 나타낸다.
PT_INTERP (3)
프로그램 해석기 이름을 포함한 세그먼트를 나타낸다.
PT_NOTE (4)
note 정보를 포함한 세그먼트를 나타낸다.
PT_SHLIB (5)
예약된 프로그램 헤더 타입으로, 정의는 되었지만 ELF ABI에서 사용하지는 않는다.
PT_PHDR (6)
프로그램 헤더를 포함한 세그먼트를 나타낸다.
expression
표현식이 프로그램 헤더 타입을 나타낸다. 이는 위에 해당하지 않는 타입의 경우 사용한다.

 

You can specify that a segment should be loaded at a particular address in memory by using an AT expression. This is identical to the AT command used as an output section attribute (see section Output section LMA). The AT command for a program header overrides the output section attribute.

The linker will normally set the segment flags based on the sections which comprise the segment. You may use the FLAGS keyword to explicitly specify the segment flags. The value of flags must be an integer. It is used to set the p_flags field of the program header.

AT 키워드로 세그먼트가 특정 주소에 로드하게 할 수 있다. 이는 출력 섹션 속성 (Output section LMA 참고) AT과 동일하다. 프로그램 헤더에 대한 AT 명령어는 출력 섹션 속성보다 우선순위를 가진다.

Here is an example of PHDRS. This shows a typical set of program headers used on a native ELF system.
아래는 PHDRS의 예이다. ELF 시스템에서 사용하는 전형적인 경우이다.

PHDRS
{
  headers PT_PHDR PHDRS ;
  interp PT_INTERP ;
  text PT_LOAD FILEHDR PHDRS ;
  data PT_LOAD ;
  dynamic PT_DYNAMIC ;
}
SECTIONS
{
  . = SIZEOF_HEADERS;
  .interp : { *(.interp) } :text :interp
  .text : { *(.text) } :text
  .rodata : { *(.rodata) } /* defaults to :text */
  ...
  . = . + 0x1000; /* move to a new page in memory */
  .data : { *(.data) } :data
  .dynamic : { *(.dynamic) } :data :dynamic
  ...
}


VERSION 명령어

 

The linker supports symbol versions when using ELF. Symbol versions are only useful when using shared libraries. The dynamic linker can use symbol versions to select a specific version of a function when it runs a program that may have been linked against an earlier version of the shared library.

You can include a version script directly in the main linker script, or you can supply the version script as an implicit linker script. You can also use the `--version-script' linker option.

The syntax of the VERSION command is simply

ELF에서 링커는 심볼 버전을 지원한다. 심볼 버전은 공유 라이브러리를 사용할 때만 유용하다. 동적 링커는 프로그램이 이전 버전의 공유 라이브러리에 링크된 경우 심볼 버전으로 함수의 버전을 선택한다.

심볼 버전을 스크립트에 직접 포함하거나 암묵적인 스크립트로 버전을 지정할 수 있다. (역주, 암묵적인 스크립트는 아래에서 설명된다.) 또 `--version-script' 옵션을 사용할 수도 있다.

아래는 VERSION 명령어 문법이다.

VERSION { version-script-commands } DEPENDENCY_VERSION

The format of the version script commands is identical to that used by Sun's linker in Solaris 2.5. The version script defines a tree of version nodes. You specify the node names and interdependencies in the version script. You can specify which symbols are bound to which version nodes, and you can reduce a specified set of symbols to local scope so that they are not globally visible outside of the shared library.

The easiest way to demonstrate the version script language is with a few examples.

버전 스크립트 명령어 문법은 Sun Solaris 2.5 링커와 동일하다. 이 명령어는 버전 트리를 정의한다. 버전 스크립트에서 노드 이름과 서로 연관관계를 설정한다. 어떤 심볼을 어떤 버전에 포함시키고, 어떤 심볼은 지역 영역으로 설정하여 공유 라이브러리 외부에서 볼 수 없게 할 수 있다.

VERS_1.1 {
	 global:
		 foo1;
	 local:
		 old*;
		 original*;
		 new*;
};
VERS_1.2 {
		 foo2;
} VERS_1.1;
VERS_2.0 {
		 bar1; bar2;
} VERS_1.2;

This example version script defines three version nodes. The first version node defined is `VERS_1.1'; it has no other dependencies. The script binds the symbol `foo1' to `VERS_1.1'. It reduces a number of symbols to local scope so that they are not visible outside of the shared library.

Next, the version script defines node `VERS_1.2'. This node depends upon `VERS_1.1'. The script binds the symbol `foo2' to the version node `VERS_1.2'.

Finally, the version script defines node `VERS_2.0'. This node depends upon `VERS_1.2'. The scripts binds the symbols `bar1' and `bar2' are bound to the version node `VERS_2.0'.

이 버전 스크립트 예는 세 버전 노드를 정의한다. 첫번째 노드는 `VERS_1.1'로 다른 의존관계가 없다. 스크립트는 심볼 `foo1'`VERS_1.1'에 포함한다. 또 많은 심볼을 지역 영역으로 하여 공유 라이브러리 외부에서 볼 수 없게 한다. 다음은 `VERS_1.2' 노드이다. 이 노드는 `VERS_1.1'에 의존한다. 스크립트는 심볼 `foo2'`VERS_1.2'에 포함한다. 마지막으로 버전 스크립트는 `VERS_2.0'를 정의한다. 이 노드는 `VERS_1.2'에 의존한다. 스크립트는 심볼 `bar1'`bar2'를 노드 `VERS_2.0'에 포함한다.

 

When the linker finds a symbol defined in a library which is not specifically bound to a version node, it will effectively bind it to an unspecified base version of the library. You can bind all otherwise unspecified symbols to a given version node by using `global: *' somewhere in the version script.

The names of the version nodes have no specific meaning other than what they might suggest to the person reading them. The `2.0' version could just as well have appeared in between `1.1' and `1.2'. However, this would be a confusing way to write a version script.

링커는 라이브러리에 정의되었지만 버전 노드에 포함되지 않은 심볼을 라이브러리의 명시하지 않은 기본 버전에 포함한다. 모든 심볼을 특정 버전 노드에 포함하려면 `global: *'를 사용한다.

버전 노드 이름은 사람에게만 의미가 있다. 버전 `2.0'`1.1'`1.2' 사이에도 나올 수 있다. 그러나 그러면 버전 스크립트를 작성하기 힘들어진다.

When you link an application against a shared library that has versioned symbols, the application itself knows which version of each symbol it requires, and it also knows which version nodes it needs from each shared library it is linked against. Thus at runtime, the dynamic loader can make a quick check to make sure that the libraries you have linked against do in fact supply all of the version nodes that the application will need to resolve all of the dynamic symbols. In this way it is possible for the dynamic linker to know with certainty that all external symbols that it needs will be resolvable without having to search for each symbol reference.

The symbol versioning is in effect a much more sophisticated way of doing minor version checking that SunOS does. The fundamental problem that is being addressed here is that typically references to external functions are bound on an as-needed basis, and are not all bound when the application starts up. If a shared library is out of date, a required interface may be missing; when the application tries to use that interface, it may suddenly and unexpectedly fail. With symbol versioning, the user will get a warning when they start their program if the libraries being used with the application are too old.

프로그램을 버전 심볼이 있는 공유 라이브러리에 링크하면, 프로그램은 필요한 심볼의 버전을 알고 링크하는 각 공유 라이브러리에서 필요한 버전 노드를 안다. 그래서 실행 중에 동적 링커는 프로그램이 동적 심볼을 리졸브하는데 필요한 버전 노드를 라이브러리가 제공하는지 빨리 확인할 수 있다. 이 경우 동적 링커가 각 심볼 참조를 검색하지 않고 필요한 외부 심볼을 확신할 수 있다.

심볼 버전은 사실 SunOS의 하위 버전 검사보다 훨씬 더 복잡하다. 중요한 점은 전형적으로 외부 함수의 참조를 프로그램이 시작할 때가 아니라 필요할 때마다 찾는 것이다. 공유 라이브러리가 오래되었다면 필요한 인터페이스가 없을 수 있다. 그래서 프로그램이 인터페이스를 찾다가 의도하지 않게 갑자기 실패할 수 있다. 프로그램이 사용하는 라이브러리가 너무 오래되었다면 버전 심볼을 이용하여 프로그램을 실행할 때 미리 경고를 받을 수 있다.

There are several GNU extensions to Sun's versioning approach. The first of these is the ability to bind a symbol to a version node in the source file where the symbol is defined instead of in the versioning script. This was done mainly to reduce the burden on the library maintainer. You can do this by putting something like:

GNU는 Sun 버전 방식에 몇몇 확장을 했다. 첫째는 버전 스크립트을 사용하지 않고 심볼을 정의한 소스파일에서 심볼을 버전 노드에 포함하는 것이다. 이는 주로 라이브러리 개발자를 편하게 하기 위해서이다. 아래과 같은 것을,

__asm__(".symver original_foo,foo@VERS_1.1");

in the C source file. This renames the function `original_foo' to be an alias for `foo' bound to the version node `VERS_1.1'. The `local:' directive can be used to prevent the symbol `original_foo' from being exported.

C 소스코드에 포함하면 된다. 이는 함수 `original_foo'를 버전 노드 `VERS_1.1'`foo'으로 이름을 바꾼다. 심볼 `original_foo'이 익스포트되지 않게 하기 위해서 `local:' 지시어를 사용한다.

The second GNU extension is to allow multiple versions of the same function to appear in a given shared library. In this way you can make an incompatible change to an interface without increasing the major version number of the shared library, while still allowing applications linked against the old interface to continue to function.

To do this, you must use multiple `.symver' directives in the source file. Here is an example:

두번째 GNU 확장은 공유 라이브러리에 같은 함수를 여러 버전에 포함시키는 것이다. 이 경우 오래된 인터페이스와 링크된 프로그램을 계속 실행가능하게 하면서 공유 라이브러리의 주 버전을 증가하지 않고 인터페이스에 호환이 안되는 변화를 줄 수 있다.

이를 위해 다음과 같이 소스코드에서 여러 `.symver' 지시어를 사용한다.

__asm__(".symver original_foo,foo@");
__asm__(".symver old_foo,foo@VERS_1.1");
__asm__(".symver old_foo1,foo@VERS_1.2");
__asm__(".symver new_foo,foo@@VERS_2.0");

In this example, `foo@' represents the symbol `foo' bound to the unspecified base version of the symbol. The source file that contains this example would define 4 C functions: `original_foo', `old_foo', `old_foo1', and `new_foo'.

When you have multiple definitions of a given symbol, there needs to be some way to specify a default version to which external references to this symbol will be bound. You can do this with the `foo@@VERS_2.0' type of `.symver' directive. You can only declare one version of a symbol as the default in this manner; otherwise you would effectively have multiple definitions of the same symbol.

위에서 `foo@'는 명시하지 않은 기본 버전에 포함된 심볼 `foo'을 의미한다. 이 예를 포함한 소스코드는 다음 네 C 함수를 정의한다. `original_foo', `old_foo', `old_foo1', `new_foo'.

주어진 심볼이 여러 정의를 가지면 심볼의 외부 참조가 어떤 버전을 가리키는지 결정해야 한다. 이는 `.symver' 지시어의 `foo@@VERS_2.0'과 같이 가능하다. 이런 식으로 기본으로 쓰일 심볼의 버전을 선언가능하다. 그렇지 않으면 같은 심볼의 여러 정의가 모두 유효하다.

If you wish to bind a reference to a specific version of the symbol within the shared library, you can use the aliases of convenience (i.e. `old_foo'), or you can use the `.symver' directive to specifically bind to an external version of the function in question.

공유 라이브러리에서 심볼의 버전에 참조를 하려면 (`old_foo' 같은) 별칭을 사용하거나 외부 버전을 명시적으로 지정하기 위해서 `.symver' 지시어를 사용한다.

 

링커 스크립트의 표현식

The syntax for expressions in the linker script language is identical to that of C expressions. All expressions are evaluated as integers. All expressions are evaluated in the same size, which is 32 bits if both the host and target are 32 bits, and is otherwise 64 bits.

You can use and set symbol values in expressions.

The linker defines several special purpose builtin functions for use in expressions.

링커 스크립트 언어의 표현식은 C의 표현식과 동일하다. 모든 표현식은 정수로 취급된다.

표현식은 모두 같은 크기로, 호스트와 대상이 모두 32 비트이면 32 비트이고 그렇지 않다면 64 비트이다.

표현식에서 심볼값을 사용하거나, 표현식을 심볼값에 대입할 수 있다.

링커는 표현식에서 사용할 수 있는 특별한 목적의 기본 함수를 정의한다.

 

상수

All constants are integers.

As in C, the linker considers an integer beginning with `0' to be octal, and an integer beginning with `0x' or `0X' to be hexadecimal. The linker considers other integers to be decimal.

In addition, you can use the suffixes K and M to scale a constant by respectively. For example, the following all refer to the same quantity:

모든 상수는 정수이다.

C와 같이 `0'으로 시작하는 정수는 8 진수, `0x'`0X'로 시작하는 정수는 16 진수이다. 다른 정수는 10 진수로 취급한다. 추가로 접미사 KM를 사용할 수 있다. 예로 다음 모두 같은 값을 가진다.

  _fourk_1 = 4K;
  _fourk_2 = 4096;
  _fourk_3 = 0x1000;


심볼 이름

 

Unless quoted, symbol names start with a letter, underscore, or period and may include letters, digits, underscores, periods, and hyphens. Unquoted symbol names must not conflict with any keywords. You can specify a symbol which contains odd characters or has the same name as a keyword by surrounding the symbol name in double quotes:

따옴표하지 않으면 심볼 이름은 문자, `_', `.'로 시작하여 문자, 숫자, `_', `.', `-'을 포함한다. 따옴표하지 않은 심볼은 어떤 키워드와도 같은 이름을 하면 안된다. 심볼 이름에 쌍따옴표를 하여 이상한 문자를 포함한 이름이나 키워드와 같은 이름을 사용할 수 있다.

  "SECTION" = 9;
  "with a space" = "also with a space" + 10;

 

Since symbols can contain many non-alphabetic characters, it is safest to delimit symbols with spaces. For example, `A-B' is one symbol, whereas `A - B' is an expression involving subtraction.

심볼 이름은 알파벳 외의 문자도 포함할 수 있기 때문에 공백으로 심볼을 구분하는 것이 안전하다. 예로 `A-B'는 한 심볼이지만 `A - B'는 빼기를 포함한 표현식이다.

 

 

위치 카운터

The special linker variable dot `.' always contains the current output location counter. Since the . always refers to a location in an output section, it may only appear in an expression within a SECTIONS command. The . symbol may appear anywhere that an ordinary symbol is allowed in an expression.

Assigning a value to . will cause the location counter to be moved. This may be used to create holes in the output section. The location counter may never be moved backwards.

특별한 변수인 `.'는 항상 현재 위치 카운터를 저장한다. .가 항상 출력 섹션의 장소를 참조하기 때문에 SECTIONS 명령어 안의 표현식에서만 사용할 수 있다. .는 표현식에서 보통 심볼이 가능한 어떤 곳이라도 나올 수 있다. 값을 .에 대입하면 위치 카운터가 변경한다. 그래서 출력 섹션에 공백을 만들 수 있다. 위치 카운터는 절대로 뒤로 움직이지 않는다.

SECTIONS
{
  output :
    {
      file1(.text)
      . = . + 1000;
      file2(.text)
      . += 1000;
      file3(.text)
    } = 0x1234;
}

In the previous example, the `.text' section from `file1' is located at the beginning of the output section `output'. It is followed by a 1000 byte gap. Then the `.text' section from `file2' appears, also with a 1000 byte gap following before the `.text' section from `file3'. The notation `= 0x1234' specifies what data to write in the gaps (see section Output section fill).

Note: . actually refers to the byte offset from the start of the current containing object. Normally this is the SECTIONS statement, whoes start address is 0, hence . can be used as an absolute address. If . is used inside a section description however, it refers to the byte offset from the start of that section, not an absolute address. Thus in a script like this:

위에서 `file1'의 섹션 `.text'은 출력 섹션 `output'의 시작에 위치한다. 그 후 1000 바이트 빈공간이 온다. 그리고 `file2'의 섹션 `.text'이 나오고, `file3'의 섹션 `.text'과 사이에 1000 바이트 빈공간이 온다. `= 0x1234'는 빈공간에 쓰여질 자료를 (Output section fill 참고) 지정한다.

주의! .눈 항상 현재 객체 시작에서 바이트 옵셋을 지칭한다. 보통 이는 시작 주소가 0인 SECTIONS이므로 .은 절대 주소로 쓰인다. 그러나 .을 섹션 기술 안에서 사용하면 절대 주소가 아니라 그 섹션 시작에서 (바이트 단위) 옵셋을 지칭한다. 그래서 다음 스크립트에서,

SECTIONS
{
    . = 0x100
    .text: {
      *(.text)
      . = 0x200
    }
    . = 0x500
    .data: {
      *(.data)
      . += 0x600
    }
}

The `.text' section will be assigned a starting address of 0x100 and a size of exactly 0x200 bytes, even if there is not enough data in the `.text' input sections to fill this area. (If there is too much data, an error will be produced because this would be an attempt to move . backwards). The `.data' section will start at 0x500 and it will have an extra 0x600 bytes worth of space after the end of the values from the `.data' input sections and before the end of the `.data' output section itself.

`.text' 섹션은 0x100에서 시작하고 입력 섹션 `.text'에 이 크기를 채우기 충분한 자료가 없더라도 크기는 정확히 0x200 바이트이다. (너무 많은 자료가 있다면 .을 뒤로 이동하려하기 때문에 오류가 발생한다.) `.data' 섹션은 0x500에서 시작하고, 입력 섹션 `.data'의 내용 끝과 출력 섹션 `.data' 끝 사이에 0x600 바이트 추가 공간을 가진다.

연산자

The linker recognizes the standard C set of arithmetic operators, with the standard bindings and precedence levels: { @obeylines@parskip=0pt@parindent=0pt @dag@quad Prefix operators. @ddag@quad See section Assigning Values to Symbols. }

 

링커는 표준 C의 산술 연산자를 같은 우선순위로 인식한다. (선행 연산자)

우선순위 순서 연산자
1 왼쪽에서 ! - ~
2 왼쪽에서 * / %
3 왼쪽에서 + -
4 왼쪽에서 >> <<
5 왼쪽에서 == != > < >=
6 왼쪽에서 &
7 왼쪽에서 |
8 왼쪽에서 &&
9 왼쪽에서 ||
10 오른쪽에서 ? :
11 오른쪽에서 &= += -= *= /= (Assigning Values to Symbols 참고)

 


값 평가

The linker evaluates expressions lazily. It only computes the value of an expression when absolutely necessary.

The linker needs some information, such as the value of the start address of the first section, and the origins and lengths of memory regions, in order to do any linking at all. These values are computed as soon as possible when the linker reads in the linker script.

However, other values (such as symbol values) are not known or needed until after storage allocation. Such values are evaluated later, when other information (such as the sizes of output sections) is available for use in the symbol assignment expression.

링커는 값 평가를 게으르게 한다. 즉, 표현식 값이 필요할 때에 계산한다.

링커는 링크를 하기 위해서 첫번째 섹션의 시작 주소나 메모리 영역의 시작과 크기와 같은 정보를 필요로 한다. 이 값은 링커가 스크립트에서 읽는 즉시 계산된다.

그러나 (심볼값과 같은) 다른 값은 공간 할당 후에도 모르거나 필요하지 않을 수 있다. 이런 값은 나중에 심볼 대입 표현식에서 (출력 섹션의 크기와 같은) 다른 정보가 필요할 때 계산된다.

 

The sizes of sections cannot be known until after allocation, so assignments dependent upon these are not performed until after allocation.

Some expressions, such as those depending upon the location counter `.', must be evaluated during section allocation.

If the result of an expression is required, but the value is not available, then an error results. For example, a script like the following

섹션의 크기는 할당이 끝날 때까지 알 수 없다. 그래서 이에 의존하는 대입은 할당이 끝날 때까지 수행할 수 없다. 위치 카운터 `.'에 의존하는 등의 표현식은 섹션 할당 중에 계산되야 한다.

표현식의 결과가 필요하지만 계산에 필요한 값을 구할 수 없다면 오류가 발생한다. 예를 들어 다음 스크립트는,

SECTIONS
  {
    .text 9+this_isnt_constant :
      { *(.text) }
  }

will cause the error message `non constant expression for initial address'.

`non constant expression for initial address'라는 오류문을 출력한다.

 

섹션의 표현

When the linker evaluates an expression, the result is either absolute or relative to some section. A relative expression is expressed as a fixed offset from the base of a section.

The position of the expression within the linker script determines whether it is absolute or relative. An expression which appears within an output section definition is relative to the base of the output section. An expression which appears elsewhere will be absolute.

A symbol set to a relative expression will be relocatable if you request relocatable output using the `-r' option. That means that a further link operation may change the value of the symbol. The symbol's section will be the section of the relative expression.

링커가 표현식을 계산할 때 결과는 섹션에 절대적이거나 상대적이다. 상대 표현은 섹션의 시작에서 변하지 않는 옵셋이다. 절대적인지 상대적인지는 스크립트에서 표현식의 위치가 결정한다. 출력 섹션 정의 안의 표현식은 출력 섹션에 상대적이다. 그외의 표현식은 절대적이다.

상대 표현의 심볼은 `-r' 옵션으로 재배치가능한 출력을 요구하면 재배치가능하게 된다. 즉 다음 링크에서도 심볼값을 변경할 수 있다. 심볼이 위치하는 섹션은 상대 표현의 기준이다.

A symbol set to an absolute expression will retain the same value through any further link operation. The symbol will be absolute, and will not have any particular associated section.

You can use the builtin function ABSOLUTE to force an expression to be absolute when it would otherwise be relative. For example, to create an absolute symbol set to the address of the end of the output section `.data':

절대 표현의 심볼은 링크를 더해도 값이 변하지 않는다. 심볼은 절대 심볼이고 연관된 섹션이 없다.

기본 함수 ABSOLUTE은 표현식을 절대 표현으로 변경한다. 예를 들어 출력 섹션 `.data' 끝에 절대 심볼을 만드려면,

SECTIONS
  {
    .data : { *(.data) _edata = ABSOLUTE(.); }
  }

If `ABSOLUTE' were not used, `_edata' would be relative to the `.data' section.

`ABSOLUTE'이 없다면 `_edata'은 섹션 `.data'에 상대적이다.

 

 

기본 함수

The linker script language includes a number of builtin functions for use in linker script expressions.
링커 스크립트 표현식에 사용할 수 있는 기본 함수들은 다음과 같다.

ABSOLUTE(exp)
Return the absolute (non-relocatable, as opposed to non-negative) value of the expression exp. Primarily useful to assign an absolute value to a symbol within a section definition, where symbol values are normally section relative. See section The Section of an expression.
표현식 exp의 (재배치가능하지 않은) 절대값을 반환한다. 심볼값이 섹션에 상대적인, 섹션 정의에 나오는 심볼에 절대값을 대입하는데 유용하다. The Section of an expression를 참고하라.
ADDR(section)
Return the absolute address (the VMA) of the named section. Your script must previously have defined the location of that section. In the following example, symbol_1 and symbol_2 are assigned identical values:
section의 절대 주소를 (VMA) 반환한다. 스크립트는 이 섹션의 주소를 전에 정의해야 한다. 다음 예에서 symbol_1symbol_2에는 같은 값이 대입된다.
SECTIONS { ...
  .output1 :
    {
    start_of_output_1 = ABSOLUTE(.);
    ...
    }
  .output :
    {
    symbol_1 = ADDR(.output1);
    symbol_2 = start_of_output_1;
    }
... }
ALIGN(exp)
Return the location counter (.) aligned to the next exp boundary. exp must be an expression whose value is a power of two. This is equivalent to
다음 exp 경계에 정렬한 위치 카운터를 (.) 반환한다. exp는 2의 제곱수이어야 한다. 이 함수는 아래와 같다.
(. + exp - 1) & ~(exp - 1)
ALIGN doesn't change the value of the location counter--it just does arithmetic on it. Here is an example which aligns the output .data section to the next 0x2000 byte boundary after the preceding section and sets a variable within the section to the next 0x8000 boundary after the input sections:
ALIGN는 위치 카운터 값을 변경하지 않고 단지 계산만 한다. 아래 예는 출력 섹션 .data을 바로 전 섹션 다음에 0x2000 바이트 경계로 정렬하고, 섹션 안에 variable를 입력 섹션 다음 0x8000 경계로 설정한다.
SECTIONS { ...
  .data ALIGN(0x2000): {
    *(.data)
    variable = ALIGN(0x8000);
  }
... }
The first use of ALIGN in this example specifies the location of a section because it is used as the optional address attribute of a section definition (see section Output section address). The second use of ALIGN is used to defines the value of a symbol. The builtin function NEXT is closely related to ALIGN.
위의 첫 ALIGN는 섹션 정의의 (Output section address 참고) 선택적인 address 속성으로 사용하여 섹션의 주소를 지정한다. 두번째는 심볼값을 정의한다. 기본 함수 NEXTALIGN과 연관이 있다.
 
BLOCK(exp)
This is a synonym for ALIGN, for compatibility with older linker scripts. It is most often seen when setting the address of an output section.
이는 오래된 링커 스크립트와 호환을 위한 것으로 ALIGN과 동일하다. 출력 섹션 주소를 설정할 때 주로 사용한다.
DEFINED(symbol)
Return 1 if symbol is in the linker global symbol table and is defined, otherwise return 0. You can use this function to provide default values for symbols. For example, the following script fragment shows how to set a global symbol `begin' to the first location in the `.text' section--but if a symbol called `begin' already existed, its value is preserved:
symbol이 전역 심볼표에 있고 정의되있다면 1을 반환하고, 아니라면 0을 반환한다. 이 함수는 심볼의 기본값을 주는데 사용한다. 아래는 전역 심볼 `begin'이 이미 정의되있다면 그 값을 유지하고, 정의되있지 않다면 섹션 `.text'의 처음으로 설정하는 예이다.
SECTIONS { ...
  .text : {
    begin = DEFINED(begin) ? begin : . ;
    ...
  }
  ...
}
LOADADDR(section)
Return the absolute LMA of the named section. This is normally the same as ADDR, but it may be different if the AT attribute is used in the output section definition (see section Output section LMA).
섹션 section의 절대 LMA를 반환한다. 이는 보통 ADDR과 같지만, 출력 섹션 정의에 (Output section LMA 참고) AT 속성을 사용한다면 다르다.
MAX(exp1, exp2)
Returns the maximum of exp1 and exp2.
exp1exp2 중 큰 값을 반환한다.
MIN(exp1, exp2)
Returns the minimum of exp1 and exp2.
exp1exp2 중 작은 값을 반환한다.
NEXT(exp)
Return the next unallocated address that is a multiple of exp. This function is closely related to ALIGN(exp); unless you use the MEMORY command to define discontinuous memory for the output file, the two functions are equivalent.
exp의 배수인 할당되지 않은 다음 주소를 반환한다. 이 함수는 ALIGN(exp)과 연관이 있다. 출력 파일에 MEMORY로 불연속적인 메모리를 정의하지 않다면 두 함수는 동일하다.
SIZEOF(section)
Return the size in bytes of the named section, if that section has been allocated. If the section has not been allocated when this is evaluated, the linker will report an error. In the following example, symbol_1 and symbol_2 are assigned identical values:
섹션 section이 정의되었다면 그 크기를 바이트 단위로 반환한다. 값을 계산할 때 섹션이 할당되지 않았다면 오류를 발생한다. 다음 예에서 symbol_1symbol_2에 같은 값이 대입된다.
SECTIONS{ ...
  .output {
    .start = . ;
    ...
    .end = . ;
    }
  symbol_1 = .end - .start ;
  symbol_2 = SIZEOF(.output);
... }
 
SIZEOF_HEADERS
sizeof_headers
Return the size in bytes of the output file's headers. This is information which appears at the start of the output file. You can use this number when setting the start address of the first section, if you choose, to facilitate paging. When producing an ELF output file, if the linker script uses the SIZEOF_HEADERS builtin function, the linker must compute the number of program headers before it has determined all the section addresses and sizes. If the linker later discovers that it needs additional program headers, it will report an error `not enough room for program headers'. To avoid this error, you must avoid using the SIZEOF_HEADERS function, or you must rework your linker script to avoid forcing the linker to use additional program headers, or you must define the program headers yourself using the PHDRS command (see section PHDRS Command).
출력파일 헤더의 크기를 바이트 단위로 반환한다. 헤더는 출력파일 시작 부분에 나오는 정보이다. 페이징을 돕기 위해 첫 섹션의 시작 주소를 이 값으로 할 수 있다. ELF 출력파일을 만들 때 링커 스크립트가 함수 SIZEOF_HEADERS를 사용하면 링커는 모든 섹션의 주소와 크기를 알기 전에 프로그램 헤더의 크기를 계산해야 한다. 링커가 나중에 추가로 프로그램 헤더가 필요하면 `not enough room for program headers'을 오류문으로 출력한다. 이를 피하기 위해서 SIZEOF_HEADERS 함수를 사용하지 않거나, 추가로 프로그램 헤더를 사용하지 않게 링커 스크립트를 재작성하거나, PHDRS 명령어로 (PHDRS Command 참고) 직접 프로그램 헤더를 정의해야 한다.


암묵 링커 스크립트

 

If you specify a linker input file which the linker can not recognize as an object file or an archive file, it will try to read the file as a linker script. If the file can not be parsed as a linker script, the linker will report an error. An implicit linker script will not replace the default linker script.

링커는 오브젝트 파일이나 아카이브 파일로 인식되지 않는 입력파일을 링커 스크립트로 간주한다. 이 파일이 링커 스크립트로 인식되지 않으면 오류가 발생한다.

이 암묵 링커 스크립트는 기본 링커 스크립트를 대체하지 않는다.

 

Typically an implicit linker script would contain only symbol assignments, or the INPUT, GROUP, or VERSION commands. Any input files read because of an implicit linker script will be read at the position in the command line where the implicit linker script was read. This can affect archive searching.

전형적으로 암묵 링커 스크립트는 심볼 대입이나 INPUT, GROUP, VERSION 명령어들 만을 포함한다.

암묵 스크립트가 요구하는 입력파일은 명령행에서 암묵 링커 스크립트의 자리에서 읽힌다. 이는 아카이브 검색에 영향을 준다.