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