]> Git Repo - binutils.git/blob - libctf/ctf-link.c
libctf: avoid the need to ever use ctf_update
[binutils.git] / libctf / ctf-link.c
1 /* CTF linking.
2    Copyright (C) 2019 Free Software Foundation, Inc.
3
4    This file is part of libctf.
5
6    libctf is free software; you can redistribute it and/or modify it under
7    the terms of the GNU General Public License as published by the Free
8    Software Foundation; either version 3, or (at your option) any later
9    version.
10
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14    See the GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; see the file COPYING.  If not see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <ctf-impl.h>
21 #include <string.h>
22
23 /* Type tracking machinery.  */
24
25 /* Record the correspondence between a source and ctf_add_type()-added
26    destination type: both types are translated into parent type IDs if need be,
27    so they relate to the actual container they are in.  Outside controlled
28    circumstances (like linking) it is probably not useful to do more than
29    compare these pointers, since there is nothing stopping the user closing the
30    source container whenever they want to.
31
32    Our OOM handling here is just to not do anything, because this is called deep
33    enough in the call stack that doing anything useful is painfully difficult:
34    the worst consequence if we do OOM is a bit of type duplication anyway.  */
35
36 void
37 ctf_add_type_mapping (ctf_file_t *src_fp, ctf_id_t src_type,
38                       ctf_file_t *dst_fp, ctf_id_t dst_type)
39 {
40   if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
41     src_fp = src_fp->ctf_parent;
42
43   src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
44
45   if (LCTF_TYPE_ISPARENT (dst_fp, dst_type) && dst_fp->ctf_parent)
46     dst_fp = dst_fp->ctf_parent;
47
48   dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type);
49
50   /* This dynhash is a bit tricky: it has a multivalued (structural) key, so we
51      need to use the sized-hash machinery to generate key hashing and equality
52      functions.  */
53
54   if (dst_fp->ctf_link_type_mapping == NULL)
55     {
56       ctf_hash_fun f = ctf_hash_type_mapping_key;
57       ctf_hash_eq_fun e = ctf_hash_eq_type_mapping_key;
58
59       if ((dst_fp->ctf_link_type_mapping = ctf_dynhash_create (f, e, free,
60                                                                NULL)) == NULL)
61         return;
62     }
63
64   ctf_link_type_mapping_key_t *key;
65   key = calloc (1, sizeof (struct ctf_link_type_mapping_key));
66   if (!key)
67     return;
68
69   key->cltm_fp = src_fp;
70   key->cltm_idx = src_type;
71
72   ctf_dynhash_insert (dst_fp->ctf_link_type_mapping, key,
73                       (void *) (uintptr_t) dst_type);
74 }
75
76 /* Look up a type mapping: return 0 if none.  The DST_FP is modified to point to
77    the parent if need be.  The ID returned is from the dst_fp's perspective.  */
78 ctf_id_t
79 ctf_type_mapping (ctf_file_t *src_fp, ctf_id_t src_type, ctf_file_t **dst_fp)
80 {
81   ctf_link_type_mapping_key_t key;
82   ctf_file_t *target_fp = *dst_fp;
83   ctf_id_t dst_type = 0;
84
85   if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
86     src_fp = src_fp->ctf_parent;
87
88   src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
89   key.cltm_fp = src_fp;
90   key.cltm_idx = src_type;
91
92   if (target_fp->ctf_link_type_mapping)
93     dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
94                                                &key);
95
96   if (dst_type != 0)
97     {
98       dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
99                                      target_fp->ctf_parent != NULL);
100       *dst_fp = target_fp;
101       return dst_type;
102     }
103
104   if (target_fp->ctf_parent)
105     target_fp = target_fp->ctf_parent;
106   else
107     return 0;
108
109   if (target_fp->ctf_link_type_mapping)
110     dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
111                                                &key);
112
113   if (dst_type)
114     dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
115                                    target_fp->ctf_parent != NULL);
116
117   *dst_fp = target_fp;
118   return dst_type;
119 }
120
121 /* Linker machinery.
122
123    CTF linking consists of adding CTF archives full of content to be merged into
124    this one to the current file (which must be writable) by calling
125    ctf_link_add_ctf().  Once this is done, a call to ctf_link() will merge the
126    type tables together, generating new CTF files as needed, with this one as a
127    parent, to contain types from the inputs which conflict.
128    ctf_link_add_strtab() takes a callback which provides string/offset pairs to
129    be added to the external symbol table and deduplicated from all CTF string
130    tables in the output link; ctf_link_shuffle_syms() takes a callback which
131    provides symtab entries in ascending order, and shuffles the function and
132    data sections to match; and ctf_link_write() emits a CTF file (if there are
133    no conflicts requiring per-compilation-unit sub-CTF files) or CTF archives
134    (otherwise) and returns it, suitable for addition in the .ctf section of the
135    output.  */
136
137 /* Add a file to a link.  */
138
139 static void ctf_arc_close_thunk (void *arc)
140 {
141   ctf_arc_close ((ctf_archive_t *) arc);
142 }
143
144 static void ctf_file_close_thunk (void *file)
145 {
146   ctf_file_close ((ctf_file_t *) file);
147 }
148
149 int
150 ctf_link_add_ctf (ctf_file_t *fp, ctf_archive_t *ctf, const char *name)
151 {
152   char *dupname = NULL;
153
154   if (fp->ctf_link_outputs)
155     return (ctf_set_errno (fp, ECTF_LINKADDEDLATE));
156   if (fp->ctf_link_inputs == NULL)
157     fp->ctf_link_inputs = ctf_dynhash_create (ctf_hash_string,
158                                               ctf_hash_eq_string, free,
159                                               ctf_arc_close_thunk);
160
161   if (fp->ctf_link_inputs == NULL)
162     goto oom;
163
164   if ((dupname = strdup (name)) == NULL)
165     goto oom;
166
167   if (ctf_dynhash_insert (fp->ctf_link_inputs, dupname, ctf) < 0)
168     goto oom;
169
170   return 0;
171  oom:
172   free (fp->ctf_link_inputs);
173   fp->ctf_link_inputs = NULL;
174   free (dupname);
175   return (ctf_set_errno (fp, ENOMEM));
176 }
177
178 /* Return a per-CU output CTF dictionary suitable for the given CU, creating and
179    interning it if need be.  */
180
181 static ctf_file_t *
182 ctf_create_per_cu (ctf_file_t *fp, const char *filename, const char *cuname)
183 {
184   ctf_file_t *cu_fp;
185   const char *ctf_name = NULL;
186   char *dynname = NULL;
187
188   /* First, check the mapping table and translate the per-CU name we use
189      accordingly.  We check both the input filename and the CU name.  Only if
190      neither are set do we fall back to the input filename as the per-CU
191      dictionary name.  We prefer the filename because this is easier for likely
192      callers to determine.  */
193
194   if (fp->ctf_link_cu_mapping)
195     {
196       if (((ctf_name = ctf_dynhash_lookup (fp->ctf_link_cu_mapping, filename)) == NULL) &&
197           ((ctf_name = ctf_dynhash_lookup (fp->ctf_link_cu_mapping, cuname)) == NULL))
198         ctf_name = filename;
199     }
200
201   if (ctf_name == NULL)
202     ctf_name = filename;
203
204   if ((cu_fp = ctf_dynhash_lookup (fp->ctf_link_outputs, ctf_name)) == NULL)
205     {
206       int err;
207
208       if ((cu_fp = ctf_create (&err)) == NULL)
209         {
210           ctf_dprintf ("Cannot create per-CU CTF archive for CU %s from "
211                        "input file %s: %s\n", cuname, filename,
212                        ctf_errmsg (err));
213           ctf_set_errno (fp, err);
214           return NULL;
215         }
216
217       if ((dynname = strdup (ctf_name)) == NULL)
218         goto oom;
219       if (ctf_dynhash_insert (fp->ctf_link_outputs, dynname, cu_fp) < 0)
220         goto oom;
221
222       ctf_import (cu_fp, fp);
223       ctf_cuname_set (cu_fp, cuname);
224       ctf_parent_name_set (cu_fp, _CTF_SECTION);
225     }
226   return cu_fp;
227
228  oom:
229   free (dynname);
230   ctf_file_close (cu_fp);
231   ctf_set_errno (fp, ENOMEM);
232   return NULL;
233 }
234
235 /* Add a mapping directing that the CU named FROM should have its
236    conflicting/non-duplicate types (depending on link mode) go into a container
237    named TO.  Many FROMs can share a TO: in this case, the effect on conflicting
238    types is not yet defined (but in time an auto-renaming algorithm will be
239    added: ugly, but there is really no right thing one can do in this
240    situation).
241
242    We forcibly add a container named TO in every case, even though it may well
243    wind up empty, because clients that use this facility usually expect to find
244    every TO container present, even if empty, and malfunction otherwise.  */
245
246 int
247 ctf_link_add_cu_mapping (ctf_file_t *fp, const char *from, const char *to)
248 {
249   int err;
250   char *f, *t;
251
252   if (fp->ctf_link_cu_mapping == NULL)
253     fp->ctf_link_cu_mapping = ctf_dynhash_create (ctf_hash_string,
254                                                   ctf_hash_eq_string, free,
255                                                   free);
256   if (fp->ctf_link_cu_mapping == NULL)
257     return ctf_set_errno (fp, ENOMEM);
258
259   if (fp->ctf_link_outputs == NULL)
260     fp->ctf_link_outputs = ctf_dynhash_create (ctf_hash_string,
261                                                ctf_hash_eq_string, free,
262                                                ctf_file_close_thunk);
263
264   if (fp->ctf_link_outputs == NULL)
265     return ctf_set_errno (fp, ENOMEM);
266
267   f = strdup (from);
268   t = strdup (to);
269   if (!f || !t)
270     goto oom;
271
272   if (ctf_create_per_cu (fp, t, t) == NULL)
273     goto oom_noerrno;                           /* Errno is set for us.  */
274
275   err = ctf_dynhash_insert (fp->ctf_link_cu_mapping, f, t);
276   if (err)
277     {
278       ctf_set_errno (fp, err);
279       goto oom_noerrno;
280     }
281
282   return 0;
283
284  oom:
285   ctf_set_errno (fp, errno);
286  oom_noerrno:
287   free (f);
288   free (t);
289   return -1;
290 }
291
292 /* Set a function which is called to transform the names of archive members.
293    This is useful for applying regular transformations to many names, where
294    ctf_link_add_cu_mapping applies arbitrarily irregular changes to single
295    names.  The member name changer is applied at ctf_link_write time, so it
296    cannot conflate multiple CUs into one the way ctf_link_add_cu_mapping can.
297    The changer function accepts a name and should return a new
298    dynamically-allocated name, or NULL if the name should be left unchanged.  */
299 void
300 ctf_link_set_memb_name_changer (ctf_file_t *fp,
301                                 ctf_link_memb_name_changer_f *changer,
302                                 void *arg)
303 {
304   fp->ctf_link_memb_name_changer = changer;
305   fp->ctf_link_memb_name_changer_arg = arg;
306 }
307
308 typedef struct ctf_link_in_member_cb_arg
309 {
310   ctf_file_t *out_fp;
311   const char *file_name;
312   ctf_file_t *in_fp;
313   ctf_file_t *main_input_fp;
314   const char *cu_name;
315   char *arcname;
316   int done_main_member;
317   int share_mode;
318   int in_input_cu_file;
319 } ctf_link_in_member_cb_arg_t;
320
321 /* Link one type into the link.  We rely on ctf_add_type() to detect
322    duplicates.  This is not terribly reliable yet (unnmamed types will be
323    mindlessly duplicated), but will improve shortly.  */
324
325 static int
326 ctf_link_one_type (ctf_id_t type, int isroot _libctf_unused_, void *arg_)
327 {
328   ctf_link_in_member_cb_arg_t *arg = (ctf_link_in_member_cb_arg_t *) arg_;
329   ctf_file_t *per_cu_out_fp;
330   int err;
331
332   if (arg->share_mode != CTF_LINK_SHARE_UNCONFLICTED)
333     {
334       ctf_dprintf ("Share-duplicated mode not yet implemented.\n");
335       return ctf_set_errno (arg->out_fp, ECTF_NOTYET);
336     }
337
338   /* Simply call ctf_add_type: if it reports a conflict and we're adding to the
339      main CTF file, add to the per-CU archive member instead, creating it if
340      necessary.  If we got this type from a per-CU archive member, add it
341      straight back to the corresponding member in the output.  */
342
343   if (!arg->in_input_cu_file)
344     {
345       if (ctf_add_type (arg->out_fp, arg->in_fp, type) != CTF_ERR)
346         return 0;
347
348       err = ctf_errno (arg->out_fp);
349       if (err != ECTF_CONFLICT)
350         {
351           if (err != ECTF_NONREPRESENTABLE)
352             ctf_dprintf ("Cannot link type %lx from archive member %s, input file %s "
353                          "into output link: %s\n", type, arg->arcname, arg->file_name,
354                          ctf_errmsg (err));
355           /* We must ignore this problem or we end up losing future types, then
356              trying to link the variables in, then exploding.  Better to link as
357              much as possible.  XXX when we add a proper link warning
358              infrastructure, we should report the error here!  */
359           return 0;
360         }
361       ctf_set_errno (arg->out_fp, 0);
362     }
363
364   if ((per_cu_out_fp = ctf_create_per_cu (arg->out_fp, arg->file_name,
365                                           arg->cu_name)) == NULL)
366     return -1;                                  /* Errno is set for us.  */
367
368   if (ctf_add_type (per_cu_out_fp, arg->in_fp, type) != CTF_ERR)
369     return 0;
370
371   err = ctf_errno (per_cu_out_fp);
372   if (err != ECTF_NONREPRESENTABLE)
373     ctf_dprintf ("Cannot link type %lx from CTF archive member %s, input file %s "
374                  "into output per-CU CTF archive member %s: %s: skipped\n", type,
375                  arg->arcname, arg->file_name, arg->arcname,
376                  ctf_errmsg (err));
377   if (err == ECTF_CONFLICT)
378       /* Conflicts are possible at this stage only if a non-ld user has combined
379          multiple TUs into a single output dictionary.  Even in this case we do not
380          want to stop the link or propagate the error.  */
381       ctf_set_errno (arg->out_fp, 0);
382
383   return 0;                                     /* As above: do not lose types.  */
384 }
385
386 /* Check if we can safely add a variable with the given type to this container.  */
387
388 static int
389 check_variable (const char *name, ctf_file_t *fp, ctf_id_t type,
390                 ctf_dvdef_t **out_dvd)
391 {
392   ctf_dvdef_t *dvd;
393
394   dvd = ctf_dynhash_lookup (fp->ctf_dvhash, name);
395   *out_dvd = dvd;
396   if (!dvd)
397     return 1;
398
399   if (dvd->dvd_type != type)
400     {
401       /* Variable here.  Wrong type: cannot add.  Just skip it, because there is
402          no way to express this in CTF.  (This might be the parent, in which
403          case we'll try adding in the child first, and only then give up.)  */
404       ctf_dprintf ("Inexpressible duplicate variable %s skipped.\n", name);
405     }
406
407   return 0;                                   /* Already exists.  */
408 }
409
410 /* Link one variable in.  */
411
412 static int
413 ctf_link_one_variable (const char *name, ctf_id_t type, void *arg_)
414 {
415   ctf_link_in_member_cb_arg_t *arg = (ctf_link_in_member_cb_arg_t *) arg_;
416   ctf_file_t *per_cu_out_fp;
417   ctf_id_t dst_type = 0;
418   ctf_file_t *check_fp;
419   ctf_dvdef_t *dvd;
420
421   /* In unconflicted link mode, if this type is mapped to a type in the parent
422      container, we want to try to add to that first: if it reports a duplicate,
423      or if the type is in a child already, add straight to the child.  */
424
425   check_fp = arg->out_fp;
426
427   dst_type = ctf_type_mapping (arg->in_fp, type, &check_fp);
428   if (dst_type != 0)
429     {
430       if (check_fp == arg->out_fp)
431         {
432           if (check_variable (name, check_fp, dst_type, &dvd))
433             {
434               /* No variable here: we can add it.  */
435               if (ctf_add_variable (check_fp, name, dst_type) < 0)
436                 return (ctf_set_errno (arg->out_fp, ctf_errno (check_fp)));
437               return 0;
438             }
439
440           /* Already present?  Nothing to do.  */
441           if (dvd && dvd->dvd_type == type)
442             return 0;
443         }
444     }
445
446   /* Can't add to the parent due to a name clash, or because it references a
447      type only present in the child.  Try adding to the child, creating if need
448      be.  */
449
450   if ((per_cu_out_fp = ctf_create_per_cu (arg->out_fp, arg->file_name,
451                                           arg->cu_name)) == NULL)
452     return -1;                                  /* Errno is set for us.  */
453
454   /* If the type was not found, check for it in the child too. */
455   if (dst_type == 0)
456     {
457       check_fp = per_cu_out_fp;
458       dst_type = ctf_type_mapping (arg->in_fp, type, &check_fp);
459
460       if (dst_type == 0)
461         {
462           ctf_dprintf ("Type %lx for variable %s in input file %s not "
463                        "found: skipped.\n", type, name, arg->file_name);
464           /* Do not terminate the link: just skip the variable.  */
465           return 0;
466         }
467     }
468
469   if (check_variable (name, per_cu_out_fp, dst_type, &dvd))
470     if (ctf_add_variable (per_cu_out_fp, name, dst_type) < 0)
471       return (ctf_set_errno (arg->out_fp, ctf_errno (per_cu_out_fp)));
472   return 0;
473 }
474
475 /* Merge every type and variable in this archive member into the link, so we can
476    relink things that have already had ld run on them.  We use the archive
477    member name, sans any leading '.ctf.', as the CU name for ambiguous types if
478    there is one and it's not the default: otherwise, we use the name of the
479    input file.  */
480 static int
481 ctf_link_one_input_archive_member (ctf_file_t *in_fp, const char *name, void *arg_)
482 {
483   ctf_link_in_member_cb_arg_t *arg = (ctf_link_in_member_cb_arg_t *) arg_;
484   int err = 0;
485
486   if (strcmp (name, _CTF_SECTION) == 0)
487     {
488       /* This file is the default member of this archive, and has already been
489          explicitly processed.
490
491          In the default sharing mode of CTF_LINK_SHARE_UNCONFLICTED, it does no
492          harm to rescan an existing shared repo again: all the types will just
493          end up in the same place.  But in CTF_LINK_SHARE_DUPLICATED mode, this
494          causes the system to erroneously conclude that all types are duplicated
495          and should be shared, even if they are not.  */
496
497       if (arg->done_main_member)
498         return 0;
499       arg->arcname = strdup (".ctf.");
500       if (arg->arcname)
501         {
502           char *new_name;
503
504           new_name = ctf_str_append (arg->arcname, arg->file_name);
505           if (new_name)
506             arg->arcname = new_name;
507           else
508             free (arg->arcname);
509         }
510     }
511   else
512     {
513       arg->arcname = strdup (name);
514
515       /* Get ambiguous types from our parent.  */
516       ctf_import (in_fp, arg->main_input_fp);
517       arg->in_input_cu_file = 1;
518     }
519
520   if (!arg->arcname)
521     return ctf_set_errno (in_fp, ENOMEM);
522
523   arg->cu_name = name;
524   if (strncmp (arg->cu_name, ".ctf.", strlen (".ctf.")) == 0)
525     arg->cu_name += strlen (".ctf.");
526   arg->in_fp = in_fp;
527
528   if ((err = ctf_type_iter_all (in_fp, ctf_link_one_type, arg)) > -1)
529     err = ctf_variable_iter (in_fp, ctf_link_one_variable, arg);
530
531   arg->in_input_cu_file = 0;
532   free (arg->arcname);
533
534   if (err < 0)
535       return -1;                                /* Errno is set for us.  */
536
537   return 0;
538 }
539
540 /* Dump the unnecessary link type mapping after one input file is processed.  */
541 static void
542 empty_link_type_mapping (void *key _libctf_unused_, void *value,
543                          void *arg _libctf_unused_)
544 {
545   ctf_file_t *fp = (ctf_file_t *) value;
546
547   if (fp->ctf_link_type_mapping)
548     ctf_dynhash_empty (fp->ctf_link_type_mapping);
549 }
550
551 /* Link one input file's types into the output file.  */
552 static void
553 ctf_link_one_input_archive (void *key, void *value, void *arg_)
554 {
555   const char *file_name = (const char *) key;
556   ctf_archive_t *arc = (ctf_archive_t *) value;
557   ctf_link_in_member_cb_arg_t *arg = (ctf_link_in_member_cb_arg_t *) arg_;
558   int err;
559
560   arg->file_name = file_name;
561   arg->done_main_member = 0;
562   if ((arg->main_input_fp = ctf_arc_open_by_name (arc, NULL, &err)) == NULL)
563     if (err != ECTF_ARNNAME)
564       {
565         ctf_dprintf ("Cannot open main archive member in input file %s in the "
566                      "link: skipping: %s.\n", arg->file_name,
567                      ctf_errmsg (err));
568         return;
569       }
570
571   if (ctf_link_one_input_archive_member (arg->main_input_fp,
572                                          _CTF_SECTION, arg) < 0)
573     {
574       ctf_file_close (arg->main_input_fp);
575       return;
576     }
577   arg->done_main_member = 1;
578   if (ctf_archive_iter (arc, ctf_link_one_input_archive_member, arg) < 0)
579     ctf_dprintf ("Cannot traverse archive in input file %s: link "
580                  "cannot continue: %s.\n", arg->file_name,
581                  ctf_errmsg (ctf_errno (arg->out_fp)));
582   else
583     {
584       /* The only error indication to the caller is the errno: so ensure that it
585          is zero if there was no actual error from the caller.  */
586       ctf_set_errno (arg->out_fp, 0);
587     }
588   ctf_file_close (arg->main_input_fp);
589
590   /* Discard the now-unnecessary mapping table data.  */
591   if (arg->out_fp->ctf_link_type_mapping)
592     ctf_dynhash_empty (arg->out_fp->ctf_link_type_mapping);
593   ctf_dynhash_iter (arg->out_fp->ctf_link_outputs, empty_link_type_mapping, NULL);
594 }
595
596 /* Merge types and variable sections in all files added to the link
597    together.  */
598 int
599 ctf_link (ctf_file_t *fp, int share_mode)
600 {
601   ctf_link_in_member_cb_arg_t arg;
602
603   memset (&arg, 0, sizeof (struct ctf_link_in_member_cb_arg));
604   arg.out_fp = fp;
605   arg.share_mode = share_mode;
606
607   if (fp->ctf_link_inputs == NULL)
608     return 0;                                   /* Nothing to do. */
609
610   if (fp->ctf_link_outputs == NULL)
611     fp->ctf_link_outputs = ctf_dynhash_create (ctf_hash_string,
612                                                ctf_hash_eq_string, free,
613                                                ctf_file_close_thunk);
614
615   if (fp->ctf_link_outputs == NULL)
616     return ctf_set_errno (fp, ENOMEM);
617
618   ctf_dynhash_iter (fp->ctf_link_inputs, ctf_link_one_input_archive,
619                     &arg);
620
621   if (ctf_errno (fp) != 0)
622     return -1;
623   return 0;
624 }
625
626 typedef struct ctf_link_out_string_cb_arg
627 {
628   const char *str;
629   uint32_t offset;
630   int err;
631 } ctf_link_out_string_cb_arg_t;
632
633 /* Intern a string in the string table of an output per-CU CTF file.  */
634 static void
635 ctf_link_intern_extern_string (void *key _libctf_unused_, void *value,
636                                void *arg_)
637 {
638   ctf_file_t *fp = (ctf_file_t *) value;
639   ctf_link_out_string_cb_arg_t *arg = (ctf_link_out_string_cb_arg_t *) arg_;
640
641   fp->ctf_flags |= LCTF_DIRTY;
642   if (!ctf_str_add_external (fp, arg->str, arg->offset))
643     arg->err = ENOMEM;
644 }
645
646 /* Repeatedly call ADD_STRING to acquire strings from the external string table,
647    adding them to the atoms table for this CU and all subsidiary CUs.
648
649    If ctf_link() is also called, it must be called first if you want the new CTF
650    files ctf_link() can create to get their strings dedupped against the ELF
651    strtab properly.  */
652 int
653 ctf_link_add_strtab (ctf_file_t *fp, ctf_link_strtab_string_f *add_string,
654                      void *arg)
655 {
656   const char *str;
657   uint32_t offset;
658   int err = 0;
659
660   while ((str = add_string (&offset, arg)) != NULL)
661     {
662       ctf_link_out_string_cb_arg_t iter_arg = { str, offset, 0 };
663
664       fp->ctf_flags |= LCTF_DIRTY;
665       if (!ctf_str_add_external (fp, str, offset))
666         err = ENOMEM;
667
668       ctf_dynhash_iter (fp->ctf_link_outputs, ctf_link_intern_extern_string,
669                         &iter_arg);
670       if (iter_arg.err)
671         err = iter_arg.err;
672     }
673
674   return -err;
675 }
676
677 /* Not yet implemented.  */
678 int
679 ctf_link_shuffle_syms (ctf_file_t *fp _libctf_unused_,
680                        ctf_link_iter_symbol_f *add_sym _libctf_unused_,
681                        void *arg _libctf_unused_)
682 {
683   return 0;
684 }
685
686 typedef struct ctf_name_list_accum_cb_arg
687 {
688   char **names;
689   ctf_file_t *fp;
690   ctf_file_t **files;
691   size_t i;
692   char **dynames;
693   size_t ndynames;
694 } ctf_name_list_accum_cb_arg_t;
695
696 /* Accumulate the names and a count of the names in the link output hash.  */
697 static void
698 ctf_accumulate_archive_names (void *key, void *value, void *arg_)
699 {
700   const char *name = (const char *) key;
701   ctf_file_t *fp = (ctf_file_t *) value;
702   char **names;
703   ctf_file_t **files;
704   ctf_name_list_accum_cb_arg_t *arg = (ctf_name_list_accum_cb_arg_t *) arg_;
705
706   if ((names = realloc (arg->names, sizeof (char *) * ++(arg->i))) == NULL)
707     {
708       (arg->i)--;
709       ctf_set_errno (arg->fp, ENOMEM);
710       return;
711     }
712
713   if ((files = realloc (arg->files, sizeof (ctf_file_t *) * arg->i)) == NULL)
714     {
715       (arg->i)--;
716       ctf_set_errno (arg->fp, ENOMEM);
717       return;
718     }
719
720   /* Allow the caller to get in and modify the name at the last minute.  If the
721      caller *does* modify the name, we have to stash away the new name the
722      caller returned so we can free it later on.  (The original name is the key
723      of the ctf_link_outputs hash and is freed by the dynhash machinery.)  */
724
725   if (fp->ctf_link_memb_name_changer)
726     {
727       char **dynames;
728       char *dyname;
729       void *nc_arg = fp->ctf_link_memb_name_changer_arg;
730
731       dyname = fp->ctf_link_memb_name_changer (fp, name, nc_arg);
732
733       if (dyname != NULL)
734         {
735           if ((dynames = realloc (arg->dynames,
736                                   sizeof (char *) * ++(arg->ndynames))) == NULL)
737             {
738               (arg->ndynames)--;
739               ctf_set_errno (arg->fp, ENOMEM);
740               return;
741             }
742             arg->dynames = dynames;
743             name = (const char *) dyname;
744         }
745     }
746
747   arg->names = names;
748   arg->names[(arg->i) - 1] = (char *) name;
749   arg->files = files;
750   arg->files[(arg->i) - 1] = fp;
751 }
752
753 /* Change the name of the parent CTF section, if the name transformer has got to
754    it.  */
755 static void
756 ctf_change_parent_name (void *key _libctf_unused_, void *value, void *arg)
757 {
758   ctf_file_t *fp = (ctf_file_t *) value;
759   const char *name = (const char *) arg;
760
761   ctf_parent_name_set (fp, name);
762 }
763
764 /* Write out a CTF archive (if there are per-CU CTF files) or a CTF file
765    (otherwise) into a new dynamically-allocated string, and return it.
766    Members with sizes above THRESHOLD are compressed.  */
767 unsigned char *
768 ctf_link_write (ctf_file_t *fp, size_t *size, size_t threshold)
769 {
770   ctf_name_list_accum_cb_arg_t arg;
771   char **names;
772   char *transformed_name = NULL;
773   ctf_file_t **files;
774   FILE *f = NULL;
775   int err;
776   long fsize;
777   const char *errloc;
778   unsigned char *buf = NULL;
779
780   memset (&arg, 0, sizeof (ctf_name_list_accum_cb_arg_t));
781   arg.fp = fp;
782
783   if (fp->ctf_link_outputs)
784     {
785       ctf_dynhash_iter (fp->ctf_link_outputs, ctf_accumulate_archive_names, &arg);
786       if (ctf_errno (fp) < 0)
787         {
788           errloc = "hash creation";
789           goto err;
790         }
791     }
792
793   /* No extra outputs? Just write a simple ctf_file_t.  */
794   if (arg.i == 0)
795     return ctf_write_mem (fp, size, threshold);
796
797   /* Writing an archive.  Stick ourselves (the shared repository, parent of all
798      other archives) on the front of it with the default name.  */
799   if ((names = realloc (arg.names, sizeof (char *) * (arg.i + 1))) == NULL)
800     {
801       errloc = "name reallocation";
802       goto err_no;
803     }
804   arg.names = names;
805   memmove (&(arg.names[1]), arg.names, sizeof (char *) * (arg.i));
806
807   arg.names[0] = (char *) _CTF_SECTION;
808   if (fp->ctf_link_memb_name_changer)
809     {
810       void *nc_arg = fp->ctf_link_memb_name_changer_arg;
811
812       transformed_name = fp->ctf_link_memb_name_changer (fp, _CTF_SECTION,
813                                                          nc_arg);
814
815       if (transformed_name != NULL)
816         {
817           arg.names[0] = transformed_name;
818           ctf_dynhash_iter (fp->ctf_link_outputs, ctf_change_parent_name,
819                             transformed_name);
820         }
821     }
822
823   if ((files = realloc (arg.files,
824                         sizeof (struct ctf_file *) * (arg.i + 1))) == NULL)
825     {
826       errloc = "ctf_file reallocation";
827       goto err_no;
828     }
829   arg.files = files;
830   memmove (&(arg.files[1]), arg.files, sizeof (ctf_file_t *) * (arg.i));
831   arg.files[0] = fp;
832
833   if ((f = tmpfile ()) == NULL)
834     {
835       errloc = "tempfile creation";
836       goto err_no;
837     }
838
839   if ((err = ctf_arc_write_fd (fileno (f), arg.files, arg.i + 1,
840                                (const char **) arg.names,
841                                threshold)) < 0)
842     {
843       errloc = "archive writing";
844       ctf_set_errno (fp, err);
845       goto err;
846     }
847
848   if (fseek (f, 0, SEEK_END) < 0)
849     {
850       errloc = "seeking to end";
851       goto err_no;
852     }
853
854   if ((fsize = ftell (f)) < 0)
855     {
856       errloc = "filesize determination";
857       goto err_no;
858     }
859
860   if (fseek (f, 0, SEEK_SET) < 0)
861     {
862       errloc = "filepos resetting";
863       goto err_no;
864     }
865
866   if ((buf = malloc (fsize)) == NULL)
867     {
868       errloc = "CTF archive buffer allocation";
869       goto err_no;
870     }
871
872   while (!feof (f) && fread (buf, fsize, 1, f) == 0)
873     if (ferror (f))
874       {
875         errloc = "reading archive from temporary file";
876         goto err_no;
877       }
878
879   *size = fsize;
880   free (arg.names);
881   free (arg.files);
882   free (transformed_name);
883   if (arg.ndynames)
884     {
885       size_t i;
886       for (i = 0; i < arg.ndynames; i++)
887         free (arg.dynames[i]);
888       free (arg.dynames);
889     }
890   return buf;
891
892  err_no:
893   ctf_set_errno (fp, errno);
894  err:
895   free (buf);
896   if (f)
897     fclose (f);
898   free (arg.names);
899   free (arg.files);
900   free (transformed_name);
901   if (arg.ndynames)
902     {
903       size_t i;
904       for (i = 0; i < arg.ndynames; i++)
905         free (arg.dynames[i]);
906       free (arg.dynames);
907     }
908   ctf_dprintf ("Cannot write archive in link: %s failure: %s\n", errloc,
909                ctf_errmsg (ctf_errno (fp)));
910   return NULL;
911 }
This page took 0.07804 seconds and 4 git commands to generate.