• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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