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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1988 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2004 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 70 #else /* ELF32 */ 71 72 #define FSZ_LONG ELF32_FSZ_WORD 73 #define ELFCLASS ELFCLASS32 74 #define _elf_snode_init _elf32_snode_init 75 #define _elfxx_cookscn _elf32_cookscn 76 #define _elf_upd_lib _elf32_upd_lib 77 #define elf_fsize elf32_fsize 78 #define _elf_entsz _elf32_entsz 79 #define _elf_msize _elf32_msize 80 #define _elf_upd_usr _elf32_upd_usr 81 #define wrt wrt32 82 #define elf_xlatetof elf32_xlatetof 83 #define _elfxx_update _elf32_update 84 85 #endif /* ELF64 */ 86 87 88 /* 89 * Output file update 90 * These functions walk an Elf structure, update its information, 91 * and optionally write the output file. Because the application 92 * may control of the output file layout, two upd_... routines 93 * exist. They're similar but too different to merge cleanly. 94 * 95 * The library defines a "dirty" bit to force parts of the file 96 * to be written on update. These routines ignore the dirty bit 97 * and do everything. A minimal update routine might be useful 98 * someday. 99 */ 100 101 102 static size_t 103 _elf_upd_lib(Elf * elf) 104 { 105 NOTE(ASSUMING_PROTECTED(*elf)) 106 Lword hi; 107 Lword hibit; 108 Elf_Scn * s; 109 register Xword sz; 110 Ehdr * eh = elf->ed_ehdr; 111 unsigned ver = eh->e_version; 112 register char *p = (char *)eh->e_ident; 113 size_t scncnt; 114 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 /* 142 * Loop through sections, skipping index zero. 143 * Compute section size before changing hi. 144 * Allow null buffers for NOBITS. 145 */ 146 147 if ((s = elf->ed_hdscn) == 0) { 148 eh->e_shnum = 0; 149 scncnt = 0; 150 } else { 151 scncnt = 1; 152 *(Shdr *)s->s_shdr = _elf_snode_init.sb_shdr; 153 s = s->s_next; 154 } 155 156 hibit = 0; 157 for (; s != 0; s = s->s_next) { 158 register Dnode *d; 159 register Lword fsz, j; 160 Shdr *sh = s->s_shdr; 161 162 scncnt++; 163 if (sh->sh_type == SHT_NULL) { 164 *sh = _elf_snode_init.sb_shdr; 165 continue; 166 } 167 168 if ((s->s_myflags & SF_READY) == 0) 169 (void) _elfxx_cookscn(s); 170 171 sh->sh_addralign = 1; 172 if ((sz = (Xword)_elf_entsz(sh->sh_type, ver)) != 0) 173 /* LINTED */ 174 sh->sh_entsize = (Half)sz; 175 sz = 0; 176 for (d = s->s_hdnode; d != 0; d = d->db_next) { 177 if ((fsz = elf_fsize(d->db_data.d_type, 178 1, ver)) == 0) 179 return (0); 180 181 j = _elf_msize(d->db_data.d_type, ver); 182 fsz *= (d->db_data.d_size / j); 183 d->db_osz = (size_t)fsz; 184 if ((j = d->db_data.d_align) > 1) { 185 if (j > sh->sh_addralign) 186 sh->sh_addralign = (Xword)j; 187 188 if (sz % j != 0) 189 sz += j - sz % j; 190 } 191 d->db_data.d_off = (off_t)sz; 192 d->db_xoff = sz; 193 sz += (Xword)fsz; 194 } 195 196 sh->sh_size = sz; 197 /* 198 * We want to take into account the offsets for NOBITS 199 * sections and let the "sh_offsets" point to where 200 * the section would 'conceptually' fit within 201 * the file (as required by the ABI). 202 * 203 * But - we must also make sure that the NOBITS does 204 * not take up any actual space in the file. We preserve 205 * the actual offset into the file in the 'hibit' variable. 206 * When we come to the first non-NOBITS section after a 207 * encountering a NOBITS section the hi counter is restored 208 * to its proper place in the file. 209 */ 210 if (sh->sh_type == SHT_NOBITS) { 211 if (hibit == 0) 212 hibit = hi; 213 } else { 214 if (hibit) { 215 hi = hibit; 216 hibit = 0; 217 } 218 } 219 j = sh->sh_addralign; 220 if ((fsz = hi % j) != 0) 221 hi += j - fsz; 222 223 /* LINTED */ 224 sh->sh_offset = (Off)hi; 225 hi += sz; 226 } 227 228 /* 229 * if last section was a 'NOBITS' section then we need to 230 * restore the 'hi' counter to point to the end of the last 231 * non 'NOBITS' section. 232 */ 233 if (hibit) { 234 hi = hibit; 235 hibit = 0; 236 } 237 238 /* 239 * Shdr table last 240 */ 241 if (scncnt != 0) { 242 if (hi % FSZ_LONG != 0) 243 hi += FSZ_LONG - hi % FSZ_LONG; 244 /* LINTED */ 245 eh->e_shoff = (Off)hi; 246 /* 247 * If we are using 'extended sections' then the 248 * e_shnum is stored in the sh_size field of the 249 * first section header. 250 * 251 * NOTE: we set e_shnum to '0' because it's specified 252 * this way in the gABI, and in the hopes that 253 * this will cause less problems to unaware 254 * tools then if we'd set it to SHN_XINDEX (0xffff). 255 */ 256 if (scncnt < SHN_LORESERVE) 257 eh->e_shnum = scncnt; 258 else { 259 Shdr *sh; 260 sh = (Shdr *)elf->ed_hdscn->s_shdr; 261 sh->sh_size = scncnt; 262 eh->e_shnum = 0; 263 } 264 /* LINTED */ 265 eh->e_shentsize = (Half)elf_fsize(ELF_T_SHDR, 1, ver); 266 hi += eh->e_shentsize * scncnt; 267 } else { 268 eh->e_shoff = 0; 269 eh->e_shentsize = 0; 270 } 271 272 #if !(defined(_LP64) && defined(_ELF64)) 273 if (hi > INT_MAX) { 274 _elf_seterr(EFMT_FBIG, 0); 275 return (0); 276 } 277 #endif 278 279 return ((size_t)hi); 280 } 281 282 283 284 static size_t 285 _elf_upd_usr(Elf * elf) 286 { 287 NOTE(ASSUMING_PROTECTED(*elf)) 288 Lword hi; 289 Elf_Scn * s; 290 register Xword sz; 291 Ehdr * eh = elf->ed_ehdr; 292 unsigned ver = eh->e_version; 293 register char *p = (char *)eh->e_ident; 294 295 296 /* 297 * Ehdr and Phdr table go first 298 */ 299 p[EI_MAG0] = ELFMAG0; 300 p[EI_MAG1] = ELFMAG1; 301 p[EI_MAG2] = ELFMAG2; 302 p[EI_MAG3] = ELFMAG3; 303 p[EI_CLASS] = ELFCLASS; 304 /* LINTED */ 305 p[EI_VERSION] = (Byte)ver; 306 hi = elf_fsize(ELF_T_EHDR, 1, ver); 307 /* LINTED */ 308 eh->e_ehsize = (Half)hi; 309 310 /* 311 * If phnum is zero, phoff "should" be zero too, 312 * but the application is responsible for it. 313 * Allow a non-zero value here and update the 314 * hi water mark accordingly. 315 */ 316 317 if (eh->e_phnum != 0) 318 /* LINTED */ 319 eh->e_phentsize = (Half)elf_fsize(ELF_T_PHDR, 1, ver); 320 else 321 eh->e_phentsize = 0; 322 if ((sz = eh->e_phoff + eh->e_phentsize * eh->e_phnum) > hi) 323 hi = sz; 324 325 /* 326 * Loop through sections, skipping index zero. 327 * Compute section size before changing hi. 328 * Allow null buffers for NOBITS. 329 */ 330 331 if ((s = elf->ed_hdscn) == 0) 332 eh->e_shnum = 0; 333 else { 334 eh->e_shnum = 1; 335 *(Shdr*)s->s_shdr = _elf_snode_init.sb_shdr; 336 s = s->s_next; 337 } 338 for (; s != 0; s = s->s_next) { 339 register Dnode *d; 340 register Xword fsz, j; 341 Shdr *sh = s->s_shdr; 342 343 if ((s->s_myflags & SF_READY) == 0) 344 (void) _elfxx_cookscn(s); 345 346 ++eh->e_shnum; 347 sz = 0; 348 for (d = s->s_hdnode; d != 0; d = d->db_next) { 349 if ((fsz = (Xword)elf_fsize(d->db_data.d_type, 1, 350 ver)) == 0) 351 return (0); 352 j = (Xword)_elf_msize(d->db_data.d_type, ver); 353 fsz *= (Xword)(d->db_data.d_size / j); 354 d->db_osz = (size_t)fsz; 355 356 if ((sh->sh_type != SHT_NOBITS) && 357 ((j = (Xword)(d->db_data.d_off + d->db_osz)) > sz)) 358 sz = j; 359 } 360 if (sh->sh_size < sz) { 361 _elf_seterr(EFMT_SCNSZ, 0); 362 return (0); 363 } 364 if ((sh->sh_type != SHT_NOBITS) && 365 (hi < sh->sh_offset + sh->sh_size)) 366 hi = sh->sh_offset + sh->sh_size; 367 } 368 369 /* 370 * Shdr table last. Comment above for phnum/phoff applies here. 371 */ 372 if (eh->e_shnum != 0) 373 /* LINTED */ 374 eh->e_shentsize = (Half)elf_fsize(ELF_T_SHDR, 1, ver); 375 else 376 eh->e_shentsize = 0; 377 378 if ((sz = eh->e_shoff + eh->e_shentsize * eh->e_shnum) > hi) 379 hi = sz; 380 381 #if !(defined(_LP64) && defined(_ELF64)) 382 if (hi > INT_MAX) { 383 _elf_seterr(EFMT_FBIG, 0); 384 return (0); 385 } 386 #endif 387 388 return ((size_t)hi); 389 } 390 391 392 static size_t 393 wrt(Elf * elf, Xword outsz, unsigned fill, int update_cmd) 394 { 395 NOTE(ASSUMING_PROTECTED(*elf)) 396 Elf_Data dst, src; 397 unsigned flag; 398 Xword hi, sz; 399 char *image; 400 Elf_Scn *s; 401 Ehdr *eh = elf->ed_ehdr; 402 unsigned ver = eh->e_version; 403 unsigned encode = eh->e_ident[EI_DATA]; 404 int byte; 405 406 /* 407 * Two issues can cause trouble for the output file. 408 * First, begin() with ELF_C_RDWR opens a file for both 409 * read and write. On the write update(), the library 410 * has to read everything it needs before truncating 411 * the file. Second, using mmap for both read and write 412 * is too tricky. Consequently, the library disables mmap 413 * on the read side. Using mmap for the output saves swap 414 * space, because that mapping is SHARED, not PRIVATE. 415 * 416 * If the file is write-only, there can be nothing of 417 * interest to bother with. 418 * 419 * The following reads the entire file, which might be 420 * more than necessary. Better safe than sorry. 421 */ 422 423 if ((elf->ed_myflags & EDF_READ) && 424 (_elf_vm(elf, (size_t)0, elf->ed_fsz) != OK_YES)) 425 return (0); 426 427 flag = elf->ed_myflags & EDF_WRALLOC; 428 if ((image = _elf_outmap(elf->ed_fd, outsz, &flag)) == 0) 429 return (0); 430 431 if (flag == 0) 432 elf->ed_myflags |= EDF_IMALLOC; 433 434 /* 435 * If an error occurs below, a "dirty" bit may be cleared 436 * improperly. To save a second pass through the file, 437 * this code sets the dirty bit on the elf descriptor 438 * when an error happens, assuming that will "cover" any 439 * accidents. 440 */ 441 442 /* 443 * Hi is needed only when 'fill' is non-zero. 444 * Fill is non-zero only when the library 445 * calculates file/section/data buffer offsets. 446 * The lib guarantees they increase monotonically. 447 * That guarantees proper filling below. 448 */ 449 450 451 /* 452 * Ehdr first 453 */ 454 455 src.d_buf = (Elf_Void *)eh; 456 src.d_type = ELF_T_EHDR; 457 src.d_size = sizeof (Ehdr); 458 src.d_version = EV_CURRENT; 459 dst.d_buf = (Elf_Void *)image; 460 dst.d_size = eh->e_ehsize; 461 dst.d_version = ver; 462 if (elf_xlatetof(&dst, &src, encode) == 0) 463 return (0); 464 elf->ed_ehflags &= ~ELF_F_DIRTY; 465 hi = eh->e_ehsize; 466 467 /* 468 * Phdr table if one exists 469 */ 470 471 if (eh->e_phnum != 0) { 472 unsigned work; 473 /* 474 * Unlike other library data, phdr table is 475 * in the user version. Change src buffer 476 * version here, fix it after translation. 477 */ 478 479 src.d_buf = (Elf_Void *)elf->ed_phdr; 480 src.d_type = ELF_T_PHDR; 481 src.d_size = elf->ed_phdrsz; 482 ELFACCESSDATA(work, _elf_work) 483 src.d_version = work; 484 dst.d_buf = (Elf_Void *)(image + eh->e_phoff); 485 dst.d_size = eh->e_phnum * eh->e_phentsize; 486 hi = (Xword)(eh->e_phoff + dst.d_size); 487 if (elf_xlatetof(&dst, &src, encode) == 0) { 488 elf->ed_uflags |= ELF_F_DIRTY; 489 return (0); 490 } 491 elf->ed_phflags &= ~ELF_F_DIRTY; 492 src.d_version = EV_CURRENT; 493 } 494 495 /* 496 * Loop through sections 497 */ 498 499 ELFACCESSDATA(byte, _elf_byte); 500 for (s = elf->ed_hdscn; s != 0; s = s->s_next) { 501 register Dnode *d, *prevd; 502 Xword off = 0; 503 Shdr *sh = s->s_shdr; 504 char *start = image + sh->sh_offset; 505 char *here; 506 507 /* 508 * Just "clean" DIRTY flag for "empty" sections. Even if 509 * NOBITS needs padding, the next thing in the 510 * file will provide it. (And if this NOBITS is 511 * the last thing in the file, no padding needed.) 512 */ 513 if ((sh->sh_type == SHT_NOBITS) || 514 (sh->sh_type == SHT_NULL)) { 515 d = s->s_hdnode, prevd = 0; 516 for (; d != 0; prevd = d, d = d->db_next) 517 d->db_uflags &= ~ELF_F_DIRTY; 518 continue; 519 } 520 /* 521 * Clear out the memory between the end of the last 522 * section and the begining of this section. 523 */ 524 if (fill && (sh->sh_offset > hi)) { 525 sz = sh->sh_offset - hi; 526 (void) memset(start - sz, byte, sz); 527 } 528 529 530 for (d = s->s_hdnode, prevd = 0; 531 d != 0; prevd = d, d = d->db_next) { 532 d->db_uflags &= ~ELF_F_DIRTY; 533 here = start + d->db_data.d_off; 534 535 /* 536 * Clear out the memory between the end of the 537 * last update and the start of this data buffer. 538 */ 539 if (fill && (d->db_data.d_off > off)) { 540 sz = (Xword)(d->db_data.d_off - off); 541 (void) memset(here - sz, byte, sz); 542 } 543 544 if ((d->db_myflags & DBF_READY) == 0) { 545 SCNLOCK(s); 546 if (_elf_locked_getdata(s, &prevd->db_data) != 547 &d->db_data) { 548 elf->ed_uflags |= ELF_F_DIRTY; 549 SCNUNLOCK(s); 550 return (0); 551 } 552 SCNUNLOCK(s); 553 } 554 dst.d_buf = (Elf_Void *)here; 555 dst.d_size = d->db_osz; 556 557 /* 558 * Copy the translated bits out to the destination 559 * image. 560 */ 561 if (elf_xlatetof(&dst, &d->db_data, encode) == 0) { 562 elf->ed_uflags |= ELF_F_DIRTY; 563 return (0); 564 } 565 566 off = (Xword)(d->db_data.d_off + dst.d_size); 567 } 568 hi = sh->sh_offset + sh->sh_size; 569 } 570 571 /* 572 * Shdr table last 573 */ 574 575 if (fill && (eh->e_shoff > hi)) { 576 sz = eh->e_shoff - hi; 577 (void) memset(image + hi, byte, sz); 578 } 579 580 src.d_type = ELF_T_SHDR; 581 src.d_size = sizeof (Shdr); 582 dst.d_buf = (Elf_Void *)(image + eh->e_shoff); 583 dst.d_size = eh->e_shentsize; 584 for (s = elf->ed_hdscn; s != 0; s = s->s_next) { 585 assert((uintptr_t)dst.d_buf < ((uintptr_t)image + outsz)); 586 s->s_shflags &= ~ELF_F_DIRTY; 587 s->s_uflags &= ~ELF_F_DIRTY; 588 src.d_buf = s->s_shdr; 589 590 if (elf_xlatetof(&dst, &src, encode) == 0) { 591 elf->ed_uflags |= ELF_F_DIRTY; 592 return (0); 593 } 594 595 dst.d_buf = (char *)dst.d_buf + eh->e_shentsize; 596 } 597 /* 598 * ELF_C_WRIMAGE signifyes that we build the memory image, but 599 * that we do not actually write it to disk. This is used 600 * by ld(1) to build up a full image of an elf file and then 601 * to process the file before it's actually written out to 602 * disk. This saves ld(1) the overhead of having to write 603 * the image out to disk twice. 604 */ 605 if (update_cmd == ELF_C_WRIMAGE) { 606 elf->ed_uflags &= ~ELF_F_DIRTY; 607 elf->ed_wrimage = image; 608 elf->ed_wrimagesz = outsz; 609 return (outsz); 610 } 611 612 if (_elf_outsync(elf->ed_fd, image, outsz, 613 ((elf->ed_myflags & EDF_IMALLOC) ? 0 : 1)) != 0) { 614 elf->ed_uflags &= ~ELF_F_DIRTY; 615 elf->ed_myflags &= ~EDF_IMALLOC; 616 return (outsz); 617 } 618 619 elf->ed_uflags |= ELF_F_DIRTY; 620 return (0); 621 } 622 623 624 625 626 /* 627 * The following is a private interface between the linkers (ld & ld.so.1) 628 * and libelf: 629 * 630 * elf_update(elf, ELF_C_WRIMAGE) 631 * This will cause full image representing the elf file 632 * described by the elf pointer to be built in memory. If the 633 * elf pointer has a valid file descriptor associated with it 634 * we will attempt to build the memory image from mmap()'ed 635 * storage. If the elf descriptor does not have a valid 636 * file descriptor (opened with elf_begin(0, ELF_C_IMAGE, 0)) 637 * then the image will be allocated from dynamic memory (malloc()). 638 * 639 * elf_update() will return the size of the memory image built 640 * when sucessful. 641 * 642 * When a subsequent call to elf_update() with ELF_C_WRITE as 643 * the command is performed it will sync the image created 644 * by ELF_C_WRIMAGE to disk (if fd available) and 645 * free the memory allocated. 646 */ 647 648 off_t 649 _elfxx_update(Elf * elf, Elf_Cmd cmd) 650 { 651 size_t sz; 652 unsigned u; 653 Ehdr *eh = elf->ed_ehdr; 654 655 if (elf == 0) 656 return (-1); 657 658 ELFWLOCK(elf) 659 switch (cmd) { 660 default: 661 _elf_seterr(EREQ_UPDATE, 0); 662 ELFUNLOCK(elf) 663 return (-1); 664 665 case ELF_C_WRIMAGE: 666 if ((elf->ed_myflags & EDF_WRITE) == 0) { 667 _elf_seterr(EREQ_UPDWRT, 0); 668 ELFUNLOCK(elf) 669 return (-1); 670 } 671 break; 672 case ELF_C_WRITE: 673 if ((elf->ed_myflags & EDF_WRITE) == 0) { 674 _elf_seterr(EREQ_UPDWRT, 0); 675 ELFUNLOCK(elf) 676 return (-1); 677 } 678 if (elf->ed_wrimage) { 679 if (elf->ed_myflags & EDF_WRALLOC) { 680 free(elf->ed_wrimage); 681 /* 682 * The size is still returned even 683 * though nothing is actually written 684 * out. This is just to be consistant 685 * with the rest of the interface. 686 */ 687 sz = elf->ed_wrimagesz; 688 elf->ed_wrimage = 0; 689 elf->ed_wrimagesz = 0; 690 ELFUNLOCK(elf); 691 return ((off_t)sz); 692 } 693 sz = _elf_outsync(elf->ed_fd, elf->ed_wrimage, 694 elf->ed_wrimagesz, 695 (elf->ed_myflags & EDF_IMALLOC ? 0 : 1)); 696 elf->ed_myflags &= ~EDF_IMALLOC; 697 elf->ed_wrimage = 0; 698 elf->ed_wrimagesz = 0; 699 ELFUNLOCK(elf); 700 return ((off_t)sz); 701 } 702 /* FALLTHROUGH */ 703 case ELF_C_NULL: 704 break; 705 } 706 707 if (eh == 0) { 708 _elf_seterr(ESEQ_EHDR, 0); 709 ELFUNLOCK(elf) 710 return (-1); 711 } 712 713 if ((u = eh->e_version) > EV_CURRENT) { 714 _elf_seterr(EREQ_VER, 0); 715 ELFUNLOCK(elf) 716 return (-1); 717 } 718 719 if (u == EV_NONE) 720 eh->e_version = EV_CURRENT; 721 722 if ((u = eh->e_ident[EI_DATA]) == ELFDATANONE) { 723 unsigned encode; 724 725 ELFACCESSDATA(encode, _elf_encode) 726 if (encode == ELFDATANONE) { 727 _elf_seterr(EREQ_ENCODE, 0); 728 ELFUNLOCK(elf) 729 return (-1); 730 } 731 /* LINTED */ 732 eh->e_ident[EI_DATA] = (Byte)encode; 733 } 734 735 u = 1; 736 if (elf->ed_uflags & ELF_F_LAYOUT) { 737 sz = _elf_upd_usr(elf); 738 u = 0; 739 } else 740 sz = _elf_upd_lib(elf); 741 742 if ((sz != 0) && ((cmd == ELF_C_WRITE) || (cmd == ELF_C_WRIMAGE))) 743 sz = wrt(elf, (Xword)sz, u, cmd); 744 745 if (sz == 0) { 746 ELFUNLOCK(elf) 747 return (-1); 748 } 749 750 ELFUNLOCK(elf) 751 return ((off_t)sz); 752 } 753 754 755 #ifndef _ELF64 756 /* class-independent, only needs to be compiled once */ 757 758 off_t 759 elf_update(Elf *elf, Elf_Cmd cmd) 760 { 761 if (elf == 0) 762 return (-1); 763 764 if (elf->ed_class == ELFCLASS32) 765 return (_elf32_update(elf, cmd)); 766 else if (elf->ed_class == ELFCLASS64) { 767 return (_elf64_update(elf, cmd)); 768 } 769 770 _elf_seterr(EREQ_CLASS, 0); 771 return (-1); 772 } 773 774 /* 775 * 4106312, 4106398, This is an ad-hoc means for the 32-bit 776 * Elf64 version of libld.so.3 to get around the limitation 777 * of a 32-bit d_off field. This is only intended to be 778 * used by libld to relocate symbols in large NOBITS sections. 779 */ 780 Elf64_Off 781 _elf_getxoff(Elf_Data * d) 782 { 783 return (((Dnode *)d)->db_xoff); 784 } 785 #endif /* !_ELF64 */ 786