Skip Navigation Links | |
Exit Print View | |
Oracle Solaris 11.1 Linkers and Libraries Guide Oracle Solaris 11.1 Information Library |
Part I Using the Link-Editor and Runtime Linker
1. Introduction to the Oracle Solaris Link Editors
Specifying the Link-Editor Options
Linking With Additional Libraries
Linking With a Mix of Shared Objects and Archives
Position of an Archive on the Command Line
Directories Searched by the Link-Editor
Directories Searched by the Runtime Linker
Initialization and Termination Sections
Generating an Executable Output File
Generating a Shared Object Output File
Tentative Symbol Order Within the Output File
Defining Additional Symbols with the -u option
Augmenting a Symbol Definition
Identifying Capability Requirements
Identifying a Platform Capability
Identifying a Machine Capability
Identifying Hardware Capabilities
Identifying Software Capabilities
Creating a Family of Symbol Capabilities Functions
Creating a Family of Symbol Capabilities Data Items
Converting Object Capabilities to Symbol Capabilities
Exercising a Capability Family
Debugger Access and Use of Ancillary Objects
5. Link-Editor Quick Reference
7. Building Objects to Optimize System Performance
10. Establishing Dependencies with Dynamic String Tokens
Part IV ELF Application Binary Interface
13. Program Loading and Dynamic Linking
A. Linker and Libraries Updates and New Features
Programs that offer extensible functionality often make use of shared objects, loaded at runtime using the dlopen() function. These shared objects are often referred to as plugins, and provide a flexible means to extend the abilities of the core system. The object that loads the plugins is referred to as the parent.
A parent object loads the plugin and accesses functions and data from within the plugin. It is also common for the parent object to provide functions and data for use by the plugin. This is illustrated by the following parent and plugin source files. Here the parent supplies a function named parent_callback() for the benefit of the plugin. The plugin supplies a function named plugin_func() for the parent to call.
$ 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()
When building any shared object, the -z defs option is recommended, in order to ensure that the object specifies all of its dependencies. However, the use of -z defs prevents the plugin object from linking due to the unsatisfied symbol from the parent object.
$ 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
A mapfile can be used to specify to the link-edit that the parent_callback() symbol is supplied by the parent object.
$ 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
The preferred solution for building a plugin is to use the -z parent option to provide the plugin with direct access to symbols from the parent. An added benefit of using -z parent instead of a mapfile, is that the name of the parent object is recorded in the dynamic section of the plugin, and is displayed by the file utility.
$ 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