• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Macros to enable writing native and generic ELF access code.
2    Copyright (C) 2003 Red Hat, Inc.
3    This file is part of elfutils.
4    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
5 
6    This file is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    elfutils is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18 
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22 
23 #include <libebl.h>
24 
25 
26 /* By default the linker is handling all architectures.  But it can
27    be configured to be a native-only linker.  */
28 #if NATIVE_ELF == 32
29 /* 32-bit only.  */
30 # define XElf_Ehdr Elf32_Ehdr
31 # define XElf_Shdr Elf32_Shdr
32 # define XElf_Off Elf32_Off
33 # define XElf_Addr Elf32_Addr
34 # define XElf_Half Elf32_Half
35 # define XElf_Word Elf32_Word
36 # define XElf_Xword Elf32_Word
37 # define XElf_Sxword Elf32_Sword
38 # define XElf_Versym Elf32_Versym
39 # define XElf_Sym Elf32_Sym
40 # define XElf_Rel Elf32_Rel
41 # define XElf_Rela Elf32_Rela
42 
43 # define XElf_Ehdr_vardef(name) Elf32_Ehdr *name
44 # define xelf_getehdr(elf, name) name = elf32_getehdr (elf)
45 # define xelf_getehdr_copy(elf, name, copy) \
46   (copy) = *(name = elf32_getehdr (elf))
47 # define xelf_newehdr(elf, klass) elf32_newehdr (elf)
48 # define xelf_update_ehdr(elf, ehdr) \
49   /* nothing */ ((void) (elf), (void) (ehdr), 1)
50 
51 # define xelf_getclass(elf) ELFCLASS32
52 
53 # define XElf_Phdr_vardef(name) Elf32_Phdr *name
54 # define xelf_newphdr(elf, n) elf32_newphdr (elf, n)
55 # define xelf_getphdr(elf, idx, name) name = elf32_getphdr (elf) + idx
56 # define xelf_getphdr_ptr(elf, idx, name) name = elf32_getphdr (elf) + idx
57 # define xelf_update_phdr(elf, idx, phdr) \
58   /* nothing */ ((void) (elf), (void) (idx), (void) (phdr), 1)
59 
60 # define XElf_Shdr_vardef(name) Elf32_Shdr *name
61 # define xelf_getshdr(scn, name) name = elf32_getshdr (scn)
62 # define xelf_getshdr_copy(scn, name, copy) \
63   (copy) = *(name = elf32_getshdr (scn))
64 # define xelf_update_shdr(scn, shdr) \
65   /* nothing */ ((void) (scn), (void) (shdr), 1)
66 
67 # define XElf_Sym_vardef(name) Elf32_Sym *name
68 # define xelf_getsym(data, idx, name) \
69   name = &((Elf32_Sym *) (data)->d_buf)[idx]
70 # define xelf_getsym_ptr(data, idx, name) \
71   name = &((Elf32_Sym *) (data)->d_buf)[idx]
72 # define xelf_getsymshndx(data, ndxdata, idx, name1, name2) \
73   (name1 = &((Elf32_Sym *) ((data)->d_buf))[idx]);			      \
74   name2 = (unlikely ((ndxdata) != NULL)					      \
75 	   ? ((Elf32_Word *) ((ndxdata)->d_buf))[idx] : 0)
76 # define xelf_update_sym(data, idx, sym) \
77   /* nothing */ ((void) (data), (void) (idx), (void) (sym), 1)
78 # define xelf_update_symshndx(data, ndxdata, idx, name1, name2, datachanged) \
79   if (datachanged)							      \
80     ((Elf32_Sym *) ((data)->d_buf))[idx] = *name1;			      \
81   if (unlikely (ndxdata != NULL))					      \
82     ((Elf32_Word *) ((ndxdata)->d_buf))[idx] = name2
83 
84 # define XElf_Versym_vardef(name) Elf32_Versym name
85 # define xelf_getversym_copy(data, idx, name) \
86   (name = ((Elf32_Versym *) ((data)->d_buf))[idx], &name)
87 
88 # define XElf_Dyn_vardef(name) Elf32_Dyn *name
89 # define xelf_getdyn(data, idx, name) \
90   name = &((Elf32_Dyn *) ((data)->d_buf))[idx]
91 # define xelf_getdyn_ptr(data, idx, name) \
92   name = &((Elf32_Dyn *) ((data)->d_buf))[idx]
93 # define xelf_update_dyn(data, idx, name) \
94   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
95 
96 # define XElf_Rel_vardef(name) Elf32_Rel *name
97 # define xelf_getrel(data, idx, name) \
98   name = &((Elf32_Rel *) ((data)->d_buf))[idx]
99 # define xelf_getrel_ptr(data, idx, name) \
100   name = &((Elf32_Rel *) ((data)->d_buf))[idx]
101 # define xelf_update_rel(data, idx, name) \
102   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
103 
104 # define XElf_Rela_vardef(name) Elf32_Rela *name
105 # define xelf_getrela(data, idx, name) \
106   name = &((Elf32_Rela *) ((data)->d_buf))[idx]
107 # define xelf_getrela_ptr(data, idx, name) \
108   name = &((Elf32_Rela *) ((data)->d_buf))[idx]
109 # define xelf_update_rela(data, idx, name) \
110   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
111 
112 # define XElf_Verdef_vardef(name) Elf32_Verdef *name
113 # define xelf_getverdef(data, offset, name) \
114   name = ((Elf32_Verdef *) ((char *) ((data)->d_buf) + (offset)))
115 
116 # define XElf_Verdaux_vardef(name) Elf32_Verdaux *name
117 # define xelf_getverdaux(data, offset, name) \
118   name = ((Elf32_Verdaux *) ((char *) ((data)->d_buf) + (offset)))
119 
120 # define XELF_ST_TYPE(info) ELF32_ST_TYPE (info)
121 # define XELF_ST_BIND(info) ELF32_ST_BIND (info)
122 # define XELF_ST_INFO(bind, type) ELF32_ST_INFO (bind, type)
123 # define XELF_ST_VISIBILITY(info) ELF32_ST_VISIBILITY (info)
124 
125 # define XELF_R_SYM(info) ELF32_R_SYM (info)
126 # define XELF_R_TYPE(info) ELF32_R_TYPE (info)
127 # define XELF_R_INFO(sym, type) ELF32_R_INFO (sym, type)
128 
129 # define xelf_fsize(elf, type, cnt) \
130   (__builtin_constant_p (type)						      \
131    ? ({ size_t fsize;							      \
132         switch (type)							      \
133 	  {								      \
134 	  case ELF_T_BYTE: fsize = 1; break;				      \
135 	  case ELF_T_ADDR: fsize = sizeof (Elf32_Addr); break;		      \
136 	  case ELF_T_DYN: fsize = sizeof (Elf32_Dyn); break;		      \
137 	  case ELF_T_EHDR: fsize = sizeof (Elf32_Ehdr); break;		      \
138 	  case ELF_T_HALF: fsize = sizeof (Elf32_Half); break;		      \
139 	  case ELF_T_OFF: fsize = sizeof (Elf32_Off); break;		      \
140 	  case ELF_T_PHDR: fsize = sizeof (Elf32_Phdr); break;		      \
141 	  case ELF_T_RELA: fsize = sizeof (Elf32_Rela); break;		      \
142 	  case ELF_T_REL: fsize = sizeof (Elf32_Rel); break;		      \
143 	  case ELF_T_SHDR: fsize = sizeof (Elf32_Shdr); break;		      \
144 	  case ELF_T_SWORD: fsize = sizeof (Elf32_Sword); break;	      \
145 	  case ELF_T_SYM: fsize = sizeof (Elf32_Sym); break;		      \
146 	  case ELF_T_WORD: fsize = sizeof (Elf32_Word); break;		      \
147 	  case ELF_T_XWORD: fsize = sizeof (Elf32_Xword); break;	      \
148 	  case ELF_T_SXWORD: fsize = sizeof (Elf32_Sxword); break;	      \
149 	  case ELF_T_VDEF: fsize = sizeof (Elf32_Verdef); break;	      \
150 	  case ELF_T_VDAUX: fsize = sizeof (Elf32_Verdaux); break;	      \
151 	  case ELF_T_VNEED: fsize = sizeof (Elf32_Verneed); break;	      \
152 	  case ELF_T_VNAUX: fsize = sizeof (Elf32_Vernaux); break;	      \
153 	  case ELF_T_NHDR: fsize = sizeof (Elf32_Nhdr); break;		      \
154 	  case ELF_T_SYMINFO: fsize = sizeof (Elf32_Syminfo); break;	      \
155 	  case ELF_T_MOVE: fsize = sizeof (Elf32_Move); break;		      \
156           default: fsize = 0; break;					      \
157 	  }								      \
158         fsize * (cnt); })						      \
159    : gelf_fsize (elf, type, cnt, EV_CURRENT))
160 #elif NATIVE_ELF == 64
161 /* 64-bit only.  */
162 # define XElf_Ehdr Elf64_Ehdr
163 # define XElf_Shdr Elf64_Shdr
164 # define XElf_Addr Elf64_Addr
165 # define XElf_Half Elf64_Half
166 # define XElf_Off Elf64_Off
167 # define XElf_Word Elf64_Word
168 # define XElf_Xword Elf64_Xword
169 # define XElf_Sxword Elf64_Sxword
170 # define XElf_Versym Elf64_Versym
171 # define XElf_Sym Elf64_Sym
172 # define XElf_Rel Elf64_Rel
173 # define XElf_Rela Elf64_Rela
174 
175 # define XElf_Ehdr_vardef(name) Elf64_Ehdr *name
176 # define xelf_getehdr(elf, name) name = elf64_getehdr (elf)
177 # define xelf_getehdr_copy(elf, name, copy) \
178   (copy) = *(name = elf64_getehdr (elf))
179 # define xelf_newehdr(elf, klass) elf64_newehdr (elf)
180 # define xelf_update_ehdr(elf, ehdr) \
181   /* nothing */ ((void) (elf), (void) (ehdr), 1)
182 
183 # define xelf_getclass(elf) ELFCLASS32
184 
185 # define XElf_Phdr_vardef(name) Elf64_Phdr *name
186 # define xelf_newphdr(elf, n) elf64_newphdr (elf, n)
187 # define xelf_getphdr(elf, idx, name) name = elf64_getphdr (elf) + idx
188 # define xelf_getphdr_ptr(elf, idx, name) name = elf64_getphdr (elf) + idx
189 # define xelf_update_phdr(elf, idx, phdr) \
190   /* nothing */ ((void) (elf), (void) (idx), (void) (phdr), 1)
191 
192 # define XElf_Shdr_vardef(name) Elf64_Shdr *name
193 # define xelf_getshdr(scn, name) name = elf64_getshdr (scn)
194 # define xelf_getshdr_copy(scn, name, copy) \
195   (copy) = *(name = elf64_getshdr (scn))
196 # define xelf_update_shdr(scn, shdr) \
197   /* nothing */ ((void) (scn), (void) (shdr), 1)
198 
199 # define XElf_Sym_vardef(name) Elf64_Sym *name
200 # define xelf_getsym(data, idx, name) \
201   name = &((Elf64_Sym *) (data)->d_buf)[idx]
202 # define xelf_getsym_ptr(data, idx, name) \
203   name = &((Elf64_Sym *) (data)->d_buf)[idx]
204 # define xelf_getsymshndx(data, ndxdata, idx, name1, name2) \
205   (name1 = &((Elf64_Sym *) ((data)->d_buf))[idx]);			      \
206   name2 = (unlikely ((ndxdata) != NULL)					      \
207 	   ? ((Elf32_Word *) ((ndxdata)->d_buf))[idx] : 0)
208 # define xelf_update_sym(data, idx, sym) \
209   /* nothing */ ((void) (data), (void) (idx), (void) (sym), 1)
210 # define xelf_update_symshndx(data, ndxdata, idx, name1, name2, datachanged) \
211   if (datachanged)							      \
212     ((Elf64_Sym *) ((data)->d_buf))[idx] = *name1;			      \
213   if (ndxdata != NULL)							      \
214     (((Elf32_Word *) ((ndxdata)->d_buf))[idx] = name2)
215 
216 # define XElf_Versym_vardef(name) Elf64_Versym name
217 # define xelf_getversym_copy(data, idx, name) \
218   (name = ((Elf64_Versym *) ((data)->d_buf))[idx], (&name))
219 
220 # define XElf_Dyn_vardef(name) Elf64_Dyn *name
221 # define xelf_getdyn(data, idx, name) \
222   name = &((Elf64_Dyn *) ((data)->d_buf))[idx]
223 # define xelf_getdyn_ptr(data, idx, name) \
224   name = &((Elf64_Dyn *) ((data)->d_buf))[idx]
225 # define xelf_update_dyn(data, idx, name) \
226   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
227 
228 # define XElf_Rel_vardef(name) Elf64_Rel *name
229 # define xelf_getrel(data, idx, name) \
230   name = &((Elf64_Rel *) ((data)->d_buf))[idx]
231 # define xelf_getrel_ptr(data, idx, name) \
232   name = &((Elf64_Rel *) ((data)->d_buf))[idx]
233 # define xelf_update_rel(data, idx, name) \
234   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
235 
236 # define XElf_Rela_vardef(name) Elf64_Rela *name
237 # define xelf_getrela(data, idx, name) \
238   name = &((Elf64_Rela *) ((data)->d_buf))[idx]
239 # define xelf_getrela_ptr(data, idx, name) \
240   name = &((Elf64_Rela *) ((data)->d_buf))[idx]
241 # define xelf_update_rela(data, idx, name) \
242   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
243 
244 # define XElf_Verdef_vardef(name) Elf64_Verdef *name
245 # define xelf_getverdef(data, offset, name) \
246   name = ((Elf64_Verdef *) ((char *) ((data)->d_buf) + (offset)))
247 
248 # define XElf_Verdaux_vardef(name) Elf64_Verdaux *name
249 # define xelf_getverdaux(data, offset, name) \
250   name = ((Elf64_Verdaux *) ((char *) ((data)->d_buf) + (offset)))
251 
252 # define XELF_ST_TYPE(info) ELF64_ST_TYPE (info)
253 # define XELF_ST_BIND(info) ELF64_ST_BIND (info)
254 # define XELF_ST_INFO(bind, type) ELF64_ST_INFO (bind, type)
255 # define XELF_ST_VISIBILITY(info) ELF64_ST_VISIBILITY (info)
256 
257 # define XELF_R_SYM(info) ELF64_R_SYM (info)
258 # define XELF_R_TYPE(info) ELF64_R_TYPE (info)
259 # define XELF_R_INFO(sym, type) ELF64_R_INFO (sym, type)
260 
261 # define xelf_fsize(elf, type, cnt) \
262   (__builtin_constant_p (type)						      \
263    ? ({ size_t fsize;							      \
264         switch (type)							      \
265 	  {								      \
266 	  case ELF_T_BYTE: fsize = 1; break;				      \
267 	  case ELF_T_ADDR: fsize = sizeof (Elf64_Addr); break;		      \
268 	  case ELF_T_DYN: fsize = sizeof (Elf64_Dyn); break;		      \
269 	  case ELF_T_EHDR: fsize = sizeof (Elf64_Ehdr); break;		      \
270 	  case ELF_T_HALF: fsize = sizeof (Elf64_Half); break;		      \
271 	  case ELF_T_OFF: fsize = sizeof (Elf64_Off); break;		      \
272 	  case ELF_T_PHDR: fsize = sizeof (Elf64_Phdr); break;		      \
273 	  case ELF_T_RELA: fsize = sizeof (Elf64_Rela); break;		      \
274 	  case ELF_T_REL: fsize = sizeof (Elf64_Rel); break;		      \
275 	  case ELF_T_SHDR: fsize = sizeof (Elf64_Shdr); break;		      \
276 	  case ELF_T_SWORD: fsize = sizeof (Elf64_Sword); break;	      \
277 	  case ELF_T_SYM: fsize = sizeof (Elf64_Sym); break;		      \
278 	  case ELF_T_WORD: fsize = sizeof (Elf64_Word); break;		      \
279 	  case ELF_T_XWORD: fsize = sizeof (Elf64_Xword); break;	      \
280 	  case ELF_T_SXWORD: fsize = sizeof (Elf64_Sxword); break;	      \
281 	  case ELF_T_VDEF: fsize = sizeof (Elf64_Verdef); break;	      \
282 	  case ELF_T_VDAUX: fsize = sizeof (Elf64_Verdaux); break;	      \
283 	  case ELF_T_VNEED: fsize = sizeof (Elf64_Verneed); break;	      \
284 	  case ELF_T_VNAUX: fsize = sizeof (Elf64_Vernaux); break;	      \
285 	  case ELF_T_NHDR: fsize = sizeof (Elf64_Nhdr); break;		      \
286 	  case ELF_T_SYMINFO: fsize = sizeof (Elf64_Syminfo); break;	      \
287 	  case ELF_T_MOVE: fsize = sizeof (Elf64_Move); break;		      \
288           default: fsize = 0; break;					      \
289 	  }								      \
290         fsize * (cnt); })						      \
291    : gelf_fsize (elf, type, cnt, EV_CURRENT))
292 #else
293 # include <gelf.h>
294 
295 /* Generic linker.  */
296 # define XElf_Ehdr GElf_Ehdr
297 # define XElf_Shdr GElf_Shdr
298 # define XElf_Addr GElf_Addr
299 # define XElf_Half GElf_Half
300 # define XElf_Off GElf_Off
301 # define XElf_Word GElf_Word
302 # define XElf_Xword GElf_Xword
303 # define XElf_Sxword GElf_Sxword
304 # define XElf_Versym GElf_Versym
305 # define XElf_Sym GElf_Sym
306 # define XElf_Rel GElf_Rel
307 # define XElf_Rela GElf_Rela
308 
309 # define XElf_Ehdr_vardef(name) GElf_Ehdr name##_mem; GElf_Ehdr *name
310 # define xelf_getehdr(elf, name) name = gelf_getehdr (elf, &name##_mem)
311 # define xelf_getehdr_copy(elf, name, copy) \
312   name = gelf_getehdr (elf, &(copy))
313 # define xelf_newehdr(elf, klass) gelf_newehdr (elf, klass)
314 # define xelf_update_ehdr(elf, ehdr) gelf_update_ehdr (elf, ehdr)
315 
316 # define xelf_getclass(elf) gelf_getclass (elf)
317 
318 # define XElf_Phdr_vardef(name) GElf_Phdr name##_mem; GElf_Phdr *name
319 # define xelf_newphdr(elf, n) gelf_newphdr (elf, n)
320 # define xelf_getphdr(elf, idx, name) \
321   name = gelf_getphdr (elf, idx, &name##_mem)
322 # define xelf_getphdr_ptr(elf, idx, name) \
323   name = &name##_mem
324 # define xelf_update_phdr(elf, idx, phdr) \
325   gelf_update_phdr (elf, idx, phdr)
326 
327 # define XElf_Shdr_vardef(name) GElf_Shdr name##_mem; GElf_Shdr *name
328 # define xelf_getshdr(scn, name) name = gelf_getshdr (scn, &name##_mem)
329 # define xelf_getshdr_copy(scn, name, copy) \
330   name = gelf_getshdr (scn, &(copy))
331 # define xelf_update_shdr(scn, shdr) gelf_update_shdr (scn, shdr)
332 
333 # define XElf_Sym_vardef(name) GElf_Sym name##_mem; GElf_Sym *name
334 # define xelf_getsym(data, idx, name) \
335   name = gelf_getsym (data, idx, &name##_mem)
336 # define xelf_getsym_ptr(data, idx, name) \
337   name = &name##_mem
338 # define xelf_getsymshndx(data, ndxdata, idx, name1, name2) \
339   name1 = gelf_getsymshndx (data, ndxdata, idx, &name1##_mem, &(name2))
340 # define xelf_update_sym(data, idx, sym) gelf_update_sym (data, idx, sym)
341 # define xelf_update_symshndx(data, ndxdata, idx, name1, name2, datachanged) \
342   gelf_update_symshndx (data, ndxdata, idx, name1, name2)
343 
344 # define XElf_Versym_vardef(name) GElf_Versym name
345 # define xelf_getversym_copy(data, idx, name) \
346   gelf_getversym (data, idx, &name)
347 
348 # define XElf_Dyn_vardef(name) GElf_Dyn name##_mem; GElf_Dyn *name
349 # define xelf_getdyn(data, idx, name) \
350   name = gelf_getdyn (data, idx, &name##_mem)
351 # define xelf_getdyn_ptr(data, idx, name) \
352   name = &name##_mem
353 # define xelf_update_dyn(data, idx, name) \
354   gelf_update_dyn (data, idx, name)
355 
356 # define XElf_Rel_vardef(name) GElf_Rel name##_mem; GElf_Rel *name
357 # define xelf_getrel(data, idx, name) \
358   name = gelf_getrel (data, idx, &name##_mem)
359 # define xelf_getrel_ptr(data, idx, name) \
360   name = &name##_mem
361 # define xelf_update_rel(data, idx, name) \
362   gelf_update_rel (data, idx, name)
363 
364 # define XElf_Rela_vardef(name) GElf_Rela name##_mem; GElf_Rela *name
365 # define xelf_getrela(data, idx, name) \
366   name = gelf_getrela (data, idx, &name##_mem)
367 # define xelf_getrela_ptr(data, idx, name) \
368   name = &name##_mem
369 # define xelf_update_rela(data, idx, name) \
370   gelf_update_rela (data, idx, name)
371 
372 # define XElf_Verdef_vardef(name) GElf_Verdef name##_mem; GElf_Verdef *name
373 # define xelf_getverdef(data, offset, name) \
374   name = gelf_getverdef (data, offset, &name##_mem)
375 
376 # define XElf_Verdaux_vardef(name) GElf_Verdaux name##_mem; GElf_Verdaux *name
377 # define xelf_getverdaux(data, offset, name) \
378   name = gelf_getverdaux (data, offset, &name##_mem)
379 
380 # define XELF_ST_TYPE(info) GELF_ST_TYPE (info)
381 # define XELF_ST_BIND(info) GELF_ST_BIND (info)
382 # define XELF_ST_INFO(bind, type) GELF_ST_INFO (bind, type)
383 # define XELF_ST_VISIBILITY(info) GELF_ST_VISIBILITY (info)
384 
385 # define XELF_R_SYM(info) GELF_R_SYM (info)
386 # define XELF_R_TYPE(info) GELF_R_TYPE (info)
387 # define XELF_R_INFO(sym, type) GELF_R_INFO (sym, type)
388 
389 # define xelf_fsize(elf, type, cnt) \
390   gelf_fsize (elf, type, cnt, EV_CURRENT)
391 #endif
392