JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris 11.1 链接程序和库指南     Oracle Solaris 11.1 Information Library (简体中文)
为本文档评分
search filter icon
search icon

文档信息

前言

第 1 部分使用链接编辑器和运行时链接程序

1.  Oracle Solaris 链接编辑器介绍

2.  链接编辑器

3.  运行时链接程序

4.  共享目标文件

第 2 部分快速参考

5.  链接编辑器快速参考

第 3 部分高级主题

6.  直接绑定

7.  生成目标文件以优化系统性能

8.  Mapfile

9.  接口和版本控制

10.  使用动态字符串标记建立依赖性

11.  可扩展性机制

链接编辑器支持接口

调用支持接口

32 位环境和 64 位环境

支持接口函数

支持接口示例

运行时链接程序审计接口

建立名称空间

创建审计库

调用审计接口

记录局部审计程序

记录全局审计程序

审计接口交互

审计接口函数

审计接口示例

审计接口演示

审计接口限制

使用应用程序代码

la_pltexit() 的用法

直接检查栈的函数

运行时链接程序调试器接口

控制进程和目标进程之间的交互

调试器接口代理

调试器导出接口

代理处理接口

错误处理

扫描可装入目标文件

事件通知

跳过过程链接表

动态目标文件填充

调试器导入接口

第 4 部分ELF 应用程序二进制接口

12.  目标文件格式

13.  程序装入和动态链接

14.  线程局部存储

第 5 部分附录

A.  链接程序和库的更新及新增功能

B.  System V 发行版 4(版本 1)Mapfile

索引

请告诉我们如何提高我们的文档:
过于简略
不易阅读或难以理解
重要信息缺失
错误的内容
需要翻译的版本
其他
Your rating has been updated
感谢您的反馈!

您的反馈将非常有助于我们提供更好的文档。 您是否愿意参与我们的内容改进并提供进一步的意见?

运行时链接程序审计接口

您可以使用 rtld-audit 接口访问与进程的运行时链接有关的信息。rtld-audit 接口实现为提供一个或多个审计接口例程的审计库。如果将该库作为进程的一部分装入,则运行时链接程序会在进程执行的不同阶段调用审计例程。审计库可以使用这些接口访问以下各项:

通过预装入专用的共享目标文件可以获取其中的部分信息。但是,预装入的目标文件与应用程序的目标文件存在于同一名称空间内。这种预装入通常会限制预装入共享目标文件的实现或者使实现变得更为复杂。rtld-audit 接口会为您提供唯一的名称空间,用于在其中执行审计库。此名称空间可确保在应用程序内进行正常绑定时审计库不会侵入。

Profiling Shared Objects中介绍对共享目标文件的运行时配置即是使用此 配置共享目标文件的一个示例。

建立名称空间

运行时链接程序将动态可执行文件与其依赖项绑定时,会生成链接映射的链接列表,用于对此应用程序进行说明。链接映射结构说明了应用程序中的每个目标文件。/usr/include/sys/link.h 中定义了此链接映射结构。绑定应用程序的目标文件所需的符号搜索机制会遍历此链接映射的列表。此链接映射列表用于提供应用程序符号解析的名称空间

运行时链接程序也通过链接映射来进行说明。此链接映射以不同于应用程序目标文件列表的列表中进行维护。因此,运行时链接程序驻留在其自己唯一的名称空间中,从而可防止应用程序查看或直接访问运行时链接程序内的任意服务。因此,应用程序只能通过 libc.so.1libdl.so.1 提供的过滤器来访问运行时链接程序。

/usr/include/link.h 中定义了两个标识符,用于定义应用程序和运行时链接程序的链接映射列表:

#define LM_ID_BASE      0     /* application link-map list */
#define LM_ID_LDSO      1     /* runtime linker link-map list */

除了这两个标准的链接映射列表以外,运行时链接程序还允许再创建任意数量的链接映射列表。其中每个链接映射列表都提供一个唯一的名称空间。rtld-audit 接口使用自己的用于维护审计库的链接映射列表。因此,在应用程序的符号绑定要求中,不涉及审计库。针对每个 rtld-audit 支持库会指定一个唯一的新链接映射标识符。

审计库可以使用 dlmopen(3C) 检查应用程序链接映射列表。将 dlmopen()RTLD_NOLOAD 标志结合使用时,审计库可以在不装入目标文件的情况下查询该目标文件是否存在。

创建审计库

审计库的生成方式与其他任何共享目标文件的生成方式相同。但是,必须注意进程内审计库名称空间的唯一性。

如果审计库引用外部接口,则审计库必须定义提供接口定义的依赖性。例如,如果审计库调用 printf(3C),则审计库必须定义与 libc 之间的依赖性。请参见生成共享目标文件输出文件。由于审计库具有唯一的名称空间,因此,所审计的应用程序中提供的 libc 无法满足符号引用。如果审计库依赖于 libc,则会向进程中装入两种版本的 libc.so.1。一种版本用于满足应用程序链接映射列表的绑定要求,另一种版本用于满足审计链接映射列表的绑定要求。

要确保生成的审计库会记录所有的依赖项,请使用链接编辑器的 -z defs 选项。

部分系统接口会假定其是进程内实现的唯一实例,例如信号和 malloc(3C)。审计库应该避免使用此类接口,因为这样做可能会无意中更改应用程序的行为。


注 - 审计库可以使用 mapmalloc(3MALLOC) 来分配内存,因为此分配方法可以与应用程序通常使用的任何分配方案同时存在。


调用审计接口

rtld-audit 接口可通过以下两种方法之一来启用。每种方法都会指示一个所审计的目标文件的作用域。

这两种定义审计程序的方法均使用一个字符串,其中包含通过 dlmopen(3C) 装入的以冒号分隔的共享目标文件列表。每个目标文件都装入各自的审计链接映射列表中。使用 dlsym(3C) 可搜索每个目标文件中的审计例程。在应用程序执行过程中的不同阶段会调用找到的审计例程。

安全应用程序只能从可信目录中获取审计库。缺省情况下,用于 32 位目标文件的运行时链接程序可识别的可信目录仅有 /lib/secure/usr/lib/secure。对于 64 位目标文件,可信目录是 /lib/secure/64/usr/lib/secure/64


注 - 通过将环境变量 LD_NOAUDIT 设置为非空值,可在运行时禁用审计。


记录局部审计程序

使用链接编辑器选项 -p-P 生成目标文件时,可以确定局部审计要求。例如,要使用审计库 audit.so.1 审计 libfoo.so.1,请在链接编辑时使用 -p 选项记录要求:

$ cc -G -o libfoo.so.1 -Wl,-paudit.so.1 -K pic foo.c
$ elfdump -d libfoo.so.1 | grep AUDIT
       [2]  AUDIT             0x96                audit.so.1

在运行时,如果存在此审计标识符,则会装入审计库。然后,将与标识目标文件相关的信息传递到此审计库。

如果单独使用此机制,则在装入审计库之前会显示搜索标识目标文件之类的信息。要提供尽可能多的审计信息,需要将存在的要求局部审计的目标文件传播给此目标文件的用户。例如,如果生成的应用程序依赖于 libfoo.so.1,则会对此应用程序进行标识,指明其依赖项需要审计:

$ cc -o main main.c libfoo.so.1
$ elfdump -d main | grep AUDIT
       [4]  DEPAUDIT          0x1be               audit.so.1

通过此机制启用的审计会导致向审计库中传递与所有应用程序显式依赖项有关的信息。使用链接编辑器的 -P 选项,还可以在创建目标文件时直接记录此依赖项审计:

$ cc -o main main.c -Wl,-Paudit.so.1
$ elfdump -d main | grep AUDIT
       [3]  DEPAUDIT          0x1b2               audit.so.1

记录全局审计程序

通过设置环境变量 LD_AUDIT 可以确定全局审计要求。例如,针对审计库 audit.so.1,此环境变量可用于审计应用程序 main 以及该应用程序的所有依赖项。

$ LD_AUDIT=audit.so.1 main

通过记录应用程序中的局部审计程序以及 -z globalaudit 选项,还可以实现全局审计。例如,通过使用链接编辑器的 -P 选项和 -z globalaudit 选项,可以生成应用程序 main 以启用全局审计。

$ cc -o main main.c -Wl,-Paudit.so.1 -z globalaudit
$ elfdump -d main | grep AUDIT
       [3]  DEPAUDIT          0x1b2               audit.so.1
      [26]  FLAGS_1           0x1000000           [ GLOBAL-AUDITING ]

通过以上任一机制启用的审计会导致向审计库中传递与应用程序的所有动态目标文件有关的信息。

审计接口交互

为审计例程提供了一个或多个 cookie。cookie 是描述单个动态目标文件的数据项。最初装入动态目标文件时,为 la_objopen() 例程提供了一个初始 cookie。此 cookie 是指向装入的动态目标文件的关联 Link_map 的指针。但是,la_objopen() 例程可自由分配,并返回至运行时链接程序(备用 cookie)。此机制为审计程序提供了一种使用每个动态目标文件维护其自身数据并使用所有后续审计例程调用接收此数据的方法。

通过 rtld-audit 接口可以提供多个审计库。在这种情况下,从一个审计程序返回的信息将传递至下一个审计程序的同一审计例程。同样,由一个审计程序建立的 cookie 将传递至下一个审计程序。设计预期与其他审计库共存的审计库时应谨慎。一种安全的方法是不应更改通常由运行时链接程序返回的绑定或 cookie。更改这些数据会在后面的审计库中产生意外结果。否则,应设计所有审计程序相互协作以安全更改任何绑定信息或 cookie 信息。

审计接口函数

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 标识启动进程的主目标文件,通常为动态可执行文件。

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

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_BINDFROMdefcook 标识定义此符号的目标文件。此标识符与传递给 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);

symndxrefcookdefcooksym_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);

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


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


la_objclose()

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

uint_t la_objclose(uintptr_t *cookie);

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

审计接口示例

以下简单示例创建了一个审计库,其中显示了动态可执行文件 date(1) 装入的每个共享目标文件依赖项的名称。

$ cat audit.c
#include        <link.h>
#include        <stdio.h>
 
uint_t
la_version(uint_t version)
{
        return (LAV_CURRENT);
}
 
uint_t
la_objopen(Link_map *lmp, Lmid_t lmid, uintptr_t *cookie)
{
        if (lmid == LM_ID_BASE)
                (void) printf("file: %s loaded\n", lmp->l_name);
        return (0);
}
$ cc -o audit.so.1 -G -K pic -z defs audit.c -lmapmalloc -lc
$ LD_AUDIT=./audit.so.1 date
file: date loaded
file: /lib/libc.so.1 loaded
file: /lib/libm.so.2 loaded
file: /usr/lib/locale/en_US/en_US.so.2 loaded
Thur Aug  10 17:03:55 PST 2000

审计接口演示

/usr/demo/link_audit 下的 pkg:/solaris/source/demo/system 软件包中提供了许多使用 rtld-audit 接口的演示应用程序。

sotruss

此演示跟踪指定的应用程序的动态目标文件之间的过程调用。

whocalls

此演示跟踪指定的应用程序每次调用指定函数时所用栈。

perfcnt

此演示跟踪指定的应用程序的每个函数执行时间。

symbindrep

此演示报告为装入指定的应用程序而执行的所有符号绑定。

sotruss(1)whocalls(1) 包括在 pkg:/developer/linker 软件包中。perfcntsymbindrep 是程序示例。这些应用程序不适用于生产环境。

审计接口限制

rtld-audit 实现中存在一些限制。设计审计库时应谨慎了解这些限制。

使用应用程序代码

将目标文件添加到进程时审计库会接收到信息。审计库接收到这种信息时,所监视目标文件可能无法执行。例如,对于装入的目标文件,审计程序可能会接收到 la_objopen() 调用。但是,在该目标文件中的任何代码可以使用之前,该目标文件必须装入其自身的依赖项并进行重定位。审计库可能需要通过使用 dlopen(3C) 获取句柄来检查装入的目标文件。然后,通过使用 dlsym(3C),该句柄可用于搜索接口。但是,除非已知目标文件的初始化已完成,否则不应调用采用这种方式获取的接口。

la_pltexit() 的用法

使用 la_pltexit() 系列存在一些限制。这些限制是由于需要在调用者和被调用者之间插入额外栈帧,以提供 la_pltexit() 返回值。此要求在仅调用 la_pltenter() 例程时不会产生问题。在这种情况下,可以在将控制权转交给目标函数之前清除任何干预栈。

由于存在这些限制,因此应该将 la_pltexit() 视为实验接口。在不确定的情况下,请避免使用 la_pltexit() 例程。

直接检查栈的函数

有少量函数可以直接检查栈或对其状态做出假设。这些函数的一些示例包括 setjmp(3C) 系列、vfork(2) 以及返回结构而不是指向结构的指针的任何函数。为支持 la_pltexit() 而创建的额外栈会破坏这些函数。

由于运行时链接程序无法检测此类型的函数,因此,审计库创建者会负责针对此类例程禁用 la_pltexit()