xref: /freebsd/contrib/elftoolchain/elfcopy/symbols.c (revision e8e8c939350bdf3c228a411caa9660c607c27a11)
1 /*-
2  * Copyright (c) 2007-2013 Kai Wang
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/param.h>
28 #include <err.h>
29 #include <fnmatch.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "elfcopy.h"
35 
36 ELFTC_VCSID("$Id: symbols.c 3222 2015-05-24 23:47:23Z kaiwang27 $");
37 
38 /* Symbol table buffer structure. */
39 struct symbuf {
40 	Elf32_Sym *l32;		/* 32bit local symbol */
41 	Elf32_Sym *g32;		/* 32bit global symbol */
42 	Elf64_Sym *l64;		/* 64bit local symbol */
43 	Elf64_Sym *g64;		/* 64bit global symbol */
44 	size_t ngs, nls;	/* number of each kind */
45 	size_t gcap, lcap; 	/* buffer capacities. */
46 };
47 
48 struct sthash {
49 	LIST_ENTRY(sthash) sh_next;
50 	size_t sh_off;
51 };
52 typedef LIST_HEAD(,sthash) hash_head;
53 #define STHASHSIZE 65536
54 
55 struct strimpl {
56 	char *buf;		/* string table */
57 	size_t sz;		/* entries */
58 	size_t cap;		/* buffer capacity */
59 	hash_head hash[STHASHSIZE];
60 };
61 
62 
63 /* String table buffer structure. */
64 struct strbuf {
65 	struct strimpl l;	/* local symbols */
66 	struct strimpl g;	/* global symbols */
67 };
68 
69 static int	is_debug_symbol(unsigned char st_info);
70 static int	is_global_symbol(unsigned char st_info);
71 static int	is_local_symbol(unsigned char st_info);
72 static int	is_local_label(const char *name);
73 static int	is_needed_symbol(struct elfcopy *ecp, int i, GElf_Sym *s);
74 static int	is_remove_symbol(struct elfcopy *ecp, size_t sc, int i,
75 		    GElf_Sym *s, const char *name);
76 static int	is_weak_symbol(unsigned char st_info);
77 static int	lookup_exact_string(hash_head *hash, const char *buf,
78 		    const char *s);
79 static int	generate_symbols(struct elfcopy *ecp);
80 static void	mark_reloc_symbols(struct elfcopy *ecp, size_t sc);
81 static void	mark_section_group_symbols(struct elfcopy *ecp, size_t sc);
82 static int	match_wildcard(const char *name, const char *pattern);
83 uint32_t	str_hash(const char *s);
84 
85 /* Convenient bit vector operation macros. */
86 #define BIT_SET(v, n) (v[(n)>>3] |= 1U << ((n) & 7))
87 #define BIT_CLR(v, n) (v[(n)>>3] &= ~(1U << ((n) & 7)))
88 #define BIT_ISSET(v, n) (v[(n)>>3] & (1U << ((n) & 7)))
89 
90 static int
91 is_debug_symbol(unsigned char st_info)
92 {
93 
94 	if (GELF_ST_TYPE(st_info) == STT_SECTION ||
95 	    GELF_ST_TYPE(st_info) == STT_FILE)
96 		return (1);
97 
98 	return (0);
99 }
100 
101 static int
102 is_global_symbol(unsigned char st_info)
103 {
104 
105 	if (GELF_ST_BIND(st_info) == STB_GLOBAL)
106 		return (1);
107 
108 	return (0);
109 }
110 
111 static int
112 is_weak_symbol(unsigned char st_info)
113 {
114 
115 	if (GELF_ST_BIND(st_info) == STB_WEAK)
116 		return (1);
117 
118 	return (0);
119 }
120 
121 static int
122 is_local_symbol(unsigned char st_info)
123 {
124 
125 	if (GELF_ST_BIND(st_info) == STB_LOCAL)
126 		return (1);
127 
128 	return (0);
129 }
130 
131 static int
132 is_hidden_symbol(unsigned char st_other)
133 {
134 
135 	if (GELF_ST_VISIBILITY(st_other) == STV_HIDDEN ||
136 	    GELF_ST_VISIBILITY(st_other) == STV_INTERNAL)
137 		return (1);
138 
139 	return (0);
140 }
141 
142 static int
143 is_local_label(const char *name)
144 {
145 
146 	/* Compiler generated local symbols that start with .L */
147 	if (name[0] == '.' && name[1] == 'L')
148 		return (1);
149 
150 	return (0);
151 }
152 
153 /*
154  * Symbols related to relocation are needed.
155  */
156 static int
157 is_needed_symbol(struct elfcopy *ecp, int i, GElf_Sym *s)
158 {
159 
160 	/* If symbol involves relocation, it is needed. */
161 	if (BIT_ISSET(ecp->v_rel, i))
162 		return (1);
163 
164 	/* Symbols refered by COMDAT sections are needed. */
165 	if (BIT_ISSET(ecp->v_grp, i))
166 		return (1);
167 
168 	/*
169 	 * For relocatable files (.o files), global and weak symbols
170 	 * are needed.
171 	 */
172 	if (ecp->flags & RELOCATABLE) {
173 		if (is_global_symbol(s->st_info) || is_weak_symbol(s->st_info))
174 			return (1);
175 	}
176 
177 	return (0);
178 }
179 
180 static int
181 is_remove_symbol(struct elfcopy *ecp, size_t sc, int i, GElf_Sym *s,
182     const char *name)
183 {
184 	GElf_Sym sym0 = {
185 		0, 		/* st_name */
186 		0,		/* st_value */
187 		0,		/* st_size */
188 		0,		/* st_info */
189 		0,		/* st_other */
190 		SHN_UNDEF,	/* st_shndx */
191 	};
192 
193 	if (lookup_symop_list(ecp, name, SYMOP_KEEP) != NULL)
194 		return (0);
195 
196 	if (lookup_symop_list(ecp, name, SYMOP_STRIP) != NULL)
197 		return (1);
198 
199 	/*
200 	 * Keep the first symbol if it is the special reserved symbol.
201 	 * XXX Should we generate one if it's missing?
202 	 */
203 	if (i == 0 && !memcmp(s, &sym0, sizeof(GElf_Sym)))
204 		return (0);
205 
206 	/* Remove the symbol if the section it refers to was removed. */
207 	if (s->st_shndx != SHN_UNDEF && s->st_shndx < SHN_LORESERVE &&
208 	    ecp->secndx[s->st_shndx] == 0)
209 		return (1);
210 
211 	if (ecp->strip == STRIP_ALL)
212 		return (1);
213 
214 	if (ecp->v_rel == NULL)
215 		mark_reloc_symbols(ecp, sc);
216 
217 	if (ecp->v_grp == NULL)
218 		mark_section_group_symbols(ecp, sc);
219 
220 	if (is_needed_symbol(ecp, i, s))
221 		return (0);
222 
223 	if (ecp->strip == STRIP_UNNEEDED)
224 		return (1);
225 
226 	if ((ecp->flags & DISCARD_LOCAL) && is_local_symbol(s->st_info) &&
227 	    !is_debug_symbol(s->st_info))
228 		return (1);
229 
230 	if ((ecp->flags & DISCARD_LLABEL) && is_local_symbol(s->st_info) &&
231 	    !is_debug_symbol(s->st_info) && is_local_label(name))
232 		return (1);
233 
234 	if (ecp->strip == STRIP_DEBUG && is_debug_symbol(s->st_info))
235 		return (1);
236 
237 	return (0);
238 }
239 
240 /*
241  * Mark symbols refered by relocation entries.
242  */
243 static void
244 mark_reloc_symbols(struct elfcopy *ecp, size_t sc)
245 {
246 	const char	*name;
247 	Elf_Data	*d;
248 	Elf_Scn		*s;
249 	GElf_Rel	 r;
250 	GElf_Rela	 ra;
251 	GElf_Shdr	 sh;
252 	size_t		 n, indx;
253 	int		 elferr, i, len;
254 
255 	ecp->v_rel = calloc((sc + 7) / 8, 1);
256 	if (ecp->v_rel == NULL)
257 		err(EXIT_FAILURE, "calloc failed");
258 
259 	if (elf_getshstrndx(ecp->ein, &indx) == 0)
260 		errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
261 		    elf_errmsg(-1));
262 
263 	s = NULL;
264 	while ((s = elf_nextscn(ecp->ein, s)) != NULL) {
265 		if (gelf_getshdr(s, &sh) != &sh)
266 			errx(EXIT_FAILURE, "elf_getshdr failed: %s",
267 			    elf_errmsg(-1));
268 
269 		if (sh.sh_type != SHT_REL && sh.sh_type != SHT_RELA)
270 			continue;
271 
272 		/*
273 		 * Skip if this reloc section won't appear in the
274 		 * output object.
275 		 */
276 		if ((name = elf_strptr(ecp->ein, indx, sh.sh_name)) == NULL)
277 			errx(EXIT_FAILURE, "elf_strptr failed: %s",
278 			    elf_errmsg(-1));
279 		if (is_remove_section(ecp, name) ||
280 		    is_remove_reloc_sec(ecp, sh.sh_info))
281 			continue;
282 
283 		/* Skip if it's not for .symtab */
284 		if (sh.sh_link != elf_ndxscn(ecp->symtab->is))
285 			continue;
286 
287 		d = NULL;
288 		n = 0;
289 		while (n < sh.sh_size && (d = elf_getdata(s, d)) != NULL) {
290 			len = d->d_size / sh.sh_entsize;
291 			for (i = 0; i < len; i++) {
292 				if (sh.sh_type == SHT_REL) {
293 					if (gelf_getrel(d, i, &r) != &r)
294 						errx(EXIT_FAILURE,
295 						    "elf_getrel failed: %s",
296 						     elf_errmsg(-1));
297 					n = GELF_R_SYM(r.r_info);
298 				} else {
299 					if (gelf_getrela(d, i, &ra) != &ra)
300 						errx(EXIT_FAILURE,
301 						    "elf_getrela failed: %s",
302 						     elf_errmsg(-1));
303 					n = GELF_R_SYM(ra.r_info);
304 				}
305 				if (n > 0 && n < sc)
306 					BIT_SET(ecp->v_rel, n);
307 				else if (n != 0)
308 					warnx("invalid symbox index");
309 			}
310 		}
311 		elferr = elf_errno();
312 		if (elferr != 0)
313 			errx(EXIT_FAILURE, "elf_getdata failed: %s",
314 			    elf_errmsg(elferr));
315 	}
316 	elferr = elf_errno();
317 	if (elferr != 0)
318 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
319 		    elf_errmsg(elferr));
320 }
321 
322 static void
323 mark_section_group_symbols(struct elfcopy *ecp, size_t sc)
324 {
325 	const char	*name;
326 	Elf_Scn		*s;
327 	GElf_Shdr	 sh;
328 	size_t		 indx;
329 	int		 elferr;
330 
331 	ecp->v_grp = calloc((sc + 7) / 8, 1);
332 	if (ecp->v_grp == NULL)
333 		err(EXIT_FAILURE, "calloc failed");
334 
335 	if (elf_getshstrndx(ecp->ein, &indx) == 0)
336 		errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
337 		    elf_errmsg(-1));
338 
339 	s = NULL;
340 	while ((s = elf_nextscn(ecp->ein, s)) != NULL) {
341 		if (gelf_getshdr(s, &sh) != &sh)
342 			errx(EXIT_FAILURE, "elf_getshdr failed: %s",
343 			    elf_errmsg(-1));
344 
345 		if (sh.sh_type != SHT_GROUP)
346 			continue;
347 
348 		if ((name = elf_strptr(ecp->ein, indx, sh.sh_name)) == NULL)
349 			errx(EXIT_FAILURE, "elf_strptr failed: %s",
350 			    elf_errmsg(-1));
351 		if (is_remove_section(ecp, name))
352 			continue;
353 
354 		if (sh.sh_info > 0 && sh.sh_info < sc)
355 			BIT_SET(ecp->v_grp, sh.sh_info);
356 		else if (sh.sh_info != 0)
357 			warnx("invalid symbox index");
358 	}
359 	elferr = elf_errno();
360 	if (elferr != 0)
361 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
362 		    elf_errmsg(elferr));
363 }
364 
365 static int
366 generate_symbols(struct elfcopy *ecp)
367 {
368 	struct section	*s;
369 	struct symop	*sp;
370 	struct symbuf	*sy_buf;
371 	struct strbuf	*st_buf;
372 	const char	*name;
373 	char		*newname;
374 	unsigned char	*gsym;
375 	GElf_Shdr	 ish;
376 	GElf_Sym	 sym;
377 	Elf_Data*	 id;
378 	Elf_Scn		*is;
379 	size_t		 ishstrndx, namelen, ndx, sc, symndx;
380 	int		 ec, elferr, i;
381 
382 	if (elf_getshstrndx(ecp->ein, &ishstrndx) == 0)
383 		errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
384 		    elf_errmsg(-1));
385 	if ((ec = gelf_getclass(ecp->eout)) == ELFCLASSNONE)
386 		errx(EXIT_FAILURE, "gelf_getclass failed: %s",
387 		    elf_errmsg(-1));
388 
389 	/* Create buffers for .symtab and .strtab. */
390 	if ((sy_buf = calloc(1, sizeof(*sy_buf))) == NULL)
391 		err(EXIT_FAILURE, "calloc failed");
392 	if ((st_buf = calloc(1, sizeof(*st_buf))) == NULL)
393 		err(EXIT_FAILURE, "calloc failed");
394 	sy_buf->gcap = sy_buf->lcap = 64;
395 	st_buf->g.cap = 256;
396 	st_buf->l.cap = 64;
397 	st_buf->l.sz = 1;	/* '\0' at start. */
398 	st_buf->g.sz = 0;
399 
400 	ecp->symtab->sz = 0;
401 	ecp->strtab->sz = 0;
402 	ecp->symtab->buf = sy_buf;
403 	ecp->strtab->buf = st_buf;
404 
405 	gsym = NULL;
406 
407 	/*
408 	 * Create bit vector v_secsym, which is used to mark sections
409 	 * that already have corresponding STT_SECTION symbols.
410 	 */
411 	ecp->v_secsym = calloc((ecp->nos + 7) / 8, 1);
412 	if (ecp->v_secsym == NULL)
413 		err(EXIT_FAILURE, "calloc failed");
414 
415 	/* Locate .strtab of input object. */
416 	symndx = 0;
417 	name = NULL;
418 	is = NULL;
419 	while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
420 		if (gelf_getshdr(is, &ish) != &ish)
421 			errx(EXIT_FAILURE, "elf_getshdr failed: %s",
422 			    elf_errmsg(-1));
423 		if ((name = elf_strptr(ecp->ein, ishstrndx, ish.sh_name)) ==
424 		    NULL)
425 			errx(EXIT_FAILURE, "elf_strptr failed: %s",
426 			    elf_errmsg(-1));
427 		if (strcmp(name, ".strtab") == 0) {
428 			symndx = elf_ndxscn(is);
429 			break;
430 		}
431 	}
432 	elferr = elf_errno();
433 	if (elferr != 0)
434 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
435 		    elf_errmsg(elferr));
436 
437 	/* Symbol table should exist if this function is called. */
438 	if (symndx == 0) {
439 		warnx("can't find .strtab section");
440 		goto clean;
441 	}
442 
443 	/* Locate .symtab of input object. */
444 	is = NULL;
445 	while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
446 		if (gelf_getshdr(is, &ish) != &ish)
447 			errx(EXIT_FAILURE, "elf_getshdr failed: %s",
448 			    elf_errmsg(-1));
449 		if ((name = elf_strptr(ecp->ein, ishstrndx, ish.sh_name)) ==
450 		    NULL)
451 			errx(EXIT_FAILURE, "elf_strptr failed: %s",
452 			    elf_errmsg(-1));
453 		if (strcmp(name, ".symtab") == 0)
454 			break;
455 	}
456 	elferr = elf_errno();
457 	if (elferr != 0)
458 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
459 		    elf_errmsg(elferr));
460 	if (is == NULL)
461 		errx(EXIT_FAILURE, "can't find .strtab section");
462 
463 	/*
464 	 * Create bit vector gsym to mark global symbols, and symndx
465 	 * to keep track of symbol index changes from input object to
466 	 * output object, it is used by update_reloc() later to update
467 	 * relocation information.
468 	 */
469 	sc = ish.sh_size / ish.sh_entsize;
470 	if (sc > 0) {
471 		ecp->symndx = calloc(sc, sizeof(*ecp->symndx));
472 		if (ecp->symndx == NULL)
473 			err(EXIT_FAILURE, "calloc failed");
474 		gsym = calloc((sc + 7) / 8, sizeof(*gsym));
475 		if (gsym == NULL)
476 			err(EXIT_FAILURE, "calloc failed");
477 		if ((id = elf_getdata(is, NULL)) == NULL) {
478 			elferr = elf_errno();
479 			if (elferr != 0)
480 				errx(EXIT_FAILURE, "elf_getdata failed: %s",
481 				    elf_errmsg(elferr));
482 			goto clean;
483 		}
484 	} else
485 		return (0);
486 
487 	/* Copy/Filter each symbol. */
488 	for (i = 0; (size_t)i < sc; i++) {
489 		if (gelf_getsym(id, i, &sym) != &sym)
490 			errx(EXIT_FAILURE, "gelf_getsym failed: %s",
491 			    elf_errmsg(-1));
492 		if ((name = elf_strptr(ecp->ein, symndx, sym.st_name)) == NULL)
493 			errx(EXIT_FAILURE, "elf_strptr failed: %s",
494 			    elf_errmsg(-1));
495 
496 		/* Symbol filtering. */
497 		if (is_remove_symbol(ecp, sc, i, &sym, name) != 0)
498 			continue;
499 
500 		/* Check if we need to change the binding of this symbol. */
501 		if (is_global_symbol(sym.st_info) ||
502 		    is_weak_symbol(sym.st_info)) {
503 			/*
504 			 * XXX Binutils objcopy does not weaken certain
505 			 * symbols.
506 			 */
507 			if (ecp->flags & WEAKEN_ALL ||
508 			    lookup_symop_list(ecp, name, SYMOP_WEAKEN) != NULL)
509 				sym.st_info = GELF_ST_INFO(STB_WEAK,
510 				    GELF_ST_TYPE(sym.st_info));
511 			/* Do not localize undefined symbols. */
512 			if (sym.st_shndx != SHN_UNDEF &&
513 			    lookup_symop_list(ecp, name, SYMOP_LOCALIZE) !=
514 			    NULL)
515 				sym.st_info = GELF_ST_INFO(STB_LOCAL,
516 				    GELF_ST_TYPE(sym.st_info));
517 			if (ecp->flags & KEEP_GLOBAL &&
518 			    sym.st_shndx != SHN_UNDEF &&
519 			    lookup_symop_list(ecp, name, SYMOP_KEEPG) == NULL)
520 				sym.st_info = GELF_ST_INFO(STB_LOCAL,
521 				    GELF_ST_TYPE(sym.st_info));
522 			if (ecp->flags & LOCALIZE_HIDDEN &&
523 			    sym.st_shndx != SHN_UNDEF &&
524 			    is_hidden_symbol(sym.st_other))
525 				sym.st_info = GELF_ST_INFO(STB_LOCAL,
526 				    GELF_ST_TYPE(sym.st_info));
527 		} else {
528 			/* STB_LOCAL binding. */
529 			if (lookup_symop_list(ecp, name, SYMOP_GLOBALIZE) !=
530 			    NULL)
531 				sym.st_info = GELF_ST_INFO(STB_GLOBAL,
532 				    GELF_ST_TYPE(sym.st_info));
533 			/* XXX We should globalize weak symbol? */
534 		}
535 
536 		/* Check if we need to rename this symbol. */
537 		if ((sp = lookup_symop_list(ecp, name, SYMOP_REDEF)) != NULL)
538 			name = sp->newname;
539 
540 		/* Check if we need to prefix the symbols. */
541 		newname = NULL;
542 		if (ecp->prefix_sym != NULL && name != NULL && *name != '\0') {
543 			namelen = strlen(name) + strlen(ecp->prefix_sym) + 1;
544 			if ((newname = malloc(namelen)) == NULL)
545 				err(EXIT_FAILURE, "malloc failed");
546 			snprintf(newname, namelen, "%s%s", ecp->prefix_sym,
547 			    name);
548 			name = newname;
549 		}
550 
551 		/* Copy symbol, mark global/weak symbol and add to index map. */
552 		if (is_global_symbol(sym.st_info) ||
553 		    is_weak_symbol(sym.st_info)) {
554 			BIT_SET(gsym, i);
555 			ecp->symndx[i] = sy_buf->ngs;
556 		} else
557 			ecp->symndx[i] = sy_buf->nls;
558 		add_to_symtab(ecp, name, sym.st_value, sym.st_size,
559 		    sym.st_shndx, sym.st_info, sym.st_other, 0);
560 
561 		if (newname != NULL)
562 			free(newname);
563 
564 		/*
565 		 * If the symbol is a STT_SECTION symbol, mark the section
566 		 * it points to.
567 		 */
568 		if (GELF_ST_TYPE(sym.st_info) == STT_SECTION)
569 			BIT_SET(ecp->v_secsym, ecp->secndx[sym.st_shndx]);
570 	}
571 
572 	/*
573 	 * Give up if there is no real symbols inside the table.
574 	 * XXX The logic here needs to be improved. We need to
575 	 * check if that only local symbol is the reserved symbol.
576 	 */
577 	if (sy_buf->nls <= 1 && sy_buf->ngs == 0)
578 		goto clean;
579 
580 	/*
581 	 * Create STT_SECTION symbols for sections that do not already
582 	 * got one. However, we do not create STT_SECTION symbol for
583 	 * .symtab, .strtab, .shstrtab and reloc sec of relocatables.
584 	 */
585 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
586 		if (s->pseudo)
587 			continue;
588 		if (strcmp(s->name, ".symtab") == 0 ||
589 		    strcmp(s->name, ".strtab") == 0 ||
590 		    strcmp(s->name, ".shstrtab") == 0)
591 			continue;
592 		if ((ecp->flags & RELOCATABLE) != 0 &&
593 		    ((s->type == SHT_REL) || (s->type == SHT_RELA)))
594 			continue;
595 
596 		if ((ndx = elf_ndxscn(s->os)) == SHN_UNDEF)
597 			errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
598 			    elf_errmsg(-1));
599 
600 		if (!BIT_ISSET(ecp->v_secsym, ndx)) {
601 			sym.st_name  = 0;
602 			sym.st_value = s->vma;
603 			sym.st_size  = 0;
604 			sym.st_info  = GELF_ST_INFO(STB_LOCAL, STT_SECTION);
605 			sym.st_other = STV_DEFAULT;
606 			/*
607 			 * Don't let add_to_symtab() touch sym.st_shndx.
608 			 * In this case, we know the index already.
609 			 */
610 			add_to_symtab(ecp, NULL, sym.st_value, sym.st_size,
611 			    ndx, sym.st_info, sym.st_other, 1);
612 		}
613 	}
614 
615 	/*
616 	 * Update st_name and index map for global/weak symbols. Note that
617 	 * global/weak symbols are put after local symbols.
618 	 */
619 	if (gsym != NULL) {
620 		for(i = 0; (size_t) i < sc; i++) {
621 			if (!BIT_ISSET(gsym, i))
622 				continue;
623 
624 			/* Update st_name. */
625 			if (ec == ELFCLASS32)
626 				sy_buf->g32[ecp->symndx[i]].st_name +=
627 				    st_buf->l.sz;
628 			else
629 				sy_buf->g64[ecp->symndx[i]].st_name +=
630 				    st_buf->l.sz;
631 
632 			/* Update index map. */
633 			ecp->symndx[i] += sy_buf->nls;
634 		}
635 		free(gsym);
636 	}
637 
638 	return (1);
639 
640 clean:
641 	free(gsym);
642 	free_symtab(ecp);
643 
644 	return (0);
645 }
646 
647 void
648 create_symtab(struct elfcopy *ecp)
649 {
650 	struct section	*s, *sy, *st;
651 	size_t		 maxndx, ndx;
652 
653 	sy = ecp->symtab;
654 	st = ecp->strtab;
655 
656 	/*
657 	 * Set section index map for .symtab and .strtab. We need to set
658 	 * these map because otherwise symbols which refer to .symtab and
659 	 * .strtab will be removed by symbol filtering unconditionally.
660 	 * And we have to figure out scn index this way (instead of calling
661 	 * elf_ndxscn) because we can not create Elf_Scn before we're certain
662 	 * that .symtab and .strtab will exist in the output object.
663 	 */
664 	maxndx = 0;
665 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
666 		if (s->os == NULL)
667 			continue;
668 		if ((ndx = elf_ndxscn(s->os)) == SHN_UNDEF)
669 			errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
670 			    elf_errmsg(-1));
671 		if (ndx > maxndx)
672 			maxndx = ndx;
673 	}
674 	ecp->secndx[elf_ndxscn(sy->is)] = maxndx + 1;
675 	ecp->secndx[elf_ndxscn(st->is)] = maxndx + 2;
676 
677 	/*
678 	 * Generate symbols for output object if SYMTAB_INTACT is not set.
679 	 * If there is no symbol in the input object or all the symbols are
680 	 * stripped, then free all the resouces allotted for symbol table,
681 	 * and clear SYMTAB_EXIST flag.
682 	 */
683 	if (((ecp->flags & SYMTAB_INTACT) == 0) && !generate_symbols(ecp)) {
684 		TAILQ_REMOVE(&ecp->v_sec, ecp->symtab, sec_list);
685 		TAILQ_REMOVE(&ecp->v_sec, ecp->strtab, sec_list);
686 		free(ecp->symtab->buf);
687 		free(ecp->symtab);
688 		free(ecp->strtab->buf);
689 		free(ecp->strtab);
690 		ecp->symtab = NULL;
691 		ecp->strtab = NULL;
692 		ecp->flags &= ~SYMTAB_EXIST;
693 		return;
694 	}
695 
696 	/* Create output Elf_Scn for .symtab and .strtab. */
697 	if ((sy->os = elf_newscn(ecp->eout)) == NULL ||
698 	    (st->os = elf_newscn(ecp->eout)) == NULL)
699 		errx(EXIT_FAILURE, "elf_newscn failed: %s",
700 		    elf_errmsg(-1));
701 	/* Update secndx anyway. */
702 	ecp->secndx[elf_ndxscn(sy->is)] = elf_ndxscn(sy->os);
703 	ecp->secndx[elf_ndxscn(st->is)] = elf_ndxscn(st->os);
704 
705 	/*
706 	 * Copy .symtab and .strtab section headers from input to output
707 	 * object to start with, these will be overridden later if need.
708 	 */
709 	copy_shdr(ecp, sy, ".symtab", 1, 0);
710 	copy_shdr(ecp, st, ".strtab", 1, 0);
711 
712 	/* Copy verbatim if symbol table is intact. */
713 	if (ecp->flags & SYMTAB_INTACT) {
714 		copy_data(sy);
715 		copy_data(st);
716 		return;
717 	}
718 
719 	create_symtab_data(ecp);
720 }
721 
722 void
723 free_symtab(struct elfcopy *ecp)
724 {
725 	struct symbuf	*sy_buf;
726 	struct strbuf	*st_buf;
727 	struct sthash	*sh, *shtmp;
728 	int i;
729 
730 	if (ecp->symtab != NULL && ecp->symtab->buf != NULL) {
731 		sy_buf = ecp->symtab->buf;
732 		if (sy_buf->l32 != NULL)
733 			free(sy_buf->l32);
734 		if (sy_buf->g32 != NULL)
735 			free(sy_buf->g32);
736 		if (sy_buf->l64 != NULL)
737 			free(sy_buf->l64);
738 		if (sy_buf->g64 != NULL)
739 			free(sy_buf->g64);
740 	}
741 
742 	if (ecp->strtab != NULL && ecp->strtab->buf != NULL) {
743 		st_buf = ecp->strtab->buf;
744 		if (st_buf->l.buf != NULL)
745 			free(st_buf->l.buf);
746 		if (st_buf->g.buf != NULL)
747 			free(st_buf->g.buf);
748 		for (i = 0; i < STHASHSIZE; i++) {
749 			LIST_FOREACH_SAFE(sh, &st_buf->l.hash[i], sh_next,
750 			    shtmp) {
751 				LIST_REMOVE(sh, sh_next);
752 				free(sh);
753 			}
754 			LIST_FOREACH_SAFE(sh, &st_buf->g.hash[i], sh_next,
755 			    shtmp) {
756 				LIST_REMOVE(sh, sh_next);
757 				free(sh);
758 			}
759 		}
760 	}
761 
762 	if (ecp->symndx != NULL) {
763 		free(ecp->symndx);
764 		ecp->symndx = NULL;
765 	}
766 	if (ecp->v_rel != NULL) {
767 		free(ecp->v_rel);
768 		ecp->v_rel = NULL;
769 	}
770 	if (ecp->v_grp != NULL) {
771 		free(ecp->v_grp);
772 		ecp->v_grp = NULL;
773 	}
774 	if (ecp->v_secsym != NULL) {
775 		free(ecp->v_secsym);
776 		ecp->v_secsym = NULL;
777 	}
778 }
779 
780 void
781 create_external_symtab(struct elfcopy *ecp)
782 {
783 	struct section *s;
784 	struct symbuf *sy_buf;
785 	struct strbuf *st_buf;
786 	GElf_Shdr sh;
787 	size_t ndx;
788 
789 	if (ecp->oec == ELFCLASS32)
790 		ecp->symtab = create_external_section(ecp, ".symtab", NULL,
791 		    NULL, 0, 0, SHT_SYMTAB, ELF_T_SYM, 0, 4, 0, 0);
792 	else
793 		ecp->symtab = create_external_section(ecp, ".symtab", NULL,
794 		    NULL, 0, 0, SHT_SYMTAB, ELF_T_SYM, 0, 8, 0, 0);
795 
796 	ecp->strtab = create_external_section(ecp, ".strtab", NULL, NULL, 0, 0,
797 	    SHT_STRTAB, ELF_T_BYTE, 0, 1, 0, 0);
798 
799 	/* Let sh_link field of .symtab section point to .strtab section. */
800 	if (gelf_getshdr(ecp->symtab->os, &sh) == NULL)
801 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
802 		    elf_errmsg(-1));
803 	sh.sh_link = elf_ndxscn(ecp->strtab->os);
804 	if (!gelf_update_shdr(ecp->symtab->os, &sh))
805 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
806 		    elf_errmsg(-1));
807 
808 	/* Create buffers for .symtab and .strtab. */
809 	if ((sy_buf = calloc(1, sizeof(*sy_buf))) == NULL)
810 		err(EXIT_FAILURE, "calloc failed");
811 	if ((st_buf = calloc(1, sizeof(*st_buf))) == NULL)
812 		err(EXIT_FAILURE, "calloc failed");
813 	sy_buf->gcap = sy_buf->lcap = 64;
814 	st_buf->g.cap = 256;
815 	st_buf->l.cap = 64;
816 	st_buf->l.sz = 1;	/* '\0' at start. */
817 	st_buf->g.sz = 0;
818 
819 	ecp->symtab->sz = 0;
820 	ecp->strtab->sz = 0;
821 	ecp->symtab->buf = sy_buf;
822 	ecp->strtab->buf = st_buf;
823 
824 	/* Always create the special symbol at the symtab beginning. */
825 	add_to_symtab(ecp, NULL, 0, 0, SHN_UNDEF,
826 	    ELF32_ST_INFO(STB_LOCAL, STT_NOTYPE), 0, 1);
827 
828 	/* Create STT_SECTION symbols. */
829 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
830 		if (s->pseudo)
831 			continue;
832 		if (strcmp(s->name, ".symtab") == 0 ||
833 		    strcmp(s->name, ".strtab") == 0 ||
834 		    strcmp(s->name, ".shstrtab") == 0)
835 			continue;
836 		(void) elf_errno();
837 		if ((ndx = elf_ndxscn(s->os)) == SHN_UNDEF) {
838 			warnx("elf_ndxscn failed: %s",
839 			    elf_errmsg(-1));
840 			continue;
841 		}
842 		add_to_symtab(ecp, NULL, 0, 0, ndx,
843 		    GELF_ST_INFO(STB_LOCAL, STT_SECTION), 0, 1);
844 	}
845 }
846 
847 void
848 add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value,
849     uint64_t st_size, uint16_t st_shndx, unsigned char st_info,
850     unsigned char st_other, int ndx_known)
851 {
852 	struct symbuf *sy_buf;
853 	struct strbuf *st_buf;
854 	struct sthash *sh;
855 	uint32_t hash;
856 	int pos;
857 
858 	/*
859 	 * Convenient macro for copying global/local 32/64 bit symbols
860 	 * from input object to the buffer created for output object.
861 	 * It handles buffer growing, st_name calculating and st_shndx
862 	 * updating for symbols with non-special section index.
863 	 */
864 #define	_ADDSYM(B, SZ) do {						\
865 	if (sy_buf->B##SZ == NULL) {					\
866 		sy_buf->B##SZ = malloc(sy_buf->B##cap *			\
867 		    sizeof(Elf##SZ##_Sym));				\
868 		if (sy_buf->B##SZ == NULL)				\
869 			err(EXIT_FAILURE, "malloc failed");		\
870 	} else if (sy_buf->n##B##s >= sy_buf->B##cap) {			\
871 		sy_buf->B##cap *= 2;					\
872 		sy_buf->B##SZ = realloc(sy_buf->B##SZ, sy_buf->B##cap *	\
873 		    sizeof(Elf##SZ##_Sym));				\
874 		if (sy_buf->B##SZ == NULL)				\
875 			err(EXIT_FAILURE, "realloc failed");		\
876 	}								\
877 	sy_buf->B##SZ[sy_buf->n##B##s].st_info	= st_info;		\
878 	sy_buf->B##SZ[sy_buf->n##B##s].st_other	= st_other;		\
879 	sy_buf->B##SZ[sy_buf->n##B##s].st_value	= st_value;		\
880 	sy_buf->B##SZ[sy_buf->n##B##s].st_size	= st_size;		\
881 	if (ndx_known)							\
882 		sy_buf->B##SZ[sy_buf->n##B##s].st_shndx = st_shndx;	\
883 	else if (st_shndx == SHN_UNDEF || st_shndx >= SHN_LORESERVE)	\
884 		sy_buf->B##SZ[sy_buf->n##B##s].st_shndx = st_shndx;	\
885 	else								\
886 		sy_buf->B##SZ[sy_buf->n##B##s].st_shndx	=		\
887 			ecp->secndx[st_shndx];				\
888 	if (st_buf->B.buf == NULL) {					\
889 		st_buf->B.buf = calloc(st_buf->B.cap,			\
890 		    sizeof(*st_buf->B.buf));				\
891 		if (st_buf->B.buf == NULL)				\
892 			err(EXIT_FAILURE, "malloc failed");		\
893 	}								\
894 	if (name != NULL && *name != '\0') {				\
895 		pos = lookup_exact_string(st_buf->B.hash, st_buf->B.buf,\
896 		    name);						\
897 		if (pos != -1)						\
898 			sy_buf->B##SZ[sy_buf->n##B##s].st_name = pos;	\
899 		else {							\
900 			sy_buf->B##SZ[sy_buf->n##B##s].st_name =	\
901 			    st_buf->B.sz;				\
902 			while (st_buf->B.sz + strlen(name) >=		\
903 			    st_buf->B.cap - 1) {			\
904 				st_buf->B.cap *= 2;			\
905 				st_buf->B.buf = realloc(st_buf->B.buf,	\
906 				    st_buf->B.cap);			\
907 				if (st_buf->B.buf == NULL)		\
908 					err(EXIT_FAILURE,		\
909 					    "realloc failed");		\
910 			}						\
911 			if ((sh = malloc(sizeof(*sh))) == NULL)		\
912 				err(EXIT_FAILURE, "malloc failed");	\
913 			sh->sh_off = st_buf->B.sz;			\
914 			hash = str_hash(name);				\
915 			LIST_INSERT_HEAD(&st_buf->B.hash[hash], sh,	\
916 			    sh_next);					\
917 			strncpy(&st_buf->B.buf[st_buf->B.sz], name,	\
918 			    strlen(name));				\
919 			st_buf->B.buf[st_buf->B.sz + strlen(name)] = '\0'; \
920 			st_buf->B.sz += strlen(name) + 1;		\
921 		}							\
922 	} else								\
923 		sy_buf->B##SZ[sy_buf->n##B##s].st_name = 0;		\
924 	sy_buf->n##B##s++;						\
925 } while (0)
926 
927 	sy_buf = ecp->symtab->buf;
928 	st_buf = ecp->strtab->buf;
929 
930 	if (ecp->oec == ELFCLASS32) {
931 		if (is_local_symbol(st_info))
932 			_ADDSYM(l, 32);
933 		else
934 			_ADDSYM(g, 32);
935 	} else {
936 		if (is_local_symbol(st_info))
937 			_ADDSYM(l, 64);
938 		else
939 			_ADDSYM(g, 64);
940 	}
941 
942 	/* Update section size. */
943 	ecp->symtab->sz = (sy_buf->nls + sy_buf->ngs) *
944 	    (ecp->oec == ELFCLASS32 ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym));
945 	ecp->strtab->sz = st_buf->l.sz + st_buf->g.sz;
946 
947 #undef	_ADDSYM
948 }
949 
950 void
951 finalize_external_symtab(struct elfcopy *ecp)
952 {
953 	struct symbuf *sy_buf;
954 	struct strbuf *st_buf;
955 	int i;
956 
957 	/*
958 	 * Update st_name for global/weak symbols. (global/weak symbols
959 	 * are put after local symbols)
960 	 */
961 	sy_buf = ecp->symtab->buf;
962 	st_buf = ecp->strtab->buf;
963 	for (i = 0; (size_t) i < sy_buf->ngs; i++) {
964 		if (ecp->oec == ELFCLASS32)
965 			sy_buf->g32[i].st_name += st_buf->l.sz;
966 		else
967 			sy_buf->g64[i].st_name += st_buf->l.sz;
968 	}
969 }
970 
971 void
972 create_symtab_data(struct elfcopy *ecp)
973 {
974 	struct section	*sy, *st;
975 	struct symbuf	*sy_buf;
976 	struct strbuf	*st_buf;
977 	Elf_Data	*gsydata, *lsydata, *gstdata, *lstdata;
978 	GElf_Shdr	 shy, sht;
979 
980 	sy = ecp->symtab;
981 	st = ecp->strtab;
982 
983 	if (gelf_getshdr(sy->os, &shy) == NULL)
984 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
985 		    elf_errmsg(-1));
986 	if (gelf_getshdr(st->os, &sht) == NULL)
987 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
988 		    elf_errmsg(-1));
989 
990 	/*
991 	 * Create two Elf_Data for .symtab section of output object, one
992 	 * for local symbols and another for global symbols. Note that
993 	 * local symbols appear first in the .symtab.
994 	 */
995 	sy_buf = sy->buf;
996 	if (sy_buf->nls > 0) {
997 		if ((lsydata = elf_newdata(sy->os)) == NULL)
998 			errx(EXIT_FAILURE, "elf_newdata() failed: %s.",
999 			     elf_errmsg(-1));
1000 		if (ecp->oec == ELFCLASS32) {
1001 			lsydata->d_align	= 4;
1002 			lsydata->d_off		= 0;
1003 			lsydata->d_buf		= sy_buf->l32;
1004 			lsydata->d_size		= sy_buf->nls *
1005 				sizeof(Elf32_Sym);
1006 			lsydata->d_type		= ELF_T_SYM;
1007 			lsydata->d_version	= EV_CURRENT;
1008 		} else {
1009 			lsydata->d_align	= 8;
1010 			lsydata->d_off		= 0;
1011 			lsydata->d_buf		= sy_buf->l64;
1012 			lsydata->d_size		= sy_buf->nls *
1013 				sizeof(Elf64_Sym);
1014 			lsydata->d_type		= ELF_T_SYM;
1015 			lsydata->d_version	= EV_CURRENT;
1016 		}
1017 	}
1018 	if (sy_buf->ngs > 0) {
1019 		if ((gsydata = elf_newdata(sy->os)) == NULL)
1020 			errx(EXIT_FAILURE, "elf_newdata() failed: %s.",
1021 			     elf_errmsg(-1));
1022 		if (ecp->oec == ELFCLASS32) {
1023 			gsydata->d_align	= 4;
1024 			gsydata->d_off		= sy_buf->nls *
1025 				sizeof(Elf32_Sym);
1026 			gsydata->d_buf		= sy_buf->g32;
1027 			gsydata->d_size		= sy_buf->ngs *
1028 				sizeof(Elf32_Sym);
1029 			gsydata->d_type		= ELF_T_SYM;
1030 			gsydata->d_version	= EV_CURRENT;
1031 		} else {
1032 			gsydata->d_align	= 8;
1033 			gsydata->d_off		= sy_buf->nls *
1034 				sizeof(Elf64_Sym);
1035 			gsydata->d_buf		= sy_buf->g64;
1036 			gsydata->d_size		= sy_buf->ngs *
1037 				sizeof(Elf64_Sym);
1038 			gsydata->d_type		= ELF_T_SYM;
1039 			gsydata->d_version	= EV_CURRENT;
1040 		}
1041 	}
1042 
1043 	/*
1044 	 * Create two Elf_Data for .strtab, one for local symbol name
1045 	 * and another for globals. Same as .symtab, local symbol names
1046 	 * appear first.
1047 	 */
1048 	st_buf = st->buf;
1049 	if ((lstdata = elf_newdata(st->os)) == NULL)
1050 		errx(EXIT_FAILURE, "elf_newdata() failed: %s.",
1051 		    elf_errmsg(-1));
1052 	lstdata->d_align	= 1;
1053 	lstdata->d_off		= 0;
1054 	lstdata->d_buf		= st_buf->l.buf;
1055 	lstdata->d_size		= st_buf->l.sz;
1056 	lstdata->d_type		= ELF_T_BYTE;
1057 	lstdata->d_version	= EV_CURRENT;
1058 
1059 	if (st_buf->g.sz > 0) {
1060 		if ((gstdata = elf_newdata(st->os)) == NULL)
1061 			errx(EXIT_FAILURE, "elf_newdata() failed: %s.",
1062 			    elf_errmsg(-1));
1063 		gstdata->d_align	= 1;
1064 		gstdata->d_off		= lstdata->d_size;
1065 		gstdata->d_buf		= st_buf->g.buf;
1066 		gstdata->d_size		= st_buf->g.sz;
1067 		gstdata->d_type		= ELF_T_BYTE;
1068 		gstdata->d_version	= EV_CURRENT;
1069 	}
1070 
1071 	shy.sh_addr		= 0;
1072 	shy.sh_addralign	= (ecp->oec == ELFCLASS32 ? 4 : 8);
1073 	shy.sh_size		= sy->sz;
1074 	shy.sh_type		= SHT_SYMTAB;
1075 	shy.sh_flags		= 0;
1076 	shy.sh_entsize		= gelf_fsize(ecp->eout, ELF_T_SYM, 1,
1077 	    EV_CURRENT);
1078 	/*
1079 	 * According to SYSV abi, here sh_info is one greater than
1080 	 * the symbol table index of the last local symbol(binding
1081 	 * STB_LOCAL).
1082 	 */
1083 	shy.sh_info		= sy_buf->nls;
1084 
1085 	sht.sh_addr		= 0;
1086 	sht.sh_addralign	= 1;
1087 	sht.sh_size		= st->sz;
1088 	sht.sh_type		= SHT_STRTAB;
1089 	sht.sh_flags		= 0;
1090 	sht.sh_entsize		= 0;
1091 	sht.sh_info		= 0;
1092 	sht.sh_link		= 0;
1093 
1094 	if (!gelf_update_shdr(sy->os, &shy))
1095 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1096 		    elf_errmsg(-1));
1097 	if (!gelf_update_shdr(st->os, &sht))
1098 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1099 		    elf_errmsg(-1));
1100 }
1101 
1102 void
1103 add_to_symop_list(struct elfcopy *ecp, const char *name, const char *newname,
1104     unsigned int op)
1105 {
1106 	struct symop *s;
1107 
1108 	if ((s = lookup_symop_list(ecp, name, ~0U)) == NULL) {
1109 		if ((s = calloc(1, sizeof(*s))) == NULL)
1110 			errx(EXIT_FAILURE, "not enough memory");
1111 		s->name = name;
1112 		if (op == SYMOP_REDEF)
1113 			s->newname = newname;
1114 	}
1115 
1116 	s->op |= op;
1117 	STAILQ_INSERT_TAIL(&ecp->v_symop, s, symop_list);
1118 }
1119 
1120 static int
1121 match_wildcard(const char *name, const char *pattern)
1122 {
1123 	int reverse, match;
1124 
1125 	reverse = 0;
1126 	if (*pattern == '!') {
1127 		reverse = 1;
1128 		pattern++;
1129 	}
1130 
1131 	match = 0;
1132 	if (!fnmatch(pattern, name, 0))
1133 		match = 1;
1134 
1135 	return (reverse ? !match : match);
1136 }
1137 
1138 struct symop *
1139 lookup_symop_list(struct elfcopy *ecp, const char *name, unsigned int op)
1140 {
1141 	struct symop *s;
1142 
1143 	STAILQ_FOREACH(s, &ecp->v_symop, symop_list) {
1144 		if (name == NULL || !strcmp(name, s->name) ||
1145 		    ((ecp->flags & WILDCARD) && match_wildcard(name, s->name)))
1146 			if ((s->op & op) != 0)
1147 				return (s);
1148 	}
1149 
1150 	return (NULL);
1151 }
1152 
1153 static int
1154 lookup_exact_string(hash_head *buckets, const char *buf, const char *s)
1155 {
1156 	struct sthash	*sh;
1157 	uint32_t	 hash;
1158 
1159 	hash = str_hash(s);
1160 	LIST_FOREACH(sh, &buckets[hash], sh_next)
1161 		if (strcmp(buf + sh->sh_off, s) == 0)
1162 			return sh->sh_off;
1163 	return (-1);
1164 }
1165 
1166 uint32_t
1167 str_hash(const char *s)
1168 {
1169 	uint32_t hash;
1170 
1171 	for (hash = 2166136261UL; *s; s++)
1172 		hash = (hash ^ *s) * 16777619;
1173 
1174 	return (hash & (STHASHSIZE - 1));
1175 }
1176