1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #ifdef DO_RELA
24: # define elf_dynamic_do_rel elf_dynamic_do_rela
25: # define RELCOUNT_IDX VERSYMIDX (DT_RELACOUNT)
26: # define Rel Rela
27: # define elf_machine_rel elf_machine_rela
28: # define elf_machine_rel_relative elf_machine_rela_relative
29: #else
30: # define RELCOUNT_IDX VERSYMIDX (DT_RELCOUNT)
31: #endif
32:
33: #ifndef DO_ELF_MACHINE_REL_RELATIVE
34: # define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \
35: elf_machine_rel_relative (l_addr, relative, \
36: (void *) (l_addr + relative->r_offset))
37: #endif
38:
39: #ifndef VERSYMIDX
40: # define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
41: #endif
42: #ifndef VALIDX
43: # define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
44: + DT_EXTRANUM + DT_VALTAGIDX (tag))
45: #endif
46:
47:
48:
49:
50:
51:
52: auto inline void __attribute__ ((always_inline))
53: elf_dynamic_do_rel (struct link_map *map,
54: ElfW(Addr) reladdr, ElfW(Addr) relsize,
55: int lazy)
56: {
57: const ElfW(Rel) *r = (const void *) reladdr;
58: const ElfW(Rel) *end = (const void *) (reladdr + relsize);
59: ElfW(Addr) l_addr = map->l_addr;
60:
61: #if (!defined DO_RELA || !defined ELF_MACHINE_PLT_REL) && !defined RTLD_BOOTSTRAP
62:
63:
64:
65: if (lazy)
66: {
67:
68: for (; r < end; ++r)
69: elf_machine_lazy_rel (map, l_addr, r);
70: }
71: else
72: #endif
73: {
74: const ElfW(Sym) *const symtab =
75: (const void *) D_PTR (map, l_info[DT_SYMTAB]);
76: ElfW(Word) nrelative = (map->l_info[RELCOUNT_IDX] == NULL
77: ? 0 : map->l_info[RELCOUNT_IDX]->d_un.d_val);
78: const ElfW(Rel) *relative = r;
79: r = r + MIN (nrelative, relsize / sizeof (ElfW(Rel)));
80:
81: #ifndef RTLD_BOOTSTRAP
82:
83:
84:
85:
86:
87:
88: # ifndef SHARED
89: weak_extern (GL(dl_rtld_map));
90: # endif
91: if (map != &GL(dl_rtld_map))
92: # if !defined DO_RELA || defined ELF_MACHINE_REL_RELATIVE
93:
94:
95:
96:
97:
98: if (l_addr != 0)
99: # else
100:
101: if (l_addr != 0 || ! map->l_info[VALIDX(DT_GNU_PRELINKED)])
102: # endif
103: #endif
104: for (; relative < r; ++relative)
105: DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative);
106:
107: #ifdef RTLD_BOOTSTRAP
108:
109: assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL);
110: #else
111: if (map->l_info[VERSYMIDX (DT_VERSYM)])
112: #endif
113: {
114: const ElfW(Half) *const version =
115: (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
116:
117: for (; r < end; ++r)
118: {
119: ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
120: elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
121: &map->l_versions[ndx],
122: (void *) (l_addr + r->r_offset));
123: }
124: }
125: #ifndef RTLD_BOOTSTRAP
126: else
127: for (; r < end; ++r)
128: elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
129: (void *) (l_addr + r->r_offset));
130: #endif
131: }
132: }
133:
134: #undef elf_dynamic_do_rel
135: #undef Rel
136: #undef elf_machine_rel
137: #undef elf_machine_rel_relative
138: #undef DO_ELF_MACHINE_REL_RELATIVE
139: #undef RELCOUNT_IDX