aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/elf.c14
-rw-r--r--bfd/elflink.c38
-rw-r--r--binutils/ChangeLog5
-rw-r--r--binutils/readelf.c4
-rw-r--r--include/ChangeLog19
-rw-r--r--include/bfdlink.h16
-rw-r--r--include/ctf-api.h18
-rw-r--r--include/ctf.h3
-rw-r--r--ld/ChangeLog42
-rw-r--r--ld/emultempl/aix.em3
-rw-r--r--ld/emultempl/armcoff.em3
-rw-r--r--ld/emultempl/beos.em3
-rw-r--r--ld/emultempl/elf-generic.em3
-rw-r--r--ld/emultempl/elf.em3
-rw-r--r--ld/emultempl/generic.em3
-rw-r--r--ld/emultempl/linux.em3
-rw-r--r--ld/emultempl/msp430.em3
-rw-r--r--ld/emultempl/pe.em3
-rw-r--r--ld/emultempl/pep.em3
-rw-r--r--ld/emultempl/ticoff.em3
-rw-r--r--ld/emultempl/vanilla.em3
-rw-r--r--ld/ldelfgen.c110
-rw-r--r--ld/ldelfgen.h9
-rw-r--r--ld/ldemul.c18
-rw-r--r--ld/ldemul.h30
-rw-r--r--ld/ldlang.c31
-rw-r--r--ld/ldlang.h6
-rw-r--r--ld/ldmain.c4
-rw-r--r--libctf/ChangeLog13
-rw-r--r--libctf/ctf-archive.c19
-rw-r--r--libctf/ctf-create.c2
-rw-r--r--libctf/ctf-impl.h1
-rw-r--r--libctf/ctf-link.c9
-rw-r--r--libctf/ctf-open-bfd.c34
-rw-r--r--libctf/libctf.ver2
36 files changed, 363 insertions, 133 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 2aa89d0..b2553a6 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+
+ * elflink.c (elf_finalize_dynstr): Call examine_strtab after
+ dynstr finalization.
+ (elf_link_swap_symbols_out): Don't call it here. Call
+ ctf_new_symbol before swap_symbol_out.
+ (elf_link_output_extsym): Call ctf_new_dynsym before
+ swap_symbol_out.
+ (bfd_elf_final_link): Likewise.
+ * elf.c (swap_out_syms): Pass in bfd_link_info. Call
+ ctf_new_symbol before swap_symbol_out.
+ (_bfd_elf_compute_section_file_positions): Adjust.
+
2020-11-19 Nick Clifton <nickc@redhat.com>
PR 26918
diff --git a/bfd/elf.c b/bfd/elf.c
index 288548d..9624df7 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -51,7 +51,8 @@ SECTION
static int elf_sort_sections (const void *, const void *);
static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
-static bfd_boolean swap_out_syms (bfd *, struct elf_strtab_hash **, int) ;
+static bfd_boolean swap_out_syms (bfd *, struct elf_strtab_hash **, int,
+ struct bfd_link_info *);
static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
file_ptr offset, size_t align);
@@ -4302,7 +4303,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
/* Non-zero if doing a relocatable link. */
int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
- if (! swap_out_syms (abfd, &strtab, relocatable_p))
+ if (! swap_out_syms (abfd, &strtab, relocatable_p, link_info))
return FALSE;
}
@@ -8050,7 +8051,8 @@ _bfd_elf_copy_private_symbol_data (bfd *ibfd,
static bfd_boolean
swap_out_syms (bfd *abfd,
struct elf_strtab_hash **sttp,
- int relocatable_p)
+ int relocatable_p,
+ struct bfd_link_info *info)
{
const struct elf_backend_data *bed;
unsigned int symcount;
@@ -8402,6 +8404,12 @@ Unable to handle section index %x in ELF symbol. Using ABS instead."),
else
elfsym->sym.st_name = _bfd_elf_strtab_offset (stt,
elfsym->sym.st_name);
+ if (info && info->callbacks->ctf_new_symbol)
+ info->callbacks->ctf_new_symbol (elfsym->dest_index,
+ &elfsym->sym);
+
+ /* Inform the linker of the addition of this symbol. */
+
bed->s->swap_symbol_out (abfd, &elfsym->sym,
(outbound_syms
+ (elfsym->dest_index
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6cc6361..7ba667a 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -3779,6 +3779,11 @@ elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
_bfd_elf_strtab_finalize (dynstr);
size = _bfd_elf_strtab_size (dynstr);
+ /* Allow the linker to examine the dynsymtab now it's fully populated. */
+
+ if (info->callbacks->examine_strtab)
+ info->callbacks->examine_strtab (dynstr);
+
bed = get_elf_backend_data (dynobj);
sdyn = bfd_get_linker_section (dynobj, ".dynamic");
BFD_ASSERT (sdyn != NULL);
@@ -9853,6 +9858,7 @@ elf_link_swap_symbols_out (struct elf_final_link_info *flinfo)
}
}
+ /* Now swap out the symbols. */
for (i = 0; i < hash_table->strtabcount; i++)
{
struct elf_sym_strtab *elfsym = &hash_table->strtab[i];
@@ -9862,6 +9868,13 @@ elf_link_swap_symbols_out (struct elf_final_link_info *flinfo)
elfsym->sym.st_name
= (unsigned long) _bfd_elf_strtab_offset (flinfo->symstrtab,
elfsym->sym.st_name);
+
+ /* Inform the linker of the addition of this symbol. */
+
+ if (flinfo->info->callbacks->ctf_new_symbol)
+ flinfo->info->callbacks->ctf_new_symbol (elfsym->dest_index,
+ &elfsym->sym);
+
bed->s->swap_symbol_out (flinfo->output_bfd, &elfsym->sym,
((bfd_byte *) symbuf
+ (elfsym->dest_index
@@ -9870,14 +9883,6 @@ elf_link_swap_symbols_out (struct elf_final_link_info *flinfo)
+ elfsym->destshndx_index));
}
- /* Allow the linker to examine the strtab and symtab now they are
- populated. */
-
- if (flinfo->info->callbacks->examine_strtab)
- flinfo->info->callbacks->examine_strtab (hash_table->strtab,
- hash_table->strtabcount,
- flinfo->symstrtab);
-
hdr = &elf_tdata (flinfo->output_bfd)->symtab_hdr;
pos = hdr->sh_offset + hdr->sh_size;
amt = hash_table->strtabcount * bed->s->sizeof_sym;
@@ -10485,6 +10490,12 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
eoinfo->failed = TRUE;
return FALSE;
}
+
+ /* Inform the linker of the addition of this symbol. */
+
+ if (flinfo->info->callbacks->ctf_new_dynsym)
+ flinfo->info->callbacks->ctf_new_dynsym (h->dynindx, &sym);
+
bed->s->swap_symbol_out (flinfo->output_bfd, &sym, esym, 0);
if (flinfo->hash_sec != NULL)
@@ -12761,6 +12772,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
}
sym.st_value = s->vma;
dest = dynsym + dynindx * bed->s->sizeof_sym;
+
+ /* Inform the linker of the addition of this symbol. */
+
+ if (info->callbacks->ctf_new_dynsym)
+ info->callbacks->ctf_new_dynsym (dynindx, &sym);
+
bed->s->swap_symbol_out (abfd, &sym, dest, 0);
}
}
@@ -12799,6 +12816,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
+ e->isym.st_value);
}
+ /* Inform the linker of the addition of this symbol. */
+
+ if (info->callbacks->ctf_new_dynsym)
+ info->callbacks->ctf_new_dynsym (e->dynindx, &sym);
+
dest = dynsym + e->dynindx * bed->s->sizeof_sym;
bed->s->swap_symbol_out (abfd, &sym, dest, 0);
}
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 6555615..f899b6d 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,10 @@
2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+ * readelf.c (dump_section_as_ctf): Use .dynsym and .dynstr, not
+ .symtab and .strtab.
+
+2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+
* objdump.c (dump_ctf): Report errors from ctf_archive_iter.
* readelf.c (dump_section_as_ctf): Likewise.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 4d484db..e4d96bb 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -14695,10 +14695,10 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
ctfsect.cts_data = data;
if (!dump_ctf_symtab_name)
- dump_ctf_symtab_name = strdup (".symtab");
+ dump_ctf_symtab_name = strdup (".dynsym");
if (!dump_ctf_strtab_name)
- dump_ctf_strtab_name = strdup (".strtab");
+ dump_ctf_strtab_name = strdup (".dynstr");
if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
{
diff --git a/include/ChangeLog b/include/ChangeLog
index 11ec1f4..5c0f6b9 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,5 +1,24 @@
2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+ * bfdlink.h (struct elf_sym_strtab): Replace with...
+ (struct elf_internal_sym): ... this.
+ (struct bfd_link_callbacks) <examine_strtab>: Take only a
+ symstrtab argument.
+ <ctf_new_symbol>: New.
+ <ctf_new_dynsym>: Likewise.
+ * ctf-api.h (struct ctf_link_sym) <st_symidx>: New.
+ <st_nameidx>: Likewise.
+ <st_nameidx_set>: Likewise.
+ (ctf_link_iter_symbol_f): Removed.
+ (ctf_link_shuffle_syms): Remove most parameters, just takes a
+ ctf_dict_t now.
+ (ctf_link_add_linker_symbol): New, split from
+ ctf_link_shuffle_syms.
+ * ctf.h (CTF_F_DYNSTR): New.
+ (CTF_F_MAX): Adjust.
+
+2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+
* ctf-api.h (ctf_arc_open_by_name): Rename to...
(ctf_dict_open): ... this, keeping compatibility function.
(ctf_arc_open_by_name_sections): Rename to...
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 55020e3..b92ef54 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -671,7 +671,7 @@ struct bfd_link_info
/* Some forward-definitions used by some callbacks. */
struct elf_strtab_hash;
-struct elf_sym_strtab;
+struct elf_internal_sym;
/* This structures holds a set of callback functions. These are called
by the BFD linker routines. */
@@ -795,11 +795,17 @@ struct bfd_link_callbacks
asection * current_section, asection * previous_section,
bfd_boolean new_segment);
/* This callback provides a chance for callers of the BFD to examine the
- ELF string table and symbol table once they are complete and indexes and
- offsets assigned. */
+ ELF (dynamic) string table once it is complete. */
void (*examine_strtab)
- (struct elf_sym_strtab *syms, bfd_size_type symcount,
- struct elf_strtab_hash *symstrtab);
+ (struct elf_strtab_hash *symstrtab);
+ /* This callback is called just before a symbol is swapped out, so that the
+ CTF machinery can look up symbols during construction. The name is
+ already an external strtab offset at this point. */
+ void (*ctf_new_symbol)
+ (int symidx, struct elf_internal_sym *sym);
+ /* Likewise, for dynamic symbols. */
+ void (*ctf_new_dynsym)
+ (int symidx, struct elf_internal_sym *sym);
/* This callback should emit the CTF section into a non-loadable section in
the output BFD named .ctf or a name beginning with ".ctf.". */
void (*emit_ctf)
diff --git a/include/ctf-api.h b/include/ctf-api.h
index 38d7758..93bd5f3 100644
--- a/include/ctf-api.h
+++ b/include/ctf-api.h
@@ -65,14 +65,20 @@ typedef struct ctf_sect
} ctf_sect_t;
/* A minimal symbol extracted from a linker's internal symbol table
- representation. */
+ representation. The symbol name can be given either via st_name or via a
+ strtab offset in st_nameidx, which corresponds to one of the string offsets
+ communicated via the ctf_link_add_strtab callback. */
typedef struct ctf_link_sym
{
- /* The st_name will not be accessed outside the call to
- ctf_link_shuffle_syms(). */
+ /* The st_name and st_nameidx will not be accessed outside the call to
+ ctf_link_shuffle_syms(). If you set st_nameidx to offset zero, make sure
+ to set st_nameidx_set as well. */
const char *st_name;
+ size_t st_nameidx;
+ int st_nameidx_set;
+ uint32_t st_symidx;
uint32_t st_shndx;
uint32_t st_type;
uint32_t st_value;
@@ -485,10 +491,8 @@ extern int ctf_link (ctf_dict_t *, int flags);
typedef const char *ctf_link_strtab_string_f (uint32_t *offset, void *arg);
extern int ctf_link_add_strtab (ctf_dict_t *, ctf_link_strtab_string_f *,
void *);
-typedef ctf_link_sym_t *ctf_link_iter_symbol_f (ctf_link_sym_t *dest,
- void *arg);
-extern int ctf_link_shuffle_syms (ctf_dict_t *, ctf_link_iter_symbol_f *,
- void *);
+extern int ctf_link_add_linker_symbol (ctf_dict_t *, ctf_link_sym_t *);
+extern int ctf_link_shuffle_syms (ctf_dict_t *);
extern unsigned char *ctf_link_write (ctf_dict_t *, size_t *size,
size_t threshold);
diff --git a/include/ctf.h b/include/ctf.h
index 6b8aa53..d0a21f1 100644
--- a/include/ctf.h
+++ b/include/ctf.h
@@ -200,7 +200,8 @@ typedef struct ctf_header
#define CTF_VERSION CTF_VERSION_3 /* Current version. */
#define CTF_F_COMPRESS 0x1 /* Data buffer is compressed by libctf. */
-#define CTF_F_MAX CTF_F_COMPRESS /* The greatest flag value in use. */
+#define CTF_F_DYNSTR 0x8 /* Strings come from .dynstr. */
+#define CTF_F_MAX (CTF_F_COMPRESS | CTF_F_DYNSTR)
typedef struct ctf_lblent
{
diff --git a/ld/ChangeLog b/ld/ChangeLog
index a00cfe9..f8265f4 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,47 @@
2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+ * ldelfgen.c (struct ctf_strsym_iter_cb_arg): Rename to...
+ (struct ctf_strtab_iter_cb_arg): ... this, changing fields:
+ <syms>: Remove.
+ <symcount>: Remove.
+ <symstrtab>: Rename to...
+ <strtab>: ... this.
+ (ldelf_ctf_strtab_iter_cb): Adjust.
+ (ldelf_ctf_symbols_iter_cb): Remove.
+ (ldelf_new_dynsym_for_ctf): New, tell libctf about a single
+ symbol.
+ (ldelf_examine_strtab_for_ctf): Rename to...
+ (ldelf_acquire_strings_for_ctf): ... this, only doing the strtab
+ portion and not symbols.
+ * ldelfgen.h: Adjust declarations accordingly.
+ * ldemul.c (ldemul_examine_strtab_for_ctf): Rename to...
+ (ldemul_acquire_strings_for_ctf): ... this.
+ (ldemul_new_dynsym_for_ctf): New.
+ * ldemul.h: Adjust declarations accordingly.
+ * ldlang.c (ldlang_ctf_apply_strsym): Rename to...
+ (ldlang_ctf_acquire_strings): ... this.
+ (ldlang_ctf_new_dynsym): New.
+ (lang_write_ctf): Call ldemul_new_dynsym_for_ctf with NULL to do
+ the actual symbol shuffle.
+ * ldlang.h (struct elf_strtab_hash): Adjust accordingly.
+ * ldmain.c (bfd_link_callbacks): Wire up new/renamed callbacks.
+
+ * emultempl/aix.em: Adjust for emulation changes:
+ ldemul_examine_strtab_for_ctf renamed to
+ ldemul_acquire_strings_for_ctf, new ldemul_new_dynsym_for_ctf.
+ * emultempl/armcoff.em: Likewise.
+ * emultempl/beos.em: Likewise.
+ * emultempl/elf.em: Likewise.
+ * emultempl/elf-generic.em: Likewise.
+ * emultempl/linux.em: Likewise.
+ * emultempl/msp430.em: Likewise.
+ * emultempl/pe.em: Likewise.
+ * emultempl/pep.em: Likewise.
+ * emultempl/ticoff.em: Likewise.
+ * emultempl/vanilla.em: Likewise.
+
+2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+
* ldlang.c (ctf_output): This is a ctf_dict_t now.
(lang_ctf_errs_warnings): Rename ctf_file_t to ctf_dict_t.
(ldlang_open_ctf): Adjust comment.
diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em
index c1fe705..df7471b 100644
--- a/ld/emultempl/aix.em
+++ b/ld/emultempl/aix.em
@@ -1595,7 +1595,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
NULL, /* new_vers_pattern */
NULL, /* extra_map_file_text */
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
gld${EMULATION_NAME}_print_symbol
};
EOF
diff --git a/ld/emultempl/armcoff.em b/ld/emultempl/armcoff.em
index ff22af4..3a86af9 100644
--- a/ld/emultempl/armcoff.em
+++ b/ld/emultempl/armcoff.em
@@ -286,7 +286,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
NULL, /* new_vers_pattern */
NULL, /* extra_map_file_text */
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF
diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em
index ace6e3a..d025f21 100644
--- a/ld/emultempl/beos.em
+++ b/ld/emultempl/beos.em
@@ -768,7 +768,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
NULL, /* new_vers_pattern */
NULL, /* extra_map_file_text */
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF
diff --git a/ld/emultempl/elf-generic.em b/ld/emultempl/elf-generic.em
index 7e0923b..a404148 100644
--- a/ld/emultempl/elf-generic.em
+++ b/ld/emultempl/elf-generic.em
@@ -28,4 +28,5 @@ EOF
# Put these extra routines in ld${EMULATION_NAME}_emulation
#
LDEMUL_EMIT_CTF_EARLY=ldelf_emit_ctf_early
-LDEMUL_EXAMINE_STRTAB_FOR_CTF=ldelf_examine_strtab_for_ctf
+LDEMUL_ACQUIRE_STRINGS_FOR_CTF=ldelf_acquire_strings_for_ctf
+LDEMUL_NEW_DYNSYM_FOR_CTF=ldelf_new_dynsym_for_ctf
diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
index 59eed70..cfdf60e 100644
--- a/ld/emultempl/elf.em
+++ b/ld/emultempl/elf.em
@@ -931,7 +931,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
${LDEMUL_NEW_VERS_PATTERN-NULL},
${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL},
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF
diff --git a/ld/emultempl/generic.em b/ld/emultempl/generic.em
index 24d3c1d..5a69c01 100644
--- a/ld/emultempl/generic.em
+++ b/ld/emultempl/generic.em
@@ -161,7 +161,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
${LDEMUL_NEW_VERS_PATTERN-NULL},
${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL},
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF
diff --git a/ld/emultempl/linux.em b/ld/emultempl/linux.em
index 1444610..0cff374 100644
--- a/ld/emultempl/linux.em
+++ b/ld/emultempl/linux.em
@@ -219,7 +219,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
NULL, /* new_vers_pattern */
NULL, /* extra_map_file_text */
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF
diff --git a/ld/emultempl/msp430.em b/ld/emultempl/msp430.em
index 7b78a53..31cba4a 100644
--- a/ld/emultempl/msp430.em
+++ b/ld/emultempl/msp430.em
@@ -936,7 +936,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
${LDEMUL_NEW_VERS_PATTERN-NULL},
${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL},
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 00db3d0..e07dc9c 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -2415,7 +2415,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
NULL, /* new_vers_pattern. */
NULL, /* extra_map_file_text. */
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 2f4bdfb..74468be 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -2235,7 +2235,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
NULL, /* new_vers_pattern. */
NULL, /* extra_map_file_text */
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF
diff --git a/ld/emultempl/ticoff.em b/ld/emultempl/ticoff.em
index 11ddd0c..1cf82be 100644
--- a/ld/emultempl/ticoff.em
+++ b/ld/emultempl/ticoff.em
@@ -186,7 +186,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
NULL, /* new_vers_pattern */
NULL, /* extra_map_file_text */
${LDEMUL_EMIT_CTF_EARLY-NULL},
- ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+ ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF
diff --git a/ld/emultempl/vanilla.em b/ld/emultempl/vanilla.em
index 70d193c..324e38a 100644
--- a/ld/emultempl/vanilla.em
+++ b/ld/emultempl/vanilla.em
@@ -87,7 +87,8 @@ struct ld_emulation_xfer_struct ld_vanilla_emulation =
NULL, /* new_vers_pattern */
NULL, /* extra_map_file_text */
NULL, /* emit_ctf_early */
- NULL, /* examine_strtab_for_ctf */
+ NULL, /* acquire_strings_for_ctf */
+ NULL, /* new_dynsym_for_ctf */
NULL /* print_symbol */
};
EOF
diff --git a/ld/ldelfgen.c b/ld/ldelfgen.c
index e9496f9..ca531ee 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
diff --git a/ld/ldelfgen.h b/ld/ldelfgen.h
index 93bdf29..3392c2b 100644
--- a/ld/ldelfgen.h
+++ b/ld/ldelfgen.h
@@ -18,12 +18,13 @@
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
-struct elf_sym_strtab;
+struct elf_internal_sym;
struct elf_strtab_hash;
struct ctf_dict;
extern void ldelf_map_segments (bfd_boolean);
extern int ldelf_emit_ctf_early (void);
-extern 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);
+extern void ldelf_acquire_strings_for_ctf
+ (struct ctf_dict *ctf_output, struct elf_strtab_hash *strtab);
+extern void ldelf_new_dynsym_for_ctf
+ (struct ctf_dict *ctf_output, int symidx, struct elf_internal_sym *sym);
diff --git a/ld/ldemul.c b/ld/ldemul.c
index 6dc5112..920afc8 100644
--- a/ld/ldemul.c
+++ b/ld/ldemul.c
@@ -418,15 +418,19 @@ ldemul_emit_ctf_early (void)
}
void
-ldemul_examine_strtab_for_ctf (struct ctf_dict *ctf_output,
- struct elf_sym_strtab *syms,
- bfd_size_type symcount,
- struct elf_strtab_hash *symstrtab)
+ldemul_acquire_strings_for_ctf (struct ctf_dict *ctf_output,
+ struct elf_strtab_hash *symstrtab)
+{
+ if (ld_emulation->acquire_strings_for_ctf)
+ ld_emulation->acquire_strings_for_ctf (ctf_output, symstrtab);
+}
+void
+ldemul_new_dynsym_for_ctf (struct ctf_dict *ctf_output, int symidx,
+ struct elf_internal_sym *sym)
{
- if (ld_emulation->examine_strtab_for_ctf)
- ld_emulation->examine_strtab_for_ctf (ctf_output, syms,
- symcount, symstrtab);
+ if (ld_emulation->new_dynsym_for_ctf)
+ ld_emulation->new_dynsym_for_ctf (ctf_output, symidx, sym);
}
bfd_boolean
diff --git a/ld/ldemul.h b/ld/ldemul.h
index 5efe4aa..0b9653e 100644
--- a/ld/ldemul.h
+++ b/ld/ldemul.h
@@ -109,9 +109,11 @@ extern void ldemul_extra_map_file_text
extern int ldemul_emit_ctf_early
(void);
/* Called from per-target code to examine the strtab and symtab. */
-extern void ldemul_examine_strtab_for_ctf
- (struct ctf_dict *, struct elf_sym_strtab *, bfd_size_type,
- struct elf_strtab_hash *);
+extern void ldemul_acquire_strings_for_ctf
+ (struct ctf_dict *, struct elf_strtab_hash *);
+extern void ldemul_new_dynsym_for_ctf
+ (struct ctf_dict *, int symidx, struct elf_internal_sym *);
+
extern bfd_boolean ldemul_print_symbol
(struct bfd_link_hash_entry *hash_entry, void *ptr);
@@ -230,14 +232,22 @@ typedef struct ld_emulation_xfer_struct {
int (*emit_ctf_early)
(void);
- /* Called to examine the string and symbol table late enough in linking that
- they are finally laid out. If emit_ctf_early returns true, this is not
- called and ldemul_maybe_emit_ctf() emits CTF in 'early' mode: otherwise, it
- waits until 'late'. (Late mode needs explicit support at per-target link
- time to get called at all). If set, called by ld when the examine_strtab
+ /* Called to examine the string table late enough in linking that it is
+ finally laid out. If emit_ctf_early returns true, this is not called, and
+ ldemul_maybe_emit_ctf emits CTF in 'early' mode: otherwise, it waits
+ until 'late'. (Late mode needs explicit support at per-target link time to
+ get called at all). If set, called by ld when the examine_strtab
bfd_link_callback is invoked by per-target code. */
- void (*examine_strtab_for_ctf) (struct ctf_dict *, struct elf_sym_strtab *,
- bfd_size_type, struct elf_strtab_hash *);
+ void (*acquire_strings_for_ctf) (struct ctf_dict *, struct elf_strtab_hash *);
+
+ /* Called when a new symbol is added to the dynamic symbol table. If
+ emit_ctf_early returns true, this is not called, and ldemul_maybe_emit_ctf
+ emits CTF in 'early' mode: otherwise, it waits until 'late'. (Late mode
+ needs explicit support at per-target link time to get called at all). If
+ set, called by ld when the ctf_new_symbol bfd_link_callback is invoked by
+ per-target code. Called with a NULL symbol when no further symbols will be
+ provided. */
+ void (*new_dynsym_for_ctf) (struct ctf_dict *, int, struct elf_internal_sym *);
/* Called when printing a symbol to the map file. AIX uses this
hook to flag gc'd symbols. */
diff --git a/ld/ldlang.c b/ld/ldlang.c
index eaf90a6..b70937a 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3826,14 +3826,20 @@ lang_merge_ctf (void)
lang_ctf_errs_warnings (ctf_output);
}
-/* Let the emulation examine the symbol table and strtab to help it optimize the
- CTF, if supported. */
+/* Let the emulation acquire strings from the dynamic strtab to help it optimize
+ the CTF, if supported. */
void
-ldlang_ctf_apply_strsym (struct elf_sym_strtab *syms, bfd_size_type symcount,
- struct elf_strtab_hash *symstrtab)
+ldlang_ctf_acquire_strings (struct elf_strtab_hash *dynstrtab)
{
- ldemul_examine_strtab_for_ctf (ctf_output, syms, symcount, symstrtab);
+ ldemul_acquire_strings_for_ctf (ctf_output, dynstrtab);
+}
+
+/* Inform the emulation about the addition of a new dynamic symbol, in BFD
+ internal format. */
+void ldlang_ctf_new_dynsym (int symidx, struct elf_internal_sym *sym)
+{
+ ldemul_new_dynsym_for_ctf (ctf_output, symidx, sym);
}
/* Write out the CTF section. Called early, if the emulation isn't going to
@@ -3860,6 +3866,11 @@ lang_write_ctf (int late)
return;
}
+ /* Inform the emulation that all the symbols that will be received have
+ been. */
+
+ ldemul_new_dynsym_for_ctf (ctf_output, 0, NULL);
+
/* Emit CTF. */
output_sect = bfd_get_section_by_name (link_info.output_bfd, ".ctf");
@@ -3922,11 +3933,11 @@ ldlang_open_ctf (void)
static void lang_merge_ctf (void) {}
void
-ldlang_ctf_apply_strsym (struct elf_sym_strtab *syms ATTRIBUTE_UNUSED,
- bfd_size_type symcount ATTRIBUTE_UNUSED,
- struct elf_strtab_hash *symstrtab ATTRIBUTE_UNUSED)
-{
-}
+ldlang_ctf_acquire_strings (struct elf_strtab_hash *dynstrtab
+ ATTRIBUTE_UNUSED) {}
+void
+ldlang_ctf_new_dynsym (int symidx ATTRIBUTE_UNUSED,
+ struct elf_internal_sym *sym ATTRIBUTE_UNUSED) {}
static void lang_write_ctf (int late ATTRIBUTE_UNUSED) {}
void ldlang_write_ctf_late (void) {}
#endif
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 196debf..6675c57 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -689,8 +689,10 @@ extern bfd_boolean load_symbols
struct elf_sym_strtab;
struct elf_strtab_hash;
-extern void ldlang_ctf_apply_strsym
- (struct elf_sym_strtab *, bfd_size_type, struct elf_strtab_hash *);
+extern void ldlang_ctf_acquire_strings
+ (struct elf_strtab_hash *);
+extern void ldlang_ctf_new_dynsym
+ (int symidx, struct elf_internal_sym *);
extern void ldlang_write_ctf_late
(void);
extern bfd_boolean
diff --git a/ld/ldmain.c b/ld/ldmain.c
index cc3df76..f8a03c6 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -151,7 +151,9 @@ static struct bfd_link_callbacks link_callbacks =
info_msg,
minfo,
ldlang_override_segment_assignment,
- ldlang_ctf_apply_strsym,
+ ldlang_ctf_acquire_strings,
+ NULL,
+ ldlang_ctf_new_dynsym,
ldlang_write_ctf_late
};
diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index 804f131..6670a6a 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,18 @@
2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+ * ctf-link.c (ctf_link_shuffle_syms): Adjust.
+ (ctf_link_add_linker_symbol): New, unimplemented stub.
+ * libctf.ver: Add it.
+ * ctf-create.c (ctf_serialize): Set CTF_F_DYNSTR on newly-serialized
+ dicts.
+ * ctf-open-bfd.c (ctf_bfdopen_ctfsect): Check for the flag: open the
+ symtab/strtab if not present, dynsym/dynstr otherwise.
+ * ctf-archive.c (ctf_arc_bufpreamble): New, get the preamble from
+ some arbitrary member of a CTF archive.
+ * ctf-impl.h (ctf_arc_bufpreamble): Declare it.
+
+2020-11-20 Nick Alcock <nick.alcock@oracle.com>
+
* ctf-archive.c (ctf_arc_open_by_offset): Rename to...
(ctf_dict_open_by_offset): ... this. Adjust callers.
(ctf_arc_open_by_name_internal): Rename to...
diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c
index 72cdef9..25c30f6 100644
--- a/libctf/ctf-archive.c
+++ b/libctf/ctf-archive.c
@@ -377,6 +377,25 @@ ctf_new_archive_internal (int is_archive, int unmap_on_close,
return arci;
}
+/* Get the CTF preamble from data in a buffer, which may be either an archive or
+ a CTF dict. If multiple dicts are present in an archive, the preamble comes
+ from an arbitrary dict. The preamble is a pointer into the ctfsect passed
+ in. */
+
+const ctf_preamble_t *
+ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
+{
+ if (ctfsect->cts_size > sizeof (uint64_t) &&
+ (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
+ {
+ struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
+ return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
+ + sizeof (uint64_t));
+ }
+ else
+ return (const ctf_preamble_t *) ctfsect->cts_data;
+}
+
/* Open a CTF archive or dictionary from data in a buffer (which the caller must
preserve until ctf_arc_close() time). Returns the archive, or NULL and an
error in *err (if not NULL). */
diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c
index c1a7a8a..384e8cf 100644
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -298,6 +298,8 @@ ctf_serialize (ctf_dict_t *fp)
hdr.cth_magic = CTF_MAGIC;
hdr.cth_version = CTF_VERSION;
+ hdr.cth_flags = CTF_F_DYNSTR;
+
/* Iterate through the dynamic type definition list and compute the
size of the CTF type section we will need to generate. */
diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h
index 3f4cfac..0e09a45 100644
--- a/libctf/ctf-impl.h
+++ b/libctf/ctf-impl.h
@@ -683,6 +683,7 @@ ctf_new_archive_internal (int is_archive, int unmap_on_close,
const ctf_sect_t *strsect, int *errp);
extern struct ctf_archive *ctf_arc_open_internal (const char *, int *);
extern void ctf_arc_close_internal (struct ctf_archive *);
+extern const ctf_preamble_t *ctf_arc_bufpreamble (const ctf_sect_t *);
extern void *ctf_set_open_errno (int *, int);
extern unsigned long ctf_set_errno (ctf_dict_t *, int);
diff --git a/libctf/ctf-link.c b/libctf/ctf-link.c
index 192d4fd..3f4f2ee 100644
--- a/libctf/ctf-link.c
+++ b/libctf/ctf-link.c
@@ -1596,9 +1596,12 @@ ctf_link_add_strtab (ctf_dict_t *fp, ctf_link_strtab_string_f *add_string,
/* Not yet implemented. */
int
-ctf_link_shuffle_syms (ctf_dict_t *fp _libctf_unused_,
- ctf_link_iter_symbol_f *add_sym _libctf_unused_,
- void *arg _libctf_unused_)
+ctf_link_add_linker_symbol (ctf_dict_t *fp, ctf_link_sym_t *sym)
+{
+ return 0;
+}
+int
+ctf_link_shuffle_syms (ctf_dict_t *fp)
{
return 0;
}
diff --git a/libctf/ctf-open-bfd.c b/libctf/ctf-open-bfd.c
index 449347e..a6f0d3f 100644
--- a/libctf/ctf-open-bfd.c
+++ b/libctf/ctf-open-bfd.c
@@ -100,12 +100,36 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
#ifdef HAVE_BFD_ELF
ctf_sect_t symsect, strsect;
- Elf_Internal_Shdr *symhdr = &elf_symtab_hdr (abfd);
+ Elf_Internal_Shdr *symhdr;
size_t symcount;
Elf_Internal_Sym *isymbuf;
bfd_byte *symtab = NULL;
+ const char *symtab_name;
const char *strtab = NULL;
+ const char *strtab_name;
size_t strsize;
+ const ctf_preamble_t *preamble;
+
+ if (ctfsect->cts_data == NULL)
+ {
+ bfderrstr = N_("CTF section is NULL");
+ goto err;
+ }
+ preamble = ctf_arc_bufpreamble (ctfsect);
+
+ if (preamble->ctp_flags & CTF_F_DYNSTR)
+ {
+ symhdr = &elf_tdata (abfd)->dynsymtab_hdr;
+ strtab_name = ".dynstr";
+ symtab_name = ".dynsym";
+ }
+ else
+ {
+ symhdr = &elf_tdata (abfd)->symtab_hdr;
+ strtab_name = ".strtab";
+ symtab_name = ".symtab";
+ }
+
/* TODO: handle SYMTAB_SHNDX. */
/* Get the symtab, and the strtab associated with it. */
@@ -145,12 +169,12 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
strtab = (const char *) strhdr->contents;
}
}
- else /* No symtab: just try getting .strtab by name. */
+ else /* No symtab: just try getting .strtab or .dynstr by name. */
{
bfd_byte *str_bcontents;
asection *str_asect;
- if ((str_asect = bfd_get_section_by_name (abfd, ".strtab")) != NULL)
+ if ((str_asect = bfd_get_section_by_name (abfd, strtab_name)) != NULL)
{
if (bfd_malloc_and_get_section (abfd, str_asect, &str_bcontents))
{
@@ -168,7 +192,7 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
use it for anything but debugging. */
strsect.cts_data = strtab;
- strsect.cts_name = ".strtab";
+ strsect.cts_name = strtab_name;
strsect.cts_size = strsize;
strsectp = &strsect;
}
@@ -176,7 +200,7 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
if (symtab)
{
assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym);
- symsect.cts_name = ".symtab";
+ symsect.cts_name = symtab_name;
symsect.cts_entsize = symhdr->sh_entsize;
symsect.cts_size = symhdr->sh_size;
symsect.cts_data = symtab;
diff --git a/libctf/libctf.ver b/libctf/libctf.ver
index cf4fa73..317913e 100644
--- a/libctf/libctf.ver
+++ b/libctf/libctf.ver
@@ -181,4 +181,6 @@ LIBCTF_1.1 {
ctf_dict_open_sections;
ctf_dict_close;
ctf_parent_dict;
+
+ ctf_link_add_linker_symbol;
} LIBCTF_1.0;