17d62b00eSchristos /* CTF linking. 2*6881a400Schristos Copyright (C) 2019-2022 Free Software Foundation, Inc. 37d62b00eSchristos 47d62b00eSchristos This file is part of libctf. 57d62b00eSchristos 67d62b00eSchristos libctf is free software; you can redistribute it and/or modify it under 77d62b00eSchristos the terms of the GNU General Public License as published by the Free 87d62b00eSchristos Software Foundation; either version 3, or (at your option) any later 97d62b00eSchristos version. 107d62b00eSchristos 117d62b00eSchristos This program is distributed in the hope that it will be useful, but 127d62b00eSchristos WITHOUT ANY WARRANTY; without even the implied warranty of 137d62b00eSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 147d62b00eSchristos See the GNU General Public License for more details. 157d62b00eSchristos 167d62b00eSchristos You should have received a copy of the GNU General Public License 177d62b00eSchristos along with this program; see the file COPYING. If not see 187d62b00eSchristos <http://www.gnu.org/licenses/>. */ 197d62b00eSchristos 207d62b00eSchristos #include <ctf-impl.h> 217d62b00eSchristos #include <string.h> 227d62b00eSchristos 237d62b00eSchristos #if defined (PIC) 247d62b00eSchristos #pragma weak ctf_open 257d62b00eSchristos #endif 267d62b00eSchristos 27*6881a400Schristos /* CTF linking consists of adding CTF archives full of content to be merged into 287d62b00eSchristos this one to the current file (which must be writable) by calling 29*6881a400Schristos ctf_link_add_ctf. Once this is done, a call to ctf_link will merge the type 30*6881a400Schristos tables together, generating new CTF files as needed, with this one as a 31*6881a400Schristos parent, to contain types from the inputs which conflict. ctf_link_add_strtab 32*6881a400Schristos takes a callback which provides string/offset pairs to be added to the 33*6881a400Schristos external symbol table and deduplicated from all CTF string tables in the 34*6881a400Schristos output link; ctf_link_shuffle_syms takes a callback which provides symtab 35*6881a400Schristos entries in ascending order, and shuffles the function and data sections to 36*6881a400Schristos match; and ctf_link_write emits a CTF file (if there are no conflicts 37*6881a400Schristos requiring per-compilation-unit sub-CTF files) or CTF archives (otherwise) and 38*6881a400Schristos returns it, suitable for addition in the .ctf section of the output. */ 397d62b00eSchristos 407d62b00eSchristos /* Return the name of the compilation unit this CTF dict or its parent applies 417d62b00eSchristos to, or a non-null string otherwise: prefer the parent. Used in debugging 427d62b00eSchristos output. Sometimes used for outputs too. */ 437d62b00eSchristos const char * 44*6881a400Schristos ctf_link_input_name (ctf_dict_t *fp) 457d62b00eSchristos { 467d62b00eSchristos if (fp->ctf_parent && fp->ctf_parent->ctf_cuname) 477d62b00eSchristos return fp->ctf_parent->ctf_cuname; 487d62b00eSchristos else if (fp->ctf_cuname) 497d62b00eSchristos return fp->ctf_cuname; 507d62b00eSchristos else 517d62b00eSchristos return "(unnamed)"; 527d62b00eSchristos } 537d62b00eSchristos 54*6881a400Schristos /* Return the cuname of a dict, or the string "unnamed-CU" if none. */ 55*6881a400Schristos 56*6881a400Schristos static const char * 57*6881a400Schristos ctf_unnamed_cuname (ctf_dict_t *fp) 58*6881a400Schristos { 59*6881a400Schristos const char *cuname = ctf_cuname (fp); 60*6881a400Schristos 61*6881a400Schristos if (!cuname) 62*6881a400Schristos cuname = "unnamed-CU"; 63*6881a400Schristos 64*6881a400Schristos return cuname; 65*6881a400Schristos } 66*6881a400Schristos 677d62b00eSchristos /* The linker inputs look like this. clin_fp is used for short-circuited 687d62b00eSchristos CU-mapped links that can entirely avoid the first link phase in some 69*6881a400Schristos situations in favour of just passing on the contained ctf_dict_t: it is 70*6881a400Schristos always the sole ctf_dict_t inside the corresponding clin_arc. If set, it 717d62b00eSchristos gets assigned directly to the final link inputs and freed from there, so it 727d62b00eSchristos never gets explicitly freed in the ctf_link_input. */ 737d62b00eSchristos typedef struct ctf_link_input 747d62b00eSchristos { 75*6881a400Schristos char *clin_filename; 767d62b00eSchristos ctf_archive_t *clin_arc; 77*6881a400Schristos ctf_dict_t *clin_fp; 787d62b00eSchristos int n; 797d62b00eSchristos } ctf_link_input_t; 807d62b00eSchristos 817d62b00eSchristos static void 827d62b00eSchristos ctf_link_input_close (void *input) 837d62b00eSchristos { 847d62b00eSchristos ctf_link_input_t *i = (ctf_link_input_t *) input; 857d62b00eSchristos if (i->clin_arc) 867d62b00eSchristos ctf_arc_close (i->clin_arc); 87*6881a400Schristos free (i->clin_filename); 887d62b00eSchristos free (i); 897d62b00eSchristos } 907d62b00eSchristos 917d62b00eSchristos /* Like ctf_link_add_ctf, below, but with no error-checking, so it can be called 927d62b00eSchristos in the middle of an ongoing link. */ 937d62b00eSchristos static int 94*6881a400Schristos ctf_link_add_ctf_internal (ctf_dict_t *fp, ctf_archive_t *ctf, 95*6881a400Schristos ctf_dict_t *fp_input, const char *name) 967d62b00eSchristos { 97*6881a400Schristos int existing = 0; 98*6881a400Schristos ctf_link_input_t *input; 99*6881a400Schristos char *filename, *keyname; 100*6881a400Schristos 101*6881a400Schristos /* Existing: return it, or (if a different dict with the same name 102*6881a400Schristos is already there) make up a new unique name. Always use the actual name 103*6881a400Schristos for the filename, because that needs to be ctf_open()ed. */ 104*6881a400Schristos 105*6881a400Schristos if ((input = ctf_dynhash_lookup (fp->ctf_link_inputs, name)) != NULL) 106*6881a400Schristos { 107*6881a400Schristos if ((fp_input != NULL && (input->clin_fp == fp_input)) 108*6881a400Schristos || (ctf != NULL && (input->clin_arc == ctf))) 109*6881a400Schristos return 0; 110*6881a400Schristos existing = 1; 111*6881a400Schristos } 112*6881a400Schristos 113*6881a400Schristos if ((filename = strdup (name)) == NULL) 114*6881a400Schristos goto oom; 1157d62b00eSchristos 1167d62b00eSchristos if ((input = calloc (1, sizeof (ctf_link_input_t))) == NULL) 117*6881a400Schristos goto oom1; 1187d62b00eSchristos 1197d62b00eSchristos input->clin_arc = ctf; 1207d62b00eSchristos input->clin_fp = fp_input; 121*6881a400Schristos input->clin_filename = filename; 1227d62b00eSchristos input->n = ctf_dynhash_elements (fp->ctf_link_inputs); 1237d62b00eSchristos 124*6881a400Schristos if (existing) 125*6881a400Schristos { 126*6881a400Schristos if (asprintf (&keyname, "%s#%li", name, (long int) 127*6881a400Schristos ctf_dynhash_elements (fp->ctf_link_inputs)) < 0) 128*6881a400Schristos goto oom2; 129*6881a400Schristos } 130*6881a400Schristos else if ((keyname = strdup (name)) == NULL) 131*6881a400Schristos goto oom2; 132*6881a400Schristos 133*6881a400Schristos if (ctf_dynhash_insert (fp->ctf_link_inputs, keyname, input) < 0) 134*6881a400Schristos goto oom3; 1357d62b00eSchristos 1367d62b00eSchristos return 0; 137*6881a400Schristos 138*6881a400Schristos oom3: 139*6881a400Schristos free (keyname); 140*6881a400Schristos oom2: 1417d62b00eSchristos free (input); 142*6881a400Schristos oom1: 143*6881a400Schristos free (filename); 144*6881a400Schristos oom: 1457d62b00eSchristos return ctf_set_errno (fp, ENOMEM); 1467d62b00eSchristos } 1477d62b00eSchristos 1487d62b00eSchristos /* Add a file, memory buffer, or unopened file (by name) to a link. 1497d62b00eSchristos 1507d62b00eSchristos You can call this with: 1517d62b00eSchristos 1527d62b00eSchristos CTF and NAME: link the passed ctf_archive_t, with the given NAME. 1537d62b00eSchristos NAME alone: open NAME as a CTF file when needed. 1547d62b00eSchristos BUF and NAME: open the BUF (of length N) as CTF, with the given NAME. (Not 1557d62b00eSchristos yet implemented.) 1567d62b00eSchristos 1577d62b00eSchristos Passed in CTF args are owned by the dictionary and will be freed by it. 1587d62b00eSchristos The BUF arg is *not* owned by the dictionary, and the user should not free 1597d62b00eSchristos its referent until the link is done. 1607d62b00eSchristos 1617d62b00eSchristos The order of calls to this function influences the order of types in the 1627d62b00eSchristos final link output, but otherwise is not important. 1637d62b00eSchristos 164*6881a400Schristos Repeated additions of the same NAME have no effect; repeated additions of 165*6881a400Schristos different dicts with the same NAME add all the dicts with unique NAMEs 166*6881a400Schristos derived from NAME. 167*6881a400Schristos 1687d62b00eSchristos Private for now, but may in time become public once support for BUF is 1697d62b00eSchristos implemented. */ 1707d62b00eSchristos 1717d62b00eSchristos static int 172*6881a400Schristos ctf_link_add (ctf_dict_t *fp, ctf_archive_t *ctf, const char *name, 1737d62b00eSchristos void *buf _libctf_unused_, size_t n _libctf_unused_) 1747d62b00eSchristos { 1757d62b00eSchristos if (buf) 1767d62b00eSchristos return (ctf_set_errno (fp, ECTF_NOTYET)); 1777d62b00eSchristos 1787d62b00eSchristos if (!((ctf && name && !buf) 1797d62b00eSchristos || (name && !buf && !ctf) 1807d62b00eSchristos || (buf && name && !ctf))) 1817d62b00eSchristos return (ctf_set_errno (fp, EINVAL)); 1827d62b00eSchristos 1837d62b00eSchristos /* We can only lazily open files if libctf.so is in use rather than 1847d62b00eSchristos libctf-nobfd.so. This is a little tricky: in shared libraries, we can use 1857d62b00eSchristos a weak symbol so that -lctf -lctf-nobfd works, but in static libraries we 1867d62b00eSchristos must distinguish between the two libraries explicitly. */ 1877d62b00eSchristos 1887d62b00eSchristos #if defined (PIC) 1897d62b00eSchristos if (!buf && !ctf && name && !ctf_open) 1907d62b00eSchristos return (ctf_set_errno (fp, ECTF_NEEDSBFD)); 1917d62b00eSchristos #elif NOBFD 1927d62b00eSchristos if (!buf && !ctf && name) 1937d62b00eSchristos return (ctf_set_errno (fp, ECTF_NEEDSBFD)); 1947d62b00eSchristos #endif 1957d62b00eSchristos 1967d62b00eSchristos if (fp->ctf_link_outputs) 1977d62b00eSchristos return (ctf_set_errno (fp, ECTF_LINKADDEDLATE)); 1987d62b00eSchristos if (fp->ctf_link_inputs == NULL) 1997d62b00eSchristos fp->ctf_link_inputs = ctf_dynhash_create (ctf_hash_string, 2007d62b00eSchristos ctf_hash_eq_string, free, 2017d62b00eSchristos ctf_link_input_close); 2027d62b00eSchristos 2037d62b00eSchristos if (fp->ctf_link_inputs == NULL) 2047d62b00eSchristos return (ctf_set_errno (fp, ENOMEM)); 2057d62b00eSchristos 2067d62b00eSchristos return ctf_link_add_ctf_internal (fp, ctf, NULL, name); 2077d62b00eSchristos } 2087d62b00eSchristos 2097d62b00eSchristos /* Add an opened CTF archive or unopened file (by name) to a link. 2107d62b00eSchristos If CTF is NULL and NAME is non-null, an unopened file is meant: 2117d62b00eSchristos otherwise, the specified archive is assumed to have the given NAME. 2127d62b00eSchristos 2137d62b00eSchristos Passed in CTF args are owned by the dictionary and will be freed by it. 2147d62b00eSchristos 2157d62b00eSchristos The order of calls to this function influences the order of types in the 2167d62b00eSchristos final link output, but otherwise is not important. */ 2177d62b00eSchristos 2187d62b00eSchristos int 219*6881a400Schristos ctf_link_add_ctf (ctf_dict_t *fp, ctf_archive_t *ctf, const char *name) 2207d62b00eSchristos { 2217d62b00eSchristos return ctf_link_add (fp, ctf, name, NULL, 0); 2227d62b00eSchristos } 2237d62b00eSchristos 224*6881a400Schristos /* Lazily open a CTF archive for linking, if not already open. 2257d62b00eSchristos 226*6881a400Schristos Returns the number of files contained within the opened archive (0 for none), 227*6881a400Schristos or -1 on error, as usual. */ 228*6881a400Schristos static ssize_t 229*6881a400Schristos ctf_link_lazy_open (ctf_dict_t *fp, ctf_link_input_t *input) 2307d62b00eSchristos { 231*6881a400Schristos size_t count; 232*6881a400Schristos int err; 233*6881a400Schristos 234*6881a400Schristos if (input->clin_arc) 235*6881a400Schristos return ctf_archive_count (input->clin_arc); 236*6881a400Schristos 237*6881a400Schristos if (input->clin_fp) 238*6881a400Schristos return 1; 239*6881a400Schristos 240*6881a400Schristos /* See ctf_link_add_ctf. */ 241*6881a400Schristos #if defined (PIC) || !NOBFD 242*6881a400Schristos input->clin_arc = ctf_open (input->clin_filename, NULL, &err); 243*6881a400Schristos #else 244*6881a400Schristos ctf_err_warn (fp, 0, ECTF_NEEDSBFD, _("cannot open %s lazily"), 245*6881a400Schristos input->clin_filename); 246*6881a400Schristos ctf_set_errno (fp, ECTF_NEEDSBFD); 247*6881a400Schristos return -1; 248*6881a400Schristos #endif 249*6881a400Schristos 250*6881a400Schristos /* Having no CTF sections is not an error. We just don't need to do 251*6881a400Schristos anything. */ 252*6881a400Schristos 253*6881a400Schristos if (!input->clin_arc) 254*6881a400Schristos { 255*6881a400Schristos if (err == ECTF_NOCTFDATA) 256*6881a400Schristos return 0; 257*6881a400Schristos 258*6881a400Schristos ctf_err_warn (fp, 0, err, _("opening CTF %s failed"), 259*6881a400Schristos input->clin_filename); 260*6881a400Schristos ctf_set_errno (fp, err); 261*6881a400Schristos return -1; 262*6881a400Schristos } 263*6881a400Schristos 264*6881a400Schristos if ((count = ctf_archive_count (input->clin_arc)) == 0) 265*6881a400Schristos ctf_arc_close (input->clin_arc); 266*6881a400Schristos 267*6881a400Schristos return (ssize_t) count; 268*6881a400Schristos } 269*6881a400Schristos 270*6881a400Schristos /* Find a non-clashing unique name for a per-CU output dict, to prevent distinct 271*6881a400Schristos members corresponding to inputs with identical cunames from overwriting each 272*6881a400Schristos other. The name should be something like NAME. */ 273*6881a400Schristos 274*6881a400Schristos static char * 275*6881a400Schristos ctf_new_per_cu_name (ctf_dict_t *fp, const char *name) 276*6881a400Schristos { 277*6881a400Schristos char *dynname; 278*6881a400Schristos long int i = 0; 279*6881a400Schristos 280*6881a400Schristos if ((dynname = strdup (name)) == NULL) 281*6881a400Schristos return NULL; 282*6881a400Schristos 283*6881a400Schristos while ((ctf_dynhash_lookup (fp->ctf_link_outputs, dynname)) != NULL) 284*6881a400Schristos { 285*6881a400Schristos free (dynname); 286*6881a400Schristos if (asprintf (&dynname, "%s#%li", name, i++) < 0) 287*6881a400Schristos return NULL; 288*6881a400Schristos } 289*6881a400Schristos 290*6881a400Schristos return dynname; 291*6881a400Schristos } 292*6881a400Schristos 293*6881a400Schristos /* Return a per-CU output CTF dictionary suitable for the given INPUT or CU, 294*6881a400Schristos creating and interning it if need be. */ 295*6881a400Schristos 296*6881a400Schristos static ctf_dict_t * 297*6881a400Schristos ctf_create_per_cu (ctf_dict_t *fp, ctf_dict_t *input, const char *cu_name) 298*6881a400Schristos { 299*6881a400Schristos ctf_dict_t *cu_fp; 3007d62b00eSchristos const char *ctf_name = NULL; 3017d62b00eSchristos char *dynname = NULL; 3027d62b00eSchristos 303*6881a400Schristos /* Already has a per-CU mapping? Just return it. */ 304*6881a400Schristos 305*6881a400Schristos if (input && input->ctf_link_in_out) 306*6881a400Schristos return input->ctf_link_in_out; 307*6881a400Schristos 308*6881a400Schristos /* Check the mapping table and translate the per-CU name we use 309*6881a400Schristos accordingly. */ 310*6881a400Schristos 311*6881a400Schristos if (cu_name == NULL) 312*6881a400Schristos cu_name = ctf_unnamed_cuname (input); 3137d62b00eSchristos 3147d62b00eSchristos if (fp->ctf_link_in_cu_mapping) 3157d62b00eSchristos { 316*6881a400Schristos if ((ctf_name = ctf_dynhash_lookup (fp->ctf_link_in_cu_mapping, 317*6881a400Schristos cu_name)) == NULL) 318*6881a400Schristos ctf_name = cu_name; 3197d62b00eSchristos } 3207d62b00eSchristos 3217d62b00eSchristos if (ctf_name == NULL) 322*6881a400Schristos ctf_name = cu_name; 3237d62b00eSchristos 324*6881a400Schristos /* Look up the per-CU dict. If we don't know of one, or it is for 325*6881a400Schristos a different input CU which just happens to have the same name, 326*6881a400Schristos create a new one. */ 327*6881a400Schristos 328*6881a400Schristos if ((cu_fp = ctf_dynhash_lookup (fp->ctf_link_outputs, ctf_name)) == NULL 329*6881a400Schristos || cu_fp->ctf_link_in_out != fp) 3307d62b00eSchristos { 3317d62b00eSchristos int err; 3327d62b00eSchristos 3337d62b00eSchristos if ((cu_fp = ctf_create (&err)) == NULL) 3347d62b00eSchristos { 3357d62b00eSchristos ctf_err_warn (fp, 0, err, _("cannot create per-CU CTF archive for " 336*6881a400Schristos "input CU %s"), cu_name); 3377d62b00eSchristos ctf_set_errno (fp, err); 3387d62b00eSchristos return NULL; 3397d62b00eSchristos } 3407d62b00eSchristos 341*6881a400Schristos ctf_import_unref (cu_fp, fp); 342*6881a400Schristos 343*6881a400Schristos if ((dynname = ctf_new_per_cu_name (fp, ctf_name)) == NULL) 3447d62b00eSchristos goto oom; 3457d62b00eSchristos 346*6881a400Schristos ctf_cuname_set (cu_fp, cu_name); 347*6881a400Schristos 3487d62b00eSchristos ctf_parent_name_set (cu_fp, _CTF_SECTION); 349*6881a400Schristos cu_fp->ctf_link_in_out = fp; 350*6881a400Schristos fp->ctf_link_in_out = cu_fp; 351*6881a400Schristos 352*6881a400Schristos if (ctf_dynhash_insert (fp->ctf_link_outputs, dynname, cu_fp) < 0) 353*6881a400Schristos goto oom; 3547d62b00eSchristos } 3557d62b00eSchristos return cu_fp; 3567d62b00eSchristos 3577d62b00eSchristos oom: 3587d62b00eSchristos free (dynname); 359*6881a400Schristos ctf_dict_close (cu_fp); 3607d62b00eSchristos ctf_set_errno (fp, ENOMEM); 3617d62b00eSchristos return NULL; 3627d62b00eSchristos } 3637d62b00eSchristos 3647d62b00eSchristos /* Add a mapping directing that the CU named FROM should have its 365*6881a400Schristos conflicting/non-duplicate types (depending on link mode) go into a dict 3667d62b00eSchristos named TO. Many FROMs can share a TO. 3677d62b00eSchristos 368*6881a400Schristos We forcibly add a dict named TO in every case, even though it may well 3697d62b00eSchristos wind up empty, because clients that use this facility usually expect to find 370*6881a400Schristos every TO dict present, even if empty, and malfunction otherwise. */ 3717d62b00eSchristos 3727d62b00eSchristos int 373*6881a400Schristos ctf_link_add_cu_mapping (ctf_dict_t *fp, const char *from, const char *to) 3747d62b00eSchristos { 3757d62b00eSchristos int err; 3767d62b00eSchristos char *f = NULL, *t = NULL; 3777d62b00eSchristos ctf_dynhash_t *one_out; 3787d62b00eSchristos 379*6881a400Schristos /* Mappings cannot be set up if per-CU output dicts already exist. */ 380*6881a400Schristos if (fp->ctf_link_outputs && ctf_dynhash_elements (fp->ctf_link_outputs) != 0) 381*6881a400Schristos return (ctf_set_errno (fp, ECTF_LINKADDEDLATE)); 382*6881a400Schristos 3837d62b00eSchristos if (fp->ctf_link_in_cu_mapping == NULL) 3847d62b00eSchristos fp->ctf_link_in_cu_mapping = ctf_dynhash_create (ctf_hash_string, 3857d62b00eSchristos ctf_hash_eq_string, free, 3867d62b00eSchristos free); 3877d62b00eSchristos if (fp->ctf_link_in_cu_mapping == NULL) 3887d62b00eSchristos goto oom; 3897d62b00eSchristos 3907d62b00eSchristos if (fp->ctf_link_out_cu_mapping == NULL) 3917d62b00eSchristos fp->ctf_link_out_cu_mapping = ctf_dynhash_create (ctf_hash_string, 3927d62b00eSchristos ctf_hash_eq_string, free, 3937d62b00eSchristos (ctf_hash_free_fun) 3947d62b00eSchristos ctf_dynhash_destroy); 3957d62b00eSchristos if (fp->ctf_link_out_cu_mapping == NULL) 3967d62b00eSchristos goto oom; 3977d62b00eSchristos 3987d62b00eSchristos f = strdup (from); 3997d62b00eSchristos t = strdup (to); 4007d62b00eSchristos if (!f || !t) 4017d62b00eSchristos goto oom; 4027d62b00eSchristos 4037d62b00eSchristos /* Track both in a list from FROM to TO and in a list from TO to a list of 4047d62b00eSchristos FROM. The former is used to create TUs with the mapped-to name at need: 4057d62b00eSchristos the latter is used in deduplicating links to pull in all input CUs 4067d62b00eSchristos corresponding to a single output CU. */ 4077d62b00eSchristos 4087d62b00eSchristos if ((err = ctf_dynhash_insert (fp->ctf_link_in_cu_mapping, f, t)) < 0) 4097d62b00eSchristos { 4107d62b00eSchristos ctf_set_errno (fp, err); 4117d62b00eSchristos goto oom_noerrno; 4127d62b00eSchristos } 4137d62b00eSchristos 4147d62b00eSchristos /* f and t are now owned by the in_cu_mapping: reallocate them. */ 4157d62b00eSchristos f = strdup (from); 4167d62b00eSchristos t = strdup (to); 4177d62b00eSchristos if (!f || !t) 4187d62b00eSchristos goto oom; 4197d62b00eSchristos 4207d62b00eSchristos if ((one_out = ctf_dynhash_lookup (fp->ctf_link_out_cu_mapping, t)) == NULL) 4217d62b00eSchristos { 4227d62b00eSchristos if ((one_out = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string, 4237d62b00eSchristos free, NULL)) == NULL) 4247d62b00eSchristos goto oom; 4257d62b00eSchristos if ((err = ctf_dynhash_insert (fp->ctf_link_out_cu_mapping, 4267d62b00eSchristos t, one_out)) < 0) 4277d62b00eSchristos { 4287d62b00eSchristos ctf_dynhash_destroy (one_out); 4297d62b00eSchristos ctf_set_errno (fp, err); 4307d62b00eSchristos goto oom_noerrno; 4317d62b00eSchristos } 4327d62b00eSchristos } 4337d62b00eSchristos else 434*6881a400Schristos { 4357d62b00eSchristos free (t); 436*6881a400Schristos t = NULL; 437*6881a400Schristos } 4387d62b00eSchristos 4397d62b00eSchristos if (ctf_dynhash_insert (one_out, f, NULL) < 0) 4407d62b00eSchristos { 4417d62b00eSchristos ctf_set_errno (fp, err); 4427d62b00eSchristos goto oom_noerrno; 4437d62b00eSchristos } 4447d62b00eSchristos 4457d62b00eSchristos return 0; 4467d62b00eSchristos 4477d62b00eSchristos oom: 4487d62b00eSchristos ctf_set_errno (fp, errno); 4497d62b00eSchristos oom_noerrno: 4507d62b00eSchristos free (f); 4517d62b00eSchristos free (t); 4527d62b00eSchristos return -1; 4537d62b00eSchristos } 4547d62b00eSchristos 4557d62b00eSchristos /* Set a function which is called to transform the names of archive members. 4567d62b00eSchristos This is useful for applying regular transformations to many names, where 4577d62b00eSchristos ctf_link_add_cu_mapping applies arbitrarily irregular changes to single 4587d62b00eSchristos names. The member name changer is applied at ctf_link_write time, so it 4597d62b00eSchristos cannot conflate multiple CUs into one the way ctf_link_add_cu_mapping can. 4607d62b00eSchristos The changer function accepts a name and should return a new 4617d62b00eSchristos dynamically-allocated name, or NULL if the name should be left unchanged. */ 4627d62b00eSchristos void 463*6881a400Schristos ctf_link_set_memb_name_changer (ctf_dict_t *fp, 4647d62b00eSchristos ctf_link_memb_name_changer_f *changer, 4657d62b00eSchristos void *arg) 4667d62b00eSchristos { 4677d62b00eSchristos fp->ctf_link_memb_name_changer = changer; 4687d62b00eSchristos fp->ctf_link_memb_name_changer_arg = arg; 4697d62b00eSchristos } 4707d62b00eSchristos 4717d62b00eSchristos /* Set a function which is used to filter out unwanted variables from the link. */ 4727d62b00eSchristos int 473*6881a400Schristos ctf_link_set_variable_filter (ctf_dict_t *fp, ctf_link_variable_filter_f *filter, 4747d62b00eSchristos void *arg) 4757d62b00eSchristos { 4767d62b00eSchristos fp->ctf_link_variable_filter = filter; 4777d62b00eSchristos fp->ctf_link_variable_filter_arg = arg; 4787d62b00eSchristos return 0; 4797d62b00eSchristos } 4807d62b00eSchristos 481*6881a400Schristos /* Check if we can safely add a variable with the given type to this dict. */ 4827d62b00eSchristos 4837d62b00eSchristos static int 484*6881a400Schristos check_variable (const char *name, ctf_dict_t *fp, ctf_id_t type, 4857d62b00eSchristos ctf_dvdef_t **out_dvd) 4867d62b00eSchristos { 4877d62b00eSchristos ctf_dvdef_t *dvd; 4887d62b00eSchristos 4897d62b00eSchristos dvd = ctf_dynhash_lookup (fp->ctf_dvhash, name); 4907d62b00eSchristos *out_dvd = dvd; 4917d62b00eSchristos if (!dvd) 4927d62b00eSchristos return 1; 4937d62b00eSchristos 4947d62b00eSchristos if (dvd->dvd_type != type) 4957d62b00eSchristos { 4967d62b00eSchristos /* Variable here. Wrong type: cannot add. Just skip it, because there is 4977d62b00eSchristos no way to express this in CTF. Don't even warn: this case is too 4987d62b00eSchristos common. (This might be the parent, in which case we'll try adding in 4997d62b00eSchristos the child first, and only then give up.) */ 5007d62b00eSchristos ctf_dprintf ("Inexpressible duplicate variable %s skipped.\n", name); 5017d62b00eSchristos } 5027d62b00eSchristos 5037d62b00eSchristos return 0; /* Already exists. */ 5047d62b00eSchristos } 5057d62b00eSchristos 506*6881a400Schristos /* Link one variable named NAME of type TYPE found in IN_FP into FP. */ 5077d62b00eSchristos 5087d62b00eSchristos static int 509*6881a400Schristos ctf_link_one_variable (ctf_dict_t *fp, ctf_dict_t *in_fp, const char *name, 510*6881a400Schristos ctf_id_t type, int cu_mapped) 5117d62b00eSchristos { 512*6881a400Schristos ctf_dict_t *per_cu_out_fp; 5137d62b00eSchristos ctf_id_t dst_type = 0; 5147d62b00eSchristos ctf_dvdef_t *dvd; 5157d62b00eSchristos 5167d62b00eSchristos /* See if this variable is filtered out. */ 5177d62b00eSchristos 518*6881a400Schristos if (fp->ctf_link_variable_filter) 5197d62b00eSchristos { 520*6881a400Schristos void *farg = fp->ctf_link_variable_filter_arg; 521*6881a400Schristos if (fp->ctf_link_variable_filter (in_fp, name, type, farg)) 5227d62b00eSchristos return 0; 5237d62b00eSchristos } 5247d62b00eSchristos 525*6881a400Schristos /* If this type is mapped to a type in the parent dict, we want to try to add 526*6881a400Schristos to that first: if it reports a duplicate, or if the type is in a child 527*6881a400Schristos already, add straight to the child. */ 5287d62b00eSchristos 529*6881a400Schristos if ((dst_type = ctf_dedup_type_mapping (fp, in_fp, type)) == CTF_ERR) 530*6881a400Schristos return -1; /* errno is set for us. */ 5317d62b00eSchristos 5327d62b00eSchristos if (dst_type != 0) 5337d62b00eSchristos { 534*6881a400Schristos if (!ctf_assert (fp, ctf_type_isparent (fp, dst_type))) 535*6881a400Schristos return -1; /* errno is set for us. */ 536*6881a400Schristos 537*6881a400Schristos if (check_variable (name, fp, dst_type, &dvd)) 5387d62b00eSchristos { 5397d62b00eSchristos /* No variable here: we can add it. */ 540*6881a400Schristos if (ctf_add_variable (fp, name, dst_type) < 0) 541*6881a400Schristos return -1; /* errno is set for us. */ 5427d62b00eSchristos return 0; 5437d62b00eSchristos } 5447d62b00eSchristos 5457d62b00eSchristos /* Already present? Nothing to do. */ 5467d62b00eSchristos if (dvd && dvd->dvd_type == dst_type) 5477d62b00eSchristos return 0; 5487d62b00eSchristos } 5497d62b00eSchristos 5507d62b00eSchristos /* Can't add to the parent due to a name clash, or because it references a 5517d62b00eSchristos type only present in the child. Try adding to the child, creating if need 5527d62b00eSchristos be. If we can't do that, skip it. Don't add to a child if we're doing a 5537d62b00eSchristos CU-mapped link, since that has only one output. */ 5547d62b00eSchristos 555*6881a400Schristos if (cu_mapped) 5567d62b00eSchristos { 5577d62b00eSchristos ctf_dprintf ("Variable %s in input file %s depends on a type %lx hidden " 558*6881a400Schristos "due to conflicts: skipped.\n", name, 559*6881a400Schristos ctf_unnamed_cuname (in_fp), type); 5607d62b00eSchristos return 0; 5617d62b00eSchristos } 5627d62b00eSchristos 563*6881a400Schristos if ((per_cu_out_fp = ctf_create_per_cu (fp, in_fp, NULL)) == NULL) 564*6881a400Schristos return -1; /* errno is set for us. */ 5657d62b00eSchristos 5667d62b00eSchristos /* If the type was not found, check for it in the child too. */ 5677d62b00eSchristos if (dst_type == 0) 5687d62b00eSchristos { 569*6881a400Schristos if ((dst_type = ctf_dedup_type_mapping (per_cu_out_fp, 570*6881a400Schristos in_fp, type)) == CTF_ERR) 571*6881a400Schristos return -1; /* errno is set for us. */ 5727d62b00eSchristos 5737d62b00eSchristos if (dst_type == 0) 5747d62b00eSchristos { 575*6881a400Schristos ctf_err_warn (fp, 1, 0, _("type %lx for variable %s in input file %s " 5767d62b00eSchristos "not found: skipped"), type, name, 577*6881a400Schristos ctf_unnamed_cuname (in_fp)); 5787d62b00eSchristos /* Do not terminate the link: just skip the variable. */ 5797d62b00eSchristos return 0; 5807d62b00eSchristos } 5817d62b00eSchristos } 5827d62b00eSchristos 5837d62b00eSchristos if (check_variable (name, per_cu_out_fp, dst_type, &dvd)) 5847d62b00eSchristos if (ctf_add_variable (per_cu_out_fp, name, dst_type) < 0) 585*6881a400Schristos return (ctf_set_errno (fp, ctf_errno (per_cu_out_fp))); 5867d62b00eSchristos return 0; 5877d62b00eSchristos } 5887d62b00eSchristos 5897d62b00eSchristos typedef struct link_sort_inputs_cb_arg 5907d62b00eSchristos { 5917d62b00eSchristos int is_cu_mapped; 592*6881a400Schristos ctf_dict_t *fp; 5937d62b00eSchristos } link_sort_inputs_cb_arg_t; 5947d62b00eSchristos 5957d62b00eSchristos /* Sort the inputs by N (the link order). For CU-mapped links, this is a 5967d62b00eSchristos mapping of input to output name, not a mapping of input name to input 5977d62b00eSchristos ctf_link_input_t: compensate accordingly. */ 5987d62b00eSchristos static int 5997d62b00eSchristos ctf_link_sort_inputs (const ctf_next_hkv_t *one, const ctf_next_hkv_t *two, 6007d62b00eSchristos void *arg) 6017d62b00eSchristos { 6027d62b00eSchristos ctf_link_input_t *input_1; 6037d62b00eSchristos ctf_link_input_t *input_2; 6047d62b00eSchristos link_sort_inputs_cb_arg_t *cu_mapped = (link_sort_inputs_cb_arg_t *) arg; 6057d62b00eSchristos 6067d62b00eSchristos if (!cu_mapped || !cu_mapped->is_cu_mapped) 6077d62b00eSchristos { 6087d62b00eSchristos input_1 = (ctf_link_input_t *) one->hkv_value; 6097d62b00eSchristos input_2 = (ctf_link_input_t *) two->hkv_value; 6107d62b00eSchristos } 6117d62b00eSchristos else 6127d62b00eSchristos { 6137d62b00eSchristos const char *name_1 = (const char *) one->hkv_key; 6147d62b00eSchristos const char *name_2 = (const char *) two->hkv_key; 6157d62b00eSchristos 6167d62b00eSchristos input_1 = ctf_dynhash_lookup (cu_mapped->fp->ctf_link_inputs, name_1); 6177d62b00eSchristos input_2 = ctf_dynhash_lookup (cu_mapped->fp->ctf_link_inputs, name_2); 6187d62b00eSchristos 6197d62b00eSchristos /* There is no guarantee that CU-mappings actually have corresponding 6207d62b00eSchristos inputs: the relative ordering in that case is unimportant. */ 6217d62b00eSchristos if (!input_1) 6227d62b00eSchristos return -1; 6237d62b00eSchristos if (!input_2) 6247d62b00eSchristos return 1; 6257d62b00eSchristos } 6267d62b00eSchristos 6277d62b00eSchristos if (input_1->n < input_2->n) 6287d62b00eSchristos return -1; 6297d62b00eSchristos else if (input_1->n > input_2->n) 6307d62b00eSchristos return 1; 6317d62b00eSchristos else 6327d62b00eSchristos return 0; 6337d62b00eSchristos } 6347d62b00eSchristos 6357d62b00eSchristos /* Count the number of input dicts in the ctf_link_inputs, or that subset of the 6367d62b00eSchristos ctf_link_inputs given by CU_NAMES if set. Return the number of input dicts, 6377d62b00eSchristos and optionally the name and ctf_link_input_t of the single input archive if 6387d62b00eSchristos only one exists (no matter how many dicts it contains). */ 6397d62b00eSchristos static ssize_t 640*6881a400Schristos ctf_link_deduplicating_count_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names, 6417d62b00eSchristos ctf_link_input_t **only_one_input) 6427d62b00eSchristos { 6437d62b00eSchristos ctf_dynhash_t *inputs = fp->ctf_link_inputs; 6447d62b00eSchristos ctf_next_t *i = NULL; 6457d62b00eSchristos void *name, *input; 6467d62b00eSchristos ctf_link_input_t *one_input = NULL; 6477d62b00eSchristos const char *one_name = NULL; 6487d62b00eSchristos ssize_t count = 0, narcs = 0; 6497d62b00eSchristos int err; 6507d62b00eSchristos 6517d62b00eSchristos if (cu_names) 6527d62b00eSchristos inputs = cu_names; 6537d62b00eSchristos 6547d62b00eSchristos while ((err = ctf_dynhash_next (inputs, &i, &name, &input)) == 0) 6557d62b00eSchristos { 6567d62b00eSchristos ssize_t one_count; 6577d62b00eSchristos 6587d62b00eSchristos one_name = (const char *) name; 6597d62b00eSchristos /* If we are processing CU names, get the real input. */ 6607d62b00eSchristos if (cu_names) 6617d62b00eSchristos one_input = ctf_dynhash_lookup (fp->ctf_link_inputs, one_name); 6627d62b00eSchristos else 6637d62b00eSchristos one_input = (ctf_link_input_t *) input; 6647d62b00eSchristos 6657d62b00eSchristos if (!one_input) 6667d62b00eSchristos continue; 6677d62b00eSchristos 6687d62b00eSchristos one_count = ctf_link_lazy_open (fp, one_input); 6697d62b00eSchristos 6707d62b00eSchristos if (one_count < 0) 6717d62b00eSchristos { 6727d62b00eSchristos ctf_next_destroy (i); 6737d62b00eSchristos return -1; /* errno is set for us. */ 6747d62b00eSchristos } 6757d62b00eSchristos 6767d62b00eSchristos count += one_count; 6777d62b00eSchristos narcs++; 6787d62b00eSchristos } 6797d62b00eSchristos if (err != ECTF_NEXT_END) 6807d62b00eSchristos { 6817d62b00eSchristos ctf_err_warn (fp, 0, err, _("iteration error counting deduplicating " 6827d62b00eSchristos "CTF link inputs")); 6837d62b00eSchristos ctf_set_errno (fp, err); 6847d62b00eSchristos return -1; 6857d62b00eSchristos } 6867d62b00eSchristos 6877d62b00eSchristos if (!count) 6887d62b00eSchristos return 0; 6897d62b00eSchristos 6907d62b00eSchristos if (narcs == 1) 6917d62b00eSchristos { 6927d62b00eSchristos if (only_one_input) 6937d62b00eSchristos *only_one_input = one_input; 6947d62b00eSchristos } 6957d62b00eSchristos else if (only_one_input) 6967d62b00eSchristos *only_one_input = NULL; 6977d62b00eSchristos 6987d62b00eSchristos return count; 6997d62b00eSchristos } 7007d62b00eSchristos 7017d62b00eSchristos /* Allocate and populate an inputs array big enough for a given set of inputs: 7027d62b00eSchristos either a specific set of CU names (those from that set found in the 7037d62b00eSchristos ctf_link_inputs), or the entire ctf_link_inputs (if cu_names is not set). 7047d62b00eSchristos The number of inputs (from ctf_link_deduplicating_count_inputs, above) is 7057d62b00eSchristos passed in NINPUTS: an array of uint32_t containing parent pointers 7067d62b00eSchristos (corresponding to those members of the inputs that have parents) is allocated 7077d62b00eSchristos and returned in PARENTS. 7087d62b00eSchristos 7097d62b00eSchristos The inputs are *archives*, not files: the archive can have multiple members 7107d62b00eSchristos if it is the result of a previous incremental link. We want to add every one 7117d62b00eSchristos in turn, including the shared parent. (The dedup machinery knows that a type 7127d62b00eSchristos used by a single dictionary and its parent should not be shared in 7137d62b00eSchristos CTF_LINK_SHARE_DUPLICATED mode.) 7147d62b00eSchristos 7157d62b00eSchristos If no inputs exist that correspond to these CUs, return NULL with the errno 7167d62b00eSchristos set to ECTF_NOCTFDATA. */ 717*6881a400Schristos static ctf_dict_t ** 718*6881a400Schristos ctf_link_deduplicating_open_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names, 7197d62b00eSchristos ssize_t ninputs, uint32_t **parents) 7207d62b00eSchristos { 7217d62b00eSchristos ctf_dynhash_t *inputs = fp->ctf_link_inputs; 7227d62b00eSchristos ctf_next_t *i = NULL; 7237d62b00eSchristos void *name, *input; 7247d62b00eSchristos link_sort_inputs_cb_arg_t sort_arg; 725*6881a400Schristos ctf_dict_t **dedup_inputs = NULL; 726*6881a400Schristos ctf_dict_t **walk; 7277d62b00eSchristos uint32_t *parents_ = NULL; 7287d62b00eSchristos int err; 7297d62b00eSchristos 7307d62b00eSchristos if (cu_names) 7317d62b00eSchristos inputs = cu_names; 7327d62b00eSchristos 733*6881a400Schristos if ((dedup_inputs = calloc (ninputs, sizeof (ctf_dict_t *))) == NULL) 7347d62b00eSchristos goto oom; 7357d62b00eSchristos 7367d62b00eSchristos if ((parents_ = calloc (ninputs, sizeof (uint32_t))) == NULL) 7377d62b00eSchristos goto oom; 7387d62b00eSchristos 7397d62b00eSchristos walk = dedup_inputs; 7407d62b00eSchristos 7417d62b00eSchristos /* Counting done: push every input into the array, in the order they were 7427d62b00eSchristos passed to ctf_link_add_ctf (and ultimately ld). */ 7437d62b00eSchristos 7447d62b00eSchristos sort_arg.is_cu_mapped = (cu_names != NULL); 7457d62b00eSchristos sort_arg.fp = fp; 7467d62b00eSchristos 7477d62b00eSchristos while ((err = ctf_dynhash_next_sorted (inputs, &i, &name, &input, 7487d62b00eSchristos ctf_link_sort_inputs, &sort_arg)) == 0) 7497d62b00eSchristos { 7507d62b00eSchristos const char *one_name = (const char *) name; 7517d62b00eSchristos ctf_link_input_t *one_input; 752*6881a400Schristos ctf_dict_t *one_fp; 753*6881a400Schristos ctf_dict_t *parent_fp = NULL; 7547d62b00eSchristos uint32_t parent_i; 7557d62b00eSchristos ctf_next_t *j = NULL; 7567d62b00eSchristos 7577d62b00eSchristos /* If we are processing CU names, get the real input. All the inputs 7587d62b00eSchristos will have been opened, if they contained any CTF at all. */ 7597d62b00eSchristos if (cu_names) 7607d62b00eSchristos one_input = ctf_dynhash_lookup (fp->ctf_link_inputs, one_name); 7617d62b00eSchristos else 7627d62b00eSchristos one_input = (ctf_link_input_t *) input; 7637d62b00eSchristos 7647d62b00eSchristos if (!one_input || (!one_input->clin_arc && !one_input->clin_fp)) 7657d62b00eSchristos continue; 7667d62b00eSchristos 7677d62b00eSchristos /* Short-circuit: if clin_fp is set, just use it. */ 7687d62b00eSchristos if (one_input->clin_fp) 7697d62b00eSchristos { 7707d62b00eSchristos parents_[walk - dedup_inputs] = walk - dedup_inputs; 7717d62b00eSchristos *walk = one_input->clin_fp; 7727d62b00eSchristos walk++; 7737d62b00eSchristos continue; 7747d62b00eSchristos } 7757d62b00eSchristos 7767d62b00eSchristos /* Get and insert the parent archive (if any), if this archive has 7777d62b00eSchristos multiple members. We assume, as elsewhere, that the parent is named 7787d62b00eSchristos _CTF_SECTION. */ 7797d62b00eSchristos 780*6881a400Schristos if ((parent_fp = ctf_dict_open (one_input->clin_arc, _CTF_SECTION, 781*6881a400Schristos &err)) == NULL) 7827d62b00eSchristos { 7837d62b00eSchristos if (err != ECTF_NOMEMBNAM) 7847d62b00eSchristos { 7857d62b00eSchristos ctf_next_destroy (i); 7867d62b00eSchristos ctf_set_errno (fp, err); 7877d62b00eSchristos goto err; 7887d62b00eSchristos } 7897d62b00eSchristos } 7907d62b00eSchristos else 7917d62b00eSchristos { 7927d62b00eSchristos *walk = parent_fp; 7937d62b00eSchristos parent_i = walk - dedup_inputs; 7947d62b00eSchristos walk++; 7957d62b00eSchristos } 7967d62b00eSchristos 7977d62b00eSchristos /* We disregard the input archive name: either it is the parent (which we 7987d62b00eSchristos already have), or we want to put everything into one TU sharing the 7997d62b00eSchristos cuname anyway (if this is a CU-mapped link), or this is the final phase 8007d62b00eSchristos of a relink with CU-mapping off (i.e. ld -r) in which case the cuname 8017d62b00eSchristos is correctly set regardless. */ 8027d62b00eSchristos while ((one_fp = ctf_archive_next (one_input->clin_arc, &j, NULL, 8037d62b00eSchristos 1, &err)) != NULL) 8047d62b00eSchristos { 8057d62b00eSchristos if (one_fp->ctf_flags & LCTF_CHILD) 8067d62b00eSchristos { 8077d62b00eSchristos /* The contents of the parents array for elements not 8087d62b00eSchristos corresponding to children is undefined. If there is no parent 8097d62b00eSchristos (itself a sign of a likely linker bug or corrupt input), we set 8107d62b00eSchristos it to itself. */ 8117d62b00eSchristos 8127d62b00eSchristos ctf_import (one_fp, parent_fp); 8137d62b00eSchristos if (parent_fp) 8147d62b00eSchristos parents_[walk - dedup_inputs] = parent_i; 8157d62b00eSchristos else 8167d62b00eSchristos parents_[walk - dedup_inputs] = walk - dedup_inputs; 8177d62b00eSchristos } 8187d62b00eSchristos *walk = one_fp; 8197d62b00eSchristos walk++; 8207d62b00eSchristos } 8217d62b00eSchristos if (err != ECTF_NEXT_END) 8227d62b00eSchristos { 8237d62b00eSchristos ctf_next_destroy (i); 8247d62b00eSchristos goto iterr; 8257d62b00eSchristos } 8267d62b00eSchristos } 8277d62b00eSchristos if (err != ECTF_NEXT_END) 8287d62b00eSchristos goto iterr; 8297d62b00eSchristos 8307d62b00eSchristos *parents = parents_; 8317d62b00eSchristos 8327d62b00eSchristos return dedup_inputs; 8337d62b00eSchristos 8347d62b00eSchristos oom: 8357d62b00eSchristos err = ENOMEM; 8367d62b00eSchristos 8377d62b00eSchristos iterr: 8387d62b00eSchristos ctf_set_errno (fp, err); 8397d62b00eSchristos 8407d62b00eSchristos err: 8417d62b00eSchristos free (dedup_inputs); 8427d62b00eSchristos free (parents_); 8437d62b00eSchristos ctf_err_warn (fp, 0, 0, _("error in deduplicating CTF link " 8447d62b00eSchristos "input allocation")); 8457d62b00eSchristos return NULL; 8467d62b00eSchristos } 8477d62b00eSchristos 8487d62b00eSchristos /* Close INPUTS that have already been linked, first the passed array, and then 8497d62b00eSchristos that subset of the ctf_link_inputs archives they came from cited by the 8507d62b00eSchristos CU_NAMES. If CU_NAMES is not specified, close all the ctf_link_inputs in one 8517d62b00eSchristos go, leaving it empty. */ 8527d62b00eSchristos static int 853*6881a400Schristos ctf_link_deduplicating_close_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names, 854*6881a400Schristos ctf_dict_t **inputs, ssize_t ninputs) 8557d62b00eSchristos { 8567d62b00eSchristos ctf_next_t *it = NULL; 8577d62b00eSchristos void *name; 8587d62b00eSchristos int err; 8597d62b00eSchristos ssize_t i; 8607d62b00eSchristos 8617d62b00eSchristos /* This is the inverse of ctf_link_deduplicating_open_inputs: so first, close 8627d62b00eSchristos all the individual input dicts, opened by the archive iterator. */ 8637d62b00eSchristos for (i = 0; i < ninputs; i++) 864*6881a400Schristos ctf_dict_close (inputs[i]); 8657d62b00eSchristos 8667d62b00eSchristos /* Now close the archives they are part of. */ 8677d62b00eSchristos if (cu_names) 8687d62b00eSchristos { 8697d62b00eSchristos while ((err = ctf_dynhash_next (cu_names, &it, &name, NULL)) == 0) 8707d62b00eSchristos { 8717d62b00eSchristos /* Remove the input from the linker inputs, if it exists, which also 8727d62b00eSchristos closes it. */ 8737d62b00eSchristos 8747d62b00eSchristos ctf_dynhash_remove (fp->ctf_link_inputs, (const char *) name); 8757d62b00eSchristos } 8767d62b00eSchristos if (err != ECTF_NEXT_END) 8777d62b00eSchristos { 8787d62b00eSchristos ctf_err_warn (fp, 0, err, _("iteration error in deduplicating link " 8797d62b00eSchristos "input freeing")); 8807d62b00eSchristos ctf_set_errno (fp, err); 8817d62b00eSchristos } 8827d62b00eSchristos } 8837d62b00eSchristos else 8847d62b00eSchristos ctf_dynhash_empty (fp->ctf_link_inputs); 8857d62b00eSchristos 8867d62b00eSchristos return 0; 8877d62b00eSchristos } 8887d62b00eSchristos 889*6881a400Schristos /* Do a deduplicating link of all variables in the inputs. 890*6881a400Schristos 891*6881a400Schristos Also, if we are not omitting the variable section, integrate all symbols from 892*6881a400Schristos the symtypetabs into the variable section too. (Duplication with the 893*6881a400Schristos symtypetab section in the output will be eliminated at serialization time.) */ 894*6881a400Schristos 8957d62b00eSchristos static int 896*6881a400Schristos ctf_link_deduplicating_variables (ctf_dict_t *fp, ctf_dict_t **inputs, 8977d62b00eSchristos size_t ninputs, int cu_mapped) 8987d62b00eSchristos { 8997d62b00eSchristos size_t i; 9007d62b00eSchristos 9017d62b00eSchristos for (i = 0; i < ninputs; i++) 9027d62b00eSchristos { 903*6881a400Schristos ctf_next_t *it = NULL; 904*6881a400Schristos ctf_id_t type; 905*6881a400Schristos const char *name; 9067d62b00eSchristos 907*6881a400Schristos /* First the variables on the inputs. */ 908*6881a400Schristos 909*6881a400Schristos while ((type = ctf_variable_next (inputs[i], &it, &name)) != CTF_ERR) 910*6881a400Schristos { 911*6881a400Schristos if (ctf_link_one_variable (fp, inputs[i], name, type, cu_mapped) < 0) 912*6881a400Schristos { 913*6881a400Schristos ctf_next_destroy (it); 914*6881a400Schristos return -1; /* errno is set for us. */ 9157d62b00eSchristos } 916*6881a400Schristos } 917*6881a400Schristos if (ctf_errno (inputs[i]) != ECTF_NEXT_END) 918*6881a400Schristos return ctf_set_errno (fp, ctf_errno (inputs[i])); 919*6881a400Schristos 920*6881a400Schristos /* Next the symbols. We integrate data symbols even though the compiler 921*6881a400Schristos is currently doing the same, to allow the compiler to stop in 922*6881a400Schristos future. */ 923*6881a400Schristos 924*6881a400Schristos while ((type = ctf_symbol_next (inputs[i], &it, &name, 0)) != CTF_ERR) 925*6881a400Schristos { 926*6881a400Schristos if (ctf_link_one_variable (fp, inputs[i], name, type, 1) < 0) 927*6881a400Schristos { 928*6881a400Schristos ctf_next_destroy (it); 929*6881a400Schristos return -1; /* errno is set for us. */ 930*6881a400Schristos } 931*6881a400Schristos } 932*6881a400Schristos if (ctf_errno (inputs[i]) != ECTF_NEXT_END) 933*6881a400Schristos return ctf_set_errno (fp, ctf_errno (inputs[i])); 934*6881a400Schristos 935*6881a400Schristos /* Finally the function symbols. */ 936*6881a400Schristos 937*6881a400Schristos while ((type = ctf_symbol_next (inputs[i], &it, &name, 1)) != CTF_ERR) 938*6881a400Schristos { 939*6881a400Schristos if (ctf_link_one_variable (fp, inputs[i], name, type, 1) < 0) 940*6881a400Schristos { 941*6881a400Schristos ctf_next_destroy (it); 942*6881a400Schristos return -1; /* errno is set for us. */ 943*6881a400Schristos } 944*6881a400Schristos } 945*6881a400Schristos if (ctf_errno (inputs[i]) != ECTF_NEXT_END) 946*6881a400Schristos return ctf_set_errno (fp, ctf_errno (inputs[i])); 947*6881a400Schristos } 948*6881a400Schristos return 0; 949*6881a400Schristos } 950*6881a400Schristos 951*6881a400Schristos /* Check for symbol conflicts during linking. Three possibilities: already 952*6881a400Schristos exists, conflicting, or nonexistent. We don't have a dvd structure we can 953*6881a400Schristos use as a flag like check_variable does, so we use a tristate return 954*6881a400Schristos value instead: -1: conflicting; 1: nonexistent: 0: already exists. */ 955*6881a400Schristos 956*6881a400Schristos static int 957*6881a400Schristos check_sym (ctf_dict_t *fp, const char *name, ctf_id_t type, int functions) 958*6881a400Schristos { 959*6881a400Schristos ctf_dynhash_t *thishash = functions ? fp->ctf_funchash : fp->ctf_objthash; 960*6881a400Schristos ctf_dynhash_t *thathash = functions ? fp->ctf_objthash : fp->ctf_funchash; 961*6881a400Schristos void *value; 962*6881a400Schristos 963*6881a400Schristos /* Wrong type (function when object is wanted, etc). */ 964*6881a400Schristos if (ctf_dynhash_lookup_kv (thathash, name, NULL, NULL)) 965*6881a400Schristos return -1; 966*6881a400Schristos 967*6881a400Schristos /* Not present at all yet. */ 968*6881a400Schristos if (!ctf_dynhash_lookup_kv (thishash, name, NULL, &value)) 969*6881a400Schristos return 1; 970*6881a400Schristos 971*6881a400Schristos /* Already present. */ 972*6881a400Schristos if ((ctf_id_t) (uintptr_t) value == type) 973*6881a400Schristos return 0; 974*6881a400Schristos 975*6881a400Schristos /* Wrong type. */ 976*6881a400Schristos return -1; 977*6881a400Schristos } 978*6881a400Schristos 979*6881a400Schristos /* Do a deduplicating link of one symtypetab (function info or data object) in 980*6881a400Schristos one input dict. */ 981*6881a400Schristos 982*6881a400Schristos static int 983*6881a400Schristos ctf_link_deduplicating_one_symtypetab (ctf_dict_t *fp, ctf_dict_t *input, 984*6881a400Schristos int cu_mapped, int functions) 985*6881a400Schristos { 986*6881a400Schristos ctf_next_t *it = NULL; 987*6881a400Schristos const char *name; 988*6881a400Schristos ctf_id_t type; 989*6881a400Schristos 990*6881a400Schristos while ((type = ctf_symbol_next (input, &it, &name, functions)) != CTF_ERR) 991*6881a400Schristos { 992*6881a400Schristos ctf_id_t dst_type; 993*6881a400Schristos ctf_dict_t *per_cu_out_fp; 994*6881a400Schristos int sym; 995*6881a400Schristos 996*6881a400Schristos /* Look in the parent first. */ 997*6881a400Schristos 998*6881a400Schristos if ((dst_type = ctf_dedup_type_mapping (fp, input, type)) == CTF_ERR) 999*6881a400Schristos return -1; /* errno is set for us. */ 1000*6881a400Schristos 1001*6881a400Schristos if (dst_type != 0) 1002*6881a400Schristos { 1003*6881a400Schristos if (!ctf_assert (fp, ctf_type_isparent (fp, dst_type))) 1004*6881a400Schristos return -1; /* errno is set for us. */ 1005*6881a400Schristos 1006*6881a400Schristos sym = check_sym (fp, name, dst_type, functions); 1007*6881a400Schristos 1008*6881a400Schristos /* Already present: next symbol. */ 1009*6881a400Schristos if (sym == 0) 1010*6881a400Schristos continue; 1011*6881a400Schristos /* Not present: add it. */ 1012*6881a400Schristos else if (sym > 0) 1013*6881a400Schristos { 1014*6881a400Schristos if (ctf_add_funcobjt_sym (fp, functions, 1015*6881a400Schristos name, dst_type) < 0) 1016*6881a400Schristos return -1; /* errno is set for us. */ 1017*6881a400Schristos continue; 1018*6881a400Schristos } 1019*6881a400Schristos } 1020*6881a400Schristos 1021*6881a400Schristos /* Can't add to the parent due to a name clash (most unlikely), or because 1022*6881a400Schristos it references a type only present in the child. Try adding to the 1023*6881a400Schristos child, creating if need be. If we can't do that, skip it. Don't add 1024*6881a400Schristos to a child if we're doing a CU-mapped link, since that has only one 1025*6881a400Schristos output. */ 1026*6881a400Schristos if (cu_mapped) 1027*6881a400Schristos { 1028*6881a400Schristos ctf_dprintf ("Symbol %s in input file %s depends on a type %lx " 1029*6881a400Schristos "hidden due to conflicts: skipped.\n", name, 1030*6881a400Schristos ctf_unnamed_cuname (input), type); 1031*6881a400Schristos continue; 1032*6881a400Schristos } 1033*6881a400Schristos 1034*6881a400Schristos if ((per_cu_out_fp = ctf_create_per_cu (fp, input, NULL)) == NULL) 1035*6881a400Schristos return -1; /* errno is set for us. */ 1036*6881a400Schristos 1037*6881a400Schristos /* If the type was not found, check for it in the child too. */ 1038*6881a400Schristos if (dst_type == 0) 1039*6881a400Schristos { 1040*6881a400Schristos if ((dst_type = ctf_dedup_type_mapping (per_cu_out_fp, 1041*6881a400Schristos input, type)) == CTF_ERR) 1042*6881a400Schristos return -1; /* errno is set for us. */ 1043*6881a400Schristos 1044*6881a400Schristos if (dst_type == 0) 1045*6881a400Schristos { 1046*6881a400Schristos ctf_err_warn (fp, 1, 0, 1047*6881a400Schristos _("type %lx for symbol %s in input file %s " 1048*6881a400Schristos "not found: skipped"), type, name, 1049*6881a400Schristos ctf_unnamed_cuname (input)); 1050*6881a400Schristos continue; 1051*6881a400Schristos } 1052*6881a400Schristos } 1053*6881a400Schristos 1054*6881a400Schristos sym = check_sym (per_cu_out_fp, name, dst_type, functions); 1055*6881a400Schristos 1056*6881a400Schristos /* Already present: next symbol. */ 1057*6881a400Schristos if (sym == 0) 1058*6881a400Schristos continue; 1059*6881a400Schristos /* Not present: add it. */ 1060*6881a400Schristos else if (sym > 0) 1061*6881a400Schristos { 1062*6881a400Schristos if (ctf_add_funcobjt_sym (per_cu_out_fp, functions, 1063*6881a400Schristos name, dst_type) < 0) 1064*6881a400Schristos return -1; /* errno is set for us. */ 1065*6881a400Schristos } 1066*6881a400Schristos else 1067*6881a400Schristos { 1068*6881a400Schristos /* Perhaps this should be an assertion failure. */ 1069*6881a400Schristos ctf_err_warn (fp, 0, ECTF_DUPLICATE, 1070*6881a400Schristos _("symbol %s in input file %s found conflicting " 1071*6881a400Schristos "even when trying in per-CU dict."), name, 1072*6881a400Schristos ctf_unnamed_cuname (input)); 1073*6881a400Schristos return (ctf_set_errno (fp, ECTF_DUPLICATE)); 1074*6881a400Schristos } 1075*6881a400Schristos } 1076*6881a400Schristos if (ctf_errno (input) != ECTF_NEXT_END) 1077*6881a400Schristos { 1078*6881a400Schristos ctf_set_errno (fp, ctf_errno (input)); 1079*6881a400Schristos ctf_err_warn (fp, 0, ctf_errno (input), 1080*6881a400Schristos functions ? _("iterating over function symbols") : 1081*6881a400Schristos _("iterating over data symbols")); 1082*6881a400Schristos return -1; 1083*6881a400Schristos } 1084*6881a400Schristos 1085*6881a400Schristos return 0; 1086*6881a400Schristos } 1087*6881a400Schristos 1088*6881a400Schristos /* Do a deduplicating link of the function info and data objects 1089*6881a400Schristos in the inputs. */ 1090*6881a400Schristos static int 1091*6881a400Schristos ctf_link_deduplicating_syms (ctf_dict_t *fp, ctf_dict_t **inputs, 1092*6881a400Schristos size_t ninputs, int cu_mapped) 1093*6881a400Schristos { 1094*6881a400Schristos size_t i; 1095*6881a400Schristos 1096*6881a400Schristos for (i = 0; i < ninputs; i++) 1097*6881a400Schristos { 1098*6881a400Schristos if (ctf_link_deduplicating_one_symtypetab (fp, inputs[i], 1099*6881a400Schristos cu_mapped, 0) < 0) 1100*6881a400Schristos return -1; /* errno is set for us. */ 1101*6881a400Schristos 1102*6881a400Schristos if (ctf_link_deduplicating_one_symtypetab (fp, inputs[i], 1103*6881a400Schristos cu_mapped, 1) < 0) 1104*6881a400Schristos return -1; /* errno is set for us. */ 1105*6881a400Schristos } 1106*6881a400Schristos 11077d62b00eSchristos return 0; 11087d62b00eSchristos } 11097d62b00eSchristos 11107d62b00eSchristos /* Do the per-CU part of a deduplicating link. */ 11117d62b00eSchristos static int 1112*6881a400Schristos ctf_link_deduplicating_per_cu (ctf_dict_t *fp) 11137d62b00eSchristos { 11147d62b00eSchristos ctf_next_t *i = NULL; 11157d62b00eSchristos int err; 11167d62b00eSchristos void *out_cu; 11177d62b00eSchristos void *in_cus; 11187d62b00eSchristos 11197d62b00eSchristos /* Links with a per-CU mapping in force get a first pass of deduplication, 11207d62b00eSchristos dedupping the inputs for a given CU mapping into the output for that 11217d62b00eSchristos mapping. The outputs from this process get fed back into the final pass 11227d62b00eSchristos that is carried out even for non-CU links. */ 11237d62b00eSchristos 11247d62b00eSchristos while ((err = ctf_dynhash_next (fp->ctf_link_out_cu_mapping, &i, &out_cu, 11257d62b00eSchristos &in_cus)) == 0) 11267d62b00eSchristos { 11277d62b00eSchristos const char *out_name = (const char *) out_cu; 11287d62b00eSchristos ctf_dynhash_t *in = (ctf_dynhash_t *) in_cus; 1129*6881a400Schristos ctf_dict_t *out = NULL; 1130*6881a400Schristos ctf_dict_t **inputs; 1131*6881a400Schristos ctf_dict_t **outputs; 11327d62b00eSchristos ctf_archive_t *in_arc; 11337d62b00eSchristos ssize_t ninputs; 11347d62b00eSchristos ctf_link_input_t *only_input; 11357d62b00eSchristos uint32_t noutputs; 11367d62b00eSchristos uint32_t *parents; 11377d62b00eSchristos 11387d62b00eSchristos if ((ninputs = ctf_link_deduplicating_count_inputs (fp, in, 11397d62b00eSchristos &only_input)) == -1) 11407d62b00eSchristos goto err_open_inputs; 11417d62b00eSchristos 11427d62b00eSchristos /* CU mapping with no inputs? Skip. */ 11437d62b00eSchristos if (ninputs == 0) 11447d62b00eSchristos continue; 11457d62b00eSchristos 11467d62b00eSchristos if (labs ((long int) ninputs) > 0xfffffffe) 11477d62b00eSchristos { 11487d62b00eSchristos ctf_err_warn (fp, 0, EFBIG, _("too many inputs in deduplicating " 11497d62b00eSchristos "link: %li"), (long int) ninputs); 11507d62b00eSchristos ctf_set_errno (fp, EFBIG); 11517d62b00eSchristos goto err_open_inputs; 11527d62b00eSchristos } 11537d62b00eSchristos 11547d62b00eSchristos /* Short-circuit: a cu-mapped link with only one input archive with 11557d62b00eSchristos unconflicting contents is a do-nothing, and we can just leave the input 11567d62b00eSchristos in place: we do have to change the cuname, though, so we unwrap it, 11577d62b00eSchristos change the cuname, then stuff it back in the linker input again, via 11587d62b00eSchristos the clin_fp short-circuit member. ctf_link_deduplicating_open_inputs 11597d62b00eSchristos will spot this member and jam it straight into the next link phase, 11607d62b00eSchristos ignoring the corresponding archive. */ 11617d62b00eSchristos if (only_input && ninputs == 1) 11627d62b00eSchristos { 11637d62b00eSchristos ctf_next_t *ai = NULL; 11647d62b00eSchristos int err; 11657d62b00eSchristos 11667d62b00eSchristos /* We can abuse an archive iterator to get the only member cheaply, no 11677d62b00eSchristos matter what its name. */ 11687d62b00eSchristos only_input->clin_fp = ctf_archive_next (only_input->clin_arc, 11697d62b00eSchristos &ai, NULL, 0, &err); 11707d62b00eSchristos if (!only_input->clin_fp) 11717d62b00eSchristos { 11727d62b00eSchristos ctf_err_warn (fp, 0, err, _("cannot open archive %s in " 11737d62b00eSchristos "CU-mapped CTF link"), 11747d62b00eSchristos only_input->clin_filename); 11757d62b00eSchristos ctf_set_errno (fp, err); 11767d62b00eSchristos goto err_open_inputs; 11777d62b00eSchristos } 11787d62b00eSchristos ctf_next_destroy (ai); 11797d62b00eSchristos 11807d62b00eSchristos if (strcmp (only_input->clin_filename, out_name) != 0) 11817d62b00eSchristos { 11827d62b00eSchristos /* Renaming. We need to add a new input, then null out the 11837d62b00eSchristos clin_arc and clin_fp of the old one to stop it being 11847d62b00eSchristos auto-closed on removal. The new input needs its cuname changed 11857d62b00eSchristos to out_name, which is doable only because the cuname is a 11867d62b00eSchristos dynamic property which can be changed even in readonly 11877d62b00eSchristos dicts. */ 11887d62b00eSchristos 11897d62b00eSchristos ctf_cuname_set (only_input->clin_fp, out_name); 11907d62b00eSchristos if (ctf_link_add_ctf_internal (fp, only_input->clin_arc, 11917d62b00eSchristos only_input->clin_fp, 11927d62b00eSchristos out_name) < 0) 11937d62b00eSchristos { 11947d62b00eSchristos ctf_err_warn (fp, 0, 0, _("cannot add intermediate files " 11957d62b00eSchristos "to link")); 11967d62b00eSchristos goto err_open_inputs; 11977d62b00eSchristos } 11987d62b00eSchristos only_input->clin_arc = NULL; 11997d62b00eSchristos only_input->clin_fp = NULL; 12007d62b00eSchristos ctf_dynhash_remove (fp->ctf_link_inputs, 12017d62b00eSchristos only_input->clin_filename); 12027d62b00eSchristos } 12037d62b00eSchristos continue; 12047d62b00eSchristos } 12057d62b00eSchristos 12067d62b00eSchristos /* This is a real CU many-to-one mapping: we must dedup the inputs into 12077d62b00eSchristos a new output to be used in the final link phase. */ 12087d62b00eSchristos 12097d62b00eSchristos if ((inputs = ctf_link_deduplicating_open_inputs (fp, in, ninputs, 12107d62b00eSchristos &parents)) == NULL) 12117d62b00eSchristos { 12127d62b00eSchristos ctf_next_destroy (i); 12137d62b00eSchristos goto err_inputs; 12147d62b00eSchristos } 12157d62b00eSchristos 12167d62b00eSchristos if ((out = ctf_create (&err)) == NULL) 12177d62b00eSchristos { 12187d62b00eSchristos ctf_err_warn (fp, 0, err, _("cannot create per-CU CTF archive " 12197d62b00eSchristos "for %s"), 12207d62b00eSchristos out_name); 12217d62b00eSchristos ctf_set_errno (fp, err); 12227d62b00eSchristos goto err_inputs; 12237d62b00eSchristos } 12247d62b00eSchristos 12257d62b00eSchristos /* Share the atoms table to reduce memory usage. */ 12267d62b00eSchristos out->ctf_dedup_atoms = fp->ctf_dedup_atoms_alloc; 12277d62b00eSchristos 12287d62b00eSchristos /* No ctf_imports at this stage: this per-CU dictionary has no parents. 12297d62b00eSchristos Parent/child deduplication happens in the link's final pass. However, 12307d62b00eSchristos the cuname *is* important, as it is propagated into the final 12317d62b00eSchristos dictionary. */ 12327d62b00eSchristos ctf_cuname_set (out, out_name); 12337d62b00eSchristos 12347d62b00eSchristos if (ctf_dedup (out, inputs, ninputs, parents, 1) < 0) 12357d62b00eSchristos { 12367d62b00eSchristos ctf_set_errno (fp, ctf_errno (out)); 12377d62b00eSchristos ctf_err_warn (fp, 0, 0, _("CU-mapped deduplication failed for %s"), 12387d62b00eSchristos out_name); 12397d62b00eSchristos goto err_inputs; 12407d62b00eSchristos } 12417d62b00eSchristos 12427d62b00eSchristos if ((outputs = ctf_dedup_emit (out, inputs, ninputs, parents, 12437d62b00eSchristos &noutputs, 1)) == NULL) 12447d62b00eSchristos { 12457d62b00eSchristos ctf_set_errno (fp, ctf_errno (out)); 12467d62b00eSchristos ctf_err_warn (fp, 0, 0, _("CU-mapped deduplicating link type emission " 12477d62b00eSchristos "failed for %s"), out_name); 12487d62b00eSchristos goto err_inputs; 12497d62b00eSchristos } 12507d62b00eSchristos if (!ctf_assert (fp, noutputs == 1)) 1251*6881a400Schristos { 1252*6881a400Schristos size_t j; 1253*6881a400Schristos for (j = 1; j < noutputs; j++) 1254*6881a400Schristos ctf_dict_close (outputs[j]); 12557d62b00eSchristos goto err_inputs_outputs; 1256*6881a400Schristos } 12577d62b00eSchristos 12587d62b00eSchristos if (!(fp->ctf_link_flags & CTF_LINK_OMIT_VARIABLES_SECTION) 12597d62b00eSchristos && ctf_link_deduplicating_variables (out, inputs, ninputs, 1) < 0) 12607d62b00eSchristos { 12617d62b00eSchristos ctf_set_errno (fp, ctf_errno (out)); 12627d62b00eSchristos ctf_err_warn (fp, 0, 0, _("CU-mapped deduplicating link variable " 12637d62b00eSchristos "emission failed for %s"), out_name); 12647d62b00eSchristos goto err_inputs_outputs; 12657d62b00eSchristos } 12667d62b00eSchristos 1267*6881a400Schristos ctf_dedup_fini (out, outputs, noutputs); 1268*6881a400Schristos 1269*6881a400Schristos /* For now, we omit symbol section linking for CU-mapped links, until it 1270*6881a400Schristos is clear how to unify the symbol table across such links. (Perhaps we 1271*6881a400Schristos should emit an unconditionally indexed symtab, like the compiler 1272*6881a400Schristos does.) */ 1273*6881a400Schristos 12747d62b00eSchristos if (ctf_link_deduplicating_close_inputs (fp, in, inputs, ninputs) < 0) 12757d62b00eSchristos { 12767d62b00eSchristos free (inputs); 12777d62b00eSchristos free (parents); 12787d62b00eSchristos goto err_outputs; 12797d62b00eSchristos } 12807d62b00eSchristos free (inputs); 12817d62b00eSchristos free (parents); 12827d62b00eSchristos 12837d62b00eSchristos /* Splice any errors or warnings created during this link back into the 12847d62b00eSchristos dict that the caller knows about. */ 12857d62b00eSchristos ctf_list_splice (&fp->ctf_errs_warnings, &outputs[0]->ctf_errs_warnings); 12867d62b00eSchristos 12877d62b00eSchristos /* This output now becomes an input to the next link phase, with a name 12887d62b00eSchristos equal to the CU name. We have to wrap it in an archive wrapper 12897d62b00eSchristos first. */ 12907d62b00eSchristos 12917d62b00eSchristos if ((in_arc = ctf_new_archive_internal (0, 0, NULL, outputs[0], NULL, 12927d62b00eSchristos NULL, &err)) == NULL) 12937d62b00eSchristos { 12947d62b00eSchristos ctf_set_errno (fp, err); 12957d62b00eSchristos goto err_outputs; 12967d62b00eSchristos } 12977d62b00eSchristos 12987d62b00eSchristos if (ctf_link_add_ctf_internal (fp, in_arc, NULL, 12997d62b00eSchristos ctf_cuname (outputs[0])) < 0) 13007d62b00eSchristos { 13017d62b00eSchristos ctf_err_warn (fp, 0, 0, _("cannot add intermediate files to link")); 13027d62b00eSchristos goto err_outputs; 13037d62b00eSchristos } 13047d62b00eSchristos 1305*6881a400Schristos ctf_dict_close (out); 13067d62b00eSchristos free (outputs); 13077d62b00eSchristos continue; 13087d62b00eSchristos 13097d62b00eSchristos err_inputs_outputs: 13107d62b00eSchristos ctf_list_splice (&fp->ctf_errs_warnings, &outputs[0]->ctf_errs_warnings); 1311*6881a400Schristos ctf_dict_close (outputs[0]); 13127d62b00eSchristos free (outputs); 13137d62b00eSchristos err_inputs: 13147d62b00eSchristos ctf_link_deduplicating_close_inputs (fp, in, inputs, ninputs); 1315*6881a400Schristos ctf_dict_close (out); 13167d62b00eSchristos free (inputs); 13177d62b00eSchristos free (parents); 13187d62b00eSchristos err_open_inputs: 13197d62b00eSchristos ctf_next_destroy (i); 13207d62b00eSchristos return -1; 13217d62b00eSchristos 13227d62b00eSchristos err_outputs: 13237d62b00eSchristos ctf_list_splice (&fp->ctf_errs_warnings, &outputs[0]->ctf_errs_warnings); 1324*6881a400Schristos ctf_dict_close (outputs[0]); 13257d62b00eSchristos free (outputs); 13267d62b00eSchristos ctf_next_destroy (i); 13277d62b00eSchristos return -1; /* Errno is set for us. */ 13287d62b00eSchristos } 13297d62b00eSchristos if (err != ECTF_NEXT_END) 13307d62b00eSchristos { 13317d62b00eSchristos ctf_err_warn (fp, 0, err, _("iteration error in CU-mapped deduplicating " 13327d62b00eSchristos "link")); 13337d62b00eSchristos return ctf_set_errno (fp, err); 13347d62b00eSchristos } 13357d62b00eSchristos 13367d62b00eSchristos return 0; 13377d62b00eSchristos } 13387d62b00eSchristos 1339*6881a400Schristos /* Empty all the ctf_link_outputs. */ 1340*6881a400Schristos static int 1341*6881a400Schristos ctf_link_empty_outputs (ctf_dict_t *fp) 1342*6881a400Schristos { 1343*6881a400Schristos ctf_next_t *i = NULL; 1344*6881a400Schristos void *v; 1345*6881a400Schristos int err; 1346*6881a400Schristos 1347*6881a400Schristos ctf_dynhash_empty (fp->ctf_link_outputs); 1348*6881a400Schristos 1349*6881a400Schristos while ((err = ctf_dynhash_next (fp->ctf_link_inputs, &i, NULL, &v)) == 0) 1350*6881a400Schristos { 1351*6881a400Schristos ctf_dict_t *in = (ctf_dict_t *) v; 1352*6881a400Schristos in->ctf_link_in_out = NULL; 1353*6881a400Schristos } 1354*6881a400Schristos if (err != ECTF_NEXT_END) 1355*6881a400Schristos { 1356*6881a400Schristos fp->ctf_flags &= ~LCTF_LINKING; 1357*6881a400Schristos ctf_err_warn (fp, 1, err, _("iteration error removing old outputs")); 1358*6881a400Schristos ctf_set_errno (fp, err); 1359*6881a400Schristos return -1; 1360*6881a400Schristos } 1361*6881a400Schristos return 0; 1362*6881a400Schristos } 1363*6881a400Schristos 13647d62b00eSchristos /* Do a deduplicating link using the ctf-dedup machinery. */ 13657d62b00eSchristos static void 1366*6881a400Schristos ctf_link_deduplicating (ctf_dict_t *fp) 13677d62b00eSchristos { 13687d62b00eSchristos size_t i; 1369*6881a400Schristos ctf_dict_t **inputs, **outputs = NULL; 13707d62b00eSchristos ssize_t ninputs; 13717d62b00eSchristos uint32_t noutputs; 13727d62b00eSchristos uint32_t *parents; 13737d62b00eSchristos 13747d62b00eSchristos if (ctf_dedup_atoms_init (fp) < 0) 13757d62b00eSchristos { 13767d62b00eSchristos ctf_err_warn (fp, 0, 0, _("allocating CTF dedup atoms table")); 13777d62b00eSchristos return; /* Errno is set for us. */ 13787d62b00eSchristos } 13797d62b00eSchristos 13807d62b00eSchristos if (fp->ctf_link_out_cu_mapping 13817d62b00eSchristos && (ctf_link_deduplicating_per_cu (fp) < 0)) 13827d62b00eSchristos return; /* Errno is set for us. */ 13837d62b00eSchristos 13847d62b00eSchristos if ((ninputs = ctf_link_deduplicating_count_inputs (fp, NULL, NULL)) < 0) 13857d62b00eSchristos return; /* Errno is set for us. */ 13867d62b00eSchristos 13877d62b00eSchristos if ((inputs = ctf_link_deduplicating_open_inputs (fp, NULL, ninputs, 13887d62b00eSchristos &parents)) == NULL) 13897d62b00eSchristos return; /* Errno is set for us. */ 13907d62b00eSchristos 13917d62b00eSchristos if (ninputs == 1 && ctf_cuname (inputs[0]) != NULL) 13927d62b00eSchristos ctf_cuname_set (fp, ctf_cuname (inputs[0])); 13937d62b00eSchristos 13947d62b00eSchristos if (ctf_dedup (fp, inputs, ninputs, parents, 0) < 0) 13957d62b00eSchristos { 13967d62b00eSchristos ctf_err_warn (fp, 0, 0, _("deduplication failed for %s"), 13977d62b00eSchristos ctf_link_input_name (fp)); 13987d62b00eSchristos goto err; 13997d62b00eSchristos } 14007d62b00eSchristos 14017d62b00eSchristos if ((outputs = ctf_dedup_emit (fp, inputs, ninputs, parents, &noutputs, 14027d62b00eSchristos 0)) == NULL) 14037d62b00eSchristos { 14047d62b00eSchristos ctf_err_warn (fp, 0, 0, _("deduplicating link type emission failed " 14057d62b00eSchristos "for %s"), ctf_link_input_name (fp)); 14067d62b00eSchristos goto err; 14077d62b00eSchristos } 14087d62b00eSchristos 14097d62b00eSchristos if (!ctf_assert (fp, outputs[0] == fp)) 1410*6881a400Schristos { 1411*6881a400Schristos for (i = 1; i < noutputs; i++) 1412*6881a400Schristos ctf_dict_close (outputs[i]); 14137d62b00eSchristos goto err; 1414*6881a400Schristos } 14157d62b00eSchristos 14167d62b00eSchristos for (i = 0; i < noutputs; i++) 14177d62b00eSchristos { 14187d62b00eSchristos char *dynname; 14197d62b00eSchristos 14207d62b00eSchristos /* We already have access to this one. Close the duplicate. */ 14217d62b00eSchristos if (i == 0) 14227d62b00eSchristos { 1423*6881a400Schristos ctf_dict_close (outputs[0]); 14247d62b00eSchristos continue; 14257d62b00eSchristos } 14267d62b00eSchristos 1427*6881a400Schristos if ((dynname = ctf_new_per_cu_name (fp, ctf_cuname (outputs[i]))) == NULL) 14287d62b00eSchristos goto oom_one_output; 14297d62b00eSchristos 14307d62b00eSchristos if (ctf_dynhash_insert (fp->ctf_link_outputs, dynname, outputs[i]) < 0) 14317d62b00eSchristos goto oom_one_output; 14327d62b00eSchristos 14337d62b00eSchristos continue; 14347d62b00eSchristos 14357d62b00eSchristos oom_one_output: 14367d62b00eSchristos ctf_set_errno (fp, ENOMEM); 14377d62b00eSchristos ctf_err_warn (fp, 0, 0, _("out of memory allocating link outputs")); 14387d62b00eSchristos free (dynname); 14397d62b00eSchristos 14407d62b00eSchristos for (; i < noutputs; i++) 1441*6881a400Schristos ctf_dict_close (outputs[i]); 14427d62b00eSchristos goto err; 14437d62b00eSchristos } 14447d62b00eSchristos 14457d62b00eSchristos if (!(fp->ctf_link_flags & CTF_LINK_OMIT_VARIABLES_SECTION) 14467d62b00eSchristos && ctf_link_deduplicating_variables (fp, inputs, ninputs, 0) < 0) 14477d62b00eSchristos { 14487d62b00eSchristos ctf_err_warn (fp, 0, 0, _("deduplicating link variable emission failed for " 14497d62b00eSchristos "%s"), ctf_link_input_name (fp)); 1450*6881a400Schristos goto err_clean_outputs; 14517d62b00eSchristos } 14527d62b00eSchristos 1453*6881a400Schristos if (ctf_link_deduplicating_syms (fp, inputs, ninputs, 0) < 0) 1454*6881a400Schristos { 1455*6881a400Schristos ctf_err_warn (fp, 0, 0, _("deduplicating link symbol emission failed for " 1456*6881a400Schristos "%s"), ctf_link_input_name (fp)); 1457*6881a400Schristos goto err_clean_outputs; 1458*6881a400Schristos } 1459*6881a400Schristos 1460*6881a400Schristos ctf_dedup_fini (fp, outputs, noutputs); 1461*6881a400Schristos 14627d62b00eSchristos /* Now close all the inputs, including per-CU intermediates. */ 14637d62b00eSchristos 14647d62b00eSchristos if (ctf_link_deduplicating_close_inputs (fp, NULL, inputs, ninputs) < 0) 14657d62b00eSchristos return; /* errno is set for us. */ 14667d62b00eSchristos 14677d62b00eSchristos ninputs = 0; /* Prevent double-close. */ 14687d62b00eSchristos ctf_set_errno (fp, 0); 14697d62b00eSchristos 14707d62b00eSchristos /* Fall through. */ 14717d62b00eSchristos 14727d62b00eSchristos err: 14737d62b00eSchristos for (i = 0; i < (size_t) ninputs; i++) 1474*6881a400Schristos ctf_dict_close (inputs[i]); 14757d62b00eSchristos free (inputs); 14767d62b00eSchristos free (parents); 14777d62b00eSchristos free (outputs); 14787d62b00eSchristos return; 1479*6881a400Schristos 1480*6881a400Schristos err_clean_outputs: 1481*6881a400Schristos ctf_link_empty_outputs (fp); 1482*6881a400Schristos goto err; 14837d62b00eSchristos } 14847d62b00eSchristos 1485*6881a400Schristos /* Merge types and variable sections in all dicts added to the link together. 1486*6881a400Schristos The result of any previous link is discarded. */ 14877d62b00eSchristos int 1488*6881a400Schristos ctf_link (ctf_dict_t *fp, int flags) 14897d62b00eSchristos { 14907d62b00eSchristos int err; 14917d62b00eSchristos 14927d62b00eSchristos fp->ctf_link_flags = flags; 14937d62b00eSchristos 14947d62b00eSchristos if (fp->ctf_link_inputs == NULL) 14957d62b00eSchristos return 0; /* Nothing to do. */ 14967d62b00eSchristos 1497*6881a400Schristos if (fp->ctf_link_outputs != NULL) 1498*6881a400Schristos ctf_link_empty_outputs (fp); 1499*6881a400Schristos else 15007d62b00eSchristos fp->ctf_link_outputs = ctf_dynhash_create (ctf_hash_string, 15017d62b00eSchristos ctf_hash_eq_string, free, 15027d62b00eSchristos (ctf_hash_free_fun) 1503*6881a400Schristos ctf_dict_close); 15047d62b00eSchristos 15057d62b00eSchristos if (fp->ctf_link_outputs == NULL) 15067d62b00eSchristos return ctf_set_errno (fp, ENOMEM); 15077d62b00eSchristos 15087d62b00eSchristos /* Create empty CUs if requested. We do not currently claim that multiple 15097d62b00eSchristos links in succession with CTF_LINK_EMPTY_CU_MAPPINGS set in some calls and 15107d62b00eSchristos not set in others will do anything especially sensible. */ 15117d62b00eSchristos 1512*6881a400Schristos fp->ctf_flags |= LCTF_LINKING; 15137d62b00eSchristos if (fp->ctf_link_out_cu_mapping && (flags & CTF_LINK_EMPTY_CU_MAPPINGS)) 15147d62b00eSchristos { 1515*6881a400Schristos ctf_next_t *i = NULL; 1516*6881a400Schristos void *k; 15177d62b00eSchristos 1518*6881a400Schristos while ((err = ctf_dynhash_next (fp->ctf_link_out_cu_mapping, &i, &k, 15197d62b00eSchristos NULL)) == 0) 15207d62b00eSchristos { 1521*6881a400Schristos const char *to = (const char *) k; 1522*6881a400Schristos if (ctf_create_per_cu (fp, NULL, to) == NULL) 15237d62b00eSchristos { 1524*6881a400Schristos fp->ctf_flags &= ~LCTF_LINKING; 15257d62b00eSchristos ctf_next_destroy (i); 15267d62b00eSchristos return -1; /* Errno is set for us. */ 15277d62b00eSchristos } 15287d62b00eSchristos } 15297d62b00eSchristos if (err != ECTF_NEXT_END) 15307d62b00eSchristos { 1531*6881a400Schristos fp->ctf_flags &= ~LCTF_LINKING; 15327d62b00eSchristos ctf_err_warn (fp, 1, err, _("iteration error creating empty CUs")); 15337d62b00eSchristos ctf_set_errno (fp, err); 15347d62b00eSchristos return -1; 15357d62b00eSchristos } 15367d62b00eSchristos } 15377d62b00eSchristos 15387d62b00eSchristos ctf_link_deduplicating (fp); 15397d62b00eSchristos 1540*6881a400Schristos fp->ctf_flags &= ~LCTF_LINKING; 15417d62b00eSchristos if ((ctf_errno (fp) != 0) && (ctf_errno (fp) != ECTF_NOCTFDATA)) 15427d62b00eSchristos return -1; 15437d62b00eSchristos return 0; 15447d62b00eSchristos } 15457d62b00eSchristos 15467d62b00eSchristos typedef struct ctf_link_out_string_cb_arg 15477d62b00eSchristos { 15487d62b00eSchristos const char *str; 15497d62b00eSchristos uint32_t offset; 15507d62b00eSchristos int err; 15517d62b00eSchristos } ctf_link_out_string_cb_arg_t; 15527d62b00eSchristos 15537d62b00eSchristos /* Intern a string in the string table of an output per-CU CTF file. */ 15547d62b00eSchristos static void 15557d62b00eSchristos ctf_link_intern_extern_string (void *key _libctf_unused_, void *value, 15567d62b00eSchristos void *arg_) 15577d62b00eSchristos { 1558*6881a400Schristos ctf_dict_t *fp = (ctf_dict_t *) value; 15597d62b00eSchristos ctf_link_out_string_cb_arg_t *arg = (ctf_link_out_string_cb_arg_t *) arg_; 15607d62b00eSchristos 15617d62b00eSchristos fp->ctf_flags |= LCTF_DIRTY; 15627d62b00eSchristos if (!ctf_str_add_external (fp, arg->str, arg->offset)) 15637d62b00eSchristos arg->err = ENOMEM; 15647d62b00eSchristos } 15657d62b00eSchristos 15667d62b00eSchristos /* Repeatedly call ADD_STRING to acquire strings from the external string table, 15677d62b00eSchristos adding them to the atoms table for this CU and all subsidiary CUs. 15687d62b00eSchristos 1569*6881a400Schristos If ctf_link is also called, it must be called first if you want the new CTF 1570*6881a400Schristos files ctf_link can create to get their strings dedupped against the ELF 15717d62b00eSchristos strtab properly. */ 15727d62b00eSchristos int 1573*6881a400Schristos ctf_link_add_strtab (ctf_dict_t *fp, ctf_link_strtab_string_f *add_string, 15747d62b00eSchristos void *arg) 15757d62b00eSchristos { 15767d62b00eSchristos const char *str; 15777d62b00eSchristos uint32_t offset; 15787d62b00eSchristos int err = 0; 15797d62b00eSchristos 15807d62b00eSchristos while ((str = add_string (&offset, arg)) != NULL) 15817d62b00eSchristos { 15827d62b00eSchristos ctf_link_out_string_cb_arg_t iter_arg = { str, offset, 0 }; 15837d62b00eSchristos 15847d62b00eSchristos fp->ctf_flags |= LCTF_DIRTY; 15857d62b00eSchristos if (!ctf_str_add_external (fp, str, offset)) 15867d62b00eSchristos err = ENOMEM; 15877d62b00eSchristos 15887d62b00eSchristos ctf_dynhash_iter (fp->ctf_link_outputs, ctf_link_intern_extern_string, 15897d62b00eSchristos &iter_arg); 15907d62b00eSchristos if (iter_arg.err) 15917d62b00eSchristos err = iter_arg.err; 15927d62b00eSchristos } 15937d62b00eSchristos 1594*6881a400Schristos if (err) 1595*6881a400Schristos ctf_set_errno (fp, err); 1596*6881a400Schristos 15977d62b00eSchristos return -err; 15987d62b00eSchristos } 15997d62b00eSchristos 1600*6881a400Schristos /* Inform the ctf-link machinery of a new symbol in the target symbol table 1601*6881a400Schristos (which must be some symtab that is not usually stripped, and which 1602*6881a400Schristos is in agreement with ctf_bfdopen_ctfsect). May be called either before or 1603*6881a400Schristos after ctf_link_add_strtab. */ 16047d62b00eSchristos int 1605*6881a400Schristos ctf_link_add_linker_symbol (ctf_dict_t *fp, ctf_link_sym_t *sym) 16067d62b00eSchristos { 1607*6881a400Schristos ctf_in_flight_dynsym_t *cid; 1608*6881a400Schristos 1609*6881a400Schristos /* Cheat a little: if there is already an ENOMEM error code recorded against 1610*6881a400Schristos this dict, we shouldn't even try to add symbols because there will be no 1611*6881a400Schristos memory to do so: probably we failed to add some previous symbol. This 1612*6881a400Schristos makes out-of-memory exits 'sticky' across calls to this function, so the 1613*6881a400Schristos caller doesn't need to worry about error conditions. */ 1614*6881a400Schristos 1615*6881a400Schristos if (ctf_errno (fp) == ENOMEM) 1616*6881a400Schristos return -ENOMEM; /* errno is set for us. */ 1617*6881a400Schristos 1618*6881a400Schristos if (ctf_symtab_skippable (sym)) 16197d62b00eSchristos return 0; 1620*6881a400Schristos 1621*6881a400Schristos if (sym->st_type != STT_OBJECT && sym->st_type != STT_FUNC) 1622*6881a400Schristos return 0; 1623*6881a400Schristos 1624*6881a400Schristos /* Add the symbol to the in-flight list. */ 1625*6881a400Schristos 1626*6881a400Schristos if ((cid = malloc (sizeof (ctf_in_flight_dynsym_t))) == NULL) 1627*6881a400Schristos goto oom; 1628*6881a400Schristos 1629*6881a400Schristos cid->cid_sym = *sym; 1630*6881a400Schristos ctf_list_append (&fp->ctf_in_flight_dynsyms, cid); 1631*6881a400Schristos 1632*6881a400Schristos return 0; 1633*6881a400Schristos 1634*6881a400Schristos oom: 1635*6881a400Schristos ctf_dynhash_destroy (fp->ctf_dynsyms); 1636*6881a400Schristos fp->ctf_dynsyms = NULL; 1637*6881a400Schristos ctf_set_errno (fp, ENOMEM); 1638*6881a400Schristos return -ENOMEM; 1639*6881a400Schristos } 1640*6881a400Schristos 1641*6881a400Schristos /* Impose an ordering on symbols. The ordering takes effect immediately, but 1642*6881a400Schristos since the ordering info does not include type IDs, lookups may return nothing 1643*6881a400Schristos until such IDs are added by calls to ctf_add_*_sym. Must be called after 1644*6881a400Schristos ctf_link_add_strtab and ctf_link_add_linker_symbol. */ 1645*6881a400Schristos int 1646*6881a400Schristos ctf_link_shuffle_syms (ctf_dict_t *fp) 1647*6881a400Schristos { 1648*6881a400Schristos ctf_in_flight_dynsym_t *did, *nid; 1649*6881a400Schristos ctf_next_t *i = NULL; 1650*6881a400Schristos int err = ENOMEM; 1651*6881a400Schristos void *name_, *sym_; 1652*6881a400Schristos 1653*6881a400Schristos if (!fp->ctf_dynsyms) 1654*6881a400Schristos { 1655*6881a400Schristos fp->ctf_dynsyms = ctf_dynhash_create (ctf_hash_string, 1656*6881a400Schristos ctf_hash_eq_string, 1657*6881a400Schristos NULL, free); 1658*6881a400Schristos if (!fp->ctf_dynsyms) 1659*6881a400Schristos { 1660*6881a400Schristos ctf_set_errno (fp, ENOMEM); 1661*6881a400Schristos return -ENOMEM; 1662*6881a400Schristos } 1663*6881a400Schristos } 1664*6881a400Schristos 1665*6881a400Schristos /* Add all the symbols, excluding only those we already know are prohibited 1666*6881a400Schristos from appearing in symtypetabs. */ 1667*6881a400Schristos 1668*6881a400Schristos for (did = ctf_list_next (&fp->ctf_in_flight_dynsyms); did != NULL; did = nid) 1669*6881a400Schristos { 1670*6881a400Schristos ctf_link_sym_t *new_sym; 1671*6881a400Schristos 1672*6881a400Schristos nid = ctf_list_next (did); 1673*6881a400Schristos ctf_list_delete (&fp->ctf_in_flight_dynsyms, did); 1674*6881a400Schristos 1675*6881a400Schristos /* We might get a name or an external strtab offset. The strtab offset is 1676*6881a400Schristos guaranteed resolvable at this point, so turn it into a string. */ 1677*6881a400Schristos 1678*6881a400Schristos if (did->cid_sym.st_name == NULL) 1679*6881a400Schristos { 1680*6881a400Schristos uint32_t off = CTF_SET_STID (did->cid_sym.st_nameidx, CTF_STRTAB_1); 1681*6881a400Schristos 1682*6881a400Schristos did->cid_sym.st_name = ctf_strraw (fp, off); 1683*6881a400Schristos did->cid_sym.st_nameidx_set = 0; 1684*6881a400Schristos if (!ctf_assert (fp, did->cid_sym.st_name != NULL)) 1685*6881a400Schristos return -ECTF_INTERNAL; /* errno is set for us. */ 1686*6881a400Schristos } 1687*6881a400Schristos 1688*6881a400Schristos /* The symbol might have turned out to be nameless, so we have to recheck 1689*6881a400Schristos for skippability here. */ 1690*6881a400Schristos if (!ctf_symtab_skippable (&did->cid_sym)) 1691*6881a400Schristos { 1692*6881a400Schristos ctf_dprintf ("symbol from linker: %s (%x)\n", did->cid_sym.st_name, 1693*6881a400Schristos did->cid_sym.st_symidx); 1694*6881a400Schristos 1695*6881a400Schristos if ((new_sym = malloc (sizeof (ctf_link_sym_t))) == NULL) 1696*6881a400Schristos goto local_oom; 1697*6881a400Schristos 1698*6881a400Schristos memcpy (new_sym, &did->cid_sym, sizeof (ctf_link_sym_t)); 1699*6881a400Schristos if (ctf_dynhash_cinsert (fp->ctf_dynsyms, new_sym->st_name, new_sym) < 0) 1700*6881a400Schristos goto local_oom; 1701*6881a400Schristos 1702*6881a400Schristos if (fp->ctf_dynsymmax < new_sym->st_symidx) 1703*6881a400Schristos fp->ctf_dynsymmax = new_sym->st_symidx; 1704*6881a400Schristos } 1705*6881a400Schristos 1706*6881a400Schristos free (did); 1707*6881a400Schristos continue; 1708*6881a400Schristos 1709*6881a400Schristos local_oom: 1710*6881a400Schristos free (did); 1711*6881a400Schristos free (new_sym); 1712*6881a400Schristos goto err; 1713*6881a400Schristos } 1714*6881a400Schristos 1715*6881a400Schristos /* If no symbols are reported, unwind what we have done and return. This 1716*6881a400Schristos makes it a bit easier for the serializer to tell that no symbols have been 1717*6881a400Schristos reported and that it should look elsewhere for reported symbols. */ 1718*6881a400Schristos if (!ctf_dynhash_elements (fp->ctf_dynsyms)) 1719*6881a400Schristos { 1720*6881a400Schristos ctf_dprintf ("No symbols: not a final link.\n"); 1721*6881a400Schristos ctf_dynhash_destroy (fp->ctf_dynsyms); 1722*6881a400Schristos fp->ctf_dynsyms = NULL; 1723*6881a400Schristos return 0; 1724*6881a400Schristos } 1725*6881a400Schristos 1726*6881a400Schristos /* Construct a mapping from shndx to the symbol info. */ 1727*6881a400Schristos free (fp->ctf_dynsymidx); 1728*6881a400Schristos if ((fp->ctf_dynsymidx = calloc (fp->ctf_dynsymmax + 1, 1729*6881a400Schristos sizeof (ctf_link_sym_t *))) == NULL) 1730*6881a400Schristos goto err; 1731*6881a400Schristos 1732*6881a400Schristos while ((err = ctf_dynhash_next (fp->ctf_dynsyms, &i, &name_, &sym_)) == 0) 1733*6881a400Schristos { 1734*6881a400Schristos const char *name = (const char *) name; 1735*6881a400Schristos ctf_link_sym_t *symp = (ctf_link_sym_t *) sym_; 1736*6881a400Schristos 1737*6881a400Schristos if (!ctf_assert (fp, symp->st_symidx <= fp->ctf_dynsymmax)) 1738*6881a400Schristos { 1739*6881a400Schristos ctf_next_destroy (i); 1740*6881a400Schristos err = ctf_errno (fp); 1741*6881a400Schristos goto err; 1742*6881a400Schristos } 1743*6881a400Schristos fp->ctf_dynsymidx[symp->st_symidx] = symp; 1744*6881a400Schristos } 1745*6881a400Schristos if (err != ECTF_NEXT_END) 1746*6881a400Schristos { 1747*6881a400Schristos ctf_err_warn (fp, 0, err, _("error iterating over shuffled symbols")); 1748*6881a400Schristos goto err; 1749*6881a400Schristos } 1750*6881a400Schristos return 0; 1751*6881a400Schristos 1752*6881a400Schristos err: 1753*6881a400Schristos /* Leave the in-flight symbols around: they'll be freed at 1754*6881a400Schristos dict close time regardless. */ 1755*6881a400Schristos ctf_dynhash_destroy (fp->ctf_dynsyms); 1756*6881a400Schristos fp->ctf_dynsyms = NULL; 1757*6881a400Schristos free (fp->ctf_dynsymidx); 1758*6881a400Schristos fp->ctf_dynsymidx = NULL; 1759*6881a400Schristos fp->ctf_dynsymmax = 0; 1760*6881a400Schristos ctf_set_errno (fp, err); 1761*6881a400Schristos return -err; 17627d62b00eSchristos } 17637d62b00eSchristos 17647d62b00eSchristos typedef struct ctf_name_list_accum_cb_arg 17657d62b00eSchristos { 17667d62b00eSchristos char **names; 1767*6881a400Schristos ctf_dict_t *fp; 1768*6881a400Schristos ctf_dict_t **files; 17697d62b00eSchristos size_t i; 17707d62b00eSchristos char **dynames; 17717d62b00eSchristos size_t ndynames; 17727d62b00eSchristos } ctf_name_list_accum_cb_arg_t; 17737d62b00eSchristos 17747d62b00eSchristos /* Accumulate the names and a count of the names in the link output hash. */ 17757d62b00eSchristos static void 17767d62b00eSchristos ctf_accumulate_archive_names (void *key, void *value, void *arg_) 17777d62b00eSchristos { 17787d62b00eSchristos const char *name = (const char *) key; 1779*6881a400Schristos ctf_dict_t *fp = (ctf_dict_t *) value; 17807d62b00eSchristos char **names; 1781*6881a400Schristos ctf_dict_t **files; 17827d62b00eSchristos ctf_name_list_accum_cb_arg_t *arg = (ctf_name_list_accum_cb_arg_t *) arg_; 17837d62b00eSchristos 17847d62b00eSchristos if ((names = realloc (arg->names, sizeof (char *) * ++(arg->i))) == NULL) 17857d62b00eSchristos { 17867d62b00eSchristos (arg->i)--; 17877d62b00eSchristos ctf_set_errno (arg->fp, ENOMEM); 17887d62b00eSchristos return; 17897d62b00eSchristos } 17907d62b00eSchristos 1791*6881a400Schristos if ((files = realloc (arg->files, sizeof (ctf_dict_t *) * arg->i)) == NULL) 17927d62b00eSchristos { 17937d62b00eSchristos (arg->i)--; 17947d62b00eSchristos ctf_set_errno (arg->fp, ENOMEM); 17957d62b00eSchristos return; 17967d62b00eSchristos } 17977d62b00eSchristos 17987d62b00eSchristos /* Allow the caller to get in and modify the name at the last minute. If the 17997d62b00eSchristos caller *does* modify the name, we have to stash away the new name the 18007d62b00eSchristos caller returned so we can free it later on. (The original name is the key 18017d62b00eSchristos of the ctf_link_outputs hash and is freed by the dynhash machinery.) */ 18027d62b00eSchristos 18037d62b00eSchristos if (fp->ctf_link_memb_name_changer) 18047d62b00eSchristos { 18057d62b00eSchristos char **dynames; 18067d62b00eSchristos char *dyname; 18077d62b00eSchristos void *nc_arg = fp->ctf_link_memb_name_changer_arg; 18087d62b00eSchristos 18097d62b00eSchristos dyname = fp->ctf_link_memb_name_changer (fp, name, nc_arg); 18107d62b00eSchristos 18117d62b00eSchristos if (dyname != NULL) 18127d62b00eSchristos { 18137d62b00eSchristos if ((dynames = realloc (arg->dynames, 18147d62b00eSchristos sizeof (char *) * ++(arg->ndynames))) == NULL) 18157d62b00eSchristos { 18167d62b00eSchristos (arg->ndynames)--; 18177d62b00eSchristos ctf_set_errno (arg->fp, ENOMEM); 18187d62b00eSchristos return; 18197d62b00eSchristos } 18207d62b00eSchristos arg->dynames = dynames; 18217d62b00eSchristos name = (const char *) dyname; 18227d62b00eSchristos } 18237d62b00eSchristos } 18247d62b00eSchristos 18257d62b00eSchristos arg->names = names; 18267d62b00eSchristos arg->names[(arg->i) - 1] = (char *) name; 18277d62b00eSchristos arg->files = files; 18287d62b00eSchristos arg->files[(arg->i) - 1] = fp; 18297d62b00eSchristos } 18307d62b00eSchristos 18317d62b00eSchristos /* Change the name of the parent CTF section, if the name transformer has got to 18327d62b00eSchristos it. */ 18337d62b00eSchristos static void 18347d62b00eSchristos ctf_change_parent_name (void *key _libctf_unused_, void *value, void *arg) 18357d62b00eSchristos { 1836*6881a400Schristos ctf_dict_t *fp = (ctf_dict_t *) value; 18377d62b00eSchristos const char *name = (const char *) arg; 18387d62b00eSchristos 18397d62b00eSchristos ctf_parent_name_set (fp, name); 18407d62b00eSchristos } 18417d62b00eSchristos 1842*6881a400Schristos /* Warn if we may suffer information loss because the CTF input files are too 1843*6881a400Schristos old. Usually we provide complete backward compatibility, but compiler 1844*6881a400Schristos changes etc which never hit a release may have a flag in the header that 1845*6881a400Schristos simply prevents those changes from being used. */ 1846*6881a400Schristos static void 1847*6881a400Schristos ctf_link_warn_outdated_inputs (ctf_dict_t *fp) 1848*6881a400Schristos { 1849*6881a400Schristos ctf_next_t *i = NULL; 1850*6881a400Schristos void *name_; 1851*6881a400Schristos void *ifp_; 1852*6881a400Schristos int err; 1853*6881a400Schristos 1854*6881a400Schristos while ((err = ctf_dynhash_next (fp->ctf_link_inputs, &i, &name_, &ifp_)) == 0) 1855*6881a400Schristos { 1856*6881a400Schristos const char *name = (const char *) name_; 1857*6881a400Schristos ctf_dict_t *ifp = (ctf_dict_t *) ifp_; 1858*6881a400Schristos 1859*6881a400Schristos if (!(ifp->ctf_header->cth_flags & CTF_F_NEWFUNCINFO) 1860*6881a400Schristos && (ifp->ctf_header->cth_varoff - ifp->ctf_header->cth_funcoff) > 0) 1861*6881a400Schristos ctf_err_warn (ifp, 1, 0, _("linker input %s has CTF func info but uses " 1862*6881a400Schristos "an old, unreleased func info format: " 1863*6881a400Schristos "this func info section will be dropped."), 1864*6881a400Schristos name); 1865*6881a400Schristos } 1866*6881a400Schristos if (err != ECTF_NEXT_END) 1867*6881a400Schristos ctf_err_warn (fp, 0, err, _("error checking for outdated inputs")); 1868*6881a400Schristos } 1869*6881a400Schristos 18707d62b00eSchristos /* Write out a CTF archive (if there are per-CU CTF files) or a CTF file 18717d62b00eSchristos (otherwise) into a new dynamically-allocated string, and return it. 18727d62b00eSchristos Members with sizes above THRESHOLD are compressed. */ 18737d62b00eSchristos unsigned char * 1874*6881a400Schristos ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold) 18757d62b00eSchristos { 18767d62b00eSchristos ctf_name_list_accum_cb_arg_t arg; 18777d62b00eSchristos char **names; 18787d62b00eSchristos char *transformed_name = NULL; 1879*6881a400Schristos ctf_dict_t **files; 18807d62b00eSchristos FILE *f = NULL; 1881*6881a400Schristos size_t i; 18827d62b00eSchristos int err; 18837d62b00eSchristos long fsize; 18847d62b00eSchristos const char *errloc; 18857d62b00eSchristos unsigned char *buf = NULL; 18867d62b00eSchristos 18877d62b00eSchristos memset (&arg, 0, sizeof (ctf_name_list_accum_cb_arg_t)); 18887d62b00eSchristos arg.fp = fp; 1889*6881a400Schristos fp->ctf_flags |= LCTF_LINKING; 1890*6881a400Schristos 1891*6881a400Schristos ctf_link_warn_outdated_inputs (fp); 18927d62b00eSchristos 18937d62b00eSchristos if (fp->ctf_link_outputs) 18947d62b00eSchristos { 18957d62b00eSchristos ctf_dynhash_iter (fp->ctf_link_outputs, ctf_accumulate_archive_names, &arg); 18967d62b00eSchristos if (ctf_errno (fp) < 0) 18977d62b00eSchristos { 18987d62b00eSchristos errloc = "hash creation"; 18997d62b00eSchristos goto err; 19007d62b00eSchristos } 19017d62b00eSchristos } 19027d62b00eSchristos 1903*6881a400Schristos /* No extra outputs? Just write a simple ctf_dict_t. */ 19047d62b00eSchristos if (arg.i == 0) 1905*6881a400Schristos { 1906*6881a400Schristos unsigned char *ret = ctf_write_mem (fp, size, threshold); 1907*6881a400Schristos fp->ctf_flags &= ~LCTF_LINKING; 1908*6881a400Schristos return ret; 1909*6881a400Schristos } 19107d62b00eSchristos 19117d62b00eSchristos /* Writing an archive. Stick ourselves (the shared repository, parent of all 19127d62b00eSchristos other archives) on the front of it with the default name. */ 19137d62b00eSchristos if ((names = realloc (arg.names, sizeof (char *) * (arg.i + 1))) == NULL) 19147d62b00eSchristos { 19157d62b00eSchristos errloc = "name reallocation"; 19167d62b00eSchristos goto err_no; 19177d62b00eSchristos } 19187d62b00eSchristos arg.names = names; 19197d62b00eSchristos memmove (&(arg.names[1]), arg.names, sizeof (char *) * (arg.i)); 19207d62b00eSchristos 19217d62b00eSchristos arg.names[0] = (char *) _CTF_SECTION; 19227d62b00eSchristos if (fp->ctf_link_memb_name_changer) 19237d62b00eSchristos { 19247d62b00eSchristos void *nc_arg = fp->ctf_link_memb_name_changer_arg; 19257d62b00eSchristos 19267d62b00eSchristos transformed_name = fp->ctf_link_memb_name_changer (fp, _CTF_SECTION, 19277d62b00eSchristos nc_arg); 19287d62b00eSchristos 19297d62b00eSchristos if (transformed_name != NULL) 19307d62b00eSchristos { 19317d62b00eSchristos arg.names[0] = transformed_name; 19327d62b00eSchristos ctf_dynhash_iter (fp->ctf_link_outputs, ctf_change_parent_name, 19337d62b00eSchristos transformed_name); 19347d62b00eSchristos } 19357d62b00eSchristos } 19367d62b00eSchristos 1937*6881a400Schristos /* Propagate the link flags to all the dicts in this link. */ 1938*6881a400Schristos for (i = 0; i < arg.i; i++) 19397d62b00eSchristos { 1940*6881a400Schristos arg.files[i]->ctf_link_flags = fp->ctf_link_flags; 1941*6881a400Schristos arg.files[i]->ctf_flags |= LCTF_LINKING; 1942*6881a400Schristos } 1943*6881a400Schristos 1944*6881a400Schristos if ((files = realloc (arg.files, 1945*6881a400Schristos sizeof (struct ctf_dict *) * (arg.i + 1))) == NULL) 1946*6881a400Schristos { 1947*6881a400Schristos errloc = "ctf_dict reallocation"; 19487d62b00eSchristos goto err_no; 19497d62b00eSchristos } 19507d62b00eSchristos arg.files = files; 1951*6881a400Schristos memmove (&(arg.files[1]), arg.files, sizeof (ctf_dict_t *) * (arg.i)); 19527d62b00eSchristos arg.files[0] = fp; 19537d62b00eSchristos 19547d62b00eSchristos if ((f = tmpfile ()) == NULL) 19557d62b00eSchristos { 19567d62b00eSchristos errloc = "tempfile creation"; 19577d62b00eSchristos goto err_no; 19587d62b00eSchristos } 19597d62b00eSchristos 19607d62b00eSchristos if ((err = ctf_arc_write_fd (fileno (f), arg.files, arg.i + 1, 19617d62b00eSchristos (const char **) arg.names, 19627d62b00eSchristos threshold)) < 0) 19637d62b00eSchristos { 19647d62b00eSchristos errloc = "archive writing"; 19657d62b00eSchristos ctf_set_errno (fp, err); 19667d62b00eSchristos goto err; 19677d62b00eSchristos } 19687d62b00eSchristos 19697d62b00eSchristos if (fseek (f, 0, SEEK_END) < 0) 19707d62b00eSchristos { 19717d62b00eSchristos errloc = "seeking to end"; 19727d62b00eSchristos goto err_no; 19737d62b00eSchristos } 19747d62b00eSchristos 19757d62b00eSchristos if ((fsize = ftell (f)) < 0) 19767d62b00eSchristos { 19777d62b00eSchristos errloc = "filesize determination"; 19787d62b00eSchristos goto err_no; 19797d62b00eSchristos } 19807d62b00eSchristos 19817d62b00eSchristos if (fseek (f, 0, SEEK_SET) < 0) 19827d62b00eSchristos { 19837d62b00eSchristos errloc = "filepos resetting"; 19847d62b00eSchristos goto err_no; 19857d62b00eSchristos } 19867d62b00eSchristos 19877d62b00eSchristos if ((buf = malloc (fsize)) == NULL) 19887d62b00eSchristos { 19897d62b00eSchristos errloc = "CTF archive buffer allocation"; 19907d62b00eSchristos goto err_no; 19917d62b00eSchristos } 19927d62b00eSchristos 19937d62b00eSchristos while (!feof (f) && fread (buf, fsize, 1, f) == 0) 19947d62b00eSchristos if (ferror (f)) 19957d62b00eSchristos { 19967d62b00eSchristos errloc = "reading archive from temporary file"; 19977d62b00eSchristos goto err_no; 19987d62b00eSchristos } 19997d62b00eSchristos 20007d62b00eSchristos *size = fsize; 20017d62b00eSchristos free (arg.names); 20027d62b00eSchristos free (arg.files); 20037d62b00eSchristos free (transformed_name); 20047d62b00eSchristos if (arg.ndynames) 20057d62b00eSchristos { 20067d62b00eSchristos size_t i; 20077d62b00eSchristos for (i = 0; i < arg.ndynames; i++) 20087d62b00eSchristos free (arg.dynames[i]); 20097d62b00eSchristos free (arg.dynames); 20107d62b00eSchristos } 20117d62b00eSchristos fclose (f); 20127d62b00eSchristos return buf; 20137d62b00eSchristos 20147d62b00eSchristos err_no: 20157d62b00eSchristos ctf_set_errno (fp, errno); 2016*6881a400Schristos 2017*6881a400Schristos /* Turn off the is-linking flag on all the dicts in this link. */ 2018*6881a400Schristos for (i = 0; i < arg.i; i++) 2019*6881a400Schristos arg.files[i]->ctf_flags &= ~LCTF_LINKING; 20207d62b00eSchristos err: 20217d62b00eSchristos free (buf); 20227d62b00eSchristos if (f) 20237d62b00eSchristos fclose (f); 20247d62b00eSchristos free (arg.names); 20257d62b00eSchristos free (arg.files); 20267d62b00eSchristos free (transformed_name); 20277d62b00eSchristos if (arg.ndynames) 20287d62b00eSchristos { 20297d62b00eSchristos size_t i; 20307d62b00eSchristos for (i = 0; i < arg.ndynames; i++) 20317d62b00eSchristos free (arg.dynames[i]); 20327d62b00eSchristos free (arg.dynames); 20337d62b00eSchristos } 20347d62b00eSchristos ctf_err_warn (fp, 0, 0, _("cannot write archive in link: %s failure"), 20357d62b00eSchristos errloc); 20367d62b00eSchristos return NULL; 20377d62b00eSchristos } 2038