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 35int 36main (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