diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-deps.c | 73 | ||||
-rw-r--r-- | elf/dynamic-link.h | 10 | ||||
-rw-r--r-- | elf/elf.h | 84 | ||||
-rw-r--r-- | elf/link.h | 7 |
4 files changed, 143 insertions, 31 deletions
diff --git a/elf/dl-deps.c b/elf/dl-deps.c index f034196762..7a6772979b 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -32,7 +32,7 @@ _dl_map_object_deps (struct link_map *map, struct link_map *map; struct list *next; }; - struct list head[2 + npreloads], *tailp, *scanp; + struct list *head, *tailp, *scanp; struct list duphead, *duptailp; unsigned int nduplist; unsigned int nlist, naux, i; @@ -49,36 +49,57 @@ _dl_map_object_deps (struct link_map *map, naux = nlist = 0; -#define AUXTAG (DT_NUM + DT_PROCNUM + DT_EXTRATAGIDX (DT_AUXILIARY)) + /* XXX The AUXILIARY implementation isn't correct in the moment. XXX + XXX The problem is that we currently do not handle auxiliary XXX + XXX entries in the loaded objects. XXX */ +#define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \ + + DT_EXTRATAGIDX (DT_AUXILIARY)) + + /* First determine the number of auxiliary objects we have to load. */ if (map->l_info[AUXTAG]) { - /* There is an auxiliary library specified. We try to load it, - and if we can, use its symbols in preference to our own. - But if we can't load it, we just silently ignore it. - XXX support multiple DT_AUXILIARYs? - */ - struct link_map *aux; - void openaux (void) - { - const char *strtab - = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr); - aux = _dl_map_object (map, strtab + map->l_info[AUXTAG]->d_un.d_val, - map->l_type == lt_executable ? lt_library : - map->l_type, trace_mode); - } - char *errstring; - const char *objname; - if (! _dl_catch_error (&errstring, &objname, &openaux)) - { - /* The auxiliary object is actually there. Use it - as the first search element, even before MAP itself. */ - preload (aux); - naux = 1; - } + ElfW(Dyn) *d; + for (d = map->l_ld; d->d_tag != DT_NULL; ++d) + if (d->d_tag == DT_AUXILIARY) + ++naux; + } + + /* Now we can allocate the array for the linker maps. */ + head = (struct list *) alloca (sizeof (struct list) + * (naux + npreloads + 2)); + + /* Load the auxiliary objects, even before the object itself. */ + if (map->l_info[AUXTAG]) + { + /* There is at least one auxiliary library specified. We try to + load it, and if we can, use its symbols in preference to our + own. But if we can't load it, we just silently ignore it. */ + const char *strtab + = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr); + ElfW(Dyn) *d; + + for (d = map->l_ld; d->d_tag != DT_NULL; ++d) + if (d->d_tag == DT_AUXILIARY) + { + struct link_map *aux; + void openaux (void) + { + aux = _dl_map_object (map, strtab + d->d_un.d_val, + (map->l_type == lt_executable + ? lt_library : map->l_type), + trace_mode); + } + char *errstring; + const char *objname; + if (! _dl_catch_error (&errstring, &objname, openaux)) + /* The auxiliary object is actually there. Use it as + the first search element, even before MAP itself. */ + preload (aux); + } } - /* Start the search list with one element: MAP itself. */ + /* Next load MAP itself. */ preload (map); /* Add the preloaded items after MAP but before any of its dependencies. */ diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index c613f824d8..1d134ddf2f 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -26,11 +26,12 @@ static inline void __attribute__ ((unused)) elf_get_dynamic_info (ElfW(Dyn) *dyn, - ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_EXTRANUM]) + ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM + + DT_EXTRANUM]) { unsigned int i; - for (i = 0; i < DT_NUM + DT_PROCNUM + DT_EXTRANUM; ++i) + for (i = 0; i < DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM; ++i) info[i] = NULL; if (! dyn) @@ -43,8 +44,11 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, else if (dyn->d_tag >= DT_LOPROC && dyn->d_tag < DT_LOPROC + DT_PROCNUM) info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn; + else if ((Elf32_Word) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM) + info[DT_VERSIONTAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM] = dyn; else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) - info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM] = dyn; + info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM + + DT_VERSIONTAGNUM] = dyn; else assert (! "bad dynamic tag"); dyn++; diff --git a/elf/elf.h b/elf/elf.h index d25934b411..05eeb3664f 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -232,6 +232,11 @@ typedef struct #define SHT_SHLIB 10 /* Reserved */ #define SHT_DYNSYM 11 /* Dynamic linker symbol table */ #define SHT_NUM 12 /* Number of defined types. */ +#define SHT_LOSUNW 0x6ffffffd /* Sun-specific low bound. */ +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ #define SHT_LOPROC 0x70000000 /* Start of processor-specific */ #define SHT_HIPROC 0x7fffffff /* End of processor-specific */ #define SHT_LOUSER 0x80000000 /* Start of application-specific */ @@ -464,6 +469,20 @@ typedef struct #define DT_HIPROC 0x7fffffff /* End of processor-specific */ #define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ +/* The versioning entry types. The next are defined as part of the + GNU extension. */ +#define DT_VERSYM 0x6ffffff0 + +/* These were chosen by Sun. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_VERSIONTAGNUM 16 + /* Sun added these machine-independent extensions in the "processor-specific" range. Be compatible. */ #define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ @@ -471,6 +490,71 @@ typedef struct #define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) #define DT_EXTRANUM 3 +/* Version definition sections. */ + +typedef struct +{ + Elf32_Half vd_version; /* Version revision */ + Elf32_Half vd_flags; /* Version information */ + Elf32_Half vd_ndx; /* Version Index */ + Elf32_Half vd_cnt; /* Number of associated aux entries */ + Elf32_Word vd_hash; /* Version name hash value */ + Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf32_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf32_Verdef; + +/* Legal values for vd_version (version revision). */ +#define VER_DEF_NONE 0 /* No version */ +#define VER_DEF_CURRENT 1 /* Current version */ +#define VER_DEF_NUM 2 /* Given version number */ + +/* Legal values for vd_flags (version information flags). */ +#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + +/* Auxialiary version information. */ + +typedef struct +{ + Elf32_Addr vda_name; /* Version or dependency names */ + Elf32_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf32_Verdaux; + +/* Version dependency section. */ + +typedef struct +{ + Elf32_Half vn_version; /* Version of structure */ + Elf32_Half vn_cnt; /* Number of associated aux entries */ + Elf32_Addr vn_file; /* Offset of filename for this + dependency */ + Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf32_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf32_Verneed; + +/* Legal values for vn_version (version revision). */ +#define VER_NEED_NONE 0 /* No version */ +#define VER_NEED_CURRENT 1 /* Current version */ +#define VER_NEED_NUM 2 /* Given version number */ + +/* Auxiliary needed version information. */ + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name */ + Elf32_Half vna_flags; /* Dependency specific information */ + Elf32_Half vna_other; /* Unused */ + Elf32_Addr vna_name; /* Dependency name string offset */ + Elf32_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf32_Vernaux; + +/* Legal values for vna_flags. */ +#define VER_FLG_WEAK 0x2 /* Weak verison identifier */ + /* Auxiliary vector. */ diff --git a/elf/link.h b/elf/link.h index 95d8f0912d..b05ecca199 100644 --- a/elf/link.h +++ b/elf/link.h @@ -99,9 +99,12 @@ struct link_map [0,DT_NUM) are indexed by the processor-independent tags. [DT_NUM,DT_NUM+DT_PROCNUM) are indexed by the tag minus DT_LOPROC. [DT_NUM+DT_PROCNUM,DT_NUM+DT_PROCNUM+DT_EXTRANUM) are indexed - by DT_EXTRATAGIDX(tagvalue) (see <elf.h>). */ + by DT_EXTRATAGIDX(tagvalue) and + [DT_NUM+DT_PROCNUM+DT_VERSIONTAGNUM, + DT_NUM+DT_PROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM) + are indexed by DT_EXTRATAGIDX(tagvalue) (see <elf.h>). */ - ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM + DT_EXTRANUM]; + ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM]; const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */ ElfW(Addr) l_entry; /* Entry point location. */ ElfW(Half) l_phnum; /* Number of program header entries. */ |