aboutsummaryrefslogtreecommitdiff
path: root/libctf/ctf-link.c
diff options
context:
space:
mode:
Diffstat (limited to 'libctf/ctf-link.c')
-rw-r--r--libctf/ctf-link.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/libctf/ctf-link.c b/libctf/ctf-link.c
index 5384b20..7c34216 100644
--- a/libctf/ctf-link.c
+++ b/libctf/ctf-link.c
@@ -1682,6 +1682,7 @@ ctf_link (ctf_dict_t *fp, int flags)
links in succession with CTF_LINK_EMPTY_CU_MAPPINGS set in some calls and
not set in others will do anything especially sensible. */
+ fp->ctf_flags |= LCTF_LINKING;
if (fp->ctf_link_out_cu_mapping && (flags & CTF_LINK_EMPTY_CU_MAPPINGS))
{
void *v;
@@ -1692,12 +1693,14 @@ ctf_link (ctf_dict_t *fp, int flags)
const char *to = (const char *) v;
if (ctf_create_per_cu (fp, to, to) == NULL)
{
+ fp->ctf_flags &= ~LCTF_LINKING;
ctf_next_destroy (i);
return -1; /* Errno is set for us. */
}
}
if (err != ECTF_NEXT_END)
{
+ fp->ctf_flags &= ~LCTF_LINKING;
ctf_err_warn (fp, 1, err, _("iteration error creating empty CUs"));
ctf_set_errno (fp, err);
return -1;
@@ -1715,6 +1718,7 @@ ctf_link (ctf_dict_t *fp, int flags)
ctf_dynhash_empty (fp->ctf_link_type_mapping);
ctf_dynhash_iter (fp->ctf_link_outputs, empty_link_type_mapping, NULL);
+ fp->ctf_flags &= ~LCTF_LINKING;
if ((ctf_errno (fp) != 0) && (ctf_errno (fp) != ECTF_NOCTFDATA))
return -1;
return 0;
@@ -1888,6 +1892,17 @@ ctf_link_shuffle_syms (ctf_dict_t *fp)
goto err;
}
+ /* If no symbols are reported, unwind what we have done and return. This
+ makes it a bit easier for the serializer to tell that no symbols have been
+ reported and that it should look elsewhere for reported symbols. */
+ if (!ctf_dynhash_elements (fp->ctf_dynsyms))
+ {
+ ctf_dprintf ("No symbols: not a final link.\n");
+ free (fp->ctf_dynsyms);
+ fp->ctf_dynsyms = NULL;
+ return 0;
+ }
+
/* Construct a mapping from shndx to the symbol info. */
free (fp->ctf_dynsymidx);
if ((fp->ctf_dynsymidx = calloc (fp->ctf_dynsymmax + 1,
@@ -2043,6 +2058,7 @@ ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold)
char *transformed_name = NULL;
ctf_dict_t **files;
FILE *f = NULL;
+ size_t i;
int err;
long fsize;
const char *errloc;
@@ -2050,6 +2066,7 @@ ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold)
memset (&arg, 0, sizeof (ctf_name_list_accum_cb_arg_t));
arg.fp = fp;
+ fp->ctf_flags |= LCTF_LINKING;
ctf_link_warn_outdated_inputs (fp);
@@ -2065,7 +2082,11 @@ ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold)
/* No extra outputs? Just write a simple ctf_dict_t. */
if (arg.i == 0)
- return ctf_write_mem (fp, size, threshold);
+ {
+ unsigned char *ret = ctf_write_mem (fp, size, threshold);
+ fp->ctf_flags &= ~LCTF_LINKING;
+ return ret;
+ }
/* Writing an archive. Stick ourselves (the shared repository, parent of all
other archives) on the front of it with the default name. */
@@ -2093,6 +2114,13 @@ ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold)
}
}
+ /* Propagate the link flags to all the dicts in this link. */
+ for (i = 0; i < arg.i; i++)
+ {
+ arg.files[i]->ctf_link_flags = fp->ctf_link_flags;
+ arg.files[i]->ctf_flags |= LCTF_LINKING;
+ }
+
if ((files = realloc (arg.files,
sizeof (struct ctf_dict *) * (arg.i + 1))) == NULL)
{
@@ -2165,6 +2193,10 @@ ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold)
err_no:
ctf_set_errno (fp, errno);
+
+ /* Turn off the is-linking flag on all the dicts in this link. */
+ for (i = 0; i < arg.i; i++)
+ arg.files[i]->ctf_flags &= ~LCTF_LINKING;
err:
free (buf);
if (f)