Imported Upstream version 0.153
[platform/upstream/elfutils.git] / tests / update4.c
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
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 }