GNU链接器简介-3

GNU链接器简介-3

  • 1 SECTIONS Command
    • 1.1 Output Section Description
    • 2.2 Output Section Name
    • 1.3 Output Section Address
    • 1.4 Input Section Description
      • 1.4.1 Input Section Basics
      • 1.4.2 Input Section Wildcard Patterns
      • 1.4.3 Input Section for Common Symbols
      • 1.4.4 Input Section and Garbage Collection
      • 1.4.5 Input Section Example
    • 1.5 Output Section Data
    • 1.6 Output Section Keywords
    • 1.7 Output Section Discarding
    • 1.8 Output Section Attributes
      • 1.8.1 Output Section Type
      • 1.8.2 Output Section LMA
      • 1.8.3 Forced Output Alignment
      • 1.8.4 Forced Input Alignment
      • 1.8.5 Output Section Constraint
      • 1.8.6 Output Section Region
      • 1.8.7 Output Section Phdr
      • 1.8.8 Output Section Fill
    • 1.9 Overlay Description
  • 2 MEMORY Command
  • 3 PHDRS Command

该篇文章是基于对 The GNU linker的翻译,并添加了部分自己的理解。

1 SECTIONS Command

The SECTIONS command tells the linker how to map input sections into output sections, and how to place the output sections in memory.
SECTIONS命令告诉链接器如何将输入段映射到输出段,以及如何将输出段放置在内存中。
The format of the SECTIONS command is:
SECTIONS命令的格式是:

SECTIONS
{sections-commandsections-command…
}

Each sections-command may of be one of the following:
每个部分命令可以使一下之一:

  • an ENTRY command (see Entry command)
  • an ENTRY command(参考Entry 命令)
  • a symbol assignment (see Assigning Values to Symbols)
  • 符号赋值(参考符号赋值)
  • an output section description
  • 输出部分描述
  • an overlay description
  • 覆盖层描述

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.
在SECTIONS命令中允许使用ENTRY命令和符号赋值,以便在这些命令中方便地使用位置计数器。这也可以使链接器脚本更容易理解,因为你可以在输出文件布局中有意义的点使用这些命令。
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.
如果你在链接器脚本中不使用SECTIONS命令,链接器会按照输入文件中首次遇到的顺序,将每个输入段放置到同名的输出段中。例如,如果所有输入段都存在于第一个文件中,那么输出文件中的段顺序将与第一个输入文件中的顺序相匹配。第一个段将位于地址零。

  • Output Section Description
  • 输出段描述
  • Output Section Name
  • 输出段名字
  • Output Section Address
  • 输出段地址
  • Input Section Description
  • 输入段描述
  • Output Section Data
  • 输出段数据
  • Output Section Keywords
  • 输出部分关键词
  • Output Section Discarding
  • 输出段丢弃
  • Output Section Attributes
  • 输出段属性
  • Overlay Description
  • 叠加说明

1.1 Output Section Description

The full description of an output section looks like this:
一个输出部分的完整描述如下:

section [address] [(type)] :[AT(lma)][ALIGN(section_align) | ALIGN_WITH_INPUT][SUBALIGN(subsection_align)][constraint]{output-section-commandoutput-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 comma at the end may be required if a fillexp is used and the next sections-command looks like a continuation of the expression. The line breaks and other white space are optional.
节周围的空白是必需的,这样节的名称才是明确的。冒号和大括号也是必需的。如果使用了fillexp并且下一个sections-command看起来像是表达式的延续,那么表达式末尾的逗号可能是必需的。换行和其他空白是可选的。
Each output-section-command may be one of the following:
每个输出部分命令可以是以下之一:

  • a symbol assignment (see Assigning Values to Symbols)
  • 符号赋值(请参考符号赋值)
  • an input section description (see Input Section Description)
  • 输入段的描述(请参考输入段描述)
  • data values to include directly (see Output Section Data)
  • 直接包含的数据值(见输出段数据)
  • a special output section keyword (see Output Section Keywords)
  • 一个输出段的关键词(请参考输出段关键字)

2.2 Output Section Name

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.
输出部分的名称是sectionsection必须满足你的输出格式的约束。在只支持有限数量部分的格式中,例如a.out,名称必须是格式支持的名称之一(例如,a.out只允许'.text''.data''.bss')。如果输出格式支持任意数量的部分,但使用数字而不是名称(如Oasys的情况),则应将名称作为带引号的数字字符串提供。部分名称可以由任何字符序列组成,但是如果名称包含任何不寻常的字符,如逗号,则必须加上引号。
The output section name ‘/DISCARD/’ is special; Output Section Discarding.
输出部分名称‘/DISCARD/’是特殊的;

1.3 Output Section Address

The address is an expression for the VMA (the virtual memory address) of the output section. This address is optional, but if it is provided then the output address will be set exactly as specified.
地址是对输出段的虚拟内存地址(VMA)的表达。这个地址是可选的,但如果提供了这个地址,输出地址将会被精确地设置为指定的值。
If the output address is not specified then one will be chosen for the section, based on the heuristic below. This address will be adjusted to fit the alignment requirement of the output section. The alignment requirement is the strictest alignment of any input section contained within the output section.
如果未指定输出地址,则将根据下面的启发式方法为该部分选择一个地址。该地址将根据输出部分的对齐要求进行调整。对齐要求是输出部分中包含的任何输入部分的最严格对齐要求。
The output section address heuristic is as follows:
输出部分地址启发式如下:

  • If an output memory region is set for the section then it is added to this region and its address will be the next free address in that region.
  • 如果为该段设置了输出内存区域,则它将被添加到该区域中,其地址将是该区域中下一个可用的地址。
  • If the MEMORY command has been used to create a list of memory regions then the first region which has attributes compatible with
    the section is selected to contain it. The section’s output address will be the next free address in that region; MEMORY Command.
    如果已经使用MEMORY命令创建了一个内存区域列表,那么会选择第一个与该段属性兼容的区域来包含它。该段的输出地址将是该区域中下一个空闲地址;
  • If no memory regions were specified, or none match the section then the output address will be based on the current value of the
    location counter.
    如果没有指定内存区域,或者没有与该部分匹配的区域,那么输出地址将基于位置计数器的当前值。

For example:

.text . : { *(.text) }

and

.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 any of the ‘.text’ input sections.
它们微妙地不同。第一个会将'.text'输出段的地址设置为位置计数器的当前值。第二个会将其设置为位置计数器的当前值,该值与任何'.text'输入段中最严格的对齐方式对齐。
The address may be an arbitrary expression; 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:
地址可以是任意表达式;链接脚本中的表达式。例如,如果要在 0x10 字节边界对齐分段,使分段地址的最低四位为零,可以这样做:

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

This works because ALIGN returns the current location counter aligned upward to the specified value.
这是因为ALIGN函数将当前的位置计数器向上对齐到指定的值。
Specifying address for a section will change the value of the location counter, provided that the section is non-empty. (Empty sections are ignored).
指定一个节的地址会改变位置计数器的值,前提是该节非空。(空节会被忽略)。

1.4 Input Section Description

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.
输入段描述是最基本的链接器脚本操作。您使用输出部段来告诉链接器如何在内存中布局您的程序。您使用输入部分描述来告诉链接器如何将输入文件映射到您的内存布局中。

  • Input Section Basics
  • 输入段基础
  • Input Section Wildcard Patterns
  • 输入段通配符模式
  • Input Section for Common Symbols
  • 常见符号输入段
  • Input Section and Garbage Collection
  • 输入段和垃圾回收机制
  • Input Section Example
  • 输入段样例

1.4.1 Input Section Basics

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 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:
最常见的输入段描述是将所有具有特定名称的输入段包含在输出段中。例如,要包含所有的输入“.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列表中指定的文件之外的所有文件。例如:

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

will cause all .ctors sections from all files except crtend.o and otherfile.o to be included. The EXCLUDE_FILE can also be placed inside the section list, for example:
将导致所有文件(除了‘crtend.o’和‘otherfile.o’)的所有.ctors段被包含。EXCLUDE FILE也可以放在段列表中,例如:

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

The result of this is identically to the previous example. Supporting two syntaxes for EXCLUDE_FILE is useful if the section list contains more than one section, as described below.
这个结果与前一个示例完全相同。如果部分列表包含多个部分,如下面所述,支持EXCLUDE FILE的两种语法是有用的。
There are two ways to include more than one section:
有两种方式可以包含不止一个部分:

*(.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, appearing in the same order as they are found in the linker input. In the second example, all ‘.text’ input sections will appear first, followed by all ‘.rdata’ input sections.
这些之间的区别在于‘.text’‘.rdata’输入段在输出段中出现的顺序。在第一个例子中,它们将被混合在一起,按照它们在链接器输入中找到的顺序出现。在第二个例子中,所有的‘.text’输入段将首先出现,然后是所有的‘.rdata’输入段。
When using EXCLUDE_FILE with more than one section, if the exclusion is within the section list then the exclusion only applies to the immediately following section, for example:
当使用EXCLUDE FILE命令并指定多个部分时,如果排除项在部分列表内,则排除仅适用于紧随其后的部分,例如:

*(EXCLUDE_FILE (*somefile.o) .text .rdata)

will cause all ‘.text’ sections from all files except somefile.o to be included, while all ‘.rdata’ sections from all files, including somefile.o, will be included. To exclude the ‘.rdata’ sections from somefile.o the example could be modified to:
将导致除了'somefile.o'之外的所有文件中的'.text'部分被包含,同时包括'somefile.o'在内的所有文件的'.rdata'部分也将被包含。要排除'somefile.o'中的'.rdata'部分,示例可以修改为:

*(EXCLUDE_FILE (*somefile.o) .text EXCLUDE_FILE (*somefile.o) .rdata)

Alternatively, placing the EXCLUDE_FILE outside of the section list, before the input file selection, will cause the exclusion to apply for all sections. Thus the previous example can be rewritten as:
或者,将排除文件放置在部分列表之外,在输入文件选择之前,将导致排除适用于所有部分。因此,前面的例子可以重写为:

EXCLUDE_FILE (*somefile.o) *(.text .rdata)

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:
你可以指定一个文件名来包含来自特定文件的部分。如果你的一个或多个文件包含需要位于内存中特定位置的特殊数据,你会这样做。例如:

data.o(.data)

To refine the sections that are included based on the section flags of an input section, INPUT_SECTION_FLAGS may be used.
为了根据输入段的段标志细化包含的段部分,可以使用输入段标志。
Here is a simple example for using Section header flags for ELF sections:
这里有一个使用ELF节区标志的简单示例:

SECTIONS {.text : { INPUT_SECTION_FLAGS (SHF_MERGE & SHF_STRINGS) *(.text) }.text2 :  { INPUT_SECTION_FLAGS (!SHF_WRITE) *(.text) }
}

In this example, the output section ‘.text’ will be comprised of any input section matching the name *(.text) whose section header flags SHF_MERGE and SHF_STRINGS are set. The output section ‘.text2’ will be comprised of any input section matching the name *(.text) whose section header flag SHF_WRITE is clear.
在这个例子中,输出部分“.text”将由任何匹配名称*(.text)且其节头标志SHF_MERGESHF_STRINGS被设置的输入部分组成。输出部分“.text2”将由任何匹配名称*(.text)且其节头标志SHF_WRITE未设置的输入部分组成。
You can also specify files within archives by writing a pattern matching the archive, a colon, then the pattern matching the file, with no whitespace around the colon.
您也可以通过写一个匹配存档的模式,后面跟一个冒号,然后是匹配文件的模式,冒号周围不要有空格,来指定存档内的文件。

‘archive:file’

matches file within archive
存档的匹配文件

‘archive:

matches the whole archive
匹配整个的归档

:file’

matches file but not one in an archive
匹配文件但不匹配存档中的一个
Either one or both of ‘archive’ and ‘file’ can contain shell wildcards. On DOS based file systems, the linker will assume that a single letter followed by a colon is a drive specifier, so ‘c:myfile.o’ is a simple file specification, not ‘myfile.o’ within an archive called ‘c’. ‘archive:file’ filespecs may also be used within an EXCLUDE_FILE list, but may not appear in other linker script contexts. For instance, you cannot extract a file from an archive by using ‘archive:file’ in an INPUT command.
“archive”“file”中的任意一个或两者都可以包含shell通配符。在基于DOS的文件系统中,链接器会假定一个单独的字母后跟一个冒号是一个驱动器标识符,因此“c:myfile.o”是一个简单的文件规范,而不是在名为“c”的存档中的“myfile.o”。也可以在EXCLUDE_FILE列表中使用“archive:file”文件规范,但它们可能不会出现在其他链接器脚本上下文中。例如,你不能通过在INPUT命令中使用“archive:file”来从存档中提取文件。
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 is not an ‘archive:file’ specifier and 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.
当你使用一个不是“archive:file”指定符且不包含任何通配符的文件名时,链接器首先会检查你是否也在链接器命令行或在INPUT命令中指定了该文件名。如果你没有这样做,链接器将尝试将该文件作为输入文件打开,就好像它出现在命令行上一样。请注意,这与INPUT命令不同,因为链接器不会在归档搜索路径中搜索该文件。

1.4.2 Input Section Wildcard Patterns

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.
通配符模式类似于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
匹配任意单个字符;可以使用‘-’字符来指定一系列字符,如‘[a-z]’来匹配任何小写字母。

  • ‘\’

quotes the following 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_BY_NAME keyword, which appears before a wildcard pattern in parentheses (e.g., SORT_BY_NAME(.text*)). When the SORT_BY_NAME keyword is used, the linker will sort the files or sections into ascending order by name before placing them in the output file.
通常情况下,链接器会按照在链接过程中遇到的顺序将匹配通配符的文件和段放置。你可以通过使用SORT_BY_NAME关键字来改变这一顺序,该关键字出现在括号内的通配符模式之前(例如,SORT_BY_NAME(.text*))。当使用SORT_BY_NAME关键字时,链接器会在将文件或段放入输出文件之前,按名称的升序对它们进行排序。
SORT_BY_ALIGNMENT is similar to SORT_BY_NAME. SORT_BY_ALIGNMENT will sort sections into descending order of alignment before placing them in the output file. Placing larger alignments before smaller alignments can reduce the amount of padding needed.
SORT_BY_ALIGNMENT 类似于 SORT_BY_NAMESORT_BY_ALIGNMENT 会先将部分按照对齐度降序排序,然后再将它们放入输出文件中。将较大的对齐度放在前面可以减少所需的填充量。
SORT_BY_INIT_PRIORITY is also similar to SORT_BY_NAME. SORT_BY_INIT_PRIORITY will sort sections into ascending numerical order of the GCC init_priority attribute encoded in the section name before placing them in the output file. In .init_array.NNNNN and .fini_array.NNNNN, NNNNN is the init_priority. In .ctors.NNNNN and .dtors.NNNNN, NNNNN is 65535 minus the init_priority.
SORT_BY_INIT_PRIORITY 与 SORT_BY_NAME 类似。SORT_BY_INIT_PRIORITY 会根据节名称中编码的 GCC 初始化优先级属性将节排序为升序数值顺序,然后再将它们放置到输出文件中。在 .init_array.NNNNN.fini_array.NNNNN 中,NNNNN 是初始化优先级。在 .ctors.NNNNN.dtors.NNNNN 中,NNNNN65535 减去初始化优先级。
SORT is an alias for SORT_BY_NAME.
SORTSORT_BY_NAME的别名。
When there are nested section sorting commands in linker script, there can be at most 1 level of nesting for section sorting commands.
当链接脚本中有嵌套的段排序命令时,段排序命令最多只能嵌套1层。

  1. SORT_BY_NAME (SORT_BY_ALIGNMENT (wildcard section pattern)). It will sort the input sections by name first, then by alignment if two sections have the same name.
    SORT_BY_NAME (SORT_BY_ALIGNMENT (通配符部分模式)). 它会首先按名称对输入部分进行排序,如果两个部分名称相同,则按对齐方式排序。
  2. SORT_BY_ALIGNMENT (SORT_BY_NAME (wildcard section pattern)). It will sort the input sections by alignment first, then by name if two sections have the same alignment.
    SORT_BY_ALIGNMENT (SORT_BY_NAME (通配符部分模式))。它会首先按对齐方式对输入的部分进行排序,如果两个部分对齐方式相同,则按名称排序。
  3. SORT_BY_NAME (SORT_BY_NAME (wildcard section pattern)) is treated the same as SORT_BY_NAME (wildcard section pattern).
    SORT_BY_NAME (SORT_BY_NAME (wildcard section pattern)) 被视为与 SORT_BY_NAME (wildcard section pattern) 相同。
  4. SORT_BY_ALIGNMENT (SORT_BY_ALIGNMENT (wildcard section pattern)) is treated the same as SORT_BY_ALIGNMENT (wildcard section pattern).
    SORT_BY_ALIGNMENT (SORT_BY_ALIGNMENT (通配符部分模式)) 被视为与 SORT_BY_ALIGNMENT (通配符部分模式) 相同。
  5. All other nested section sorting commands are invalid.
    所有其他嵌套的节排序命令都是无效的。

When both command-line section sorting option and linker script section sorting command are used, section sorting command always takes precedence over the command-line option.
当同时使用命令行部分排序选项和链接器脚本部分排序命令时,部分排序命令总是优先于命令行选项。
If the section sorting command in linker script isn’t nested, the command-line option will make the section sorting command to be treated as nested sorting command.
如果链接脚本中的段排序命令没有嵌套,那么命令行选项将使段排序命令被视为嵌套排序命令。

  1. SORT_BY_NAME (wildcard section pattern ) with --sort-sections alignment is equivalent to SORT_BY_NAME SORT_BY_ALIGNMENT (wildcard section pattern)).
    SORT_BY_NAME(通配符部分模式)‘--sort-sections alignment’等效于SORT_BY_NAME(SORT_BY_ALIGNMENT(通配符部分模式))
  2. SORT_BY_ALIGNMENT (wildcard section pattern) with --sort-section name is equivalent to SORT_BY_ALIGNMENT (SORT_BY_NAME (wildcard section pattern)).
    SORT_BY_ALIGNMENT (通配符部分模式)‘--sort-section name’ 等价于 SORT_BY_ALIGNMENT (SORT_BY_NAME (通配符部分模式))

If the section sorting command in linker script is nested, the command-line option will be ignored.
如果链接器脚本中的段排序命令是嵌套的,那么命令行选项将被忽略。
SORT_NONE disables section sorting by ignoring the command-line section sorting option.
SORT_NONE 禁用通过忽略命令行部分排序选项来实现的部分排序。
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.
如果你对输入部分的去向感到困惑,可以使用‘-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) }
}

1.4.3 Input Section for Common Symbols

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’.
需要一种特殊的符号表示法来表示常见的符号,因为在许多目标文件格式中,常见的符号并没有特定的输入段。链接器将常见的符号视为它们位于一个名为‘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”部分的文件名。你可以用这个方法将特定输入文件中的通用符号放在一个部分,而将其他输入文件中的通用符号放在另一个部分。
In most cases, common symbols in input files will be placed in the ‘.bss’ section in the output file. For example:
在大多数情况下,输入文件中的常见符号会被放置在输出文件的‘.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.
一些目标文件格式具有多种类型的常见符号。例如,MIPS ELF目标文件格式区分标准常见符号和小型常见符号。在这种情况下,链接器将为其他类型的常见符号使用不同的特殊节名称。在MIPS ELF的情况下,链接器使用'COMMON'用于标准常见符号,使用'.scommon'用于小型常见符号。这允许你将不同类型的常见符号映射到内存的不同位置。
You will sometimes see ‘[COMMON]’ in old linker scripts. This notation is now considered obsolete. It is equivalent to ‘*(COMMON)’.
在旧的链接脚本中,你有时会看到‘[COMMON]’这样的标记。这种表示法现在被认为是过时的。它等同于‘*(COMMON)’

1.4.4 Input Section and Garbage Collection

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_BY_NAME()(.ctors)).
当使用链接时垃圾收集(‘--gc-sections’)时,通常很有用标记不应该被消除的节。这可以通过用KEEP()包围输入节的通配符条目来实现,例如KEEP(*(.init))KEEP(SORT_BY_NAME(*)(.ctors))

1.4.5 Input Section Example

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’中的所有节,并将它们放置在输出节‘outputa’的开始处,该节从位置‘0x10000’开始。紧接着,文件‘foo.o’中的所有‘.input1’节紧随其后,位于同一个输出节中。来自‘foo.o’的所有‘.input2’节被放入输出节‘outputb’,后面跟着来自‘foo1.o’‘.input1’节。任何文件中剩余的‘.input1’‘.input2’节都被写入输出节‘outputc’

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

If an output section’s name is the same as the input section’s name and is representable as a C identifier, then the linker will automatically see PROVIDE two symbols: __start_SECNAME and __stop_SECNAME, where SECNAME is the name of the section. These indicate the start address and end address of the output section respectively. Note: most section names are not representable as C identifiers because they contain a ‘.’ character.
如果输出段的名称与输入段的名称相同,并且可以表示为C标识符,那么链接器将自动识别两个符号:__start_SECNAME__stop_SECNAME,其中SECNAME是该段的名称。这些分别表示输出段的起始地址和结束地址。注意:大多数段名称不能表示为C标识符,因为它们包含一个'.'字符。

1.5 Output Section Data

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 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.

For example, this will store the byte 1 followed by the four byte value of the symbol ‘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.

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 value 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 ‘0x90’:

FILL(0x90909090)

The FILL command is similar to the ‘=fillexp’ output section attribute, 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. See Output Section Fill, for details on the fill expression.

1.6 Output Section Keywords

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.

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 CTOR_END marks the end. Similarly, DTOR_LIST and DTOR_END mark the start and end of the global destructors. 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.

  __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_BY_NAME(CONSTRUCTORS)’ instead. When using the .ctors and .dtors sections, use ‘(SORT_BY_NAME(.ctors))’ and ‘(SORT_BY_NAME(.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.

1.7 Output Section Discarding

The linker will not normally create output sections with no 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, and if the input sections are not all empty. Other link script directives that allocate space in an output section will also create the output section. So too will assignments to dot even if the assignment does not create space, except for ‘. = 0’, ‘. = . + 0’, ‘. = sym’, ‘. = . + sym’ and ‘. = ALIGN (. != 0, expr, 1)’ when ‘sym’ is an absolute symbol of value 0 defined in the script. This allows you to force output of an empty section with ‘. = .’.

The linker will ignore address assignments (see Output Section Address) on discarded output sections, except when the linker script defines symbols in the output section. In that case the linker will obey the address assignments, possibly advancing dot even though the section is discarded.

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.

This can be used to discard input sections marked with the ELF flag SHF_GNU_RETAIN, which would otherwise have been saved from linker garbage collection.

Note, sections that match the ‘/DISCARD/’ output section will be discarded even if they are in an ELF section group which has other members which are not being discarded. This is deliberate. Discarding takes precedence over grouping.

1.8 Output Section Attributes

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

section [address] [(type)] :[AT(lma)][ALIGN(section_align) | ALIGN_WITH_INPUT][SUBALIGN(subsection_align)][constraint]{output-section-commandoutput-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.

  • Output Section Type
  • Output Section LMA
  • Forced Output Alignment
  • Forced Input Alignment
  • Output Section Constraint
  • Output Section Region
  • Output Section Phdr
  • Output Section Fill

1.8.1 Output Section Type

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.

READONLY
The section should be marked as read-only.

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.

TYPE = type
Set the section type to the integer type. When generating an ELF output file, type names SHT_PROGBITS, SHT_STRTAB, SHT_NOTE, SHT_NOBITS, SHT_INIT_ARRAY, SHT_FINI_ARRAY, and SHT_PREINIT_ARRAY are also allowed for type. It is the user’s responsibility to ensure that any special requirements of the section type are met.

Note - the TYPE only is used if some or all of the contents of the section do not have an implicit type of their own. So for example:

  .foo . TYPE = SHT_PROGBITS { *(.bar) }

will set the type of section ‘.foo’ to the type of the section ‘.bar’ in the input files, which may not be the SHT_PROGBITS type. Whereas:

  .foo . TYPE = SHT_PROGBITS { BYTE(1) }

will set the type of ‘.foo’ to SHT_PROGBBITS. If it is necessary to override the type of incoming sections and force the output section type then an extra piece of untyped data will be needed:

  .foo . TYPE = SHT_PROGBITS { BYTE(1); *(.bar) }

READONLY ( TYPE = type )
This form of the syntax combines the READONLY type with the type specified by type.

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.

SECTIONS {ROM 0 (NOLOAD) : {}}

1.8.2 Output Section LMA

Every section has a virtual address (VMA) and a load address (LMA); see Basic Linker Script Concepts. The virtual address is specified by the see Output Section Address described earlier. The load address is specified by the AT or AT> keywords. Specifying a load address is optional.

The AT keyword takes an expression as an argument. This specifies the exact load address of the section. The AT> keyword takes the name of a memory region as an argument. See MEMORY Command. The load address of the section is set to the next free address in the region, aligned to the section’s alignment requirements.

If neither AT nor AT> is specified for an allocatable section, the linker will use the following heuristic to determine the load address:

If the section has a specific VMA address, then this is used as the LMA address as well.
If the section is not allocatable then its LMA is set to its VMA.
Otherwise if a memory region can be found that is compatible with the current section, and this region contains at least one section, then the LMA is set so the difference between the VMA and LMA is the same as the difference between the VMA and LMA of the last section in the located region.
If no memory regions have been declared then a default region that covers the entire address space is used in the previous step.
If no suitable region could be found, or there was no previous section then the LMA is set equal to the VMA.
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.

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.

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;

1.8.3 Forced Output Alignment

You can increase an output section’s alignment by using ALIGN. As an alternative you can enforce that the difference between the VMA and LMA remains intact throughout this output section with the ALIGN_WITH_INPUT attribute.

1.8.4 Forced Input Alignment

You can force input section alignment within an output section by using SUBALIGN. The value specified overrides any alignment given by input sections, whether larger or smaller.

1.8.5 Output Section Constraint

You can specify that an output section should only be created if all of its input sections are read-only or all of its input sections are read-write by using the keyword ONLY_IF_RO and ONLY_IF_RW respectively.

1.8.6 Output Section Region

You can assign a section to a previously defined region of memory by using ‘>region’. See MEMORY Command.

Here is a simple example:

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

1.8.7 Output Section Phdr

You can assign a section to a previously defined program segment by using ‘:phdr’. See 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:

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

1.8.8 Output Section Fill

You can set the fill pattern for an entire section by using ‘=fillexp’. fillexp is an expression (see 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 value, repeated as necessary. If the fill expression is a simple hex number, ie. a string of hex digit starting with ‘0x’ and without a trailing ‘k’ or ‘M’, then an arbitrarily long sequence of hex digits can be used to specify the fill pattern; Leading zeros become part of the pattern too. For all other cases, including extra parentheses or a unary +, the fill pattern is the four least significant bytes of the value of the expression. In all cases, the number is big-endian.

You can also change the fill value with a FILL command in the output section commands; (see Output Section Data).

Here is a simple example:

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

1.9 Overlay Description

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 [start] : [NOCROSSREFS] [AT ( ldaddr )]{secname1{output-section-commandoutput-section-command…} [:phdr…] [=fill]secname2{output-section-commandoutput-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 construct (see SECTIONS Command), except that no addresses and no memory regions may be defined for sections within an OVERLAY.

The comma at the end may be required if a fill is used and the next sections-command looks like a continuation of the expression.

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).

If the NOCROSSREFS keyword is used, and there are 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 NOCROSSREFS.

For each section within the OVERLAY, the linker automatically provides 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.

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.

  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 if referenced: __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.

  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.

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

2 MEMORY Command

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.

A linker script may contain many uses of the MEMORY command, however, all memory blocks defined are treated as if they were specified inside a single MEMORY command. The syntax for MEMORY is:

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 within the MEMORY command. However you can add later alias names to existing memory regions with the Assign alias names to memory regions command.

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 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.

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 attributes that follow

If an unmapped section matches any of the listed attributes other than ‘!’, it will be placed in the memory region. The ‘!’ attribute reverses the test for the characters that follow, so that an unmapped section will be placed in the memory region only if it does not match any of the attributes listed afterwards. Thus an attribute string of ‘RW!X’ will match any unmapped section that has either or both of the ‘R’ and ‘W’ attributes, but only as long as the section does not also have the ‘X’ attribute.

The origin is an numerical expression for the start address of the memory region. The expression must evaluate to a constant and it cannot involve any symbols. The keyword ORIGIN may be abbreviated to org or o (but not, for example, ORG).

The len is an expression for the size in bytes of the memory region. As with the origin expression, the expression must be numerical only and must evaluate to a constant. 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.

MEMORY{rom (rx)  : ORIGIN = 0, LENGTH = 256Kram (!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 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.

It is possible to access the origin and length of a memory in an expression via the ORIGIN(memory) and LENGTH(memory) functions:

  _fstack = ORIGIN(ram) + LENGTH(ram) - 4;

3 PHDRS Command

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.

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.

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

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. The headers are processed in order and it is usual for them to map to sections in ascending load address order.

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 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.

You may use the FILEHDR and PHDRS keywords 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. If applied to a loadable segment (PT_LOAD), all prior loadable segments must have one of these keywords.

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

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.

PT_TLS (7)
Indicates a segment containing thread local storage.

expression
An expression giving the numeric type of the program header. This may be used for types not defined above.

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 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.

Here is an example of PHDRS. This shows a typical set of program headers used on a native ELF system.

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…
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/66352.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

音视频-----RTSP协议 音视频编解码

流媒体协议详解&#xff1a;RTSP、RTP、RTCP、SIP、SDP、RTMP、WebRTC、WebSocket-CSDN博客 上文讲解比较清楚 多媒体编解码基础知识 一文详解WebRTC、RTSP、RTMP、SRT-腾讯云开发者社区-腾讯云 流媒体协议简介 &#xff08;整理&总结&#xff09;-CSDN博客 RTP :(Real-…

家教老师预约平台小程序系统开发方案

家教老师预约平台小程序系统将连接学生/家长与家教老师&#xff0c;提供一站式的家教服务预约体验。 一、用户需求分析1、家教老师&#xff1a;希望获得更多的学生资源&#xff0c;通过平台展示自己的教学特长和经验&#xff0c;管理个人日程&#xff0c;接收并确认预约请求&a…

Linux 系统安装 NCBI Blast + A Quick Guide

前言 NCBI BLAST&#xff08;Basic Local Alignment Search Tool&#xff09;是由美国国家生物技术信息中心&#xff08;NCBI&#xff09;开发的一个深受生物信息学研究者青睐的基因序列比对工具。作为生物序列信息比对的行业标准&#xff0c;BLAST可用于分析核酸&#xff08;…

嵌入式科普(26)为什么heap通常8字节对齐

目录 一、概述 二、newlibc heap 2.1 stm32cubeide .ld heap 2.2 e2studio .ld heap 三、glibc源码 3.1 Ubuntu c heap 四、总结 一、概述 结论&#xff1a;在嵌入式c语言中&#xff0c;heap通常8字节对齐 本文主要分析这个问题的分析过程 二、newlibc heap newlibc…

nginx学习之路-nginx配置https服务器

文章目录 1. 生成证书2. 配置证书1. 拷贝证书文件2. 修改conf/nginx.conf文件内容 3. 查看效果1. 重载配置2. 访问 1. 生成证书 在linux系统下执行&#xff0c;使用openssl命令。&#xff08;windows环境也可以使用cmder&#xff09; # 1. 生成私钥 server2025.key(无密码保护…

VulnHub—potato-suncs

使用命令扫描靶机ip arp-scan -l 尝试访问一下ip 发现一个大土豆没什么用 尝试扫描一下子域名 没有发现什么有用的信息 尝试扫描端口 namp -A 192.168.19.137 -p- 尝试访问一下端口,发现都访问不进去 查看源代码发现了网页的标题 potato&#xff0c;就想着爆破一下密码 hydr…

【AI部署】腾讯云每月1w小时免费GPU获取

一、如何进入活动页面 进入腾讯云官网&#xff0c;点击控制台&#xff1a; https://curl.qcloud.com/zl1rLuMf 点击工具&#xff0c;进入CloudStudio&#xff1a; 找到高性能工作空间&#xff0c;每月会有1w分钟的免费时长&#xff1a; 二、创建AI模版 点击直接创建 选择…

开源平台Kubernetes的优势是什么?

Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;方便进行声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统&#xff0c;其服务、支持和工具的使用范围广泛。 Kubernetes 这个名字源于希腊语&#xff0c;意…

INT305 Machine Learning

W1 Introduction Nearest Neighbor Preliminaries and Nearest Neighbor Methods • Suppose we’re given a novel input vector &#x1d465; we’d like to classify. • The idea: find the nearest input vector to &#x1d465; in the training set and copy …

2025_0105_生活记录

3号去内蒙看了流星雨。还记得上次看流星的时间是2018年&#xff0c;也是冬天&#xff0c;大家在雁栖湖校区的操场上仰望星空。那个时候幸运的看到了一颗流星&#xff0c;便迅速地在心里许愿。这次看到了三颗流星&#xff0c;我也许了愿&#xff0c;希望实现。 24年走过了十多个…

Docker安装Prometheus和Grafana

概念简述 安装prometheus 第一步&#xff1a;确保安装有docker 第二步&#xff1a;拉取镜像 第三步&#xff1a;准备相关挂载目录及文件 第四步&#xff1a;启动容器 第五步&#xff1a;访问测试 安装grafana 第一步&#xff1a;确保安装有docker 第二步&#xff1a;拉…

详解GPT-信息抽取任务 (GPT-3 FAMILY LARGE LANGUAGE MODELS)

GPT-3 FAMILY LARGE LANGUAGE MODELS Information Extraction 自然语言处理信息提取任务&#xff08;NLP-IE&#xff09;&#xff1a;从非结构化文本数据中提取结构化数据&#xff0c;例如提取实体、关系和事件 [164]。将非结构化文本数据转换为结构化数据可以实现高效的数据处…

数据结构9.3 - 文件基础(C++)

目录 1 打开文件字符读写关闭文件 上图源自&#xff1a;https://blog.csdn.net/LG1259156776/article/details/47035583 1 打开文件 法 1法 2ofstream file(path);ofstream file;file.open(path); #include<bits/stdc.h> using namespace std;int main() {char path[]…

k8s基础(3)—Kubernetes-Deployment

一、 Deployment概述 ‌ Kubernetes Deployment‌是Kubernetes中的一个核心概念&#xff0c;它是一种高级别的控制器&#xff0c;用于管理Pod和ReplicaSet&#xff0c;确保应用程序的高可用性和稳定性。Deployment通过声明式配置来创建和更新Pod和ReplicaSet&#xff0c;从而…

C#跨窗口传递Halcon图像/参数

Demo目的&#xff0c;图像同步到附属窗口&#xff0c;通过附属窗口各类操作&#xff08;参数设置&#xff0c;ROI重置等&#xff09;简化主界面 本文主要演示图像传递 主界面 附属界面 运行效果 主界面代码 using System; using System.Collections.Generic; using System.C…

LeetCode:700.二叉搜索树中的搜索

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;700.二叉搜索树中的搜索 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你…

美食烹饪互动平台

本文结尾处获取源码。 一、相关技术 后端&#xff1a;Java、JavaWeb / Springboot。前端&#xff1a;Vue、HTML / CSS / Javascript 等。数据库&#xff1a;MySQL 二、相关软件&#xff08;列出的软件其一均可运行&#xff09; IDEAEclipseVisual Studio Code(VScode)Navica…

单片机从入门到放弃教程001

1. 单片机介绍 单片微型计算机(Single Chip Microcomputer)简称单片机&#xff0c;是典型的嵌入式微处理器(Micro Controller Unit简称MCU)&#xff0c;是一种将中央处理器&#xff08;CPU&#xff09;、内存、输入输出接口以及其他功能模块集成在单一芯片上的微型计算机。 1…

Mysql数据实时同步到Es上

同步方案 ① 同步双写 同步双写实一种数据同步策略&#xff0c;它指的是在主数据库(如mysql) 上进行数据修改操作&#xff0c;同时将这些修改同步写入到ES 中&#xff0c;这种策略旨在确保两个数据库之间的数据一致性&#xff0c;并且优化系统的读写性能。 目标 同步双写是…

供需平台信息发布付费查看小程序系统开发方案

供需平台信息发布付费查看小程序系统主要是为了满足个人及企业用户的供需信息发布与匹配需求。 一、目标用户群体 个人用户&#xff1a;寻找兼职工作、二手物品交换、本地服务&#xff08;如家政、维修&#xff09;等。 小微企业&#xff1a;推广产品和服务&#xff0c;寻找合…