ia64/xen-unstable

view xen/common/libelf/libelf-tools.c @ 18594:5e4e234d58be

x86: Define __per_cpu_shift label to help kdump/crashdump.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Oct 08 13:11:06 2008 +0100 (2008-10-08)
parents 7ee30cf72fd3
children
line source
1 /*
2 * various helper functions to access elf structures
3 */
5 #include "libelf-private.h"
7 /* ------------------------------------------------------------------------ */
9 uint64_t elf_access_unsigned(struct elf_binary * elf, const void *ptr,
10 uint64_t offset, size_t size)
11 {
12 int need_swap = elf_swap(elf);
13 const uint8_t *u8;
14 const uint16_t *u16;
15 const uint32_t *u32;
16 const uint64_t *u64;
18 switch ( size )
19 {
20 case 1:
21 u8 = ptr + offset;
22 return *u8;
23 case 2:
24 u16 = ptr + offset;
25 return need_swap ? bswap_16(*u16) : *u16;
26 case 4:
27 u32 = ptr + offset;
28 return need_swap ? bswap_32(*u32) : *u32;
29 case 8:
30 u64 = ptr + offset;
31 return need_swap ? bswap_64(*u64) : *u64;
32 default:
33 return 0;
34 }
35 }
37 int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
38 uint64_t offset, size_t size)
39 {
40 int need_swap = elf_swap(elf);
41 const int8_t *s8;
42 const int16_t *s16;
43 const int32_t *s32;
44 const int64_t *s64;
46 switch ( size )
47 {
48 case 1:
49 s8 = ptr + offset;
50 return *s8;
51 case 2:
52 s16 = ptr + offset;
53 return need_swap ? bswap_16(*s16) : *s16;
54 case 4:
55 s32 = ptr + offset;
56 return need_swap ? bswap_32(*s32) : *s32;
57 case 8:
58 s64 = ptr + offset;
59 return need_swap ? bswap_64(*s64) : *s64;
60 default:
61 return 0;
62 }
63 }
65 uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
66 {
67 int elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
69 return (addr + elf_round) & ~elf_round;
70 }
72 /* ------------------------------------------------------------------------ */
74 int elf_shdr_count(struct elf_binary *elf)
75 {
76 return elf_uval(elf, elf->ehdr, e_shnum);
77 }
79 int elf_phdr_count(struct elf_binary *elf)
80 {
81 return elf_uval(elf, elf->ehdr, e_phnum);
82 }
84 const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name)
85 {
86 uint64_t count = elf_shdr_count(elf);
87 const elf_shdr *shdr;
88 const char *sname;
89 int i;
91 for ( i = 0; i < count; i++ )
92 {
93 shdr = elf_shdr_by_index(elf, i);
94 sname = elf_section_name(elf, shdr);
95 if ( sname && !strcmp(sname, name) )
96 return shdr;
97 }
98 return NULL;
99 }
101 const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index)
102 {
103 uint64_t count = elf_shdr_count(elf);
104 const void *ptr;
106 if ( index >= count )
107 return NULL;
109 ptr = (elf->image
110 + elf_uval(elf, elf->ehdr, e_shoff)
111 + elf_uval(elf, elf->ehdr, e_shentsize) * index);
112 return ptr;
113 }
115 const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index)
116 {
117 uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
118 const void *ptr;
120 if ( index >= count )
121 return NULL;
123 ptr = (elf->image
124 + elf_uval(elf, elf->ehdr, e_phoff)
125 + elf_uval(elf, elf->ehdr, e_phentsize) * index);
126 return ptr;
127 }
129 const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr)
130 {
131 if ( elf->sec_strtab == NULL )
132 return "unknown";
133 return elf->sec_strtab + elf_uval(elf, shdr, sh_name);
134 }
136 const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr)
137 {
138 return elf->image + elf_uval(elf, shdr, sh_offset);
139 }
141 const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr)
142 {
143 return elf->image
144 + elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size);
145 }
147 const void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr)
148 {
149 return elf->image + elf_uval(elf, phdr, p_offset);
150 }
152 const void *elf_segment_end(struct elf_binary *elf, const elf_phdr * phdr)
153 {
154 return elf->image
155 + elf_uval(elf, phdr, p_offset) + elf_uval(elf, phdr, p_filesz);
156 }
158 const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol)
159 {
160 const void *ptr = elf_section_start(elf, elf->sym_tab);
161 const void *end = elf_section_end(elf, elf->sym_tab);
162 const elf_sym *sym;
163 uint64_t info, name;
165 for ( ; ptr < end; ptr += elf_size(elf, sym) )
166 {
167 sym = ptr;
168 info = elf_uval(elf, sym, st_info);
169 name = elf_uval(elf, sym, st_name);
170 if ( ELF32_ST_BIND(info) != STB_GLOBAL )
171 continue;
172 if ( strcmp(elf->sym_strtab + name, symbol) )
173 continue;
174 return sym;
175 }
176 return NULL;
177 }
179 const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index)
180 {
181 const void *ptr = elf_section_start(elf, elf->sym_tab);
182 const elf_sym *sym;
184 sym = ptr + index * elf_size(elf, sym);
185 return sym;
186 }
188 const char *elf_note_name(struct elf_binary *elf, const elf_note * note)
189 {
190 return (void *)note + elf_size(elf, note);
191 }
193 const void *elf_note_desc(struct elf_binary *elf, const elf_note * note)
194 {
195 int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
197 return (void *)note + elf_size(elf, note) + namesz;
198 }
200 uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note)
201 {
202 const void *desc = elf_note_desc(elf, note);
203 int descsz = elf_uval(elf, note, descsz);
205 switch (descsz)
206 {
207 case 1:
208 case 2:
209 case 4:
210 case 8:
211 return elf_access_unsigned(elf, desc, 0, descsz);
212 default:
213 return 0;
214 }
215 }
216 const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note)
217 {
218 int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
219 int descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
221 return (void *)note + elf_size(elf, note) + namesz + descsz;
222 }
224 /* ------------------------------------------------------------------------ */
226 int elf_is_elfbinary(const void *image)
227 {
228 const Elf32_Ehdr *ehdr = image;
230 return IS_ELF(*ehdr);
231 }
233 int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr)
234 {
235 uint64_t p_type = elf_uval(elf, phdr, p_type);
236 uint64_t p_flags = elf_uval(elf, phdr, p_flags);
238 return ((p_type == PT_LOAD) && (p_flags & (PF_W | PF_X)) != 0);
239 }
241 /*
242 * Local variables:
243 * mode: C
244 * c-set-style: "BSD"
245 * c-basic-offset: 4
246 * tab-width: 4
247 * indent-tabs-mode: nil
248 * End:
249 */