1 /* Test program for elf_update function.
2 Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
3 This file is part of Red Hat elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
5
6 Red Hat elfutils is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by the
8 Free Software Foundation; version 2 of the License.
9
10 Red Hat elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with Red Hat elfutils; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
18
19 Red Hat elfutils is an included package of the Open Invention Network.
20 An included package of the Open Invention Network is a package for which
21 Open Invention Network licensees cross-license their patents. No patent
22 license is granted, either expressly or impliedly, by designation as an
23 included package. Should you wish to participate in the Open Invention
24 Network licensing program, please visit www.openinventionnetwork.com
25 <http://www.openinventionnetwork.com>. */
26
27 #ifdef HAVE_CONFIG_H
28 # include <config.h>
29 #endif
30
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <libelf.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38
39 #include ELFUTILS_HEADER(ebl)
40
41
42 int
main(int argc,char * argv[])43 main (int argc, char *argv[] __attribute__ ((unused)))
44 {
45 const char fname[] = "xxx";
46 int fd;
47 Elf *elf;
48 Elf32_Ehdr *ehdr;
49 Elf32_Phdr *phdr;
50 Elf_Scn *scn;
51 Elf32_Shdr *shdr;
52 Elf_Data *data;
53 struct Ebl_Strtab *shst;
54 struct Ebl_Strent *firstse;
55 struct Ebl_Strent *secondse;
56 struct Ebl_Strent *thirdse;
57 struct Ebl_Strent *fourthse;
58 struct Ebl_Strent *shstrtabse;
59 int i;
60
61 fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
62 if (fd == -1)
63 {
64 printf ("cannot open `%s': %s\n", fname, strerror (errno));
65 exit (1);
66 }
67
68 elf_version (EV_CURRENT);
69
70 elf_fill (0x42);
71
72 elf = elf_begin (fd, ELF_C_WRITE, NULL);
73 if (elf == NULL)
74 {
75 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
76 exit (1);
77 }
78
79 /* Create an ELF header. */
80 ehdr = elf32_newehdr (elf);
81 if (ehdr == NULL)
82 {
83 printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
84 exit (1);
85 }
86
87 /* Print the ELF header values. */
88 if (argc > 1)
89 {
90 for (i = 0; i < EI_NIDENT; ++i)
91 printf (" %02x", ehdr->e_ident[i]);
92 printf ("\
93 \ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
94 "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
95 "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
96 ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
97 ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
98 ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
99 ehdr->e_shnum, ehdr->e_shstrndx);
100 }
101
102 ehdr->e_ident[0] = 42;
103 ehdr->e_ident[4] = 1;
104 ehdr->e_ident[5] = 1;
105 ehdr->e_ident[6] = 2;
106 ehdr->e_type = ET_EXEC;
107 ehdr->e_version = 1;
108 ehdr->e_ehsize = 1;
109 elf_flagehdr (elf, ELF_C_SET, ELF_F_DIRTY);
110
111 /* Create the program header. */
112 phdr = elf32_newphdr (elf, 1);
113 if (phdr == NULL)
114 {
115 printf ("cannot create program header: %s\n", elf_errmsg (-1));
116 exit (1);
117 }
118
119 phdr[0].p_type = PT_PHDR;
120 elf_flagphdr (elf, ELF_C_SET, ELF_F_DIRTY);
121
122 shst = ebl_strtabinit (true);
123
124 scn = elf_newscn (elf);
125 if (scn == NULL)
126 {
127 printf ("cannot create first section: %s\n", elf_errmsg (-1));
128 exit (1);
129 }
130 shdr = elf32_getshdr (scn);
131 if (shdr == NULL)
132 {
133 printf ("cannot get header for first section: %s\n", elf_errmsg (-1));
134 exit (1);
135 }
136
137 firstse = ebl_strtabadd (shst, ".first", 0);
138
139 shdr->sh_type = SHT_PROGBITS;
140 shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
141 shdr->sh_addr = 0;
142 shdr->sh_link = 0;
143 shdr->sh_info = 0;
144 shdr->sh_entsize = 1;
145
146 data = elf_newdata (scn);
147 if (data == NULL)
148 {
149 printf ("cannot create data first section: %s\n", elf_errmsg (-1));
150 exit (1);
151 }
152
153 data->d_buf = "hello";
154 data->d_type = ELF_T_BYTE;
155 data->d_version = EV_CURRENT;
156 data->d_size = 5;
157 data->d_align = 16;
158
159
160 scn = elf_newscn (elf);
161 if (scn == NULL)
162 {
163 printf ("cannot create second section: %s\n", elf_errmsg (-1));
164 exit (1);
165 }
166 shdr = elf32_getshdr (scn);
167 if (shdr == NULL)
168 {
169 printf ("cannot get header for second section: %s\n", elf_errmsg (-1));
170 exit (1);
171 }
172
173 secondse = ebl_strtabadd (shst, ".second", 0);
174
175 shdr->sh_type = SHT_PROGBITS;
176 shdr->sh_flags = SHF_ALLOC | SHF_WRITE;
177 shdr->sh_addr = 0;
178 shdr->sh_link = 0;
179 shdr->sh_info = 0;
180 shdr->sh_entsize = 1;
181
182 data = elf_newdata (scn);
183 if (data == NULL)
184 {
185 printf ("cannot create data second section: %s\n", elf_errmsg (-1));
186 exit (1);
187 }
188
189 data->d_buf = "world";
190 data->d_type = ELF_T_BYTE;
191 data->d_version = EV_CURRENT;
192 data->d_size = 5;
193 data->d_align = 16;
194
195
196 scn = elf_newscn (elf);
197 if (scn == NULL)
198 {
199 printf ("cannot create third section: %s\n", elf_errmsg (-1));
200 exit (1);
201 }
202 shdr = elf32_getshdr (scn);
203 if (shdr == NULL)
204 {
205 printf ("cannot get header for third section: %s\n", elf_errmsg (-1));
206 exit (1);
207 }
208
209 thirdse = ebl_strtabadd (shst, ".third", 0);
210
211 shdr->sh_type = SHT_PROGBITS;
212 shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
213 shdr->sh_addr = 0;
214 shdr->sh_link = 0;
215 shdr->sh_info = 0;
216 shdr->sh_entsize = 1;
217
218 data = elf_newdata (scn);
219 if (data == NULL)
220 {
221 printf ("cannot create data third section: %s\n", elf_errmsg (-1));
222 exit (1);
223 }
224
225 data->d_buf = "!!!!!";
226 data->d_type = ELF_T_BYTE;
227 data->d_version = EV_CURRENT;
228 data->d_size = 5;
229 data->d_align = 16;
230
231
232 scn = elf_newscn (elf);
233 if (scn == NULL)
234 {
235 printf ("cannot create fourth section: %s\n", elf_errmsg (-1));
236 exit (1);
237 }
238 shdr = elf32_getshdr (scn);
239 if (shdr == NULL)
240 {
241 printf ("cannot get header for fourth section: %s\n", elf_errmsg (-1));
242 exit (1);
243 }
244
245 fourthse = ebl_strtabadd (shst, ".fourth", 0);
246
247 shdr->sh_type = SHT_NOBITS;
248 shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
249 shdr->sh_addr = 0;
250 shdr->sh_link = 0;
251 shdr->sh_info = 0;
252 shdr->sh_entsize = 1;
253 shdr->sh_size = 100;
254
255 data = elf_newdata (scn);
256 if (data == NULL)
257 {
258 printf ("cannot create data fourth section: %s\n", elf_errmsg (-1));
259 exit (1);
260 }
261
262 data->d_buf = NULL;
263 data->d_type = ELF_T_BYTE;
264 data->d_version = EV_CURRENT;
265 data->d_size = 100;
266 data->d_align = 16;
267
268
269 scn = elf_newscn (elf);
270 if (scn == NULL)
271 {
272 printf ("cannot create SHSTRTAB section: %s\n", elf_errmsg (-1));
273 exit (1);
274 }
275 shdr = elf32_getshdr (scn);
276 if (shdr == NULL)
277 {
278 printf ("cannot get header for SHSTRTAB section: %s\n", elf_errmsg (-1));
279 exit (1);
280 }
281
282 shstrtabse = ebl_strtabadd (shst, ".shstrtab", 0);
283
284 shdr->sh_type = SHT_STRTAB;
285 shdr->sh_flags = 0;
286 shdr->sh_addr = 0;
287 shdr->sh_link = SHN_UNDEF;
288 shdr->sh_info = SHN_UNDEF;
289 shdr->sh_entsize = 1;
290
291 /* We have to store the section index in the ELF header. */
292 ehdr->e_shstrndx = elf_ndxscn (scn);
293
294 data = elf_newdata (scn);
295 if (data == NULL)
296 {
297 printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1));
298 exit (1);
299 }
300
301 /* No more sections, finalize the section header string table. */
302 ebl_strtabfinalize (shst, data);
303
304 elf32_getshdr (elf_getscn (elf, 1))->sh_name = ebl_strtaboffset (firstse);
305 elf32_getshdr (elf_getscn (elf, 2))->sh_name = ebl_strtaboffset (secondse);
306 elf32_getshdr (elf_getscn (elf, 3))->sh_name = ebl_strtaboffset (thirdse);
307 elf32_getshdr (elf_getscn (elf, 4))->sh_name = ebl_strtaboffset (fourthse);
308 shdr->sh_name = ebl_strtaboffset (shstrtabse);
309
310 /* Let the library compute the internal structure information. */
311 if (elf_update (elf, ELF_C_NULL) < 0)
312 {
313 printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
314 exit (1);
315 }
316
317 ehdr = elf32_getehdr (elf);
318
319 phdr[0].p_offset = ehdr->e_phoff;
320 phdr[0].p_offset = ehdr->e_phoff;
321 phdr[0].p_vaddr = ehdr->e_phoff;
322 phdr[0].p_paddr = ehdr->e_phoff;
323 phdr[0].p_flags = PF_R | PF_X;
324 phdr[0].p_filesz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
325 phdr[0].p_memsz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
326 phdr[0].p_align = sizeof (Elf32_Word);
327
328 /* Write out the file. */
329 if (elf_update (elf, ELF_C_WRITE) < 0)
330 {
331 printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
332 exit (1);
333 }
334
335 /* We don't need the string table anymore. */
336 ebl_strtabfree (shst);
337
338 /* And the data allocated in the .shstrtab section. */
339 free (data->d_buf);
340
341 /* Print the ELF header values. */
342 if (argc > 1)
343 {
344 for (i = 0; i < EI_NIDENT; ++i)
345 printf (" %02x", ehdr->e_ident[i]);
346 printf ("\
347 \ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
348 "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
349 "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
350 ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
351 ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
352 ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
353 ehdr->e_shnum, ehdr->e_shstrndx);
354 }
355
356 if (elf_end (elf) != 0)
357 {
358 printf ("failure in elf_end: %s\n", elf_errmsg (-1));
359 exit (1);
360 }
361
362 unlink (fname);
363
364 return 0;
365 }
366