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