debuggers.hg

view xen/common/libelf/libelf-tools.c @ 22848:6341fe0f4e5a

Added tag 4.1.0-rc2 for changeset 9dca60d88c63
author Keir Fraser <keir@xen.org>
date Tue Jan 25 14:06:55 2011 +0000 (2011-01-25)
parents eccfdeb41b80
children
line source
1 /*
2 * various helper functions to access elf structures
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation;
7 * version 2.1 of the License.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
19 #include "libelf-private.h"
21 /* ------------------------------------------------------------------------ */
23 uint64_t elf_access_unsigned(struct elf_binary * elf, const void *ptr,
24 uint64_t offset, size_t size)
25 {
26 int need_swap = elf_swap(elf);
27 const uint8_t *u8;
28 const uint16_t *u16;
29 const uint32_t *u32;
30 const uint64_t *u64;
32 switch ( size )
33 {
34 case 1:
35 u8 = ptr + offset;
36 return *u8;
37 case 2:
38 u16 = ptr + offset;
39 return need_swap ? bswap_16(*u16) : *u16;
40 case 4:
41 u32 = ptr + offset;
42 return need_swap ? bswap_32(*u32) : *u32;
43 case 8:
44 u64 = ptr + offset;
45 return need_swap ? bswap_64(*u64) : *u64;
46 default:
47 return 0;
48 }
49 }
51 int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
52 uint64_t offset, size_t size)
53 {
54 int need_swap = elf_swap(elf);
55 const int8_t *s8;
56 const int16_t *s16;
57 const int32_t *s32;
58 const int64_t *s64;
60 switch ( size )
61 {
62 case 1:
63 s8 = ptr + offset;
64 return *s8;
65 case 2:
66 s16 = ptr + offset;
67 return need_swap ? bswap_16(*s16) : *s16;
68 case 4:
69 s32 = ptr + offset;
70 return need_swap ? bswap_32(*s32) : *s32;
71 case 8:
72 s64 = ptr + offset;
73 return need_swap ? bswap_64(*s64) : *s64;
74 default:
75 return 0;
76 }
77 }
79 uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
80 {
81 int elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
83 return (addr + elf_round) & ~elf_round;
84 }
86 /* ------------------------------------------------------------------------ */
88 int elf_shdr_count(struct elf_binary *elf)
89 {
90 return elf_uval(elf, elf->ehdr, e_shnum);
91 }
93 int elf_phdr_count(struct elf_binary *elf)
94 {
95 return elf_uval(elf, elf->ehdr, e_phnum);
96 }
98 const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name)
99 {
100 uint64_t count = elf_shdr_count(elf);
101 const elf_shdr *shdr;
102 const char *sname;
103 int i;
105 for ( i = 0; i < count; i++ )
106 {
107 shdr = elf_shdr_by_index(elf, i);
108 sname = elf_section_name(elf, shdr);
109 if ( sname && !strcmp(sname, name) )
110 return shdr;
111 }
112 return NULL;
113 }
115 const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index)
116 {
117 uint64_t count = elf_shdr_count(elf);
118 const void *ptr;
120 if ( index >= count )
121 return NULL;
123 ptr = (elf->image
124 + elf_uval(elf, elf->ehdr, e_shoff)
125 + elf_uval(elf, elf->ehdr, e_shentsize) * index);
126 return ptr;
127 }
129 const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index)
130 {
131 uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
132 const void *ptr;
134 if ( index >= count )
135 return NULL;
137 ptr = (elf->image
138 + elf_uval(elf, elf->ehdr, e_phoff)
139 + elf_uval(elf, elf->ehdr, e_phentsize) * index);
140 return ptr;
141 }
143 const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr)
144 {
145 if ( elf->sec_strtab == NULL )
146 return "unknown";
147 return elf->sec_strtab + elf_uval(elf, shdr, sh_name);
148 }
150 const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr)
151 {
152 return elf->image + elf_uval(elf, shdr, sh_offset);
153 }
155 const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr)
156 {
157 return elf->image
158 + elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size);
159 }
161 const void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr)
162 {
163 return elf->image + elf_uval(elf, phdr, p_offset);
164 }
166 const void *elf_segment_end(struct elf_binary *elf, const elf_phdr * phdr)
167 {
168 return elf->image
169 + elf_uval(elf, phdr, p_offset) + elf_uval(elf, phdr, p_filesz);
170 }
172 const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol)
173 {
174 const void *ptr = elf_section_start(elf, elf->sym_tab);
175 const void *end = elf_section_end(elf, elf->sym_tab);
176 const elf_sym *sym;
177 uint64_t info, name;
179 for ( ; ptr < end; ptr += elf_size(elf, sym) )
180 {
181 sym = ptr;
182 info = elf_uval(elf, sym, st_info);
183 name = elf_uval(elf, sym, st_name);
184 if ( ELF32_ST_BIND(info) != STB_GLOBAL )
185 continue;
186 if ( strcmp(elf->sym_strtab + name, symbol) )
187 continue;
188 return sym;
189 }
190 return NULL;
191 }
193 const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index)
194 {
195 const void *ptr = elf_section_start(elf, elf->sym_tab);
196 const elf_sym *sym;
198 sym = ptr + index * elf_size(elf, sym);
199 return sym;
200 }
202 const char *elf_note_name(struct elf_binary *elf, const elf_note * note)
203 {
204 return (void *)note + elf_size(elf, note);
205 }
207 const void *elf_note_desc(struct elf_binary *elf, const elf_note * note)
208 {
209 int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
211 return (void *)note + elf_size(elf, note) + namesz;
212 }
214 uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note)
215 {
216 const void *desc = elf_note_desc(elf, note);
217 int descsz = elf_uval(elf, note, descsz);
219 switch (descsz)
220 {
221 case 1:
222 case 2:
223 case 4:
224 case 8:
225 return elf_access_unsigned(elf, desc, 0, descsz);
226 default:
227 return 0;
228 }
229 }
230 const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note)
231 {
232 int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
233 int descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
235 return (void *)note + elf_size(elf, note) + namesz + descsz;
236 }
238 /* ------------------------------------------------------------------------ */
240 int elf_is_elfbinary(const void *image)
241 {
242 const Elf32_Ehdr *ehdr = image;
244 return IS_ELF(*ehdr);
245 }
247 int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr)
248 {
249 uint64_t p_type = elf_uval(elf, phdr, p_type);
250 uint64_t p_flags = elf_uval(elf, phdr, p_flags);
252 return ((p_type == PT_LOAD) && (p_flags & (PF_R | PF_W | PF_X)) != 0);
253 }
255 /*
256 * Local variables:
257 * mode: C
258 * c-set-style: "BSD"
259 * c-basic-offset: 4
260 * tab-width: 4
261 * indent-tabs-mode: nil
262 * End:
263 */