libctf: handle nonrepresentable types at link time
[deliverable/binutils-gdb.git] / libctf / ctf-link.c
CommitLineData
72c83edd
NA
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
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 {
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. */
78ctf_id_t
79ctf_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
72c83edd
NA
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
139static void ctf_arc_close_thunk (void *arc)
140{
141 ctf_arc_close ((ctf_archive_t *) arc);
142}
143
144static void ctf_file_close_thunk (void *file)
145{
146 ctf_file_close ((ctf_file_t *) file);
147}
148
149int
150ctf_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
eabb7154
NA
178/* Return a per-CU output CTF dictionary suitable for the given CU, creating and
179 interning it if need be. */
180
181static ctf_file_t *
182ctf_create_per_cu (ctf_file_t *fp, const char *filename, const char *cuname)
183{
184 ctf_file_t *cu_fp;
49ea9b45 185 const char *ctf_name = NULL;
eabb7154
NA
186 char *dynname = NULL;
187
49ea9b45
NA
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)
eabb7154
NA
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
49ea9b45 217 if ((dynname = strdup (ctf_name)) == NULL)
eabb7154
NA
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
49ea9b45
NA
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
246int
247ctf_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. */
299void
300ctf_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
72c83edd
NA
308typedef 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
325static int
326ctf_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 {
791915db
NA
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;
72c83edd
NA
360 }
361 ctf_set_errno (arg->out_fp, 0);
362 }
363
49ea9b45 364 if ((per_cu_out_fp = ctf_create_per_cu (arg->out_fp, arg->file_name,
eabb7154
NA
365 arg->cu_name)) == NULL)
366 return -1; /* Errno is set for us. */
72c83edd
NA
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);
791915db
NA
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));
72c83edd
NA
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
eabb7154
NA
386/* Check if we can safely add a variable with the given type to this container. */
387
388static int
389check_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
412static int
413ctf_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
49ea9b45 450 if ((per_cu_out_fp = ctf_create_per_cu (arg->out_fp, arg->file_name,
eabb7154
NA
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
72c83edd
NA
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. */
480static int
481ctf_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
eabb7154
NA
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);
72c83edd
NA
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
886453cb
NA
540/* Dump the unnecessary link type mapping after one input file is processed. */
541static void
542empty_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
72c83edd
NA
551/* Link one input file's types into the output file. */
552static void
553ctf_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);
886453cb
NA
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);
72c83edd
NA
594}
595
596/* Merge types and variable sections in all files added to the link
597 together. */
598int
599ctf_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
626typedef 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. */
634static void
635ctf_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) == NULL)
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. */
652int
653ctf_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) == NULL)
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. */
678int
679ctf_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
686typedef 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;
49ea9b45
NA
692 char **dynames;
693 size_t ndynames;
72c83edd
NA
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 and run ctf_update() on them to generate them. */
698static void
699ctf_accumulate_archive_names (void *key, void *value, void *arg_)
700{
701 const char *name = (const char *) key;
702 ctf_file_t *fp = (ctf_file_t *) value;
703 char **names;
704 ctf_file_t **files;
705 ctf_name_list_accum_cb_arg_t *arg = (ctf_name_list_accum_cb_arg_t *) arg_;
706 int err;
707
708 if ((err = ctf_update (fp)) < 0)
709 {
710 ctf_set_errno (arg->fp, ctf_errno (fp));
711 return;
712 }
713
714 if ((names = realloc (arg->names, sizeof (char *) * ++(arg->i))) == NULL)
715 {
716 (arg->i)--;
717 ctf_set_errno (arg->fp, ENOMEM);
718 return;
719 }
720
721 if ((files = realloc (arg->files, sizeof (ctf_file_t *) * arg->i)) == NULL)
722 {
723 (arg->i)--;
724 ctf_set_errno (arg->fp, ENOMEM);
725 return;
726 }
49ea9b45
NA
727
728 /* Allow the caller to get in and modify the name at the last minute. If the
729 caller *does* modify the name, we have to stash away the new name the
730 caller returned so we can free it later on. (The original name is the key
731 of the ctf_link_outputs hash and is freed by the dynhash machinery.) */
732
733 if (fp->ctf_link_memb_name_changer)
734 {
735 char **dynames;
736 char *dyname;
737 void *nc_arg = fp->ctf_link_memb_name_changer_arg;
738
739 dyname = fp->ctf_link_memb_name_changer (fp, name, nc_arg);
740
741 if (dyname != NULL)
742 {
743 if ((dynames = realloc (arg->dynames,
744 sizeof (char *) * ++(arg->ndynames))) == NULL)
745 {
746 (arg->ndynames)--;
747 ctf_set_errno (arg->fp, ENOMEM);
748 return;
749 }
750 arg->dynames = dynames;
751 name = (const char *) dyname;
752 }
753 }
754
72c83edd
NA
755 arg->names = names;
756 arg->names[(arg->i) - 1] = (char *) name;
757 arg->files = files;
758 arg->files[(arg->i) - 1] = fp;
759}
760
49ea9b45
NA
761/* Change the name of the parent CTF section, if the name transformer has got to
762 it. */
763static void
764ctf_change_parent_name (void *key _libctf_unused_, void *value, void *arg)
765{
766 ctf_file_t *fp = (ctf_file_t *) value;
767 const char *name = (const char *) arg;
768
769 ctf_parent_name_set (fp, name);
770}
771
72c83edd
NA
772/* Write out a CTF archive (if there are per-CU CTF files) or a CTF file
773 (otherwise) into a new dynamically-allocated string, and return it.
774 Members with sizes above THRESHOLD are compressed. */
775unsigned char *
776ctf_link_write (ctf_file_t *fp, size_t *size, size_t threshold)
777{
778 ctf_name_list_accum_cb_arg_t arg;
779 char **names;
49ea9b45 780 char *transformed_name = NULL;
72c83edd
NA
781 ctf_file_t **files;
782 FILE *f = NULL;
783 int err;
784 long fsize;
785 const char *errloc;
786 unsigned char *buf = NULL;
787
788 memset (&arg, 0, sizeof (ctf_name_list_accum_cb_arg_t));
789 arg.fp = fp;
790
791 if (ctf_update (fp) < 0)
792 {
793 errloc = "CTF file construction";
794 goto err;
795 }
796
797 if (fp->ctf_link_outputs)
798 {
799 ctf_dynhash_iter (fp->ctf_link_outputs, ctf_accumulate_archive_names, &arg);
800 if (ctf_errno (fp) < 0)
801 {
802 errloc = "hash creation";
803 goto err;
804 }
805 }
806
807 /* No extra outputs? Just write a simple ctf_file_t. */
808 if (arg.i == 0)
809 return ctf_write_mem (fp, size, threshold);
810
811 /* Writing an archive. Stick ourselves (the shared repository, parent of all
812 other archives) on the front of it with the default name. */
813 if ((names = realloc (arg.names, sizeof (char *) * (arg.i + 1))) == NULL)
814 {
815 errloc = "name reallocation";
816 goto err_no;
817 }
818 arg.names = names;
819 memmove (&(arg.names[1]), arg.names, sizeof (char *) * (arg.i));
49ea9b45 820
72c83edd 821 arg.names[0] = (char *) _CTF_SECTION;
49ea9b45
NA
822 if (fp->ctf_link_memb_name_changer)
823 {
824 void *nc_arg = fp->ctf_link_memb_name_changer_arg;
825
826 transformed_name = fp->ctf_link_memb_name_changer (fp, _CTF_SECTION,
827 nc_arg);
828
829 if (transformed_name != NULL)
830 {
831 arg.names[0] = transformed_name;
832 ctf_dynhash_iter (fp->ctf_link_outputs, ctf_change_parent_name,
833 transformed_name);
834 }
835 }
72c83edd
NA
836
837 if ((files = realloc (arg.files,
838 sizeof (struct ctf_file *) * (arg.i + 1))) == NULL)
839 {
840 errloc = "ctf_file reallocation";
841 goto err_no;
842 }
843 arg.files = files;
844 memmove (&(arg.files[1]), arg.files, sizeof (ctf_file_t *) * (arg.i));
845 arg.files[0] = fp;
846
847 if ((f = tmpfile ()) == NULL)
848 {
849 errloc = "tempfile creation";
850 goto err_no;
851 }
852
853 if ((err = ctf_arc_write_fd (fileno (f), arg.files, arg.i + 1,
854 (const char **) arg.names,
855 threshold)) < 0)
856 {
857 errloc = "archive writing";
858 ctf_set_errno (fp, err);
859 goto err;
860 }
861
862 if (fseek (f, 0, SEEK_END) < 0)
863 {
864 errloc = "seeking to end";
865 goto err_no;
866 }
867
868 if ((fsize = ftell (f)) < 0)
869 {
870 errloc = "filesize determination";
871 goto err_no;
872 }
873
874 if (fseek (f, 0, SEEK_SET) < 0)
875 {
876 errloc = "filepos resetting";
877 goto err_no;
878 }
879
880 if ((buf = malloc (fsize)) == NULL)
881 {
882 errloc = "CTF archive buffer allocation";
883 goto err_no;
884 }
885
886 while (!feof (f) && fread (buf, fsize, 1, f) == 0)
887 if (ferror (f))
888 {
889 errloc = "reading archive from temporary file";
890 goto err_no;
891 }
892
893 *size = fsize;
894 free (arg.names);
895 free (arg.files);
49ea9b45
NA
896 free (transformed_name);
897 if (arg.ndynames)
898 {
899 size_t i;
900 for (i = 0; i < arg.ndynames; i++)
901 free (arg.dynames[i]);
902 free (arg.dynames);
903 }
72c83edd
NA
904 return buf;
905
906 err_no:
907 ctf_set_errno (fp, errno);
908 err:
909 free (buf);
910 if (f)
911 fclose (f);
912 free (arg.names);
913 free (arg.files);
49ea9b45
NA
914 free (transformed_name);
915 if (arg.ndynames)
916 {
917 size_t i;
918 for (i = 0; i < arg.ndynames; i++)
919 free (arg.dynames[i]);
920 free (arg.dynames);
921 }
72c83edd
NA
922 ctf_dprintf ("Cannot write archive in link: %s failure: %s\n", errloc,
923 ctf_errmsg (ctf_errno (fp)));
924 return NULL;
925}
This page took 0.057419 seconds and 4 git commands to generate.