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