/src/binutils-gdb/libctf/ctf-link.c
Line | Count | Source |
1 | | /* CTF linking. |
2 | | Copyright (C) 2019-2026 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 | | /* CTF linking consists of adding CTF archives full of content to be merged into |
24 | | this one to the current file (which must be writable) by calling |
25 | | ctf_link_add_ctf. Once this is done, a call to ctf_link will merge the type |
26 | | tables together, generating new CTF files as needed, with this one as a |
27 | | parent, to contain types from the inputs which conflict. ctf_link_add_strtab |
28 | | takes a callback which provides string/offset pairs to be added to the |
29 | | external symbol table and deduplicated from all CTF string tables in the |
30 | | output link; ctf_link_shuffle_syms takes a callback which provides symtab |
31 | | entries in ascending order, and shuffles the function and data sections to |
32 | | match; and ctf_link_write emits a CTF file (if there are no conflicts |
33 | | requiring per-compilation-unit sub-CTF files) or CTF archives (otherwise) and |
34 | | returns it, suitable for addition in the .ctf section of the output. */ |
35 | | |
36 | | /* Return the name of the compilation unit this CTF dict or its parent applies |
37 | | to, or a non-null string otherwise: prefer the parent. Used in debugging |
38 | | output. Sometimes used for outputs too. */ |
39 | | const char * |
40 | | ctf_link_input_name (ctf_dict_t *fp) |
41 | 0 | { |
42 | 0 | if (fp->ctf_parent && fp->ctf_parent->ctf_cuname) |
43 | 0 | return fp->ctf_parent->ctf_cuname; |
44 | 0 | else if (fp->ctf_cuname) |
45 | 0 | return fp->ctf_cuname; |
46 | 0 | else |
47 | 0 | return "(unnamed)"; |
48 | 0 | } |
49 | | |
50 | | /* Return the cuname of a dict, or the string "unnamed-CU" if none. */ |
51 | | |
52 | | static const char * |
53 | | ctf_unnamed_cuname (ctf_dict_t *fp) |
54 | 0 | { |
55 | 0 | const char *cuname = ctf_cuname (fp); |
56 | |
|
57 | 0 | if (!cuname) |
58 | 0 | cuname = "unnamed-CU"; |
59 | |
|
60 | 0 | return cuname; |
61 | 0 | } |
62 | | |
63 | | /* The linker inputs look like this. clin_fp is used for short-circuited |
64 | | CU-mapped links that can entirely avoid the first link phase in some |
65 | | situations in favour of just passing on the contained ctf_dict_t: it is |
66 | | always the sole ctf_dict_t inside the corresponding clin_arc. If set, it |
67 | | gets assigned directly to the final link inputs and freed from there, so it |
68 | | never gets explicitly freed in the ctf_link_input. */ |
69 | | typedef struct ctf_link_input |
70 | | { |
71 | | char *clin_filename; |
72 | | ctf_archive_t *clin_arc; |
73 | | ctf_dict_t *clin_fp; |
74 | | int n; |
75 | | } ctf_link_input_t; |
76 | | |
77 | | static void |
78 | | ctf_link_input_close (void *input) |
79 | 0 | { |
80 | 0 | ctf_link_input_t *i = (ctf_link_input_t *) input; |
81 | 0 | if (i->clin_arc) |
82 | 0 | ctf_arc_close (i->clin_arc); |
83 | 0 | free (i->clin_filename); |
84 | 0 | free (i); |
85 | 0 | } |
86 | | |
87 | | /* Like ctf_link_add_ctf, below, but with no error-checking, so it can be called |
88 | | in the middle of an ongoing link. */ |
89 | | static int |
90 | | ctf_link_add_ctf_internal (ctf_dict_t *fp, ctf_archive_t *ctf, |
91 | | ctf_dict_t *fp_input, const char *name) |
92 | 0 | { |
93 | 0 | int existing = 0; |
94 | 0 | ctf_link_input_t *input; |
95 | 0 | char *filename, *keyname; |
96 | | |
97 | | /* Existing: return it, or (if a different dict with the same name |
98 | | is already there) make up a new unique name. Always use the actual name |
99 | | for the filename, because that needs to be ctf_open()ed. */ |
100 | |
|
101 | 0 | if ((input = ctf_dynhash_lookup (fp->ctf_link_inputs, name)) != NULL) |
102 | 0 | { |
103 | 0 | if ((fp_input != NULL && (input->clin_fp == fp_input)) |
104 | 0 | || (ctf != NULL && (input->clin_arc == ctf))) |
105 | 0 | return 0; |
106 | 0 | existing = 1; |
107 | 0 | } |
108 | | |
109 | 0 | if ((filename = strdup (name)) == NULL) |
110 | 0 | goto oom; |
111 | | |
112 | 0 | if ((input = calloc (1, sizeof (ctf_link_input_t))) == NULL) |
113 | 0 | goto oom1; |
114 | | |
115 | 0 | input->clin_arc = ctf; |
116 | 0 | input->clin_fp = fp_input; |
117 | 0 | input->clin_filename = filename; |
118 | 0 | input->n = ctf_dynhash_elements (fp->ctf_link_inputs); |
119 | |
|
120 | 0 | if (existing) |
121 | 0 | { |
122 | 0 | if (asprintf (&keyname, "%s#%li", name, (long int) |
123 | 0 | ctf_dynhash_elements (fp->ctf_link_inputs)) < 0) |
124 | 0 | goto oom2; |
125 | 0 | } |
126 | 0 | else if ((keyname = strdup (name)) == NULL) |
127 | 0 | goto oom2; |
128 | | |
129 | 0 | if (ctf_dynhash_insert (fp->ctf_link_inputs, keyname, input) < 0) |
130 | 0 | goto oom3; |
131 | | |
132 | 0 | return 0; |
133 | | |
134 | 0 | oom3: |
135 | 0 | free (keyname); |
136 | 0 | oom2: |
137 | 0 | free (input); |
138 | 0 | oom1: |
139 | 0 | free (filename); |
140 | 0 | oom: |
141 | 0 | return ctf_set_errno (fp, ENOMEM); |
142 | 0 | } |
143 | | |
144 | | /* Add an opened CTF archive or unopened file (by name) to a link. |
145 | | If CTF is NULL and NAME is non-null, an unopened file is meant: |
146 | | otherwise, the specified archive is assumed to have the given NAME. |
147 | | |
148 | | If CTF is NULL, the NAME is only opened when needed, and is closed when no |
149 | | longer needed, so that large cu-mapped links will only use memory for their |
150 | | cu-mapped inputs briefly (compensating for the memory usage of the |
151 | | smushed-together cu-mapped verion). |
152 | | |
153 | | Passed in CTF args are owned by the dictionary and will be freed by it. |
154 | | |
155 | | The order of calls to this function influences the order of types in the |
156 | | final link output, but otherwise is not important. |
157 | | |
158 | | Repeated additions of the same NAME have no effect; repeated additions of |
159 | | different dicts with the same NAME add all the dicts with unique NAMEs |
160 | | derived from NAME. */ |
161 | | |
162 | | int |
163 | | ctf_link_add_ctf (ctf_dict_t *fp, ctf_archive_t *ctf, const char *name) |
164 | 0 | { |
165 | 0 | if (!name) |
166 | 0 | return (ctf_set_errno (fp, EINVAL)); |
167 | | |
168 | 0 | if (fp->ctf_link_outputs) |
169 | 0 | return (ctf_set_errno (fp, ECTF_LINKADDEDLATE)); |
170 | | |
171 | 0 | if (fp->ctf_link_inputs == NULL) |
172 | 0 | fp->ctf_link_inputs = ctf_dynhash_create (ctf_hash_string, |
173 | 0 | ctf_hash_eq_string, free, |
174 | 0 | ctf_link_input_close); |
175 | |
|
176 | 0 | if (fp->ctf_link_inputs == NULL) |
177 | 0 | return (ctf_set_errno (fp, ENOMEM)); |
178 | | |
179 | | /* We can only lazily open files if libctf.so is in use rather than |
180 | | libctf-nobfd.so. */ |
181 | | |
182 | | #if NOBFD |
183 | | if (!ctf) |
184 | | return (ctf_set_errno (fp, ECTF_NEEDSBFD)); |
185 | | #endif |
186 | | |
187 | 0 | return ctf_link_add_ctf_internal (fp, ctf, NULL, name); |
188 | 0 | } |
189 | | |
190 | | /* Lazily open a CTF archive for linking, if not already open. |
191 | | |
192 | | Returns the number of files contained within the opened archive (0 for none), |
193 | | or -1 on error, as usual. */ |
194 | | static ssize_t |
195 | | ctf_link_lazy_open (ctf_dict_t *fp, ctf_link_input_t *input) |
196 | 0 | { |
197 | 0 | size_t count; |
198 | 0 | int err; |
199 | |
|
200 | 0 | if (input->clin_arc) |
201 | 0 | return ctf_archive_count (input->clin_arc); |
202 | | |
203 | 0 | if (input->clin_fp) |
204 | 0 | return 1; |
205 | | |
206 | | /* See ctf_link_add_ctf. */ |
207 | | #if NOBFD |
208 | | ctf_err_warn (fp, 0, ECTF_NEEDSBFD, _("cannot open %s lazily"), |
209 | | input->clin_filename); |
210 | | return ctf_set_errno (fp, ECTF_NEEDSBFD); |
211 | | #else |
212 | 0 | input->clin_arc = ctf_open (input->clin_filename, NULL, &err); |
213 | 0 | #endif |
214 | | |
215 | | /* Having no CTF sections is not an error. We just don't need to do |
216 | | anything. */ |
217 | |
|
218 | 0 | if (!input->clin_arc) |
219 | 0 | { |
220 | 0 | if (err == ECTF_NOCTFDATA) |
221 | 0 | return 0; |
222 | | |
223 | 0 | ctf_err_warn (fp, 0, err, _("opening CTF %s failed"), |
224 | 0 | input->clin_filename); |
225 | 0 | return ctf_set_errno (fp, err); |
226 | 0 | } |
227 | | |
228 | 0 | if ((count = ctf_archive_count (input->clin_arc)) == 0) |
229 | 0 | ctf_arc_close (input->clin_arc); |
230 | |
|
231 | 0 | return (ssize_t) count; |
232 | 0 | } |
233 | | |
234 | | /* Find a non-clashing unique name for a per-CU output dict, to prevent distinct |
235 | | members corresponding to inputs with identical cunames from overwriting each |
236 | | other. The name should be something like NAME. */ |
237 | | |
238 | | static char * |
239 | | ctf_new_per_cu_name (ctf_dict_t *fp, const char *name) |
240 | 0 | { |
241 | 0 | char *dynname; |
242 | 0 | long int i = 0; |
243 | |
|
244 | 0 | if ((dynname = strdup (name)) == NULL) |
245 | 0 | return NULL; |
246 | | |
247 | 0 | while ((ctf_dynhash_lookup (fp->ctf_link_outputs, dynname)) != NULL) |
248 | 0 | { |
249 | 0 | free (dynname); |
250 | 0 | if (asprintf (&dynname, "%s#%li", name, i++) < 0) |
251 | 0 | return NULL; |
252 | 0 | } |
253 | | |
254 | 0 | return dynname; |
255 | 0 | } |
256 | | |
257 | | /* Return a per-CU output CTF dictionary suitable for the given INPUT or CU, |
258 | | creating and interning it if need be. */ |
259 | | |
260 | | static ctf_dict_t * |
261 | | ctf_create_per_cu (ctf_dict_t *fp, ctf_dict_t *input, const char *cu_name) |
262 | 0 | { |
263 | 0 | ctf_dict_t *cu_fp; |
264 | 0 | const char *ctf_name = NULL; |
265 | 0 | char *dynname = NULL; |
266 | | |
267 | | /* Already has a per-CU mapping? Just return it. */ |
268 | |
|
269 | 0 | if (input && input->ctf_link_in_out) |
270 | 0 | return input->ctf_link_in_out; |
271 | | |
272 | | /* Check the mapping table and translate the per-CU name we use |
273 | | accordingly. */ |
274 | | |
275 | 0 | if (cu_name == NULL) |
276 | 0 | cu_name = ctf_unnamed_cuname (input); |
277 | |
|
278 | 0 | if (fp->ctf_link_in_cu_mapping) |
279 | 0 | { |
280 | 0 | if ((ctf_name = ctf_dynhash_lookup (fp->ctf_link_in_cu_mapping, |
281 | 0 | cu_name)) == NULL) |
282 | 0 | ctf_name = cu_name; |
283 | 0 | } |
284 | |
|
285 | 0 | if (ctf_name == NULL) |
286 | 0 | ctf_name = cu_name; |
287 | | |
288 | | /* Look up the per-CU dict. If we don't know of one, or it is for a different input |
289 | | CU which just happens to have the same name, create a new one. If we are creating |
290 | | a dict with no input specified, anything will do. */ |
291 | |
|
292 | 0 | if ((cu_fp = ctf_dynhash_lookup (fp->ctf_link_outputs, ctf_name)) == NULL |
293 | 0 | || (input && cu_fp->ctf_link_in_out != fp)) |
294 | 0 | { |
295 | 0 | int err; |
296 | |
|
297 | 0 | if ((cu_fp = ctf_create (&err)) == NULL) |
298 | 0 | { |
299 | 0 | ctf_set_errno (fp, err); |
300 | 0 | ctf_err_warn (fp, 0, 0, _("cannot create per-CU CTF archive for " |
301 | 0 | "input CU %s"), cu_name); |
302 | 0 | return NULL; |
303 | 0 | } |
304 | | |
305 | | /* The deduplicator is ready for strict enumerator value checking. */ |
306 | 0 | cu_fp->ctf_flags |= LCTF_STRICT_NO_DUP_ENUMERATORS; |
307 | 0 | ctf_import_unref (cu_fp, fp); |
308 | |
|
309 | 0 | if ((dynname = ctf_new_per_cu_name (fp, ctf_name)) == NULL) |
310 | 0 | goto oom; |
311 | | |
312 | 0 | ctf_cuname_set (cu_fp, cu_name); |
313 | |
|
314 | 0 | ctf_parent_name_set (cu_fp, _CTF_SECTION); |
315 | 0 | cu_fp->ctf_link_in_out = fp; |
316 | 0 | fp->ctf_link_in_out = cu_fp; |
317 | |
|
318 | 0 | if (ctf_dynhash_insert (fp->ctf_link_outputs, dynname, cu_fp) < 0) |
319 | 0 | goto oom; |
320 | 0 | } |
321 | 0 | return cu_fp; |
322 | | |
323 | 0 | oom: |
324 | 0 | free (dynname); |
325 | 0 | ctf_dict_close (cu_fp); |
326 | 0 | ctf_set_errno (fp, ENOMEM); |
327 | 0 | return NULL; |
328 | 0 | } |
329 | | |
330 | | /* Add a mapping directing that the CU named FROM should have its |
331 | | conflicting/non-duplicate types (depending on link mode) go into a dict |
332 | | named TO. Many FROMs can share a TO, but adding the same FROM with |
333 | | a different TO will replace the old mapping. |
334 | | |
335 | | We forcibly add a dict named TO in every case, even though it may well |
336 | | wind up empty, because clients that use this facility usually expect to find |
337 | | every TO dict present, even if empty, and malfunction otherwise. */ |
338 | | |
339 | | int |
340 | | ctf_link_add_cu_mapping (ctf_dict_t *fp, const char *from, const char *to) |
341 | 0 | { |
342 | 0 | int err; |
343 | 0 | char *f = NULL, *t = NULL, *existing; |
344 | 0 | ctf_dynhash_t *one_out; |
345 | | |
346 | | /* Mappings cannot be set up if per-CU output dicts already exist. */ |
347 | 0 | if (fp->ctf_link_outputs && ctf_dynhash_elements (fp->ctf_link_outputs) != 0) |
348 | 0 | return (ctf_set_errno (fp, ECTF_LINKADDEDLATE)); |
349 | | |
350 | 0 | if (fp->ctf_link_in_cu_mapping == NULL) |
351 | 0 | fp->ctf_link_in_cu_mapping = ctf_dynhash_create (ctf_hash_string, |
352 | 0 | ctf_hash_eq_string, free, |
353 | 0 | free); |
354 | 0 | if (fp->ctf_link_in_cu_mapping == NULL) |
355 | 0 | goto oom; |
356 | | |
357 | 0 | if (fp->ctf_link_out_cu_mapping == NULL) |
358 | 0 | fp->ctf_link_out_cu_mapping = ctf_dynhash_create (ctf_hash_string, |
359 | 0 | ctf_hash_eq_string, free, |
360 | 0 | (ctf_hash_free_fun) |
361 | 0 | ctf_dynhash_destroy); |
362 | 0 | if (fp->ctf_link_out_cu_mapping == NULL) |
363 | 0 | goto oom; |
364 | | |
365 | | /* If this FROM already exists, remove the mapping from both the FROM->TO |
366 | | and the TO->FROM lists: the user wants to change it. */ |
367 | | |
368 | 0 | if ((existing = ctf_dynhash_lookup (fp->ctf_link_in_cu_mapping, from)) != NULL) |
369 | 0 | { |
370 | 0 | one_out = ctf_dynhash_lookup (fp->ctf_link_out_cu_mapping, existing); |
371 | 0 | if (!ctf_assert (fp, one_out)) |
372 | 0 | return -1; /* errno is set for us. */ |
373 | | |
374 | 0 | ctf_dynhash_remove (one_out, from); |
375 | 0 | ctf_dynhash_remove (fp->ctf_link_in_cu_mapping, from); |
376 | 0 | } |
377 | | |
378 | 0 | f = strdup (from); |
379 | 0 | t = strdup (to); |
380 | 0 | if (!f || !t) |
381 | 0 | goto oom; |
382 | | |
383 | | /* Track both in a list from FROM to TO and in a list from TO to a list of |
384 | | FROM. The former is used to create TUs with the mapped-to name at need: |
385 | | the latter is used in deduplicating links to pull in all input CUs |
386 | | corresponding to a single output CU. */ |
387 | | |
388 | 0 | if ((err = ctf_dynhash_insert (fp->ctf_link_in_cu_mapping, f, t)) < 0) |
389 | 0 | { |
390 | 0 | ctf_set_errno (fp, err); |
391 | 0 | goto oom_noerrno; |
392 | 0 | } |
393 | | |
394 | | /* f and t are now owned by the in_cu_mapping: reallocate them. */ |
395 | 0 | f = strdup (from); |
396 | 0 | t = strdup (to); |
397 | 0 | if (!f || !t) |
398 | 0 | goto oom; |
399 | | |
400 | 0 | if ((one_out = ctf_dynhash_lookup (fp->ctf_link_out_cu_mapping, t)) == NULL) |
401 | 0 | { |
402 | 0 | if ((one_out = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string, |
403 | 0 | free, NULL)) == NULL) |
404 | 0 | goto oom; |
405 | 0 | if ((err = ctf_dynhash_insert (fp->ctf_link_out_cu_mapping, |
406 | 0 | t, one_out)) < 0) |
407 | 0 | { |
408 | 0 | ctf_dynhash_destroy (one_out); |
409 | 0 | ctf_set_errno (fp, err); |
410 | 0 | goto oom_noerrno; |
411 | 0 | } |
412 | 0 | } |
413 | 0 | else |
414 | 0 | { |
415 | 0 | free (t); |
416 | 0 | t = NULL; |
417 | 0 | } |
418 | | |
419 | 0 | if (ctf_dynhash_insert (one_out, f, NULL) < 0) |
420 | 0 | { |
421 | 0 | ctf_set_errno (fp, err); |
422 | 0 | goto oom_noerrno; |
423 | 0 | } |
424 | | |
425 | 0 | return 0; |
426 | | |
427 | 0 | oom: |
428 | 0 | ctf_set_errno (fp, errno); |
429 | 0 | oom_noerrno: |
430 | 0 | free (f); |
431 | 0 | free (t); |
432 | 0 | return -1; |
433 | 0 | } |
434 | | |
435 | | /* Set a function which is called to transform the names of archive members. |
436 | | This is useful for applying regular transformations to many names, where |
437 | | ctf_link_add_cu_mapping applies arbitrarily irregular changes to single |
438 | | names. The member name changer is applied at ctf_link_write time, so it |
439 | | cannot conflate multiple CUs into one the way ctf_link_add_cu_mapping can. |
440 | | The changer function accepts a name and should return a new |
441 | | dynamically-allocated name, or NULL if the name should be left unchanged. */ |
442 | | void |
443 | | ctf_link_set_memb_name_changer (ctf_dict_t *fp, |
444 | | ctf_link_memb_name_changer_f *changer, |
445 | | void *arg) |
446 | 0 | { |
447 | 0 | fp->ctf_link_memb_name_changer = changer; |
448 | 0 | fp->ctf_link_memb_name_changer_arg = arg; |
449 | 0 | } |
450 | | |
451 | | /* Set a function which is used to filter out unwanted variables from the link. */ |
452 | | int |
453 | | ctf_link_set_variable_filter (ctf_dict_t *fp, ctf_link_variable_filter_f *filter, |
454 | | void *arg) |
455 | 0 | { |
456 | 0 | fp->ctf_link_variable_filter = filter; |
457 | 0 | fp->ctf_link_variable_filter_arg = arg; |
458 | 0 | return 0; |
459 | 0 | } |
460 | | |
461 | | /* Check if we can safely add a variable with the given type to this dict. */ |
462 | | |
463 | | static int |
464 | | check_variable (const char *name, ctf_dict_t *fp, ctf_id_t type, |
465 | | ctf_dvdef_t **out_dvd) |
466 | 0 | { |
467 | 0 | ctf_dvdef_t *dvd; |
468 | |
|
469 | 0 | dvd = ctf_dynhash_lookup (fp->ctf_dvhash, name); |
470 | 0 | *out_dvd = dvd; |
471 | 0 | if (!dvd) |
472 | 0 | return 1; |
473 | | |
474 | 0 | if (dvd->dvd_type != type) |
475 | 0 | { |
476 | | /* Variable here. Wrong type: cannot add. Just skip it, because there is |
477 | | no way to express this in CTF. Don't even warn: this case is too |
478 | | common. (This might be the parent, in which case we'll try adding in |
479 | | the child first, and only then give up.) */ |
480 | 0 | ctf_dprintf ("Inexpressible duplicate variable %s skipped.\n", name); |
481 | 0 | } |
482 | |
|
483 | 0 | return 0; /* Already exists. */ |
484 | 0 | } |
485 | | |
486 | | /* Link one variable named NAME of type TYPE found in IN_FP into FP. */ |
487 | | |
488 | | static int |
489 | | ctf_link_one_variable (ctf_dict_t *fp, ctf_dict_t *in_fp, const char *name, |
490 | | ctf_id_t type, int cu_mapped) |
491 | 0 | { |
492 | 0 | ctf_dict_t *per_cu_out_fp; |
493 | 0 | ctf_id_t dst_type = 0; |
494 | 0 | ctf_dvdef_t *dvd; |
495 | | |
496 | | /* See if this variable is filtered out. */ |
497 | |
|
498 | 0 | if (fp->ctf_link_variable_filter) |
499 | 0 | { |
500 | 0 | void *farg = fp->ctf_link_variable_filter_arg; |
501 | 0 | if (fp->ctf_link_variable_filter (in_fp, name, type, farg)) |
502 | 0 | return 0; |
503 | 0 | } |
504 | | |
505 | | /* If this type is mapped to a type in the parent dict, we want to try to add |
506 | | to that first: if it reports a duplicate, or if the type is in a child |
507 | | already, add straight to the child. */ |
508 | | |
509 | 0 | if ((dst_type = ctf_dedup_type_mapping (fp, in_fp, type)) == CTF_ERR) |
510 | 0 | return -1; /* errno is set for us. */ |
511 | | |
512 | 0 | if (dst_type != 0) |
513 | 0 | { |
514 | 0 | if (!ctf_assert (fp, ctf_type_isparent (fp, dst_type))) |
515 | 0 | return -1; /* errno is set for us. */ |
516 | | |
517 | 0 | if (check_variable (name, fp, dst_type, &dvd)) |
518 | 0 | { |
519 | | /* No variable here: we can add it. */ |
520 | 0 | if (ctf_add_variable (fp, name, dst_type) < 0) |
521 | 0 | return -1; /* errno is set for us. */ |
522 | 0 | return 0; |
523 | 0 | } |
524 | | |
525 | | /* Already present? Nothing to do. */ |
526 | 0 | if (dvd && dvd->dvd_type == dst_type) |
527 | 0 | return 0; |
528 | 0 | } |
529 | | |
530 | | /* Can't add to the parent due to a name clash, or because it references a |
531 | | type only present in the child. Try adding to the child, creating if need |
532 | | be. If we can't do that, skip it. Don't add to a child if we're doing a |
533 | | CU-mapped link, since that has only one output. */ |
534 | | |
535 | 0 | if (cu_mapped) |
536 | 0 | { |
537 | 0 | ctf_dprintf ("Variable %s in input file %s depends on a type %lx hidden " |
538 | 0 | "due to conflicts: skipped.\n", name, |
539 | 0 | ctf_unnamed_cuname (in_fp), type); |
540 | 0 | return 0; |
541 | 0 | } |
542 | | |
543 | 0 | if ((per_cu_out_fp = ctf_create_per_cu (fp, in_fp, NULL)) == NULL) |
544 | 0 | return -1; /* errno is set for us. */ |
545 | | |
546 | | /* If the type was not found, check for it in the child too. */ |
547 | 0 | if (dst_type == 0) |
548 | 0 | { |
549 | 0 | if ((dst_type = ctf_dedup_type_mapping (per_cu_out_fp, |
550 | 0 | in_fp, type)) == CTF_ERR) |
551 | 0 | return -1; /* errno is set for us. */ |
552 | | |
553 | 0 | if (dst_type == 0) |
554 | 0 | { |
555 | 0 | ctf_err_warn (fp, 1, 0, _("type %lx for variable %s in input file %s " |
556 | 0 | "not found: skipped"), type, name, |
557 | 0 | ctf_unnamed_cuname (in_fp)); |
558 | | /* Do not terminate the link: just skip the variable. */ |
559 | 0 | return 0; |
560 | 0 | } |
561 | 0 | } |
562 | | |
563 | 0 | if (check_variable (name, per_cu_out_fp, dst_type, &dvd)) |
564 | 0 | if (ctf_add_variable (per_cu_out_fp, name, dst_type) < 0) |
565 | 0 | return (ctf_set_errno (fp, ctf_errno (per_cu_out_fp))); |
566 | 0 | return 0; |
567 | 0 | } |
568 | | |
569 | | typedef struct link_sort_inputs_cb_arg |
570 | | { |
571 | | int is_cu_mapped; |
572 | | ctf_dict_t *fp; |
573 | | } link_sort_inputs_cb_arg_t; |
574 | | |
575 | | /* Sort the inputs by N (the link order). For CU-mapped links, this is a |
576 | | mapping of input to output name, not a mapping of input name to input |
577 | | ctf_link_input_t: compensate accordingly. */ |
578 | | static int |
579 | | ctf_link_sort_inputs (const ctf_next_hkv_t *one, const ctf_next_hkv_t *two, |
580 | | void *arg) |
581 | 0 | { |
582 | 0 | ctf_link_input_t *input_1; |
583 | 0 | ctf_link_input_t *input_2; |
584 | 0 | link_sort_inputs_cb_arg_t *cu_mapped = (link_sort_inputs_cb_arg_t *) arg; |
585 | |
|
586 | 0 | if (!cu_mapped || !cu_mapped->is_cu_mapped) |
587 | 0 | { |
588 | 0 | input_1 = (ctf_link_input_t *) one->hkv_value; |
589 | 0 | input_2 = (ctf_link_input_t *) two->hkv_value; |
590 | 0 | } |
591 | 0 | else |
592 | 0 | { |
593 | 0 | const char *name_1 = (const char *) one->hkv_key; |
594 | 0 | const char *name_2 = (const char *) two->hkv_key; |
595 | |
|
596 | 0 | input_1 = ctf_dynhash_lookup (cu_mapped->fp->ctf_link_inputs, name_1); |
597 | 0 | input_2 = ctf_dynhash_lookup (cu_mapped->fp->ctf_link_inputs, name_2); |
598 | | |
599 | | /* There is no guarantee that CU-mappings actually have corresponding |
600 | | inputs: the relative ordering in that case is unimportant. */ |
601 | 0 | if (!input_1) |
602 | 0 | return -1; |
603 | 0 | if (!input_2) |
604 | 0 | return 1; |
605 | 0 | } |
606 | | |
607 | 0 | if (input_1->n < input_2->n) |
608 | 0 | return -1; |
609 | 0 | else if (input_1->n > input_2->n) |
610 | 0 | return 1; |
611 | 0 | else |
612 | 0 | return 0; |
613 | 0 | } |
614 | | |
615 | | /* Count the number of input dicts in the ctf_link_inputs, or that subset of the |
616 | | ctf_link_inputs given by CU_NAMES if set. Return the number of input dicts, |
617 | | and optionally the name and ctf_link_input_t of the single input archive if |
618 | | only one exists (no matter how many dicts it contains). */ |
619 | | static ssize_t |
620 | | ctf_link_deduplicating_count_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names, |
621 | | ctf_link_input_t **only_one_input) |
622 | 0 | { |
623 | 0 | ctf_dynhash_t *inputs = fp->ctf_link_inputs; |
624 | 0 | ctf_next_t *i = NULL; |
625 | 0 | void *name, *input; |
626 | 0 | ctf_link_input_t *one_input = NULL; |
627 | 0 | const char *one_name = NULL; |
628 | 0 | ssize_t count = 0, narcs = 0; |
629 | 0 | int err; |
630 | |
|
631 | 0 | if (cu_names) |
632 | 0 | inputs = cu_names; |
633 | |
|
634 | 0 | while ((err = ctf_dynhash_next (inputs, &i, &name, &input)) == 0) |
635 | 0 | { |
636 | 0 | ssize_t one_count; |
637 | |
|
638 | 0 | one_name = (const char *) name; |
639 | | /* If we are processing CU names, get the real input. */ |
640 | 0 | if (cu_names) |
641 | 0 | one_input = ctf_dynhash_lookup (fp->ctf_link_inputs, one_name); |
642 | 0 | else |
643 | 0 | one_input = (ctf_link_input_t *) input; |
644 | |
|
645 | 0 | if (!one_input) |
646 | 0 | continue; |
647 | | |
648 | 0 | one_count = ctf_link_lazy_open (fp, one_input); |
649 | |
|
650 | 0 | if (one_count < 0) |
651 | 0 | { |
652 | 0 | ctf_next_destroy (i); |
653 | 0 | return -1; /* errno is set for us. */ |
654 | 0 | } |
655 | | |
656 | 0 | count += one_count; |
657 | 0 | narcs++; |
658 | 0 | } |
659 | 0 | if (err != ECTF_NEXT_END) |
660 | 0 | { |
661 | 0 | ctf_err_warn (fp, 0, err, _("iteration error counting deduplicating " |
662 | 0 | "CTF link inputs")); |
663 | 0 | return ctf_set_errno (fp, err); |
664 | 0 | } |
665 | | |
666 | 0 | if (!count) |
667 | 0 | return 0; |
668 | | |
669 | 0 | if (narcs == 1) |
670 | 0 | { |
671 | 0 | if (only_one_input) |
672 | 0 | *only_one_input = one_input; |
673 | 0 | } |
674 | 0 | else if (only_one_input) |
675 | 0 | *only_one_input = NULL; |
676 | |
|
677 | 0 | return count; |
678 | 0 | } |
679 | | |
680 | | /* Allocate and populate an inputs array big enough for a given set of inputs: |
681 | | either a specific set of CU names (those from that set found in the |
682 | | ctf_link_inputs), or the entire ctf_link_inputs (if cu_names is not set). |
683 | | The number of inputs (from ctf_link_deduplicating_count_inputs, above) is |
684 | | passed in NINPUTS: an array of uint32_t containing parent pointers |
685 | | (corresponding to those members of the inputs that have parents) is allocated |
686 | | and returned in PARENTS. |
687 | | |
688 | | The inputs are *archives*, not files: the archive can have multiple members |
689 | | if it is the result of a previous incremental link. We want to add every one |
690 | | in turn, including the shared parent. (The dedup machinery knows that a type |
691 | | used by a single dictionary and its parent should not be shared in |
692 | | CTF_LINK_SHARE_DUPLICATED mode.) |
693 | | |
694 | | If no inputs exist that correspond to these CUs, return NULL with the errno |
695 | | set to ECTF_NOCTFDATA. */ |
696 | | static ctf_dict_t ** |
697 | | ctf_link_deduplicating_open_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names, |
698 | | ssize_t ninputs, uint32_t **parents) |
699 | 0 | { |
700 | 0 | ctf_dynhash_t *inputs = fp->ctf_link_inputs; |
701 | 0 | ctf_next_t *i = NULL; |
702 | 0 | void *name, *input; |
703 | 0 | link_sort_inputs_cb_arg_t sort_arg; |
704 | 0 | ctf_dict_t **dedup_inputs = NULL; |
705 | 0 | ctf_dict_t **walk; |
706 | 0 | uint32_t *parents_ = NULL; |
707 | 0 | int err; |
708 | |
|
709 | 0 | if (cu_names) |
710 | 0 | inputs = cu_names; |
711 | |
|
712 | 0 | if ((dedup_inputs = calloc (ninputs, sizeof (ctf_dict_t *))) == NULL) |
713 | 0 | goto oom; |
714 | | |
715 | 0 | if ((parents_ = calloc (ninputs, sizeof (uint32_t))) == NULL) |
716 | 0 | goto oom; |
717 | | |
718 | 0 | walk = dedup_inputs; |
719 | | |
720 | | /* Counting done: push every input into the array, in the order they were |
721 | | passed to ctf_link_add_ctf (and ultimately ld). */ |
722 | |
|
723 | 0 | sort_arg.is_cu_mapped = (cu_names != NULL); |
724 | 0 | sort_arg.fp = fp; |
725 | |
|
726 | 0 | while ((err = ctf_dynhash_next_sorted (inputs, &i, &name, &input, |
727 | 0 | ctf_link_sort_inputs, &sort_arg)) == 0) |
728 | 0 | { |
729 | 0 | const char *one_name = (const char *) name; |
730 | 0 | ctf_link_input_t *one_input; |
731 | 0 | ctf_dict_t *one_fp; |
732 | 0 | ctf_dict_t *parent_fp = NULL; |
733 | 0 | uint32_t parent_i = 0; |
734 | 0 | ctf_next_t *j = NULL; |
735 | | |
736 | | /* If we are processing CU names, get the real input. All the inputs |
737 | | will have been opened, if they contained any CTF at all. */ |
738 | 0 | if (cu_names) |
739 | 0 | one_input = ctf_dynhash_lookup (fp->ctf_link_inputs, one_name); |
740 | 0 | else |
741 | 0 | one_input = (ctf_link_input_t *) input; |
742 | |
|
743 | 0 | if (!one_input || (!one_input->clin_arc && !one_input->clin_fp)) |
744 | 0 | continue; |
745 | | |
746 | | /* Short-circuit: if clin_fp is set, just use it. */ |
747 | 0 | if (one_input->clin_fp) |
748 | 0 | { |
749 | 0 | parents_[walk - dedup_inputs] = walk - dedup_inputs; |
750 | 0 | *walk = one_input->clin_fp; |
751 | 0 | walk++; |
752 | 0 | continue; |
753 | 0 | } |
754 | | |
755 | | /* Get and insert the parent archive (if any), if this archive has |
756 | | multiple members. We assume, as elsewhere, that the parent is named |
757 | | _CTF_SECTION. */ |
758 | | |
759 | 0 | if ((parent_fp = ctf_dict_open (one_input->clin_arc, _CTF_SECTION, |
760 | 0 | &err)) == NULL) |
761 | 0 | { |
762 | 0 | if (err != ECTF_NOMEMBNAM) |
763 | 0 | { |
764 | 0 | ctf_next_destroy (i); |
765 | 0 | ctf_set_errno (fp, err); |
766 | 0 | goto err; |
767 | 0 | } |
768 | 0 | } |
769 | 0 | else |
770 | 0 | { |
771 | 0 | *walk = parent_fp; |
772 | 0 | parent_i = walk - dedup_inputs; |
773 | 0 | walk++; |
774 | 0 | } |
775 | | |
776 | | /* We disregard the input archive name: either it is the parent (which we |
777 | | already have), or we want to put everything into one TU sharing the |
778 | | cuname anyway (if this is a CU-mapped link), or this is the final phase |
779 | | of a relink with CU-mapping off (i.e. ld -r) in which case the cuname |
780 | | is correctly set regardless. */ |
781 | 0 | while ((one_fp = ctf_archive_next (one_input->clin_arc, &j, NULL, |
782 | 0 | 1, &err)) != NULL) |
783 | 0 | { |
784 | 0 | if (one_fp->ctf_flags & LCTF_CHILD) |
785 | 0 | { |
786 | | /* The contents of the parents array for elements not |
787 | | corresponding to children is undefined. If there is no parent |
788 | | (itself a sign of a likely linker bug or corrupt input), we set |
789 | | it to itself. */ |
790 | |
|
791 | 0 | ctf_import (one_fp, parent_fp); |
792 | 0 | if (parent_fp) |
793 | 0 | parents_[walk - dedup_inputs] = parent_i; |
794 | 0 | else |
795 | 0 | parents_[walk - dedup_inputs] = walk - dedup_inputs; |
796 | 0 | } |
797 | 0 | *walk = one_fp; |
798 | 0 | walk++; |
799 | 0 | } |
800 | 0 | if (err != ECTF_NEXT_END) |
801 | 0 | { |
802 | 0 | ctf_next_destroy (i); |
803 | 0 | goto iterr; |
804 | 0 | } |
805 | 0 | } |
806 | 0 | if (err != ECTF_NEXT_END) |
807 | 0 | goto iterr; |
808 | | |
809 | 0 | *parents = parents_; |
810 | |
|
811 | 0 | return dedup_inputs; |
812 | | |
813 | 0 | oom: |
814 | 0 | err = ENOMEM; |
815 | |
|
816 | 0 | iterr: |
817 | 0 | ctf_set_errno (fp, err); |
818 | |
|
819 | 0 | err: |
820 | 0 | free (dedup_inputs); |
821 | 0 | free (parents_); |
822 | 0 | ctf_err_warn (fp, 0, 0, _("error in deduplicating CTF link " |
823 | 0 | "input allocation")); |
824 | 0 | return NULL; |
825 | 0 | } |
826 | | |
827 | | /* Close INPUTS that have already been linked, first the passed array, and then |
828 | | that subset of the ctf_link_inputs archives they came from cited by the |
829 | | CU_NAMES. If CU_NAMES is not specified, close all the ctf_link_inputs in one |
830 | | go, leaving it empty. */ |
831 | | static int |
832 | | ctf_link_deduplicating_close_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names, |
833 | | ctf_dict_t **inputs, ssize_t ninputs) |
834 | 0 | { |
835 | 0 | ctf_next_t *it = NULL; |
836 | 0 | void *name; |
837 | 0 | int err; |
838 | 0 | ssize_t i; |
839 | | |
840 | | /* This is the inverse of ctf_link_deduplicating_open_inputs: so first, close |
841 | | all the individual input dicts, opened by the archive iterator. */ |
842 | 0 | for (i = 0; i < ninputs; i++) |
843 | 0 | ctf_dict_close (inputs[i]); |
844 | | |
845 | | /* Now close the archives they are part of. */ |
846 | 0 | if (cu_names) |
847 | 0 | { |
848 | 0 | while ((err = ctf_dynhash_next (cu_names, &it, &name, NULL)) == 0) |
849 | 0 | { |
850 | | /* Remove the input from the linker inputs, if it exists, which also |
851 | | closes it. */ |
852 | |
|
853 | 0 | ctf_dynhash_remove (fp->ctf_link_inputs, (const char *) name); |
854 | 0 | } |
855 | 0 | if (err != ECTF_NEXT_END) |
856 | 0 | { |
857 | 0 | ctf_set_errno (fp, err); |
858 | 0 | ctf_err_warn (fp, 0, 0, _("iteration error in deduplicating link " |
859 | 0 | "input freeing")); |
860 | 0 | } |
861 | 0 | } |
862 | 0 | else |
863 | 0 | ctf_dynhash_empty (fp->ctf_link_inputs); |
864 | |
|
865 | 0 | return 0; |
866 | 0 | } |
867 | | |
868 | | /* Do a deduplicating link of all variables in the inputs. |
869 | | |
870 | | Also, if we are not omitting the variable section, integrate all symbols from |
871 | | the symtypetabs into the variable section too. (Duplication with the |
872 | | symtypetab section in the output will be eliminated at serialization time.) */ |
873 | | |
874 | | static int |
875 | | ctf_link_deduplicating_variables (ctf_dict_t *fp, ctf_dict_t **inputs, |
876 | | size_t ninputs, int cu_mapped) |
877 | 0 | { |
878 | 0 | size_t i; |
879 | |
|
880 | 0 | for (i = 0; i < ninputs; i++) |
881 | 0 | { |
882 | 0 | ctf_next_t *it = NULL; |
883 | 0 | ctf_id_t type; |
884 | 0 | const char *name; |
885 | | |
886 | | /* First the variables on the inputs. */ |
887 | |
|
888 | 0 | while ((type = ctf_variable_next (inputs[i], &it, &name)) != CTF_ERR) |
889 | 0 | { |
890 | 0 | if (ctf_link_one_variable (fp, inputs[i], name, type, cu_mapped) < 0) |
891 | 0 | { |
892 | 0 | ctf_next_destroy (it); |
893 | 0 | return -1; /* errno is set for us. */ |
894 | 0 | } |
895 | 0 | } |
896 | 0 | if (ctf_errno (inputs[i]) != ECTF_NEXT_END) |
897 | 0 | return ctf_set_errno (fp, ctf_errno (inputs[i])); |
898 | | |
899 | | /* Next the symbols. We integrate data symbols even though the compiler |
900 | | is currently doing the same, to allow the compiler to stop in |
901 | | future. */ |
902 | | |
903 | 0 | while ((type = ctf_symbol_next (inputs[i], &it, &name, 0)) != CTF_ERR) |
904 | 0 | { |
905 | 0 | if (ctf_link_one_variable (fp, inputs[i], name, type, 1) < 0) |
906 | 0 | { |
907 | 0 | ctf_next_destroy (it); |
908 | 0 | return -1; /* errno is set for us. */ |
909 | 0 | } |
910 | 0 | } |
911 | 0 | if (ctf_errno (inputs[i]) != ECTF_NEXT_END) |
912 | 0 | return ctf_set_errno (fp, ctf_errno (inputs[i])); |
913 | | |
914 | | /* Finally the function symbols. */ |
915 | | |
916 | 0 | while ((type = ctf_symbol_next (inputs[i], &it, &name, 1)) != CTF_ERR) |
917 | 0 | { |
918 | 0 | if (ctf_link_one_variable (fp, inputs[i], name, type, 1) < 0) |
919 | 0 | { |
920 | 0 | ctf_next_destroy (it); |
921 | 0 | return -1; /* errno is set for us. */ |
922 | 0 | } |
923 | 0 | } |
924 | 0 | if (ctf_errno (inputs[i]) != ECTF_NEXT_END) |
925 | 0 | return ctf_set_errno (fp, ctf_errno (inputs[i])); |
926 | 0 | } |
927 | 0 | return 0; |
928 | 0 | } |
929 | | |
930 | | /* Check for symbol conflicts during linking. Three possibilities: already |
931 | | exists, conflicting, or nonexistent. We don't have a dvd structure we can |
932 | | use as a flag like check_variable does, so we use a tristate return |
933 | | value instead: -1: conflicting; 1: nonexistent: 0: already exists. */ |
934 | | |
935 | | static int |
936 | | check_sym (ctf_dict_t *fp, const char *name, ctf_id_t type, int functions) |
937 | 0 | { |
938 | 0 | ctf_dynhash_t *thishash = functions ? fp->ctf_funchash : fp->ctf_objthash; |
939 | 0 | ctf_dynhash_t *thathash = functions ? fp->ctf_objthash : fp->ctf_funchash; |
940 | 0 | void *value; |
941 | | |
942 | | /* Wrong type (function when object is wanted, etc). */ |
943 | 0 | if (ctf_dynhash_lookup_kv (thathash, name, NULL, NULL)) |
944 | 0 | return -1; |
945 | | |
946 | | /* Not present at all yet. */ |
947 | 0 | if (!ctf_dynhash_lookup_kv (thishash, name, NULL, &value)) |
948 | 0 | return 1; |
949 | | |
950 | | /* Already present. */ |
951 | 0 | if ((ctf_id_t) (uintptr_t) value == type) |
952 | 0 | return 0; |
953 | | |
954 | | /* Wrong type. */ |
955 | 0 | return -1; |
956 | 0 | } |
957 | | |
958 | | /* Do a deduplicating link of one symtypetab (function info or data object) in |
959 | | one input dict. */ |
960 | | |
961 | | static int |
962 | | ctf_link_deduplicating_one_symtypetab (ctf_dict_t *fp, ctf_dict_t *input, |
963 | | int cu_mapped, int functions) |
964 | 0 | { |
965 | 0 | ctf_next_t *it = NULL; |
966 | 0 | const char *name; |
967 | 0 | ctf_id_t type; |
968 | |
|
969 | 0 | while ((type = ctf_symbol_next (input, &it, &name, functions)) != CTF_ERR) |
970 | 0 | { |
971 | 0 | ctf_id_t dst_type; |
972 | 0 | ctf_dict_t *per_cu_out_fp; |
973 | 0 | int sym; |
974 | | |
975 | | /* Look in the parent first. */ |
976 | |
|
977 | 0 | if ((dst_type = ctf_dedup_type_mapping (fp, input, type)) == CTF_ERR) |
978 | 0 | return -1; /* errno is set for us. */ |
979 | | |
980 | 0 | if (dst_type != 0) |
981 | 0 | { |
982 | 0 | if (!ctf_assert (fp, ctf_type_isparent (fp, dst_type))) |
983 | 0 | return -1; /* errno is set for us. */ |
984 | | |
985 | 0 | sym = check_sym (fp, name, dst_type, functions); |
986 | | |
987 | | /* Already present: next symbol. */ |
988 | 0 | if (sym == 0) |
989 | 0 | continue; |
990 | | /* Not present: add it. */ |
991 | 0 | else if (sym > 0) |
992 | 0 | { |
993 | 0 | if (ctf_add_funcobjt_sym (fp, functions, |
994 | 0 | name, dst_type) < 0) |
995 | 0 | return -1; /* errno is set for us. */ |
996 | 0 | continue; |
997 | 0 | } |
998 | 0 | } |
999 | | |
1000 | | /* Can't add to the parent due to a name clash (most unlikely), or because |
1001 | | it references a type only present in the child. Try adding to the |
1002 | | child, creating if need be. If we can't do that, skip it. Don't add |
1003 | | to a child if we're doing a CU-mapped link, since that has only one |
1004 | | output. */ |
1005 | 0 | if (cu_mapped) |
1006 | 0 | { |
1007 | 0 | ctf_dprintf ("Symbol %s in input file %s depends on a type %lx " |
1008 | 0 | "hidden due to conflicts: skipped.\n", name, |
1009 | 0 | ctf_unnamed_cuname (input), type); |
1010 | 0 | continue; |
1011 | 0 | } |
1012 | | |
1013 | 0 | if ((per_cu_out_fp = ctf_create_per_cu (fp, input, NULL)) == NULL) |
1014 | 0 | return -1; /* errno is set for us. */ |
1015 | | |
1016 | | /* If the type was not found, check for it in the child too. */ |
1017 | 0 | if (dst_type == 0) |
1018 | 0 | { |
1019 | 0 | if ((dst_type = ctf_dedup_type_mapping (per_cu_out_fp, |
1020 | 0 | input, type)) == CTF_ERR) |
1021 | 0 | return -1; /* errno is set for us. */ |
1022 | | |
1023 | 0 | if (dst_type == 0) |
1024 | 0 | { |
1025 | 0 | ctf_err_warn (fp, 1, 0, |
1026 | 0 | _("type %lx for symbol %s in input file %s " |
1027 | 0 | "not found: skipped"), type, name, |
1028 | 0 | ctf_unnamed_cuname (input)); |
1029 | 0 | continue; |
1030 | 0 | } |
1031 | 0 | } |
1032 | | |
1033 | 0 | sym = check_sym (per_cu_out_fp, name, dst_type, functions); |
1034 | | |
1035 | | /* Already present: next symbol. */ |
1036 | 0 | if (sym == 0) |
1037 | 0 | continue; |
1038 | | /* Not present: add it. */ |
1039 | 0 | else if (sym > 0) |
1040 | 0 | { |
1041 | 0 | if (ctf_add_funcobjt_sym (per_cu_out_fp, functions, |
1042 | 0 | name, dst_type) < 0) |
1043 | 0 | return -1; /* errno is set for us. */ |
1044 | 0 | } |
1045 | 0 | else |
1046 | 0 | { |
1047 | | /* Perhaps this should be an assertion failure. */ |
1048 | 0 | ctf_err_warn (fp, 0, ECTF_DUPLICATE, |
1049 | 0 | _("symbol %s in input file %s found conflicting " |
1050 | 0 | "even when trying in per-CU dict."), name, |
1051 | 0 | ctf_unnamed_cuname (input)); |
1052 | 0 | return (ctf_set_errno (fp, ECTF_DUPLICATE)); |
1053 | 0 | } |
1054 | 0 | } |
1055 | 0 | if (ctf_errno (input) != ECTF_NEXT_END) |
1056 | 0 | { |
1057 | 0 | ctf_set_errno (fp, ctf_errno (input)); |
1058 | 0 | ctf_err_warn (fp, 0, 0, functions ? |
1059 | 0 | _("iterating over function symbols") : |
1060 | 0 | _("iterating over data symbols")); |
1061 | 0 | return -1; |
1062 | 0 | } |
1063 | | |
1064 | 0 | return 0; |
1065 | 0 | } |
1066 | | |
1067 | | /* Do a deduplicating link of the function info and data objects |
1068 | | in the inputs. */ |
1069 | | static int |
1070 | | ctf_link_deduplicating_syms (ctf_dict_t *fp, ctf_dict_t **inputs, |
1071 | | size_t ninputs, int cu_mapped) |
1072 | 0 | { |
1073 | 0 | size_t i; |
1074 | |
|
1075 | 0 | for (i = 0; i < ninputs; i++) |
1076 | 0 | { |
1077 | 0 | if (ctf_link_deduplicating_one_symtypetab (fp, inputs[i], |
1078 | 0 | cu_mapped, 0) < 0) |
1079 | 0 | return -1; /* errno is set for us. */ |
1080 | | |
1081 | 0 | if (ctf_link_deduplicating_one_symtypetab (fp, inputs[i], |
1082 | 0 | cu_mapped, 1) < 0) |
1083 | 0 | return -1; /* errno is set for us. */ |
1084 | 0 | } |
1085 | | |
1086 | 0 | return 0; |
1087 | 0 | } |
1088 | | |
1089 | | /* Do the per-CU part of a deduplicating link. */ |
1090 | | static int |
1091 | | ctf_link_deduplicating_per_cu (ctf_dict_t *fp) |
1092 | 0 | { |
1093 | 0 | ctf_next_t *i = NULL; |
1094 | 0 | int err; |
1095 | 0 | void *out_cu; |
1096 | 0 | void *in_cus; |
1097 | | |
1098 | | /* Links with a per-CU mapping in force get a first pass of deduplication, |
1099 | | dedupping the inputs for a given CU mapping into the output for that |
1100 | | mapping. The outputs from this process get fed back into the final pass |
1101 | | that is carried out even for non-CU links. */ |
1102 | |
|
1103 | 0 | while ((err = ctf_dynhash_next (fp->ctf_link_out_cu_mapping, &i, &out_cu, |
1104 | 0 | &in_cus)) == 0) |
1105 | 0 | { |
1106 | 0 | const char *out_name = (const char *) out_cu; |
1107 | 0 | ctf_dynhash_t *in = (ctf_dynhash_t *) in_cus; |
1108 | 0 | ctf_dict_t *out = NULL; |
1109 | 0 | ctf_dict_t **inputs; |
1110 | 0 | ctf_dict_t **outputs; |
1111 | 0 | ctf_archive_t *in_arc; |
1112 | 0 | ssize_t ninputs; |
1113 | 0 | ctf_link_input_t *only_input; |
1114 | 0 | uint32_t noutputs; |
1115 | 0 | uint32_t *parents; |
1116 | |
|
1117 | 0 | if ((ninputs = ctf_link_deduplicating_count_inputs (fp, in, |
1118 | 0 | &only_input)) == -1) |
1119 | 0 | goto err_open_inputs; |
1120 | | |
1121 | | /* CU mapping with no inputs? Skip. */ |
1122 | 0 | if (ninputs == 0) |
1123 | 0 | continue; |
1124 | | |
1125 | 0 | if (labs ((long int) ninputs) > 0xfffffffe) |
1126 | 0 | { |
1127 | 0 | ctf_set_errno (fp, EFBIG); |
1128 | 0 | ctf_err_warn (fp, 0, 0, _("too many inputs in deduplicating " |
1129 | 0 | "link: %li"), (long int) ninputs); |
1130 | 0 | goto err_open_inputs; |
1131 | 0 | } |
1132 | | |
1133 | | /* Short-circuit: a cu-mapped link with only one input archive with |
1134 | | unconflicting contents is a do-nothing, and we can just leave the input |
1135 | | in place: we do have to change the cuname, though, so we unwrap it, |
1136 | | change the cuname, then stuff it back in the linker input again, via |
1137 | | the clin_fp short-circuit member. ctf_link_deduplicating_open_inputs |
1138 | | will spot this member and jam it straight into the next link phase, |
1139 | | ignoring the corresponding archive. */ |
1140 | 0 | if (only_input && ninputs == 1) |
1141 | 0 | { |
1142 | 0 | ctf_next_t *ai = NULL; |
1143 | 0 | int err; |
1144 | | |
1145 | | /* We can abuse an archive iterator to get the only member cheaply, no |
1146 | | matter what its name. */ |
1147 | 0 | only_input->clin_fp = ctf_archive_next (only_input->clin_arc, |
1148 | 0 | &ai, NULL, 0, &err); |
1149 | 0 | if (!only_input->clin_fp) |
1150 | 0 | { |
1151 | 0 | ctf_set_errno (fp, err); |
1152 | 0 | ctf_err_warn (fp, 0, 0, _("cannot open archive %s in " |
1153 | 0 | "CU-mapped CTF link"), |
1154 | 0 | only_input->clin_filename); |
1155 | 0 | goto err_open_inputs; |
1156 | 0 | } |
1157 | 0 | ctf_next_destroy (ai); |
1158 | |
|
1159 | 0 | if (strcmp (only_input->clin_filename, out_name) != 0) |
1160 | 0 | { |
1161 | | /* Renaming. We need to add a new input, then null out the |
1162 | | clin_arc and clin_fp of the old one to stop it being |
1163 | | auto-closed on removal. The new input needs its cuname changed |
1164 | | to out_name, which is doable only because the cuname is a |
1165 | | dynamic property which can be changed even in readonly |
1166 | | dicts. */ |
1167 | |
|
1168 | 0 | ctf_cuname_set (only_input->clin_fp, out_name); |
1169 | 0 | if (ctf_link_add_ctf_internal (fp, only_input->clin_arc, |
1170 | 0 | only_input->clin_fp, |
1171 | 0 | out_name) < 0) |
1172 | 0 | { |
1173 | 0 | ctf_err_warn (fp, 0, 0, _("cannot add intermediate files " |
1174 | 0 | "to link")); |
1175 | 0 | goto err_open_inputs; |
1176 | 0 | } |
1177 | 0 | only_input->clin_arc = NULL; |
1178 | 0 | only_input->clin_fp = NULL; |
1179 | 0 | ctf_dynhash_remove (fp->ctf_link_inputs, |
1180 | 0 | only_input->clin_filename); |
1181 | 0 | } |
1182 | 0 | continue; |
1183 | 0 | } |
1184 | | |
1185 | | /* This is a real CU many-to-one mapping: we must dedup the inputs into |
1186 | | a new output to be used in the final link phase. */ |
1187 | | |
1188 | 0 | if ((inputs = ctf_link_deduplicating_open_inputs (fp, in, ninputs, |
1189 | 0 | &parents)) == NULL) |
1190 | 0 | { |
1191 | 0 | ctf_next_destroy (i); |
1192 | 0 | goto err_open_inputs; |
1193 | 0 | } |
1194 | | |
1195 | 0 | if ((out = ctf_create (&err)) == NULL) |
1196 | 0 | { |
1197 | 0 | ctf_err_warn (fp, 0, err, _("cannot create per-CU CTF archive " |
1198 | 0 | "for %s"), |
1199 | 0 | out_name); |
1200 | 0 | ctf_set_errno (fp, err); |
1201 | 0 | goto err_inputs; |
1202 | 0 | } |
1203 | | |
1204 | | /* The deduplicator is ready for strict enumerator value checking. */ |
1205 | 0 | out->ctf_flags |= LCTF_STRICT_NO_DUP_ENUMERATORS; |
1206 | | |
1207 | | /* Share the atoms table to reduce memory usage. */ |
1208 | 0 | out->ctf_dedup_atoms = fp->ctf_dedup_atoms_alloc; |
1209 | | |
1210 | | /* No ctf_imports at this stage: this per-CU dictionary has no parents. |
1211 | | Parent/child deduplication happens in the link's final pass. However, |
1212 | | the cuname *is* important, as it is propagated into the final |
1213 | | dictionary. */ |
1214 | 0 | ctf_cuname_set (out, out_name); |
1215 | |
|
1216 | 0 | if (ctf_dedup (out, inputs, ninputs, 1) < 0) |
1217 | 0 | { |
1218 | 0 | ctf_set_errno (fp, ctf_errno (out)); |
1219 | 0 | ctf_err_warn (fp, 0, 0, _("CU-mapped deduplication failed for %s"), |
1220 | 0 | out_name); |
1221 | 0 | goto err_inputs; |
1222 | 0 | } |
1223 | | |
1224 | 0 | if ((outputs = ctf_dedup_emit (out, inputs, ninputs, parents, |
1225 | 0 | &noutputs, 1)) == NULL) |
1226 | 0 | { |
1227 | 0 | ctf_set_errno (fp, ctf_errno (out)); |
1228 | 0 | ctf_err_warn (fp, 0, 0, _("CU-mapped deduplicating link type emission " |
1229 | 0 | "failed for %s"), out_name); |
1230 | 0 | goto err_inputs; |
1231 | 0 | } |
1232 | 0 | if (!ctf_assert (fp, noutputs == 1)) |
1233 | 0 | { |
1234 | 0 | size_t j; |
1235 | 0 | for (j = 1; j < noutputs; j++) |
1236 | 0 | ctf_dict_close (outputs[j]); |
1237 | 0 | goto err_inputs_outputs; |
1238 | 0 | } |
1239 | | |
1240 | 0 | if (!(fp->ctf_link_flags & CTF_LINK_OMIT_VARIABLES_SECTION) |
1241 | 0 | && ctf_link_deduplicating_variables (out, inputs, ninputs, 1) < 0) |
1242 | 0 | { |
1243 | 0 | ctf_set_errno (fp, ctf_errno (out)); |
1244 | 0 | ctf_err_warn (fp, 0, 0, _("CU-mapped deduplicating link variable " |
1245 | 0 | "emission failed for %s"), out_name); |
1246 | 0 | goto err_inputs_outputs; |
1247 | 0 | } |
1248 | | |
1249 | 0 | ctf_dedup_fini (out, outputs, noutputs); |
1250 | | |
1251 | | /* For now, we omit symbol section linking for CU-mapped links, until it |
1252 | | is clear how to unify the symbol table across such links. (Perhaps we |
1253 | | should emit an unconditionally indexed symtab, like the compiler |
1254 | | does.) */ |
1255 | |
|
1256 | 0 | if (ctf_link_deduplicating_close_inputs (fp, in, inputs, ninputs) < 0) |
1257 | 0 | { |
1258 | 0 | free (inputs); |
1259 | 0 | free (parents); |
1260 | 0 | goto err_outputs; |
1261 | 0 | } |
1262 | 0 | free (inputs); |
1263 | 0 | free (parents); |
1264 | | |
1265 | | /* Splice any errors or warnings created during this link back into the |
1266 | | dict that the caller knows about. */ |
1267 | 0 | ctf_list_splice (&fp->ctf_errs_warnings, &outputs[0]->ctf_errs_warnings); |
1268 | | |
1269 | | /* This output now becomes an input to the next link phase, with a name |
1270 | | equal to the CU name. We have to wrap it in an archive wrapper |
1271 | | first. */ |
1272 | |
|
1273 | 0 | if ((in_arc = ctf_new_archive_internal (0, 0, NULL, outputs[0], NULL, |
1274 | 0 | NULL, &err)) == NULL) |
1275 | 0 | { |
1276 | 0 | ctf_set_errno (fp, err); |
1277 | 0 | goto err_outputs; |
1278 | 0 | } |
1279 | | |
1280 | 0 | if (ctf_link_add_ctf_internal (fp, in_arc, NULL, |
1281 | 0 | ctf_cuname (outputs[0])) < 0) |
1282 | 0 | { |
1283 | 0 | ctf_err_warn (fp, 0, 0, _("cannot add intermediate files to link")); |
1284 | 0 | goto err_outputs; |
1285 | 0 | } |
1286 | | |
1287 | 0 | ctf_dict_close (out); |
1288 | 0 | free (outputs); |
1289 | 0 | continue; |
1290 | | |
1291 | 0 | err_inputs_outputs: |
1292 | 0 | ctf_list_splice (&fp->ctf_errs_warnings, &outputs[0]->ctf_errs_warnings); |
1293 | 0 | ctf_dict_close (outputs[0]); |
1294 | 0 | free (outputs); |
1295 | 0 | err_inputs: |
1296 | 0 | ctf_link_deduplicating_close_inputs (fp, in, inputs, ninputs); |
1297 | 0 | ctf_dict_close (out); |
1298 | 0 | free (inputs); |
1299 | 0 | free (parents); |
1300 | 0 | err_open_inputs: |
1301 | 0 | ctf_next_destroy (i); |
1302 | 0 | return -1; |
1303 | | |
1304 | 0 | err_outputs: |
1305 | 0 | ctf_list_splice (&fp->ctf_errs_warnings, &outputs[0]->ctf_errs_warnings); |
1306 | 0 | ctf_dict_close (outputs[0]); |
1307 | 0 | free (outputs); |
1308 | 0 | ctf_next_destroy (i); |
1309 | 0 | return -1; /* Errno is set for us. */ |
1310 | 0 | } |
1311 | 0 | if (err != ECTF_NEXT_END) |
1312 | 0 | { |
1313 | 0 | ctf_err_warn (fp, 0, err, _("iteration error in CU-mapped deduplicating " |
1314 | 0 | "link")); |
1315 | 0 | return ctf_set_errno (fp, err); |
1316 | 0 | } |
1317 | | |
1318 | 0 | return 0; |
1319 | 0 | } |
1320 | | |
1321 | | /* Empty all the ctf_link_outputs. */ |
1322 | | static int |
1323 | | ctf_link_empty_outputs (ctf_dict_t *fp) |
1324 | 0 | { |
1325 | 0 | ctf_next_t *i = NULL; |
1326 | 0 | void *v; |
1327 | 0 | int err; |
1328 | |
|
1329 | 0 | ctf_dynhash_empty (fp->ctf_link_outputs); |
1330 | |
|
1331 | 0 | while ((err = ctf_dynhash_next (fp->ctf_link_inputs, &i, NULL, &v)) == 0) |
1332 | 0 | { |
1333 | 0 | ctf_dict_t *in = (ctf_dict_t *) v; |
1334 | 0 | in->ctf_link_in_out = NULL; |
1335 | 0 | } |
1336 | 0 | if (err != ECTF_NEXT_END) |
1337 | 0 | { |
1338 | 0 | fp->ctf_flags &= ~LCTF_LINKING; |
1339 | 0 | ctf_err_warn (fp, 1, err, _("iteration error removing old outputs")); |
1340 | 0 | return ctf_set_errno (fp, err); |
1341 | 0 | } |
1342 | 0 | return 0; |
1343 | 0 | } |
1344 | | |
1345 | | /* Do a deduplicating link using the ctf-dedup machinery. */ |
1346 | | static void |
1347 | | ctf_link_deduplicating (ctf_dict_t *fp) |
1348 | 0 | { |
1349 | 0 | size_t i; |
1350 | 0 | ctf_dict_t **inputs, **outputs = NULL; |
1351 | 0 | ssize_t ninputs; |
1352 | 0 | uint32_t noutputs; |
1353 | 0 | uint32_t *parents; |
1354 | 0 | int cu_phase = 0; |
1355 | |
|
1356 | 0 | if (ctf_dedup_atoms_init (fp) < 0) |
1357 | 0 | { |
1358 | 0 | ctf_err_warn (fp, 0, 0, _("allocating CTF dedup atoms table")); |
1359 | 0 | return; /* Errno is set for us. */ |
1360 | 0 | } |
1361 | | |
1362 | | /* Trigger a CU-mapped link if need be: one pass of dedups squashing inputs into |
1363 | | single child dicts corresponding to each CU mapping, and one pass that |
1364 | | treats those as if they are ordinary inputs and links them together. |
1365 | | |
1366 | | This latter pass does need to act very slightly differently from normal, so we |
1367 | | keep track of the "CU phase", with 0 being a normal link, 1 being the |
1368 | | squash-together phase, and 2 being the final act-as-if-it-were-normal pass. */ |
1369 | | |
1370 | 0 | if (fp->ctf_link_out_cu_mapping) |
1371 | 0 | { |
1372 | 0 | if (ctf_link_deduplicating_per_cu (fp) < 0) |
1373 | 0 | return; /* Errno is set for us. */ |
1374 | 0 | cu_phase = 2; |
1375 | 0 | } |
1376 | | |
1377 | 0 | if ((ninputs = ctf_link_deduplicating_count_inputs (fp, NULL, NULL)) < 0) |
1378 | 0 | return; /* Errno is set for us. */ |
1379 | | |
1380 | 0 | if ((inputs = ctf_link_deduplicating_open_inputs (fp, NULL, ninputs, |
1381 | 0 | &parents)) == NULL) |
1382 | 0 | return; /* Errno is set for us. */ |
1383 | | |
1384 | 0 | if (ninputs == 1 && ctf_cuname (inputs[0]) != NULL) |
1385 | 0 | ctf_cuname_set (fp, ctf_cuname (inputs[0])); |
1386 | |
|
1387 | 0 | if (ctf_dedup (fp, inputs, ninputs, cu_phase) < 0) |
1388 | 0 | { |
1389 | 0 | ctf_err_warn (fp, 0, 0, _("deduplication failed for %s"), |
1390 | 0 | ctf_link_input_name (fp)); |
1391 | 0 | goto err; |
1392 | 0 | } |
1393 | | |
1394 | 0 | if ((outputs = ctf_dedup_emit (fp, inputs, ninputs, parents, &noutputs, |
1395 | 0 | cu_phase)) == NULL) |
1396 | 0 | { |
1397 | 0 | ctf_err_warn (fp, 0, 0, _("deduplicating link type emission failed " |
1398 | 0 | "for %s"), ctf_link_input_name (fp)); |
1399 | 0 | goto err; |
1400 | 0 | } |
1401 | | |
1402 | 0 | if (!ctf_assert (fp, outputs[0] == fp)) |
1403 | 0 | { |
1404 | 0 | for (i = 1; i < noutputs; i++) |
1405 | 0 | ctf_dict_close (outputs[i]); |
1406 | 0 | goto err; |
1407 | 0 | } |
1408 | | |
1409 | 0 | for (i = 0; i < noutputs; i++) |
1410 | 0 | { |
1411 | 0 | char *dynname; |
1412 | | |
1413 | | /* We already have access to this one. Close the duplicate. */ |
1414 | 0 | if (i == 0) |
1415 | 0 | { |
1416 | 0 | ctf_dict_close (outputs[0]); |
1417 | 0 | continue; |
1418 | 0 | } |
1419 | | |
1420 | 0 | if ((dynname = ctf_new_per_cu_name (fp, ctf_cuname (outputs[i]))) == NULL) |
1421 | 0 | goto oom_one_output; |
1422 | | |
1423 | 0 | if (ctf_dynhash_insert (fp->ctf_link_outputs, dynname, outputs[i]) < 0) |
1424 | 0 | goto oom_one_output; |
1425 | | |
1426 | 0 | continue; |
1427 | | |
1428 | 0 | oom_one_output: |
1429 | 0 | ctf_set_errno (fp, ENOMEM); |
1430 | 0 | ctf_err_warn (fp, 0, 0, _("out of memory allocating link outputs")); |
1431 | 0 | free (dynname); |
1432 | |
|
1433 | 0 | for (; i < noutputs; i++) |
1434 | 0 | ctf_dict_close (outputs[i]); |
1435 | 0 | goto err; |
1436 | 0 | } |
1437 | | |
1438 | 0 | if (!(fp->ctf_link_flags & CTF_LINK_OMIT_VARIABLES_SECTION) |
1439 | 0 | && ctf_link_deduplicating_variables (fp, inputs, ninputs, 0) < 0) |
1440 | 0 | { |
1441 | 0 | ctf_err_warn (fp, 0, 0, _("deduplicating link variable emission failed for " |
1442 | 0 | "%s"), ctf_link_input_name (fp)); |
1443 | 0 | goto err_clean_outputs; |
1444 | 0 | } |
1445 | | |
1446 | 0 | if (ctf_link_deduplicating_syms (fp, inputs, ninputs, 0) < 0) |
1447 | 0 | { |
1448 | 0 | ctf_err_warn (fp, 0, 0, _("deduplicating link symbol emission failed for " |
1449 | 0 | "%s"), ctf_link_input_name (fp)); |
1450 | 0 | goto err_clean_outputs; |
1451 | 0 | } |
1452 | | |
1453 | 0 | ctf_dedup_fini (fp, outputs, noutputs); |
1454 | | |
1455 | | /* Now close all the inputs, including per-CU intermediates. */ |
1456 | |
|
1457 | 0 | if (ctf_link_deduplicating_close_inputs (fp, NULL, inputs, ninputs) < 0) |
1458 | 0 | return; /* errno is set for us. */ |
1459 | | |
1460 | 0 | ninputs = 0; /* Prevent double-close. */ |
1461 | 0 | ctf_set_errno (fp, 0); |
1462 | | |
1463 | | /* Fall through. */ |
1464 | |
|
1465 | 0 | err: |
1466 | 0 | for (i = 0; i < (size_t) ninputs; i++) |
1467 | 0 | ctf_dict_close (inputs[i]); |
1468 | 0 | free (inputs); |
1469 | 0 | free (parents); |
1470 | 0 | free (outputs); |
1471 | 0 | return; |
1472 | | |
1473 | 0 | err_clean_outputs: |
1474 | 0 | ctf_link_empty_outputs (fp); |
1475 | 0 | goto err; |
1476 | 0 | } |
1477 | | |
1478 | | /* Merge types and variable sections in all dicts added to the link together. |
1479 | | The result of any previous link is discarded. */ |
1480 | | int |
1481 | | ctf_link (ctf_dict_t *fp, int flags) |
1482 | 0 | { |
1483 | 0 | int err; |
1484 | 0 | int oldflags = fp->ctf_flags; |
1485 | |
|
1486 | 0 | fp->ctf_link_flags = flags; |
1487 | |
|
1488 | 0 | if (fp->ctf_link_inputs == NULL) |
1489 | 0 | return 0; /* Nothing to do. */ |
1490 | | |
1491 | 0 | if (fp->ctf_link_outputs != NULL) |
1492 | 0 | ctf_link_empty_outputs (fp); |
1493 | 0 | else |
1494 | 0 | fp->ctf_link_outputs = ctf_dynhash_create (ctf_hash_string, |
1495 | 0 | ctf_hash_eq_string, free, |
1496 | 0 | (ctf_hash_free_fun) |
1497 | 0 | ctf_dict_close); |
1498 | |
|
1499 | 0 | if (fp->ctf_link_outputs == NULL) |
1500 | 0 | return ctf_set_errno (fp, ENOMEM); |
1501 | | |
1502 | 0 | fp->ctf_flags |= LCTF_LINKING & LCTF_STRICT_NO_DUP_ENUMERATORS; |
1503 | 0 | ctf_link_deduplicating (fp); |
1504 | 0 | fp->ctf_flags = oldflags; |
1505 | |
|
1506 | 0 | if ((ctf_errno (fp) != 0) && (ctf_errno (fp) != ECTF_NOCTFDATA)) |
1507 | 0 | return -1; |
1508 | | |
1509 | | /* Create empty CUs if requested. We do not currently claim that multiple |
1510 | | links in succession with CTF_LINK_EMPTY_CU_MAPPINGS set in some calls and |
1511 | | not set in others will do anything especially sensible. */ |
1512 | | |
1513 | 0 | if (fp->ctf_link_out_cu_mapping && (flags & CTF_LINK_EMPTY_CU_MAPPINGS)) |
1514 | 0 | { |
1515 | 0 | ctf_next_t *i = NULL; |
1516 | 0 | void *k; |
1517 | |
|
1518 | 0 | while ((err = ctf_dynhash_next (fp->ctf_link_out_cu_mapping, &i, &k, |
1519 | 0 | NULL)) == 0) |
1520 | 0 | { |
1521 | 0 | const char *to = (const char *) k; |
1522 | 0 | if (ctf_create_per_cu (fp, NULL, to) == NULL) |
1523 | 0 | { |
1524 | 0 | fp->ctf_flags = oldflags; |
1525 | 0 | ctf_next_destroy (i); |
1526 | 0 | return -1; /* Errno is set for us. */ |
1527 | 0 | } |
1528 | 0 | } |
1529 | 0 | if (err != ECTF_NEXT_END) |
1530 | 0 | { |
1531 | 0 | fp->ctf_flags = oldflags; |
1532 | 0 | ctf_err_warn (fp, 1, err, _("iteration error creating empty CUs")); |
1533 | 0 | return ctf_set_errno (fp, err); |
1534 | 0 | } |
1535 | 0 | } |
1536 | | |
1537 | 0 | return 0; |
1538 | 0 | } |
1539 | | |
1540 | | typedef struct ctf_link_out_string_cb_arg |
1541 | | { |
1542 | | const char *str; |
1543 | | uint32_t offset; |
1544 | | int err; |
1545 | | } ctf_link_out_string_cb_arg_t; |
1546 | | |
1547 | | /* Intern a string in the string table of an output per-CU CTF file. */ |
1548 | | static void |
1549 | | ctf_link_intern_extern_string (void *key _libctf_unused_, void *value, |
1550 | | void *arg_) |
1551 | 0 | { |
1552 | 0 | ctf_dict_t *fp = (ctf_dict_t *) value; |
1553 | 0 | ctf_link_out_string_cb_arg_t *arg = (ctf_link_out_string_cb_arg_t *) arg_; |
1554 | |
|
1555 | 0 | if (!ctf_str_add_external (fp, arg->str, arg->offset)) |
1556 | 0 | arg->err = ENOMEM; |
1557 | 0 | } |
1558 | | |
1559 | | /* Repeatedly call ADD_STRING to acquire strings from the external string table, |
1560 | | adding them to the atoms table for this CU and all subsidiary CUs. |
1561 | | |
1562 | | Must be called on a dict that has not yet been serialized. |
1563 | | |
1564 | | If ctf_link is also called, it must be called first if you want the new CTF |
1565 | | files ctf_link can create to get their strings dedupped against the ELF |
1566 | | strtab properly. */ |
1567 | | int |
1568 | | ctf_link_add_strtab (ctf_dict_t *fp, ctf_link_strtab_string_f *add_string, |
1569 | | void *arg) |
1570 | 0 | { |
1571 | 0 | const char *str; |
1572 | 0 | uint32_t offset; |
1573 | 0 | int err = 0; |
1574 | |
|
1575 | 0 | if (fp->ctf_stypes > 0) |
1576 | 0 | return ctf_set_errno (fp, ECTF_RDONLY); |
1577 | | |
1578 | 0 | while ((str = add_string (&offset, arg)) != NULL) |
1579 | 0 | { |
1580 | 0 | ctf_link_out_string_cb_arg_t iter_arg = { str, offset, 0 }; |
1581 | |
|
1582 | 0 | if (!ctf_str_add_external (fp, str, offset)) |
1583 | 0 | err = ENOMEM; |
1584 | |
|
1585 | 0 | ctf_dynhash_iter (fp->ctf_link_outputs, ctf_link_intern_extern_string, |
1586 | 0 | &iter_arg); |
1587 | 0 | if (iter_arg.err) |
1588 | 0 | err = iter_arg.err; |
1589 | 0 | } |
1590 | |
|
1591 | 0 | if (err) |
1592 | 0 | ctf_set_errno (fp, err); |
1593 | |
|
1594 | 0 | return -err; |
1595 | 0 | } |
1596 | | |
1597 | | /* Inform the ctf-link machinery of a new symbol in the target symbol table |
1598 | | (which must be some symtab that is not usually stripped, and which |
1599 | | is in agreement with ctf_bfdopen_ctfsect). May be called either before or |
1600 | | after ctf_link_add_strtab. As with that function, must be called on a dict which |
1601 | | has not yet been serialized. */ |
1602 | | int |
1603 | | ctf_link_add_linker_symbol (ctf_dict_t *fp, ctf_link_sym_t *sym) |
1604 | 0 | { |
1605 | 0 | ctf_in_flight_dynsym_t *cid; |
1606 | | |
1607 | | /* Cheat a little: if there is already an ENOMEM error code recorded against |
1608 | | this dict, we shouldn't even try to add symbols because there will be no |
1609 | | memory to do so: probably we failed to add some previous symbol. This |
1610 | | makes out-of-memory exits 'sticky' across calls to this function, so the |
1611 | | caller doesn't need to worry about error conditions. */ |
1612 | |
|
1613 | 0 | if (ctf_errno (fp) == ENOMEM) |
1614 | 0 | return -ENOMEM; /* errno is set for us. */ |
1615 | | |
1616 | 0 | if (fp->ctf_stypes > 0) |
1617 | 0 | return ctf_set_errno (fp, ECTF_RDONLY); |
1618 | | |
1619 | 0 | if (ctf_symtab_skippable (sym)) |
1620 | 0 | return 0; |
1621 | | |
1622 | 0 | if (sym->st_type != STT_OBJECT && sym->st_type != STT_FUNC) |
1623 | 0 | return 0; |
1624 | | |
1625 | | /* Add the symbol to the in-flight list. */ |
1626 | | |
1627 | 0 | if ((cid = malloc (sizeof (ctf_in_flight_dynsym_t))) == NULL) |
1628 | 0 | goto oom; |
1629 | | |
1630 | 0 | cid->cid_sym = *sym; |
1631 | 0 | ctf_list_append (&fp->ctf_in_flight_dynsyms, cid); |
1632 | |
|
1633 | 0 | return 0; |
1634 | | |
1635 | 0 | oom: |
1636 | 0 | ctf_dynhash_destroy (fp->ctf_dynsyms); |
1637 | 0 | fp->ctf_dynsyms = NULL; |
1638 | 0 | ctf_set_errno (fp, ENOMEM); |
1639 | 0 | return -ENOMEM; |
1640 | 0 | } |
1641 | | |
1642 | | /* Impose an ordering on symbols. The ordering takes effect immediately, but |
1643 | | since the ordering info does not include type IDs, lookups may return nothing |
1644 | | until such IDs are added by calls to ctf_add_*_sym. Must be called after |
1645 | | ctf_link_add_strtab and ctf_link_add_linker_symbol. */ |
1646 | | int |
1647 | | ctf_link_shuffle_syms (ctf_dict_t *fp) |
1648 | 0 | { |
1649 | 0 | ctf_in_flight_dynsym_t *did, *nid; |
1650 | 0 | ctf_next_t *i = NULL; |
1651 | 0 | int err = ENOMEM; |
1652 | 0 | void *name_, *sym_; |
1653 | |
|
1654 | 0 | if (fp->ctf_stypes > 0) |
1655 | 0 | return ctf_set_errno (fp, ECTF_RDONLY); |
1656 | | |
1657 | 0 | if (!fp->ctf_dynsyms) |
1658 | 0 | { |
1659 | 0 | fp->ctf_dynsyms = ctf_dynhash_create (ctf_hash_string, |
1660 | 0 | ctf_hash_eq_string, |
1661 | 0 | NULL, free); |
1662 | 0 | if (!fp->ctf_dynsyms) |
1663 | 0 | { |
1664 | 0 | ctf_set_errno (fp, ENOMEM); |
1665 | 0 | return -ENOMEM; |
1666 | 0 | } |
1667 | 0 | } |
1668 | | |
1669 | | /* Add all the symbols, excluding only those we already know are prohibited |
1670 | | from appearing in symtypetabs. */ |
1671 | | |
1672 | 0 | for (did = ctf_list_next (&fp->ctf_in_flight_dynsyms); did != NULL; did = nid) |
1673 | 0 | { |
1674 | 0 | ctf_link_sym_t *new_sym; |
1675 | |
|
1676 | 0 | nid = ctf_list_next (did); |
1677 | 0 | ctf_list_delete (&fp->ctf_in_flight_dynsyms, did); |
1678 | | |
1679 | | /* We might get a name or an external strtab offset. The strtab offset is |
1680 | | guaranteed resolvable at this point, so turn it into a string. */ |
1681 | |
|
1682 | 0 | if (did->cid_sym.st_name == NULL) |
1683 | 0 | { |
1684 | 0 | uint32_t off = CTF_SET_STID (did->cid_sym.st_nameidx, CTF_STRTAB_1); |
1685 | |
|
1686 | 0 | did->cid_sym.st_name = ctf_strraw (fp, off); |
1687 | 0 | did->cid_sym.st_nameidx_set = 0; |
1688 | 0 | if (!ctf_assert (fp, did->cid_sym.st_name != NULL)) |
1689 | 0 | return -ECTF_INTERNAL; /* errno is set for us. */ |
1690 | 0 | } |
1691 | | |
1692 | | /* The symbol might have turned out to be nameless, so we have to recheck |
1693 | | for skippability here. */ |
1694 | 0 | if (!ctf_symtab_skippable (&did->cid_sym)) |
1695 | 0 | { |
1696 | 0 | ctf_dprintf ("symbol from linker: %s (%x)\n", did->cid_sym.st_name, |
1697 | 0 | did->cid_sym.st_symidx); |
1698 | |
|
1699 | 0 | if ((new_sym = malloc (sizeof (ctf_link_sym_t))) == NULL) |
1700 | 0 | goto local_oom; |
1701 | | |
1702 | 0 | memcpy (new_sym, &did->cid_sym, sizeof (ctf_link_sym_t)); |
1703 | 0 | if (ctf_dynhash_cinsert (fp->ctf_dynsyms, new_sym->st_name, new_sym) < 0) |
1704 | 0 | goto local_oom; |
1705 | | |
1706 | 0 | if (fp->ctf_dynsymmax < new_sym->st_symidx) |
1707 | 0 | fp->ctf_dynsymmax = new_sym->st_symidx; |
1708 | 0 | } |
1709 | | |
1710 | 0 | free (did); |
1711 | 0 | continue; |
1712 | | |
1713 | 0 | local_oom: |
1714 | 0 | free (did); |
1715 | 0 | free (new_sym); |
1716 | 0 | goto err; |
1717 | 0 | } |
1718 | | |
1719 | | /* If no symbols are reported, unwind what we have done and return. This |
1720 | | makes it a bit easier for the serializer to tell that no symbols have been |
1721 | | reported and that it should look elsewhere for reported symbols. */ |
1722 | 0 | if (!ctf_dynhash_elements (fp->ctf_dynsyms)) |
1723 | 0 | { |
1724 | 0 | ctf_dprintf ("No symbols: not a final link.\n"); |
1725 | 0 | ctf_dynhash_destroy (fp->ctf_dynsyms); |
1726 | 0 | fp->ctf_dynsyms = NULL; |
1727 | 0 | return 0; |
1728 | 0 | } |
1729 | | |
1730 | | /* Construct a mapping from shndx to the symbol info. */ |
1731 | 0 | free (fp->ctf_dynsymidx); |
1732 | 0 | if ((fp->ctf_dynsymidx = calloc (fp->ctf_dynsymmax + 1, |
1733 | 0 | sizeof (ctf_link_sym_t *))) == NULL) |
1734 | 0 | goto err; |
1735 | | |
1736 | 0 | while ((err = ctf_dynhash_next (fp->ctf_dynsyms, &i, &name_, &sym_)) == 0) |
1737 | 0 | { |
1738 | 0 | const char *name = (const char *) name; |
1739 | 0 | ctf_link_sym_t *symp = (ctf_link_sym_t *) sym_; |
1740 | |
|
1741 | 0 | if (!ctf_assert (fp, symp->st_symidx <= fp->ctf_dynsymmax)) |
1742 | 0 | { |
1743 | 0 | ctf_next_destroy (i); |
1744 | 0 | err = ctf_errno (fp); |
1745 | 0 | goto err; |
1746 | 0 | } |
1747 | 0 | fp->ctf_dynsymidx[symp->st_symidx] = symp; |
1748 | 0 | } |
1749 | 0 | if (err != ECTF_NEXT_END) |
1750 | 0 | { |
1751 | 0 | ctf_err_warn (fp, 0, err, _("error iterating over shuffled symbols")); |
1752 | 0 | goto err; |
1753 | 0 | } |
1754 | 0 | return 0; |
1755 | | |
1756 | 0 | err: |
1757 | | /* Leave the in-flight symbols around: they'll be freed at |
1758 | | dict close time regardless. */ |
1759 | 0 | ctf_dynhash_destroy (fp->ctf_dynsyms); |
1760 | 0 | fp->ctf_dynsyms = NULL; |
1761 | 0 | free (fp->ctf_dynsymidx); |
1762 | 0 | fp->ctf_dynsymidx = NULL; |
1763 | 0 | fp->ctf_dynsymmax = 0; |
1764 | 0 | ctf_set_errno (fp, err); |
1765 | 0 | return -err; |
1766 | 0 | } |
1767 | | |
1768 | | typedef struct ctf_name_list_accum_cb_arg |
1769 | | { |
1770 | | char **names; |
1771 | | ctf_dict_t *fp; |
1772 | | ctf_dict_t **files; |
1773 | | size_t i; |
1774 | | char **dynames; |
1775 | | size_t ndynames; |
1776 | | } ctf_name_list_accum_cb_arg_t; |
1777 | | |
1778 | | /* Accumulate the names and a count of the names in the link output hash. */ |
1779 | | static void |
1780 | | ctf_accumulate_archive_names (void *key, void *value, void *arg_) |
1781 | 0 | { |
1782 | 0 | const char *name = (const char *) key; |
1783 | 0 | ctf_dict_t *fp = (ctf_dict_t *) value; |
1784 | 0 | char **names; |
1785 | 0 | ctf_dict_t **files; |
1786 | 0 | ctf_name_list_accum_cb_arg_t *arg = (ctf_name_list_accum_cb_arg_t *) arg_; |
1787 | |
|
1788 | 0 | if ((names = realloc (arg->names, sizeof (char *) * ++(arg->i))) == NULL) |
1789 | 0 | { |
1790 | 0 | (arg->i)--; |
1791 | 0 | ctf_set_errno (arg->fp, ENOMEM); |
1792 | 0 | return; |
1793 | 0 | } |
1794 | | |
1795 | 0 | if ((files = realloc (arg->files, sizeof (ctf_dict_t *) * arg->i)) == NULL) |
1796 | 0 | { |
1797 | 0 | (arg->i)--; |
1798 | 0 | ctf_set_errno (arg->fp, ENOMEM); |
1799 | 0 | return; |
1800 | 0 | } |
1801 | | |
1802 | | /* Allow the caller to get in and modify the name at the last minute. If the |
1803 | | caller *does* modify the name, we have to stash away the new name the |
1804 | | caller returned so we can free it later on. (The original name is the key |
1805 | | of the ctf_link_outputs hash and is freed by the dynhash machinery.) */ |
1806 | | |
1807 | 0 | if (fp->ctf_link_memb_name_changer) |
1808 | 0 | { |
1809 | 0 | char **dynames; |
1810 | 0 | char *dyname; |
1811 | 0 | void *nc_arg = fp->ctf_link_memb_name_changer_arg; |
1812 | |
|
1813 | 0 | dyname = fp->ctf_link_memb_name_changer (fp, name, nc_arg); |
1814 | |
|
1815 | 0 | if (dyname != NULL) |
1816 | 0 | { |
1817 | 0 | if ((dynames = realloc (arg->dynames, |
1818 | 0 | sizeof (char *) * ++(arg->ndynames))) == NULL) |
1819 | 0 | { |
1820 | 0 | (arg->ndynames)--; |
1821 | 0 | ctf_set_errno (arg->fp, ENOMEM); |
1822 | 0 | return; |
1823 | 0 | } |
1824 | 0 | arg->dynames = dynames; |
1825 | 0 | name = (const char *) dyname; |
1826 | 0 | } |
1827 | 0 | } |
1828 | | |
1829 | 0 | arg->names = names; |
1830 | 0 | arg->names[(arg->i) - 1] = (char *) name; |
1831 | 0 | arg->files = files; |
1832 | 0 | arg->files[(arg->i) - 1] = fp; |
1833 | 0 | } |
1834 | | |
1835 | | /* Change the name of the parent CTF section, if the name transformer has got to |
1836 | | it. */ |
1837 | | static void |
1838 | | ctf_change_parent_name (void *key _libctf_unused_, void *value, void *arg) |
1839 | 0 | { |
1840 | 0 | ctf_dict_t *fp = (ctf_dict_t *) value; |
1841 | 0 | const char *name = (const char *) arg; |
1842 | |
|
1843 | 0 | ctf_parent_name_set (fp, name); |
1844 | 0 | } |
1845 | | |
1846 | | /* Warn if we may suffer information loss because the CTF input files are too |
1847 | | old. Usually we provide complete backward compatibility, but compiler |
1848 | | changes etc which never hit a release may have a flag in the header that |
1849 | | simply prevents those changes from being used. */ |
1850 | | static void |
1851 | | ctf_link_warn_outdated_inputs (ctf_dict_t *fp) |
1852 | 0 | { |
1853 | 0 | ctf_next_t *i = NULL; |
1854 | 0 | void *name_; |
1855 | 0 | void *input_; |
1856 | 0 | int err; |
1857 | |
|
1858 | 0 | while ((err = ctf_dynhash_next (fp->ctf_link_inputs, &i, &name_, &input_)) == 0) |
1859 | 0 | { |
1860 | 0 | const char *name = (const char *) name_; |
1861 | 0 | ctf_link_input_t *input = (ctf_link_input_t *) input_; |
1862 | 0 | ctf_next_t *j = NULL; |
1863 | 0 | ctf_dict_t *ifp; |
1864 | 0 | int err; |
1865 | | |
1866 | | /* We only care about CTF archives by this point: lazy-opened archives |
1867 | | have always been opened by this point, and short-circuited entries have |
1868 | | a matching corresponding archive member. Entries with NULL clin_arc can |
1869 | | exist, and constitute old entries renamed via a name changer: the |
1870 | | renamed entries exist elsewhere in the list, so we can just skip |
1871 | | those. */ |
1872 | |
|
1873 | 0 | if (!input->clin_arc) |
1874 | 0 | continue; |
1875 | | |
1876 | | /* All entries in the archive will necessarily contain the same |
1877 | | CTF_F_NEWFUNCINFO flag, so we only need to check the first. We don't |
1878 | | even need to do that if we can't open it for any reason at all: the |
1879 | | link will fail later on regardless, since an input can't be opened. */ |
1880 | | |
1881 | 0 | ifp = ctf_archive_next (input->clin_arc, &j, NULL, 0, &err); |
1882 | 0 | if (!ifp) |
1883 | 0 | continue; |
1884 | 0 | ctf_next_destroy (j); |
1885 | |
|
1886 | 0 | if (!(ifp->ctf_header->cth_flags & CTF_F_NEWFUNCINFO) |
1887 | 0 | && (ifp->ctf_header->cth_varoff - ifp->ctf_header->cth_funcoff) > 0) |
1888 | 0 | ctf_err_warn (fp, 1, 0, _("linker input %s has CTF func info but uses " |
1889 | 0 | "an old, unreleased func info format: " |
1890 | 0 | "this func info section will be dropped."), |
1891 | 0 | name); |
1892 | 0 | } |
1893 | 0 | if (err != ECTF_NEXT_END) |
1894 | 0 | ctf_err_warn (fp, 0, err, _("error checking for outdated inputs")); |
1895 | 0 | } |
1896 | | |
1897 | | /* Write out a CTF archive (if there are per-CU CTF files) or a CTF file |
1898 | | (otherwise) into a new dynamically-allocated string, and return it. |
1899 | | Members with sizes above THRESHOLD are compressed. */ |
1900 | | unsigned char * |
1901 | | ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold) |
1902 | 0 | { |
1903 | 0 | ctf_name_list_accum_cb_arg_t arg; |
1904 | 0 | char **names; |
1905 | 0 | char *transformed_name = NULL; |
1906 | 0 | ctf_dict_t **files; |
1907 | 0 | FILE *f = NULL; |
1908 | 0 | size_t i; |
1909 | 0 | int err; |
1910 | 0 | long fsize; |
1911 | 0 | const char *errloc; |
1912 | 0 | unsigned char *buf = NULL; |
1913 | |
|
1914 | 0 | memset (&arg, 0, sizeof (ctf_name_list_accum_cb_arg_t)); |
1915 | 0 | arg.fp = fp; |
1916 | 0 | fp->ctf_flags |= LCTF_LINKING; |
1917 | |
|
1918 | 0 | ctf_link_warn_outdated_inputs (fp); |
1919 | |
|
1920 | 0 | if (fp->ctf_link_outputs) |
1921 | 0 | { |
1922 | 0 | ctf_dynhash_iter (fp->ctf_link_outputs, ctf_accumulate_archive_names, &arg); |
1923 | 0 | if (ctf_errno (fp) < 0) |
1924 | 0 | { |
1925 | 0 | errloc = "hash creation"; |
1926 | 0 | goto err; |
1927 | 0 | } |
1928 | 0 | } |
1929 | | |
1930 | | /* No extra outputs? Just write a simple ctf_dict_t. */ |
1931 | 0 | if (arg.i == 0) |
1932 | 0 | { |
1933 | 0 | unsigned char *ret = ctf_write_mem (fp, size, threshold); |
1934 | 0 | fp->ctf_flags &= ~LCTF_LINKING; |
1935 | 0 | return ret; |
1936 | 0 | } |
1937 | | |
1938 | | /* Writing an archive. Stick ourselves (the shared repository, parent of all |
1939 | | other archives) on the front of it with the default name. */ |
1940 | 0 | if ((names = realloc (arg.names, sizeof (char *) * (arg.i + 1))) == NULL) |
1941 | 0 | { |
1942 | 0 | errloc = "name reallocation"; |
1943 | 0 | goto err_no; |
1944 | 0 | } |
1945 | 0 | arg.names = names; |
1946 | 0 | memmove (&(arg.names[1]), arg.names, sizeof (char *) * (arg.i)); |
1947 | |
|
1948 | 0 | arg.names[0] = (char *) _CTF_SECTION; |
1949 | 0 | if (fp->ctf_link_memb_name_changer) |
1950 | 0 | { |
1951 | 0 | void *nc_arg = fp->ctf_link_memb_name_changer_arg; |
1952 | |
|
1953 | 0 | transformed_name = fp->ctf_link_memb_name_changer (fp, _CTF_SECTION, |
1954 | 0 | nc_arg); |
1955 | |
|
1956 | 0 | if (transformed_name != NULL) |
1957 | 0 | { |
1958 | 0 | arg.names[0] = transformed_name; |
1959 | 0 | ctf_dynhash_iter (fp->ctf_link_outputs, ctf_change_parent_name, |
1960 | 0 | transformed_name); |
1961 | 0 | } |
1962 | 0 | } |
1963 | | |
1964 | | /* Propagate the link flags to all the dicts in this link. */ |
1965 | 0 | for (i = 0; i < arg.i; i++) |
1966 | 0 | { |
1967 | 0 | arg.files[i]->ctf_link_flags = fp->ctf_link_flags; |
1968 | 0 | arg.files[i]->ctf_flags |= LCTF_LINKING; |
1969 | 0 | } |
1970 | |
|
1971 | 0 | if ((files = realloc (arg.files, |
1972 | 0 | sizeof (struct ctf_dict *) * (arg.i + 1))) == NULL) |
1973 | 0 | { |
1974 | 0 | errloc = "ctf_dict reallocation"; |
1975 | 0 | goto err_no; |
1976 | 0 | } |
1977 | 0 | arg.files = files; |
1978 | 0 | memmove (&(arg.files[1]), arg.files, sizeof (ctf_dict_t *) * (arg.i)); |
1979 | 0 | arg.files[0] = fp; |
1980 | |
|
1981 | 0 | if ((f = tmpfile ()) == NULL) |
1982 | 0 | { |
1983 | 0 | errloc = "tempfile creation"; |
1984 | 0 | goto err_no; |
1985 | 0 | } |
1986 | | |
1987 | 0 | if ((err = ctf_arc_write_fd (fileno (f), arg.files, arg.i + 1, |
1988 | 0 | (const char **) arg.names, |
1989 | 0 | threshold)) < 0) |
1990 | 0 | { |
1991 | 0 | errloc = "archive writing"; |
1992 | 0 | ctf_set_errno (fp, err); |
1993 | 0 | goto err; |
1994 | 0 | } |
1995 | | |
1996 | 0 | if (fseek (f, 0, SEEK_END) < 0) |
1997 | 0 | { |
1998 | 0 | errloc = "seeking to end"; |
1999 | 0 | goto err_no; |
2000 | 0 | } |
2001 | | |
2002 | 0 | if ((fsize = ftell (f)) < 0) |
2003 | 0 | { |
2004 | 0 | errloc = "filesize determination"; |
2005 | 0 | goto err_no; |
2006 | 0 | } |
2007 | | |
2008 | 0 | if (fseek (f, 0, SEEK_SET) < 0) |
2009 | 0 | { |
2010 | 0 | errloc = "filepos resetting"; |
2011 | 0 | goto err_no; |
2012 | 0 | } |
2013 | | |
2014 | 0 | if ((buf = malloc (fsize)) == NULL) |
2015 | 0 | { |
2016 | 0 | errloc = "CTF archive buffer allocation"; |
2017 | 0 | goto err_no; |
2018 | 0 | } |
2019 | | |
2020 | 0 | while (!feof (f) && fread (buf, fsize, 1, f) == 0) |
2021 | 0 | if (ferror (f)) |
2022 | 0 | { |
2023 | 0 | errloc = "reading archive from temporary file"; |
2024 | 0 | goto err_no; |
2025 | 0 | } |
2026 | | |
2027 | | /* Turn off the is-linking flag on all the dicts in this link: if the strict enum |
2028 | | checking flag is off on the parent, turn it off on all the children too. */ |
2029 | 0 | for (i = 0; i < arg.i; i++) |
2030 | 0 | { |
2031 | 0 | arg.files[i]->ctf_flags &= ~LCTF_LINKING; |
2032 | 0 | if (!(fp->ctf_flags & LCTF_STRICT_NO_DUP_ENUMERATORS)) |
2033 | 0 | arg.files[i]->ctf_flags &= ~LCTF_STRICT_NO_DUP_ENUMERATORS; |
2034 | 0 | } |
2035 | |
|
2036 | 0 | *size = fsize; |
2037 | 0 | free (arg.names); |
2038 | 0 | free (arg.files); |
2039 | 0 | free (transformed_name); |
2040 | 0 | if (arg.ndynames) |
2041 | 0 | { |
2042 | 0 | size_t i; |
2043 | 0 | for (i = 0; i < arg.ndynames; i++) |
2044 | 0 | free (arg.dynames[i]); |
2045 | 0 | free (arg.dynames); |
2046 | 0 | } |
2047 | 0 | fclose (f); |
2048 | 0 | return buf; |
2049 | | |
2050 | 0 | err_no: |
2051 | 0 | ctf_set_errno (fp, errno); |
2052 | | |
2053 | | /* Turn off the is-linking flag on all the dicts in this link, as above. */ |
2054 | 0 | for (i = 0; i < arg.i; i++) |
2055 | 0 | { |
2056 | 0 | arg.files[i]->ctf_flags &= ~LCTF_LINKING; |
2057 | 0 | if (!(fp->ctf_flags & LCTF_STRICT_NO_DUP_ENUMERATORS)) |
2058 | 0 | arg.files[i]->ctf_flags &= ~LCTF_STRICT_NO_DUP_ENUMERATORS; |
2059 | 0 | } |
2060 | 0 | err: |
2061 | 0 | free (buf); |
2062 | 0 | if (f) |
2063 | 0 | fclose (f); |
2064 | 0 | free (arg.names); |
2065 | 0 | free (arg.files); |
2066 | 0 | free (transformed_name); |
2067 | 0 | if (arg.ndynames) |
2068 | 0 | { |
2069 | 0 | size_t i; |
2070 | 0 | for (i = 0; i < arg.ndynames; i++) |
2071 | 0 | free (arg.dynames[i]); |
2072 | 0 | free (arg.dynames); |
2073 | 0 | } |
2074 | 0 | ctf_err_warn (fp, 0, 0, _("cannot write archive in link: %s failure"), |
2075 | 0 | errloc); |
2076 | | return NULL; |
2077 | 0 | } |