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