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