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