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