1/******************************************************************************
2 * libelf.h
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __XC_LIBELF__
24#define __XC_LIBELF__ 1
25
26#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__)
27#define XEN_ELF_LITTLE_ENDIAN
28#else
29#error define architectural endianness
30#endif
31
32#undef ELFSIZE
33#include "elfnote.h"
34#include "elfstructs.h"
35#include "features.h"
36
37/* ------------------------------------------------------------------------ */
38
39typedef union {
40    Elf32_Ehdr e32;
41    Elf64_Ehdr e64;
42} elf_ehdr;
43
44typedef union {
45    Elf32_Phdr e32;
46    Elf64_Phdr e64;
47} elf_phdr;
48
49typedef union {
50    Elf32_Shdr e32;
51    Elf64_Shdr e64;
52} elf_shdr;
53
54typedef union {
55    Elf32_Sym e32;
56    Elf64_Sym e64;
57} elf_sym;
58
59typedef union {
60    Elf32_Rel e32;
61    Elf64_Rel e64;
62} elf_rel;
63
64typedef union {
65    Elf32_Rela e32;
66    Elf64_Rela e64;
67} elf_rela;
68
69typedef union {
70    Elf32_Note e32;
71    Elf64_Note e64;
72} elf_note;
73
74struct elf_binary {
75    /* elf binary */
76    const char *image;
77    size_t size;
78    char class;
79    char data;
80
81    const elf_ehdr *ehdr;
82    const char *sec_strtab;
83    const elf_shdr *sym_tab;
84    const char *sym_strtab;
85
86    /* loaded to */
87    char *dest;
88    uint64_t pstart;
89    uint64_t pend;
90    uint64_t reloc_offset;
91
92    uint64_t bsd_symtab_pstart;
93    uint64_t bsd_symtab_pend;
94
95#ifndef __XEN__
96    /* misc */
97    FILE *log;
98#endif
99    int verbose;
100};
101
102/* ------------------------------------------------------------------------ */
103/* accessing elf header fields                                              */
104
105#ifdef XEN_ELF_BIG_ENDIAN
106# define NATIVE_ELFDATA ELFDATA2MSB
107#else
108# define NATIVE_ELFDATA ELFDATA2LSB
109#endif
110
111#define elf_32bit(elf) (ELFCLASS32 == (elf)->class)
112#define elf_64bit(elf) (ELFCLASS64 == (elf)->class)
113#define elf_msb(elf)   (ELFDATA2MSB == (elf)->data)
114#define elf_lsb(elf)   (ELFDATA2LSB == (elf)->data)
115#define elf_swap(elf)  (NATIVE_ELFDATA != (elf)->data)
116
117#define elf_uval(elf, str, elem)                                        \
118    ((ELFCLASS64 == (elf)->class)                                       \
119     ? elf_access_unsigned((elf), (str),                                \
120                           offsetof(typeof(*(str)),e64.elem),           \
121                           sizeof((str)->e64.elem))                     \
122     : elf_access_unsigned((elf), (str),                                \
123                           offsetof(typeof(*(str)),e32.elem),           \
124                           sizeof((str)->e32.elem)))
125
126#define elf_sval(elf, str, elem)                                        \
127    ((ELFCLASS64 == (elf)->class)                                       \
128     ? elf_access_signed((elf), (str),                                  \
129                         offsetof(typeof(*(str)),e64.elem),             \
130                         sizeof((str)->e64.elem))                       \
131     : elf_access_signed((elf), (str),                                  \
132                         offsetof(typeof(*(str)),e32.elem),             \
133                         sizeof((str)->e32.elem)))
134
135#define elf_size(elf, str)                              \
136    ((ELFCLASS64 == (elf)->class)                       \
137     ? sizeof((str)->e64) : sizeof((str)->e32))
138
139uint64_t elf_access_unsigned(struct elf_binary *elf, const void *ptr,
140                             uint64_t offset, size_t size);
141int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
142                          uint64_t offset, size_t size);
143
144uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
145
146/* ------------------------------------------------------------------------ */
147/* xc_libelf_tools.c                                                        */
148
149int elf_shdr_count(struct elf_binary *elf);
150int elf_phdr_count(struct elf_binary *elf);
151
152const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name);
153const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index);
154const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index);
155
156const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr);
157const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr);
158const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr);
159
160const void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr);
161const void *elf_segment_end(struct elf_binary *elf, const elf_phdr * phdr);
162
163const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol);
164const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index);
165
166const char *elf_note_name(struct elf_binary *elf, const elf_note * note);
167const void *elf_note_desc(struct elf_binary *elf, const elf_note * note);
168uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note);
169const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note);
170
171int elf_is_elfbinary(const void *image);
172int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr);
173
174/* ------------------------------------------------------------------------ */
175/* xc_libelf_loader.c                                                       */
176
177int elf_init(struct elf_binary *elf, const char *image, size_t size);
178#ifdef __XEN__
179void elf_set_verbose(struct elf_binary *elf);
180#else
181void elf_set_logfile(struct elf_binary *elf, FILE * log, int verbose);
182#endif
183
184void elf_parse_binary(struct elf_binary *elf);
185void elf_load_binary(struct elf_binary *elf);
186
187void *elf_get_ptr(struct elf_binary *elf, unsigned long addr);
188uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
189
190void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart); /* private */
191
192/* ------------------------------------------------------------------------ */
193/* xc_libelf_relocate.c                                                     */
194
195int elf_reloc(struct elf_binary *elf);
196
197/* ------------------------------------------------------------------------ */
198/* xc_libelf_dominfo.c                                                      */
199
200#define UNSET_ADDR          ((uint64_t)-1)
201
202enum xen_elfnote_type {
203    XEN_ENT_NONE = 0,
204    XEN_ENT_LONG = 1,
205    XEN_ENT_STR  = 2
206};
207
208struct xen_elfnote {
209    enum xen_elfnote_type type;
210    const char *name;
211    union {
212        const char *str;
213        uint64_t num;
214    } data;
215};
216
217struct elf_dom_parms {
218    /* raw */
219    const char *guest_info;
220    const void *elf_note_start;
221    const void *elf_note_end;
222    struct xen_elfnote elf_notes[XEN_ELFNOTE_MAX + 1];
223
224    /* parsed */
225    char guest_os[16];
226    char guest_ver[16];
227    char xen_ver[16];
228    char loader[16];
229    int pae;
230    int bsd_symtab;
231    uint64_t virt_base;
232    uint64_t virt_entry;
233    uint64_t virt_hypercall;
234    uint64_t virt_hv_start_low;
235    uint64_t elf_paddr_offset;
236    uint32_t f_supported[XENFEAT_NR_SUBMAPS];
237    uint32_t f_required[XENFEAT_NR_SUBMAPS];
238
239    /* calculated */
240    uint64_t virt_offset;
241    uint64_t virt_kstart;
242    uint64_t virt_kend;
243};
244
245static inline void elf_xen_feature_set(int nr, uint32_t * addr)
246{
247    addr[nr >> 5] |= 1 << (nr & 31);
248}
249static inline int elf_xen_feature_get(int nr, uint32_t * addr)
250{
251    return !!(addr[nr >> 5] & (1 << (nr & 31)));
252}
253
254int elf_xen_parse_features(const char *features,
255                           uint32_t *supported,
256                           uint32_t *required);
257int elf_xen_parse_note(struct elf_binary *elf,
258                       struct elf_dom_parms *parms,
259                       const elf_note *note);
260int elf_xen_parse_guest_info(struct elf_binary *elf,
261                             struct elf_dom_parms *parms);
262int elf_xen_parse(struct elf_binary *elf,
263                  struct elf_dom_parms *parms);
264
265#endif /* __XC_LIBELF__ */
266