8f18a4927163027379a64bc9e35262e875ac69e8
[deliverable/binutils-gdb.git] / libctf / ctf-link.c
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
23 /* Linker machinery.
24
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
37 output. */
38
39 /* Add a file to a link. */
40
41 static void ctf_arc_close_thunk (void *arc)
42 {
43 ctf_arc_close ((ctf_archive_t *) arc);
44 }
45
46 static void ctf_file_close_thunk (void *file)
47 {
48 ctf_file_close ((ctf_file_t *) file);
49 }
50
51 int
52 ctf_link_add_ctf (ctf_file_t *fp, ctf_archive_t *ctf, const char *name)
53 {
54 char *dupname = NULL;
55
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,
61 ctf_arc_close_thunk);
62
63 if (fp->ctf_link_inputs == NULL)
64 goto oom;
65
66 if ((dupname = strdup (name)) == NULL)
67 goto oom;
68
69 if (ctf_dynhash_insert (fp->ctf_link_inputs, dupname, ctf) < 0)
70 goto oom;
71
72 return 0;
73 oom:
74 free (fp->ctf_link_inputs);
75 fp->ctf_link_inputs = NULL;
76 free (dupname);
77 return (ctf_set_errno (fp, ENOMEM));
78 }
79
80 typedef struct ctf_link_in_member_cb_arg
81 {
82 ctf_file_t *out_fp;
83 const char *file_name;
84 ctf_file_t *in_fp;
85 ctf_file_t *main_input_fp;
86 const char *cu_name;
87 char *arcname;
88 int done_main_member;
89 int share_mode;
90 int in_input_cu_file;
91 } ctf_link_in_member_cb_arg_t;
92
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. */
96
97 static int
98 ctf_link_one_type (ctf_id_t type, int isroot _libctf_unused_, void *arg_)
99 {
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;
102 int err;
103
104 if (arg->share_mode != CTF_LINK_SHARE_UNCONFLICTED)
105 {
106 ctf_dprintf ("Share-duplicated mode not yet implemented.\n");
107 return ctf_set_errno (arg->out_fp, ECTF_NOTYET);
108 }
109
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. */
114
115 if (!arg->in_input_cu_file)
116 {
117 if (ctf_add_type (arg->out_fp, arg->in_fp, type) != CTF_ERR)
118 return 0;
119
120 err = ctf_errno (arg->out_fp);
121 if (err != ECTF_CONFLICT)
122 {
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,
125 ctf_errmsg (err));
126 return -1;
127 }
128 ctf_set_errno (arg->out_fp, 0);
129 }
130
131 if ((per_cu_out_fp = ctf_dynhash_lookup (arg->out_fp->ctf_link_outputs,
132 arg->arcname)) == NULL)
133 {
134 int err;
135
136 if ((per_cu_out_fp = ctf_create (&err)) == NULL)
137 {
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);
141 return -1;
142 }
143
144 if (ctf_dynhash_insert (arg->out_fp->ctf_link_outputs, arg->arcname,
145 per_cu_out_fp) < 0)
146 {
147 ctf_set_errno (arg->out_fp, ENOMEM);
148 return -1;
149 }
150
151 ctf_import (per_cu_out_fp, arg->out_fp);
152 ctf_cuname_set (per_cu_out_fp, arg->cu_name);
153 }
154
155 if (ctf_add_type (per_cu_out_fp, arg->in_fp, type) != CTF_ERR)
156 return 0;
157
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);
164
165 return 0; /* As above: do not lose types. */
166 }
167
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
172 input file. */
173 static int
174 ctf_link_one_input_archive_member (ctf_file_t *in_fp, const char *name, void *arg_)
175 {
176 ctf_link_in_member_cb_arg_t *arg = (ctf_link_in_member_cb_arg_t *) arg_;
177 int err = 0;
178
179 if (strcmp (name, _CTF_SECTION) == 0)
180 {
181 /* This file is the default member of this archive, and has already been
182 explicitly processed.
183
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. */
189
190 if (arg->done_main_member)
191 return 0;
192 arg->arcname = strdup (".ctf.");
193 if (arg->arcname)
194 {
195 char *new_name;
196
197 new_name = ctf_str_append (arg->arcname, arg->file_name);
198 if (new_name)
199 arg->arcname = new_name;
200 else
201 free (arg->arcname);
202 }
203 }
204 else
205 {
206 arg->arcname = strdup (name);
207
208 /* Get ambiguous types from our parent. */
209 ctf_import (in_fp, arg->main_input_fp);
210 arg->in_input_cu_file = 1;
211 }
212
213 if (!arg->arcname)
214 return ctf_set_errno (in_fp, ENOMEM);
215
216 arg->cu_name = name;
217 if (strncmp (arg->cu_name, ".ctf.", strlen (".ctf.")) == 0)
218 arg->cu_name += strlen (".ctf.");
219 arg->in_fp = in_fp;
220
221 err = ctf_type_iter_all (in_fp, ctf_link_one_type, arg);
222
223 arg->in_input_cu_file = 0;
224 free (arg->arcname);
225
226 if (err < 0)
227 return -1; /* Errno is set for us. */
228
229 return 0;
230 }
231
232 /* Link one input file's types into the output file. */
233 static void
234 ctf_link_one_input_archive (void *key, void *value, void *arg_)
235 {
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_;
239 int err;
240
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)
245 {
246 ctf_dprintf ("Cannot open main archive member in input file %s in the "
247 "link: skipping: %s.\n", arg->file_name,
248 ctf_errmsg (err));
249 return;
250 }
251
252 if (ctf_link_one_input_archive_member (arg->main_input_fp,
253 _CTF_SECTION, arg) < 0)
254 {
255 ctf_file_close (arg->main_input_fp);
256 return;
257 }
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)));
263 else
264 {
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);
268 }
269 ctf_file_close (arg->main_input_fp);
270 }
271
272 /* Merge types and variable sections in all files added to the link
273 together. */
274 int
275 ctf_link (ctf_file_t *fp, int share_mode)
276 {
277 ctf_link_in_member_cb_arg_t arg;
278
279 memset (&arg, 0, sizeof (struct ctf_link_in_member_cb_arg));
280 arg.out_fp = fp;
281 arg.share_mode = share_mode;
282
283 if (fp->ctf_link_inputs == NULL)
284 return 0; /* Nothing to do. */
285
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);
290
291 if (fp->ctf_link_outputs == NULL)
292 return ctf_set_errno (fp, ENOMEM);
293
294 ctf_dynhash_iter (fp->ctf_link_inputs, ctf_link_one_input_archive,
295 &arg);
296
297 if (ctf_errno (fp) != 0)
298 return -1;
299 return 0;
300 }
301
302 typedef struct ctf_link_out_string_cb_arg
303 {
304 const char *str;
305 uint32_t offset;
306 int err;
307 } ctf_link_out_string_cb_arg_t;
308
309 /* Intern a string in the string table of an output per-CU CTF file. */
310 static void
311 ctf_link_intern_extern_string (void *key _libctf_unused_, void *value,
312 void *arg_)
313 {
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_;
316
317 fp->ctf_flags |= LCTF_DIRTY;
318 if (ctf_str_add_external (fp, arg->str, arg->offset) == NULL)
319 arg->err = ENOMEM;
320 }
321
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.
324
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
327 strtab properly. */
328 int
329 ctf_link_add_strtab (ctf_file_t *fp, ctf_link_strtab_string_f *add_string,
330 void *arg)
331 {
332 const char *str;
333 uint32_t offset;
334 int err = 0;
335
336 while ((str = add_string (&offset, arg)) != NULL)
337 {
338 ctf_link_out_string_cb_arg_t iter_arg = { str, offset, 0 };
339
340 fp->ctf_flags |= LCTF_DIRTY;
341 if (ctf_str_add_external (fp, str, offset) == NULL)
342 err = ENOMEM;
343
344 ctf_dynhash_iter (fp->ctf_link_outputs, ctf_link_intern_extern_string,
345 &iter_arg);
346 if (iter_arg.err)
347 err = iter_arg.err;
348 }
349
350 return -err;
351 }
352
353 /* Not yet implemented. */
354 int
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_)
358 {
359 return 0;
360 }
361
362 typedef struct ctf_name_list_accum_cb_arg
363 {
364 char **names;
365 ctf_file_t *fp;
366 ctf_file_t **files;
367 size_t i;
368 } ctf_name_list_accum_cb_arg_t;
369
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. */
372 static void
373 ctf_accumulate_archive_names (void *key, void *value, void *arg_)
374 {
375 const char *name = (const char *) key;
376 ctf_file_t *fp = (ctf_file_t *) value;
377 char **names;
378 ctf_file_t **files;
379 ctf_name_list_accum_cb_arg_t *arg = (ctf_name_list_accum_cb_arg_t *) arg_;
380 int err;
381
382 if ((err = ctf_update (fp)) < 0)
383 {
384 ctf_set_errno (arg->fp, ctf_errno (fp));
385 return;
386 }
387
388 if ((names = realloc (arg->names, sizeof (char *) * ++(arg->i))) == NULL)
389 {
390 (arg->i)--;
391 ctf_set_errno (arg->fp, ENOMEM);
392 return;
393 }
394
395 if ((files = realloc (arg->files, sizeof (ctf_file_t *) * arg->i)) == NULL)
396 {
397 (arg->i)--;
398 ctf_set_errno (arg->fp, ENOMEM);
399 return;
400 }
401 arg->names = names;
402 arg->names[(arg->i) - 1] = (char *) name;
403 arg->files = files;
404 arg->files[(arg->i) - 1] = fp;
405 }
406
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. */
410 unsigned char *
411 ctf_link_write (ctf_file_t *fp, size_t *size, size_t threshold)
412 {
413 ctf_name_list_accum_cb_arg_t arg;
414 char **names;
415 ctf_file_t **files;
416 FILE *f = NULL;
417 int err;
418 long fsize;
419 const char *errloc;
420 unsigned char *buf = NULL;
421
422 memset (&arg, 0, sizeof (ctf_name_list_accum_cb_arg_t));
423 arg.fp = fp;
424
425 if (ctf_update (fp) < 0)
426 {
427 errloc = "CTF file construction";
428 goto err;
429 }
430
431 if (fp->ctf_link_outputs)
432 {
433 ctf_dynhash_iter (fp->ctf_link_outputs, ctf_accumulate_archive_names, &arg);
434 if (ctf_errno (fp) < 0)
435 {
436 errloc = "hash creation";
437 goto err;
438 }
439 }
440
441 /* No extra outputs? Just write a simple ctf_file_t. */
442 if (arg.i == 0)
443 return ctf_write_mem (fp, size, threshold);
444
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)
448 {
449 errloc = "name reallocation";
450 goto err_no;
451 }
452 arg.names = names;
453 memmove (&(arg.names[1]), arg.names, sizeof (char *) * (arg.i));
454 arg.names[0] = (char *) _CTF_SECTION;
455
456 if ((files = realloc (arg.files,
457 sizeof (struct ctf_file *) * (arg.i + 1))) == NULL)
458 {
459 errloc = "ctf_file reallocation";
460 goto err_no;
461 }
462 arg.files = files;
463 memmove (&(arg.files[1]), arg.files, sizeof (ctf_file_t *) * (arg.i));
464 arg.files[0] = fp;
465
466 if ((f = tmpfile ()) == NULL)
467 {
468 errloc = "tempfile creation";
469 goto err_no;
470 }
471
472 if ((err = ctf_arc_write_fd (fileno (f), arg.files, arg.i + 1,
473 (const char **) arg.names,
474 threshold)) < 0)
475 {
476 errloc = "archive writing";
477 ctf_set_errno (fp, err);
478 goto err;
479 }
480
481 if (fseek (f, 0, SEEK_END) < 0)
482 {
483 errloc = "seeking to end";
484 goto err_no;
485 }
486
487 if ((fsize = ftell (f)) < 0)
488 {
489 errloc = "filesize determination";
490 goto err_no;
491 }
492
493 if (fseek (f, 0, SEEK_SET) < 0)
494 {
495 errloc = "filepos resetting";
496 goto err_no;
497 }
498
499 if ((buf = malloc (fsize)) == NULL)
500 {
501 errloc = "CTF archive buffer allocation";
502 goto err_no;
503 }
504
505 while (!feof (f) && fread (buf, fsize, 1, f) == 0)
506 if (ferror (f))
507 {
508 errloc = "reading archive from temporary file";
509 goto err_no;
510 }
511
512 *size = fsize;
513 free (arg.names);
514 free (arg.files);
515 return buf;
516
517 err_no:
518 ctf_set_errno (fp, errno);
519 err:
520 free (buf);
521 if (f)
522 fclose (f);
523 free (arg.names);
524 free (arg.files);
525 ctf_dprintf ("Cannot write archive in link: %s failure: %s\n", errloc,
526 ctf_errmsg (ctf_errno (fp)));
527 return NULL;
528 }
This page took 0.071894 seconds and 3 git commands to generate.