1 /*- 2 * Copyright (c) 2006-2011 Joseph Koshy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/stat.h> 29 30 #include <assert.h> 31 #include <errno.h> 32 #include <gelf.h> 33 #include <libelf.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <unistd.h> 37 38 #include "_libelf.h" 39 40 #if ELFTC_HAVE_MMAP 41 #include <sys/mman.h> 42 #endif 43 44 ELFTC_VCSID("$Id: elf_update.c 2931 2013-03-23 11:41:07Z jkoshy $"); 45 46 /* 47 * Layout strategy: 48 * 49 * - Case 1: ELF_F_LAYOUT is asserted 50 * In this case the application has full control over where the 51 * section header table, program header table, and section data 52 * will reside. The library only perform error checks. 53 * 54 * - Case 2: ELF_F_LAYOUT is not asserted 55 * 56 * The library will do the object layout using the following 57 * ordering: 58 * - The executable header is placed first, are required by the 59 * ELF specification. 60 * - The program header table is placed immediately following the 61 * executable header. 62 * - Section data, if any, is placed after the program header 63 * table, aligned appropriately. 64 * - The section header table, if needed, is placed last. 65 * 66 * There are two sub-cases to be taken care of: 67 * 68 * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR 69 * 70 * In this sub-case, the underlying ELF object may already have 71 * content in it, which the application may have modified. The 72 * library will retrieve content from the existing object as 73 * needed. 74 * 75 * - Case 2b: e->e_cmd == ELF_C_WRITE 76 * 77 * The ELF object is being created afresh in this sub-case; 78 * there is no pre-existing content in the underlying ELF 79 * object. 80 */ 81 82 /* 83 * The types of extents in an ELF object. 84 */ 85 enum elf_extent { 86 ELF_EXTENT_EHDR, 87 ELF_EXTENT_PHDR, 88 ELF_EXTENT_SECTION, 89 ELF_EXTENT_SHDR 90 }; 91 92 /* 93 * A extent descriptor, used when laying out an ELF object. 94 */ 95 struct _Elf_Extent { 96 SLIST_ENTRY(_Elf_Extent) ex_next; 97 uint64_t ex_start; /* Start of the region. */ 98 uint64_t ex_size; /* The size of the region. */ 99 enum elf_extent ex_type; /* Type of region. */ 100 void *ex_desc; /* Associated descriptor. */ 101 }; 102 103 SLIST_HEAD(_Elf_Extent_List, _Elf_Extent); 104 105 /* 106 * Compute the extents of a section, by looking at the data 107 * descriptors associated with it. The function returns 1 108 * if successful, or zero if an error was detected. 109 */ 110 static int 111 _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) 112 { 113 int ec; 114 Elf_Data *d; 115 size_t fsz, msz; 116 uint32_t sh_type; 117 uint64_t d_align; 118 Elf32_Shdr *shdr32; 119 Elf64_Shdr *shdr64; 120 unsigned int elftype; 121 struct _Libelf_Data *ld; 122 uint64_t scn_size, scn_alignment; 123 uint64_t sh_align, sh_entsize, sh_offset, sh_size; 124 125 ec = e->e_class; 126 127 shdr32 = &s->s_shdr.s_shdr32; 128 shdr64 = &s->s_shdr.s_shdr64; 129 if (ec == ELFCLASS32) { 130 sh_type = shdr32->sh_type; 131 sh_align = (uint64_t) shdr32->sh_addralign; 132 sh_entsize = (uint64_t) shdr32->sh_entsize; 133 sh_offset = (uint64_t) shdr32->sh_offset; 134 sh_size = (uint64_t) shdr32->sh_size; 135 } else { 136 sh_type = shdr64->sh_type; 137 sh_align = shdr64->sh_addralign; 138 sh_entsize = shdr64->sh_entsize; 139 sh_offset = shdr64->sh_offset; 140 sh_size = shdr64->sh_size; 141 } 142 143 assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS); 144 145 elftype = _libelf_xlate_shtype(sh_type); 146 if (elftype > ELF_T_LAST) { 147 LIBELF_SET_ERROR(SECTION, 0); 148 return (0); 149 } 150 151 if (sh_align == 0) 152 sh_align = _libelf_falign(elftype, ec); 153 154 /* 155 * Compute the section's size and alignment using the data 156 * descriptors associated with the section. 157 */ 158 if (STAILQ_EMPTY(&s->s_data)) { 159 /* 160 * The section's content (if any) has not been read in 161 * yet. If section is not dirty marked dirty, we can 162 * reuse the values in the 'sh_size' and 'sh_offset' 163 * fields of the section header. 164 */ 165 if ((s->s_flags & ELF_F_DIRTY) == 0) { 166 /* 167 * If the library is doing the layout, then we 168 * compute the new start offset for the 169 * section based on the current offset and the 170 * section's alignment needs. 171 * 172 * If the application is doing the layout, we 173 * can use the value in the 'sh_offset' field 174 * in the section header directly. 175 */ 176 if (e->e_flags & ELF_F_LAYOUT) 177 goto updatedescriptor; 178 else 179 goto computeoffset; 180 } 181 182 /* 183 * Otherwise, we need to bring in the section's data 184 * from the underlying ELF object. 185 */ 186 if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL) 187 return (0); 188 } 189 190 /* 191 * Loop through the section's data descriptors. 192 */ 193 scn_size = 0L; 194 scn_alignment = 0; 195 STAILQ_FOREACH(ld, &s->s_data, d_next) { 196 197 d = &ld->d_data; 198 199 /* 200 * The data buffer's type is known. 201 */ 202 if (d->d_type >= ELF_T_NUM) { 203 LIBELF_SET_ERROR(DATA, 0); 204 return (0); 205 } 206 207 /* 208 * The data buffer's version is supported. 209 */ 210 if (d->d_version != e->e_version) { 211 LIBELF_SET_ERROR(VERSION, 0); 212 return (0); 213 } 214 215 /* 216 * The buffer's alignment is non-zero and a power of 217 * two. 218 */ 219 if ((d_align = d->d_align) == 0 || 220 (d_align & (d_align - 1))) { 221 LIBELF_SET_ERROR(DATA, 0); 222 return (0); 223 } 224 225 /* 226 * The buffer's size should be a multiple of the 227 * memory size of the underlying type. 228 */ 229 msz = _libelf_msize(d->d_type, ec, e->e_version); 230 if (d->d_size % msz) { 231 LIBELF_SET_ERROR(DATA, 0); 232 return (0); 233 } 234 235 /* 236 * If the application is controlling layout, then the 237 * d_offset field should be compatible with the 238 * buffer's specified alignment. 239 */ 240 if ((e->e_flags & ELF_F_LAYOUT) && 241 (d->d_off & (d_align - 1))) { 242 LIBELF_SET_ERROR(LAYOUT, 0); 243 return (0); 244 } 245 246 /* 247 * Compute the section's size. 248 */ 249 if (e->e_flags & ELF_F_LAYOUT) { 250 if ((uint64_t) d->d_off + d->d_size > scn_size) 251 scn_size = d->d_off + d->d_size; 252 } else { 253 scn_size = roundup2(scn_size, d->d_align); 254 d->d_off = scn_size; 255 fsz = _libelf_fsize(d->d_type, ec, d->d_version, 256 d->d_size / msz); 257 scn_size += fsz; 258 } 259 260 /* 261 * The section's alignment is the maximum alignment 262 * needed for its data buffers. 263 */ 264 if (d_align > scn_alignment) 265 scn_alignment = d_align; 266 } 267 268 269 /* 270 * If the application is requesting full control over the 271 * layout of the section, check the section's specified size, 272 * offsets and alignment for sanity. 273 */ 274 if (e->e_flags & ELF_F_LAYOUT) { 275 if (scn_alignment > sh_align || sh_offset % sh_align || 276 sh_size < scn_size) { 277 LIBELF_SET_ERROR(LAYOUT, 0); 278 return (0); 279 } 280 goto updatedescriptor; 281 } 282 283 /* 284 * Otherwise, compute the values in the section header. 285 * 286 * The section alignment is the maximum alignment for any of 287 * its contained data descriptors. 288 */ 289 if (scn_alignment > sh_align) 290 sh_align = scn_alignment; 291 292 /* 293 * If the section entry size is zero, try and fill in an 294 * appropriate entry size. Per the elf(5) manual page 295 * sections without fixed-size entries should have their 296 * 'sh_entsize' field set to zero. 297 */ 298 if (sh_entsize == 0 && 299 (sh_entsize = _libelf_fsize(elftype, ec, e->e_version, 300 (size_t) 1)) == 1) 301 sh_entsize = 0; 302 303 sh_size = scn_size; 304 305 computeoffset: 306 /* 307 * Compute the new offset for the section based on 308 * the section's alignment needs. 309 */ 310 sh_offset = roundup(rc, sh_align); 311 312 /* 313 * Update the section header. 314 */ 315 if (ec == ELFCLASS32) { 316 shdr32->sh_addralign = (uint32_t) sh_align; 317 shdr32->sh_entsize = (uint32_t) sh_entsize; 318 shdr32->sh_offset = (uint32_t) sh_offset; 319 shdr32->sh_size = (uint32_t) sh_size; 320 } else { 321 shdr64->sh_addralign = sh_align; 322 shdr64->sh_entsize = sh_entsize; 323 shdr64->sh_offset = sh_offset; 324 shdr64->sh_size = sh_size; 325 } 326 327 updatedescriptor: 328 /* 329 * Update the section descriptor. 330 */ 331 s->s_size = sh_size; 332 s->s_offset = sh_offset; 333 334 return (1); 335 } 336 337 /* 338 * Free a list of extent descriptors. 339 */ 340 341 static void 342 _libelf_release_extents(struct _Elf_Extent_List *extents) 343 { 344 struct _Elf_Extent *ex; 345 346 while ((ex = SLIST_FIRST(extents)) != NULL) { 347 SLIST_REMOVE_HEAD(extents, ex_next); 348 free(ex); 349 } 350 } 351 352 /* 353 * Check if an extent 's' defined by [start..start+size) is free. 354 * This routine assumes that the given extent list is sorted in order 355 * of ascending extent offsets. 356 */ 357 358 static int 359 _libelf_extent_is_unused(struct _Elf_Extent_List *extents, 360 const uint64_t start, const uint64_t size, struct _Elf_Extent **prevt) 361 { 362 uint64_t tmax, tmin; 363 struct _Elf_Extent *t, *pt; 364 const uint64_t smax = start + size; 365 366 /* First, look for overlaps with existing extents. */ 367 pt = NULL; 368 SLIST_FOREACH(t, extents, ex_next) { 369 tmin = t->ex_start; 370 tmax = tmin + t->ex_size; 371 372 if (tmax <= start) { 373 /* 374 * 't' lies entirely before 's': ...| t |...| s |... 375 */ 376 pt = t; 377 continue; 378 } else if (smax <= tmin) { 379 /* 380 * 's' lies entirely before 't', and after 'pt': 381 * ...| pt |...| s |...| t |... 382 */ 383 assert(pt == NULL || 384 pt->ex_start + pt->ex_size <= start); 385 break; 386 } else 387 /* 's' and 't' overlap. */ 388 return (0); 389 } 390 391 if (prevt) 392 *prevt = pt; 393 return (1); 394 } 395 396 /* 397 * Insert an extent into the list of extents. 398 */ 399 400 static int 401 _libelf_insert_extent(struct _Elf_Extent_List *extents, int type, 402 uint64_t start, uint64_t size, void *desc) 403 { 404 struct _Elf_Extent *ex, *prevt; 405 406 assert(type >= ELF_EXTENT_EHDR && type <= ELF_EXTENT_SHDR); 407 408 prevt = NULL; 409 410 /* 411 * If the requested range overlaps with an existing extent, 412 * signal an error. 413 */ 414 if (!_libelf_extent_is_unused(extents, start, size, &prevt)) { 415 LIBELF_SET_ERROR(LAYOUT, 0); 416 return (0); 417 } 418 419 /* Allocate and fill in a new extent descriptor. */ 420 if ((ex = malloc(sizeof(struct _Elf_Extent))) == NULL) { 421 LIBELF_SET_ERROR(RESOURCE, errno); 422 return (0); 423 } 424 ex->ex_start = start; 425 ex->ex_size = size; 426 ex->ex_desc = desc; 427 ex->ex_type = type; 428 429 /* Insert the region descriptor into the list. */ 430 if (prevt) 431 SLIST_INSERT_AFTER(prevt, ex, ex_next); 432 else 433 SLIST_INSERT_HEAD(extents, ex, ex_next); 434 return (1); 435 } 436 437 /* 438 * Recompute section layout. 439 */ 440 441 static off_t 442 _libelf_resync_sections(Elf *e, off_t rc, struct _Elf_Extent_List *extents) 443 { 444 int ec; 445 Elf_Scn *s; 446 size_t sh_type; 447 448 ec = e->e_class; 449 450 /* 451 * Make a pass through sections, computing the extent of each 452 * section. 453 */ 454 STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { 455 if (ec == ELFCLASS32) 456 sh_type = s->s_shdr.s_shdr32.sh_type; 457 else 458 sh_type = s->s_shdr.s_shdr64.sh_type; 459 460 if (sh_type == SHT_NOBITS || sh_type == SHT_NULL) 461 continue; 462 463 if (_libelf_compute_section_extents(e, s, rc) == 0) 464 return ((off_t) -1); 465 466 if (s->s_size == 0) 467 continue; 468 469 if (!_libelf_insert_extent(extents, ELF_EXTENT_SECTION, 470 s->s_offset, s->s_size, s)) 471 return ((off_t) -1); 472 473 if ((size_t) rc < s->s_offset + s->s_size) 474 rc = s->s_offset + s->s_size; 475 } 476 477 return (rc); 478 } 479 480 /* 481 * Recompute the layout of the ELF object and update the internal data 482 * structures associated with the ELF descriptor. 483 * 484 * Returns the size in bytes the ELF object would occupy in its file 485 * representation. 486 * 487 * After a successful call to this function, the following structures 488 * are updated: 489 * 490 * - The ELF header is updated. 491 * - All extents in the ELF object are sorted in order of ascending 492 * addresses. Sections have their section header table entries 493 * updated. An error is signalled if an overlap was detected among 494 * extents. 495 * - Data descriptors associated with sections are checked for valid 496 * types, offsets and alignment. 497 * 498 * After a resync_elf() successfully returns, the ELF descriptor is 499 * ready for being handed over to _libelf_write_elf(). 500 */ 501 502 static off_t 503 _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) 504 { 505 int ec, eh_class; 506 unsigned int eh_byteorder, eh_version; 507 size_t align, fsz; 508 size_t phnum, shnum; 509 off_t rc, phoff, shoff; 510 void *ehdr, *phdr; 511 Elf32_Ehdr *eh32; 512 Elf64_Ehdr *eh64; 513 514 rc = 0; 515 516 ec = e->e_class; 517 518 assert(ec == ELFCLASS32 || ec == ELFCLASS64); 519 520 /* 521 * Prepare the EHDR. 522 */ 523 if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) 524 return ((off_t) -1); 525 526 eh32 = ehdr; 527 eh64 = ehdr; 528 529 if (ec == ELFCLASS32) { 530 eh_byteorder = eh32->e_ident[EI_DATA]; 531 eh_class = eh32->e_ident[EI_CLASS]; 532 phoff = (uint64_t) eh32->e_phoff; 533 shoff = (uint64_t) eh32->e_shoff; 534 eh_version = eh32->e_version; 535 } else { 536 eh_byteorder = eh64->e_ident[EI_DATA]; 537 eh_class = eh64->e_ident[EI_CLASS]; 538 phoff = eh64->e_phoff; 539 shoff = eh64->e_shoff; 540 eh_version = eh64->e_version; 541 } 542 543 if (eh_version == EV_NONE) 544 eh_version = EV_CURRENT; 545 546 if (eh_version != e->e_version) { /* always EV_CURRENT */ 547 LIBELF_SET_ERROR(VERSION, 0); 548 return ((off_t) -1); 549 } 550 551 if (eh_class != e->e_class) { 552 LIBELF_SET_ERROR(CLASS, 0); 553 return ((off_t) -1); 554 } 555 556 if (e->e_cmd != ELF_C_WRITE && eh_byteorder != e->e_byteorder) { 557 LIBELF_SET_ERROR(HEADER, 0); 558 return ((off_t) -1); 559 } 560 561 shnum = e->e_u.e_elf.e_nscn; 562 phnum = e->e_u.e_elf.e_nphdr; 563 564 e->e_byteorder = eh_byteorder; 565 566 #define INITIALIZE_EHDR(E,EC,V) do { \ 567 (E)->e_ident[EI_MAG0] = ELFMAG0; \ 568 (E)->e_ident[EI_MAG1] = ELFMAG1; \ 569 (E)->e_ident[EI_MAG2] = ELFMAG2; \ 570 (E)->e_ident[EI_MAG3] = ELFMAG3; \ 571 (E)->e_ident[EI_CLASS] = (EC); \ 572 (E)->e_ident[EI_VERSION] = (V); \ 573 (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \ 574 (size_t) 1); \ 575 (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \ 576 ELF_T_PHDR, (EC), (V), (size_t) 1); \ 577 (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \ 578 (size_t) 1); \ 579 } while (0) 580 581 if (ec == ELFCLASS32) 582 INITIALIZE_EHDR(eh32, ec, eh_version); 583 else 584 INITIALIZE_EHDR(eh64, ec, eh_version); 585 586 (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); 587 588 rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); 589 590 if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, rc, ehdr)) 591 return ((off_t) -1); 592 593 /* 594 * Compute the layout the program header table, if one is 595 * present. The program header table needs to be aligned to a 596 * `natural' boundary. 597 */ 598 if (phnum) { 599 fsz = _libelf_fsize(ELF_T_PHDR, ec, eh_version, phnum); 600 align = _libelf_falign(ELF_T_PHDR, ec); 601 602 if (e->e_flags & ELF_F_LAYOUT) { 603 /* 604 * Check offsets for sanity. 605 */ 606 if (rc > phoff) { 607 LIBELF_SET_ERROR(LAYOUT, 0); 608 return ((off_t) -1); 609 } 610 611 if (phoff % align) { 612 LIBELF_SET_ERROR(LAYOUT, 0); 613 return ((off_t) -1); 614 } 615 616 } else 617 phoff = roundup(rc, align); 618 619 rc = phoff + fsz; 620 621 phdr = _libelf_getphdr(e, ec); 622 623 if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, phoff, 624 fsz, phdr)) 625 return ((off_t) -1); 626 } else 627 phoff = 0; 628 629 /* 630 * Compute the layout of the sections associated with the 631 * file. 632 */ 633 634 if (e->e_cmd != ELF_C_WRITE && 635 (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && 636 _libelf_load_section_headers(e, ehdr) == 0) 637 return ((off_t) -1); 638 639 if ((rc = _libelf_resync_sections(e, rc, extents)) < 0) 640 return ((off_t) -1); 641 642 /* 643 * Compute the space taken up by the section header table, if 644 * one is needed. 645 * 646 * If ELF_F_LAYOUT has been asserted, the application may have 647 * placed the section header table in between existing 648 * sections, so the net size of the file need not increase due 649 * to the presence of the section header table. 650 * 651 * If the library is responsible for laying out the object, 652 * the section header table is placed after section data. 653 */ 654 if (shnum) { 655 fsz = _libelf_fsize(ELF_T_SHDR, ec, eh_version, shnum); 656 align = _libelf_falign(ELF_T_SHDR, ec); 657 658 if (e->e_flags & ELF_F_LAYOUT) { 659 if (shoff % align) { 660 LIBELF_SET_ERROR(LAYOUT, 0); 661 return ((off_t) -1); 662 } 663 } else 664 shoff = roundup(rc, align); 665 666 if (shoff + fsz > (size_t) rc) 667 rc = shoff + fsz; 668 669 if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, shoff, 670 fsz, NULL)) 671 return ((off_t) -1); 672 } else 673 shoff = 0; 674 675 /* 676 * Set the fields of the Executable Header that could potentially use 677 * extended numbering. 678 */ 679 _libelf_setphnum(e, ehdr, ec, phnum); 680 _libelf_setshnum(e, ehdr, ec, shnum); 681 682 /* 683 * Update the `e_phoff' and `e_shoff' fields if the library is 684 * doing the layout. 685 */ 686 if ((e->e_flags & ELF_F_LAYOUT) == 0) { 687 if (ec == ELFCLASS32) { 688 eh32->e_phoff = (uint32_t) phoff; 689 eh32->e_shoff = (uint32_t) shoff; 690 } else { 691 eh64->e_phoff = (uint64_t) phoff; 692 eh64->e_shoff = (uint64_t) shoff; 693 } 694 } 695 696 return (rc); 697 } 698 699 /* 700 * Write out the contents of an ELF section. 701 */ 702 703 static size_t 704 _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) 705 { 706 int ec; 707 Elf_Scn *s; 708 int elftype; 709 Elf_Data *d, dst; 710 uint32_t sh_type; 711 struct _Libelf_Data *ld; 712 uint64_t sh_off, sh_size; 713 size_t fsz, msz, nobjects, rc; 714 715 assert(ex->ex_type == ELF_EXTENT_SECTION); 716 717 s = ex->ex_desc; 718 rc = ex->ex_start; 719 720 if ((ec = e->e_class) == ELFCLASS32) { 721 sh_type = s->s_shdr.s_shdr32.sh_type; 722 sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; 723 } else { 724 sh_type = s->s_shdr.s_shdr64.sh_type; 725 sh_size = s->s_shdr.s_shdr64.sh_size; 726 } 727 728 /* 729 * Ignore sections that do not allocate space in the file. 730 */ 731 if (sh_type == SHT_NOBITS || sh_type == SHT_NULL || sh_size == 0) 732 return (rc); 733 734 elftype = _libelf_xlate_shtype(sh_type); 735 assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST); 736 737 sh_off = s->s_offset; 738 assert(sh_off % _libelf_falign(elftype, ec) == 0); 739 740 /* 741 * If the section has a `rawdata' descriptor, and the section 742 * contents have not been modified, use its contents directly. 743 * The `s_rawoff' member contains the offset into the original 744 * file, while `s_offset' contains its new location in the 745 * destination. 746 */ 747 748 if (STAILQ_EMPTY(&s->s_data)) { 749 750 if ((d = elf_rawdata(s, NULL)) == NULL) 751 return ((off_t) -1); 752 753 STAILQ_FOREACH(ld, &s->s_rawdata, d_next) { 754 755 d = &ld->d_data; 756 757 if ((uint64_t) rc < sh_off + d->d_off) 758 (void) memset(nf + rc, 759 LIBELF_PRIVATE(fillchar), sh_off + 760 d->d_off - rc); 761 rc = sh_off + d->d_off; 762 763 assert(d->d_buf != NULL); 764 assert(d->d_type == ELF_T_BYTE); 765 assert(d->d_version == e->e_version); 766 767 (void) memcpy(nf + rc, 768 e->e_rawfile + s->s_rawoff + d->d_off, d->d_size); 769 770 rc += d->d_size; 771 } 772 773 return (rc); 774 } 775 776 /* 777 * Iterate over the set of data descriptors for this section. 778 * The prior call to _libelf_resync_elf() would have setup the 779 * descriptors for this step. 780 */ 781 782 dst.d_version = e->e_version; 783 784 STAILQ_FOREACH(ld, &s->s_data, d_next) { 785 786 d = &ld->d_data; 787 788 msz = _libelf_msize(d->d_type, ec, e->e_version); 789 790 if ((uint64_t) rc < sh_off + d->d_off) 791 (void) memset(nf + rc, 792 LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); 793 794 rc = sh_off + d->d_off; 795 796 assert(d->d_buf != NULL); 797 assert(d->d_version == e->e_version); 798 assert(d->d_size % msz == 0); 799 800 nobjects = d->d_size / msz; 801 802 fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); 803 804 dst.d_buf = nf + rc; 805 dst.d_size = fsz; 806 807 if (_libelf_xlate(&dst, d, e->e_byteorder, ec, ELF_TOFILE) == 808 NULL) 809 return ((off_t) -1); 810 811 rc += fsz; 812 } 813 814 return ((off_t) rc); 815 } 816 817 /* 818 * Write out an ELF Executable Header. 819 */ 820 821 static off_t 822 _libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex) 823 { 824 int ec; 825 void *ehdr; 826 size_t fsz, msz; 827 Elf_Data dst, src; 828 829 assert(ex->ex_type == ELF_EXTENT_EHDR); 830 assert(ex->ex_start == 0); /* Ehdr always comes first. */ 831 832 ec = e->e_class; 833 834 ehdr = _libelf_ehdr(e, ec, 0); 835 assert(ehdr != NULL); 836 837 fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); 838 msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version); 839 840 (void) memset(&dst, 0, sizeof(dst)); 841 (void) memset(&src, 0, sizeof(src)); 842 843 src.d_buf = ehdr; 844 src.d_size = msz; 845 src.d_type = ELF_T_EHDR; 846 src.d_version = dst.d_version = e->e_version; 847 848 dst.d_buf = nf; 849 dst.d_size = fsz; 850 851 if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == 852 NULL) 853 return ((off_t) -1); 854 855 return ((off_t) fsz); 856 } 857 858 /* 859 * Write out an ELF program header table. 860 */ 861 862 static off_t 863 _libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) 864 { 865 int ec; 866 void *ehdr; 867 Elf32_Ehdr *eh32; 868 Elf64_Ehdr *eh64; 869 Elf_Data dst, src; 870 size_t fsz, phnum; 871 uint64_t phoff; 872 873 assert(ex->ex_type == ELF_EXTENT_PHDR); 874 875 ec = e->e_class; 876 ehdr = _libelf_ehdr(e, ec, 0); 877 phnum = e->e_u.e_elf.e_nphdr; 878 879 assert(phnum > 0); 880 881 if (ec == ELFCLASS32) { 882 eh32 = (Elf32_Ehdr *) ehdr; 883 phoff = (uint64_t) eh32->e_phoff; 884 } else { 885 eh64 = (Elf64_Ehdr *) ehdr; 886 phoff = eh64->e_phoff; 887 } 888 889 assert(phoff > 0); 890 assert(ex->ex_start == phoff); 891 assert(phoff % _libelf_falign(ELF_T_PHDR, ec) == 0); 892 893 (void) memset(&dst, 0, sizeof(dst)); 894 (void) memset(&src, 0, sizeof(src)); 895 896 fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum); 897 assert(fsz > 0); 898 899 src.d_buf = _libelf_getphdr(e, ec); 900 src.d_version = dst.d_version = e->e_version; 901 src.d_type = ELF_T_PHDR; 902 src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec, 903 e->e_version); 904 905 dst.d_size = fsz; 906 dst.d_buf = nf + ex->ex_start; 907 908 if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == 909 NULL) 910 return ((off_t) -1); 911 912 return (phoff + fsz); 913 } 914 915 /* 916 * Write out an ELF section header table. 917 */ 918 919 static off_t 920 _libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex) 921 { 922 int ec; 923 void *ehdr; 924 Elf_Scn *scn; 925 uint64_t shoff; 926 Elf32_Ehdr *eh32; 927 Elf64_Ehdr *eh64; 928 size_t fsz, nscn; 929 Elf_Data dst, src; 930 931 assert(ex->ex_type == ELF_EXTENT_SHDR); 932 933 ec = e->e_class; 934 ehdr = _libelf_ehdr(e, ec, 0); 935 nscn = e->e_u.e_elf.e_nscn; 936 937 if (ec == ELFCLASS32) { 938 eh32 = (Elf32_Ehdr *) ehdr; 939 shoff = (uint64_t) eh32->e_shoff; 940 } else { 941 eh64 = (Elf64_Ehdr *) ehdr; 942 shoff = eh64->e_shoff; 943 } 944 945 assert(nscn > 0); 946 assert(shoff % _libelf_falign(ELF_T_SHDR, ec) == 0); 947 assert(ex->ex_start == shoff); 948 949 (void) memset(&dst, 0, sizeof(dst)); 950 (void) memset(&src, 0, sizeof(src)); 951 952 src.d_type = ELF_T_SHDR; 953 src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version); 954 src.d_version = dst.d_version = e->e_version; 955 956 fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); 957 958 STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) { 959 if (ec == ELFCLASS32) 960 src.d_buf = &scn->s_shdr.s_shdr32; 961 else 962 src.d_buf = &scn->s_shdr.s_shdr64; 963 964 dst.d_size = fsz; 965 dst.d_buf = nf + ex->ex_start + scn->s_ndx * fsz; 966 967 if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, 968 ELF_TOFILE) == NULL) 969 return ((off_t) -1); 970 } 971 972 return (ex->ex_start + nscn * fsz); 973 } 974 975 /* 976 * Write out the file image. 977 * 978 * The original file could have been mapped in with an ELF_C_RDWR 979 * command and the application could have added new content or 980 * re-arranged its sections before calling elf_update(). Consequently 981 * its not safe to work `in place' on the original file. So we 982 * malloc() the required space for the updated ELF object and build 983 * the object there and write it out to the underlying file at the 984 * end. Note that the application may have opened the underlying file 985 * in ELF_C_RDWR and only retrieved/modified a few sections. We take 986 * care to avoid translating file sections unnecessarily. 987 * 988 * Gaps in the coverage of the file by the file's sections will be 989 * filled with the fill character set by elf_fill(3). 990 */ 991 992 static off_t 993 _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) 994 { 995 off_t nrc, rc; 996 char *newfile; 997 Elf_Scn *scn, *tscn; 998 struct _Elf_Extent *ex; 999 1000 assert(e->e_kind == ELF_K_ELF); 1001 assert(e->e_cmd == ELF_C_RDWR || e->e_cmd == ELF_C_WRITE); 1002 assert(e->e_fd >= 0); 1003 1004 if ((newfile = malloc((size_t) newsize)) == NULL) { 1005 LIBELF_SET_ERROR(RESOURCE, errno); 1006 return ((off_t) -1); 1007 } 1008 1009 nrc = rc = 0; 1010 SLIST_FOREACH(ex, extents, ex_next) { 1011 1012 /* Fill inter-extent gaps. */ 1013 if (ex->ex_start > (size_t) rc) 1014 (void) memset(newfile + rc, LIBELF_PRIVATE(fillchar), 1015 ex->ex_start - rc); 1016 1017 switch (ex->ex_type) { 1018 case ELF_EXTENT_EHDR: 1019 if ((nrc = _libelf_write_ehdr(e, newfile, ex)) < 0) 1020 goto error; 1021 break; 1022 1023 case ELF_EXTENT_PHDR: 1024 if ((nrc = _libelf_write_phdr(e, newfile, ex)) < 0) 1025 goto error; 1026 break; 1027 1028 case ELF_EXTENT_SECTION: 1029 if ((nrc = _libelf_write_scn(e, newfile, ex)) < 0) 1030 goto error; 1031 break; 1032 1033 case ELF_EXTENT_SHDR: 1034 if ((nrc = _libelf_write_shdr(e, newfile, ex)) < 0) 1035 goto error; 1036 break; 1037 1038 default: 1039 assert(0); 1040 break; 1041 } 1042 1043 assert(ex->ex_start + ex->ex_size == (size_t) nrc); 1044 assert(rc < nrc); 1045 1046 rc = nrc; 1047 } 1048 1049 assert(rc == newsize); 1050 1051 /* 1052 * For regular files, throw away existing file content and 1053 * unmap any existing mappings. 1054 */ 1055 if ((e->e_flags & LIBELF_F_SPECIAL_FILE) == 0) { 1056 if (ftruncate(e->e_fd, (off_t) 0) < 0 || 1057 lseek(e->e_fd, (off_t) 0, SEEK_SET)) { 1058 LIBELF_SET_ERROR(IO, errno); 1059 goto error; 1060 } 1061 #if ELFTC_HAVE_MMAP 1062 if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { 1063 assert(e->e_rawfile != NULL); 1064 assert(e->e_cmd == ELF_C_RDWR); 1065 if (munmap(e->e_rawfile, e->e_rawsize) < 0) { 1066 LIBELF_SET_ERROR(IO, errno); 1067 goto error; 1068 } 1069 } 1070 #endif 1071 } 1072 1073 /* 1074 * Write out the new contents. 1075 */ 1076 if (write(e->e_fd, newfile, (size_t) newsize) != newsize) { 1077 LIBELF_SET_ERROR(IO, errno); 1078 goto error; 1079 } 1080 1081 /* 1082 * For files opened in ELF_C_RDWR mode, set up the new 'raw' 1083 * contents. 1084 */ 1085 if (e->e_cmd == ELF_C_RDWR) { 1086 assert(e->e_rawfile != NULL); 1087 assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) || 1088 (e->e_flags & LIBELF_F_RAWFILE_MMAP)); 1089 if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) { 1090 free(e->e_rawfile); 1091 e->e_rawfile = newfile; 1092 newfile = NULL; 1093 } 1094 #if ELFTC_HAVE_MMAP 1095 else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { 1096 if ((e->e_rawfile = mmap(NULL, (size_t) newsize, 1097 PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) == 1098 MAP_FAILED) { 1099 LIBELF_SET_ERROR(IO, errno); 1100 goto error; 1101 } 1102 } 1103 #endif /* ELFTC_HAVE_MMAP */ 1104 1105 /* Record the new size of the file. */ 1106 e->e_rawsize = newsize; 1107 } else { 1108 /* File opened in ELF_C_WRITE mode. */ 1109 assert(e->e_rawfile == NULL); 1110 } 1111 1112 /* 1113 * Reset flags, remove existing section descriptors and 1114 * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr() 1115 * and elf_getscn() will function correctly. 1116 */ 1117 1118 e->e_flags &= ~ELF_F_DIRTY; 1119 1120 STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) 1121 _libelf_release_scn(scn); 1122 1123 if (e->e_class == ELFCLASS32) { 1124 free(e->e_u.e_elf.e_ehdr.e_ehdr32); 1125 if (e->e_u.e_elf.e_phdr.e_phdr32) 1126 free(e->e_u.e_elf.e_phdr.e_phdr32); 1127 1128 e->e_u.e_elf.e_ehdr.e_ehdr32 = NULL; 1129 e->e_u.e_elf.e_phdr.e_phdr32 = NULL; 1130 } else { 1131 free(e->e_u.e_elf.e_ehdr.e_ehdr64); 1132 if (e->e_u.e_elf.e_phdr.e_phdr64) 1133 free(e->e_u.e_elf.e_phdr.e_phdr64); 1134 1135 e->e_u.e_elf.e_ehdr.e_ehdr64 = NULL; 1136 e->e_u.e_elf.e_phdr.e_phdr64 = NULL; 1137 } 1138 1139 /* Free the temporary buffer. */ 1140 if (newfile) 1141 free(newfile); 1142 1143 return (rc); 1144 1145 error: 1146 free(newfile); 1147 1148 return ((off_t) -1); 1149 } 1150 1151 /* 1152 * Update an ELF object. 1153 */ 1154 1155 off_t 1156 elf_update(Elf *e, Elf_Cmd c) 1157 { 1158 int ec; 1159 off_t rc; 1160 struct _Elf_Extent_List extents; 1161 1162 rc = (off_t) -1; 1163 1164 if (e == NULL || e->e_kind != ELF_K_ELF || 1165 (c != ELF_C_NULL && c != ELF_C_WRITE)) { 1166 LIBELF_SET_ERROR(ARGUMENT, 0); 1167 return (rc); 1168 } 1169 1170 if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { 1171 LIBELF_SET_ERROR(CLASS, 0); 1172 return (rc); 1173 } 1174 1175 if (e->e_version == EV_NONE) 1176 e->e_version = EV_CURRENT; 1177 1178 if (c == ELF_C_WRITE && e->e_cmd == ELF_C_READ) { 1179 LIBELF_SET_ERROR(MODE, 0); 1180 return (rc); 1181 } 1182 1183 SLIST_INIT(&extents); 1184 1185 if ((rc = _libelf_resync_elf(e, &extents)) < 0) 1186 goto done; 1187 1188 if (c == ELF_C_NULL) 1189 goto done; 1190 1191 if (e->e_fd < 0) { 1192 rc = (off_t) -1; 1193 LIBELF_SET_ERROR(SEQUENCE, 0); 1194 goto done; 1195 } 1196 1197 rc = _libelf_write_elf(e, rc, &extents); 1198 1199 done: 1200 _libelf_release_extents(&extents); 1201 return (rc); 1202 } 1203