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_GETSHDRSTRNDX_FILE),
 569                                             fptr->ar_pathname, elf_errmsg(-1));
 570                                 } else {
 571                                         (void) fprintf(stderr,
 572                                             MSG_INTL(MSG_ELF_GETSHDRSTRNDX_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 }