Anonymous | Login | 2024-12-12 01:21 UTC |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||
ID | Category | Severity | Type | Date Submitted | Last Update | ||
0000993 | [1003.1(2008)/Issue 7] Base Definitions and Headers | Editorial | Clarification Requested | 2015-10-18 10:22 | 2024-06-11 08:52 | ||
Reporter | EdSchouten | View Status | public | ||||
Assigned To | ajosey | ||||||
Priority | normal | Resolution | Accepted As Marked | ||||
Status | Closed | ||||||
Name | Ed Schouten | ||||||
Organization | Nuxi | ||||||
User Reference | |||||||
Section | dlfcn.h | ||||||
Page Number | n/a | ||||||
Line Number | n/a | ||||||
Interp Status | --- | ||||||
Final Accepted Text | Note: 0005335 | ||||||
Summary | 0000993: Standardizing dladdr() | ||||||
Description |
Though POSIX already standardizes the <dlfcn.h> functions to load shared libraries at runtime, it does not standardize the dladdr() function. My observation is that this function is used in a couple of important places, to generate backtraces or to improve error messages. It seems to be implemented universally as far as I know, always using the same prototype: typedef struct { const char *dli_fname; // Pathname of shared object. void *dli_fbase; // Base address of shared object. const char *dli_sname; // Name of nearest symbol. void *dli_saddr; // Address of nearest symbol. } Dl_info; int dladdr(const void *, Dl_info *); |
||||||
Desired Action | Due to its universal adoption, would it make sense to standardize it? | ||||||
Tags | issue8 | ||||||
Attached Files | |||||||
|
Notes | |
(0002882) wahern (reporter) 2015-11-04 20:01 |
It's missing completely on AIX. I've only ever used the dli_fname member (from modules which attempt to reopen and pin themselves in memory). FWIW, that at least appears to work the same from FreeBSD, Linux/glibc, Linux/musl, NetBSD, OpenBSD, OS X, and Solaris. |
(0002883) shware_systems (reporter) 2015-11-05 14:00 |
Also FWIW, while a function like this may make writing a generic debugger easier, as a legitimate purpose, its primary use in an application that I can see would be for reverse engineering a module that's been obfuscated and as such it constitutes a security hole. If it were to be included in the standard as a formalization of common practice I would hope it be as part of an option group, not a candidate for the base set of interfaces, and visible only when NDEBUG is defined similar to the assert macros. |
(0002886) EdSchouten (updater) 2015-11-05 18:17 |
I'm not sure I agree with this reasoning. The information that is returned by dladdr() is in many cases already public knowledge. - You can also extract this information outside of the process using the nm(1) utility. - Even if your system does not provide this function, but does provide the dl_iterate_phdr() function (present on many systems that use ELF), you can just search for the .dynsym section and parse the symbol entries manually. |
(0002891) dalias (reporter) 2015-11-06 16:33 |
In regard to comment 2883, the only security model in the standard is the user/group system. While additional security models are permitted (see "appropriate privileges" etc.), anything "DRM-like" is not a security measure by any stretch of the word and there is no precedent for attempting to offer such snake oil. However the whole issue is irrelevant to dladdr. An implementation wanting to attempt such futile measures could simply have dladdr fail for such modules. (Then, the user need only patch the module to make it start working again, or implement their own unencumbered but nonportable dladdr that only works on the particular implementation they need it on.) In regard to comment 2886, dl_iterate_phdr is also not provided in the standard and thus not a substitute for dladdr. Even if it were provided, however, there are implementations in which dl_iterate_phdr does not provide sufficient information to implement dladdr on top of it. In particular, for any implementation using function descriptors that are dynamically allocated (ELF/FDPIC ABIs), the headers lack sufficient information to determine the identity of a function pointer; additional runtime state known only to the dynamic linker is needed. |
(0003236) nico (reporter) 2016-05-27 16:07 |
dladdr() is extremely useful, and no, nm(1) and other such tools don't help. Suppose that you have a library for parsing configuration files where you want to open a configuration file by relative path -- relative to the *caller*'s object. First, you need the return address (and since there's no portable way to get, an address given by the caller). Next you call dladdr(), obtain the caller's object (or executable) path, and now you can find the absolute path given that configuration file relative path. There is no portable way to do this without dladdr() or similar because the caller may not know its path due to its being intended to be relocatable! Making applications relocatable (that is, not tied to an absolute install path) is difficult. dladdr(), along with $ORIGIN, helps a lot. POSIX should provide more interfaces to make it possible to write relocatable code. There are other uses of dladdr(), naturally. Reflection/introspection, for example, especially in codebases that pass around function pointer tables obtained or filled with dlsym() on objects loaded with dlopen() -- this is a case where the information is available in other ways, but where arranging to make that available conveniently may not be easy without much refactoring. I can probably think of other uses of dladdr(). Making relocation easier seems quite compelling to me. |
(0003237) nico (reporter) 2016-05-27 16:13 |
The hoops that we jump through to make code relocatable! Anyone who has had to use libtool has some idea (e.g., abuse LD_LIBRARY_PATH in order to run built-but-not-yet-installed artifacts). There is also Conda (which binary-edits install paths in build artifacts at install time). There are libraries to help find files by path relative to the application's install path (which can generally be determined via getauxval() or, failing that, main()'s argv[0]), but doing so relative to *objects* (as opposed to the executable) really does require dladdr(). |
(0003300) Don Cragun (manager) 2016-07-21 15:23 |
We will ask The Open Group if they would like to sponsor this additional interface. In the future, it would be nice if requests like this included text to be included in the standard, rather than hoping a sponsor organization will not only approve the suggestion but also take the additional effort to create all of the needed documentation. |
(0004974) geoffclare (manager) 2020-09-07 09:06 edited on: 2020-09-07 09:14 |
Suggested changes to go into The Open Group company review... Page and line numbers are for the 2016/2018 edition. On page 233 line 7838 section <dlfcn.h>, add: The <dlfcn.h> header shall define the Dl_info_t structure type, which shall include at least the following members:const char *dli_fname Pathname of mapped object file. void *dli_fbase Base of mapped address range. const char *dli_sname Symbol name or null pointer. void *dli_saddr Symbol address or null pointer. On page 233 line 7848 section <dlfcn.h>, insert: int dladdr(const void *restrict, Dl_info_t *restrict); On page 233 line 7859 section <dlfcn.h>, add dladdr() to SEE ALSO. On page 475 line 16317 section 2.2.2 The Name Space, change: RTLD_to: RTLD_, dli_ On page 2053 insert a new dladdr page: NAME dladdr -- get information relating to an address SYNOPSIS #include <dlfcn.h> int dladdr(const void *restrict addr, Dl_info_t *restrict dlip); DESCRIPTION The dladdr() function shall determine whether the address specified by addr is located within the address range occupied by a mapped object. The mapped objects examined shall include any executable object files that have previously been loaded by a call to dlopen() and for which dlclose() has not subsequently been called, and any shared library files that were loaded as dependencies of the executable file from which the current process image was loaded; they may also include any executable object files that have previously been loaded by a call to dlopen() and for which dlclose() has subsequently been called, the executable file from which the current process image was loaded, and implementation-defined additional mapped objects (for example, all regular files mapped using mmap() might be included). If the specified address is within the mapped address range of one of these mapped objects and the object contains a symbol table, the symbol table shall be searched for a symbol (a function identifier or a data object identifier) that has the largest address less than or equal to the specified address. RETURN VALUE Upon successful completion, a non-zero value shall be returned. If the specified address is not located within the address range occupied by an examined mapped object, or if an error occurs, zero shall be returned. More detailed diagnostic information shall be available through dlerror(). ERRORS No errors are defined. EXAMPLES None. APPLICATION USAGE The Dl_info_t members may point to addresses within the mapped object. These pointers can become invalid if the object is unmapped (for example, loaded executable objects may be unloaded by dlclose()). RATIONALE None. FUTURE DIRECTIONS None. SEE ALSO dlclose(), dlerror(), dlopen(), dlsym() CHANGE HISTORY First released in Issue 8. Add dladdr() to the SEE ALSO section for each function page listed in the dladdr() SEE ALSO above. On page 3791 line 130067 section E.1, add dladdr() to the POSIX_DYNAMIC_LINKING subprofile group. |
(0005051) geoffclare (manager) 2020-10-16 09:35 |
The dladdr() additions have been made in the Issue8NewAPIs branch in gitlab, based on Note: 0004974. |
(0005335) geoffclare (manager) 2021-04-29 15:19 |
Make the changes from "Additional APIs for Issue 8, Part 1" (Austin/1110). |
Issue History | |||
Date Modified | Username | Field | Change |
2015-10-18 10:22 | EdSchouten | New Issue | |
2015-10-18 10:22 | EdSchouten | Status | New => Under Review |
2015-10-18 10:22 | EdSchouten | Assigned To | => ajosey |
2015-10-18 10:22 | EdSchouten | Name | => Ed Schouten |
2015-10-18 10:22 | EdSchouten | Organization | => Nuxi |
2015-10-18 10:22 | EdSchouten | Section | => dlfcn.h |
2015-10-18 10:22 | EdSchouten | Page Number | => n/a |
2015-10-18 10:22 | EdSchouten | Line Number | => n/a |
2015-11-04 20:01 | wahern | Note Added: 0002882 | |
2015-11-05 14:00 | shware_systems | Note Added: 0002883 | |
2015-11-05 18:17 | EdSchouten | Note Added: 0002886 | |
2015-11-06 16:33 | dalias | Note Added: 0002891 | |
2016-05-27 16:07 | nico | Note Added: 0003236 | |
2016-05-27 16:13 | nico | Note Added: 0003237 | |
2016-07-21 15:23 | Don Cragun | Note Added: 0003300 | |
2016-09-14 14:24 | emaste | Issue Monitored: emaste | |
2020-09-07 09:06 | geoffclare | Note Added: 0004974 | |
2020-09-07 09:07 | geoffclare | Note Edited: 0004974 | |
2020-09-07 09:14 | geoffclare | Note Edited: 0004974 | |
2020-10-16 09:35 | geoffclare | Note Added: 0005051 | |
2021-04-29 15:19 | geoffclare | Note Added: 0005335 | |
2021-04-29 15:20 | geoffclare | Interp Status | => --- |
2021-04-29 15:20 | geoffclare | Final Accepted Text | => Note: 0005335 |
2021-04-29 15:20 | geoffclare | Status | Under Review => Resolved |
2021-04-29 15:20 | geoffclare | Resolution | Open => Accepted As Marked |
2021-04-29 15:20 | geoffclare | Tag Attached: issue8 | |
2021-05-07 15:21 | geoffclare | Status | Resolved => Applied |
2024-06-11 08:52 | agadmin | Status | Applied => Closed |
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |