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