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/>. */
25 CTF linking consists of adding CTF archives full of content to be merged into
26 this one to the current file (which must be writable) by calling
27 ctf_link_add_ctf(). Once this is done, a call to ctf_link() will merge the
28 type tables together, generating new CTF files as needed, with this one as a
29 parent, to contain types from the inputs which conflict.
30 ctf_link_add_strtab() takes a callback which provides string/offset pairs to
31 be added to the external symbol table and deduplicated from all CTF string
32 tables in the output link; ctf_link_shuffle_syms() takes a callback which
33 provides symtab entries in ascending order, and shuffles the function and
34 data sections to match; and ctf_link_write() emits a CTF file (if there are
35 no conflicts requiring per-compilation-unit sub-CTF files) or CTF archives
36 (otherwise) and returns it, suitable for addition in the .ctf section of the
39 /* Add a file to a link. */
41 static void ctf_arc_close_thunk (void *arc
)
43 ctf_arc_close ((ctf_archive_t
*) arc
);
46 static void ctf_file_close_thunk (void *file
)
48 ctf_file_close ((ctf_file_t
*) file
);
52 ctf_link_add_ctf (ctf_file_t
*fp
, ctf_archive_t
*ctf
, const char *name
)
56 if (fp
->ctf_link_outputs
)
57 return (ctf_set_errno (fp
, ECTF_LINKADDEDLATE
));
58 if (fp
->ctf_link_inputs
== NULL
)
59 fp
->ctf_link_inputs
= ctf_dynhash_create (ctf_hash_string
,
60 ctf_hash_eq_string
, free
,
63 if (fp
->ctf_link_inputs
== NULL
)
66 if ((dupname
= strdup (name
)) == NULL
)
69 if (ctf_dynhash_insert (fp
->ctf_link_inputs
, dupname
, ctf
) < 0)
74 free (fp
->ctf_link_inputs
);
75 fp
->ctf_link_inputs
= NULL
;
77 return (ctf_set_errno (fp
, ENOMEM
));
80 typedef struct ctf_link_in_member_cb_arg
83 const char *file_name
;
85 ctf_file_t
*main_input_fp
;
91 } ctf_link_in_member_cb_arg_t
;
93 /* Link one type into the link. We rely on ctf_add_type() to detect
94 duplicates. This is not terribly reliable yet (unnmamed types will be
95 mindlessly duplicated), but will improve shortly. */
98 ctf_link_one_type (ctf_id_t type
, int isroot _libctf_unused_
, void *arg_
)
100 ctf_link_in_member_cb_arg_t
*arg
= (ctf_link_in_member_cb_arg_t
*) arg_
;
101 ctf_file_t
*per_cu_out_fp
;
104 if (arg
->share_mode
!= CTF_LINK_SHARE_UNCONFLICTED
)
106 ctf_dprintf ("Share-duplicated mode not yet implemented.\n");
107 return ctf_set_errno (arg
->out_fp
, ECTF_NOTYET
);
110 /* Simply call ctf_add_type: if it reports a conflict and we're adding to the
111 main CTF file, add to the per-CU archive member instead, creating it if
112 necessary. If we got this type from a per-CU archive member, add it
113 straight back to the corresponding member in the output. */
115 if (!arg
->in_input_cu_file
)
117 if (ctf_add_type (arg
->out_fp
, arg
->in_fp
, type
) != CTF_ERR
)
120 err
= ctf_errno (arg
->out_fp
);
121 if (err
!= ECTF_CONFLICT
)
123 ctf_dprintf ("Cannot link type %lx from archive member %s, input file %s "
124 "into output link: %s\n", type
, arg
->arcname
, arg
->file_name
,
128 ctf_set_errno (arg
->out_fp
, 0);
131 if ((per_cu_out_fp
= ctf_dynhash_lookup (arg
->out_fp
->ctf_link_outputs
,
132 arg
->arcname
)) == NULL
)
136 if ((per_cu_out_fp
= ctf_create (&err
)) == NULL
)
138 ctf_dprintf ("Cannot create per-CU CTF archive for member %s: %s\n",
139 arg
->arcname
, ctf_errmsg (err
));
140 ctf_set_errno (arg
->out_fp
, err
);
144 if (ctf_dynhash_insert (arg
->out_fp
->ctf_link_outputs
, arg
->arcname
,
147 ctf_set_errno (arg
->out_fp
, ENOMEM
);
151 ctf_import (per_cu_out_fp
, arg
->out_fp
);
152 ctf_cuname_set (per_cu_out_fp
, arg
->cu_name
);
155 if (ctf_add_type (per_cu_out_fp
, arg
->in_fp
, type
) != CTF_ERR
)
158 err
= ctf_errno (per_cu_out_fp
);
159 if (err
== ECTF_CONFLICT
)
160 /* Conflicts are possible at this stage only if a non-ld user has combined
161 multiple TUs into a single output dictionary. Even in this case we do not
162 want to stop the link or propagate the error. */
163 ctf_set_errno (arg
->out_fp
, 0);
165 return 0; /* As above: do not lose types. */
168 /* Merge every type and variable in this archive member into the link, so we can
169 relink things that have already had ld run on them. We use the archive
170 member name, sans any leading '.ctf.', as the CU name for ambiguous types if
171 there is one and it's not the default: otherwise, we use the name of the
174 ctf_link_one_input_archive_member (ctf_file_t
*in_fp
, const char *name
, void *arg_
)
176 ctf_link_in_member_cb_arg_t
*arg
= (ctf_link_in_member_cb_arg_t
*) arg_
;
179 if (strcmp (name
, _CTF_SECTION
) == 0)
181 /* This file is the default member of this archive, and has already been
182 explicitly processed.
184 In the default sharing mode of CTF_LINK_SHARE_UNCONFLICTED, it does no
185 harm to rescan an existing shared repo again: all the types will just
186 end up in the same place. But in CTF_LINK_SHARE_DUPLICATED mode, this
187 causes the system to erroneously conclude that all types are duplicated
188 and should be shared, even if they are not. */
190 if (arg
->done_main_member
)
192 arg
->arcname
= strdup (".ctf.");
197 new_name
= ctf_str_append (arg
->arcname
, arg
->file_name
);
199 arg
->arcname
= new_name
;
206 arg
->arcname
= strdup (name
);
208 /* Get ambiguous types from our parent. */
209 ctf_import (in_fp
, arg
->main_input_fp
);
210 arg
->in_input_cu_file
= 1;
214 return ctf_set_errno (in_fp
, ENOMEM
);
217 if (strncmp (arg
->cu_name
, ".ctf.", strlen (".ctf.")) == 0)
218 arg
->cu_name
+= strlen (".ctf.");
221 err
= ctf_type_iter_all (in_fp
, ctf_link_one_type
, arg
);
223 arg
->in_input_cu_file
= 0;
227 return -1; /* Errno is set for us. */
232 /* Link one input file's types into the output file. */
234 ctf_link_one_input_archive (void *key
, void *value
, void *arg_
)
236 const char *file_name
= (const char *) key
;
237 ctf_archive_t
*arc
= (ctf_archive_t
*) value
;
238 ctf_link_in_member_cb_arg_t
*arg
= (ctf_link_in_member_cb_arg_t
*) arg_
;
241 arg
->file_name
= file_name
;
242 arg
->done_main_member
= 0;
243 if ((arg
->main_input_fp
= ctf_arc_open_by_name (arc
, NULL
, &err
)) == NULL
)
244 if (err
!= ECTF_ARNNAME
)
246 ctf_dprintf ("Cannot open main archive member in input file %s in the "
247 "link: skipping: %s.\n", arg
->file_name
,
252 if (ctf_link_one_input_archive_member (arg
->main_input_fp
,
253 _CTF_SECTION
, arg
) < 0)
255 ctf_file_close (arg
->main_input_fp
);
258 arg
->done_main_member
= 1;
259 if (ctf_archive_iter (arc
, ctf_link_one_input_archive_member
, arg
) < 0)
260 ctf_dprintf ("Cannot traverse archive in input file %s: link "
261 "cannot continue: %s.\n", arg
->file_name
,
262 ctf_errmsg (ctf_errno (arg
->out_fp
)));
265 /* The only error indication to the caller is the errno: so ensure that it
266 is zero if there was no actual error from the caller. */
267 ctf_set_errno (arg
->out_fp
, 0);
269 ctf_file_close (arg
->main_input_fp
);
272 /* Merge types and variable sections in all files added to the link
275 ctf_link (ctf_file_t
*fp
, int share_mode
)
277 ctf_link_in_member_cb_arg_t arg
;
279 memset (&arg
, 0, sizeof (struct ctf_link_in_member_cb_arg
));
281 arg
.share_mode
= share_mode
;
283 if (fp
->ctf_link_inputs
== NULL
)
284 return 0; /* Nothing to do. */
286 if (fp
->ctf_link_outputs
== NULL
)
287 fp
->ctf_link_outputs
= ctf_dynhash_create (ctf_hash_string
,
288 ctf_hash_eq_string
, free
,
289 ctf_file_close_thunk
);
291 if (fp
->ctf_link_outputs
== NULL
)
292 return ctf_set_errno (fp
, ENOMEM
);
294 ctf_dynhash_iter (fp
->ctf_link_inputs
, ctf_link_one_input_archive
,
297 if (ctf_errno (fp
) != 0)
302 typedef struct ctf_link_out_string_cb_arg
307 } ctf_link_out_string_cb_arg_t
;
309 /* Intern a string in the string table of an output per-CU CTF file. */
311 ctf_link_intern_extern_string (void *key _libctf_unused_
, void *value
,
314 ctf_file_t
*fp
= (ctf_file_t
*) value
;
315 ctf_link_out_string_cb_arg_t
*arg
= (ctf_link_out_string_cb_arg_t
*) arg_
;
317 fp
->ctf_flags
|= LCTF_DIRTY
;
318 if (ctf_str_add_external (fp
, arg
->str
, arg
->offset
) == NULL
)
322 /* Repeatedly call ADD_STRING to acquire strings from the external string table,
323 adding them to the atoms table for this CU and all subsidiary CUs.
325 If ctf_link() is also called, it must be called first if you want the new CTF
326 files ctf_link() can create to get their strings dedupped against the ELF
329 ctf_link_add_strtab (ctf_file_t
*fp
, ctf_link_strtab_string_f
*add_string
,
336 while ((str
= add_string (&offset
, arg
)) != NULL
)
338 ctf_link_out_string_cb_arg_t iter_arg
= { str
, offset
, 0 };
340 fp
->ctf_flags
|= LCTF_DIRTY
;
341 if (ctf_str_add_external (fp
, str
, offset
) == NULL
)
344 ctf_dynhash_iter (fp
->ctf_link_outputs
, ctf_link_intern_extern_string
,
353 /* Not yet implemented. */
355 ctf_link_shuffle_syms (ctf_file_t
*fp _libctf_unused_
,
356 ctf_link_iter_symbol_f
*add_sym _libctf_unused_
,
357 void *arg _libctf_unused_
)
362 typedef struct ctf_name_list_accum_cb_arg
368 } ctf_name_list_accum_cb_arg_t
;
370 /* Accumulate the names and a count of the names in the link output hash,
371 and run ctf_update() on them to generate them. */
373 ctf_accumulate_archive_names (void *key
, void *value
, void *arg_
)
375 const char *name
= (const char *) key
;
376 ctf_file_t
*fp
= (ctf_file_t
*) value
;
379 ctf_name_list_accum_cb_arg_t
*arg
= (ctf_name_list_accum_cb_arg_t
*) arg_
;
382 if ((err
= ctf_update (fp
)) < 0)
384 ctf_set_errno (arg
->fp
, ctf_errno (fp
));
388 if ((names
= realloc (arg
->names
, sizeof (char *) * ++(arg
->i
))) == NULL
)
391 ctf_set_errno (arg
->fp
, ENOMEM
);
395 if ((files
= realloc (arg
->files
, sizeof (ctf_file_t
*) * arg
->i
)) == NULL
)
398 ctf_set_errno (arg
->fp
, ENOMEM
);
402 arg
->names
[(arg
->i
) - 1] = (char *) name
;
404 arg
->files
[(arg
->i
) - 1] = fp
;
407 /* Write out a CTF archive (if there are per-CU CTF files) or a CTF file
408 (otherwise) into a new dynamically-allocated string, and return it.
409 Members with sizes above THRESHOLD are compressed. */
411 ctf_link_write (ctf_file_t
*fp
, size_t *size
, size_t threshold
)
413 ctf_name_list_accum_cb_arg_t arg
;
420 unsigned char *buf
= NULL
;
422 memset (&arg
, 0, sizeof (ctf_name_list_accum_cb_arg_t
));
425 if (ctf_update (fp
) < 0)
427 errloc
= "CTF file construction";
431 if (fp
->ctf_link_outputs
)
433 ctf_dynhash_iter (fp
->ctf_link_outputs
, ctf_accumulate_archive_names
, &arg
);
434 if (ctf_errno (fp
) < 0)
436 errloc
= "hash creation";
441 /* No extra outputs? Just write a simple ctf_file_t. */
443 return ctf_write_mem (fp
, size
, threshold
);
445 /* Writing an archive. Stick ourselves (the shared repository, parent of all
446 other archives) on the front of it with the default name. */
447 if ((names
= realloc (arg
.names
, sizeof (char *) * (arg
.i
+ 1))) == NULL
)
449 errloc
= "name reallocation";
453 memmove (&(arg
.names
[1]), arg
.names
, sizeof (char *) * (arg
.i
));
454 arg
.names
[0] = (char *) _CTF_SECTION
;
456 if ((files
= realloc (arg
.files
,
457 sizeof (struct ctf_file
*) * (arg
.i
+ 1))) == NULL
)
459 errloc
= "ctf_file reallocation";
463 memmove (&(arg
.files
[1]), arg
.files
, sizeof (ctf_file_t
*) * (arg
.i
));
466 if ((f
= tmpfile ()) == NULL
)
468 errloc
= "tempfile creation";
472 if ((err
= ctf_arc_write_fd (fileno (f
), arg
.files
, arg
.i
+ 1,
473 (const char **) arg
.names
,
476 errloc
= "archive writing";
477 ctf_set_errno (fp
, err
);
481 if (fseek (f
, 0, SEEK_END
) < 0)
483 errloc
= "seeking to end";
487 if ((fsize
= ftell (f
)) < 0)
489 errloc
= "filesize determination";
493 if (fseek (f
, 0, SEEK_SET
) < 0)
495 errloc
= "filepos resetting";
499 if ((buf
= malloc (fsize
)) == NULL
)
501 errloc
= "CTF archive buffer allocation";
505 while (!feof (f
) && fread (buf
, fsize
, 1, f
) == 0)
508 errloc
= "reading archive from temporary file";
518 ctf_set_errno (fp
, errno
);
525 ctf_dprintf ("Cannot write archive in link: %s failure: %s\n", errloc
,
526 ctf_errmsg (ctf_errno (fp
)));