1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * 27 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #if !defined(_ELF64) 34 #pragma weak elf_update = _elf_update 35 #endif 36 37 #include "syn.h" 38 #include <memory.h> 39 #include <malloc.h> 40 #include <limits.h> 41 42 #include <sgs.h> 43 #include "decl.h" 44 #include "msg.h" 45 46 /* 47 * This module is compiled twice, the second time having 48 * -D_ELF64 defined. The following set of macros, along 49 * with machelf.h, represent the differences between the 50 * two compilations. Be careful *not* to add any class- 51 * dependent code (anything that has elf32 or elf64 in the 52 * name) to this code without hiding it behind a switch- 53 * able macro like these. 54 */ 55 #if defined(_ELF64) 56 57 #define FSZ_LONG ELF64_FSZ_XWORD 58 #define ELFCLASS ELFCLASS64 59 #define _elf_snode_init _elf64_snode_init 60 #define _elfxx_cookscn _elf64_cookscn 61 #define _elf_upd_lib _elf64_upd_lib 62 #define elf_fsize elf64_fsize 63 #define _elf_entsz _elf64_entsz 64 #define _elf_msize _elf64_msize 65 #define _elf_upd_usr _elf64_upd_usr 66 #define wrt wrt64 67 #define elf_xlatetof elf64_xlatetof 68 #define _elfxx_update _elf64_update 69 #define _elfxx_swap_wrimage _elf64_swap_wrimage 70 71 #else /* ELF32 */ 72 73 #define FSZ_LONG ELF32_FSZ_WORD 74 #define ELFCLASS ELFCLASS32 75 #define _elf_snode_init _elf32_snode_init 76 #define _elfxx_cookscn _elf32_cookscn 77 #define _elf_upd_lib _elf32_upd_lib 78 #define elf_fsize elf32_fsize 79 #define _elf_entsz _elf32_entsz 80 #define _elf_msize _elf32_msize 81 #define _elf_upd_usr _elf32_upd_usr 82 #define wrt wrt32 83 #define elf_xlatetof elf32_xlatetof 84 #define _elfxx_update _elf32_update 85 #define _elfxx_swap_wrimage _elf32_swap_wrimage 86 87 #endif /* ELF64 */ 88 89 90 /* 91 * Output file update 92 * These functions walk an Elf structure, update its information, 93 * and optionally write the output file. Because the application 94 * may control of the output file layout, two upd_... routines 95 * exist. They're similar but too different to merge cleanly. 96 * 97 * The library defines a "dirty" bit to force parts of the file 98 * to be written on update. These routines ignore the dirty bit 99 * and do everything. A minimal update routine might be useful 100 * someday. 101 */ 102 103 static size_t 104 _elf_upd_lib(Elf * elf) 105 { 106 NOTE(ASSUMING_PROTECTED(*elf)) 107 Lword hi; 108 Lword hibit; 109 Elf_Scn * s; 110 register Xword sz; 111 Ehdr * eh = elf->ed_ehdr; 112 unsigned ver = eh->e_version; 113 register char *p = (char *)eh->e_ident; 114 size_t scncnt; 115 116 /* 117 * Ehdr and Phdr table go first 118 */ 119 p[EI_MAG0] = ELFMAG0; 120 p[EI_MAG1] = ELFMAG1; 121 p[EI_MAG2] = ELFMAG2; 122 p[EI_MAG3] = ELFMAG3; 123 p[EI_CLASS] = ELFCLASS; 124 /* LINTED */ 125 p[EI_VERSION] = (Byte)ver; 126 hi = elf_fsize(ELF_T_EHDR, 1, ver); 127 /* LINTED */ 128 eh->e_ehsize = (Half)hi; 129 if (eh->e_phnum != 0) { 130 /* LINTED */ 131 eh->e_phentsize = (Half)elf_fsize(ELF_T_PHDR, 1, ver); 132 /* LINTED */ 133 eh->e_phoff = (Off)hi; 134 hi += eh->e_phentsize * eh->e_phnum; 135 } else { 136 eh->e_phoff = 0; 137 eh->e_phentsize = 0; 138 } 139 140 /* 141 * Obtain the first section header. Typically, this section has NULL 142 * contents, however in the case of Extended ELF Sections this section 143 * is used to hold an alternative e_shnum, e_shstrndx and e_phnum. 144 * On initial allocation (see _elf_snode) the elements of this section 145 * would have been zeroed. The e_shnum is initialized later, after the 146 * section header count has been determined. The e_shstrndx and 147 * e_phnum may have already been initialized by the caller (for example, 148 * gelf_update_shdr() in mcs(1)). 149 */ 150 if ((s = elf->ed_hdscn) == 0) { 151 eh->e_shnum = 0; 152 scncnt = 0; 153 } else { 154 s = s->s_next; 155 scncnt = 1; 156 } 157 158 /* 159 * Loop through sections. Compute section size before changing hi. 160 * Allow null buffers for NOBITS. 161 */ 162 hibit = 0; 163 for (; s != 0; s = s->s_next) { 164 register Dnode *d; 165 register Lword fsz, j; 166 Shdr *sh = s->s_shdr; 167 168 scncnt++; 169 if (sh->sh_type == SHT_NULL) { 170 *sh = _elf_snode_init.sb_shdr; 171 continue; 172 } 173 174 if ((s->s_myflags & SF_READY) == 0) 175 (void) _elfxx_cookscn(s); 176 177 sh->sh_addralign = 1; 178 if ((sz = (Xword)_elf_entsz(elf, sh->sh_type, ver)) != 0) 179 /* LINTED */ 180 sh->sh_entsize = (Half)sz; 181 sz = 0; 182 for (d = s->s_hdnode; d != 0; d = d->db_next) { 183 if ((fsz = elf_fsize(d->db_data.d_type, 184 1, ver)) == 0) 185 return (0); 186 187 j = _elf_msize(d->db_data.d_type, ver); 188 fsz *= (d->db_data.d_size / j); 189 d->db_osz = (size_t)fsz; 190 if ((j = d->db_data.d_align) > 1) { 191 if (j > sh->sh_addralign) 192 sh->sh_addralign = (Xword)j; 193 194 if (sz % j != 0) 195 sz += j - sz % j; 196 } 197 d->db_data.d_off = (off_t)sz; 198 d->db_xoff = sz; 199 sz += (Xword)fsz; 200 } 201 202 sh->sh_size = sz; 203 /* 204 * We want to take into account the offsets for NOBITS 205 * sections and let the "sh_offsets" point to where 206 * the section would 'conceptually' fit within 207 * the file (as required by the ABI). 208 * 209 * But - we must also make sure that the NOBITS does 210 * not take up any actual space in the file. We preserve 211 * the actual offset into the file in the 'hibit' variable. 212 * When we come to the first non-NOBITS section after a 213 * encountering a NOBITS section the hi counter is restored 214 * to its proper place in the file. 215 */ 216 if (sh->sh_type == SHT_NOBITS) { 217 if (hibit == 0) 218 hibit = hi; 219 } else { 220 if (hibit) { 221 hi = hibit; 222 hibit = 0; 223 } 224 } 225 j = sh->sh_addralign; 226 if ((fsz = hi % j) != 0) 227 hi += j - fsz; 228 229 /* LINTED */ 230 sh->sh_offset = (Off)hi; 231 hi += sz; 232 } 233 234 /* 235 * if last section was a 'NOBITS' section then we need to 236 * restore the 'hi' counter to point to the end of the last 237 * non 'NOBITS' section. 238 */ 239 if (hibit) { 240 hi = hibit; 241 hibit = 0; 242 } 243 244 /* 245 * Shdr table last 246 */ 247 if (scncnt != 0) { 248 if (hi % FSZ_LONG != 0) 249 hi += FSZ_LONG - hi % FSZ_LONG; 250 /* LINTED */ 251 eh->e_shoff = (Off)hi; 252 /* 253 * If we are using 'extended sections' then the 254 * e_shnum is stored in the sh_size field of the 255 * first section header. 256 * 257 * NOTE: we set e_shnum to '0' because it's specified 258 * this way in the gABI, and in the hopes that 259 * this will cause less problems to unaware 260 * tools then if we'd set it to SHN_XINDEX (0xffff). 261 */ 262 if (scncnt < SHN_LORESERVE) 263 eh->e_shnum = scncnt; 264 else { 265 Shdr *sh; 266 sh = (Shdr *)elf->ed_hdscn->s_shdr; 267 sh->sh_size = scncnt; 268 eh->e_shnum = 0; 269 } 270 /* LINTED */ 271 eh->e_shentsize = (Half)elf_fsize(ELF_T_SHDR, 1, ver); 272 hi += eh->e_shentsize * scncnt; 273 } else { 274 eh->e_shoff = 0; 275 eh->e_shentsize = 0; 276 } 277 278 #if !(defined(_LP64) && defined(_ELF64)) 279 if (hi > INT_MAX) { 280 _elf_seterr(EFMT_FBIG, 0); 281 return (0); 282 } 283 #endif 284 285 return ((size_t)hi); 286 } 287 288 289 290 static size_t 291 _elf_upd_usr(Elf * elf) 292 { 293 NOTE(ASSUMING_PROTECTED(*elf)) 294 Lword hi; 295 Elf_Scn * s; 296 register Xword sz; 297 Ehdr * eh = elf->ed_ehdr; 298 unsigned ver = eh->e_version; 299 register char *p = (char *)eh->e_ident; 300 301 302 /* 303 * Ehdr and Phdr table go first 304 */ 305 p[EI_MAG0] = ELFMAG0; 306 p[EI_MAG1] = ELFMAG1; 307 p[EI_MAG2] = ELFMAG2; 308 p[EI_MAG3] = ELFMAG3; 309 p[EI_CLASS] = ELFCLASS; 310 /* LINTED */ 311 p[EI_VERSION] = (Byte)ver; 312 hi = elf_fsize(ELF_T_EHDR, 1, ver); 313 /* LINTED */ 314 eh->e_ehsize = (Half)hi; 315 316 /* 317 * If phnum is zero, phoff "should" be zero too, 318 * but the application is responsible for it. 319 * Allow a non-zero value here and update the 320 * hi water mark accordingly. 321 */ 322 323 if (eh->e_phnum != 0) 324 /* LINTED */ 325 eh->e_phentsize = (Half)elf_fsize(ELF_T_PHDR, 1, ver); 326 else 327 eh->e_phentsize = 0; 328 if ((sz = eh->e_phoff + eh->e_phentsize * eh->e_phnum) > hi) 329 hi = sz; 330 331 /* 332 * Loop through sections, skipping index zero. 333 * Compute section size before changing hi. 334 * Allow null buffers for NOBITS. 335 */ 336 337 if ((s = elf->ed_hdscn) == 0) 338 eh->e_shnum = 0; 339 else { 340 eh->e_shnum = 1; 341 *(Shdr*)s->s_shdr = _elf_snode_init.sb_shdr; 342 s = s->s_next; 343 } 344 for (; s != 0; s = s->s_next) { 345 register Dnode *d; 346 register Xword fsz, j; 347 Shdr *sh = s->s_shdr; 348 349 if ((s->s_myflags & SF_READY) == 0) 350 (void) _elfxx_cookscn(s); 351 352 ++eh->e_shnum; 353 sz = 0; 354 for (d = s->s_hdnode; d != 0; d = d->db_next) { 355 if ((fsz = (Xword)elf_fsize(d->db_data.d_type, 1, 356 ver)) == 0) 357 return (0); 358 j = (Xword)_elf_msize(d->db_data.d_type, ver); 359 fsz *= (Xword)(d->db_data.d_size / j); 360 d->db_osz = (size_t)fsz; 361 362 if ((sh->sh_type != SHT_NOBITS) && 363 ((j = (Xword)(d->db_data.d_off + d->db_osz)) > sz)) 364 sz = j; 365 } 366 if (sh->sh_size < sz) { 367 _elf_seterr(EFMT_SCNSZ, 0); 368 return (0); 369 } 370 if ((sh->sh_type != SHT_NOBITS) && 371 (hi < sh->sh_offset + sh->sh_size)) 372 hi = sh->sh_offset + sh->sh_size; 373 } 374 375 /* 376 * Shdr table last. Comment above for phnum/phoff applies here. 377 */ 378 if (eh->e_shnum != 0) 379 /* LINTED */ 380 eh->e_shentsize = (Half)elf_fsize(ELF_T_SHDR, 1, ver); 381 else 382 eh->e_shentsize = 0; 383 384 if ((sz = eh->e_shoff + eh->e_shentsize * eh->e_shnum) > hi) 385 hi = sz; 386 387 #if !(defined(_LP64) && defined(_ELF64)) 388 if (hi > INT_MAX) { 389 _elf_seterr(EFMT_FBIG, 0); 390 return (0); 391 } 392 #endif 393 394 return ((size_t)hi); 395 } 396 397 398 static size_t 399 wrt(Elf * elf, Xword outsz, unsigned fill, int update_cmd) 400 { 401 NOTE(ASSUMING_PROTECTED(*elf)) 402 Elf_Data dst, src; 403 unsigned flag; 404 Xword hi, sz; 405 char *image; 406 Elf_Scn *s; 407 Ehdr *eh = elf->ed_ehdr; 408 unsigned ver = eh->e_version; 409 unsigned encode; 410 int byte; 411 412 /* 413 * If this is an ELF_C_WRIMAGE write, then we encode into the 414 * byte order of the system we are running on rather than that of 415 * of the object. For ld.so.1, this is the same order, but 416 * for 'ld', it might not be in the case where we are cross 417 * linking an object for a different target. In this later case, 418 * the linker-host byte order is necessary so that the linker can 419 * manipulate the resulting image. It is expected that the linker 420 * will call elf_swap_wrimage() if necessary to convert the image 421 * to the target byte order. 422 */ 423 encode = (update_cmd == ELF_C_WRIMAGE) ? _elf_sys_encoding() : 424 eh->e_ident[EI_DATA]; 425 426 /* 427 * Two issues can cause trouble for the output file. 428 * First, begin() with ELF_C_RDWR opens a file for both 429 * read and write. On the write update(), the library 430 * has to read everything it needs before truncating 431 * the file. Second, using mmap for both read and write 432 * is too tricky. Consequently, the library disables mmap 433 * on the read side. Using mmap for the output saves swap 434 * space, because that mapping is SHARED, not PRIVATE. 435 * 436 * If the file is write-only, there can be nothing of 437 * interest to bother with. 438 * 439 * The following reads the entire file, which might be 440 * more than necessary. Better safe than sorry. 441 */ 442 443 if ((elf->ed_myflags & EDF_READ) && 444 (_elf_vm(elf, (size_t)0, elf->ed_fsz) != OK_YES)) 445 return (0); 446 447 flag = elf->ed_myflags & EDF_WRALLOC; 448 if ((image = _elf_outmap(elf->ed_fd, outsz, &flag)) == 0) 449 return (0); 450 451 if (flag == 0) 452 elf->ed_myflags |= EDF_IMALLOC; 453 454 /* 455 * If an error occurs below, a "dirty" bit may be cleared 456 * improperly. To save a second pass through the file, 457 * this code sets the dirty bit on the elf descriptor 458 * when an error happens, assuming that will "cover" any 459 * accidents. 460 */ 461 462 /* 463 * Hi is needed only when 'fill' is non-zero. 464 * Fill is non-zero only when the library 465 * calculates file/section/data buffer offsets. 466 * The lib guarantees they increase monotonically. 467 * That guarantees proper filling below. 468 */ 469 470 471 /* 472 * Ehdr first 473 */ 474 475 src.d_buf = (Elf_Void *)eh; 476 src.d_type = ELF_T_EHDR; 477 src.d_size = sizeof (Ehdr); 478 src.d_version = EV_CURRENT; 479 dst.d_buf = (Elf_Void *)image; 480 dst.d_size = eh->e_ehsize; 481 dst.d_version = ver; 482 if (elf_xlatetof(&dst, &src, encode) == 0) 483 return (0); 484 elf->ed_ehflags &= ~ELF_F_DIRTY; 485 hi = eh->e_ehsize; 486 487 /* 488 * Phdr table if one exists 489 */ 490 491 if (eh->e_phnum != 0) { 492 unsigned work; 493 /* 494 * Unlike other library data, phdr table is 495 * in the user version. Change src buffer 496 * version here, fix it after translation. 497 */ 498 499 src.d_buf = (Elf_Void *)elf->ed_phdr; 500 src.d_type = ELF_T_PHDR; 501 src.d_size = elf->ed_phdrsz; 502 ELFACCESSDATA(work, _elf_work) 503 src.d_version = work; 504 dst.d_buf = (Elf_Void *)(image + eh->e_phoff); 505 dst.d_size = eh->e_phnum * eh->e_phentsize; 506 hi = (Xword)(eh->e_phoff + dst.d_size); 507 if (elf_xlatetof(&dst, &src, encode) == 0) { 508 elf->ed_uflags |= ELF_F_DIRTY; 509 return (0); 510 } 511 elf->ed_phflags &= ~ELF_F_DIRTY; 512 src.d_version = EV_CURRENT; 513 } 514 515 /* 516 * Loop through sections 517 */ 518 519 ELFACCESSDATA(byte, _elf_byte); 520 for (s = elf->ed_hdscn; s != 0; s = s->s_next) { 521 register Dnode *d, *prevd; 522 Xword off = 0; 523 Shdr *sh = s->s_shdr; 524 char *start = image + sh->sh_offset; 525 char *here; 526 527 /* 528 * Just "clean" DIRTY flag for "empty" sections. Even if 529 * NOBITS needs padding, the next thing in the 530 * file will provide it. (And if this NOBITS is 531 * the last thing in the file, no padding needed.) 532 */ 533 if ((sh->sh_type == SHT_NOBITS) || 534 (sh->sh_type == SHT_NULL)) { 535 d = s->s_hdnode, prevd = 0; 536 for (; d != 0; prevd = d, d = d->db_next) 537 d->db_uflags &= ~ELF_F_DIRTY; 538 continue; 539 } 540 /* 541 * Clear out the memory between the end of the last 542 * section and the begining of this section. 543 */ 544 if (fill && (sh->sh_offset > hi)) { 545 sz = sh->sh_offset - hi; 546 (void) memset(start - sz, byte, sz); 547 } 548 549 550 for (d = s->s_hdnode, prevd = 0; 551 d != 0; prevd = d, d = d->db_next) { 552 d->db_uflags &= ~ELF_F_DIRTY; 553 here = start + d->db_data.d_off; 554 555 /* 556 * Clear out the memory between the end of the 557 * last update and the start of this data buffer. 558 */ 559 if (fill && (d->db_data.d_off > off)) { 560 sz = (Xword)(d->db_data.d_off - off); 561 (void) memset(here - sz, byte, sz); 562 } 563 564 if ((d->db_myflags & DBF_READY) == 0) { 565 SCNLOCK(s); 566 if (_elf_locked_getdata(s, &prevd->db_data) != 567 &d->db_data) { 568 elf->ed_uflags |= ELF_F_DIRTY; 569 SCNUNLOCK(s); 570 return (0); 571 } 572 SCNUNLOCK(s); 573 } 574 dst.d_buf = (Elf_Void *)here; 575 dst.d_size = d->db_osz; 576 577 /* 578 * Copy the translated bits out to the destination 579 * image. 580 */ 581 if (elf_xlatetof(&dst, &d->db_data, encode) == 0) { 582 elf->ed_uflags |= ELF_F_DIRTY; 583 return (0); 584 } 585 586 off = (Xword)(d->db_data.d_off + dst.d_size); 587 } 588 hi = sh->sh_offset + sh->sh_size; 589 } 590 591 /* 592 * Shdr table last 593 */ 594 595 if (fill && (eh->e_shoff > hi)) { 596 sz = eh->e_shoff - hi; 597 (void) memset(image + hi, byte, sz); 598 } 599 600 src.d_type = ELF_T_SHDR; 601 src.d_size = sizeof (Shdr); 602 dst.d_buf = (Elf_Void *)(image + eh->e_shoff); 603 dst.d_size = eh->e_shentsize; 604 for (s = elf->ed_hdscn; s != 0; s = s->s_next) { 605 assert((uintptr_t)dst.d_buf < ((uintptr_t)image + outsz)); 606 s->s_shflags &= ~ELF_F_DIRTY; 607 s->s_uflags &= ~ELF_F_DIRTY; 608 src.d_buf = s->s_shdr; 609 610 if (elf_xlatetof(&dst, &src, encode) == 0) { 611 elf->ed_uflags |= ELF_F_DIRTY; 612 return (0); 613 } 614 615 dst.d_buf = (char *)dst.d_buf + eh->e_shentsize; 616 } 617 /* 618 * ELF_C_WRIMAGE signifyes that we build the memory image, but 619 * that we do not actually write it to disk. This is used 620 * by ld(1) to build up a full image of an elf file and then 621 * to process the file before it's actually written out to 622 * disk. This saves ld(1) the overhead of having to write 623 * the image out to disk twice. 624 */ 625 if (update_cmd == ELF_C_WRIMAGE) { 626 elf->ed_uflags &= ~ELF_F_DIRTY; 627 elf->ed_wrimage = image; 628 elf->ed_wrimagesz = outsz; 629 return (outsz); 630 } 631 632 if (_elf_outsync(elf->ed_fd, image, outsz, 633 ((elf->ed_myflags & EDF_IMALLOC) ? 0 : 1)) != 0) { 634 elf->ed_uflags &= ~ELF_F_DIRTY; 635 elf->ed_myflags &= ~EDF_IMALLOC; 636 return (outsz); 637 } 638 639 elf->ed_uflags |= ELF_F_DIRTY; 640 return (0); 641 } 642 643 644 645 646 /* 647 * The following is a private interface between the linkers (ld & ld.so.1) 648 * and libelf: 649 * 650 * elf_update(elf, ELF_C_WRIMAGE) 651 * This will cause full image representing the elf file 652 * described by the elf pointer to be built in memory. If the 653 * elf pointer has a valid file descriptor associated with it 654 * we will attempt to build the memory image from mmap()'ed 655 * storage. If the elf descriptor does not have a valid 656 * file descriptor (opened with elf_begin(0, ELF_C_IMAGE, 0)) 657 * then the image will be allocated from dynamic memory (malloc()). 658 * 659 * elf_update() will return the size of the memory image built 660 * when sucessful. 661 * 662 * When a subsequent call to elf_update() with ELF_C_WRITE as 663 * the command is performed it will sync the image created 664 * by ELF_C_WRIMAGE to disk (if fd available) and 665 * free the memory allocated. 666 */ 667 668 off_t 669 _elfxx_update(Elf * elf, Elf_Cmd cmd) 670 { 671 size_t sz; 672 unsigned u; 673 Ehdr *eh = elf->ed_ehdr; 674 675 if (elf == 0) 676 return (-1); 677 678 ELFWLOCK(elf) 679 switch (cmd) { 680 default: 681 _elf_seterr(EREQ_UPDATE, 0); 682 ELFUNLOCK(elf) 683 return (-1); 684 685 case ELF_C_WRIMAGE: 686 if ((elf->ed_myflags & EDF_WRITE) == 0) { 687 _elf_seterr(EREQ_UPDWRT, 0); 688 ELFUNLOCK(elf) 689 return (-1); 690 } 691 break; 692 case ELF_C_WRITE: 693 if ((elf->ed_myflags & EDF_WRITE) == 0) { 694 _elf_seterr(EREQ_UPDWRT, 0); 695 ELFUNLOCK(elf) 696 return (-1); 697 } 698 if (elf->ed_wrimage) { 699 if (elf->ed_myflags & EDF_WRALLOC) { 700 free(elf->ed_wrimage); 701 /* 702 * The size is still returned even 703 * though nothing is actually written 704 * out. This is just to be consistant 705 * with the rest of the interface. 706 */ 707 sz = elf->ed_wrimagesz; 708 elf->ed_wrimage = 0; 709 elf->ed_wrimagesz = 0; 710 ELFUNLOCK(elf); 711 return ((off_t)sz); 712 } 713 sz = _elf_outsync(elf->ed_fd, elf->ed_wrimage, 714 elf->ed_wrimagesz, 715 (elf->ed_myflags & EDF_IMALLOC ? 0 : 1)); 716 elf->ed_myflags &= ~EDF_IMALLOC; 717 elf->ed_wrimage = 0; 718 elf->ed_wrimagesz = 0; 719 ELFUNLOCK(elf); 720 return ((off_t)sz); 721 } 722 /* FALLTHROUGH */ 723 case ELF_C_NULL: 724 break; 725 } 726 727 if (eh == 0) { 728 _elf_seterr(ESEQ_EHDR, 0); 729 ELFUNLOCK(elf) 730 return (-1); 731 } 732 733 if ((u = eh->e_version) > EV_CURRENT) { 734 _elf_seterr(EREQ_VER, 0); 735 ELFUNLOCK(elf) 736 return (-1); 737 } 738 739 if (u == EV_NONE) 740 eh->e_version = EV_CURRENT; 741 742 if ((u = eh->e_ident[EI_DATA]) == ELFDATANONE) { 743 unsigned encode; 744 745 ELFACCESSDATA(encode, _elf_encode) 746 if (encode == ELFDATANONE) { 747 _elf_seterr(EREQ_ENCODE, 0); 748 ELFUNLOCK(elf) 749 return (-1); 750 } 751 /* LINTED */ 752 eh->e_ident[EI_DATA] = (Byte)encode; 753 } 754 755 u = 1; 756 if (elf->ed_uflags & ELF_F_LAYOUT) { 757 sz = _elf_upd_usr(elf); 758 u = 0; 759 } else 760 sz = _elf_upd_lib(elf); 761 762 if ((sz != 0) && ((cmd == ELF_C_WRITE) || (cmd == ELF_C_WRIMAGE))) 763 sz = wrt(elf, (Xword)sz, u, cmd); 764 765 if (sz == 0) { 766 ELFUNLOCK(elf) 767 return (-1); 768 } 769 770 ELFUNLOCK(elf) 771 return ((off_t)sz); 772 } 773 774 775 /* 776 * When wrt() processes an ELF_C_WRIMAGE request, the resulting image 777 * gets the byte order (encoding) of the platform running the linker 778 * rather than that of the target host. This allows the linker to modify 779 * the image, prior to flushing it to the output file. This routine 780 * is used to re-translate such an image into the byte order of the 781 * target host. 782 */ 783 int 784 _elfxx_swap_wrimage(Elf * elf) 785 { 786 NOTE(ASSUMING_PROTECTED(*elf)) 787 Elf_Data dst, src; 788 Elf_Scn *s; 789 Ehdr *eh = elf->ed_ehdr; 790 Half e_phnum = eh->e_phnum; 791 unsigned ver = eh->e_version; 792 unsigned encode = eh->e_ident[EI_DATA]; 793 794 /* 795 * Ehdr first 796 */ 797 798 src.d_buf = dst.d_buf = (Elf_Void *)eh; 799 src.d_type = dst.d_type = ELF_T_EHDR; 800 src.d_size = dst.d_size = sizeof (Ehdr); 801 src.d_version = dst.d_version = ver; 802 if (elf_xlatetof(&dst, &src, encode) == 0) 803 return (1); 804 805 /* 806 * Phdr table if one exists 807 */ 808 809 if (e_phnum != 0) { 810 unsigned work; 811 /* 812 * Unlike other library data, phdr table is 813 * in the user version. 814 */ 815 816 src.d_buf = dst.d_buf = (Elf_Void *)elf->ed_phdr; 817 src.d_type = dst.d_type = ELF_T_PHDR; 818 src.d_size = dst.d_size = elf->ed_phdrsz; 819 ELFACCESSDATA(work, _elf_work) 820 src.d_version = dst.d_version = work; 821 if (elf_xlatetof(&dst, &src, encode) == 0) { 822 return (1); 823 } 824 } 825 826 /* 827 * Loop through sections 828 */ 829 830 for (s = elf->ed_hdscn; s != 0; s = s->s_next) { 831 register Dnode *d, *prevd; 832 Shdr *sh = s->s_shdr; 833 834 if ((sh->sh_type == SHT_NOBITS) || (sh->sh_type == SHT_NULL)) 835 continue; 836 837 for (d = s->s_hdnode, prevd = 0; 838 d != 0; prevd = d, d = d->db_next) { 839 840 if ((d->db_myflags & DBF_READY) == 0) { 841 SCNLOCK(s); 842 if (_elf_locked_getdata(s, &prevd->db_data) != 843 &d->db_data) { 844 SCNUNLOCK(s); 845 return (1); 846 } 847 SCNUNLOCK(s); 848 } 849 850 dst = d->db_data; 851 if (elf_xlatetof(&dst, &d->db_data, encode) == 0) 852 return (1); 853 } 854 } 855 856 /* 857 * Shdr table 858 */ 859 860 src.d_type = dst.d_type = ELF_T_SHDR; 861 src.d_version = dst.d_version = ver; 862 for (s = elf->ed_hdscn; s != 0; s = s->s_next) { 863 src.d_buf = dst.d_buf = s->s_shdr; 864 src.d_size = dst.d_size = sizeof (Shdr); 865 if (elf_xlatetof(&dst, &src, encode) == 0) 866 return (1); 867 } 868 869 return (0); 870 } 871 872 873 874 #ifndef _ELF64 875 /* class-independent, only needs to be compiled once */ 876 877 off_t 878 elf_update(Elf *elf, Elf_Cmd cmd) 879 { 880 if (elf == 0) 881 return (-1); 882 883 if (elf->ed_class == ELFCLASS32) 884 return (_elf32_update(elf, cmd)); 885 else if (elf->ed_class == ELFCLASS64) { 886 return (_elf64_update(elf, cmd)); 887 } 888 889 _elf_seterr(EREQ_CLASS, 0); 890 return (-1); 891 } 892 893 int 894 _elf_swap_wrimage(Elf *elf) 895 { 896 if (elf == 0) 897 return (0); 898 899 if (elf->ed_class == ELFCLASS32) 900 return (_elf32_swap_wrimage(elf)); 901 902 if (elf->ed_class == ELFCLASS64) 903 return (_elf64_swap_wrimage(elf)); 904 905 _elf_seterr(EREQ_CLASS, 0); 906 return (0); 907 } 908 909 /* 910 * 4106312, 4106398, This is an ad-hoc means for the 32-bit 911 * Elf64 version of libld.so.3 to get around the limitation 912 * of a 32-bit d_off field. This is only intended to be 913 * used by libld to relocate symbols in large NOBITS sections. 914 */ 915 Elf64_Off 916 _elf_getxoff(Elf_Data * d) 917 { 918 return (((Dnode *)d)->db_xoff); 919 } 920 #endif /* !_ELF64 */ 921