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