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