xref: /aosp_15_r20/external/elfutils/src/arlib.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
1*7304104dSAndroid Build Coastguard Worker /* Functions to handle creation of Linux archives.
2*7304104dSAndroid Build Coastguard Worker    Copyright (C) 2007-2012, 2016 Red Hat, Inc.
3*7304104dSAndroid Build Coastguard Worker    This file is part of elfutils.
4*7304104dSAndroid Build Coastguard Worker    Written by Ulrich Drepper <[email protected]>, 2007.
5*7304104dSAndroid Build Coastguard Worker 
6*7304104dSAndroid Build Coastguard Worker    This file is free software; you can redistribute it and/or modify
7*7304104dSAndroid Build Coastguard Worker    it under the terms of the GNU General Public License as published by
8*7304104dSAndroid Build Coastguard Worker    the Free Software Foundation; either version 3 of the License, or
9*7304104dSAndroid Build Coastguard Worker    (at your option) any later version.
10*7304104dSAndroid Build Coastguard Worker 
11*7304104dSAndroid Build Coastguard Worker    elfutils is distributed in the hope that it will be useful, but
12*7304104dSAndroid Build Coastguard Worker    WITHOUT ANY WARRANTY; without even the implied warranty of
13*7304104dSAndroid Build Coastguard Worker    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*7304104dSAndroid Build Coastguard Worker    GNU General Public License for more details.
15*7304104dSAndroid Build Coastguard Worker 
16*7304104dSAndroid Build Coastguard Worker    You should have received a copy of the GNU General Public License
17*7304104dSAndroid Build Coastguard Worker    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18*7304104dSAndroid Build Coastguard Worker 
19*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
20*7304104dSAndroid Build Coastguard Worker # include <config.h>
21*7304104dSAndroid Build Coastguard Worker #endif
22*7304104dSAndroid Build Coastguard Worker 
23*7304104dSAndroid Build Coastguard Worker #include <assert.h>
24*7304104dSAndroid Build Coastguard Worker #include <gelf.h>
25*7304104dSAndroid Build Coastguard Worker #include <inttypes.h>
26*7304104dSAndroid Build Coastguard Worker #include <stdio.h>
27*7304104dSAndroid Build Coastguard Worker #include <stdlib.h>
28*7304104dSAndroid Build Coastguard Worker #include <time.h>
29*7304104dSAndroid Build Coastguard Worker 
30*7304104dSAndroid Build Coastguard Worker #include <libeu.h>
31*7304104dSAndroid Build Coastguard Worker 
32*7304104dSAndroid Build Coastguard Worker #include "system.h"
33*7304104dSAndroid Build Coastguard Worker #include "arlib.h"
34*7304104dSAndroid Build Coastguard Worker 
35*7304104dSAndroid Build Coastguard Worker 
36*7304104dSAndroid Build Coastguard Worker /* The one symbol table we hanble.  */
37*7304104dSAndroid Build Coastguard Worker struct arlib_symtab symtab;
38*7304104dSAndroid Build Coastguard Worker 
39*7304104dSAndroid Build Coastguard Worker 
40*7304104dSAndroid Build Coastguard Worker /* Initialize ARLIB_SYMTAB structure.  */
41*7304104dSAndroid Build Coastguard Worker void
arlib_init(void)42*7304104dSAndroid Build Coastguard Worker arlib_init (void)
43*7304104dSAndroid Build Coastguard Worker {
44*7304104dSAndroid Build Coastguard Worker #define obstack_chunk_alloc xmalloc
45*7304104dSAndroid Build Coastguard Worker #define obstack_chunk_free free
46*7304104dSAndroid Build Coastguard Worker   obstack_init (&symtab.symsoffob);
47*7304104dSAndroid Build Coastguard Worker   obstack_init (&symtab.symsnameob);
48*7304104dSAndroid Build Coastguard Worker   obstack_init (&symtab.longnamesob);
49*7304104dSAndroid Build Coastguard Worker 
50*7304104dSAndroid Build Coastguard Worker   /* We add the archive header here as well, that avoids allocating
51*7304104dSAndroid Build Coastguard Worker      another memory block.  */
52*7304104dSAndroid Build Coastguard Worker   struct ar_hdr ar_hdr;
53*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_name, "/               ", sizeof (ar_hdr.ar_name));
54*7304104dSAndroid Build Coastguard Worker   /* Using snprintf here has a problem: the call always wants to add a
55*7304104dSAndroid Build Coastguard Worker      NUL byte.  We could use a trick whereby we specify the target
56*7304104dSAndroid Build Coastguard Worker      buffer size longer than it is and this would not actually fail,
57*7304104dSAndroid Build Coastguard Worker      since all the fields are consecutive and we fill them in
58*7304104dSAndroid Build Coastguard Worker      sequence (i.e., the NUL byte gets overwritten).  But
59*7304104dSAndroid Build Coastguard Worker      _FORTIFY_SOURCE=2 would not let us play these games.  Therefore
60*7304104dSAndroid Build Coastguard Worker      we play it safe.  */
61*7304104dSAndroid Build Coastguard Worker   char tmpbuf[sizeof (ar_hdr.ar_date) + 1];
62*7304104dSAndroid Build Coastguard Worker   int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*lld",
63*7304104dSAndroid Build Coastguard Worker 		    (int) sizeof (ar_hdr.ar_date),
64*7304104dSAndroid Build Coastguard Worker                     (arlib_deterministic_output ? 0
65*7304104dSAndroid Build Coastguard Worker                      : (long long int) time (NULL)));
66*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_date, tmpbuf, s);
67*7304104dSAndroid Build Coastguard Worker   assert ((sizeof (struct ar_hdr)  % sizeof (uint32_t)) == 0);
68*7304104dSAndroid Build Coastguard Worker 
69*7304104dSAndroid Build Coastguard Worker   /* Note the string for the ar_uid and ar_gid cases is longer than
70*7304104dSAndroid Build Coastguard Worker      necessary.  This does not matter since we copy only as much as
71*7304104dSAndroid Build Coastguard Worker      necessary but it helps the compiler to use the same string for
72*7304104dSAndroid Build Coastguard Worker      the ar_mode case.  */
73*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_uid, "0       ", sizeof (ar_hdr.ar_uid));
74*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_gid, "0       ", sizeof (ar_hdr.ar_gid));
75*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_mode, "0       ", sizeof (ar_hdr.ar_mode));
76*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_fmag, ARFMAG, sizeof (ar_hdr.ar_fmag));
77*7304104dSAndroid Build Coastguard Worker 
78*7304104dSAndroid Build Coastguard Worker   /* Add the archive header to the file content.  */
79*7304104dSAndroid Build Coastguard Worker   obstack_grow (&symtab.symsoffob, &ar_hdr, sizeof (ar_hdr));
80*7304104dSAndroid Build Coastguard Worker 
81*7304104dSAndroid Build Coastguard Worker   /* The first word in the offset table specifies the size.  Create
82*7304104dSAndroid Build Coastguard Worker      such an entry now.  The real value will be filled-in later.  For
83*7304104dSAndroid Build Coastguard Worker      all supported platforms the following is true.  */
84*7304104dSAndroid Build Coastguard Worker   assert (sizeof (uint32_t) == sizeof (int));
85*7304104dSAndroid Build Coastguard Worker   obstack_int_grow (&symtab.symsoffob, 0);
86*7304104dSAndroid Build Coastguard Worker 
87*7304104dSAndroid Build Coastguard Worker   /* The long name obstack also gets its archive header.  As above,
88*7304104dSAndroid Build Coastguard Worker      some of the input strings are longer than required but we only
89*7304104dSAndroid Build Coastguard Worker      copy the necessary part.  */
90*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_name, "//              ", sizeof (ar_hdr.ar_name));
91*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_date, "            ", sizeof (ar_hdr.ar_date));
92*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_uid, "            ", sizeof (ar_hdr.ar_uid));
93*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_gid, "            ", sizeof (ar_hdr.ar_gid));
94*7304104dSAndroid Build Coastguard Worker   memcpy (ar_hdr.ar_mode, "            ", sizeof (ar_hdr.ar_mode));
95*7304104dSAndroid Build Coastguard Worker   /* The ar_size field will be filled in later and ar_fmag is already OK.  */
96*7304104dSAndroid Build Coastguard Worker   obstack_grow (&symtab.longnamesob, &ar_hdr, sizeof (ar_hdr));
97*7304104dSAndroid Build Coastguard Worker 
98*7304104dSAndroid Build Coastguard Worker   /* All other members are zero.  */
99*7304104dSAndroid Build Coastguard Worker   symtab.symsofflen = 0;
100*7304104dSAndroid Build Coastguard Worker   symtab.symsoff = NULL;
101*7304104dSAndroid Build Coastguard Worker   symtab.symsnamelen = 0;
102*7304104dSAndroid Build Coastguard Worker   symtab.symsname = NULL;
103*7304104dSAndroid Build Coastguard Worker }
104*7304104dSAndroid Build Coastguard Worker 
105*7304104dSAndroid Build Coastguard Worker 
106*7304104dSAndroid Build Coastguard Worker /* Finalize ARLIB_SYMTAB content.  */
107*7304104dSAndroid Build Coastguard Worker void
arlib_finalize(void)108*7304104dSAndroid Build Coastguard Worker arlib_finalize (void)
109*7304104dSAndroid Build Coastguard Worker {
110*7304104dSAndroid Build Coastguard Worker   /* Note that the size is stored as decimal string in 10 chars,
111*7304104dSAndroid Build Coastguard Worker      without zero terminator (we add + 1 here only so snprintf can
112*7304104dSAndroid Build Coastguard Worker      put it at the end, we then don't use it when we memcpy it).  */
113*7304104dSAndroid Build Coastguard Worker   char tmpbuf[sizeof (((struct ar_hdr *) NULL)->ar_size) + 1];
114*7304104dSAndroid Build Coastguard Worker 
115*7304104dSAndroid Build Coastguard Worker   symtab.longnameslen = obstack_object_size (&symtab.longnamesob);
116*7304104dSAndroid Build Coastguard Worker   if (symtab.longnameslen != sizeof (struct ar_hdr))
117*7304104dSAndroid Build Coastguard Worker     {
118*7304104dSAndroid Build Coastguard Worker       if ((symtab.longnameslen & 1) != 0)
119*7304104dSAndroid Build Coastguard Worker 	{
120*7304104dSAndroid Build Coastguard Worker 	  /* Add one more byte to make length even.  */
121*7304104dSAndroid Build Coastguard Worker 	  obstack_grow (&symtab.longnamesob, "\n", 1);
122*7304104dSAndroid Build Coastguard Worker 	  ++symtab.longnameslen;
123*7304104dSAndroid Build Coastguard Worker 	}
124*7304104dSAndroid Build Coastguard Worker 
125*7304104dSAndroid Build Coastguard Worker       symtab.longnames = obstack_finish (&symtab.longnamesob);
126*7304104dSAndroid Build Coastguard Worker 
127*7304104dSAndroid Build Coastguard Worker       int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRIu32 "",
128*7304104dSAndroid Build Coastguard Worker 			(int) sizeof (((struct ar_hdr *) NULL)->ar_size),
129*7304104dSAndroid Build Coastguard Worker 			(uint32_t) (symtab.longnameslen - sizeof (struct ar_hdr)));
130*7304104dSAndroid Build Coastguard Worker       memcpy (&((struct ar_hdr *) symtab.longnames)->ar_size, tmpbuf, s);
131*7304104dSAndroid Build Coastguard Worker     }
132*7304104dSAndroid Build Coastguard Worker 
133*7304104dSAndroid Build Coastguard Worker   symtab.symsofflen = obstack_object_size (&symtab.symsoffob);
134*7304104dSAndroid Build Coastguard Worker   assert (symtab.symsofflen % sizeof (uint32_t) == 0);
135*7304104dSAndroid Build Coastguard Worker   if (symtab.symsofflen != 0)
136*7304104dSAndroid Build Coastguard Worker     {
137*7304104dSAndroid Build Coastguard Worker       symtab.symsoff = (uint32_t *) obstack_finish (&symtab.symsoffob);
138*7304104dSAndroid Build Coastguard Worker 
139*7304104dSAndroid Build Coastguard Worker       /* Fill in the number of offsets now.  */
140*7304104dSAndroid Build Coastguard Worker       symtab.symsoff[AR_HDR_WORDS] = le_bswap_32 ((symtab.symsofflen
141*7304104dSAndroid Build Coastguard Worker 						    - sizeof (struct ar_hdr))
142*7304104dSAndroid Build Coastguard Worker 						   / sizeof (uint32_t) - 1);
143*7304104dSAndroid Build Coastguard Worker     }
144*7304104dSAndroid Build Coastguard Worker 
145*7304104dSAndroid Build Coastguard Worker   symtab.symsnamelen = obstack_object_size (&symtab.symsnameob);
146*7304104dSAndroid Build Coastguard Worker   if ((symtab.symsnamelen & 1) != 0)
147*7304104dSAndroid Build Coastguard Worker     {
148*7304104dSAndroid Build Coastguard Worker       /* Add one more NUL byte to make length even.  */
149*7304104dSAndroid Build Coastguard Worker       obstack_grow (&symtab.symsnameob, "", 1);
150*7304104dSAndroid Build Coastguard Worker       ++symtab.symsnamelen;
151*7304104dSAndroid Build Coastguard Worker     }
152*7304104dSAndroid Build Coastguard Worker   symtab.symsname = obstack_finish (&symtab.symsnameob);
153*7304104dSAndroid Build Coastguard Worker 
154*7304104dSAndroid Build Coastguard Worker   /* Determine correction for the offsets in the symbol table.   */
155*7304104dSAndroid Build Coastguard Worker   off_t disp = 0;
156*7304104dSAndroid Build Coastguard Worker   if (symtab.symsnamelen > 0)
157*7304104dSAndroid Build Coastguard Worker     disp = symtab.symsofflen + symtab.symsnamelen;
158*7304104dSAndroid Build Coastguard Worker   if (symtab.longnameslen > sizeof (struct ar_hdr))
159*7304104dSAndroid Build Coastguard Worker     disp += symtab.longnameslen;
160*7304104dSAndroid Build Coastguard Worker 
161*7304104dSAndroid Build Coastguard Worker   if (disp != 0 && symtab.symsoff != NULL)
162*7304104dSAndroid Build Coastguard Worker     {
163*7304104dSAndroid Build Coastguard Worker       uint32_t nsyms = le_bswap_32 (symtab.symsoff[AR_HDR_WORDS]);
164*7304104dSAndroid Build Coastguard Worker 
165*7304104dSAndroid Build Coastguard Worker       for (uint32_t cnt = 1; cnt <= nsyms; ++cnt)
166*7304104dSAndroid Build Coastguard Worker 	{
167*7304104dSAndroid Build Coastguard Worker 	  uint32_t val = le_bswap_32 (symtab.symsoff[AR_HDR_WORDS + cnt]);
168*7304104dSAndroid Build Coastguard Worker 	  val += disp;
169*7304104dSAndroid Build Coastguard Worker 	  symtab.symsoff[AR_HDR_WORDS + cnt] = le_bswap_32 (val);
170*7304104dSAndroid Build Coastguard Worker 	}
171*7304104dSAndroid Build Coastguard Worker     }
172*7304104dSAndroid Build Coastguard Worker 
173*7304104dSAndroid Build Coastguard Worker   /* See comment for ar_date above.  */
174*7304104dSAndroid Build Coastguard Worker   memcpy (&((struct ar_hdr *) symtab.symsoff)->ar_size, tmpbuf,
175*7304104dSAndroid Build Coastguard Worker 	  snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRIu32 "",
176*7304104dSAndroid Build Coastguard Worker 		    (int) sizeof (((struct ar_hdr *) NULL)->ar_size),
177*7304104dSAndroid Build Coastguard Worker 		    (uint32_t) (symtab.symsofflen + symtab.symsnamelen
178*7304104dSAndroid Build Coastguard Worker 				- sizeof (struct ar_hdr))));
179*7304104dSAndroid Build Coastguard Worker }
180*7304104dSAndroid Build Coastguard Worker 
181*7304104dSAndroid Build Coastguard Worker 
182*7304104dSAndroid Build Coastguard Worker /* Free resources for ARLIB_SYMTAB.  */
183*7304104dSAndroid Build Coastguard Worker void
arlib_fini(void)184*7304104dSAndroid Build Coastguard Worker arlib_fini (void)
185*7304104dSAndroid Build Coastguard Worker {
186*7304104dSAndroid Build Coastguard Worker   obstack_free (&symtab.symsoffob, NULL);
187*7304104dSAndroid Build Coastguard Worker   obstack_free (&symtab.symsnameob, NULL);
188*7304104dSAndroid Build Coastguard Worker   obstack_free (&symtab.longnamesob, NULL);
189*7304104dSAndroid Build Coastguard Worker }
190*7304104dSAndroid Build Coastguard Worker 
191*7304104dSAndroid Build Coastguard Worker 
192*7304104dSAndroid Build Coastguard Worker /* Add name a file offset of a symbol.  */
193*7304104dSAndroid Build Coastguard Worker void
arlib_add_symref(const char * symname,off_t symoff)194*7304104dSAndroid Build Coastguard Worker arlib_add_symref (const char *symname, off_t symoff)
195*7304104dSAndroid Build Coastguard Worker {
196*7304104dSAndroid Build Coastguard Worker   /* For all supported platforms the following is true.  */
197*7304104dSAndroid Build Coastguard Worker   assert (sizeof (uint32_t) == sizeof (int));
198*7304104dSAndroid Build Coastguard Worker   obstack_int_grow (&symtab.symsoffob, (int) le_bswap_32 (symoff));
199*7304104dSAndroid Build Coastguard Worker 
200*7304104dSAndroid Build Coastguard Worker   size_t symname_len = strlen (symname) + 1;
201*7304104dSAndroid Build Coastguard Worker   obstack_grow (&symtab.symsnameob, symname, symname_len);
202*7304104dSAndroid Build Coastguard Worker }
203*7304104dSAndroid Build Coastguard Worker 
204*7304104dSAndroid Build Coastguard Worker 
205*7304104dSAndroid Build Coastguard Worker /* Add symbols from ELF with value OFFSET to the symbol table SYMTAB.  */
206*7304104dSAndroid Build Coastguard Worker void
arlib_add_symbols(Elf * elf,const char * arfname,const char * membername,off_t off)207*7304104dSAndroid Build Coastguard Worker arlib_add_symbols (Elf *elf, const char *arfname, const char *membername,
208*7304104dSAndroid Build Coastguard Worker 		   off_t off)
209*7304104dSAndroid Build Coastguard Worker {
210*7304104dSAndroid Build Coastguard Worker   if (sizeof (off) > sizeof (uint32_t) && off > ~((uint32_t) 0))
211*7304104dSAndroid Build Coastguard Worker     /* The archive is too big.  */
212*7304104dSAndroid Build Coastguard Worker     error_exit (0, _("the archive '%s' is too large"),
213*7304104dSAndroid Build Coastguard Worker 		arfname);
214*7304104dSAndroid Build Coastguard Worker 
215*7304104dSAndroid Build Coastguard Worker   /* We only add symbol tables for ELF files.  It makes not much sense
216*7304104dSAndroid Build Coastguard Worker      to add symbols from executables but we do so for compatibility.
217*7304104dSAndroid Build Coastguard Worker      For DSOs and executables we use the dynamic symbol table, for
218*7304104dSAndroid Build Coastguard Worker      relocatable files all the DT_SYMTAB tables.  */
219*7304104dSAndroid Build Coastguard Worker   if (elf_kind (elf) != ELF_K_ELF)
220*7304104dSAndroid Build Coastguard Worker     return;
221*7304104dSAndroid Build Coastguard Worker 
222*7304104dSAndroid Build Coastguard Worker   GElf_Ehdr ehdr_mem;
223*7304104dSAndroid Build Coastguard Worker   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
224*7304104dSAndroid Build Coastguard Worker   if (ehdr == NULL)
225*7304104dSAndroid Build Coastguard Worker     error_exit (0, _("cannot read ELF header of %s(%s): %s"),
226*7304104dSAndroid Build Coastguard Worker 		arfname, membername, elf_errmsg (-1));
227*7304104dSAndroid Build Coastguard Worker 
228*7304104dSAndroid Build Coastguard Worker   GElf_Word symtype;
229*7304104dSAndroid Build Coastguard Worker   if (ehdr->e_type == ET_REL)
230*7304104dSAndroid Build Coastguard Worker     symtype = SHT_SYMTAB;
231*7304104dSAndroid Build Coastguard Worker   else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN)
232*7304104dSAndroid Build Coastguard Worker     symtype = SHT_DYNSYM;
233*7304104dSAndroid Build Coastguard Worker   else
234*7304104dSAndroid Build Coastguard Worker     /* We do not handle that type.  */
235*7304104dSAndroid Build Coastguard Worker     return;
236*7304104dSAndroid Build Coastguard Worker 
237*7304104dSAndroid Build Coastguard Worker   /* Iterate over all sections.  */
238*7304104dSAndroid Build Coastguard Worker   Elf_Scn *scn = NULL;
239*7304104dSAndroid Build Coastguard Worker   while ((scn = elf_nextscn (elf, scn)) != NULL)
240*7304104dSAndroid Build Coastguard Worker     {
241*7304104dSAndroid Build Coastguard Worker       /* Get the section header.  */
242*7304104dSAndroid Build Coastguard Worker       GElf_Shdr shdr_mem;
243*7304104dSAndroid Build Coastguard Worker       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
244*7304104dSAndroid Build Coastguard Worker       if (shdr == NULL)
245*7304104dSAndroid Build Coastguard Worker 	continue;
246*7304104dSAndroid Build Coastguard Worker 
247*7304104dSAndroid Build Coastguard Worker       if (shdr->sh_type != symtype)
248*7304104dSAndroid Build Coastguard Worker 	continue;
249*7304104dSAndroid Build Coastguard Worker 
250*7304104dSAndroid Build Coastguard Worker       Elf_Data *data = elf_getdata (scn, NULL);
251*7304104dSAndroid Build Coastguard Worker       if (data == NULL)
252*7304104dSAndroid Build Coastguard Worker 	continue;
253*7304104dSAndroid Build Coastguard Worker 
254*7304104dSAndroid Build Coastguard Worker       if (shdr->sh_entsize == 0)
255*7304104dSAndroid Build Coastguard Worker 	continue;
256*7304104dSAndroid Build Coastguard Worker 
257*7304104dSAndroid Build Coastguard Worker       int nsyms = shdr->sh_size / shdr->sh_entsize;
258*7304104dSAndroid Build Coastguard Worker       for (int ndx = shdr->sh_info; ndx < nsyms; ++ndx)
259*7304104dSAndroid Build Coastguard Worker 	{
260*7304104dSAndroid Build Coastguard Worker 	  GElf_Sym sym_mem;
261*7304104dSAndroid Build Coastguard Worker 	  GElf_Sym *sym = gelf_getsym (data, ndx, &sym_mem);
262*7304104dSAndroid Build Coastguard Worker 	  if (sym == NULL)
263*7304104dSAndroid Build Coastguard Worker 	    continue;
264*7304104dSAndroid Build Coastguard Worker 
265*7304104dSAndroid Build Coastguard Worker 	  /* Ignore undefined symbols.  */
266*7304104dSAndroid Build Coastguard Worker 	  if (sym->st_shndx == SHN_UNDEF)
267*7304104dSAndroid Build Coastguard Worker 	    continue;
268*7304104dSAndroid Build Coastguard Worker 
269*7304104dSAndroid Build Coastguard Worker 	  /* Use this symbol.  */
270*7304104dSAndroid Build Coastguard Worker 	  const char *symname = elf_strptr (elf, shdr->sh_link, sym->st_name);
271*7304104dSAndroid Build Coastguard Worker 	  if (symname != NULL)
272*7304104dSAndroid Build Coastguard Worker 	    arlib_add_symref (symname, off);
273*7304104dSAndroid Build Coastguard Worker 	}
274*7304104dSAndroid Build Coastguard Worker 
275*7304104dSAndroid Build Coastguard Worker       /* Only relocatable files can have more than one symbol table.  */
276*7304104dSAndroid Build Coastguard Worker       if (ehdr->e_type != ET_REL)
277*7304104dSAndroid Build Coastguard Worker 	break;
278*7304104dSAndroid Build Coastguard Worker     }
279*7304104dSAndroid Build Coastguard Worker }
280