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