libctf: sort out potential refcount loops
[deliverable/binutils-gdb.git] / libctf / ctf-link.c
CommitLineData
72c83edd 1/* CTF linking.
b3adc24a 2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
72c83edd
NA
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
886453cb
NA
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
36void
37ctf_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 {
3166467b
NA
56 ctf_hash_fun f = ctf_hash_type_key;
57 ctf_hash_eq_fun e = ctf_hash_eq_type_key;
886453cb
NA
58
59 if ((dst_fp->ctf_link_type_mapping = ctf_dynhash_create (f, e, free,
60 NULL)) == NULL)
61 return;
62 }
63
3166467b
NA
64 ctf_link_type_key_t *key;
65 key = calloc (1, sizeof (struct ctf_link_type_key));
886453cb
NA
66 if (!key)
67 return;
68
3166467b
NA
69 key->cltk_fp = src_fp;
70 key->cltk_idx = src_type;
886453cb 71
3166467b
NA
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). */
886453cb
NA
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. */
81ctf_id_t
82ctf_type_mapping (ctf_file_t *src_fp, ctf_id_t src_type, ctf_file_t **dst_fp)
83{
3166467b 84 ctf_link_type_key_t key;
886453cb
NA
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);
3166467b
NA
92 key.cltk_fp = src_fp;
93 key.cltk_idx = src_type;
886453cb
NA
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
72c83edd
NA
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
142static void ctf_arc_close_thunk (void *arc)
143{
144 ctf_arc_close ((ctf_archive_t *) arc);
145}
146
147static void ctf_file_close_thunk (void *file)
148{
149 ctf_file_close ((ctf_file_t *) file);
150}
151
152int
153ctf_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
eabb7154
NA
181/* Return a per-CU output CTF dictionary suitable for the given CU, creating and
182 interning it if need be. */
183
184static ctf_file_t *
185ctf_create_per_cu (ctf_file_t *fp, const char *filename, const char *cuname)
186{
187 ctf_file_t *cu_fp;
49ea9b45 188 const char *ctf_name = NULL;
eabb7154
NA
189 char *dynname = NULL;
190
49ea9b45
NA
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)
eabb7154
NA
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
49ea9b45 220 if ((dynname = strdup (ctf_name)) == NULL)
eabb7154
NA
221 goto oom;
222 if (ctf_dynhash_insert (fp->ctf_link_outputs, dynname, cu_fp) < 0)
223 goto oom;
224
1fa7a0c2 225 ctf_import_unref (cu_fp, fp);
eabb7154
NA
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
49ea9b45
NA
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
249int
250ctf_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. */
302void
303ctf_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
72c83edd
NA
311typedef 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
328static int
329ctf_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 {
791915db
NA
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;
72c83edd
NA
363 }
364 ctf_set_errno (arg->out_fp, 0);
365 }
366
49ea9b45 367 if ((per_cu_out_fp = ctf_create_per_cu (arg->out_fp, arg->file_name,
eabb7154
NA
368 arg->cu_name)) == NULL)
369 return -1; /* Errno is set for us. */
72c83edd
NA
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);
791915db
NA
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));
72c83edd
NA
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
eabb7154
NA
389/* Check if we can safely add a variable with the given type to this container. */
390
391static int
392check_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
415static int
416ctf_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
49ea9b45 453 if ((per_cu_out_fp = ctf_create_per_cu (arg->out_fp, arg->file_name,
eabb7154
NA
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
72c83edd
NA
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. */
483static int
484ctf_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
eabb7154
NA
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);
72c83edd
NA
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
886453cb
NA
543/* Dump the unnecessary link type mapping after one input file is processed. */
544static void
545empty_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
72c83edd
NA
554/* Link one input file's types into the output file. */
555static void
556ctf_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);
886453cb
NA
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);
72c83edd
NA
597}
598
599/* Merge types and variable sections in all files added to the link
600 together. */
601int
602ctf_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
629typedef 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. */
637static void
638ctf_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;
676c3ecb 645 if (!ctf_str_add_external (fp, arg->str, arg->offset))
72c83edd
NA
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. */
655int
656ctf_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;
676c3ecb 668 if (!ctf_str_add_external (fp, str, offset))
72c83edd
NA
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. */
681int
682ctf_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
689typedef 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;
49ea9b45
NA
695 char **dynames;
696 size_t ndynames;
72c83edd
NA
697} ctf_name_list_accum_cb_arg_t;
698
676c3ecb 699/* Accumulate the names and a count of the names in the link output hash. */
72c83edd
NA
700static void
701ctf_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_;
72c83edd
NA
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 }
49ea9b45
NA
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
72c83edd
NA
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
49ea9b45
NA
756/* Change the name of the parent CTF section, if the name transformer has got to
757 it. */
758static void
759ctf_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
72c83edd
NA
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. */
770unsigned char *
771ctf_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;
49ea9b45 775 char *transformed_name = NULL;
72c83edd
NA
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
72c83edd
NA
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));
49ea9b45 809
72c83edd 810 arg.names[0] = (char *) _CTF_SECTION;
49ea9b45
NA
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 }
72c83edd
NA
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);
49ea9b45
NA
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 }
72c83edd
NA
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);
49ea9b45
NA
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 }
72c83edd
NA
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.099291 seconds and 4 git commands to generate.