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 (at) 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 } 366