source: trunk/packages/xen-3.1/xen-3.1/xen/common/libelf/libelf-tools.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 6.0 KB
Line 
1/*
2 * various helper functions to access elf structures
3 */
4
5#include "libelf-private.h"
6
7/* ------------------------------------------------------------------------ */
8
9uint64_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;
17
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}
36
37int64_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;
45
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}
64
65uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
66{
67    int elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
68
69    return (addr + elf_round) & ~elf_round;
70}
71
72/* ------------------------------------------------------------------------ */
73
74int elf_shdr_count(struct elf_binary *elf)
75{
76    return elf_uval(elf, elf->ehdr, e_shnum);
77}
78
79int elf_phdr_count(struct elf_binary *elf)
80{
81    return elf_uval(elf, elf->ehdr, e_phnum);
82}
83
84const 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;
90
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}
100
101const 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;
105
106    if ( index >= count )
107        return NULL;
108
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}
114
115const 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;
119
120    if ( index >= count )
121        return NULL;
122
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}
128
129const 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}
135
136const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr)
137{
138    return elf->image + elf_uval(elf, shdr, sh_offset);
139}
140
141const 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}
146
147const void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr)
148{
149    return elf->image + elf_uval(elf, phdr, p_offset);
150}
151
152const 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}
157
158const 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;
164
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}
178
179const 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;
183
184    sym = ptr + index * elf_size(elf, sym);
185    return sym;
186}
187
188const char *elf_note_name(struct elf_binary *elf, const elf_note * note)
189{
190    return (void *)note + elf_size(elf, note);
191}
192
193const void *elf_note_desc(struct elf_binary *elf, const elf_note * note)
194{
195    int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
196
197    return (void *)note + elf_size(elf, note) + namesz;
198}
199
200uint64_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);
204
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}
216const 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;
220
221    return (void *)note + elf_size(elf, note) + namesz + descsz;
222}
223
224/* ------------------------------------------------------------------------ */
225
226int elf_is_elfbinary(const void *image)
227{
228    const Elf32_Ehdr *ehdr = image;
229
230    return IS_ELF(*ehdr);
231}
232
233int 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);
237
238    return ((p_type == PT_LOAD) && (p_flags & (PF_W | PF_X)) != 0);
239}
240
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 */
Note: See TracBrowser for help on using the repository browser.