> ----------------------------------------------------------------------
> (0000205) Don Cragun (manager) - 2009-08-27 00:03
> http://austingroupbugs.net/view.php?id=74#c205
> ----------------------------------------------------------------------
[snip]
> ------------------------------------------------------------------------
>
> Cross volume change:
> Delete subclause 2.12.3 from XBD P541, L18881-18886.
Not a cross volume change; that page is in XSH.
> ------------------------------------------------------------------------
>
> Replace the NAME, SYNOPSIS, DESCRIPTION, RETURN VALUE, ERRORS, EXAMPLES,
> and APPLICATION USAGE sections of the dlclose() descripion on P728,
> L24469-24513 with:
>
> NAME
> dlclose -- close a symbol table handle
>
> SYNOPSIS
> #include <dlfcn.h>
> int dlclose(void *handle);
>
> DESCRIPTION
> The dlclose() function shall inform the system that the symbol
> table handle specified by handle is no longer needed by the
> application.
>
> An application writer may use dlclose() to make a statement of
> intent on the part of the process, but this statemen does not
> create any requirement upon the implementation.
This is contradicted by the last sentence of the same paragraph, which
states a requirement on the implementation (to close object files if
the handle contains their last reference).
I think the above sentence could just be removed.
> When the symbol
> table handle is closed, the implementation may unload the
> executable object files that were loaded by dlopen() when the
> symbol table handle was opened and those that were loaded by
> dlsym() when using the symbol table handle identified by handle.
> Once a symbol table handle has been closed, an application
> should assume that any symbols (function identifiers and data
> object identifiers) made visible using handle, are no longer
> available to the process. Executable object files opened as a
> result of using handle shall be closed if this handle contains
> their last reference.
I think "result of using" should be "result of opening or using".
> ------------------------------------------------------------------------
>
> Replace the NAME, SYNOPSIS, DESCRIPTION, and RETURN VALUE sections of
> the dlopen() descripion on P732-733, L24575-24666:
>
> NAME
> dlopen -- open a symbol table handle
>
> SYNOPSIS
> #include <dlfcn.h>
> void *dlopen(const char *file, int mode);
>
> DESCRIPTION
> The dlopen() function shall make the symbols (function
> identifiers and data object identifiers) in the executable
> object file specified by file available to the calling program.
> The class of files eligible for this operation and the manner of
> their construction are implementation-defined, though typically
> such files are executable object files such as shared libraries
> or programs.
Since the first sentence says that file refers to an executable object
file, this last part is effectively saying that executable object
files are typically executable object files. I suggest:
The class of executable object files eligible for this
operation and the manner of their construction are
implementation-defined, though typically such files are
shared libraries or programs.
> Note that some implementations permit the
> construction of embedded dependencies in executable object
> files. In such cases, a dlopen() operation shall load those
> dependencies in addition to the executable object file specified
> by file. Implementations may also impose specific constraints
> on the construction of programs that can employ dlopen() and its
> related services.
>
> A successful dlopen() shall return a symbol table handle which
> the caller may use on subsequent calls to dlsym() and dlclose().
> The value of this symbol table handle should not be interpreted
> in any way by the caller.
>
> The file argument is used to construct a pathname to the
> executable object file. If file contains a <slash> character,
> the file argument is used as the pathname for the file.
> Otherwise, file is used in an implementation-defined manner to
> yield a pathname.
>
> If file is NULL, dlopen() shall return a global symbol table
Should be: If file is a null pointer, ...
> handle for the currently running process image. This symbol
> table handle shall provide access to the symbols from an ordered
> set of executable object files consisting of the original
> program image file, any executable object files loaded at
> program start-up as specified by that process image file (for
> example, shared libraries), and the set of executable object
> files loaded using dlopen() operations with the RTLD_GLOBAL
> flag. As the latter set of executable object files can change
> during execution, the set of symbols made available by this
> symbol table handle can also change dynamically.
>
> Only a single copy of an executable object file shall be brought
> into the address space, even if dlopen() is invoked multiple
> times in reference to the executable object file, and even if
> different pathnames are used to reference the executable object
> file.
>
> The mode parameter describes how dlopen() shall operate upon
> file with respect to the processing of relocations and the scope
> of visibility of the symbols provided within file. When an
> executable object file is brought into the address space of a
> process, it may contain references to symbols whose addresses
> are not known until the executable object file is loaded.
> These references shall be relocated before the symbols can be
> accessed. The mode parameter governs when these relocations
> take place and may have the following values:
>
> RTLD_LAZY Relocations shall be performed at an
> implementation-defined time, ranging from the
> time of the dlopen() call until the first
> reference to a given symbol occurs. Specifying
> RTLD_LAZY should improve performance on
> implementations supporting dynamic symbol
> binding since a process might not reference all
> of the symbols in an executable object file.
> And, for systems supporting dynamic symbol
> resolution for normal process execution, this
> behavior mimics the normal handling of process
> execution.
>
> RTLD_NOW All necessary relocations shall be performed
> when the executable object file is first loaded.
> This may waste some processing if relocations
> are performed for symbols that are never
> referenced. This behavior may be useful for
> applications that need to know that all symbols
> referenced during execution will be available
> before dlopen() returns.
>
> Any executable object file loaded by dlopen() that requires
> relocations against global symbols can reference the symbols in
> the original process image file, any executable object files
> loaded at program start-up, from the initial process image
> itself, from any other executable object file included in the
> same dlopen() invocation, and any executable object files that
> were loaded in any dlopen() invocation and which specified the
> RTLD_GLOBAL flag. To determine the scope of visibility for the
> symbols loaded with a dlopen() invocation, the mode parameter
> should be a bitwise-inclusive OR with one of the following
> values:
>
> RTLD_GLOBAL The executable object file's symbols shall be
> made available for relocation processing of any
> other executable object file. In addition,
> symbol lookup using dlopen(NULL, mode) and an
> associated dlsym() allows executable object
> files loaded with this mode to be searched.
>
> RTLD_LOCAL The executable object file's symbols shall not
> be made available for relocation processing of
> any other executable object file.
>
> If neither RTLD_GLOBAL nor RTLD_LOCAL are specified, the default
> behavior is unspecified.
>
> If an executable object file is specified in multiple dlopen()
> invocations, mode is interpreted at each invocation. Note,
> however, that once RTLD_NOW has been specified, all relocations
> shall have been completed rendering further RTLD_NOW operations
> redundant and any further RTLD_LAZY operations irrelevant.
> Similarly, note that once RTLD_GLOBAL has been specified, the
> executable object file shall maintain the RTLD_GLOBAL status
> regardless of any previous or future specification of
> RTLD_LOCAL, as long as the executable object file remains in the
> address space (see dlclose()).
>
> Symbols introduced into the process image through calls to
> dlopen() may be used in relocation activities. Symbols so
> introduced may duplicate symbols already defined by the program
> or previous dlopen() operations. To resolve the ambiguities
> such a situation might present, the resolution of a symbol
> reference to symbol definition is based on a symbol resolution
> order. Two such resolution orders are defined: load order and
> dependency order. Load order establishes an ordering among
> symbol definitions, such that the first definition loaded
> (including definitions from the process image file and any
> dependent executable object files loaded with it) has priority
> over executable object files added later (by dlopen()). Load
> ordering is used in relocation processing. Dependency ordering
> uses a breadth-first order starting with a given executable
> object file, then all of its dependencies, then any dependents
> of those, iterating until all dependencies are satisfied. With
> the exception of the global symbol table handle obtained via a
> dlopen() operation on a file of NULL, dependency ordering is
Should be: dlopen() operation with a null pointer as the file argument, ...
> used by the dlsym() function. Load ordering is used in dlsym()
> operations upon the global symbol table handle.
>
> When an executable object file is first made accessible via
> dlopen(), it and its dependent executable object files are added
> in dependency order. Once all the executable object files are
> added, relocations are performed using load order. Note that if
> an executable object file or its dependencies had been
> previously loaded, the load and dependency orders may yield
> different resolutions.
>
> The symbols introduced by dlopen() operations and available
> through dlsym() are at a minimum those which are exported as
> identifiers of global scope by the executable object file.
> Typically such identifiers shall be those that were specified in
> (for example) C source code as having extern linkage. The
> precise manner in which an implementation constructs the set of
> exported symbols for an executable object file is
> implementation-defined.
>
> RETURN VALUE
> Upon successful completion, dlopen() shall return a symbol table
> handle. If file cannot be found, cannot be opened for reading,
> is not of an appropriate executable object file format for
> processing by dlopen(), or if an error occurs during the process
> of loading file or relocating its symbolic references, dlopen()
> shall return NULL. More detailed diagnostic information shall
> be available through dlerror().
>
> ------------------------------------------------------------------------
>
> Replace the NAME, SYNOPSIS, DESCRIPTION, RETURN VALUE, ERRORS, EXAMPLES,
> APPLICATION USAGE, and RATIONALE sections of the dlsym() descripion on
> P735-736, L24689-24748 with:
>
> NAME
> dlsym -- get the address of a symbol from a symbol table handle
>
> SYNOPSIS
> #include <dlfcn.h>
> void *dlsym(void *restrict handle, const char *restrict name);
>
> DESCRIPTION
> The dlsym() function shall obtain the address of a symbol (a
> function identifier or a data object identifier) defined in the
> symbol table identified by the handle argument. The handle
> argument is a symbol table handle returned from a call to
> dlopen() (and which has not since been released by a call to
> dlclose()), and name is the symbol's name as a character
> string. The return value from dlsym(), cast to a pointer to the
> type of the named symbol, may be used to call (in the case of a
s/may/can/
> function) or access the contents of (in the case of a data
> object) the named symbol.
>
> The dlsym() function shall search for the named symbol in
> the symbol table referenced by handle. If the symbol table was
> created with lazy loading (see RTLD_LAZY in dlopen()), load
> ordering shall be used in dlsym() operations to relocate
> executable object files needed to resolve the symbol. The
> symbol resolution algorithm used shall be dependency order
> as described in dlopen().
>
> The RTLD_DEFAULT and RTLD_NEXT symbolic constants (which may be
> defined in <dlfcn.h>) are reserved for future use as special
> values that applications may be allowed to use for handle.
>
> RETURN VALUE
> Upon successful completion, if name names a function identifier,
> dlsym() shall return the address of the function converted from
> type pointer to function to type pointer to void; otherwise
> dlsym() shall return the address of the data object associated
> with the data object identfier named by name converted from a
> pointer to the type of the data object to a pointer to void. If
> handle does not refer to a valid symbol table handle or if the
> symbol named by name cannot be found in the symbol table
> associated with handle, dlsym() shall return NULL. More
> detailed diagnostic information shall be available through
> dlerror().
>
> ERRORS
> No errors are defined.
>
> EXAMPLES
> The following example shows how dlopen() and dlsym() can be used
> to access either a function or a data object. For simplicity,
> error checking has been omitted.
>
> void *handle;
> int (*fptr)(int),
> *iptr,
> result;
>
> /* open the needed symbol table */
> handle = dlopen("/usr/home/me/libfoo.so", RTLD_LOCAL | RTLD_LAZY);
>
> /* find the address of the function my_function */
> *(void **)(&fptr) = dlsym(handle, "my_function");
Should be:
fptr = (int (*)(int))dlsym(handle, "my_function");
>
> /* find the address of the data object my_object */
> iptr = (int *)dlsym(handle, "my_OBJ");
>
> /* invoke my_function, passing the value of my_OBJ as the parameter */
> result = (*fptr)(*iptr);
>
> APPLICATION USAGE
> The following special purpose values for handle are reserved for
> future use and have the indicated meanings:
>
> RTLD_DEFAULT The identifier lookup happens in the normal
> global scope; that is, a search for a identifier
> using handle would find the same definition as a
> direct use of this identifier in the program
> code.
>
> RTLD_NEXT Specifies the next executable object file after
> this one that defines name. This one refers to
> the executable object file containing the
> invocation of dlsym(). The next executable
> object file is the one found upon the
> application of a load order symbol resolution
> algorithm (see dlopen()). The next symbol is
> either one of global scope (because it was
> introduced as part of the original process image
> or because it was added with a dlopen()
> operation including the RTLD_GLOBAL flag), or is
> in an executable object file that was included
> in the same dlopen() operation that loaded this
> one.
>
> The RTLD_NEXT flag is useful to navigate an
> intentionally created hierarchy of
> multiply-defined symbols created through
> interposition. For example, if a program wished
> to create an implementation of malloc() that
> embedded some statistics gathering about memory
> allocations, such an implementation could use
> the real malloc() definition to perform the
> memory allocation-and itself only embed the
> necessary logic to implement the statistics
> gathering function.
>
> Note that compilers conforming to the ISO C standard are
> required to generate a warning if a conversion from a void *
> pointer to a function pointer is attempted as in:
>
> fptr = (int (*)(int))dlsym(handle, "my_function");
I suggest adding:
However, conversion using a cast like this is the only
portable way of obtaining a function pointer from dlsym().
Some earlier versions of this standard suggested the use
of the following alternative to avoid the warning:
*(void **)(&fptr) = dlsym(handle, "my_function");
Execution of this code results in undefined behavior.
--
Geoff Clare <g.clare@opengroup.org>
The Open Group, Thames Tower, Station Road, Reading, RG1 1LX, England
|