@@ -35,38 +35,42 @@ Place, Suite 330, Boston, MA 02111-1307 USA
3535 *
3636 * \fn signed long lookup_gnu_hash_symbol(const char *name,
3737 ElfW(Sym) *syms,
38+ ElfW(Half) *versym,
3839 char *symnames,
3940 void *header);
4041 *
4142 * \brief Looks up the index of a symbol in a symbol table given a symbol name
4243 *
4344 * \param name The name of the function to be looked up
4445 * \param syms The pointer to the symbol table
46+ * \param versym The pointer to the symbol versioning table
4547 * \param symnames A pointer into the string table
4648 * \param header The parameters the underlying GNU Hash function will use
4749 *
4850 ******************************************************************************
4951 */
50- signed long lookup_gnu_hash_symbol (const char * name , ElfW (Sym ) * syms , char * symnames , void * sheader );
52+ signed long lookup_gnu_hash_symbol (const char * name , ElfW (Sym ) * syms , ElfW ( Half ) * versym , char * symnames , void * sheader );
5153
5254/*!
5355 ******************************************************************************
5456 *
5557 * \fn signed long lookup_elf_hash_symbol(const char *name,
5658 ElfW(Sym) *syms,
59+ ElfW(Half) *versym,
5760 char *symnames,
5861 ElfW(Word) *header);
5962 *
6063 * \brief Looks up the index of a symbol in a symbol table given a symbol name
6164 *
6265 * \param name The name of the function to be looked up
6366 * \param syms The pointer to the symbol table
67+ * \param versym The pointer to the symbol versioning table
6468 * \param symnames A pointer into the string table
6569 * \param header The parameters the underlying ELF Hash function will use
6670 *
6771 ******************************************************************************
6872 */
69- signed long lookup_elf_hash_symbol (const char * name , ElfW (Sym ) * syms , char * symnames , ElfW (Word ) * header );
73+ signed long lookup_elf_hash_symbol (const char * name , ElfW (Sym ) * syms , ElfW ( Half ) * versym , char * symnames , ElfW (Word ) * header );
7074
7175/*!
7276 ******************************************************************************
@@ -85,6 +89,7 @@ signed long lookup_elf_hash_symbol(const char *name, ElfW(Sym) *syms, char *symn
8589 * \param[out] gnu_hash
8690 * \param[out] got
8791 * \param[out] strtab
92+ * \param[out] versym
8893 *
8994 ******************************************************************************
9095 */
@@ -96,13 +101,22 @@ signed long lookup_elf_hash_symbol(const char *name, ElfW(Sym) *syms, char *symn
96101 ElfW(Sym) *symtab = NULL; \
97102 ElfW(Addr) gnu_hash = 0x0, elf_hash = 0x0; \
98103 ElfW(Addr) got = 0x0; \
104+ ElfW(Half) *versym = NULL; \
99105 char *strtab = NULL; \
100106 unsigned int rel_size = 0, rel_count = 0, is_rela = 0, i; \
101107 dynsec = lmap->l_ld; \
102108 if (!dynsec) \
103109 return -1; \
104110 for (dentry = dynsec; dentry->d_tag != DT_NULL; dentry++) { \
105111 switch (dentry->d_tag) { \
112+ case DT_REL: { \
113+ rel = (ElfW(Rel) *)dentry->d_un.d_ptr; \
114+ break; \
115+ } \
116+ case DT_RELA: { \
117+ rela = (ElfW(Rela) *) dentry->d_un.d_ptr; \
118+ break; \
119+ } \
106120 case DT_PLTRELSZ: { \
107121 rel_size = (unsigned int) dentry->d_un.d_val; \
108122 break; \
@@ -135,6 +149,10 @@ signed long lookup_elf_hash_symbol(const char *name, ElfW(Sym) *syms, char *symn
135149 gnu_hash = dentry->d_un.d_val; \
136150 break; \
137151 } \
152+ case DT_VERSYM: { \
153+ versym = (ElfW(Half) *) dentry->d_un.d_ptr; \
154+ break; \
155+ } \
138156 } \
139157 } \
140158 rel_count = rel_size / (is_rela ? sizeof(ElfW(Rela)) : sizeof(ElfW(Rel))); \
@@ -149,6 +167,7 @@ signed long lookup_elf_hash_symbol(const char *name, ElfW(Sym) *syms, char *symn
149167 (void) rel_size; \
150168 (void) rel_count; \
151169 (void) is_rela; \
170+ (void) versym; \
152171 (void) i;
153172
154173/*!
@@ -188,17 +207,23 @@ signed long lookup_elf_hash_symbol(const char *name, ElfW(Sym) *syms, char *symn
188207 *
189208 ******************************************************************************
190209 */
191- #define FOR_EACH_PLTREL (lmap , op , ...) { \
210+ #define FOR_EACH_PLTREL (lookup_rel , lmap , op , ...) { \
192211 INIT_DYNAMIC(lmap) \
193212 ElfW(Addr) offset = lmap->l_addr; \
194213 (void) offset; \
195214 if (is_rela) { \
196- rela = (ElfW(Rela) *) jmprel; \
197- FOR_EACH_PLTREL_INT(rela, op, ## __VA_ARGS__); \
215+ ElfW(Rela) * jmp_rela = (ElfW(Rela) *) jmprel; \
216+ FOR_EACH_PLTREL_INT(jmp_rela, op, ## __VA_ARGS__); \
217+ if (lookup_rel && rela) { \
218+ FOR_EACH_PLTREL_INT(rela, op, ## __VA_ARGS__); \
219+ } \
198220 } \
199221 else { \
200- rel = (ElfW(Rel) *) jmprel; \
201- FOR_EACH_PLTREL_INT(rel, op, ## __VA_ARGS__); \
222+ ElfW(Rel) * jmp_rel = (ElfW(Rel) *) jmprel; \
223+ FOR_EACH_PLTREL_INT(jmp_rel, op, ## __VA_ARGS__); \
224+ if (lookup_rel && rel) { \
225+ FOR_EACH_PLTREL_INT(rel, op, ## __VA_ARGS__); \
226+ } \
202227 } \
203228 }
204229
0 commit comments