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