file.c revision 12792:1f56a791e275
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 */
39ARFILE	*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 */
50typedef 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
56static ARSTRTBL	sym_strtbl;
57static 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 */
67static 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 */
103static void		arwrite(const char *, int, const char *, size_t);
104static size_t		mklong_tab();
105static size_t		mksymtab(const char *, ARFILEP **, int *);
106static const char	*make_tmpname(const char *);
107static size_t		sizeof_symtbl(size_t, int, size_t);
108static void		savelongname(ARFILE *);
109static void		savename(char *);
110static int		search_sym_tab(const char *, ARFILE *, Elf *,
111			    Elf_Scn *, size_t *, ARFILEP **, size_t *);
112static size_t		sizeofmembers(size_t);
113static char		*sputl32(uint32_t, char *);
114static char		*sputl64(uint64_t, char *);
115static void		strtbl_pad(ARSTRTBL *, size_t, int);
116static char		*trimslash(char *s);
117static 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 */
124static void
125exit_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 */
137int
138getaf(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 */
181static size_t
182pad(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 */
203static void
204recover_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 */
303ARFILE *
304getfile(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 */
400ARFILE *
401newfile(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
428static char *
429trimslash(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
438char *
439trim(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 */
468static size_t
469mksymtab(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*/
697static void
698write_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 */
736static void
737writesymtab(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 */
784static void
785strtbl_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
863limit_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 */
891static void
892strtbl_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 */
907static void
908savename(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 */
933static void
934savelongname(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 */
983static int
984require64(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
1023void
1024writefile(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 */
1337static size_t
1338mklong_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 */
1361static char *
1362sputl32(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
1373static char *
1374sputl64(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
1390static int
1391search_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 */
1523static size_t
1524sizeofmembers(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 */
1568static size_t
1569sizeof_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
1582static void
1583arwrite(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
1592static const char *
1593make_tmpname(const char *filename) {
1594	char	*slash, *tmpname;
1595	size_t	prefix_cnt = 0;
1596
1597	/*
1598	 * If there is a path prefix in front of the filename, we
1599	 * want to put the temporary file in the same directory.
1600	 * Determine the length of the path.
1601	 */
1602	slash = strrchr(filename, '/');
1603	if (slash != NULL)
1604		prefix_cnt = slash - filename + 1;
1605	tmpname = malloc(prefix_cnt + MSG_STR_MKTEMP_SIZE + 1);
1606	if (tmpname == NULL) {
1607		int err = errno;
1608		(void) fprintf(stderr, MSG_INTL(MSG_MALLOC), strerror(err));
1609		exit(1);
1610	}
1611
1612	if (prefix_cnt > 0)
1613		(void) strncpy(tmpname, filename, prefix_cnt);
1614	(void) strcpy(tmpname + prefix_cnt, MSG_ORIG(MSG_STR_MKTEMP));
1615	(void) mktemp(tmpname);
1616
1617	return (tmpname);
1618}
1619