链接程序和库指南

支持接口函数

所有 ld-support 接口均在头文件 link.h 中定义。所有接口参数均为基本的 C 类型或 ELF 类型。可以通过 ELF 访问库 libelf 检查 ELF 数据类型。有关 libelf 内容的说明,请参见 elf(3ELF)。以下接口函数由 ld-support 接口提供,并且按照预期的使用顺序进行了说明。

ld_version()

此函数提供了链接编辑器与支持库之间的初次握手。

uint_t ld_version(uint_t version);

链接编辑器使用其可以支持的最高版本的 ld-support 接口来调用此接口。支持库可以检验此版本是否达到使用的最低要求,并返回支持库要求使用的版本。此版本通常为 LD_SUP_VCURRENT

如果支持库没有提供此接口,则采用初始支持级别 LD_SUP_VERSION1

如果支持库返回版本零,或者返回的版本值高于链接编辑器所支持的 ld-support 接口的版本,则无法使用支持库。

ld_start()

此函数在初始验证链接编辑器命令行之后调用,表示开始处理输入文件。

void ld_start(const char * name, const Elf32_Half type,

        const char * caller);



void ld_start64(const char * name, const Elf64_Half type,

        const char * caller);

name 是所创建的输出文件名。type 是输出文件类型,可以为 ET_DYNET_RELET_EXEC,如 sys/elf.h 中所定义。caller 是调用接口的应用程序,通常为 /usr/ccs/bin/ld

ld_file()

执行任何文件数据处理之前,会针对每个输入文件调用此函数。

void ld_file(const char * name, const Elf_Kind kind, int flags,

        Elf * elf);



void ld_file64(const char * name, const Elf_Kind kind, int flags,

        Elf * elf);

name 是要处理的输入文件。kind 表示输入文件类型,可以是 ELF_K_ARELF_K_ELF,如 libelf.h 中所定义。flags 表示链接编辑器获取文件的方式,可以是以下一个或多个定义:

  • LD_SUP_DERIVED-文件名不是在命令行中显式指定的。文件是从 -l 扩展派生而来,或者文件标识提取的归档成员。

  • LD_SUP_EXTRACTED-文件提取自归档。

  • LD_SUP_INHERITED-文件作为命令行共享库的依赖项获取。

如果未指定 flags 值,则表明已在命令行中显式指定了输入文件。elf 是指向文件的 ELF 描述符的指针。

ld_input_section()

此函数会针对输入文件的每一节调用,并且在链接编辑器确定是否应将节传播给输出文件之前即会调用此函数。此函数不同于 ld_section() 处理,后者仅针对组成输出文件的各节进行调用。

void ld_input_section(const char * name, Elf32_Shdr ** shdr,

        Elf32_Word sndx, Elf_Data * data, Elf * elf, unit_t flags);



void ld_input_section64(const char * name, Elf64_Shdr ** shdr,

        Elf64_Word sndx, Elf_Data * data, Elf * elf, uint_t flags);

name 是输入节的名称。shdr 是指向关联节标题的指针。sndx 是输入文件内的节索引。data 是指向关联数据缓冲区的指针。elf 是指向文件的 ELF 描述符的指针。flags 保留供将来使用。

节标题的修改是通过重新分配节标题并为新标题重新指定 *shdr 来完成的。链接编辑器使用从 ld_input_section() 返回时 *shdr 所指向的节标题信息来处理节。

通过重新分配数据并重新指定 Elf_Data 缓冲区的 d_buf 指针,可以修改数据。对数据进行任何修改都应确保正确设置 Elf_Data 缓冲区的 d_size 元素。对于成为输出映像一部分的输入节,将 d_size 元素设置为零可以有效地删除输出映像中的数据。

flags 字段指向初始值为零的 uint_t 数据字段。虽然在将来的更新中可通过链接编辑器或支持库来指定标志,但是当前未指定任何标志。

ld_section()

此函数针对传播给输出文件的输入文件的每一节调用,并且在执行任何节数据处理之前即会调用此函数。

void ld_section(const char * name, Elf32_Shdr * shdr,

        Elf32_Word sndx, Elf_Data * data, Elf * elf);



void ld_section64(const char * name, Elf64_Shdr * shdr,

        Elf64_Word sndx, Elf_Data * data, Elf * elf);

name 是输入节的名称。shdr 是指向关联节标题的指针。sndx 是输入文件内的节索引。data 是指向关联数据缓冲区的指针。elf 是指向文件 ELF 描述符的指针。

通过重新分配数据并重新指定 Elf_Data 缓冲区的 d_buf 指针,可以修改数据。对数据进行任何修改都应确保正确设置 Elf_Data 缓冲区的 d_size 元素。对于成为输出映像一部分的输入节,将 d_size 元素设置为零可以有效地删除输出映像中的数据。


注 –

使用链接编辑器的 -s 选项删除的各节,或者由于 SHT_SUNW_COMDAT 处理或SHF_EXCLUDE 标识而废弃的各节不会向 ld_section() 进行报告。请参见COMDAT 节表 7–8


ld_input_done()

此函数在完成输入文件处理之后但在对输出文件进行布局之前调用。

void ld_input_done(uint_t flags);

flags 字段指向初始值为零的 uint_t 数据字段。虽然在将来的更新中可通过链接编辑器或支持库来指定标志,但是当前未指定任何标志。

ld_atexit()

此函数在完成链接编辑时调用。

void ld_atexit(int status);



void ld_atexit64(int status);

status 是将由链接编辑器返回的 exit(2) 代码,可以是 EXIT_FAILUREEXIT_SUCCESS,如 stdlib.h 中所定义。