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