summaryrefslogtreecommitdiff
path: root/ld/ldelfgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'ld/ldelfgen.c')
-rw-r--r--ld/ldelfgen.c110
1 files changed, 57 insertions, 53 deletions
diff --git a/ld/ldelfgen.c b/ld/ldelfgen.c
index e9496f918f5..ca531ee7cfe 100644
--- a/ld/ldelfgen.c
+++ b/ld/ldelfgen.c
@@ -28,6 +28,7 @@
#include "ldexp.h"
#include "ldlang.h"
#include "elf-bfd.h"
+#include "elf/internal.h"
#include "ldelfgen.h"
void
@@ -103,11 +104,9 @@ ldelf_emit_ctf_early (void)
/* Callbacks used to map from bfd types to libctf types, under libctf's
control. */
-struct ctf_strsym_iter_cb_arg
+struct ctf_strtab_iter_cb_arg
{
- struct elf_sym_strtab *syms;
- bfd_size_type symcount;
- struct elf_strtab_hash *symstrtab;
+ struct elf_strtab_hash *strtab;
size_t next_i;
size_t next_idx;
};
@@ -121,20 +120,20 @@ ldelf_ctf_strtab_iter_cb (uint32_t *offset, void *arg_)
bfd_size_type off;
const char *ret;
- struct ctf_strsym_iter_cb_arg *arg =
- (struct ctf_strsym_iter_cb_arg *) arg_;
+ struct ctf_strtab_iter_cb_arg *arg =
+ (struct ctf_strtab_iter_cb_arg *) arg_;
/* There is no zeroth string. */
if (arg->next_i == 0)
arg->next_i = 1;
- if (arg->next_i >= _bfd_elf_strtab_len (arg->symstrtab))
+ if (arg->next_i >= _bfd_elf_strtab_len (arg->strtab))
{
arg->next_i = 0;
return NULL;
}
- ret = _bfd_elf_strtab_str (arg->symstrtab, arg->next_i++, &off);
+ ret = _bfd_elf_strtab_str (arg->strtab, arg->next_i++, &off);
*offset = off;
/* If we've overflowed, we cannot share any further strings: the CTF
@@ -145,69 +144,74 @@ ldelf_ctf_strtab_iter_cb (uint32_t *offset, void *arg_)
return ret;
}
-/* Return symbols from the symbol table to libctf, one by one. We assume (and
- assert) that the symbols in the elf_link_hash_table are in strictly ascending
- order, and that none will be added in between existing ones. Returns NULL
- when iteration is complete. */
-
-static struct ctf_link_sym *
-ldelf_ctf_symbols_iter_cb (struct ctf_link_sym *dest,
- void *arg_)
+void
+ldelf_acquire_strings_for_ctf
+ (struct ctf_dict *ctf_output, struct elf_strtab_hash *strtab)
{
- struct ctf_strsym_iter_cb_arg *arg =
- (struct ctf_strsym_iter_cb_arg *) arg_;
+ struct ctf_strtab_iter_cb_arg args = { strtab, 0, 0 };
+ if (!ctf_output)
+ return;
- if (arg->next_i > arg->symcount)
+ if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
{
- arg->next_i = 0;
- arg->next_idx = 0;
- return NULL;
+ if (ctf_link_add_strtab (ctf_output, ldelf_ctf_strtab_iter_cb,
+ &args) < 0)
+ einfo (_("%F%P: warning: CTF strtab association failed; strings will "
+ "not be shared: %s\n"),
+ ctf_errmsg (ctf_errno (ctf_output)));
}
-
- ASSERT (arg->syms[arg->next_i].dest_index == arg->next_idx);
- dest->st_name = _bfd_elf_strtab_str (arg->symstrtab, arg->next_i, NULL);
- dest->st_shndx = arg->syms[arg->next_i].sym.st_shndx;
- dest->st_type = ELF_ST_TYPE (arg->syms[arg->next_i].sym.st_info);
- dest->st_value = arg->syms[arg->next_i].sym.st_value;
- arg->next_i++;
- return dest;
}
void
-ldelf_examine_strtab_for_ctf
- (struct ctf_dict *ctf_output, struct elf_sym_strtab *syms,
- bfd_size_type symcount, struct elf_strtab_hash *symstrtab)
+ldelf_new_dynsym_for_ctf (struct ctf_dict *ctf_output, int symidx,
+ struct elf_internal_sym *sym)
{
- struct ctf_strsym_iter_cb_arg args = { syms, symcount, symstrtab,
- 0, 0 };
- if (!ctf_output)
+ ctf_link_sym_t lsym;
+
+ if (!ctf_output)
return;
- if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
- && !bfd_link_relocatable (&link_info))
+ /* New symbol. */
+ if (sym != NULL)
{
- if (ctf_link_add_strtab (ctf_output, ldelf_ctf_strtab_iter_cb,
- &args) < 0)
- einfo (_("%F%P: warning: CTF strtab association failed; strings will "
- "not be shared: %s\n"),
- ctf_errmsg (ctf_errno (ctf_output)));
+ lsym.st_name = NULL;
+ lsym.st_nameidx = sym->st_name;
+ lsym.st_nameidx_set = 1;
+ lsym.st_symidx = symidx;
+ lsym.st_shndx = sym->st_shndx;
+ lsym.st_type = ELF_ST_TYPE (sym->st_info);
+ lsym.st_value = sym->st_value;
+ if (ctf_link_add_linker_symbol (ctf_output, &lsym) < 0)
+ {
+ einfo (_("%F%P: warning: CTF symbol addition failed; CTF will "
+ "not be tied to symbols: %s\n"),
+ ctf_errmsg (ctf_errno (ctf_output)));
+ }
+ }
+ else
+ {
+ /* Shuffle all the symbols. */
- if (ctf_link_shuffle_syms (ctf_output, ldelf_ctf_symbols_iter_cb,
- &args) < 0)
- einfo (_("%F%P: warning: CTF symbol shuffling failed; slight space "
- "cost: %s\n"), ctf_errmsg (ctf_errno (ctf_output)));
+ if (ctf_link_shuffle_syms (ctf_output) < 0)
+ einfo (_("%F%P: warning: CTF symbol shuffling failed; CTF will "
+ "not be tied to symbols: %s\n"),
+ ctf_errmsg (ctf_errno (ctf_output)));
}
}
#else
-extern int ldelf_emit_ctf_early (void)
+int
+ldelf_emit_ctf_early (void)
{
return 0;
}
-extern void ldelf_examine_strtab_for_ctf
- (struct ctf_dict *ctf_output ATTRIBUTE_UNUSED,
- struct elf_sym_strtab *syms ATTRIBUTE_UNUSED,
- bfd_size_type symcount ATTRIBUTE_UNUSED,
- struct elf_strtab_hash *symstrtab ATTRIBUTE_UNUSED)
+void
+ldelf_acquire_strings_for_ctf (struct ctf_dict *ctf_output ATTRIBUTE_UNUSED,
+ struct elf_strtab_hash *strtab ATTRIBUTE_UNUSED)
+{}
+void
+ldelf_new_dynsym_for_ctf (struct ctf_dict *ctf_output ATTRIBUTE_UNUSED,
+ int symidx ATTRIBUTE_UNUSED,
+ struct elf_internal_sym *sym ATTRIBUTE_UNUSED)
{}
#endif