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.  链接编辑器

调用链接编辑器

直接调用

使用编译器驱动程序

跨链接编辑

指定链接编辑器选项

输入文件处理

归档处理

共享目标文件处理

与其他库链接

库命名约定

同时链接共享目标文件和归档

命令行中归档的位置

链接编辑器搜索的目录

运行时链接程序搜索的目录

初始化节和终止节

符号处理

符号可见性

符号解析

简单解析

复杂解析

致命解析

未定义符号

生成可执行输出文件

生成共享目标文件输出文件

弱符号

输出文件中的暂定符号顺序

定义其他符号

使用 -u 选项定义其他符号

定义符号引用

定义绝对符号

定义暂定 (tentative) 符号

扩充符号定义

缩减符号作用域

删除符号

外部绑定

字符串表压缩

生成输出文件

标识功能要求

标识平台功能

标识计算机功能

标识硬件功能

标识软件功能

创建符号功能函数系列

创建符号功能数据项系列

将目标文件功能转换为符号功能

功能系列试验

重定位处理

位移重定位

桩目标文件

辅助目标文件

调试器访问及辅助目标文件使用

父目标文件

调试帮助

3.  运行时链接程序

4.  共享目标文件

第 2 部分快速参考

5.  链接编辑器快速参考

第 3 部分高级主题

6.  直接绑定

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

8.  Mapfile

9.  接口和版本控制

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

11.  可扩展性机制

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

12.  目标文件格式

13.  程序装入和动态链接

14.  线程局部存储

第 5 部分附录

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

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

索引

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

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

父目标文件

提供可扩展功能的程序通常使用在运行时使用 dlopen() 函数装入的共享目标文件。这些共享目标文件通常称为插件,它们提供了一种用于扩展核心系统的功能的灵活方法。装入插件的目标文件称为父目标文件

父目标文件装入插件并从插件内访问函数和数据。对于父目标文件,通过插件提供要使用的函数和数据很常见。以下父目标文件和插件源文件对此进行了说明。为了利用插件,此处父目标文件提供了名为 parent_callback() 的函数。插件为父目标文件提供了名为 plugin_func() 的函数以供调用。

$ cat main.c
#include <stdio.h>
#include <dlfcn.h>
#include <link.h>

void
parent_callback(void)
{
        (void) printf("plugin_func() has called parent_callback()\n");
}

int
main(int argc, char **argv)
{
        typedef void plugin_func_t(void);

        void            *hdl;
        plugin_func_t   *plugin_func;

        if (argc != 2) {
                (void) fprintf(stderr, "usage: main plugin\n");
                return (1);
        }

        if ((hdl = dlopen(argv[1], RTLD_LAZY)) == NULL) {
                (void) fprintf(stderr, "unable to load plugin: %s\n", dlerror());
                return (1);
        }

        plugin_func = (plugin_func_t *) dlsym(hdl, "plugin_func");
        if (plugin_func == NULL) {
                (void) fprintf(stderr, "unable to find plugin_func: %s\n",
                    dlerror());
                return (1);
        }

        (*plugin_func)();

        return (0);
}

$ cat plugin.c
#include <stdio.h>
extern    void    parent_callback(void);
void
plugin_func(void)
{
    (void) printf("parent has called plugin_func() from plugin.so\n");
    parent_callback();
}

$ cc -o main main.c -lc
$ cc -Kpic -G -o plugin.so plugin.c -lc
$ ./main ./plugin.so
parent has called plugin_func() from plugin.so
plugin_func() has called parent_callback()

构建任何共享目标文件时,为了确保目标文件指定了其所有依赖项,建议使用 -z defs 选项。但是,由于父目标文件中有未满足的符号,使用 -z defs 会阻止插件目标文件进行链接。

$ cc -zdefs -Kpic -G -o plugin.so plugin.c -lc
Undefined                       first referenced
 symbol                             in file
parent_callback                     plugin.o
ld: fatal: symbol referencing errors. No output written to plugin.so

可以使用 mapfile 向链接编辑指定 parent_callback() 符号由父目标文件提供。

$ cat plugin.mapfile
$mapfile_version 2

SYMBOL_SCOPE {
    global:
        parent_callback         { FLAGS = PARENT };
};
$ cc -zdefs -Mplugin.mapfile -Kpic -G -o plugin.so plugin.c -lc

构建插件的首选解决方案是使用 -z parent 选项向插件提供对父目标文件的直接访问。使用 -z parent 而非 mapfile 的另一好处是父目标文件的名称将记录在插件的动态节中,并由 file 实用程序显示。

$ cc -zdefs -zparent=main -Kpic -G -o plugin.so plugin.c -lc
$ elfdump -d plugin.so | grep PARENT
       [0]  SUNW_PARENT       0xcc                main
$ file plugin.so 
plugin.so: ELF 32-bit LSB dynamic lib 80386 Version 1,
           parent main, dynamically linked, not stripped