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) 1995, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2022 Oxide Computer Company 25 */ 26 27 /* 28 * Copyright (c) 1988 AT&T 29 * All Rights Reserved 30 * 31 */ 32 33 #include <sys/sendfile.h> 34 #include "inc.h" 35 #include "gelf.h" 36 37 /* 38 * List of archive members, accessed globally by cmd and file. 39 */ 40 ARFILE *listhead, *listend; 41 42 /* 43 * Type used to manage string tables. Archives can have two of these: 44 * 45 * sym_strtbl: String table included at the end of the symbol table 46 * archive member, following the offset array. 47 * 48 * long_strtbl: String table used to hold member names that exceed 15 49 * characters in length, found in the long names archive member. 50 */ 51 typedef struct { 52 char *base; /* Base of string table memory */ 53 size_t used; /* # bytes used from allocation */ 54 size_t size; /* Size of allocation */ 55 } ARSTRTBL; 56 57 static ARSTRTBL sym_strtbl; 58 static ARSTRTBL long_strtbl; 59 60 61 /* 62 * Name and file descriptor used when creating a new archive. 63 * If this variable references an open file when exit_cleanup() 64 * executes, it will close and remove the file, preventing incomplete 65 * temporary files from being left behind in the case of a failure 66 * or interruption. 67 */ 68 static struct { 69 int fd; /* -1, or open file descriptor */ 70 const char *path; /* Path to open file */ 71 } ar_outfile; 72 73 /* 74 * The ar file format requires objects to be padded to an even size. 75 * We do that, but it turns out to be beneficial to go farther. 76 * 77 * ld(1) accesses archives by mmapping them into memory. If the mapped 78 * objects (member data) have the proper alignment, we can access them 79 * directly. If the data alignment is wrong, libelf "slides" them over the 80 * archive header to correct the misalignment. This is expensive in time 81 * (to copy memory) and space (it causes swap to be allocated by the system 82 * to back the now-modified pages). Hence, we really want to ensure that 83 * the alignment is right. 84 * 85 * We used to align 32-bit objects at 4-byte boundaries, and 64-bit objects 86 * at 8-byte. More recently, an elf section type has appeared that has 87 * 8-byte alignment requirements (SUNW_move) even in 32-bit objects. So, 88 * the current strategy is to align all objects to 8-bytes. 89 * 90 * There are two important things to consider when setting this value: 91 * 1) If a new elf section that ld(1) accesses in memory appears 92 * with a greater than 8-byte alignment requirement, this value 93 * will need to be raised. Or, alternatively, the entire approach may 94 * need reconsideration. 95 * 2) The size of this padding must be smaller than the size of the 96 * smallest possible ELF section. Otherwise, the logic contained 97 * in recover_padding() can be tricked. 98 */ 99 #define PADSZ 8 100 101 /* 102 * Forward Declarations 103 */ 104 static void arwrite(const char *, int, const char *, size_t); 105 static size_t mklong_tab(); 106 static size_t mksymtab(const char *, ARFILEP **, int *); 107 static const char *make_tmpname(const char *); 108 static size_t sizeof_symtbl(size_t, int, size_t); 109 static void savelongname(ARFILE *); 110 static void savename(char *); 111 static int search_sym_tab(const char *, ARFILE *, Elf *, 112 Elf_Scn *, size_t *, ARFILEP **, size_t *); 113 static size_t sizeofmembers(size_t); 114 static char *sputl32(uint32_t, char *); 115 static char *sputl64(uint64_t, char *); 116 static void strtbl_pad(ARSTRTBL *, size_t, int); 117 static char *trimslash(char *s); 118 static void writesymtab(const char *, int fd, size_t, ARFILEP *, 119 size_t); 120 121 122 /* 123 * Function to be called on exit to clean up incomplete new archive. 124 */ 125 static void 126 exit_cleanup(void) 127 { 128 if (ar_outfile.fd != -1) { 129 /* Both of these system calls are Async-Signal-Safe */ 130 (void) close(ar_outfile.fd); 131 (void) unlink(ar_outfile.path); 132 } 133 } 134 135 /* 136 * Open an existing archive. 137 */ 138 int 139 getaf(Cmd_info *cmd_info) 140 { 141 Elf_Cmd cmd; 142 int fd; 143 char *arnam = cmd_info->arnam; 144 145 if (elf_version(EV_CURRENT) == EV_NONE) { 146 (void) fprintf(stderr, MSG_INTL(MSG_ELF_VERSION), 147 elf_errmsg(-1)); 148 exit(1); 149 } 150 151 if ((cmd_info->afd = fd = open(arnam, O_RDONLY)) == -1) { 152 int err = errno; 153 154 if (err == ENOENT) { 155 /* archive does not exist yet, may have to create one */ 156 return (fd); 157 } else { 158 /* problem other than "does not exist" */ 159 (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), 160 arnam, strerror(err)); 161 exit(1); 162 } 163 } 164 165 cmd = ELF_C_READ; 166 cmd_info->arf = elf_begin(fd, cmd, (Elf *)0); 167 168 if (elf_kind(cmd_info->arf) != ELF_K_AR) { 169 (void) fprintf(stderr, MSG_INTL(MSG_NOT_ARCHIVE), arnam); 170 if (cmd_info->opt_flgs & (a_FLAG | b_FLAG)) 171 (void) fprintf(stderr, MSG_INTL(MSG_USAGE_POSNAME), 172 cmd_info->ponam); 173 exit(1); 174 } 175 return (fd); 176 } 177 178 /* 179 * Given a value, and a pad alignment, return the number of bytes 180 * required to pad the value to the next alignment boundary. 181 */ 182 static size_t 183 pad(size_t n, size_t align) 184 { 185 size_t r; 186 187 r = n % align; 188 if (r) 189 r = align - r; 190 191 return (r); 192 } 193 194 /* 195 * If the current archive item is an ELF object, then ar(1) may have added 196 * newline padding at the end in order to bring the following object 197 * into PADSZ alignment within the file. This padding cannot be 198 * distinguished from data using the information kept in the member header. 199 * This routine examines the objects, using knowledge of 200 * ELF and how our tools lay out objects to determine whether padding was 201 * added to an archive item. If so, it adjusts the st_size and 202 * st_padding fields of the file argument to reflect it. 203 */ 204 static void 205 recover_padding(Elf *elf, ARFILE *file) 206 { 207 size_t extent; 208 size_t padding; 209 size_t shnum; 210 GElf_Ehdr ehdr; 211 212 213 /* ar(1) only pads objects, so bail if not looking at one */ 214 if (gelf_getclass(elf) == ELFCLASSNONE) 215 return; 216 217 /* 218 * libelf always puts the section header array at the end 219 * of the object, and all of our compilers and other tools 220 * use libelf or follow this convention. So, it is extremely 221 * likely that the section header array is at the end of this 222 * object: Find the address at the end of the array and compare 223 * it to the archive ar_size. If they are within PADSZ bytes, then 224 * we've found the end, and the difference is padding (We assume 225 * that no ELF section can fit into PADSZ bytes). 226 */ 227 if (elf_getshdrnum(elf, &shnum) == -1) 228 return; 229 230 extent = gelf_getehdr(elf, &ehdr) 231 ? (ehdr.e_shoff + (shnum * ehdr.e_shentsize)) : 0; 232 233 /* 234 * If the extent exceeds the end of the archive member 235 * (negative padding), then we don't know what is going on 236 * and simply leave things alone. 237 */ 238 if (extent > file->ar_size) 239 return; 240 241 padding = file->ar_size - extent; 242 if (padding >= PADSZ) { 243 /* 244 * The section header array is not at the end of the object. 245 * Traverse the section headers and look for the one with 246 * the highest used address. If this address is within 247 * PADSZ bytes of ar_size, then this is the end of the object. 248 */ 249 Elf_Scn *scn = NULL; 250 251 do { 252 scn = elf_nextscn(elf, scn); 253 if (scn) { 254 GElf_Shdr shdr; 255 256 if (gelf_getshdr(scn, &shdr)) { 257 size_t t; 258 259 t = shdr.sh_offset + shdr.sh_size; 260 if (t > extent) 261 extent = t; 262 } 263 } 264 } while (scn); 265 266 if (extent > file->ar_size) 267 return; 268 padding = file->ar_size - extent; 269 } 270 271 /* 272 * Now, test the padding. We only act on padding in the range 273 * (0 < pad < PADSZ) (ar(1) will never add more than this). A pad 274 * of 0 requires no action, and any other size above (PADSZ-1) means 275 * that we don't understand the layout of this object, and as such, 276 * cannot do anything. 277 * 278 * If the padding is in range, and the raw data for the 279 * object is available, then we perform one additional sanity 280 * check before moving forward: ar(1) always pads with newline 281 * characters. If anything else is seen, it is not padding so 282 * leave it alone. 283 */ 284 if (padding < PADSZ) { 285 if (file->ar_contents) { 286 size_t cnt = padding; 287 char *p = file->ar_contents + extent; 288 289 while (cnt--) { 290 if (*p++ != '\n') { /* No padding */ 291 padding = 0; 292 break; 293 } 294 } 295 } 296 297 /* Remove the padding from the size */ 298 file->ar_size -= padding; 299 file->ar_padding = padding; 300 } 301 } 302 303 /* 304 * Each call to getfile() returns the next unread archive member 305 * from the archive opened by getaf(). Returns NULL if no more 306 * archive members are left. 307 */ 308 ARFILE * 309 getfile(Cmd_info *cmd_info) 310 { 311 Elf_Arhdr *mem_header = NULL; 312 ARFILE *file; 313 char *tmp_rawname, *file_rawname; 314 Elf *elf; 315 char *arnam = cmd_info->arnam; 316 int fd = cmd_info->afd; 317 Elf *arf = cmd_info->arf; 318 319 if (fd == -1) 320 return (NULL); /* the archive doesn't exist */ 321 322 while (mem_header == NULL) { 323 if ((elf = elf_begin(fd, ELF_C_READ, arf)) == 0) 324 return (NULL); /* archive is empty or have hit end */ 325 326 if ((mem_header = elf_getarhdr(elf)) == NULL) { 327 (void) fprintf(stderr, MSG_INTL(MSG_ELF_MALARCHIVE), 328 arnam, EC_XWORD(elf_getbase(elf)), elf_errmsg(-1)); 329 exit(1); 330 } 331 332 /* Ignore special members like the symbol and string tables */ 333 if (mem_header->ar_name[0] == '/') { 334 (void) elf_next(elf); 335 (void) elf_end(elf); 336 mem_header = NULL; 337 } 338 } 339 340 /* 341 * NOTE: 342 * The mem_header->ar_name[] is set to a NULL string 343 * if the archive member header has some error. 344 * (See elf_getarhdr() man page.) 345 * It is set to NULL for example, the ar command reads 346 * the archive files created by SunOS 4.1 system. 347 * See c block comment in cmd.c, "Incompatible Archive Header". 348 */ 349 file = newfile(); 350 (void) strncpy(file->ar_name, mem_header->ar_name, SNAME); 351 352 if ((file->ar_longname = malloc(strlen(mem_header->ar_name) + 1)) 353 == NULL) { 354 int err = errno; 355 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(err)); 356 exit(1); 357 } 358 (void) strcpy(file->ar_longname, mem_header->ar_name); 359 if ((file->ar_rawname = malloc(strlen(mem_header->ar_rawname) + 1)) 360 == NULL) { 361 int err = errno; 362 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(err)); 363 exit(1); 364 } 365 tmp_rawname = mem_header->ar_rawname; 366 file_rawname = file->ar_rawname; 367 while (!isspace(*tmp_rawname) && 368 ((*file_rawname = *tmp_rawname) != '\0')) { 369 file_rawname++; 370 tmp_rawname++; 371 } 372 if (!(*tmp_rawname == '\0')) 373 *file_rawname = '\0'; 374 375 file->ar_date = mem_header->ar_date; 376 file->ar_uid = mem_header->ar_uid; 377 file->ar_gid = mem_header->ar_gid; 378 file->ar_mode = (unsigned long) mem_header->ar_mode; 379 file->ar_size = mem_header->ar_size; 380 381 /* reverse logic */ 382 if ((cmd_info->opt_flgs & (t_FLAG | s_FLAG)) != t_FLAG) { 383 size_t ptr; 384 file->ar_flag = F_ELFRAW; 385 if ((file->ar_contents = elf_rawfile(elf, &ptr)) 386 == NULL) { 387 if (ptr != 0) { 388 (void) fprintf(stderr, 389 MSG_INTL(MSG_ELF_RAWFILE), elf_errmsg(-1)); 390 exit(1); 391 } 392 } 393 file->ar_elf = elf; 394 } 395 396 recover_padding(elf, file); 397 398 (void) elf_next(elf); 399 return (file); 400 } 401 402 /* 403 * Allocate a new archive member descriptor and add it to the list. 404 */ 405 ARFILE * 406 newfile(void) 407 { 408 static ARFILE *buffer = NULL; 409 static size_t count = 0; 410 ARFILE *fileptr; 411 412 if (count == 0) { 413 if ((buffer = (ARFILE *) calloc(CHUNK, sizeof (ARFILE))) 414 == NULL) { 415 int err = errno; 416 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC), 417 strerror(err)); 418 exit(1); 419 } 420 count = CHUNK; 421 } 422 count--; 423 fileptr = buffer++; 424 425 if (listhead) 426 listend->ar_next = fileptr; 427 else 428 listhead = fileptr; 429 listend = fileptr; 430 return (fileptr); 431 } 432 433 static char * 434 trimslash(char *s) 435 { 436 static char buf[SNAME]; 437 438 (void) strncpy(buf, trim(s), SNAME - 2); 439 buf[SNAME - 2] = '\0'; 440 return (strcat(buf, MSG_ORIG(MSG_STR_SLASH))); 441 } 442 443 char * 444 trim(char *s) 445 { 446 char *p1, *p2; 447 448 for (p1 = s; *p1; p1++) 449 ; 450 while (p1 > s) { 451 if (*--p1 != '/') 452 break; 453 *p1 = 0; 454 } 455 p2 = s; 456 for (p1 = s; *p1; p1++) 457 if (*p1 == '/') 458 p2 = p1 + 1; 459 return (p2); 460 } 461 462 463 /* 464 * Find all the global symbols exported by ELF archive members, and 465 * build a list associating each one with the archive member that 466 * provides it. 467 * 468 * exit: 469 * *symlist is set to the list of symbols. If any ELF object was 470 * found, *found_obj is set to TRUE (1). Returns the number of symbols 471 * located. 472 */ 473 static size_t 474 mksymtab(const char *arname, ARFILEP **symlist, int *found_obj) 475 { 476 ARFILE *fptr; 477 size_t mem_offset = 0; 478 Elf *elf; 479 Elf_Scn *scn; 480 GElf_Ehdr ehdr; 481 int newfd; 482 size_t nsyms = 0; 483 int class = 0; 484 Elf_Data *data; 485 size_t num_errs = 0; 486 487 newfd = 0; 488 for (fptr = listhead; fptr; fptr = fptr->ar_next) { 489 /* determine if file is coming from the archive or not */ 490 if ((fptr->ar_elf != NULL) && (fptr->ar_pathname == NULL)) { 491 /* 492 * I can use the saved elf descriptor. 493 */ 494 elf = fptr->ar_elf; 495 } else if ((fptr->ar_elf == NULL) && 496 (fptr->ar_pathname != NULL)) { 497 #ifdef _LP64 498 /* 499 * The archive member header ar_size field is 10 500 * decimal digits, sufficient to represent a 32-bit 501 * value, but not a 64-bit one. Hence, we reject 502 * attempts to insert a member larger than 4GB. 503 * 504 * One obvious way to extend the format without altering 505 * the ar_hdr struct is to use the same mechanism used 506 * for ar_name: Put the size string into the long name 507 * string table and write a string /xxx into ar_size, 508 * where xxx is the string table offset. 509 * 510 * At the time of this writing (June 2010), the largest 511 * relocatable objects are measured in 10s or 100s 512 * of megabytes, so we still have many years to go 513 * before this becomes limiting. By that time, it may 514 * turn out that a completely new archive format is 515 * a better solution, as the current format has many 516 * warts and inefficiencies. In the meantime, we 517 * won't burden the current implementation with support 518 * for a bandaid feature that will have little use. 519 */ 520 if (fptr->ar_size > 0xffffffff) { 521 (void) fprintf(stderr, 522 MSG_INTL(MSG_ERR_MEMBER4G), 523 fptr->ar_pathname); 524 num_errs++; 525 continue; 526 } 527 #endif 528 if ((newfd = 529 open(fptr->ar_pathname, O_RDONLY)) == -1) { 530 int err = errno; 531 (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), 532 fptr->ar_pathname, strerror(err)); 533 num_errs++; 534 continue; 535 } 536 537 if ((elf = elf_begin(newfd, 538 ELF_C_READ, (Elf *)0)) == 0) { 539 (void) fprintf(stderr, 540 MSG_INTL(MSG_ELF_BEGIN_FILE), 541 fptr->ar_pathname, elf_errmsg(-1)); 542 (void) close(newfd); 543 newfd = 0; 544 num_errs++; 545 continue; 546 } 547 if (elf_kind(elf) == ELF_K_AR) { 548 if (newfd) { 549 (void) close(newfd); 550 newfd = 0; 551 } 552 (void) elf_end(elf); 553 continue; 554 } 555 } else { 556 (void) fprintf(stderr, MSG_INTL(MSG_INTERNAL_01)); 557 exit(1); 558 } 559 if (gelf_getehdr(elf, &ehdr) != 0) { 560 size_t shstrndx = 0; 561 if ((class = gelf_getclass(elf)) == ELFCLASS64) { 562 fptr->ar_flag |= F_CLASS64; 563 } else if (class == ELFCLASS32) 564 fptr->ar_flag |= F_CLASS32; 565 566 if (elf_getshdrstrndx(elf, &shstrndx) == -1) { 567 if (fptr->ar_pathname != NULL) { 568 (void) fprintf(stderr, 569 MSG_INTL(MSG_ELF_GETSHSTRNDX_FILE), 570 fptr->ar_pathname, elf_errmsg(-1)); 571 } else { 572 (void) fprintf(stderr, 573 MSG_INTL(MSG_ELF_GETSHSTRNDX_AR), 574 arname, fptr->ar_longname, 575 elf_errmsg(-1)); 576 } 577 num_errs++; 578 if (newfd) { 579 (void) close(newfd); 580 newfd = 0; 581 } 582 (void) elf_end(elf); 583 continue; 584 } 585 586 scn = elf_getscn(elf, shstrndx); 587 if (scn == NULL) { 588 if (fptr->ar_pathname != NULL) 589 (void) fprintf(stderr, 590 MSG_INTL(MSG_ELF_GETSCN_FILE), 591 fptr->ar_pathname, elf_errmsg(-1)); 592 else 593 (void) fprintf(stderr, 594 MSG_INTL(MSG_ELF_GETSCN_AR), 595 arname, fptr->ar_longname, 596 elf_errmsg(-1)); 597 num_errs++; 598 if (newfd) { 599 (void) close(newfd); 600 newfd = 0; 601 } 602 (void) elf_end(elf); 603 continue; 604 } 605 606 data = 0; 607 data = elf_getdata(scn, data); 608 if (data == NULL) { 609 if (fptr->ar_pathname != NULL) 610 (void) fprintf(stderr, 611 MSG_INTL(MSG_ELF_GETDATA_FILE), 612 fptr->ar_pathname, elf_errmsg(-1)); 613 else 614 (void) fprintf(stderr, 615 MSG_INTL(MSG_ELF_GETDATA_AR), 616 arname, fptr->ar_longname, 617 elf_errmsg(-1)); 618 num_errs++; 619 if (newfd) { 620 (void) close(newfd); 621 newfd = 0; 622 } 623 (void) elf_end(elf); 624 continue; 625 } 626 if (data->d_size == 0) { 627 if (fptr->ar_pathname != NULL) 628 (void) fprintf(stderr, 629 MSG_INTL(MSG_W_ELF_NODATA_FILE), 630 fptr->ar_pathname); 631 else 632 (void) fprintf(stderr, 633 MSG_INTL(MSG_W_ELF_NODATA_AR), 634 arname, fptr->ar_longname); 635 if (newfd) { 636 (void) close(newfd); 637 newfd = 0; 638 } 639 (void) elf_end(elf); 640 num_errs++; 641 continue; 642 } 643 644 /* loop through sections to find symbol table */ 645 scn = 0; 646 while ((scn = elf_nextscn(elf, scn)) != 0) { 647 GElf_Shdr shdr; 648 if (gelf_getshdr(scn, &shdr) == NULL) { 649 /* BEGIN CSTYLED */ 650 if (fptr->ar_pathname != NULL) 651 (void) fprintf(stderr, 652 MSG_INTL(MSG_ELF_GETDATA_FILE), 653 fptr->ar_pathname, 654 elf_errmsg(-1)); 655 else 656 (void) fprintf(stderr, 657 MSG_INTL(MSG_ELF_GETDATA_AR), 658 arname, fptr->ar_longname, 659 elf_errmsg(-1)); 660 /* END CSTYLED */ 661 if (newfd) { 662 (void) close(newfd); 663 newfd = 0; 664 } 665 num_errs++; 666 (void) elf_end(elf); 667 continue; 668 } 669 *found_obj = 1; 670 if (shdr.sh_type == SHT_SYMTAB) { 671 if (search_sym_tab(arname, fptr, elf, 672 scn, &nsyms, symlist, 673 &num_errs) == -1) { 674 if (newfd) { 675 (void) close(newfd); 676 newfd = 0; 677 } 678 continue; 679 } 680 } 681 } 682 } 683 mem_offset += sizeof (struct ar_hdr) + fptr->ar_size; 684 if (fptr->ar_size & 01) 685 mem_offset++; 686 (void) elf_end(elf); 687 if (newfd) { 688 (void) close(newfd); 689 newfd = 0; 690 } 691 } 692 if (num_errs) 693 exit(1); 694 695 if (found_obj) { 696 if (nsyms == 0) { 697 /* 698 * It is possible, though rare, to have ELF objects 699 * that do not export any global symbols. Presumably 700 * such objects operate via their .init/.fini 701 * sections. In this case, we produce an empty 702 * symbol table, so that applications that rely 703 * on a successful call to elf_getarsym() to determine 704 * if ELF objects are present will succeed. To do this, 705 * we require a small empty symbol string table. 706 */ 707 strtbl_pad(&sym_strtbl, 4, '\0'); 708 } else { 709 /* 710 * Historical behavior is to pad string tables 711 * to a multiple of 4. 712 */ 713 strtbl_pad(&sym_strtbl, pad(sym_strtbl.used, 4), '\0'); 714 } 715 716 } 717 718 return (nsyms); 719 } 720 721 /* 722 * Output a member header. 723 */ 724 /*ARGSUSED*/ 725 static void 726 write_member_header(const char *filename, int fd, int is_elf, 727 const char *name, time_t timestamp, uid_t uid, gid_t gid, mode_t mode, 728 size_t size) 729 { 730 char buf[sizeof (struct ar_hdr) + 1]; 731 int len; 732 733 len = snprintf(buf, sizeof (buf), MSG_ORIG(MSG_MH_FORMAT), name, 734 EC_WORD(timestamp), EC_WORD(uid), EC_WORD(gid), EC_WORD(mode), 735 EC_XWORD(size), ARFMAG); 736 737 /* 738 * If snprintf() reports that it needed more space than we gave 739 * it, it means that the caller fed us a long name, which is a 740 * fatal internal error. 741 */ 742 if (len != sizeof (struct ar_hdr)) { 743 (void) fprintf(stderr, MSG_INTL(MSG_INTERNAL_02)); 744 exit(1); 745 } 746 747 arwrite(filename, fd, buf, len); 748 749 /* 750 * We inject inter-member padding to ensure that ELF object 751 * member data is aligned on PADSZ. If this is a debug build, 752 * verify that the computations were right. 753 */ 754 assert(!is_elf || (pad(lseek(fd, 0, SEEK_CUR), PADSZ) == 0)); 755 } 756 757 /* 758 * Write the archive symbol table member to the output archive file. 759 * 760 * note: 761 * sizeofmembers() must have been called to establish member offset 762 * and padding values before writesymtab() is used. 763 */ 764 static void 765 writesymtab(const char *filename, int fd, size_t nsyms, ARFILEP *symlist, 766 size_t eltsize) 767 { 768 size_t i, j; 769 ARFILEP *ptr; 770 size_t tblsize; 771 char *buf, *dst; 772 int is64 = (eltsize == 8); 773 774 /* 775 * We require a buffer large enough to hold a symbol table count, 776 * plus one offset for each symbol. 777 */ 778 tblsize = (nsyms + 1) * eltsize; 779 if ((buf = dst = malloc(tblsize)) == NULL) { 780 int err = errno; 781 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(err)); 782 exit(1); 783 } 784 785 write_member_header(filename, fd, 0, 786 (is64 ? MSG_ORIG(MSG_STR_SYM64) : MSG_ORIG(MSG_STR_SLASH)), 787 time(0), 0, 0, 0, tblsize + sym_strtbl.used); 788 789 dst = is64 ? sputl64(nsyms, dst) : sputl32(nsyms, dst); 790 791 for (i = 0, j = SYMCHUNK, ptr = symlist; i < nsyms; i++, j--, ptr++) { 792 if (!j) { 793 j = SYMCHUNK; 794 ptr = (ARFILEP *)*ptr; 795 } 796 dst = is64 ? sputl64((*ptr)->ar_offset, dst) : 797 sputl32((*ptr)->ar_offset, dst); 798 } 799 arwrite(filename, fd, buf, tblsize); 800 free(buf); 801 arwrite(filename, fd, sym_strtbl.base, sym_strtbl.used); 802 } 803 804 /* 805 * Grow the size of the given string table so that there is room 806 * for at least need bytes. 807 * 808 * entry: 809 * strtbl - String table to grow 810 * need - Amount of space required by caller 811 */ 812 static void 813 strtbl_alloc(ARSTRTBL *strtbl, size_t need) 814 { 815 #define STRTBL_INITSZ 8196 816 817 /* 818 * On 32-bit systems, we require a larger integer type in order 819 * to avoid overflow and wraparound when doing our computations. 820 */ 821 uint64_t need64 = need; 822 uint64_t used64 = strtbl->used; 823 uint64_t size64 = strtbl->size; 824 uint64_t target = need64 + used64; 825 826 int sys32, tbl32; 827 828 if (target <= size64) 829 return; 830 831 /* 832 * Detect 32-bit system. We might usually do this with the preprocessor, 833 * but it can serve as a predicate in tests that also apply to 64-bit 834 * systems. 835 */ 836 sys32 = (sizeof (size_t) == 4); 837 838 /* 839 * The symbol string table can be larger than 32-bits on a 64-bit 840 * system. However, the long name table must stay below that limit. 841 * The reason for this is that there is not enough room in the ar_name 842 * field of the member header to represent 64-bit offsets. 843 */ 844 tbl32 = (strtbl == &long_strtbl); 845 846 /* 847 * If request is larger than 4GB and we can't do it because we 848 * are a 32-bit program, or because the table is format limited, 849 * we can go no further. 850 */ 851 if ((target > 0xffffffff) && (sys32 || tbl32)) 852 goto limit_fail; 853 854 /* Default starting size */ 855 if (strtbl->base == NULL) 856 size64 = STRTBL_INITSZ; 857 858 /* 859 * Our strategy is to double the size until we find a size that 860 * exceeds the request. However, if this table cannot exceed 4GB, 861 * then once we exceed 2GB, we switch to a strategy of taking the 862 * current request and rounding it up to STRTBL_INITSZ. 863 */ 864 while (target > size64) { 865 if ((target > 0x7fffffff) && (sys32 || tbl32)) { 866 size64 = ((target + STRTBL_INITSZ) / STRTBL_INITSZ) * 867 STRTBL_INITSZ; 868 869 /* 870 * If we are so close to the line that this small 871 * increment exceeds 4GB, give it up. 872 */ 873 if ((size64 > 0xffffffff) && (sys32 || tbl32)) 874 goto limit_fail; 875 876 break; 877 } 878 879 size64 *= 2; 880 } 881 882 strtbl->base = realloc(strtbl->base, size64); 883 if (strtbl->base == NULL) { 884 int err = errno; 885 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(err)); 886 exit(1); 887 } 888 strtbl->size = (size_t)size64; 889 return; 890 891 limit_fail: 892 /* 893 * Control comes here if we are unable to allocate more than 4GB of 894 * memory for the string table due to one of the following reasons: 895 * 896 * - A 32-bit process is attempting to be larger than 4GB 897 * 898 * - A 64-bit process is attempting to grow the long names string 899 * table beyond the ar format limit of 32-bits. 900 */ 901 if (sys32) 902 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(ENOMEM)); 903 else 904 (void) fprintf(stderr, MSG_INTL(MSG_ERR_LONGSTRTBLSZ)); 905 exit(1); 906 907 #undef STRTBL_INITSZ 908 } 909 910 /* 911 * Add the specified number of pad characters to the end of the 912 * given string table. 913 * 914 * entry: 915 * strtbl - String table to pad 916 * n - # of pad characters to add 917 * ch - Pad character to use 918 */ 919 static void 920 strtbl_pad(ARSTRTBL *strtbl, size_t n, int ch) 921 { 922 if (n == 0) 923 return; 924 925 if ((n + strtbl->used) > strtbl->size) 926 strtbl_alloc(strtbl, n); 927 928 while (n--) 929 strtbl->base[strtbl->used++] = ch; 930 } 931 932 /* 933 * Enter a symbol name into the symbol string table. 934 */ 935 static void 936 savename(char *symbol) 937 { 938 size_t need; 939 940 need = strlen(symbol) + 1; 941 if ((need + sym_strtbl.used) > sym_strtbl.size) 942 strtbl_alloc(&sym_strtbl, need); 943 944 (void) strcpy(sym_strtbl.base + sym_strtbl.used, symbol); 945 sym_strtbl.used += need; 946 } 947 948 /* 949 * Prepare an archive member with a long (>15 characters) name for 950 * the output archive. 951 * 952 * entry: 953 * fptr - pointer to archive member with long name 954 * 955 * exit: 956 * The long name is entered into the long name string table, 957 * and fptr->ar_name has been replaced with the special /xxx 958 * name used to indicate that the real name is in the string table 959 * at offset xxx. 960 */ 961 static void 962 savelongname(ARFILE *fptr) 963 { 964 size_t len, need; 965 char *p; 966 967 /* Size of new item to add */ 968 len = strlen(fptr->ar_longname); 969 need = len + 2; 970 971 /* Ensure there's room */ 972 if ((need + long_strtbl.used) > long_strtbl.size) 973 strtbl_alloc(&long_strtbl, need); 974 975 /* 976 * Generate the index string to be written into the member header 977 * 978 * This will not overflow the ar_name field because that field is 979 * 16 characters in size, and a 32-bit unsigned value can be formatted 980 * in 10 characters. Allowing a character for the leading '/', and one 981 * for the NULL termination, that leaves us with 4 extra spaces. 982 */ 983 (void) snprintf(fptr->ar_name, sizeof (fptr->ar_name), 984 MSG_ORIG(MSG_FMT_LLINT), EC_XWORD(long_strtbl.used)); 985 986 /* 987 * Enter long name into reserved spot, terminated with a slash 988 * and a newline character. 989 */ 990 p = long_strtbl.base + long_strtbl.used; 991 long_strtbl.used += need; 992 (void) strcpy(p, fptr->ar_longname); 993 p += len; 994 *p++ = '/'; 995 *p++ = '\n'; 996 } 997 998 /* 999 * Determine if the archive we're about to write will exceed the 1000 * 32-bit limit of 4GB. 1001 * 1002 * entry: 1003 * mksymtab() and mklong_tab() have been called to set up 1004 * the string tables. 1005 * 1006 * exit: 1007 * Returns TRUE (1) if the 64-bit symbol table is needed, and 1008 * FALSE (0) otherwise. 1009 * 1010 */ 1011 static int 1012 require64(size_t nsyms, int found_obj, size_t longnames) 1013 { 1014 ARFILE *fptr; 1015 uint64_t size; 1016 1017 /* 1018 * If there are more than 4GB symbols, we have to use 1019 * the 64-bit form. Note that longnames cannot exceed 4GB 1020 * because that symbol table is limited to a length of 4GB by 1021 * the archive format. 1022 */ 1023 if (nsyms > 0xffffffff) 1024 return (1); 1025 1026 /* 1027 * Make a worst case estimate for the size of the resulting 1028 * archive by assuming full padding between members. 1029 */ 1030 size = SARMAG; 1031 if (longnames) 1032 size += sizeof (struct ar_hdr) + long_strtbl.used + PADSZ; 1033 1034 if (found_obj) 1035 size += sizeof_symtbl(nsyms, found_obj, 4) + PADSZ; 1036 1037 if (size > 0xffffffff) 1038 return (1); 1039 1040 for (fptr = listhead; fptr; fptr = fptr->ar_next) { 1041 size += sizeof (struct ar_hdr) + fptr->ar_size + PADSZ; 1042 1043 if (size > 0xffffffff) 1044 return (1); 1045 } 1046 1047 /* 32-bit symbol table will suffice */ 1048 return (0); 1049 } 1050 1051 void 1052 writefile(Cmd_info *cmd_info) 1053 { 1054 ARFILE *fptr; 1055 ARFILEP *symlist = 0; 1056 size_t longnames; 1057 size_t nsyms; 1058 int new_archive = 0; 1059 char *name = cmd_info->arnam; 1060 size_t arsize; /* Size of magic # and special members */ 1061 size_t symtbl_eltsize = 4; 1062 int found_obj = 0; 1063 int fd; 1064 off_t off; 1065 struct stat stbuf, ar_stbuf; 1066 char pad_bytes[PADSZ]; 1067 size_t pad_cnt; 1068 int is_elf; 1069 1070 /* 1071 * Gather the list of symbols and associate each one to the 1072 * ARFILE descriptor of the object it belongs to. At the same 1073 * time, tag each ELF object with the appropriate F_CLASSxx 1074 * flag. 1075 */ 1076 nsyms = mksymtab(name, &symlist, &found_obj); 1077 1078 /* Generate the string table for long member names */ 1079 longnames = mklong_tab(); 1080 1081 /* 1082 * Will this archive exceed 4GB? If we're a 32-bit process, we can't 1083 * do it. If we're a 64-bit process, then we'll have to use a 1084 * 64-bit symbol table. 1085 */ 1086 if (require64(nsyms, found_obj, longnames)) { 1087 #ifdef _LP64 1088 symtbl_eltsize = 8; 1089 #else 1090 (void) fprintf(stderr, MSG_INTL(MSG_TOOBIG4G)); 1091 exit(1); 1092 #endif 1093 } 1094 1095 /* 1096 * If the user requested it, use the 64-bit symbol table even if 1097 * a 32-bit one would suffice. 32-bit tables are more portable and 1098 * take up less room, so this feature is primarily for testing. 1099 */ 1100 if (cmd_info->opt_flgs & S_FLAG) 1101 symtbl_eltsize = 8; 1102 1103 /* 1104 * If the first non-special archive member is an ELF object, then we 1105 * need to arrange for its data to have an alignment of PADSZ. The 1106 * preceeding special member will be the symbol table, or the long 1107 * name string table. We pad the string table that precedes the 1108 * ELF member in order to achive the desired alignment. 1109 */ 1110 is_elf = listhead && (listhead->ar_flag & (F_CLASS32 | F_CLASS64)); 1111 arsize = SARMAG; 1112 if (found_obj) { 1113 arsize += sizeof_symtbl(nsyms, found_obj, symtbl_eltsize); 1114 if (is_elf && (longnames == 0)) { 1115 pad_cnt = pad(arsize + sizeof (struct ar_hdr), PADSZ); 1116 strtbl_pad(&sym_strtbl, pad_cnt, '\0'); 1117 arsize += pad_cnt; 1118 } 1119 } 1120 if (longnames > 0) { 1121 arsize += sizeof (struct ar_hdr) + long_strtbl.used; 1122 if (is_elf) { 1123 pad_cnt = pad(arsize + sizeof (struct ar_hdr), PADSZ); 1124 strtbl_pad(&long_strtbl, pad_cnt, '\0'); 1125 arsize += pad_cnt; 1126 } 1127 } 1128 1129 /* 1130 * For each user visible (non-special) archive member, determine 1131 * the header offset, and the size of any required padding. 1132 */ 1133 (void) sizeofmembers(arsize); 1134 1135 /* 1136 * Is this a new archive, or are we updating an existing one? 1137 * 1138 * A subtlety here is that POSIX says we are not supposed 1139 * to replace a non-writable file. The only 100% reliable test 1140 * against this is to open the file for non-destructive 1141 * write access. If the open succeeds, we are clear to 1142 * replace it, and if not, then the error generated is 1143 * the error we need to report. 1144 */ 1145 if ((fd = open(name, O_RDWR)) < 0) { 1146 int err = errno; 1147 1148 if (err != ENOENT) { 1149 (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), 1150 name, strerror(err)); 1151 exit(1); 1152 } 1153 new_archive = 1; 1154 if ((cmd_info->opt_flgs & c_FLAG) == 0) { 1155 (void) fprintf(stderr, MSG_INTL(MSG_BER_MES_CREATE), 1156 cmd_info->arnam); 1157 } 1158 } else { 1159 /* Capture mode and owner information to apply to replacement */ 1160 if (fstat(fd, &ar_stbuf) < 0) { 1161 int err = errno; 1162 (void) fprintf(stderr, MSG_INTL(MSG_SYS_STAT), 1163 name, strerror(err)); 1164 (void) close(fd); 1165 exit(1); 1166 } 1167 (void) close(fd); 1168 new_archive = 0; 1169 } 1170 1171 1172 /* 1173 * Register exit handler function to clean up after us if we exit 1174 * before completing the new archive. atexit() is defined as 1175 * only being able to fail due to memory exhaustion. 1176 */ 1177 if (atexit(exit_cleanup) != 0) { 1178 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(ENOMEM)); 1179 exit(1); 1180 } 1181 1182 /* 1183 * If a new archive, create it in place. If updating an archive, 1184 * create the replacement under a temporary name and then rename it 1185 * into place. 1186 */ 1187 ar_outfile.path = new_archive ? name : make_tmpname(name); 1188 ar_outfile.fd = open(ar_outfile.path, O_RDWR|O_CREAT|O_LARGEFILE, 0666); 1189 if (ar_outfile.fd == -1) { 1190 int err = errno; 1191 (void) fprintf(stderr, new_archive ? 1192 MSG_INTL(MSG_BAD_CREATE) : MSG_INTL(MSG_SYS_OPEN), 1193 ar_outfile.path, strerror(err)); 1194 exit(1); 1195 } 1196 1197 /* Output magic string */ 1198 arwrite(name, ar_outfile.fd, ARMAG, SARMAG); 1199 1200 /* 1201 * The symbol table member is always first if present. Note that 1202 * writesymtab() uses the member offsets computed by sizeofmembers() 1203 * above. 1204 */ 1205 if (found_obj) 1206 writesymtab(name, ar_outfile.fd, nsyms, symlist, 1207 symtbl_eltsize); 1208 1209 if (longnames) { 1210 write_member_header(name, ar_outfile.fd, 0, 1211 MSG_ORIG(MSG_STR_DSLASH), time(0), 0, 0, 0, 1212 long_strtbl.used); 1213 arwrite(name, ar_outfile.fd, long_strtbl.base, 1214 long_strtbl.used); 1215 } 1216 1217 /* 1218 * The accuracy of the symbol table depends on our having calculated 1219 * the size of the archive accurately to this point. If this is a 1220 * debug build, verify it. 1221 */ 1222 assert(arsize == lseek(ar_outfile.fd, 0, SEEK_CUR)); 1223 1224 #ifndef XPG4 1225 if (cmd_info->opt_flgs & v_FLAG) { 1226 (void) fprintf(stderr, MSG_INTL(MSG_BER_MES_WRITE), 1227 cmd_info->arnam); 1228 } 1229 #endif 1230 1231 /* 1232 * Fill pad_bytes array with newline characters. This array 1233 * is used to supply padding bytes at the end of ELF objects. 1234 * There can never be more tha PADSZ such bytes, so this number 1235 * will always suffice. 1236 */ 1237 for (pad_cnt = 0; pad_cnt < PADSZ; pad_cnt++) 1238 pad_bytes[pad_cnt] = '\n'; 1239 1240 for (fptr = listhead; fptr; fptr = fptr->ar_next) { 1241 /* 1242 * We computed the expected offset for each ELF member and 1243 * used those offsets to fill the symbol table. If this is 1244 * a debug build, verify that the computed offset was right. 1245 */ 1246 is_elf = (fptr->ar_flag & (F_CLASS32 | F_CLASS64)) != 0; 1247 assert(!is_elf || 1248 (fptr->ar_offset == lseek(ar_outfile.fd, 0, SEEK_CUR))); 1249 1250 /* 1251 * NOTE: 1252 * The mem_header->ar_name[] is set to a NULL string 1253 * if the archive member header has some error. 1254 * (See elf_getarhdr() man page.) 1255 * It is set to NULL for example, the ar command reads 1256 * the archive files created by SunOS 4.1 system. 1257 * See c block comment in cmd.c, "Incompatible Archive Header". 1258 */ 1259 if (fptr->ar_name[0] == 0) { 1260 fptr->ar_longname = fptr->ar_rawname; 1261 (void) strncpy(fptr->ar_name, fptr->ar_rawname, SNAME); 1262 } 1263 write_member_header(name, ar_outfile.fd, is_elf, 1264 (strlen(fptr->ar_longname) <= (unsigned)SNAME-2) ? 1265 trimslash(fptr->ar_longname) : fptr->ar_name, 1266 EC_WORD(fptr->ar_date), fptr->ar_uid, fptr->ar_gid, 1267 fptr->ar_mode, fptr->ar_size + fptr->ar_padding); 1268 1269 1270 if ((fptr->ar_flag & F_ELFRAW) == 0) { 1271 /* 1272 * The file doesn't come from the archive, and is 1273 * therefore not already in memory(fptr->ar_contents) 1274 * so open it and do a direct file-to-file transfer of 1275 * its contents. We use the sendfile() system call 1276 * to make the kernel do the transfer, so we don't have 1277 * to buffer data in process, and we trust that the 1278 * kernel will use an optimal transfer strategy. 1279 */ 1280 if ((fd = open(fptr->ar_pathname, O_RDONLY)) == -1) { 1281 int err = errno; 1282 (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), 1283 fptr->ar_longname, strerror(err)); 1284 exit(1); 1285 } 1286 if (stat(fptr->ar_pathname, &stbuf) < 0) { 1287 int err = errno; 1288 (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), 1289 fptr->ar_longname, strerror(err)); 1290 (void) close(fd); 1291 exit(1); 1292 } 1293 off = 0; 1294 if (sendfile(ar_outfile.fd, fd, &off, 1295 stbuf.st_size) != stbuf.st_size) { 1296 int err = errno; 1297 (void) fprintf(stderr, MSG_INTL(MSG_SYS_WRITE), 1298 name, strerror(err)); 1299 exit(2); 1300 } 1301 (void) close(fd); 1302 } else { 1303 /* Archive member is in memory. Write it out */ 1304 arwrite(name, ar_outfile.fd, fptr->ar_contents, 1305 fptr->ar_size); 1306 } 1307 1308 /* 1309 * All archive members are padded to at least a boundary of 2. 1310 * The expression ((fptr->ar_size & 0x1) != 0) yields 1 for 1311 * odd boundaries, and 0 for even ones. To this, we add 1312 * whatever padding is needed for ELF objects. 1313 */ 1314 pad_cnt = ((fptr->ar_size & 0x1) != 0) + fptr->ar_padding; 1315 if (pad_cnt > 0) 1316 arwrite(name, ar_outfile.fd, pad_bytes, pad_cnt); 1317 } 1318 1319 /* 1320 * All archive output is done. 1321 */ 1322 if (close(ar_outfile.fd) < 0) { 1323 int err = errno; 1324 (void) fprintf(stderr, MSG_INTL(MSG_SYS_CLOSE), ar_outfile.path, 1325 strerror(err)); 1326 exit(1); 1327 } 1328 ar_outfile.fd = -1; /* Prevent removal on exit */ 1329 (void) elf_end(cmd_info->arf); 1330 (void) close(cmd_info->afd); 1331 1332 /* 1333 * If updating an existing archive, rename the new version on 1334 * top of the original. 1335 */ 1336 if (!new_archive) { 1337 /* 1338 * Prevent the replacement of the original archive from 1339 * being interrupted, to lower the possibility of an 1340 * interrupt destroying a pre-existing archive. 1341 */ 1342 establish_sighandler(SIG_IGN); 1343 1344 if (rename(ar_outfile.path, name) < 0) { 1345 int err = errno; 1346 (void) fprintf(stderr, MSG_INTL(MSG_SYS_RENAME), 1347 ar_outfile.path, name, strerror(err)); 1348 (void) unlink(ar_outfile.path); 1349 exit(1); 1350 } 1351 (void) chmod(name, ar_stbuf.st_mode & 0777); 1352 if (chown(name, ar_stbuf.st_uid, ar_stbuf.st_gid) >= 0) 1353 (void) chmod(name, ar_stbuf.st_mode & 07777); 1354 1355 } 1356 } 1357 1358 /* 1359 * Examine all the archive members, enter any member names longer than 1360 * 15 characters into the long name string table, and count the number 1361 * of names found. 1362 * 1363 * Returns the size of the resulting archive member, including the 1364 * member header. 1365 */ 1366 static size_t 1367 mklong_tab(void) 1368 { 1369 ARFILE *fptr; 1370 size_t longnames = 0; 1371 1372 for (fptr = listhead; fptr; fptr = fptr->ar_next) { 1373 if (strlen(fptr->ar_longname) >= (unsigned)SNAME-1) { 1374 longnames++; 1375 savelongname(fptr); 1376 } 1377 } 1378 1379 /* round up table that keeps the long filenames */ 1380 if (longnames > 0) 1381 strtbl_pad(&long_strtbl, pad(long_strtbl.used, 4), '\n'); 1382 1383 return (longnames); 1384 } 1385 1386 /* 1387 * Write 32/64-bit words into buffer in archive symbol table 1388 * standard byte order (MSB). 1389 */ 1390 static char * 1391 sputl32(uint32_t n, char *cp) 1392 { 1393 *cp++ = n >> 24; 1394 *cp++ = n >> 16; 1395 *cp++ = n >> 8; 1396 1397 *cp++ = n & 255; 1398 1399 return (cp); 1400 } 1401 1402 static char * 1403 sputl64(uint64_t n, char *cp) 1404 { 1405 *cp++ = n >> 56; 1406 *cp++ = n >> 48; 1407 *cp++ = n >> 40; 1408 *cp++ = n >> 32; 1409 1410 *cp++ = n >> 24; 1411 *cp++ = n >> 16; 1412 *cp++ = n >> 8; 1413 1414 *cp++ = n & 255; 1415 1416 return (cp); 1417 } 1418 1419 static int 1420 search_sym_tab(const char *arname, ARFILE *fptr, Elf *elf, Elf_Scn *scn, 1421 size_t *nsyms, ARFILEP **symlist, size_t *num_errs) 1422 { 1423 Elf_Data *str_data, *sym_data; /* string table, symbol table */ 1424 Elf_Scn *str_scn; 1425 GElf_Sxword no_of_symbols; 1426 GElf_Shdr shdr; 1427 int counter; 1428 int str_shtype; 1429 char *symname; 1430 static ARFILEP *sym_ptr = 0; 1431 static ARFILEP *nextsym = NULL; 1432 static int syms_left = 0; 1433 char *fname = fptr->ar_pathname; 1434 1435 (void) gelf_getshdr(scn, &shdr); 1436 str_scn = elf_getscn(elf, shdr.sh_link); /* index for string table */ 1437 if (str_scn == NULL) { 1438 if (fname != NULL) 1439 (void) fprintf(stderr, MSG_INTL(MSG_ELF_GETDATA_FILE), 1440 fname, elf_errmsg(-1)); 1441 else 1442 (void) fprintf(stderr, MSG_INTL(MSG_ELF_GETDATA_AR), 1443 arname, fptr->ar_longname, elf_errmsg(-1)); 1444 (*num_errs)++; 1445 return (-1); 1446 } 1447 1448 no_of_symbols = shdr.sh_size / shdr.sh_entsize; 1449 if (no_of_symbols == -1) { 1450 (void) fprintf(stderr, MSG_INTL(MSG_SYMTAB_01)); 1451 return (-1); 1452 } 1453 1454 (void) gelf_getshdr(str_scn, &shdr); 1455 str_shtype = shdr.sh_type; 1456 if (str_shtype == -1) { 1457 if (fname != NULL) 1458 (void) fprintf(stderr, MSG_INTL(MSG_ELF_GETDATA_FILE), 1459 fname, elf_errmsg(-1)); 1460 else 1461 (void) fprintf(stderr, MSG_INTL(MSG_ELF_GETDATA_AR), 1462 arname, fptr->ar_longname, elf_errmsg(-1)); 1463 (*num_errs)++; 1464 return (-1); 1465 } 1466 1467 /* This test must happen before testing the string table. */ 1468 if (no_of_symbols == 1) 1469 return (0); /* no symbols; 0th symbol is the non-symbol */ 1470 1471 if (str_shtype != SHT_STRTAB) { 1472 if (fname != NULL) 1473 (void) fprintf(stderr, MSG_INTL(MSG_SYMTAB_NOSTR_FILE), 1474 fname); 1475 else 1476 (void) fprintf(stderr, MSG_INTL(MSG_SYMTAB_NOSTR_AR), 1477 arname, fptr->ar_longname); 1478 return (0); 1479 } 1480 str_data = 0; 1481 if ((str_data = elf_getdata(str_scn, str_data)) == 0) { 1482 if (fname != NULL) 1483 (void) fprintf(stderr, MSG_INTL(MSG_SYMTAB_NODAT_FILE), 1484 fname); 1485 else 1486 (void) fprintf(stderr, MSG_INTL(MSG_SYMTAB_NODAT_AR), 1487 arname, fptr->ar_longname); 1488 return (0); 1489 } 1490 if (str_data->d_size == 0) { 1491 if (fname != NULL) 1492 (void) fprintf(stderr, MSG_INTL(MSG_SYMTAB_ZDAT_FILE), 1493 fname); 1494 else 1495 (void) fprintf(stderr, MSG_INTL(MSG_SYMTAB_ZDAT_AR), 1496 arname, fptr->ar_longname); 1497 return (0); 1498 } 1499 sym_data = 0; 1500 if ((sym_data = elf_getdata(scn, sym_data)) == NULL) { 1501 if (fname != NULL) 1502 (void) fprintf(stderr, MSG_INTL(MSG_ELF_LIB_FILE), 1503 fname, elf_errmsg(-1)); 1504 else 1505 (void) fprintf(stderr, MSG_INTL(MSG_ELF_LIB_AR), 1506 arname, fptr->ar_longname, elf_errmsg(-1)); 1507 return (0); 1508 } 1509 1510 /* start at 1, first symbol entry is ignored */ 1511 for (counter = 1; counter < no_of_symbols; counter++) { 1512 GElf_Sym sym; 1513 (void) gelf_getsym(sym_data, counter, &sym); 1514 1515 symname = (char *)(str_data->d_buf) + sym.st_name; 1516 1517 if (((GELF_ST_BIND(sym.st_info) == STB_GLOBAL) || 1518 (GELF_ST_BIND(sym.st_info) == STB_WEAK)) && 1519 (sym.st_shndx != SHN_UNDEF)) { 1520 if (!syms_left) { 1521 sym_ptr = malloc((SYMCHUNK+1) 1522 * sizeof (ARFILEP)); 1523 if (sym_ptr == NULL) { 1524 int err = errno; 1525 (void) fprintf(stderr, 1526 MSG_INTL(MSG_MALLOC), 1527 strerror(err)); 1528 exit(1); 1529 } 1530 syms_left = SYMCHUNK; 1531 if (nextsym) 1532 *nextsym = (ARFILEP)sym_ptr; 1533 else 1534 *symlist = sym_ptr; 1535 nextsym = sym_ptr; 1536 } 1537 sym_ptr = nextsym; 1538 nextsym++; 1539 syms_left--; 1540 (*nsyms)++; 1541 *sym_ptr = fptr; 1542 savename(symname); /* put name in the archiver's */ 1543 /* symbol table string table */ 1544 } 1545 } 1546 return (0); 1547 } 1548 1549 /* 1550 * Get the output file size 1551 */ 1552 static size_t 1553 sizeofmembers(size_t psum) 1554 { 1555 size_t sum = 0; 1556 ARFILE *fptr; 1557 size_t hdrsize = sizeof (struct ar_hdr); 1558 1559 for (fptr = listhead; fptr; fptr = fptr->ar_next) { 1560 fptr->ar_offset = psum + sum; 1561 sum += fptr->ar_size; 1562 if (fptr->ar_size & 01) 1563 sum++; 1564 sum += hdrsize; 1565 1566 /* 1567 * If the current item, and the next item are both ELF 1568 * objects, then add padding to current item so that the 1569 * data in the next item will have PADSZ alignment. 1570 * 1571 * In any other case, set the padding to 0. If the 1572 * item comes from another archive, it may be carrying 1573 * a non-zero padding value from that archive that does 1574 * not apply to the one we are about to build. 1575 */ 1576 if ((fptr->ar_flag & (F_CLASS32 | F_CLASS64)) && 1577 fptr->ar_next && 1578 (fptr->ar_next->ar_flag & (F_CLASS32 | F_CLASS64))) { 1579 fptr->ar_padding = pad(psum + sum + hdrsize, PADSZ); 1580 sum += fptr->ar_padding; 1581 } else { 1582 fptr->ar_padding = 0; 1583 } 1584 } 1585 return (sum); 1586 } 1587 1588 /* 1589 * Compute the size of the symbol table archive member. 1590 * 1591 * entry: 1592 * nsyms - # of symbols in the table 1593 * found_obj - TRUE if the archive contains any ELF objects 1594 * eltsize - Size of the integer type to use for the symbol 1595 * table. 4 for 32-bit tables, and 8 for 64-bit tables. 1596 */ 1597 static size_t 1598 sizeof_symtbl(size_t nsyms, int found_obj, size_t eltsize) 1599 { 1600 size_t sum = 0; 1601 1602 if (found_obj) { 1603 /* Member header, symbol count, and one slot per symbol */ 1604 sum += sizeof (struct ar_hdr) + ((nsyms + 1) * eltsize); 1605 sum += sym_strtbl.used; 1606 } 1607 1608 return (sum); 1609 } 1610 1611 static void 1612 arwrite(const char *name, int nfd, const char *dst, size_t size) 1613 { 1614 if (write(nfd, dst, size) != size) { 1615 int err = errno; 1616 (void) fprintf(stderr, MSG_INTL(MSG_SYS_WRITE), 1617 name, strerror(err)); 1618 exit(2); 1619 } 1620 } 1621 1622 static const char * 1623 make_tmpname(const char *filename) 1624 { 1625 char *slash, *tmpname; 1626 size_t prefix_cnt = 0; 1627 1628 /* 1629 * If there is a path prefix in front of the filename, we 1630 * want to put the temporary file in the same directory. 1631 * Determine the length of the path. 1632 */ 1633 slash = strrchr(filename, '/'); 1634 if (slash != NULL) 1635 prefix_cnt = slash - filename + 1; 1636 tmpname = malloc(prefix_cnt + MSG_STR_MKTEMP_SIZE + 1); 1637 if (tmpname == NULL) { 1638 int err = errno; 1639 (void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(err)); 1640 exit(1); 1641 } 1642 1643 if (prefix_cnt > 0) 1644 (void) strncpy(tmpname, filename, prefix_cnt); 1645 (void) strcpy(tmpname + prefix_cnt, MSG_ORIG(MSG_STR_MKTEMP)); 1646 (void) mktemp(tmpname); 1647 1648 return (tmpname); 1649 } 1650