1 /* Generic ELF wrapper for libelf which does not support gelf_ API.
2 Copyright (C) 2001, 2002, 2004 Red Hat, Inc.
3 Written by Jakub Jelinek <jakub@redhat.com>, 2001.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 #include <sys/types.h>
28 gelf_getclass (Elf *elf)
31 char *e_ident = elf_getident (elf, &size);
35 switch (e_ident [EI_CLASS])
39 return e_ident [EI_CLASS];
46 gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int ver)
48 switch (gelf_getclass (elf))
51 return elf32_fsize (type, count, ver);
53 return elf64_fsize (type, count, ver);
60 gelf_getehdr (Elf *elf, GElf_Ehdr *dst)
65 switch (gelf_getclass (elf))
68 ehdr32 = elf32_getehdr (elf);
71 memcpy (dst->e_ident, ehdr32->e_ident, EI_NIDENT);
72 dst->e_type = ehdr32->e_type;
73 dst->e_machine = ehdr32->e_machine;
74 dst->e_version = ehdr32->e_version;
75 dst->e_entry = ehdr32->e_entry;
76 dst->e_phoff = ehdr32->e_phoff;
77 dst->e_shoff = ehdr32->e_shoff;
78 dst->e_flags = ehdr32->e_flags;
79 dst->e_ehsize = ehdr32->e_ehsize;
80 dst->e_phentsize = ehdr32->e_phentsize;
81 dst->e_phnum = ehdr32->e_phnum;
82 dst->e_shentsize = ehdr32->e_shentsize;
83 dst->e_shnum = ehdr32->e_shnum;
84 dst->e_shstrndx = ehdr32->e_shstrndx;
89 ehdr64 = elf64_getehdr (elf);
92 memcpy (dst, ehdr64, sizeof (Elf64_Ehdr));
100 gelf_update_ehdr (Elf *elf, GElf_Ehdr *src)
105 switch (gelf_getclass (elf))
108 ehdr32 = elf32_getehdr (elf);
111 memcpy (ehdr32->e_ident, src->e_ident, EI_NIDENT);
112 ehdr32->e_type = src->e_type;
113 ehdr32->e_machine = src->e_machine;
114 ehdr32->e_version = src->e_version;
115 ehdr32->e_entry = src->e_entry;
116 ehdr32->e_phoff = src->e_phoff;
117 ehdr32->e_shoff = src->e_shoff;
118 ehdr32->e_flags = src->e_flags;
119 ehdr32->e_ehsize = src->e_ehsize;
120 ehdr32->e_phentsize = src->e_phentsize;
121 ehdr32->e_phnum = src->e_phnum;
122 ehdr32->e_shentsize = src->e_shentsize;
123 ehdr32->e_shnum = src->e_shnum;
124 ehdr32->e_shstrndx = src->e_shstrndx;
127 ehdr64 = elf64_getehdr (elf);
130 memcpy (ehdr64, src, sizeof (Elf64_Ehdr));
140 gelf_newehdr (Elf *elf, int class)
145 return (unsigned long) elf32_newehdr (elf);
147 return (unsigned long) elf64_newehdr (elf);
154 gelf_getphdr (Elf *elf, int ndx, GElf_Phdr *dst)
161 switch (gelf_getclass (elf))
164 phdr32 = elf32_getphdr (elf);
167 ehdr32 = elf32_getehdr (elf);
170 if (ndx >= ehdr32->e_phnum)
173 dst->p_type = phdr32->p_type;
174 dst->p_offset = phdr32->p_offset;
175 dst->p_vaddr = phdr32->p_vaddr;
176 dst->p_paddr = phdr32->p_paddr;
177 dst->p_filesz = phdr32->p_filesz;
178 dst->p_memsz = phdr32->p_memsz;
179 dst->p_flags = phdr32->p_flags;
180 dst->p_align = phdr32->p_align;
183 phdr64 = elf64_getphdr (elf);
186 ehdr64 = elf64_getehdr (elf);
189 if (ndx >= ehdr64->e_phnum)
191 memcpy (dst, phdr64 + ndx, sizeof (Elf64_Phdr));
199 gelf_update_phdr (Elf *elf, int ndx, GElf_Phdr *src)
206 switch (gelf_getclass (elf))
209 phdr32 = elf32_getphdr (elf);
212 ehdr32 = elf32_getehdr (elf);
215 if (ndx >= ehdr32->e_phnum)
218 phdr32->p_type = src->p_type;
219 phdr32->p_offset = src->p_offset;
220 phdr32->p_vaddr = src->p_vaddr;
221 phdr32->p_paddr = src->p_paddr;
222 phdr32->p_filesz = src->p_filesz;
223 phdr32->p_memsz = src->p_memsz;
224 phdr32->p_flags = src->p_flags;
225 phdr32->p_align = src->p_align;
228 phdr64 = elf64_getphdr (elf);
231 ehdr64 = elf64_getehdr (elf);
234 if (ndx >= ehdr64->e_phnum)
236 memcpy (phdr64 + ndx, src, sizeof (Elf64_Phdr));
244 gelf_newphdr (Elf *elf, size_t phnum)
246 switch (gelf_getclass (elf))
249 return (unsigned long) elf32_newphdr (elf, phnum);
251 return (unsigned long) elf64_newphdr (elf, phnum);
258 gelfx_getshdr (Elf *elf, Elf_Scn *scn, GElf_Shdr *dst)
263 switch (gelf_getclass (elf))
266 shdr32 = elf32_getshdr (scn);
269 dst->sh_name = shdr32->sh_name;
270 dst->sh_type = shdr32->sh_type;
271 dst->sh_flags = shdr32->sh_flags;
272 dst->sh_addr = shdr32->sh_addr;
273 dst->sh_offset = shdr32->sh_offset;
274 dst->sh_size = shdr32->sh_size;
275 dst->sh_link = shdr32->sh_link;
276 dst->sh_info = shdr32->sh_info;
277 dst->sh_addralign = shdr32->sh_addralign;
278 dst->sh_entsize = shdr32->sh_entsize;
281 shdr64 = elf64_getshdr (scn);
284 memcpy (dst, shdr64, sizeof (Elf64_Shdr));
292 gelfx_update_shdr (Elf *elf, Elf_Scn *scn, GElf_Shdr *src)
297 switch (gelf_getclass (elf))
300 shdr32 = elf32_getshdr (scn);
303 shdr32->sh_name = src->sh_name;
304 shdr32->sh_type = src->sh_type;
305 shdr32->sh_flags = src->sh_flags;
306 shdr32->sh_addr = src->sh_addr;
307 shdr32->sh_offset = src->sh_offset;
308 shdr32->sh_size = src->sh_size;
309 shdr32->sh_link = src->sh_link;
310 shdr32->sh_info = src->sh_info;
311 shdr32->sh_addralign = src->sh_addralign;
312 shdr32->sh_entsize = src->sh_entsize;
315 shdr64 = elf64_getshdr (scn);
318 memcpy (shdr64, src, sizeof (Elf64_Shdr));
326 gelf_xlatetom (Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
328 switch (gelf_getclass (elf))
331 return elf32_xlatetom (dst, src, encode);
333 return elf64_xlatetom (dst, src, encode);
340 gelf_xlatetof (Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
342 switch (gelf_getclass (elf))
345 return elf32_xlatetof (dst, src, encode);
347 return elf64_xlatetof (dst, src, encode);
353 GElf_Sym *gelfx_getsym (Elf *elf, Elf_Data *data, int ndx, GElf_Sym *dst)
357 if (data->d_type != ELF_T_SYM)
360 switch (gelf_getclass (elf))
363 if ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size)
365 sym32 = &((Elf32_Sym *) data->d_buf)[ndx];
366 dst->st_name = sym32->st_name;
367 dst->st_info = sym32->st_info;
368 dst->st_other = sym32->st_other;
369 dst->st_shndx = sym32->st_shndx;
370 dst->st_value = sym32->st_value;
371 dst->st_size = sym32->st_size;
374 if ((ndx + 1) * sizeof (Elf64_Sym) > data->d_size)
376 *dst = ((GElf_Sym *) data->d_buf)[ndx];
383 int gelfx_update_sym (Elf *elf, Elf_Data *data, int ndx, GElf_Sym *src)
387 if (data->d_type != ELF_T_SYM)
390 switch (gelf_getclass (elf))
393 if ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size)
395 sym32 = &((Elf32_Sym *) data->d_buf)[ndx];
396 sym32->st_name = src->st_name;
397 sym32->st_info = src->st_info;
398 sym32->st_other = src->st_other;
399 sym32->st_shndx = src->st_shndx;
400 sym32->st_value = src->st_value;
401 sym32->st_size = src->st_size;
404 if ((ndx + 1) * sizeof (Elf64_Sym) > data->d_size)
406 ((GElf_Sym *) data->d_buf)[ndx] = *src;
413 GElf_Dyn *gelfx_getdyn (Elf *elf, Elf_Data *data, int ndx, GElf_Dyn *dst)
417 if (data->d_type != ELF_T_DYN)
420 switch (gelf_getclass (elf))
423 if ((ndx + 1) * sizeof (Elf32_Dyn) > data->d_size)
425 dyn32 = &((Elf32_Dyn *) data->d_buf)[ndx];
426 dst->d_tag = dyn32->d_tag;
427 dst->d_un.d_val = dyn32->d_un.d_val;
430 if ((ndx + 1) * sizeof (Elf64_Dyn) > data->d_size)
432 *dst = ((GElf_Dyn *) data->d_buf)[ndx];
439 int gelfx_update_dyn (Elf *elf, Elf_Data *data, int ndx, GElf_Dyn *src)
443 if (data->d_type != ELF_T_DYN)
446 switch (gelf_getclass (elf))
449 if ((ndx + 1) * sizeof (Elf32_Dyn) > data->d_size)
451 dyn32 = &((Elf32_Dyn *) data->d_buf)[ndx];
452 dyn32->d_tag = src->d_tag;
453 dyn32->d_un.d_val = src->d_un.d_val;
456 if ((ndx + 1) * sizeof (Elf64_Dyn) > data->d_size)
458 ((GElf_Dyn *) data->d_buf)[ndx] = *src;
465 GElf_Rel *gelfx_getrel (Elf *elf, Elf_Data *data, int ndx, GElf_Rel *dst)
469 if (data->d_type != ELF_T_REL)
472 switch (gelf_getclass (elf))
475 if ((ndx + 1) * sizeof (Elf32_Rel) > data->d_size)
477 rel32 = &((Elf32_Rel *) data->d_buf)[ndx];
478 dst->r_offset = rel32->r_offset;
479 dst->r_info = GELF_R_INFO (ELF32_R_SYM (rel32->r_info),
480 ELF32_R_TYPE (rel32->r_info));
483 if ((ndx + 1) * sizeof (Elf64_Rel) > data->d_size)
485 *dst = ((GElf_Rel *) data->d_buf)[ndx];
492 int gelfx_update_rel (Elf *elf, Elf_Data *data, int ndx, GElf_Rel *src)
496 if (data->d_type != ELF_T_REL)
499 switch (gelf_getclass (elf))
502 if ((ndx + 1) * sizeof (Elf32_Rel) > data->d_size)
504 rel32 = &((Elf32_Rel *) data->d_buf)[ndx];
505 rel32->r_offset = src->r_offset;
506 rel32->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info),
507 GELF_R_TYPE (src->r_info));
510 if ((ndx + 1) * sizeof (Elf64_Rel) > data->d_size)
512 ((GElf_Rel *) data->d_buf)[ndx] = *src;
519 GElf_Rela *gelfx_getrela (Elf *elf, Elf_Data *data, int ndx, GElf_Rela *dst)
523 if (data->d_type != ELF_T_RELA)
526 switch (gelf_getclass (elf))
529 if ((ndx + 1) * sizeof (Elf32_Rela) > data->d_size)
531 rela32 = &((Elf32_Rela *) data->d_buf)[ndx];
532 dst->r_offset = rela32->r_offset;
533 dst->r_info = GELF_R_INFO (ELF32_R_SYM (rela32->r_info),
534 ELF32_R_TYPE (rela32->r_info));
535 dst->r_addend = rela32->r_addend;
538 if ((ndx + 1) * sizeof (Elf64_Rela) > data->d_size)
540 *dst = ((GElf_Rela *) data->d_buf)[ndx];
547 int gelfx_update_rela (Elf *elf, Elf_Data *data, int ndx, GElf_Rela *src)
551 if (data->d_type != ELF_T_RELA)
554 switch (gelf_getclass (elf))
557 if ((ndx + 1) * sizeof (Elf32_Rela) > data->d_size)
559 rela32 = &((Elf32_Rela *) data->d_buf)[ndx];
560 rela32->r_offset = src->r_offset;
561 rela32->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info),
562 GELF_R_TYPE (src->r_info));
563 rela32->r_addend = src->r_addend;
566 if ((ndx + 1) * sizeof (Elf64_Rela) > data->d_size)
568 ((GElf_Rela *) data->d_buf)[ndx] = *src;