ia64/xen-unstable

view xen/common/libelf/libelf-loader.c @ 13952:1b74475ad511

[LIBELF] Print phdr addresses when loading.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Hollis Blanchard <hollisb@us.ibm.com>
date Fri Feb 09 14:43:21 2007 -0600 (2007-02-09)
parents db3d03dfe92f
children 9af0c7e4ff51
line source
1 /*
2 * parse and load elf binaries
3 */
5 #include "libelf-private.h"
7 /* ------------------------------------------------------------------------ */
9 int elf_init(struct elf_binary *elf, const char *image, size_t size)
10 {
11 const elf_shdr *shdr;
12 uint64_t i, count, section, offset;
14 if (!elf_is_elfbinary(image))
15 {
16 elf_err(elf, "%s: not an ELF binary\n", __FUNCTION__);
17 return -1;
18 }
20 memset(elf, 0, sizeof(*elf));
21 elf->image = image;
22 elf->size = size;
23 elf->ehdr = (elf_ehdr *) image;
24 elf->class = elf->ehdr->e32.e_ident[EI_CLASS];
25 elf->data = elf->ehdr->e32.e_ident[EI_DATA];
27 /* sanity check phdr */
28 offset = elf_uval(elf, elf->ehdr, e_phoff) +
29 elf_uval(elf, elf->ehdr, e_phentsize) * elf_phdr_count(elf);
30 if (offset > elf->size)
31 {
32 elf_err(elf, "%s: phdr overflow (off %" PRIx64 " > size %lx)\n",
33 __FUNCTION__, offset, (unsigned long)elf->size);
34 return -1;
35 }
37 /* sanity check shdr */
38 offset = elf_uval(elf, elf->ehdr, e_shoff) +
39 elf_uval(elf, elf->ehdr, e_shentsize) * elf_shdr_count(elf);
40 if (offset > elf->size)
41 {
42 elf_err(elf, "%s: shdr overflow (off %" PRIx64 " > size %lx)\n",
43 __FUNCTION__, offset, (unsigned long)elf->size);
44 return -1;
45 }
47 /* find section string table */
48 section = elf_uval(elf, elf->ehdr, e_shstrndx);
49 shdr = elf_shdr_by_index(elf, section);
50 if (NULL != shdr)
51 elf->sec_strtab = elf_section_start(elf, shdr);
53 /* find symbol table, symbol string table */
54 count = elf_shdr_count(elf);
55 for (i = 0; i < count; i++)
56 {
57 shdr = elf_shdr_by_index(elf, i);
58 if (elf_uval(elf, shdr, sh_type) != SHT_SYMTAB)
59 continue;
60 elf->sym_tab = shdr;
61 shdr = elf_shdr_by_index(elf, elf_uval(elf, shdr, sh_link));
62 if (NULL == shdr)
63 {
64 elf->sym_tab = NULL;
65 continue;
66 }
67 elf->sym_strtab = elf_section_start(elf, shdr);
68 break;
69 }
70 return 0;
71 }
73 #ifndef __XEN__
74 void elf_set_logfile(struct elf_binary *elf, FILE * log, int verbose)
75 {
76 elf->log = log;
77 elf->verbose = verbose;
78 }
79 #else
80 void elf_set_verbose(struct elf_binary *elf)
81 {
82 elf->verbose = 1;
83 }
84 #endif
86 void elf_parse_binary(struct elf_binary *elf)
87 {
88 const elf_phdr *phdr;
89 uint64_t low = -1;
90 uint64_t high = 0;
91 uint64_t i, count, paddr, memsz;
93 count = elf_uval(elf, elf->ehdr, e_phnum);
94 for (i = 0; i < count; i++)
95 {
96 phdr = elf_phdr_by_index(elf, i);
97 if (!elf_phdr_is_loadable(elf, phdr))
98 continue;
99 paddr = elf_uval(elf, phdr, p_paddr);
100 memsz = elf_uval(elf, phdr, p_memsz);
101 elf_msg(elf, "%s: phdr: paddr=0x%" PRIx64
102 " memsz=0x%" PRIx64 "\n", __FUNCTION__, paddr, memsz);
103 if (low > paddr)
104 low = paddr;
105 if (high < paddr + memsz)
106 high = paddr + memsz;
107 }
108 elf->pstart = low;
109 elf->pend = high;
110 elf_msg(elf, "%s: memory: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
111 __FUNCTION__, elf->pstart, elf->pend);
112 }
114 void elf_load_binary(struct elf_binary *elf)
115 {
116 const elf_phdr *phdr;
117 uint64_t i, count, paddr, offset, filesz, memsz;
118 char *dest;
120 count = elf_uval(elf, elf->ehdr, e_phnum);
121 for (i = 0; i < count; i++)
122 {
123 phdr = elf_phdr_by_index(elf, i);
124 if (!elf_phdr_is_loadable(elf, phdr))
125 continue;
126 paddr = elf_uval(elf, phdr, p_paddr);
127 offset = elf_uval(elf, phdr, p_offset);
128 filesz = elf_uval(elf, phdr, p_filesz);
129 memsz = elf_uval(elf, phdr, p_memsz);
130 dest = elf_get_ptr(elf, paddr);
131 elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%p -> 0x%p\n",
132 __func__, i, dest, dest + filesz);
133 memcpy(dest, elf->image + offset, filesz);
134 memset(dest + filesz, 0, memsz - filesz);
135 }
136 }
138 void *elf_get_ptr(struct elf_binary *elf, unsigned long addr)
139 {
140 return elf->dest + addr - elf->pstart;
141 }
143 uint64_t elf_lookup_addr(struct elf_binary * elf, const char *symbol)
144 {
145 const elf_sym *sym;
146 uint64_t value;
148 sym = elf_sym_by_name(elf, symbol);
149 if (NULL == sym)
150 {
151 elf_err(elf, "%s: not found: %s\n", __FUNCTION__, symbol);
152 return -1;
153 }
154 value = elf_uval(elf, sym, st_value);
155 elf_msg(elf, "%s: symbol \"%s\" at 0x%" PRIx64 "\n", __FUNCTION__,
156 symbol, value);
157 return value;
158 }