Fix pthread_setname_np build error
[deliverable/binutils-gdb.git] / ld / ldelfgen.c
index 98bcecd89fce8f2c0ca85422ce438df08727ddd5..682872f9dcad6e596269804b5b3f7f08036c2af9 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "sysdep.h"
 #include "bfd.h"
+#include "bfdlink.h"
+#include "ctf-api.h"
 #include "ld.h"
 #include "ldmain.h"
 #include "ldmisc.h"
@@ -72,3 +74,113 @@ ldelf_map_segments (bfd_boolean need_layout)
   if (tries == 0)
     einfo (_("%F%P: looping in map_segments"));
 }
+
+/* We want to emit CTF early if and only if we are not targetting ELF with this
+   invocation.  */
+
+int
+ldelf_emit_ctf_early (void)
+{
+  if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
+    return 0;
+  return 1;
+}
+
+/* Callbacks used to map from bfd types to libctf types, under libctf's
+   control.  */
+
+struct ctf_strsym_iter_cb_arg
+{
+  struct elf_sym_strtab *syms;
+  bfd_size_type symcount;
+  struct elf_strtab_hash *symstrtab;
+  size_t next_i;
+  size_t next_idx;
+};
+
+/* Return strings from the strtab to libctf, one by one.  Returns NULL when
+   iteration is complete.  */
+
+static const char *
+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_;
+
+  /* There is no zeroth string.  */
+  if (arg->next_i == 0)
+    arg->next_i = 1;
+
+  if (arg->next_i >= _bfd_elf_strtab_len (arg->symstrtab))
+    {
+      arg->next_i = 0;
+      return NULL;
+    }
+
+  ret = _bfd_elf_strtab_str (arg->symstrtab, arg->next_i++, &off);
+  *offset = off;
+
+  /* If we've overflowed, we cannot share any further strings: the CTF
+     format cannot encode strings with such high offsets.  */
+  if (*offset != off)
+    return NULL;
+
+  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_)
+{
+  struct ctf_strsym_iter_cb_arg *arg =
+    (struct ctf_strsym_iter_cb_arg *) arg_;
+
+  if (arg->next_i > arg->symcount)
+    {
+      arg->next_i = 0;
+      arg->next_idx = 0;
+      return NULL;
+    }
+
+  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_file *ctf_output, struct elf_sym_strtab *syms,
+   bfd_size_type symcount, struct elf_strtab_hash *symstrtab)
+{
+  struct ctf_strsym_iter_cb_arg args = { syms, symcount, symstrtab,
+                                         0, 0 };
+   if (!ctf_output)
+     return;
+
+   if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
+       && !bfd_link_relocatable (&link_info))
+    {
+      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)));
+
+      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)));
+    }
+}
This page took 0.024347 seconds and 4 git commands to generate.