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, ©len);
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