xref: /aosp_15_r20/external/elfutils/libdwelf/dwelf_strtab.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
1*7304104dSAndroid Build Coastguard Worker /* ELF/DWARF string table handling.
2*7304104dSAndroid Build Coastguard Worker    Copyright (C) 2000, 2001, 2002, 2005, 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]>, 2000.
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 either
8*7304104dSAndroid Build Coastguard Worker 
9*7304104dSAndroid Build Coastguard Worker      * the GNU Lesser General Public License as published by the Free
10*7304104dSAndroid Build Coastguard Worker        Software Foundation; either version 3 of the License, or (at
11*7304104dSAndroid Build Coastguard Worker        your option) any later version
12*7304104dSAndroid Build Coastguard Worker 
13*7304104dSAndroid Build Coastguard Worker    or
14*7304104dSAndroid Build Coastguard Worker 
15*7304104dSAndroid Build Coastguard Worker      * the GNU General Public License as published by the Free
16*7304104dSAndroid Build Coastguard Worker        Software Foundation; either version 2 of the License, or (at
17*7304104dSAndroid Build Coastguard Worker        your option) any later version
18*7304104dSAndroid Build Coastguard Worker 
19*7304104dSAndroid Build Coastguard Worker    or both in parallel, as here.
20*7304104dSAndroid Build Coastguard Worker 
21*7304104dSAndroid Build Coastguard Worker    elfutils is distributed in the hope that it will be useful, but
22*7304104dSAndroid Build Coastguard Worker    WITHOUT ANY WARRANTY; without even the implied warranty of
23*7304104dSAndroid Build Coastguard Worker    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24*7304104dSAndroid Build Coastguard Worker    General Public License for more details.
25*7304104dSAndroid Build Coastguard Worker 
26*7304104dSAndroid Build Coastguard Worker    You should have received copies of the GNU General Public License and
27*7304104dSAndroid Build Coastguard Worker    the GNU Lesser General Public License along with this program.  If
28*7304104dSAndroid Build Coastguard Worker    not, see <http://www.gnu.org/licenses/>.  */
29*7304104dSAndroid Build Coastguard Worker 
30*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
31*7304104dSAndroid Build Coastguard Worker # include <config.h>
32*7304104dSAndroid Build Coastguard Worker #endif
33*7304104dSAndroid Build Coastguard Worker 
34*7304104dSAndroid Build Coastguard Worker #include <assert.h>
35*7304104dSAndroid Build Coastguard Worker #include <inttypes.h>
36*7304104dSAndroid Build Coastguard Worker #include <libelf.h>
37*7304104dSAndroid Build Coastguard Worker #include <stddef.h>
38*7304104dSAndroid Build Coastguard Worker #include <stdlib.h>
39*7304104dSAndroid Build Coastguard Worker #include <string.h>
40*7304104dSAndroid Build Coastguard Worker 
41*7304104dSAndroid Build Coastguard Worker #include "libdwelfP.h"
42*7304104dSAndroid Build Coastguard Worker #include <system.h>
43*7304104dSAndroid Build Coastguard Worker 
44*7304104dSAndroid Build Coastguard Worker 
45*7304104dSAndroid Build Coastguard Worker struct Dwelf_Strent
46*7304104dSAndroid Build Coastguard Worker {
47*7304104dSAndroid Build Coastguard Worker   const char *string;
48*7304104dSAndroid Build Coastguard Worker   size_t len;
49*7304104dSAndroid Build Coastguard Worker   struct Dwelf_Strent *next;
50*7304104dSAndroid Build Coastguard Worker   struct Dwelf_Strent *left;
51*7304104dSAndroid Build Coastguard Worker   struct Dwelf_Strent *right;
52*7304104dSAndroid Build Coastguard Worker   size_t offset;
53*7304104dSAndroid Build Coastguard Worker   char reverse[0];
54*7304104dSAndroid Build Coastguard Worker };
55*7304104dSAndroid Build Coastguard Worker 
56*7304104dSAndroid Build Coastguard Worker 
57*7304104dSAndroid Build Coastguard Worker struct memoryblock
58*7304104dSAndroid Build Coastguard Worker {
59*7304104dSAndroid Build Coastguard Worker   struct memoryblock *next;
60*7304104dSAndroid Build Coastguard Worker   char memory[0];
61*7304104dSAndroid Build Coastguard Worker };
62*7304104dSAndroid Build Coastguard Worker 
63*7304104dSAndroid Build Coastguard Worker 
64*7304104dSAndroid Build Coastguard Worker struct Dwelf_Strtab
65*7304104dSAndroid Build Coastguard Worker {
66*7304104dSAndroid Build Coastguard Worker   struct Dwelf_Strent *root;
67*7304104dSAndroid Build Coastguard Worker   struct memoryblock *memory;
68*7304104dSAndroid Build Coastguard Worker   char *backp;
69*7304104dSAndroid Build Coastguard Worker   size_t left;
70*7304104dSAndroid Build Coastguard Worker   size_t total;
71*7304104dSAndroid Build Coastguard Worker   bool nullstr;
72*7304104dSAndroid Build Coastguard Worker 
73*7304104dSAndroid Build Coastguard Worker   struct Dwelf_Strent null;
74*7304104dSAndroid Build Coastguard Worker };
75*7304104dSAndroid Build Coastguard Worker 
76*7304104dSAndroid Build Coastguard Worker 
77*7304104dSAndroid Build Coastguard Worker /* Cache for the pagesize.  */
78*7304104dSAndroid Build Coastguard Worker static size_t ps;
79*7304104dSAndroid Build Coastguard Worker /* We correct this value a bit so that `malloc' is not allocating more
80*7304104dSAndroid Build Coastguard Worker    than a page. */
81*7304104dSAndroid Build Coastguard Worker #define MALLOC_OVERHEAD (2 * sizeof (void *))
82*7304104dSAndroid Build Coastguard Worker 
83*7304104dSAndroid Build Coastguard Worker 
84*7304104dSAndroid Build Coastguard Worker Dwelf_Strtab *
dwelf_strtab_init(bool nullstr)85*7304104dSAndroid Build Coastguard Worker dwelf_strtab_init (bool nullstr)
86*7304104dSAndroid Build Coastguard Worker {
87*7304104dSAndroid Build Coastguard Worker   if (ps == 0)
88*7304104dSAndroid Build Coastguard Worker     {
89*7304104dSAndroid Build Coastguard Worker       ps = sysconf (_SC_PAGESIZE);
90*7304104dSAndroid Build Coastguard Worker       assert (sizeof (struct memoryblock) < ps - MALLOC_OVERHEAD);
91*7304104dSAndroid Build Coastguard Worker     }
92*7304104dSAndroid Build Coastguard Worker 
93*7304104dSAndroid Build Coastguard Worker   Dwelf_Strtab *ret = calloc (1, sizeof (struct Dwelf_Strtab));
94*7304104dSAndroid Build Coastguard Worker   if (ret != NULL)
95*7304104dSAndroid Build Coastguard Worker     {
96*7304104dSAndroid Build Coastguard Worker       ret->nullstr = nullstr;
97*7304104dSAndroid Build Coastguard Worker 
98*7304104dSAndroid Build Coastguard Worker       if (nullstr)
99*7304104dSAndroid Build Coastguard Worker 	{
100*7304104dSAndroid Build Coastguard Worker 	  ret->null.len = 1;
101*7304104dSAndroid Build Coastguard Worker 	  ret->null.string = "";
102*7304104dSAndroid Build Coastguard Worker 	}
103*7304104dSAndroid Build Coastguard Worker     }
104*7304104dSAndroid Build Coastguard Worker 
105*7304104dSAndroid Build Coastguard Worker   return ret;
106*7304104dSAndroid Build Coastguard Worker }
107*7304104dSAndroid Build Coastguard Worker 
108*7304104dSAndroid Build Coastguard Worker 
109*7304104dSAndroid Build Coastguard Worker static int
morememory(Dwelf_Strtab * st,size_t len)110*7304104dSAndroid Build Coastguard Worker morememory (Dwelf_Strtab *st, size_t len)
111*7304104dSAndroid Build Coastguard Worker {
112*7304104dSAndroid Build Coastguard Worker   size_t overhead = offsetof (struct memoryblock, memory);
113*7304104dSAndroid Build Coastguard Worker   len += overhead + MALLOC_OVERHEAD;
114*7304104dSAndroid Build Coastguard Worker 
115*7304104dSAndroid Build Coastguard Worker   /* Allocate nearest multiple of pagesize >= len.  */
116*7304104dSAndroid Build Coastguard Worker   len = ((len / ps) + (len % ps != 0)) * ps - MALLOC_OVERHEAD;
117*7304104dSAndroid Build Coastguard Worker 
118*7304104dSAndroid Build Coastguard Worker   struct memoryblock *newmem = malloc (len);
119*7304104dSAndroid Build Coastguard Worker   if (newmem == NULL)
120*7304104dSAndroid Build Coastguard Worker     return 1;
121*7304104dSAndroid Build Coastguard Worker 
122*7304104dSAndroid Build Coastguard Worker   newmem->next = st->memory;
123*7304104dSAndroid Build Coastguard Worker   st->memory = newmem;
124*7304104dSAndroid Build Coastguard Worker   st->backp = newmem->memory;
125*7304104dSAndroid Build Coastguard Worker   st->left = len - overhead;
126*7304104dSAndroid Build Coastguard Worker 
127*7304104dSAndroid Build Coastguard Worker   return 0;
128*7304104dSAndroid Build Coastguard Worker }
129*7304104dSAndroid Build Coastguard Worker 
130*7304104dSAndroid Build Coastguard Worker 
131*7304104dSAndroid Build Coastguard Worker void
dwelf_strtab_free(Dwelf_Strtab * st)132*7304104dSAndroid Build Coastguard Worker dwelf_strtab_free (Dwelf_Strtab *st)
133*7304104dSAndroid Build Coastguard Worker {
134*7304104dSAndroid Build Coastguard Worker   struct memoryblock *mb = st->memory;
135*7304104dSAndroid Build Coastguard Worker 
136*7304104dSAndroid Build Coastguard Worker   while (mb != NULL)
137*7304104dSAndroid Build Coastguard Worker     {
138*7304104dSAndroid Build Coastguard Worker       void *old = mb;
139*7304104dSAndroid Build Coastguard Worker       mb = mb->next;
140*7304104dSAndroid Build Coastguard Worker       free (old);
141*7304104dSAndroid Build Coastguard Worker     }
142*7304104dSAndroid Build Coastguard Worker 
143*7304104dSAndroid Build Coastguard Worker   free (st);
144*7304104dSAndroid Build Coastguard Worker }
145*7304104dSAndroid Build Coastguard Worker 
146*7304104dSAndroid Build Coastguard Worker 
147*7304104dSAndroid Build Coastguard Worker static Dwelf_Strent *
newstring(Dwelf_Strtab * st,const char * str,size_t len)148*7304104dSAndroid Build Coastguard Worker newstring (Dwelf_Strtab *st, const char *str, size_t len)
149*7304104dSAndroid Build Coastguard Worker {
150*7304104dSAndroid Build Coastguard Worker   /* Compute the amount of padding needed to make the structure aligned.  */
151*7304104dSAndroid Build Coastguard Worker   size_t align = ((__alignof__ (struct Dwelf_Strent)
152*7304104dSAndroid Build Coastguard Worker 		   - (((uintptr_t) st->backp)
153*7304104dSAndroid Build Coastguard Worker 		      & (__alignof__ (struct Dwelf_Strent) - 1)))
154*7304104dSAndroid Build Coastguard Worker 		  & (__alignof__ (struct Dwelf_Strent) - 1));
155*7304104dSAndroid Build Coastguard Worker 
156*7304104dSAndroid Build Coastguard Worker   /* Make sure there is enough room in the memory block.  */
157*7304104dSAndroid Build Coastguard Worker   if (st->left < align + sizeof (struct Dwelf_Strent) + len)
158*7304104dSAndroid Build Coastguard Worker     {
159*7304104dSAndroid Build Coastguard Worker       if (morememory (st, sizeof (struct Dwelf_Strent) + len))
160*7304104dSAndroid Build Coastguard Worker 	return NULL;
161*7304104dSAndroid Build Coastguard Worker 
162*7304104dSAndroid Build Coastguard Worker       align = 0;
163*7304104dSAndroid Build Coastguard Worker     }
164*7304104dSAndroid Build Coastguard Worker 
165*7304104dSAndroid Build Coastguard Worker   /* Create the reserved string.  */
166*7304104dSAndroid Build Coastguard Worker   Dwelf_Strent *newstr = (Dwelf_Strent *) (st->backp + align);
167*7304104dSAndroid Build Coastguard Worker   newstr->string = str;
168*7304104dSAndroid Build Coastguard Worker   newstr->len = len;
169*7304104dSAndroid Build Coastguard Worker   newstr->next = NULL;
170*7304104dSAndroid Build Coastguard Worker   newstr->left = NULL;
171*7304104dSAndroid Build Coastguard Worker   newstr->right = NULL;
172*7304104dSAndroid Build Coastguard Worker   newstr->offset = 0;
173*7304104dSAndroid Build Coastguard Worker   for (int i = len - 2; i >= 0; --i)
174*7304104dSAndroid Build Coastguard Worker     newstr->reverse[i] = str[len - 2 - i];
175*7304104dSAndroid Build Coastguard Worker   newstr->reverse[len - 1] = '\0';
176*7304104dSAndroid Build Coastguard Worker   st->backp += align + sizeof (struct Dwelf_Strent) + len;
177*7304104dSAndroid Build Coastguard Worker   st->left -= align + sizeof (struct Dwelf_Strent) + len;
178*7304104dSAndroid Build Coastguard Worker 
179*7304104dSAndroid Build Coastguard Worker   return newstr;
180*7304104dSAndroid Build Coastguard Worker }
181*7304104dSAndroid Build Coastguard Worker 
182*7304104dSAndroid Build Coastguard Worker 
183*7304104dSAndroid Build Coastguard Worker /* XXX This function should definitely be rewritten to use a balancing
184*7304104dSAndroid Build Coastguard Worker    tree algorithm (AVL, red-black trees).  For now a simple, correct
185*7304104dSAndroid Build Coastguard Worker    implementation is enough.  */
186*7304104dSAndroid Build Coastguard Worker static Dwelf_Strent **
searchstring(Dwelf_Strent ** sep,Dwelf_Strent * newstr)187*7304104dSAndroid Build Coastguard Worker searchstring (Dwelf_Strent **sep, Dwelf_Strent *newstr)
188*7304104dSAndroid Build Coastguard Worker {
189*7304104dSAndroid Build Coastguard Worker   /* More strings?  */
190*7304104dSAndroid Build Coastguard Worker   if (*sep == NULL)
191*7304104dSAndroid Build Coastguard Worker     {
192*7304104dSAndroid Build Coastguard Worker       *sep = newstr;
193*7304104dSAndroid Build Coastguard Worker       return sep;
194*7304104dSAndroid Build Coastguard Worker     }
195*7304104dSAndroid Build Coastguard Worker 
196*7304104dSAndroid Build Coastguard Worker   /* Compare the strings.  */
197*7304104dSAndroid Build Coastguard Worker   int cmpres = memcmp ((*sep)->reverse, newstr->reverse,
198*7304104dSAndroid Build Coastguard Worker 		       MIN ((*sep)->len, newstr->len) - 1);
199*7304104dSAndroid Build Coastguard Worker   if (cmpres == 0)
200*7304104dSAndroid Build Coastguard Worker     /* We found a matching string.  */
201*7304104dSAndroid Build Coastguard Worker     return sep;
202*7304104dSAndroid Build Coastguard Worker   else if (cmpres > 0)
203*7304104dSAndroid Build Coastguard Worker     return searchstring (&(*sep)->left, newstr);
204*7304104dSAndroid Build Coastguard Worker   else
205*7304104dSAndroid Build Coastguard Worker     return searchstring (&(*sep)->right, newstr);
206*7304104dSAndroid Build Coastguard Worker }
207*7304104dSAndroid Build Coastguard Worker 
208*7304104dSAndroid Build Coastguard Worker 
209*7304104dSAndroid Build Coastguard Worker /* Add new string.  The actual string is assumed to be permanent.  */
210*7304104dSAndroid Build Coastguard Worker static Dwelf_Strent *
strtab_add(Dwelf_Strtab * st,const char * str,size_t len)211*7304104dSAndroid Build Coastguard Worker strtab_add (Dwelf_Strtab *st, const char *str, size_t len)
212*7304104dSAndroid Build Coastguard Worker {
213*7304104dSAndroid Build Coastguard Worker   /* Make sure all "" strings get offset 0 but only if the table was
214*7304104dSAndroid Build Coastguard Worker      created with a special null entry in mind.  */
215*7304104dSAndroid Build Coastguard Worker   if (len == 1 && st->null.string != NULL)
216*7304104dSAndroid Build Coastguard Worker     return &st->null;
217*7304104dSAndroid Build Coastguard Worker 
218*7304104dSAndroid Build Coastguard Worker   /* Allocate memory for the new string and its associated information.  */
219*7304104dSAndroid Build Coastguard Worker   Dwelf_Strent *newstr = newstring (st, str, len);
220*7304104dSAndroid Build Coastguard Worker   if (newstr == NULL)
221*7304104dSAndroid Build Coastguard Worker     return NULL;
222*7304104dSAndroid Build Coastguard Worker 
223*7304104dSAndroid Build Coastguard Worker   /* Search in the array for the place to insert the string.  If there
224*7304104dSAndroid Build Coastguard Worker      is no string with matching prefix and no string with matching
225*7304104dSAndroid Build Coastguard Worker      leading substring, create a new entry.  */
226*7304104dSAndroid Build Coastguard Worker   Dwelf_Strent **sep = searchstring (&st->root, newstr);
227*7304104dSAndroid Build Coastguard Worker   if (*sep != newstr)
228*7304104dSAndroid Build Coastguard Worker     {
229*7304104dSAndroid Build Coastguard Worker       /* This is not the same entry.  This means we have a prefix match.  */
230*7304104dSAndroid Build Coastguard Worker       if ((*sep)->len > newstr->len)
231*7304104dSAndroid Build Coastguard Worker 	{
232*7304104dSAndroid Build Coastguard Worker 	  /* Check whether we already know this string.  */
233*7304104dSAndroid Build Coastguard Worker 	  for (Dwelf_Strent *subs = (*sep)->next; subs != NULL;
234*7304104dSAndroid Build Coastguard Worker 	       subs = subs->next)
235*7304104dSAndroid Build Coastguard Worker 	    if (subs->len == newstr->len)
236*7304104dSAndroid Build Coastguard Worker 	      {
237*7304104dSAndroid Build Coastguard Worker 		/* We have an exact match with a substring.  Free the memory
238*7304104dSAndroid Build Coastguard Worker 		   we allocated.  */
239*7304104dSAndroid Build Coastguard Worker 		st->left += st->backp - (char *) newstr;
240*7304104dSAndroid Build Coastguard Worker 		st->backp = (char *) newstr;
241*7304104dSAndroid Build Coastguard Worker 
242*7304104dSAndroid Build Coastguard Worker 		return subs;
243*7304104dSAndroid Build Coastguard Worker 	      }
244*7304104dSAndroid Build Coastguard Worker 
245*7304104dSAndroid Build Coastguard Worker 	  /* We have a new substring.  This means we don't need the reverse
246*7304104dSAndroid Build Coastguard Worker 	     string of this entry anymore.  */
247*7304104dSAndroid Build Coastguard Worker 	  st->backp -= newstr->len;
248*7304104dSAndroid Build Coastguard Worker 	  st->left += newstr->len;
249*7304104dSAndroid Build Coastguard Worker 
250*7304104dSAndroid Build Coastguard Worker 	  newstr->next = (*sep)->next;
251*7304104dSAndroid Build Coastguard Worker 	  (*sep)->next = newstr;
252*7304104dSAndroid Build Coastguard Worker 	}
253*7304104dSAndroid Build Coastguard Worker       else if ((*sep)->len != newstr->len)
254*7304104dSAndroid Build Coastguard Worker 	{
255*7304104dSAndroid Build Coastguard Worker 	  /* When we get here it means that the string we are about to
256*7304104dSAndroid Build Coastguard Worker 	     add has a common prefix with a string we already have but
257*7304104dSAndroid Build Coastguard Worker 	     it is longer.  In this case we have to put it first.  */
258*7304104dSAndroid Build Coastguard Worker 	  st->total += newstr->len - (*sep)->len;
259*7304104dSAndroid Build Coastguard Worker 	  newstr->next = *sep;
260*7304104dSAndroid Build Coastguard Worker 	  newstr->left = (*sep)->left;
261*7304104dSAndroid Build Coastguard Worker 	  newstr->right = (*sep)->right;
262*7304104dSAndroid Build Coastguard Worker 	  *sep = newstr;
263*7304104dSAndroid Build Coastguard Worker 	}
264*7304104dSAndroid Build Coastguard Worker       else
265*7304104dSAndroid Build Coastguard Worker 	{
266*7304104dSAndroid Build Coastguard Worker 	  /* We have an exact match.  Free the memory we allocated.  */
267*7304104dSAndroid Build Coastguard Worker 	  st->left += st->backp - (char *) newstr;
268*7304104dSAndroid Build Coastguard Worker 	  st->backp = (char *) newstr;
269*7304104dSAndroid Build Coastguard Worker 
270*7304104dSAndroid Build Coastguard Worker 	  newstr = *sep;
271*7304104dSAndroid Build Coastguard Worker 	}
272*7304104dSAndroid Build Coastguard Worker     }
273*7304104dSAndroid Build Coastguard Worker   else
274*7304104dSAndroid Build Coastguard Worker     st->total += newstr->len;
275*7304104dSAndroid Build Coastguard Worker 
276*7304104dSAndroid Build Coastguard Worker   return newstr;
277*7304104dSAndroid Build Coastguard Worker }
278*7304104dSAndroid Build Coastguard Worker 
279*7304104dSAndroid Build Coastguard Worker Dwelf_Strent *
dwelf_strtab_add(Dwelf_Strtab * st,const char * str)280*7304104dSAndroid Build Coastguard Worker dwelf_strtab_add (Dwelf_Strtab *st, const char *str)
281*7304104dSAndroid Build Coastguard Worker {
282*7304104dSAndroid Build Coastguard Worker   return strtab_add (st, str, strlen (str) + 1);
283*7304104dSAndroid Build Coastguard Worker }
284*7304104dSAndroid Build Coastguard Worker 
285*7304104dSAndroid Build Coastguard Worker Dwelf_Strent *
dwelf_strtab_add_len(Dwelf_Strtab * st,const char * str,size_t len)286*7304104dSAndroid Build Coastguard Worker dwelf_strtab_add_len (Dwelf_Strtab *st, const char *str, size_t len)
287*7304104dSAndroid Build Coastguard Worker {
288*7304104dSAndroid Build Coastguard Worker   return strtab_add (st, str, len);
289*7304104dSAndroid Build Coastguard Worker }
290*7304104dSAndroid Build Coastguard Worker 
291*7304104dSAndroid Build Coastguard Worker static void
copystrings(Dwelf_Strent * nodep,char ** freep,size_t * offsetp)292*7304104dSAndroid Build Coastguard Worker copystrings (Dwelf_Strent *nodep, char **freep, size_t *offsetp)
293*7304104dSAndroid Build Coastguard Worker {
294*7304104dSAndroid Build Coastguard Worker   if (nodep->left != NULL)
295*7304104dSAndroid Build Coastguard Worker     copystrings (nodep->left, freep, offsetp);
296*7304104dSAndroid Build Coastguard Worker 
297*7304104dSAndroid Build Coastguard Worker   /* Process the current node.  */
298*7304104dSAndroid Build Coastguard Worker   nodep->offset = *offsetp;
299*7304104dSAndroid Build Coastguard Worker   *freep = (char *) mempcpy (*freep, nodep->string, nodep->len);
300*7304104dSAndroid Build Coastguard Worker   *offsetp += nodep->len;
301*7304104dSAndroid Build Coastguard Worker 
302*7304104dSAndroid Build Coastguard Worker   for (Dwelf_Strent *subs = nodep->next; subs != NULL; subs = subs->next)
303*7304104dSAndroid Build Coastguard Worker     {
304*7304104dSAndroid Build Coastguard Worker       assert (subs->len < nodep->len);
305*7304104dSAndroid Build Coastguard Worker       subs->offset = nodep->offset + nodep->len - subs->len;
306*7304104dSAndroid Build Coastguard Worker       assert (subs->offset != 0 || subs->string[0] == '\0');
307*7304104dSAndroid Build Coastguard Worker     }
308*7304104dSAndroid Build Coastguard Worker 
309*7304104dSAndroid Build Coastguard Worker   if (nodep->right != NULL)
310*7304104dSAndroid Build Coastguard Worker     copystrings (nodep->right, freep, offsetp);
311*7304104dSAndroid Build Coastguard Worker }
312*7304104dSAndroid Build Coastguard Worker 
313*7304104dSAndroid Build Coastguard Worker 
314*7304104dSAndroid Build Coastguard Worker Elf_Data *
dwelf_strtab_finalize(Dwelf_Strtab * st,Elf_Data * data)315*7304104dSAndroid Build Coastguard Worker dwelf_strtab_finalize (Dwelf_Strtab *st, Elf_Data *data)
316*7304104dSAndroid Build Coastguard Worker {
317*7304104dSAndroid Build Coastguard Worker   size_t nulllen = st->nullstr ? 1 : 0;
318*7304104dSAndroid Build Coastguard Worker 
319*7304104dSAndroid Build Coastguard Worker   /* Fill in the information.  */
320*7304104dSAndroid Build Coastguard Worker   data->d_buf = malloc (st->total + nulllen);
321*7304104dSAndroid Build Coastguard Worker   if (data->d_buf == NULL)
322*7304104dSAndroid Build Coastguard Worker     return NULL;
323*7304104dSAndroid Build Coastguard Worker 
324*7304104dSAndroid Build Coastguard Worker   /* The first byte must always be zero if we created the table with a
325*7304104dSAndroid Build Coastguard Worker      null string.  */
326*7304104dSAndroid Build Coastguard Worker   if (st->nullstr)
327*7304104dSAndroid Build Coastguard Worker     *((char *) data->d_buf) = '\0';
328*7304104dSAndroid Build Coastguard Worker 
329*7304104dSAndroid Build Coastguard Worker   data->d_type = ELF_T_BYTE;
330*7304104dSAndroid Build Coastguard Worker   data->d_size = st->total + nulllen;
331*7304104dSAndroid Build Coastguard Worker   data->d_off = 0;
332*7304104dSAndroid Build Coastguard Worker   data->d_align = 1;
333*7304104dSAndroid Build Coastguard Worker   data->d_version = EV_CURRENT;
334*7304104dSAndroid Build Coastguard Worker 
335*7304104dSAndroid Build Coastguard Worker   /* Now run through the tree and add all the string while also updating
336*7304104dSAndroid Build Coastguard Worker      the offset members of the elfstrent records.  */
337*7304104dSAndroid Build Coastguard Worker   char *endp = (char *) data->d_buf + nulllen;
338*7304104dSAndroid Build Coastguard Worker   size_t copylen = nulllen;
339*7304104dSAndroid Build Coastguard Worker   if (st->root)
340*7304104dSAndroid Build Coastguard Worker     copystrings (st->root, &endp, &copylen);
341*7304104dSAndroid Build Coastguard Worker   assert (copylen == st->total + nulllen);
342*7304104dSAndroid Build Coastguard Worker 
343*7304104dSAndroid Build Coastguard Worker   return data;
344*7304104dSAndroid Build Coastguard Worker }
345*7304104dSAndroid Build Coastguard Worker 
346*7304104dSAndroid Build Coastguard Worker 
347*7304104dSAndroid Build Coastguard Worker size_t
dwelf_strent_off(Dwelf_Strent * se)348*7304104dSAndroid Build Coastguard Worker dwelf_strent_off (Dwelf_Strent *se)
349*7304104dSAndroid Build Coastguard Worker {
350*7304104dSAndroid Build Coastguard Worker   return se->offset;
351*7304104dSAndroid Build Coastguard Worker }
352*7304104dSAndroid Build Coastguard Worker 
353*7304104dSAndroid Build Coastguard Worker 
354*7304104dSAndroid Build Coastguard Worker const char *
dwelf_strent_str(Dwelf_Strent * se)355*7304104dSAndroid Build Coastguard Worker dwelf_strent_str (Dwelf_Strent *se)
356*7304104dSAndroid Build Coastguard Worker {
357*7304104dSAndroid Build Coastguard Worker   return se->string;
358*7304104dSAndroid Build Coastguard Worker }
359