1/*- 2 * Copyright (c) 2006-2008 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/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/mman.h> 31#include <sys/param.h> 32 33#include <assert.h> 34#include <errno.h> 35#include <gelf.h> 36#include <libelf.h> 37#include <stdlib.h> 38#include <string.h> 39#include <unistd.h> 40 41#include "_libelf.h" 42 43/* 44 * Layout strategy: 45 * 46 * - Case 1: ELF_F_LAYOUT is asserted 47 * In this case the application has full control over where the 48 * section header table, program header table, and section data 49 * will reside. The library only perform error checks. 50 * 51 * - Case 2: ELF_F_LAYOUT is not asserted 52 * 53 * The library will do the object layout using the following 54 * ordering: 55 * - The executable header is placed first, are required by the 56 * ELF specification. 57 * - The program header table is placed immediately following the 58 * executable header. 59 * - Section data, if any, is placed after the program header 60 * table, aligned appropriately. 61 * - The section header table, if needed, is placed last. 62 * 63 * There are two sub-cases to be taken care of: 64 * 65 * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR 66 * 67 * In this sub-case, the underlying ELF object may already have 68 * content in it, which the application may have modified. The 69 * library will retrieve content from the existing object as 70 * needed. 71 * 72 * - Case 2b: e->e_cmd == ELF_C_WRITE 73 * 74 * The ELF object is being created afresh in this sub-case; 75 * there is no pre-existing content in the underlying ELF 76 * object. 77 */ 78 79/* 80 * Compute the extents of a section, by looking at the data 81 * descriptors associated with it. The function returns 1 if 82 * successful, or zero if an error was detected. 83 */ 84static int 85_libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) 86{ 87 int ec; 88 size_t fsz, msz; 89 Elf_Data *d; 90 Elf32_Shdr *shdr32; 91 Elf64_Shdr *shdr64; 92 unsigned int elftype; 93 uint32_t sh_type; 94 uint64_t d_align; 95 uint64_t sh_align, sh_entsize, sh_offset, sh_size; 96 uint64_t scn_size, scn_alignment; 97 98 ec = e->e_class; 99 100 shdr32 = &s->s_shdr.s_shdr32; 101 shdr64 = &s->s_shdr.s_shdr64; 102 if (ec == ELFCLASS32) { 103 sh_type = shdr32->sh_type; 104 sh_align = (uint64_t) shdr32->sh_addralign; 105 sh_entsize = (uint64_t) shdr32->sh_entsize; 106 sh_offset = (uint64_t) shdr32->sh_offset; 107 sh_size = (uint64_t) shdr32->sh_size; 108 } else { 109 sh_type = shdr64->sh_type; 110 sh_align = shdr64->sh_addralign; 111 sh_entsize = shdr64->sh_entsize; 112 sh_offset = shdr64->sh_offset; 113 sh_size = shdr64->sh_size; 114 } 115 116 assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS); 117 118 elftype = _libelf_xlate_shtype(sh_type); 119 if (elftype > ELF_T_LAST) { 120 LIBELF_SET_ERROR(SECTION, 0); 121 return (0); 122 } 123 124 if (sh_align == 0) 125 sh_align = _libelf_falign(elftype, ec); 126 127 /* 128 * Check the section's data buffers for sanity and compute the 129 * section's alignment. 130 * Compute the section's size and alignment using the data 131 * descriptors associated with the section. 132 */ 133 if (STAILQ_EMPTY(&s->s_data)) { 134 /* 135 * The section's content (if any) has not been read in 136 * yet. If section is not dirty marked dirty, we can 137 * reuse the values in the 'sh_size' and 'sh_offset' 138 * fields of the section header. 139 */ 140 if ((s->s_flags & ELF_F_DIRTY) == 0) { 141 /* 142 * If the library is doing the layout, then we 143 * compute the new start offset for the 144 * section based on the current offset and the 145 * section's alignment needs. 146 * 147 * If the application is doing the layout, we 148 * can use the value in the 'sh_offset' field 149 * in the section header directly. 150 */ 151 if (e->e_flags & ELF_F_LAYOUT) 152 goto updatedescriptor; 153 else 154 goto computeoffset; 155 } 156 157 /* 158 * Otherwise, we need to bring in the section's data 159 * from the underlying ELF object. 160 */ 161 if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL) 162 return (0); 163 } 164 165 /* 166 * Loop through the section's data descriptors. 167 */ 168 scn_size = 0L; 169 scn_alignment = 0L; 170 STAILQ_FOREACH(d, &s->s_data, d_next) { 171 if (d->d_type > ELF_T_LAST) { 172 LIBELF_SET_ERROR(DATA, 0); 173 return (0); 174 } 175 if (d->d_version != e->e_version) { 176 LIBELF_SET_ERROR(VERSION, 0); 177 return (0); 178 } 179 if ((d_align = d->d_align) == 0 || (d_align & (d_align - 1))) { 180 LIBELF_SET_ERROR(DATA, 0); 181 return (0); 182 } 183 184 /* 185 * The buffer's size should be a multiple of the 186 * memory size of the underlying type. 187 */ 188 msz = _libelf_msize(d->d_type, ec, e->e_version); 189 if (d->d_size % msz) { 190 LIBELF_SET_ERROR(DATA, 0); 191 return (0); 192 } 193 194 /* 195 * Compute the section's size. 196 */ 197 if (e->e_flags & ELF_F_LAYOUT) { 198 if ((uint64_t) d->d_off + d->d_size > scn_size) 199 scn_size = d->d_off + d->d_size; 200 } else { 201 scn_size = roundup2(scn_size, d->d_align); 202 d->d_off = scn_size; 203 fsz = _libelf_fsize(d->d_type, ec, d->d_version, 204 d->d_size / msz); 205 scn_size += fsz; 206 } 207 208 /* 209 * The section's alignment is the maximum alignment 210 * needed for its data buffers. 211 */ 212 if (d_align > scn_alignment) 213 scn_alignment = d_align; 214 } 215 216 217 /* 218 * If the application is requesting full control over the layout 219 * of the section, check its values for sanity. 220 */ 221 if (e->e_flags & ELF_F_LAYOUT) { 222 if (scn_alignment > sh_align || sh_offset % sh_align || 223 sh_size < scn_size) { 224 LIBELF_SET_ERROR(LAYOUT, 0); 225 return (0); 226 } 227 goto updatedescriptor; 228 } 229 230 /* 231 * Otherwise compute the values in the section header. 232 * 233 * The section alignment is the maximum alignment for any of 234 * its contained data descriptors. 235 */ 236 if (scn_alignment > sh_align) 237 sh_align = scn_alignment; 238 239 /* 240 * If the section entry size is zero, try and fill in an 241 * appropriate entry size. Per the elf(5) manual page 242 * sections without fixed-size entries should have their 243 * 'sh_entsize' field set to zero. 244 */ 245 if (sh_entsize == 0 && 246 (sh_entsize = _libelf_fsize(elftype, ec, e->e_version, 247 (size_t) 1)) == 1) 248 sh_entsize = 0; 249 250 sh_size = scn_size; 251 252computeoffset: 253 /* 254 * Compute the new offset for the section based on 255 * the section's alignment needs. 256 */ 257 sh_offset = roundup(rc, sh_align); 258 259 /* 260 * Update the section header. 261 */ 262 if (ec == ELFCLASS32) { 263 shdr32->sh_addralign = (uint32_t) sh_align; 264 shdr32->sh_entsize = (uint32_t) sh_entsize; 265 shdr32->sh_offset = (uint32_t) sh_offset; 266 shdr32->sh_size = (uint32_t) sh_size; 267 } else { 268 shdr64->sh_addralign = sh_align; 269 shdr64->sh_entsize = sh_entsize; 270 shdr64->sh_offset = sh_offset; 271 shdr64->sh_size = sh_size; 272 } 273 274updatedescriptor: 275 /* 276 * Update the section descriptor. 277 */ 278 s->s_size = sh_size; 279 s->s_offset = sh_offset; 280 281 return (1); 282} 283 284 285/* 286 * Insert a section in ascending order in the list 287 */ 288 289static int 290_libelf_insert_section(Elf *e, Elf_Scn *s) 291{ 292 Elf_Scn *t, *prevt; 293 uint64_t smax, smin, tmax, tmin; 294 295 smin = s->s_offset; 296 smax = smin + s->s_size; 297 298 prevt = NULL; 299 STAILQ_FOREACH(t, &e->e_u.e_elf.e_scn, s_next) { 300 tmin = t->s_offset; 301 tmax = tmin + t->s_size; 302 303 if (tmax <= smin) { 304 /* 305 * 't' lies entirely before 's': ...| t |...| s |... 306 */ 307 prevt = t; 308 continue; 309 } else if (smax <= tmin) 310 /* 311 * 's' lies entirely before 't', and after 'prevt': 312 * ...| prevt |...| s |...| t |... 313 */ 314 break; 315 else { /* 's' and 't' overlap. */ 316 LIBELF_SET_ERROR(LAYOUT, 0); 317 return (0); 318 } 319 } 320 321 if (prevt) 322 STAILQ_INSERT_AFTER(&e->e_u.e_elf.e_scn, prevt, s, s_next); 323 else 324 STAILQ_INSERT_HEAD(&e->e_u.e_elf.e_scn, s, s_next); 325 return (1); 326} 327 328/* 329 * Recompute section layout. 330 */ 331 332static off_t 333_libelf_resync_sections(Elf *e, off_t rc) 334{ 335 int ec; 336 Elf_Scn *s; 337 size_t sh_type, shdr_start, shdr_end; 338 339 ec = e->e_class; 340 341 /* 342 * Make a pass through sections, computing the extent of each 343 * section. Order in increasing order of addresses. 344 */ 345 STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { 346 if (ec == ELFCLASS32) 347 sh_type = s->s_shdr.s_shdr32.sh_type; 348 else 349 sh_type = s->s_shdr.s_shdr64.sh_type; 350 351 if (sh_type == SHT_NOBITS || sh_type == SHT_NULL) 352 continue; 353 354 if (_libelf_compute_section_extents(e, s, rc) == 0) 355 return ((off_t) -1); 356 357 if (s->s_size == 0) 358 continue; 359 360 if (s->s_offset + s->s_size < (size_t) rc) { 361 /* 362 * Try insert this section in the 363 * correct place in the list, 364 * detecting overlaps if any. 365 */ 366 STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, 367 s_next); 368 if (_libelf_insert_section(e, s) == 0) 369 return ((off_t) -1); 370 } else 371 rc = s->s_offset + s->s_size; 372 } 373 374 /* 375 * If the application is controlling file layout, check for an 376 * overlap between this section's extents and the SHDR table. 377 */ 378 if (e->e_flags & ELF_F_LAYOUT) { 379 380 if (e->e_class == ELFCLASS32) 381 shdr_start = e->e_u.e_elf.e_ehdr.e_ehdr32->e_shoff; 382 else 383 shdr_start = e->e_u.e_elf.e_ehdr.e_ehdr64->e_shoff; 384 385 shdr_end = shdr_start + _libelf_fsize(ELF_T_SHDR, e->e_class, 386 e->e_version, e->e_u.e_elf.e_nscn); 387 388 STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { 389 if (s->s_offset >= shdr_end || 390 s->s_offset + s->s_size <= shdr_start) 391 continue; 392 LIBELF_SET_ERROR(LAYOUT, 0); 393 return ((off_t) -1); 394 } 395 } 396 397 return (rc); 398} 399 400static off_t 401_libelf_resync_elf(Elf *e) 402{ 403 int ec, eh_class, eh_type; 404 unsigned int eh_byteorder, eh_version; 405 size_t align, fsz; 406 size_t phnum, shnum; 407 off_t rc, phoff, shoff; 408 void *ehdr; 409 Elf32_Ehdr *eh32; 410 Elf64_Ehdr *eh64; 411 412 rc = 0; 413 414 ec = e->e_class; 415 416 assert(ec == ELFCLASS32 || ec == ELFCLASS64); 417 418 /* 419 * Prepare the EHDR. 420 */ 421 if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) 422 return ((off_t) -1); 423 424 eh32 = ehdr; 425 eh64 = ehdr; 426 427 if (ec == ELFCLASS32) { 428 eh_byteorder = eh32->e_ident[EI_DATA]; 429 eh_class = eh32->e_ident[EI_CLASS]; 430 phoff = (uint64_t) eh32->e_phoff; 431 shoff = (uint64_t) eh32->e_shoff; 432 eh_type = eh32->e_type; 433 eh_version = eh32->e_version; 434 } else { 435 eh_byteorder = eh64->e_ident[EI_DATA]; 436 eh_class = eh64->e_ident[EI_CLASS]; 437 phoff = eh64->e_phoff; 438 shoff = eh64->e_shoff; 439 eh_type = eh64->e_type; 440 eh_version = eh64->e_version; 441 } 442 443 if (eh_version == EV_NONE) 444 eh_version = EV_CURRENT; 445 446 if (eh_version != e->e_version) { /* always EV_CURRENT */ 447 LIBELF_SET_ERROR(VERSION, 0); 448 return ((off_t) -1); 449 } 450 451 if (eh_class != e->e_class) { 452 LIBELF_SET_ERROR(CLASS, 0); 453 return ((off_t) -1); 454 } 455 456 if (e->e_cmd != ELF_C_WRITE && eh_byteorder != e->e_byteorder) { 457 LIBELF_SET_ERROR(HEADER, 0); 458 return ((off_t) -1); 459 } 460 461 shnum = e->e_u.e_elf.e_nscn; 462 phnum = e->e_u.e_elf.e_nphdr; 463 464 e->e_byteorder = eh_byteorder; 465 466#define INITIALIZE_EHDR(E,EC,V) do { \ 467 (E)->e_ident[EI_MAG0] = ELFMAG0; \ 468 (E)->e_ident[EI_MAG1] = ELFMAG1; \ 469 (E)->e_ident[EI_MAG2] = ELFMAG2; \ 470 (E)->e_ident[EI_MAG3] = ELFMAG3; \ 471 (E)->e_ident[EI_CLASS] = (EC); \ 472 (E)->e_ident[EI_VERSION] = (V); \ 473 (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \ 474 (size_t) 1); \ 475 (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \ 476 ELF_T_PHDR, (EC), (V), (size_t) 1); \ 477 (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \ 478 (size_t) 1); \ 479 } while (0) 480 481 if (ec == ELFCLASS32) 482 INITIALIZE_EHDR(eh32, ec, eh_version); 483 else 484 INITIALIZE_EHDR(eh64, ec, eh_version); 485 486 (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); 487 488 rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); 489 490 /* 491 * Compute the layout the program header table, if one is 492 * present. The program header table needs to be aligned to a 493 * `natural' boundary. 494 */ 495 if (phnum) { 496 fsz = _libelf_fsize(ELF_T_PHDR, ec, eh_version, phnum); 497 align = _libelf_falign(ELF_T_PHDR, ec); 498 499 if (e->e_flags & ELF_F_LAYOUT) { 500 /* 501 * Check offsets for sanity. 502 */ 503 if (rc > phoff) { 504 LIBELF_SET_ERROR(HEADER, 0); 505 return ((off_t) -1); 506 } 507 508 if (phoff % align) { 509 LIBELF_SET_ERROR(LAYOUT, 0); 510 return ((off_t) -1); 511 } 512 513 } else 514 phoff = roundup(rc, align); 515 516 rc = phoff + fsz; 517 } else 518 phoff = 0; 519 520 /* 521 * Compute the layout of the sections associated with the 522 * file. 523 */ 524 525 if (e->e_cmd != ELF_C_WRITE && 526 (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && 527 _libelf_load_scn(e, ehdr) == 0) 528 return ((off_t) -1); 529 530 if ((rc = _libelf_resync_sections(e, rc)) < 0) 531 return ((off_t) -1); 532 533 /* 534 * Compute the space taken up by the section header table, if 535 * one is needed. If ELF_F_LAYOUT is asserted, the 536 * application may have placed the section header table in 537 * between existing sections, so the net size of the file need 538 * not increase due to the presence of the section header 539 * table. 540 */ 541 if (shnum) { 542 fsz = _libelf_fsize(ELF_T_SHDR, ec, eh_version, (size_t) 1); 543 align = _libelf_falign(ELF_T_SHDR, ec); 544 545 if (e->e_flags & ELF_F_LAYOUT) { 546 if (shoff % align) { 547 LIBELF_SET_ERROR(LAYOUT, 0); 548 return ((off_t) -1); 549 } 550 } else 551 shoff = roundup(rc, align); 552 553 if (shoff + fsz * shnum > (size_t) rc) 554 rc = shoff + fsz * shnum; 555 } else 556 shoff = 0; 557 558 /* 559 * Set the fields of the Executable Header that could potentially use 560 * extended numbering. 561 */ 562 _libelf_setphnum(e, ehdr, ec, phnum); 563 _libelf_setshnum(e, ehdr, ec, shnum); 564 565 /* 566 * Update the `e_phoff' and `e_shoff' fields if the library is 567 * doing the layout. 568 */ 569 if ((e->e_flags & ELF_F_LAYOUT) == 0) { 570 if (ec == ELFCLASS32) { 571 eh32->e_phoff = (uint32_t) phoff; 572 eh32->e_shoff = (uint32_t) shoff; 573 } else { 574 eh64->e_phoff = (uint64_t) phoff; 575 eh64->e_shoff = (uint64_t) shoff; 576 } 577 } 578 579 return (rc); 580} 581 582/* 583 * Write out the contents of a section. 584 */ 585 586static off_t 587_libelf_write_scn(Elf *e, char *nf, Elf_Scn *s, off_t rc) 588{ 589 int ec; 590 size_t fsz, msz, nobjects; 591 uint32_t sh_type; 592 uint64_t sh_off, sh_size; 593 int elftype; 594 Elf_Data *d, dst; 595 596 if ((ec = e->e_class) == ELFCLASS32) { 597 sh_type = s->s_shdr.s_shdr32.sh_type; 598 sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; 599 } else { 600 sh_type = s->s_shdr.s_shdr64.sh_type; 601 sh_size = s->s_shdr.s_shdr64.sh_size; 602 } 603 604 /* 605 * Ignore sections that do not allocate space in the file. 606 */ 607 if (sh_type == SHT_NOBITS || sh_type == SHT_NULL || sh_size == 0) 608 return (rc); 609 610 elftype = _libelf_xlate_shtype(sh_type); 611 assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST); 612 613 sh_off = s->s_offset; 614 assert(sh_off % _libelf_falign(elftype, ec) == 0); 615 616 /* 617 * If the section has a `rawdata' descriptor, and the section 618 * contents have not been modified, use its contents directly. 619 * The `s_rawoff' member contains the offset into the original 620 * file, while `s_offset' contains its new location in the 621 * destination. 622 */ 623 624 if (STAILQ_EMPTY(&s->s_data)) { 625 626 if ((d = elf_rawdata(s, NULL)) == NULL) 627 return ((off_t) -1); 628 629 STAILQ_FOREACH(d, &s->s_rawdata, d_next) { 630 if ((uint64_t) rc < sh_off + d->d_off) 631 (void) memset(nf + rc, 632 LIBELF_PRIVATE(fillchar), sh_off + 633 d->d_off - rc); 634 rc = sh_off + d->d_off; 635 636 assert(d->d_buf != NULL); 637 assert(d->d_type == ELF_T_BYTE); 638 assert(d->d_version == e->e_version); 639 640 (void) memcpy(nf + rc, 641 e->e_rawfile + s->s_rawoff + d->d_off, d->d_size); 642 643 rc += d->d_size; 644 } 645 646 return (rc); 647 } 648 649 /* 650 * Iterate over the set of data descriptors for this section. 651 * The prior call to _libelf_resync_elf() would have setup the 652 * descriptors for this step. 653 */ 654 655 dst.d_version = e->e_version; 656 657 STAILQ_FOREACH(d, &s->s_data, d_next) { 658 659 msz = _libelf_msize(d->d_type, ec, e->e_version); 660 661 if ((uint64_t) rc < sh_off + d->d_off) 662 (void) memset(nf + rc, 663 LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); 664 665 rc = sh_off + d->d_off; 666 667 assert(d->d_buf != NULL); 668 assert(d->d_version == e->e_version); 669 assert(d->d_size % msz == 0); 670 671 nobjects = d->d_size / msz; 672 673 fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); 674 675 dst.d_buf = nf + rc; 676 dst.d_size = fsz; 677 678 if (_libelf_xlate(&dst, d, e->e_byteorder, ec, ELF_TOFILE) == 679 NULL) 680 return ((off_t) -1); 681 682 rc += fsz; 683 } 684 685 return ((off_t) rc); 686} 687 688/* 689 * Write out the file image. 690 * 691 * The original file could have been mapped in with an ELF_C_RDWR 692 * command and the application could have added new content or 693 * re-arranged its sections before calling elf_update(). Consequently 694 * its not safe to work `in place' on the original file. So we 695 * malloc() the required space for the updated ELF object and build 696 * the object there and write it out to the underlying file at the 697 * end. Note that the application may have opened the underlying file 698 * in ELF_C_RDWR and only retrieved/modified a few sections. We take 699 * care to avoid translating file sections unnecessarily. 700 * 701 * Gaps in the coverage of the file by the file's sections will be 702 * filled with the fill character set by elf_fill(3). 703 */ 704 705static off_t 706_libelf_write_elf(Elf *e, off_t newsize) 707{ 708 int ec; 709 off_t maxrc, rc; 710 size_t fsz, msz, phnum, shnum; 711 uint64_t phoff, shoff; 712 void *ehdr; 713 char *newfile; 714 Elf_Data dst, src; 715 Elf_Scn *scn, *tscn; 716 Elf32_Ehdr *eh32; 717 Elf64_Ehdr *eh64; 718 719 assert(e->e_kind == ELF_K_ELF); 720 assert(e->e_cmd != ELF_C_READ); 721 assert(e->e_fd >= 0); 722 723 if ((newfile = malloc((size_t) newsize)) == NULL) { 724 LIBELF_SET_ERROR(RESOURCE, errno); 725 return ((off_t) -1); 726 } 727 728 ec = e->e_class; 729 730 ehdr = _libelf_ehdr(e, ec, 0); 731 assert(ehdr != NULL); 732 733 phnum = e->e_u.e_elf.e_nphdr; 734 735 if (ec == ELFCLASS32) { 736 eh32 = (Elf32_Ehdr *) ehdr; 737 738 phoff = (uint64_t) eh32->e_phoff; 739 shnum = eh32->e_shnum; 740 shoff = (uint64_t) eh32->e_shoff; 741 } else { 742 eh64 = (Elf64_Ehdr *) ehdr; 743 744 phoff = eh64->e_phoff; 745 shnum = eh64->e_shnum; 746 shoff = eh64->e_shoff; 747 } 748 749 fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); 750 msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version); 751 752 (void) memset(&dst, 0, sizeof(dst)); 753 (void) memset(&src, 0, sizeof(src)); 754 755 src.d_buf = ehdr; 756 src.d_size = msz; 757 src.d_type = ELF_T_EHDR; 758 src.d_version = dst.d_version = e->e_version; 759 760 rc = 0; 761 762 dst.d_buf = newfile + rc; 763 dst.d_size = fsz; 764 765 if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == 766 NULL) 767 goto error; 768 769 rc += fsz; 770 771 /* 772 * Write the program header table if present. 773 */ 774 775 if (phnum != 0 && phoff != 0) { 776 assert((unsigned) rc <= phoff); 777 778 fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum); 779 780 assert(phoff % _libelf_falign(ELF_T_PHDR, ec) == 0); 781 assert(fsz > 0); 782 783 src.d_buf = _libelf_getphdr(e, ec); 784 src.d_version = dst.d_version = e->e_version; 785 src.d_type = ELF_T_PHDR; 786 src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec, 787 e->e_version); 788 789 dst.d_size = fsz; 790 791 if ((uint64_t) rc < phoff) 792 (void) memset(newfile + rc, 793 LIBELF_PRIVATE(fillchar), phoff - rc); 794 795 dst.d_buf = newfile + rc; 796 797 if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == 798 NULL) 799 goto error; 800 801 rc = phoff + fsz; 802 } 803 804 /* 805 * Write out individual sections. 806 */ 807 808 STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) 809 if ((rc = _libelf_write_scn(e, newfile, scn, rc)) < 0) 810 goto error; 811 812 /* 813 * Write out the section header table, if required. Note that 814 * if flag ELF_F_LAYOUT has been set the section header table 815 * could reside in between byte ranges mapped by section 816 * descriptors. 817 */ 818 if (shnum != 0 && shoff != 0) { 819 if ((uint64_t) rc < shoff) 820 (void) memset(newfile + rc, 821 LIBELF_PRIVATE(fillchar), shoff - rc); 822 823 maxrc = rc; 824 rc = shoff; 825 826 assert(rc % _libelf_falign(ELF_T_SHDR, ec) == 0); 827 828 src.d_type = ELF_T_SHDR; 829 src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version); 830 src.d_version = dst.d_version = e->e_version; 831 832 fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); 833 834 STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) { 835 if (ec == ELFCLASS32) 836 src.d_buf = &scn->s_shdr.s_shdr32; 837 else 838 src.d_buf = &scn->s_shdr.s_shdr64; 839 840 dst.d_size = fsz; 841 dst.d_buf = newfile + rc + scn->s_ndx * fsz; 842 843 if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, 844 ELF_TOFILE) != &dst) 845 goto error; 846 } 847 848 rc += e->e_u.e_elf.e_nscn * fsz; 849 if (maxrc > rc) 850 rc = maxrc; 851 } 852 853 assert(rc == newsize); 854 855 /* 856 * Write out the constructed contents and remap the file in 857 * read-only. 858 */ 859 860 if (e->e_rawfile && munmap(e->e_rawfile, e->e_rawsize) < 0) { 861 LIBELF_SET_ERROR(IO, errno); 862 goto error; 863 } 864 865 if (write(e->e_fd, newfile, (size_t) newsize) != newsize || 866 lseek(e->e_fd, (off_t) 0, SEEK_SET) < 0) { 867 LIBELF_SET_ERROR(IO, errno); 868 goto error; 869 } 870 871 if (e->e_cmd != ELF_C_WRITE) { 872 if ((e->e_rawfile = mmap(NULL, (size_t) newsize, PROT_READ, 873 MAP_PRIVATE, e->e_fd, (off_t) 0)) == MAP_FAILED) { 874 LIBELF_SET_ERROR(IO, errno); 875 goto error; 876 } 877 e->e_rawsize = newsize; 878 } 879 880 /* 881 * Reset flags, remove existing section descriptors and 882 * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr() 883 * and elf_getscn() will function correctly. 884 */ 885 886 e->e_flags &= ~ELF_F_DIRTY; 887 888 STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) 889 _libelf_release_scn(scn); 890 891 if (ec == ELFCLASS32) { 892 free(e->e_u.e_elf.e_ehdr.e_ehdr32); 893 if (e->e_u.e_elf.e_phdr.e_phdr32) 894 free(e->e_u.e_elf.e_phdr.e_phdr32); 895 896 e->e_u.e_elf.e_ehdr.e_ehdr32 = NULL; 897 e->e_u.e_elf.e_phdr.e_phdr32 = NULL; 898 } else { 899 free(e->e_u.e_elf.e_ehdr.e_ehdr64); 900 if (e->e_u.e_elf.e_phdr.e_phdr64) 901 free(e->e_u.e_elf.e_phdr.e_phdr64); 902 903 e->e_u.e_elf.e_ehdr.e_ehdr64 = NULL; 904 e->e_u.e_elf.e_phdr.e_phdr64 = NULL; 905 } 906 907 free(newfile); 908 909 return (rc); 910 911 error: 912 free(newfile); 913 914 return ((off_t) -1); 915} 916 917off_t 918elf_update(Elf *e, Elf_Cmd c) 919{ 920 int ec; 921 off_t rc; 922 923 rc = (off_t) -1; 924 925 if (e == NULL || e->e_kind != ELF_K_ELF || 926 (c != ELF_C_NULL && c != ELF_C_WRITE)) { 927 LIBELF_SET_ERROR(ARGUMENT, 0); 928 return (rc); 929 } 930 931 if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { 932 LIBELF_SET_ERROR(CLASS, 0); 933 return (rc); 934 } 935 936 if (e->e_version == EV_NONE) 937 e->e_version = EV_CURRENT; 938 939 if (c == ELF_C_WRITE && e->e_cmd == ELF_C_READ) { 940 LIBELF_SET_ERROR(MODE, 0); 941 return (rc); 942 } 943 944 if ((rc = _libelf_resync_elf(e)) < 0) 945 return (rc); 946 947 if (c == ELF_C_NULL) 948 return (rc); 949 950 if (e->e_cmd == ELF_C_READ) { 951 /* 952 * This descriptor was opened in read-only mode or by 953 * elf_memory(). 954 */ 955 if (e->e_fd) 956 LIBELF_SET_ERROR(MODE, 0); 957 else 958 LIBELF_SET_ERROR(ARGUMENT, 0); 959 return ((off_t) -1); 960 } 961 962 if (e->e_fd < 0) { 963 LIBELF_SET_ERROR(SEQUENCE, 0); 964 return ((off_t) -1); 965 } 966 967 return (_libelf_write_elf(e, rc)); 968} 969