extern "C" {
#endif
+#ifndef ATTRIBUTE_HIDDEN
+#if HAVE_HIDDEN
+#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
+#else
+#define ATTRIBUTE_HIDDEN
+#endif
+#endif
+
/* The number of entries in a section is its size divided by the size
of a single entry. This is normally only applicable to reloc and
symbol table sections.
extern struct elf_link_hash_entry * _bfd_elf_get_link_hash_entry
(struct elf_link_hash_entry **, unsigned int, Elf_Internal_Shdr *);
+extern struct bfd_link_info *_bfd_elf_get_link_info (bfd *)
+ ATTRIBUTE_HIDDEN;
+
/* Large common section. */
extern asection _bfd_elf_large_com_section;
|| (H)->start_stop \
|| ((INFO)->dynamic && !(H)->dynamic)))
-/* Determine if a section contains CTF data, using its name. */
+/* Determine if a section contains data deduplicable using the libctf
+ deduplicator, using its name. */
static inline bool
-bfd_section_is_ctf (const asection *sec)
+bfd_section_is_libctf_deduppable (const asection *sec)
{
const char *name = bfd_section_name (sec);
- return startswith (name, ".ctf") && (name[4] == 0 || name[4] == '.');
+ struct bfd_link_info *info;
+
+ info = _bfd_elf_get_link_info (sec->owner);
+
+ if (!info || info->ctf_disabled)
+ return false;
+
+ return (startswith (name, ".ctf") || startswith (name, ".BTF"))
+ && (name[4] == 0 || name[4] == '.');
}
#ifdef __cplusplus
static const struct bfd_elf_special_section special_sections_b[] =
{
+ { STRING_COMMA_LEN (".BTF"), 0, SHT_PROGBITS, 0 },
{ STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
{ NULL, 0, 0, 0, 0 }
};
|| (abfd->is_linker_output
&& hdr->bfd_section != NULL
&& (hdr->sh_name == -1u
- || bfd_section_is_ctf (hdr->bfd_section)))
+ || bfd_section_is_libctf_deduppable (hdr->bfd_section)))
|| hdr == i_shdrpp[elf_onesymtab (abfd)]
|| (elf_symtab_shndx_list (abfd) != NULL
&& hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx])
VMAs must be known before this is called.
Reloc sections come in two flavours: Those processed specially as
- "side-channel" data attached to a section to which they apply, and
- those that bfd doesn't process as relocations. The latter sort are
- stored in a normal bfd section by bfd_section_from_shdr. We don't
- consider the former sort here, unless they form part of the loadable
- image. Reloc sections not assigned here (and compressed debugging
- sections and CTF sections which nothing else in the file can rely
- upon) will be handled later by assign_file_positions_for_relocs.
+ "side-channel" data attached to a section to which they apply, and those
+ that bfd doesn't process as relocations. The latter sort are stored in a
+ normal bfd section by bfd_section_from_shdr. We don't consider the
+ former sort here, unless they form part of the loadable image. Reloc
+ sections not assigned here (and compressed debugging sections and CTF or
+ BTF sections which nothing else in the file can rely upon) will be
+ handled later by assign_file_positions_for_relocs.
+
+ XXX UPTODO BTF sections can be depended upon by other sections: what to do
+ about them?
We also don't set the positions of the .symtab and .strtab here. */
|| (abfd->is_linker_output
&& hdr->bfd_section != NULL
&& (hdr->sh_name == -1u
- || bfd_section_is_ctf (hdr->bfd_section)))
+ || bfd_section_is_libctf_deduppable (hdr->bfd_section)))
|| i == elf_onesymtab (abfd)
|| (elf_symtab_shndx_list (abfd) != NULL
&& hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx])
|| shdrp->sh_type == SHT_REL
|| shdrp->sh_type == SHT_RELA)
;
- else if (bfd_section_is_ctf (sec))
+ else if (bfd_section_is_libctf_deduppable (sec))
{
/* Update section size and contents. */
shdrp->sh_size = sec->size;
if (elfsym->sym.st_name != 0)
elfsym->sym.st_name = _bfd_elf_strtab_offset (stt,
elfsym->sym.st_name);
- if (info && info->callbacks->ctf_new_symbol)
+ if (info && info->callbacks->ctf_new_symbol && !info->ctf_disabled)
info->callbacks->ctf_new_symbol (elfsym->dest_index,
&elfsym->sym);
{
unsigned char *contents;
- if (bfd_section_is_ctf (section))
+ if (bfd_section_is_libctf_deduppable (section))
/* Nothing to do with this section: the contents are generated
later. */
return true;
return get_link_hash_entry (sym_hashes, symndx, symtab_hdr->sh_info);
}
+struct bfd_link_info *
+_bfd_elf_get_link_info (bfd *abfd)
+{
+ return _bfd_get_link_info (abfd);
+}
+
static struct elf_link_hash_entry *
get_ext_sym_hash_from_cookie (struct elf_reloc_cookie *cookie, unsigned long r_symndx)
{
/* Inform the linker of the addition of this symbol. */
- if (flinfo->info->callbacks->ctf_new_symbol)
+ if (flinfo->info->callbacks->ctf_new_symbol
+ && !flinfo->info->ctf_disabled)
flinfo->info->callbacks->ctf_new_symbol (elfsym->dest_index,
&elfsym->sym);
/* Inform the linker of the addition of this symbol. */
- if (flinfo->info->callbacks->ctf_new_dynsym)
+ if (flinfo->info->callbacks->ctf_new_dynsym
+ && !flinfo->info->ctf_disabled)
flinfo->info->callbacks->ctf_new_dynsym (h->dynindx, &sym);
bed->s->swap_symbol_out (flinfo->output_bfd, &sym, esym, 0);
esdo->rela.count = 0;
if ((esdo->this_hdr.sh_offset == (file_ptr) -1)
- && !bfd_section_is_ctf (o))
+ && !bfd_section_is_libctf_deduppable (o))
{
/* Cache the section contents so that they can be compressed
later. Use bfd_malloc since it will be freed by
/* Inform the linker of the addition of this symbol. */
- if (info->callbacks->ctf_new_dynsym)
+ if (info->callbacks->ctf_new_dynsym && !info->ctf_disabled)
info->callbacks->ctf_new_dynsym (dynindx, &sym);
bed->s->swap_symbol_out (abfd, &sym, dest, 0);
/* Inform the linker of the addition of this symbol. */
- if (info->callbacks->ctf_new_dynsym)
+ if (info->callbacks->ctf_new_dynsym && !info->ctf_disabled)
info->callbacks->ctf_new_dynsym (e->dynindx, &sym);
dest = dynsym + e->dynindx * bed->s->sizeof_sym;
if (! _bfd_elf_write_section_sframe (abfd, info))
goto error_return;
- if (info->callbacks->emit_ctf)
+ if (info->callbacks->emit_ctf && !info->ctf_disabled)
info->callbacks->emit_ctf ();
elf_final_link_free (abfd, &flinfo);
/* TRUE if commonpagesize is set on command-line. */
unsigned int commonpagesize_is_set : 1;
+ /* TRUE if BTF and CTF linking are disabled. */
+ unsigned int ctf_disabled : 1;
+
/* Char that may appear as the first char of a symbol, but should be
skipped (like symbol_leading_char) when looking up symbols in
wrap_hash. Used by PowerPC Linux for 'dot' symbols. */
consumer at runtime.
@end table
+@kindex --disable-ctf-dedup
+@kindex --disable-ctf-dedup
+@item --disable-ctf-dedup
+Disable CTF and BTF deduplication entirely. The input sections are concatenated
+just like any other section. Note that concatenated CTF and BTF sections are
+not in general useful: libctf and other consumers will typically read the first
+portion and ignore any subsequent portions. Nonetheless, this is sometimes
+useful in special circumstances, such as when the section's format is not
+actually that of a CTF or BTF section but merely shares the same name.
+
@cindex common allocation
@kindex --no-define-common
@item --no-define-common
int any_ctf = 0;
int err;
+ if (link_info.ctf_disabled)
+ return;
+
LANG_FOR_EACH_INPUT_STATEMENT (file)
{
asection *sect;
void
ldlang_ctf_acquire_strings (struct elf_strtab_hash *dynstrtab)
{
- ldemul_acquire_strings_for_ctf (ctf_output, dynstrtab);
+ if (!link_info.ctf_disabled)
+ 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);
+ if (!link_info.ctf_disabled)
+ ldemul_new_dynsym_for_ctf (ctf_output, symidx, sym);
}
/* Write out the CTF section. Called early, if the emulation isn't going to
static void
ldlang_open_ctf (void)
{
+ if (link_info.ctf_disabled)
+ return;
+
LANG_FOR_EACH_INPUT_STATEMENT (file)
{
asection *sect;
OPTION_CTF_VARIABLES,
OPTION_NO_CTF_VARIABLES,
OPTION_CTF_SHARE_TYPES,
+ OPTION_DISABLE_CTF_DEDUP,
+ OPTION_ENABLE_CTF_DEDUP,
OPTION_ERROR_EXECSTACK,
OPTION_NO_ERROR_EXECSTACK,
OPTION_WARN_EXECSTACK_OBJECTS,
" <method> is: share-unconflicted (default),\n"
" share-duplicated"),
TWO_DASHES },
+ { {"disable-ctf-dedup", no_argument, NULL, OPTION_DISABLE_CTF_DEDUP},
+ '\0', NULL, N_("Disable CTF and BTF deduplication: just concatenate\n"),
+ TWO_DASHES },
+ { {"enable-ctf-dedup", no_argument, NULL, OPTION_ENABLE_CTF_DEDUP},
+ '\0', NULL, NULL, NO_HELP }
};
#define OPTION_COUNT ARRAY_SIZE (ld_options)
else
fatal (_("%P: bad --ctf-share-types option: %s\n"), optarg);
break;
+
+ case OPTION_DISABLE_CTF_DEDUP:
+ link_info.ctf_disabled = true;
+ break;
+
+ case OPTION_ENABLE_CTF_DEDUP:
+ link_info.ctf_disabled = false;
+ break;
}
}