debuggers.hg

view xen/arch/x86/boot/mkelf32.c @ 3619:ec53c623cf23

bitkeeper revision 1.1159.212.51 (41fa5cccoJa4CtdiYB99zon6qwiusw)

Merge firebug.cl.cam.ac.uk:/auto/anfs/scratch/scramble/kaf24/xen-2.0-testing.bk
into firebug.cl.cam.ac.uk:/auto/anfs/scratch/scramble/kaf24/xen-unstable.bk
author kaf24@firebug.cl.cam.ac.uk
date Fri Jan 28 15:39:56 2005 +0000 (2005-01-28)
parents cda0735bdc4c 3857ec2f2189
children bbe8541361dd 177865f3143e
line source
1 /******************************************************************************
2 * mkelf32.c
3 *
4 * Usage: elf-prefix <in-image> <out-image> <load-base>
5 *
6 * Converts an Elf32 or Elf64 executable binary <in-image> into a simple Elf32
7 * image <out-image> comprising a single chunk to be loaded at <load-base>.
8 */
10 #include <errno.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <unistd.h>
19 /*
20 * Here I'm taking care not to conflict with possible typedef's in
21 * standard headers by instead using the macro namespace.
22 */
23 #undef u8
24 #undef u16
25 #undef u32
26 #undef u64
27 #undef s8
28 #undef s16
29 #undef s32
30 #undef s64
31 #define u8 unsigned char
32 #define u16 unsigned short
33 #define u32 unsigned int
34 #define s8 signed char
35 #define s16 signed short
36 #define s32 signed int
37 #if defined(__i386__)
38 #define u64 unsigned long long
39 #define s64 signed long long
40 #else
41 #define u64 unsigned long
42 #define s64 signed long
43 #endif
45 #include "../../../include/xen/elf.h"
47 #define DYNAMICALLY_FILLED 0
48 #define RAW_OFFSET 128
50 static Elf32_Ehdr out_ehdr = {
51 { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, /* EI_MAG{0-3} */
52 ELFCLASS32, /* EI_CLASS */
53 ELFDATA2LSB, /* EI_DATA */
54 EV_CURRENT, /* EI_VERSION */
55 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* e_ident */
56 ET_EXEC, /* e_type */
57 EM_386, /* e_machine */
58 EV_CURRENT, /* e_version */
59 DYNAMICALLY_FILLED, /* e_entry */
60 sizeof(Elf32_Ehdr), /* e_phoff */
61 DYNAMICALLY_FILLED, /* e_shoff */
62 0, /* e_flags */
63 sizeof(Elf32_Ehdr), /* e_ehsize */
64 sizeof(Elf32_Phdr), /* e_phentsize */
65 1, /* e_phnum */
66 sizeof(Elf32_Shdr), /* e_shentsize */
67 3, /* e_shnum */
68 2 /* e_shstrndx */
69 };
71 static Elf32_Phdr out_phdr = {
72 PT_LOAD, /* p_type */
73 RAW_OFFSET, /* p_offset */
74 DYNAMICALLY_FILLED, /* p_vaddr */
75 DYNAMICALLY_FILLED, /* p_paddr */
76 DYNAMICALLY_FILLED, /* p_filesz */
77 DYNAMICALLY_FILLED, /* p_memsz */
78 PF_R|PF_W|PF_X, /* p_flags */
79 64 /* p_align */
80 };
82 static u8 out_shstrtab[] = "\0.text\0.shstrtab";
84 static Elf32_Shdr out_shdr[] = {
85 { 0 },
86 { 1, /* sh_name */
87 SHT_PROGBITS, /* sh_type */
88 SHF_WRITE|SHF_ALLOC|SHF_EXECINSTR, /* sh_flags */
89 DYNAMICALLY_FILLED, /* sh_addr */
90 RAW_OFFSET, /* sh_offset */
91 DYNAMICALLY_FILLED, /* sh_size */
92 0, /* sh_link */
93 0, /* sh_info */
94 64, /* sh_addralign */
95 0 /* sh_entsize */
96 },
97 { 7, /* sh_name */
98 SHT_STRTAB, /* sh_type */
99 0, /* sh_flags */
100 0, /* sh_addr */
101 DYNAMICALLY_FILLED, /* sh_offset */
102 sizeof(out_shstrtab), /* sh_size */
103 0, /* sh_link */
104 0, /* sh_info */
105 1, /* sh_addralign */
106 0 /* sh_entsize */
107 }
108 };
110 static void do_write(int fd, void *data, int len)
111 {
112 int done, left = len;
113 char *p = data;
115 while ( left != 0 )
116 {
117 if ( (done = write(fd, p, left)) == -1 )
118 {
119 if ( errno == EINTR )
120 continue;
121 fprintf(stderr, "Error writing output image: %d (%s).\n",
122 errno, strerror(errno));
123 exit(1);
124 }
126 left -= done;
127 p += done;
128 }
129 }
131 static void do_read(int fd, void *data, int len)
132 {
133 int done, left = len;
134 char *p = data;
136 while ( left != 0 )
137 {
138 if ( (done = read(fd, p, left)) == -1 )
139 {
140 if ( errno == EINTR )
141 continue;
142 fprintf(stderr, "Error reading input image: %d (%s).\n",
143 errno, strerror(errno));
144 exit(1);
145 }
147 left -= done;
148 p += done;
149 }
150 }
152 int main(int argc, char **argv)
153 {
154 u32 loadbase, dat_siz, mem_siz;
155 char *inimage, *outimage;
156 int infd, outfd;
157 char buffer[1024];
158 int bytes, todo;
160 Elf32_Ehdr in32_ehdr;
161 Elf32_Phdr in32_phdr;
163 Elf64_Ehdr in64_ehdr;
164 Elf64_Phdr in64_phdr;
166 if ( argc != 4 )
167 {
168 fprintf(stderr, "Usage: mkelf32 <in-image> <out-image> <load-base>\n");
169 return 1;
170 }
172 inimage = argv[1];
173 outimage = argv[2];
174 loadbase = strtoul(argv[3], NULL, 16);
176 infd = open(inimage, O_RDONLY);
177 if ( infd == -1 )
178 {
179 fprintf(stderr, "Failed to open input image '%s': %d (%s).\n",
180 inimage, errno, strerror(errno));
181 return 1;
182 }
184 do_read(infd, &in32_ehdr, sizeof(in32_ehdr));
185 if ( !IS_ELF(in32_ehdr) ||
186 (in32_ehdr.e_ident[EI_DATA] != ELFDATA2LSB) )
187 {
188 fprintf(stderr, "Input image must be a little-endian Elf image.\n");
189 return 1;
190 }
192 switch ( in32_ehdr.e_ident[EI_CLASS] )
193 {
194 case ELFCLASS32:
195 if ( in32_ehdr.e_phentsize != sizeof(in32_phdr) )
196 {
197 fprintf(stderr, "Bad program header size (%d != %d).\n",
198 (int)in32_ehdr.e_phentsize, (int)sizeof(in32_phdr));
199 return 1;
200 }
202 if ( in32_ehdr.e_phnum != 1 )
203 {
204 fprintf(stderr, "Expect precisely 1 program header; found %d.\n",
205 (int)in32_ehdr.e_phnum);
206 return 1;
207 }
209 (void)lseek(infd, in32_ehdr.e_phoff, SEEK_SET);
210 do_read(infd, &in32_phdr, sizeof(in32_phdr));
212 (void)lseek(infd, in32_phdr.p_offset, SEEK_SET);
213 dat_siz = (u32)in32_phdr.p_filesz;
214 mem_siz = (u32)in32_phdr.p_memsz;
215 break;
217 case ELFCLASS64:
218 (void)lseek(infd, 0, SEEK_SET);
219 do_read(infd, &in64_ehdr, sizeof(in64_ehdr));
221 if ( in64_ehdr.e_phentsize != sizeof(in64_phdr) )
222 {
223 fprintf(stderr, "Bad program header size (%d != %d).\n",
224 (int)in64_ehdr.e_phentsize, (int)sizeof(in64_phdr));
225 return 1;
226 }
228 if ( in64_ehdr.e_phnum != 1 )
229 {
230 fprintf(stderr, "Expect precisly 1 program header; found %d.\n",
231 (int)in64_ehdr.e_phnum);
232 return 1;
233 }
235 (void)lseek(infd, in64_ehdr.e_phoff, SEEK_SET);
236 do_read(infd, &in64_phdr, sizeof(in64_phdr));
238 (void)lseek(infd, in64_phdr.p_offset, SEEK_SET);
239 dat_siz = (u32)in64_phdr.p_filesz;
240 mem_siz = (u32)in64_phdr.p_memsz;
241 break;
243 default:
244 fprintf(stderr, "Input image must be a 32- or 64-bit Elf image.\n");
245 return 1;
246 }
248 out_ehdr.e_entry = loadbase;
249 out_ehdr.e_shoff = RAW_OFFSET + dat_siz;
251 out_phdr.p_vaddr = loadbase;
252 out_phdr.p_paddr = loadbase;
253 out_phdr.p_filesz = dat_siz;
254 out_phdr.p_memsz = mem_siz;
256 out_shdr[1].sh_addr = loadbase;
257 out_shdr[1].sh_size = dat_siz;
258 out_shdr[2].sh_offset = RAW_OFFSET + dat_siz + sizeof(out_shdr);
260 outfd = open(outimage, O_WRONLY|O_CREAT|O_TRUNC, 0775);
261 if ( outfd == -1 )
262 {
263 fprintf(stderr, "Failed to open output image '%s': %d (%s).\n",
264 outimage, errno, strerror(errno));
265 return 1;
266 }
268 do_write(outfd, &out_ehdr, sizeof(out_ehdr));
269 do_write(outfd, &out_phdr, sizeof(out_phdr));
271 if ( (bytes = RAW_OFFSET - sizeof(out_ehdr) - sizeof(out_phdr)) < 0 )
272 {
273 fprintf(stderr, "Header overflow.\n");
274 return 1;
275 }
276 do_write(outfd, buffer, bytes);
278 for ( bytes = 0; bytes < dat_siz; bytes += todo )
279 {
280 todo = ((dat_siz - bytes) > sizeof(buffer)) ?
281 sizeof(buffer) : (dat_siz - bytes);
282 do_read(infd, buffer, todo);
283 do_write(outfd, buffer, todo);
284 }
286 do_write(outfd, &out_shdr[0], sizeof(out_shdr));
287 do_write(outfd, out_shstrtab, sizeof(out_shstrtab));
288 do_write(outfd, buffer, 4-((sizeof(out_shstrtab)+dat_siz)&3));
290 close(infd);
291 close(outfd);
293 return 0;
294 }