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