|
1 /* |
|
2 * gelfshdr.c - gelf_* translation functions. |
|
3 * Copyright (C) 2000 - 2006 Michael Riepe |
|
4 * |
|
5 * This library is free software; you can redistribute it and/or |
|
6 * modify it under the terms of the GNU Library General Public |
|
7 * License as published by the Free Software Foundation; either |
|
8 * version 2 of the License, or (at your option) any later version. |
|
9 * |
|
10 * This library 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 GNU |
|
13 * Library General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU Library General Public |
|
16 * License along with this library; if not, write to the Free Software |
|
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
18 */ |
|
19 |
|
20 #include <private.h> |
|
21 |
|
22 #if __LIBELF64 |
|
23 |
|
24 #ifndef lint |
|
25 static const char rcsid[] = "@(#) $Id: gelfshdr.c,v 1.9 2006/07/07 22:16:43 michael Exp $"; |
|
26 #endif /* lint */ |
|
27 |
|
28 #define check_and_copy(type, d, s, name, eret) \ |
|
29 do { \ |
|
30 if (sizeof((d)->name) < sizeof((s)->name) \ |
|
31 && (type)(s)->name != (s)->name) { \ |
|
32 seterr(ERROR_BADVALUE); \ |
|
33 return (eret); \ |
|
34 } \ |
|
35 (d)->name = (type)(s)->name; \ |
|
36 } while (0) |
|
37 |
|
38 GElf_Shdr* |
|
39 gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst) { |
|
40 GElf_Shdr buf; |
|
41 |
|
42 if (!scn) { |
|
43 return NULL; |
|
44 } |
|
45 elf_assert(scn->s_magic == SCN_MAGIC); |
|
46 elf_assert(scn->s_elf); |
|
47 elf_assert(scn->s_elf->e_magic == ELF_MAGIC); |
|
48 if (!dst) { |
|
49 dst = &buf; |
|
50 } |
|
51 if (scn->s_elf->e_class == ELFCLASS64) { |
|
52 *dst = scn->s_shdr64; |
|
53 } |
|
54 else if (scn->s_elf->e_class == ELFCLASS32) { |
|
55 Elf32_Shdr *src = &scn->s_shdr32; |
|
56 |
|
57 check_and_copy(GElf_Word, dst, src, sh_name, NULL); |
|
58 check_and_copy(GElf_Word, dst, src, sh_type, NULL); |
|
59 check_and_copy(GElf_Xword, dst, src, sh_flags, NULL); |
|
60 check_and_copy(GElf_Addr, dst, src, sh_addr, NULL); |
|
61 check_and_copy(GElf_Off, dst, src, sh_offset, NULL); |
|
62 check_and_copy(GElf_Xword, dst, src, sh_size, NULL); |
|
63 check_and_copy(GElf_Word, dst, src, sh_link, NULL); |
|
64 check_and_copy(GElf_Word, dst, src, sh_info, NULL); |
|
65 check_and_copy(GElf_Xword, dst, src, sh_addralign, NULL); |
|
66 check_and_copy(GElf_Xword, dst, src, sh_entsize, NULL); |
|
67 } |
|
68 else { |
|
69 if (valid_class(scn->s_elf->e_class)) { |
|
70 seterr(ERROR_UNIMPLEMENTED); |
|
71 } |
|
72 else { |
|
73 seterr(ERROR_UNKNOWN_CLASS); |
|
74 } |
|
75 return NULL; |
|
76 } |
|
77 if (dst == &buf) { |
|
78 dst = (GElf_Shdr*)malloc(sizeof(GElf_Shdr)); |
|
79 if (!dst) { |
|
80 seterr(ERROR_MEM_SHDR); |
|
81 return NULL; |
|
82 } |
|
83 *dst = buf; |
|
84 } |
|
85 return dst; |
|
86 } |
|
87 |
|
88 int |
|
89 gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src) { |
|
90 if (!scn || !src) { |
|
91 return 0; |
|
92 } |
|
93 elf_assert(scn->s_magic == SCN_MAGIC); |
|
94 elf_assert(scn->s_elf); |
|
95 elf_assert(scn->s_elf->e_magic == ELF_MAGIC); |
|
96 if (scn->s_elf->e_class == ELFCLASS64) { |
|
97 scn->s_shdr64 = *src; |
|
98 } |
|
99 else if (scn->s_elf->e_class == ELFCLASS32) { |
|
100 Elf32_Shdr *dst = &scn->s_shdr32; |
|
101 |
|
102 check_and_copy(Elf32_Word, dst, src, sh_name, 0); |
|
103 check_and_copy(Elf32_Word, dst, src, sh_type, 0); |
|
104 check_and_copy(Elf32_Word, dst, src, sh_flags, 0); |
|
105 check_and_copy(Elf32_Addr, dst, src, sh_addr, 0); |
|
106 check_and_copy(Elf32_Off, dst, src, sh_offset, 0); |
|
107 check_and_copy(Elf32_Word, dst, src, sh_size, 0); |
|
108 check_and_copy(Elf32_Word, dst, src, sh_link, 0); |
|
109 check_and_copy(Elf32_Word, dst, src, sh_info, 0); |
|
110 check_and_copy(Elf32_Word, dst, src, sh_addralign, 0); |
|
111 check_and_copy(Elf32_Word, dst, src, sh_entsize, 0); |
|
112 } |
|
113 else { |
|
114 if (valid_class(scn->s_elf->e_class)) { |
|
115 seterr(ERROR_UNIMPLEMENTED); |
|
116 } |
|
117 else { |
|
118 seterr(ERROR_UNKNOWN_CLASS); |
|
119 } |
|
120 return 0; |
|
121 } |
|
122 return 1; |
|
123 } |
|
124 |
|
125 #endif /* __LIBELF64 */ |