1183375Skmacy/******************************************************************************
2183375Skmacy * libelf.h
3183375Skmacy *
4183375Skmacy * Permission is hereby granted, free of charge, to any person obtaining a copy
5183375Skmacy * of this software and associated documentation files (the "Software"), to
6183375Skmacy * deal in the Software without restriction, including without limitation the
7183375Skmacy * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8183375Skmacy * sell copies of the Software, and to permit persons to whom the Software is
9183375Skmacy * furnished to do so, subject to the following conditions:
10183375Skmacy *
11183375Skmacy * The above copyright notice and this permission notice shall be included in
12183375Skmacy * all copies or substantial portions of the Software.
13183375Skmacy *
14183375Skmacy * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15183375Skmacy * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16183375Skmacy * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17183375Skmacy * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18183375Skmacy * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19183375Skmacy * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20183375Skmacy * DEALINGS IN THE SOFTWARE.
21183375Skmacy */
22183375Skmacy
23181624Skmacy#ifndef __XC_LIBELF__
24181624Skmacy#define __XC_LIBELF__ 1
25181624Skmacy
26183375Skmacy#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__)
27181624Skmacy#define XEN_ELF_LITTLE_ENDIAN
28181624Skmacy#else
29181624Skmacy#error define architectural endianness
30181624Skmacy#endif
31181624Skmacy
32181624Skmacy#undef ELFSIZE
33181624Skmacy#include "elfnote.h"
34181624Skmacy#include "elfstructs.h"
35181624Skmacy#include "features.h"
36181624Skmacy
37181624Skmacy/* ------------------------------------------------------------------------ */
38181624Skmacy
39181624Skmacytypedef union {
40181624Skmacy    Elf32_Ehdr e32;
41181624Skmacy    Elf64_Ehdr e64;
42181624Skmacy} elf_ehdr;
43181624Skmacy
44181624Skmacytypedef union {
45181624Skmacy    Elf32_Phdr e32;
46181624Skmacy    Elf64_Phdr e64;
47181624Skmacy} elf_phdr;
48181624Skmacy
49181624Skmacytypedef union {
50181624Skmacy    Elf32_Shdr e32;
51181624Skmacy    Elf64_Shdr e64;
52181624Skmacy} elf_shdr;
53181624Skmacy
54181624Skmacytypedef union {
55181624Skmacy    Elf32_Sym e32;
56181624Skmacy    Elf64_Sym e64;
57181624Skmacy} elf_sym;
58181624Skmacy
59181624Skmacytypedef union {
60181624Skmacy    Elf32_Rel e32;
61181624Skmacy    Elf64_Rel e64;
62181624Skmacy} elf_rel;
63181624Skmacy
64181624Skmacytypedef union {
65181624Skmacy    Elf32_Rela e32;
66181624Skmacy    Elf64_Rela e64;
67181624Skmacy} elf_rela;
68181624Skmacy
69181624Skmacytypedef union {
70181624Skmacy    Elf32_Note e32;
71181624Skmacy    Elf64_Note e64;
72181624Skmacy} elf_note;
73181624Skmacy
74181624Skmacystruct elf_binary {
75181624Skmacy    /* elf binary */
76181624Skmacy    const char *image;
77181624Skmacy    size_t size;
78181624Skmacy    char class;
79181624Skmacy    char data;
80181624Skmacy
81181624Skmacy    const elf_ehdr *ehdr;
82181624Skmacy    const char *sec_strtab;
83181624Skmacy    const elf_shdr *sym_tab;
84181624Skmacy    const char *sym_strtab;
85181624Skmacy
86181624Skmacy    /* loaded to */
87181624Skmacy    char *dest;
88181624Skmacy    uint64_t pstart;
89181624Skmacy    uint64_t pend;
90181624Skmacy    uint64_t reloc_offset;
91181624Skmacy
92183375Skmacy    uint64_t bsd_symtab_pstart;
93183375Skmacy    uint64_t bsd_symtab_pend;
94183375Skmacy
95181624Skmacy#ifndef __XEN__
96181624Skmacy    /* misc */
97181624Skmacy    FILE *log;
98181624Skmacy#endif
99181624Skmacy    int verbose;
100181624Skmacy};
101181624Skmacy
102181624Skmacy/* ------------------------------------------------------------------------ */
103181624Skmacy/* accessing elf header fields                                              */
104181624Skmacy
105181624Skmacy#ifdef XEN_ELF_BIG_ENDIAN
106181624Skmacy# define NATIVE_ELFDATA ELFDATA2MSB
107181624Skmacy#else
108181624Skmacy# define NATIVE_ELFDATA ELFDATA2LSB
109181624Skmacy#endif
110181624Skmacy
111181624Skmacy#define elf_32bit(elf) (ELFCLASS32 == (elf)->class)
112181624Skmacy#define elf_64bit(elf) (ELFCLASS64 == (elf)->class)
113181624Skmacy#define elf_msb(elf)   (ELFDATA2MSB == (elf)->data)
114181624Skmacy#define elf_lsb(elf)   (ELFDATA2LSB == (elf)->data)
115181624Skmacy#define elf_swap(elf)  (NATIVE_ELFDATA != (elf)->data)
116181624Skmacy
117183375Skmacy#define elf_uval(elf, str, elem)                                        \
118183375Skmacy    ((ELFCLASS64 == (elf)->class)                                       \
119183375Skmacy     ? elf_access_unsigned((elf), (str),                                \
120183375Skmacy                           offsetof(typeof(*(str)),e64.elem),           \
121183375Skmacy                           sizeof((str)->e64.elem))                     \
122183375Skmacy     : elf_access_unsigned((elf), (str),                                \
123183375Skmacy                           offsetof(typeof(*(str)),e32.elem),           \
124183375Skmacy                           sizeof((str)->e32.elem)))
125181624Skmacy
126183375Skmacy#define elf_sval(elf, str, elem)                                        \
127183375Skmacy    ((ELFCLASS64 == (elf)->class)                                       \
128183375Skmacy     ? elf_access_signed((elf), (str),                                  \
129183375Skmacy                         offsetof(typeof(*(str)),e64.elem),             \
130183375Skmacy                         sizeof((str)->e64.elem))                       \
131183375Skmacy     : elf_access_signed((elf), (str),                                  \
132183375Skmacy                         offsetof(typeof(*(str)),e32.elem),             \
133183375Skmacy                         sizeof((str)->e32.elem)))
134181624Skmacy
135183375Skmacy#define elf_size(elf, str)                              \
136183375Skmacy    ((ELFCLASS64 == (elf)->class)                       \
137183375Skmacy     ? sizeof((str)->e64) : sizeof((str)->e32))
138181624Skmacy
139181624Skmacyuint64_t elf_access_unsigned(struct elf_binary *elf, const void *ptr,
140183375Skmacy                             uint64_t offset, size_t size);
141181624Skmacyint64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
142183375Skmacy                          uint64_t offset, size_t size);
143181624Skmacy
144181624Skmacyuint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
145181624Skmacy
146181624Skmacy/* ------------------------------------------------------------------------ */
147181624Skmacy/* xc_libelf_tools.c                                                        */
148181624Skmacy
149181624Skmacyint elf_shdr_count(struct elf_binary *elf);
150181624Skmacyint elf_phdr_count(struct elf_binary *elf);
151181624Skmacy
152181624Skmacyconst elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name);
153181624Skmacyconst elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index);
154181624Skmacyconst elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index);
155181624Skmacy
156181624Skmacyconst char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr);
157181624Skmacyconst void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr);
158181624Skmacyconst void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr);
159181624Skmacy
160181624Skmacyconst void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr);
161181624Skmacyconst void *elf_segment_end(struct elf_binary *elf, const elf_phdr * phdr);
162181624Skmacy
163181624Skmacyconst elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol);
164181624Skmacyconst elf_sym *elf_sym_by_index(struct elf_binary *elf, int index);
165181624Skmacy
166181624Skmacyconst char *elf_note_name(struct elf_binary *elf, const elf_note * note);
167181624Skmacyconst void *elf_note_desc(struct elf_binary *elf, const elf_note * note);
168181624Skmacyuint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note);
169181624Skmacyconst elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note);
170181624Skmacy
171181624Skmacyint elf_is_elfbinary(const void *image);
172181624Skmacyint elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr);
173181624Skmacy
174181624Skmacy/* ------------------------------------------------------------------------ */
175181624Skmacy/* xc_libelf_loader.c                                                       */
176181624Skmacy
177181624Skmacyint elf_init(struct elf_binary *elf, const char *image, size_t size);
178181624Skmacy#ifdef __XEN__
179181624Skmacyvoid elf_set_verbose(struct elf_binary *elf);
180181624Skmacy#else
181181624Skmacyvoid elf_set_logfile(struct elf_binary *elf, FILE * log, int verbose);
182181624Skmacy#endif
183181624Skmacy
184181624Skmacyvoid elf_parse_binary(struct elf_binary *elf);
185181624Skmacyvoid elf_load_binary(struct elf_binary *elf);
186181624Skmacy
187181624Skmacyvoid *elf_get_ptr(struct elf_binary *elf, unsigned long addr);
188181624Skmacyuint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
189181624Skmacy
190183375Skmacyvoid elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart); /* private */
191183375Skmacy
192181624Skmacy/* ------------------------------------------------------------------------ */
193181624Skmacy/* xc_libelf_relocate.c                                                     */
194181624Skmacy
195181624Skmacyint elf_reloc(struct elf_binary *elf);
196181624Skmacy
197181624Skmacy/* ------------------------------------------------------------------------ */
198181624Skmacy/* xc_libelf_dominfo.c                                                      */
199181624Skmacy
200181624Skmacy#define UNSET_ADDR          ((uint64_t)-1)
201181624Skmacy
202181624Skmacyenum xen_elfnote_type {
203181624Skmacy    XEN_ENT_NONE = 0,
204181624Skmacy    XEN_ENT_LONG = 1,
205181624Skmacy    XEN_ENT_STR  = 2
206181624Skmacy};
207181624Skmacy
208181624Skmacystruct xen_elfnote {
209181624Skmacy    enum xen_elfnote_type type;
210181624Skmacy    const char *name;
211181624Skmacy    union {
212183375Skmacy        const char *str;
213183375Skmacy        uint64_t num;
214181624Skmacy    } data;
215181624Skmacy};
216181624Skmacy
217181624Skmacystruct elf_dom_parms {
218181624Skmacy    /* raw */
219181624Skmacy    const char *guest_info;
220181624Skmacy    const void *elf_note_start;
221181624Skmacy    const void *elf_note_end;
222181624Skmacy    struct xen_elfnote elf_notes[XEN_ELFNOTE_MAX + 1];
223181624Skmacy
224181624Skmacy    /* parsed */
225181624Skmacy    char guest_os[16];
226181624Skmacy    char guest_ver[16];
227181624Skmacy    char xen_ver[16];
228181624Skmacy    char loader[16];
229181624Skmacy    int pae;
230181624Skmacy    int bsd_symtab;
231181624Skmacy    uint64_t virt_base;
232181624Skmacy    uint64_t virt_entry;
233181624Skmacy    uint64_t virt_hypercall;
234181624Skmacy    uint64_t virt_hv_start_low;
235181624Skmacy    uint64_t elf_paddr_offset;
236181624Skmacy    uint32_t f_supported[XENFEAT_NR_SUBMAPS];
237181624Skmacy    uint32_t f_required[XENFEAT_NR_SUBMAPS];
238181624Skmacy
239181624Skmacy    /* calculated */
240181624Skmacy    uint64_t virt_offset;
241181624Skmacy    uint64_t virt_kstart;
242181624Skmacy    uint64_t virt_kend;
243181624Skmacy};
244181624Skmacy
245181624Skmacystatic inline void elf_xen_feature_set(int nr, uint32_t * addr)
246181624Skmacy{
247181624Skmacy    addr[nr >> 5] |= 1 << (nr & 31);
248181624Skmacy}
249181624Skmacystatic inline int elf_xen_feature_get(int nr, uint32_t * addr)
250181624Skmacy{
251181624Skmacy    return !!(addr[nr >> 5] & (1 << (nr & 31)));
252181624Skmacy}
253181624Skmacy
254181624Skmacyint elf_xen_parse_features(const char *features,
255183375Skmacy                           uint32_t *supported,
256183375Skmacy                           uint32_t *required);
257181624Skmacyint elf_xen_parse_note(struct elf_binary *elf,
258183375Skmacy                       struct elf_dom_parms *parms,
259183375Skmacy                       const elf_note *note);
260181624Skmacyint elf_xen_parse_guest_info(struct elf_binary *elf,
261183375Skmacy                             struct elf_dom_parms *parms);
262181624Skmacyint elf_xen_parse(struct elf_binary *elf,
263183375Skmacy                  struct elf_dom_parms *parms);
264181624Skmacy
265181624Skmacy#endif /* __XC_LIBELF__ */
266