Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

审计接口函数

rtld-audit 接口提供了以下例程。这些例程按照其预期的使用顺序进行说明。


注 - 为了简化讨论,对体系结构或目标文件类特定接口的引用会缩减为其通用名称。例如,对 la_symbind32()la_symbind64() 的引用会指定为 la_symbind()
la_version()

此例程可提供运行时链接程序与审计库之间的初次握手。必须提供此接口才能装入审计库。

uint_t la_version(uint_t version);

运行时链接程序通过其可以支持的最高 version 的 rtld-audit 接口来调用此接口。审计库可以检验此版本是否足以供其使用,并返回审计库预期使用的版本。此版本通常为 /usr/include/link.h 中定义的 LAV_CURRENT

如果审计库返回零,或者返回的版本高于运行时链接程序所支持的 rtld-audit 接口的版本,则会废弃该审计库。

为其余审计例程提供了一个或多个 cookie。请参见审计接口交互

la_version() 调用之后,对 la_objopen() 例程进行了两次调用。第一次调用提供动态可执行文件的链接映射信息,第二次调用提供运行时链接程序的链接映射信息。

la_objopen()

此例程在运行时链接程序装入新目标文件时调用。

uint_t la_objopen(Link_map *lmp, Lmid_t lmid, uintptr_t *cookie);

lmp 提供说明新目标文件的链接映射结构。lmid 标识添加了目标文件的链接映射列表。cookie 提供指向某个标识符的指针。此标识符会初始化为目标文件 lmp。审计库可以重新指定此标识符,以便更好地标识其他 rtld-audit 接口例程的目标文件。

la_objopen() 例程会返回表示与此目标文件相关的符号绑定的值。返回值是 /usr/include/link.h 中定义的以下值的掩码:

  • LA_FLG_BINDTO-审计此目标文件的符号绑定。

  • LA_FLG_BINDFROM-审计来自此目标文件的符号绑定。

通过这些值,审计程序可以选择要使用 la_symbind() 监视的目标文件。返回值为零表示绑定信息与此目标文件无关。

例如,审计程序可以监视从 libfoo.solibbar.so 的绑定。将 la_objopen() 用于 libfoo.so 会返回 LA_FLG_BINDFROM。将 la_objopen() 用于 libbar.so 会返回 LA_FLG_BINDTO

审计程序可以监视 libfoo.solibbar.so 之间的所有绑定。将 la_objopen() 用于这两个目标文件会返回 LA_FLG_BINDFROMLA_FLG_BINDTO

审计程序可以监视到 libbar.so 的所有绑定。将 la_objopen() 用于 libbar.so 会返回 LA_FLG_BINDTO。所有 la_objopen() 调用都会返回 LA_FLG_BINDFROM

使用审计版本 LAV_VERSION5,将一个表示动态可执行文件的 la_objopen() 调用提供给局部审计程序。在这种情况下,审计程序不会返回符号绑定标志,因为它可能装入过晚,而无法监视与该动态可执行文件关联的符号绑定。忽略审计程序返回的任何标志。la_objopen() 调用为局部审计程序提供了一个初始 cookie,它是任意后续 la_preinit()la_activity() 调用所需的。

la_activity()

此例程可通知审计程序正在进行链接映射活动。

void la_activity(uintptr_t *cookie, uint_t flags);

cookie 标识作为链接映射标题的目标文件。flags 表示活动类型,如 /usr/include/link.h 中所定义:

  • LA_ACT_ADD-正在向链接映射列表中添加目标文件。

  • LA_ACT_DELETE-正在从链接映射列表中删除目标文件。

  • LA_ACT_CONSISTENT-已经完成目标文件活动。

在动态可执行文件和运行时链接程序进行 la_objopen() 调用之后,在进程启动时调用 LA_ACT_ADD 活动,以指示添加了新的依赖项。对于延迟装入和 dlopen(3C) 事件,也会调用此活动。使用 dlclose(3C) 删除目标文件时,也会调用 LA_ACT_DELETE 活动。

LA_ACT_ADDLA_ACT_DELETE 活动均为预期随后发生的事件的提示。在一些情况下,呈现的事件可能有所不同。例如,如果目标文件未能完全重定位,则添加新目标文件可能会导致一些新目标文件被删除。如果 .fini 执行导致延迟装入新目标文件,则删除目标文件还会导致添加新目标文件。LA_ACT_CONSISTENT 活动在任何目标文件添加或删除操作之后发生,可依赖它来指示应用程序链接映射列表的一致性。审计程序应谨慎检验实际结果,而不是盲目相信 LA_ACT_ADDLA_ACT_DELETE 提示。

对于审计版本 LAV_VERSION1LAV_VERSION4,仅针对全局审计程序调用 la_activity()。对于审计版本 LAV_VERSION5,局部审计程序可获取活动事件。活动事件提供一个表示应用程序链接映射的 cookie。要准备此活动并允许审计程序控制此 cookie 的内容,请首先对局部审计程序进行 la_objopen() 调用。la_objopen() 调用提供一个表示应用程序链接映射的初始 cookie。请参见审计接口交互

la_objsearch()

此例程可通知审计程序将要搜索目标文件。

char *la_objsearch(const char *name, uintptr_t *cookie, uint_t flags);

name 表示所搜索的文件名或路径名。cookie 标识启动搜索的目标文件。flags 标识 name 的来源和创建方式,如 /usr/include/link.h 中所定义:

  • LA_SER_ORIG-初始搜索名称。通常,此名称表示记录为 DT_NEEDED 项的文件名或者提供给 dlopen(3C) 的参数。

  • LA_SER_LIBPATH-已经通过 LD_LIBRARY_PATH 组件创建了路径名。

  • LA_SER_RUNPATH-已经通过运行路径组件创建了路径名。

  • LA_SER_DEFAULT-已经通过缺省搜索路径组件创建了路径名。

  • LA_SER_CONFIG-路径组件源自配置文件。请参见 crle(1)

  • LA_SER_SECURE-路径组件特定于安全目标文件。

返回值会指明运行时链接程序应该继续处理的搜索路径名。值为零表示应该忽略此路径。监视搜索路径的审计库会返回 name。

la_objfilter()

此例程在过滤器装入新的 filtee 时调用。请参见作为过滤器的共享目标文件

int la_objfilter(uintptr_t *fltrcook, const char *fltestr,
    uintptr_t *fltecook, uint_t flags);

fltrcook 标识过滤器。fltestr 指向 filtee 字符串。fltecook 标识 filtee。flags 当前未使用。对于过滤器和 filtee,la_objfilter() 在调用 la_objopen() 之后调用。

值为零表示应该忽略此 filtee。监视过滤器使用情况的审计库会返回非零值。

la_preinit()

此例程在为应用程序装入所有即时依赖性之后调用一次。

void la_preinit(uintptr_t *cookie);

cookie 标识启动进程的主目标文件,通常为动态可执行文件。

调用 la_preinit() 后,进程仍需要线程初始化,包括创建任何初始线程局部存储。请参见程序启动。此外,所有装入的目标文件的初始化节在执行之前仍需要收集和排序。请参见初始化和终止例程。此函数提供了一个便利的控制点,用于将其他目标文件添加到初始进程。这些目标文件可用于初始线程局部存储和进程初始化。

对于审计版本 LAV_VERSION1LAV_VERSION4,仅针对全局审计程序调用 la_preinit()。对于审计版本 LAV_VERSION5,局部审计程序可获取 preinit 事件。preinit 事件提供一个表示应用程序链接映射的 cookie。要准备此 preinit 并允许审计程序控制此 cookie 的内容,请首先对局部审计程序进行 la_objopen() 调用。la_objopen() 调用提供一个表示应用程序链接映射的初始 cookie。请参见审计接口交互

la_callinit()

在完成线程初始化且建立所有初始线程局部存储之后,将调用此例程。此外,已收集并对所有初始化例程进行排序,以待执行。

void la_callinit(uintptr_t *cookie);

将针对 la_preinit() 介绍 cookie 以及在全局或局部审计程序中的调用。

审计版本 LAV_VERSION6 添加的此接口标志到执行应用程序代码的转换。

la_callentry()

在执行所有初始化例程之后,将调用此例程。

void la_callentry(uintptr_t *cookie);

将针对 la_preinit() 介绍 cookie 以及在全局或局部审计程序中的调用。

审计版本 LAV_VERSION6 添加的此接口将标记到应用程序入口点的转换。

la_symbind()

在已经通过 la_objopen() 标记用于绑定通知的两个目标文件之间进行绑定时,会调用此例程。

uintptr_t la_symbind32(Elf32_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook, uint_t *flags);

uintptr_t la_symbind64(Elf64_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook, uint_t *flags,
    const char *sym_name);

sym 是构造的符号结构,其 sym->st_value 表示所绑定的符号定义的地址。请参见 /usr/include/sys/elf.hla_symbind32() 可将 sym->st_name 调整为指向实际符号名称。la_symbind64() 可保留 sym->st_name 作为绑定目标文件字符串表的索引。

ndx 表示绑定目标文件的动态符号表内的符号索引。refcook 标识引用此符号的目标文件。此标识符与传递给 la_objopen() 例程的标识符相同,此例程会返回 LA_FLG_BINDFROM。defcook 标识定义此符号的目标文件。此标识符与传递给 la_objopen() 的标识符相同,此函数会返回 LA_FLG_BINDTO

flags 指向可以传送与绑定相关的信息的数据项。此数据项还可用于修改对此过程链接表项的继续审计。该值是 /usr/include/link.h 中定义的符号绑定标志的掩码。

可以为 la_symbind() 提供以下标志:

  • LA_SYMB_DLSYM-由于调用 dlsym(3C) 而发生的符号绑定。

  • LA_SYMB_ALTVALUE (LAV_VERSION2)-通过先前调用 la_symbind() 为符号值返回替换值。

如果 la_pltenter()la_pltexit() 例程存在,则对于过程链接表的各项,这些例程在 la_symbind() 之后调用。每次引用符号时都会调用这些例程。另请参见审计接口限制

la_symbind() 可以提供以下标志来更改此缺省行为。这些标志可应用于按位或运算(包含边界值),并通过 flags 参数来指示其值。

  • LA_SYMB_NOPLTENTER请勿针对此符号调用 la_pltenter() 例程。

  • LA_SYMB_NOPLTEXIT请勿针对此符号调用 la_pltexit() 例程。

返回值表示在此调用后将控制权传递到的地址。监视符号绑定的审计库应该返回值 sym->st_value,以便将控制权传递给绑定符号定义。审计库可以通过返回不同的值对符号绑定进行专门重定向。

sym_name 仅适用于 la_symbind64(),其中包含所处理的符号的名称。对于 32 位接口,可在 sym->st_name 字段中使用此名称。

la_pltenter()

这些例程是系统特定的。调用过程链接表中位于已经标记用于绑定通知的两个目标文件之间的一项时,会调用这些例程。

uintptr_t la_sparcv8_pltenter(Elf32_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook,
    La_sparcv8_regs *regs, uint_t *flags);

uintptr_t la_sparcv9_pltenter(Elf64_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook,
    La_sparcv9_regs *regs, uint_t *flags,
    const char *sym_name);

uintptr_t la_i86_pltenter(Elf32_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook,
    La_i86_regs *regs, uint_t *flags);

uintptr_t la_amd64_pltenter(Elf64_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook,
    La_amd64_regs *regs, uint_t *flags, const char *sym_name);

sym、ndx、refcook、defcook 和 sym_name 提供的信息与传递给 la_symbind() 的信息相同。

对于 la_sparcv8_pltenter()la_sparcv9_pltenter(),regs 指向输出寄存器。对于 la_i86_pltenter(),regs 指向栈寄存器和帧寄存器。对于 la_amd64_pltenter(),regs 指向栈寄存器、帧寄存器以及用于传递整数参数的寄存器。regs 在 /usr/include/link.h 中定义。

flags 指向可以传送与绑定相关的信息的数据项。此数据项可用于修改对此过程链接表项的继续审计。此数据项与 la_symbind() 中的 flags 指向的数据项相同。

la_pltenter() 可以提供以下标志来更改当前的审计行为。这些标志可应用于按位或运算(包含边界值),并通过 flags 参数来指示其值。

  • LA_SYMB_NOPLTENTER不能针对此符号再次调用 la_pltenter()

  • LA_SYMB_NOPLTEXIT不能针对此符号再次调用 la_pltexit()

返回值表示在此调用后将控制权传递到的地址。监视符号绑定的审计库应该返回值 sym->st_value,以便将控制权传递给绑定符号定义。审计库可以通过返回不同的值对符号绑定进行专门重定向。

la_pltexit()

返回过程链接表中位于已经标记用于绑定通知的两个目标文件之间的一项时,会调用此例程。此例程在调用者获取控制权之前调用。

uintptr_t la_pltexit(Elf32_Sym *sym, uint_t ndx, uintptr_t *refcook,
    uintptr_t *defcook, uintptr_t retval);

uintptr_t la_pltexit64(Elf64_Sym *sym, uint_t ndx, uintptr_t *refcook,
    uintptr_t *defcook, uintptr_t retval, const char *sym_name);

sym、ndx、refcook、defcook 和 sym_name 提供的信息与传递给 la_symbind() 的信息相同。retval 是绑定函数的返回代码。监视符号绑定的审计库应该返回 retval。审计库可以专门返回不同的值。


注 - la_pltexit() 接口是实验接口。请参见审计接口限制
la_objclose()

此例程在执行目标文件的任何终止代码之后和卸载目标文件之前调用。

uint_t la_objclose(uintptr_t *cookie);

cookie 标识目标文件,并从先前的 la_objopen() 中获取。当前会忽略任何返回值。