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 }