diff options
-rw-r--r-- | include/link.h | 20 | ||||
-rw-r--r-- | ldso/ldso/dl-elf.c | 24 |
2 files changed, 43 insertions, 1 deletions
diff --git a/include/link.h b/include/link.h index c3ef6a6b0..f8e7f629d 100644 --- a/include/link.h +++ b/include/link.h @@ -92,4 +92,24 @@ struct link_map struct link_map *l_next, *l_prev; /* Chain of loaded objects. */ }; +#ifdef __USE_GNU + +struct dl_phdr_info + { + ElfW(Addr) dlpi_addr; + const char *dlpi_name; + const ElfW(Phdr) *dlpi_phdr; + ElfW(Half) dlpi_phnum; + }; + +__BEGIN_DECLS + +extern int dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, + size_t size, void *data), + void *data) __THROW; + +__END_DECLS + +#endif + #endif /* link.h */ diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index e11cb0d92..c58ca5dfb 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -894,4 +894,26 @@ char *_dl_strdup(const char *string) _dl_strcpy(retval, string); return retval; } - +#ifdef __USE_GNU +#if ! defined LIBDL || (! defined PIC && ! defined __PIC__) +int +__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data) +{ + struct elf_resolve *l; + struct dl_phdr_info info; + int ret = 0; + + for (l = _dl_loaded_modules; l != NULL; l = l->next) { + info.dlpi_addr = l->loadaddr; + info.dlpi_name = l->libname; + info.dlpi_phdr = l->ppnt; + info.dlpi_phnum = l->n_phent; + ret = callback (&info, sizeof (struct dl_phdr_info), data); + if (ret) + break; + } + return ret; +} +strong_alias(__dl_iterate_phdr, dl_iterate_phdr); +#endif +#endif |