2 Copyright (C) 2019 Free Software Foundation, Inc.
4 This file is part of libctf.
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
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.
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/>. */
23 /* Type tracking machinery. */
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.
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. */
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
)
40 if (LCTF_TYPE_ISPARENT (src_fp
, src_type
) && src_fp
->ctf_parent
)
41 src_fp
= src_fp
->ctf_parent
;
43 src_type
= LCTF_TYPE_TO_INDEX(src_fp
, src_type
);
45 if (LCTF_TYPE_ISPARENT (dst_fp
, dst_type
) && dst_fp
->ctf_parent
)
46 dst_fp
= dst_fp
->ctf_parent
;
48 dst_type
= LCTF_TYPE_TO_INDEX(dst_fp
, dst_type
);
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
54 if (dst_fp
->ctf_link_type_mapping
== NULL
)
56 ctf_hash_fun f
= ctf_hash_type_mapping_key
;
57 ctf_hash_eq_fun e
= ctf_hash_eq_type_mapping_key
;
59 if ((dst_fp
->ctf_link_type_mapping
= ctf_dynhash_create (f
, e
, free
,
64 ctf_link_type_mapping_key_t
*key
;
65 key
= calloc (1, sizeof (struct ctf_link_type_mapping_key
));
69 key
->cltm_fp
= src_fp
;
70 key
->cltm_idx
= src_type
;
72 ctf_dynhash_insert (dst_fp
->ctf_link_type_mapping
, key
,
73 (void *) (uintptr_t) dst_type
);
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. */
79 ctf_type_mapping (ctf_file_t
*src_fp
, ctf_id_t src_type
, ctf_file_t
**dst_fp
)
81 ctf_link_type_mapping_key_t key
;
82 ctf_file_t
*target_fp
= *dst_fp
;
83 ctf_id_t dst_type
= 0;
85 if (LCTF_TYPE_ISPARENT (src_fp
, src_type
) && src_fp
->ctf_parent
)
86 src_fp
= src_fp
->ctf_parent
;
88 src_type
= LCTF_TYPE_TO_INDEX(src_fp
, src_type
);
90 key
.cltm_idx
= src_type
;
92 if (target_fp
->ctf_link_type_mapping
)
93 dst_type
= (uintptr_t) ctf_dynhash_lookup (target_fp
->ctf_link_type_mapping
,
98 dst_type
= LCTF_INDEX_TO_TYPE (target_fp
, dst_type
,
99 target_fp
->ctf_parent
!= NULL
);
104 if (target_fp
->ctf_parent
)
105 target_fp
= target_fp
->ctf_parent
;
109 if (target_fp
->ctf_link_type_mapping
)
110 dst_type
= (uintptr_t) ctf_dynhash_lookup (target_fp
->ctf_link_type_mapping
,
114 dst_type
= LCTF_INDEX_TO_TYPE (target_fp
, dst_type
,
115 target_fp
->ctf_parent
!= NULL
);
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
137 /* Add a file to a link. */
139 static void ctf_arc_close_thunk (void *arc
)
141 ctf_arc_close ((ctf_archive_t
*) arc
);
144 static void ctf_file_close_thunk (void *file
)
146 ctf_file_close ((ctf_file_t
*) file
);
150 ctf_link_add_ctf (ctf_file_t
*fp
, ctf_archive_t
*ctf
, const char *name
)
152 char *dupname
= NULL
;
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
);
161 if (fp
->ctf_link_inputs
== NULL
)
164 if ((dupname
= strdup (name
)) == NULL
)
167 if (ctf_dynhash_insert (fp
->ctf_link_inputs
, dupname
, ctf
) < 0)
172 free (fp
->ctf_link_inputs
);
173 fp
->ctf_link_inputs
= NULL
;
175 return (ctf_set_errno (fp
, ENOMEM
));
178 typedef struct ctf_link_in_member_cb_arg
181 const char *file_name
;
183 ctf_file_t
*main_input_fp
;
186 int done_main_member
;
188 int in_input_cu_file
;
189 } ctf_link_in_member_cb_arg_t
;
191 /* Link one type into the link. We rely on ctf_add_type() to detect
192 duplicates. This is not terribly reliable yet (unnmamed types will be
193 mindlessly duplicated), but will improve shortly. */
196 ctf_link_one_type (ctf_id_t type
, int isroot _libctf_unused_
, void *arg_
)
198 ctf_link_in_member_cb_arg_t
*arg
= (ctf_link_in_member_cb_arg_t
*) arg_
;
199 ctf_file_t
*per_cu_out_fp
;
202 if (arg
->share_mode
!= CTF_LINK_SHARE_UNCONFLICTED
)
204 ctf_dprintf ("Share-duplicated mode not yet implemented.\n");
205 return ctf_set_errno (arg
->out_fp
, ECTF_NOTYET
);
208 /* Simply call ctf_add_type: if it reports a conflict and we're adding to the
209 main CTF file, add to the per-CU archive member instead, creating it if
210 necessary. If we got this type from a per-CU archive member, add it
211 straight back to the corresponding member in the output. */
213 if (!arg
->in_input_cu_file
)
215 if (ctf_add_type (arg
->out_fp
, arg
->in_fp
, type
) != CTF_ERR
)
218 err
= ctf_errno (arg
->out_fp
);
219 if (err
!= ECTF_CONFLICT
)
221 ctf_dprintf ("Cannot link type %lx from archive member %s, input file %s "
222 "into output link: %s\n", type
, arg
->arcname
, arg
->file_name
,
226 ctf_set_errno (arg
->out_fp
, 0);
229 if ((per_cu_out_fp
= ctf_dynhash_lookup (arg
->out_fp
->ctf_link_outputs
,
230 arg
->arcname
)) == NULL
)
234 if ((per_cu_out_fp
= ctf_create (&err
)) == NULL
)
236 ctf_dprintf ("Cannot create per-CU CTF archive for member %s: %s\n",
237 arg
->arcname
, ctf_errmsg (err
));
238 ctf_set_errno (arg
->out_fp
, err
);
242 if (ctf_dynhash_insert (arg
->out_fp
->ctf_link_outputs
, arg
->arcname
,
245 ctf_set_errno (arg
->out_fp
, ENOMEM
);
249 ctf_import (per_cu_out_fp
, arg
->out_fp
);
250 ctf_cuname_set (per_cu_out_fp
, arg
->cu_name
);
253 if (ctf_add_type (per_cu_out_fp
, arg
->in_fp
, type
) != CTF_ERR
)
256 err
= ctf_errno (per_cu_out_fp
);
257 if (err
== ECTF_CONFLICT
)
258 /* Conflicts are possible at this stage only if a non-ld user has combined
259 multiple TUs into a single output dictionary. Even in this case we do not
260 want to stop the link or propagate the error. */
261 ctf_set_errno (arg
->out_fp
, 0);
263 return 0; /* As above: do not lose types. */
266 /* Merge every type and variable in this archive member into the link, so we can
267 relink things that have already had ld run on them. We use the archive
268 member name, sans any leading '.ctf.', as the CU name for ambiguous types if
269 there is one and it's not the default: otherwise, we use the name of the
272 ctf_link_one_input_archive_member (ctf_file_t
*in_fp
, const char *name
, void *arg_
)
274 ctf_link_in_member_cb_arg_t
*arg
= (ctf_link_in_member_cb_arg_t
*) arg_
;
277 if (strcmp (name
, _CTF_SECTION
) == 0)
279 /* This file is the default member of this archive, and has already been
280 explicitly processed.
282 In the default sharing mode of CTF_LINK_SHARE_UNCONFLICTED, it does no
283 harm to rescan an existing shared repo again: all the types will just
284 end up in the same place. But in CTF_LINK_SHARE_DUPLICATED mode, this
285 causes the system to erroneously conclude that all types are duplicated
286 and should be shared, even if they are not. */
288 if (arg
->done_main_member
)
290 arg
->arcname
= strdup (".ctf.");
295 new_name
= ctf_str_append (arg
->arcname
, arg
->file_name
);
297 arg
->arcname
= new_name
;
304 arg
->arcname
= strdup (name
);
306 /* Get ambiguous types from our parent. */
307 ctf_import (in_fp
, arg
->main_input_fp
);
308 arg
->in_input_cu_file
= 1;
312 return ctf_set_errno (in_fp
, ENOMEM
);
315 if (strncmp (arg
->cu_name
, ".ctf.", strlen (".ctf.")) == 0)
316 arg
->cu_name
+= strlen (".ctf.");
319 err
= ctf_type_iter_all (in_fp
, ctf_link_one_type
, arg
);
321 arg
->in_input_cu_file
= 0;
325 return -1; /* Errno is set for us. */
330 /* Dump the unnecessary link type mapping after one input file is processed. */
332 empty_link_type_mapping (void *key _libctf_unused_
, void *value
,
333 void *arg _libctf_unused_
)
335 ctf_file_t
*fp
= (ctf_file_t
*) value
;
337 if (fp
->ctf_link_type_mapping
)
338 ctf_dynhash_empty (fp
->ctf_link_type_mapping
);
341 /* Link one input file's types into the output file. */
343 ctf_link_one_input_archive (void *key
, void *value
, void *arg_
)
345 const char *file_name
= (const char *) key
;
346 ctf_archive_t
*arc
= (ctf_archive_t
*) value
;
347 ctf_link_in_member_cb_arg_t
*arg
= (ctf_link_in_member_cb_arg_t
*) arg_
;
350 arg
->file_name
= file_name
;
351 arg
->done_main_member
= 0;
352 if ((arg
->main_input_fp
= ctf_arc_open_by_name (arc
, NULL
, &err
)) == NULL
)
353 if (err
!= ECTF_ARNNAME
)
355 ctf_dprintf ("Cannot open main archive member in input file %s in the "
356 "link: skipping: %s.\n", arg
->file_name
,
361 if (ctf_link_one_input_archive_member (arg
->main_input_fp
,
362 _CTF_SECTION
, arg
) < 0)
364 ctf_file_close (arg
->main_input_fp
);
367 arg
->done_main_member
= 1;
368 if (ctf_archive_iter (arc
, ctf_link_one_input_archive_member
, arg
) < 0)
369 ctf_dprintf ("Cannot traverse archive in input file %s: link "
370 "cannot continue: %s.\n", arg
->file_name
,
371 ctf_errmsg (ctf_errno (arg
->out_fp
)));
374 /* The only error indication to the caller is the errno: so ensure that it
375 is zero if there was no actual error from the caller. */
376 ctf_set_errno (arg
->out_fp
, 0);
378 ctf_file_close (arg
->main_input_fp
);
380 /* Discard the now-unnecessary mapping table data. */
381 if (arg
->out_fp
->ctf_link_type_mapping
)
382 ctf_dynhash_empty (arg
->out_fp
->ctf_link_type_mapping
);
383 ctf_dynhash_iter (arg
->out_fp
->ctf_link_outputs
, empty_link_type_mapping
, NULL
);
386 /* Merge types and variable sections in all files added to the link
389 ctf_link (ctf_file_t
*fp
, int share_mode
)
391 ctf_link_in_member_cb_arg_t arg
;
393 memset (&arg
, 0, sizeof (struct ctf_link_in_member_cb_arg
));
395 arg
.share_mode
= share_mode
;
397 if (fp
->ctf_link_inputs
== NULL
)
398 return 0; /* Nothing to do. */
400 if (fp
->ctf_link_outputs
== NULL
)
401 fp
->ctf_link_outputs
= ctf_dynhash_create (ctf_hash_string
,
402 ctf_hash_eq_string
, free
,
403 ctf_file_close_thunk
);
405 if (fp
->ctf_link_outputs
== NULL
)
406 return ctf_set_errno (fp
, ENOMEM
);
408 ctf_dynhash_iter (fp
->ctf_link_inputs
, ctf_link_one_input_archive
,
411 if (ctf_errno (fp
) != 0)
416 typedef struct ctf_link_out_string_cb_arg
421 } ctf_link_out_string_cb_arg_t
;
423 /* Intern a string in the string table of an output per-CU CTF file. */
425 ctf_link_intern_extern_string (void *key _libctf_unused_
, void *value
,
428 ctf_file_t
*fp
= (ctf_file_t
*) value
;
429 ctf_link_out_string_cb_arg_t
*arg
= (ctf_link_out_string_cb_arg_t
*) arg_
;
431 fp
->ctf_flags
|= LCTF_DIRTY
;
432 if (ctf_str_add_external (fp
, arg
->str
, arg
->offset
) == NULL
)
436 /* Repeatedly call ADD_STRING to acquire strings from the external string table,
437 adding them to the atoms table for this CU and all subsidiary CUs.
439 If ctf_link() is also called, it must be called first if you want the new CTF
440 files ctf_link() can create to get their strings dedupped against the ELF
443 ctf_link_add_strtab (ctf_file_t
*fp
, ctf_link_strtab_string_f
*add_string
,
450 while ((str
= add_string (&offset
, arg
)) != NULL
)
452 ctf_link_out_string_cb_arg_t iter_arg
= { str
, offset
, 0 };
454 fp
->ctf_flags
|= LCTF_DIRTY
;
455 if (ctf_str_add_external (fp
, str
, offset
) == NULL
)
458 ctf_dynhash_iter (fp
->ctf_link_outputs
, ctf_link_intern_extern_string
,
467 /* Not yet implemented. */
469 ctf_link_shuffle_syms (ctf_file_t
*fp _libctf_unused_
,
470 ctf_link_iter_symbol_f
*add_sym _libctf_unused_
,
471 void *arg _libctf_unused_
)
476 typedef struct ctf_name_list_accum_cb_arg
482 } ctf_name_list_accum_cb_arg_t
;
484 /* Accumulate the names and a count of the names in the link output hash,
485 and run ctf_update() on them to generate them. */
487 ctf_accumulate_archive_names (void *key
, void *value
, void *arg_
)
489 const char *name
= (const char *) key
;
490 ctf_file_t
*fp
= (ctf_file_t
*) value
;
493 ctf_name_list_accum_cb_arg_t
*arg
= (ctf_name_list_accum_cb_arg_t
*) arg_
;
496 if ((err
= ctf_update (fp
)) < 0)
498 ctf_set_errno (arg
->fp
, ctf_errno (fp
));
502 if ((names
= realloc (arg
->names
, sizeof (char *) * ++(arg
->i
))) == NULL
)
505 ctf_set_errno (arg
->fp
, ENOMEM
);
509 if ((files
= realloc (arg
->files
, sizeof (ctf_file_t
*) * arg
->i
)) == NULL
)
512 ctf_set_errno (arg
->fp
, ENOMEM
);
516 arg
->names
[(arg
->i
) - 1] = (char *) name
;
518 arg
->files
[(arg
->i
) - 1] = fp
;
521 /* Write out a CTF archive (if there are per-CU CTF files) or a CTF file
522 (otherwise) into a new dynamically-allocated string, and return it.
523 Members with sizes above THRESHOLD are compressed. */
525 ctf_link_write (ctf_file_t
*fp
, size_t *size
, size_t threshold
)
527 ctf_name_list_accum_cb_arg_t arg
;
534 unsigned char *buf
= NULL
;
536 memset (&arg
, 0, sizeof (ctf_name_list_accum_cb_arg_t
));
539 if (ctf_update (fp
) < 0)
541 errloc
= "CTF file construction";
545 if (fp
->ctf_link_outputs
)
547 ctf_dynhash_iter (fp
->ctf_link_outputs
, ctf_accumulate_archive_names
, &arg
);
548 if (ctf_errno (fp
) < 0)
550 errloc
= "hash creation";
555 /* No extra outputs? Just write a simple ctf_file_t. */
557 return ctf_write_mem (fp
, size
, threshold
);
559 /* Writing an archive. Stick ourselves (the shared repository, parent of all
560 other archives) on the front of it with the default name. */
561 if ((names
= realloc (arg
.names
, sizeof (char *) * (arg
.i
+ 1))) == NULL
)
563 errloc
= "name reallocation";
567 memmove (&(arg
.names
[1]), arg
.names
, sizeof (char *) * (arg
.i
));
568 arg
.names
[0] = (char *) _CTF_SECTION
;
570 if ((files
= realloc (arg
.files
,
571 sizeof (struct ctf_file
*) * (arg
.i
+ 1))) == NULL
)
573 errloc
= "ctf_file reallocation";
577 memmove (&(arg
.files
[1]), arg
.files
, sizeof (ctf_file_t
*) * (arg
.i
));
580 if ((f
= tmpfile ()) == NULL
)
582 errloc
= "tempfile creation";
586 if ((err
= ctf_arc_write_fd (fileno (f
), arg
.files
, arg
.i
+ 1,
587 (const char **) arg
.names
,
590 errloc
= "archive writing";
591 ctf_set_errno (fp
, err
);
595 if (fseek (f
, 0, SEEK_END
) < 0)
597 errloc
= "seeking to end";
601 if ((fsize
= ftell (f
)) < 0)
603 errloc
= "filesize determination";
607 if (fseek (f
, 0, SEEK_SET
) < 0)
609 errloc
= "filepos resetting";
613 if ((buf
= malloc (fsize
)) == NULL
)
615 errloc
= "CTF archive buffer allocation";
619 while (!feof (f
) && fread (buf
, fsize
, 1, f
) == 0)
622 errloc
= "reading archive from temporary file";
632 ctf_set_errno (fp
, errno
);
639 ctf_dprintf ("Cannot write archive in link: %s failure: %s\n", errloc
,
640 ctf_errmsg (ctf_errno (fp
)));