diff options
49 files changed, 710 insertions, 47 deletions
@@ -1,3 +1,8 @@ +2019-07-13 Nick Alcock <nick.alcock@oracle.com> + + * Makefile.def (dependencies): all-ld depends on all-libctf. + * Makefile.in: Regenerated. + 2019-09-09 Phil Blundell <pb@pbcl.net> binutils 2.33 branch created diff --git a/Makefile.def b/Makefile.def index 28bf61d..e887f49 100644 --- a/Makefile.def +++ b/Makefile.def @@ -432,6 +432,7 @@ dependencies = { module=all-binutils; on=all-build-bison; }; dependencies = { module=all-binutils; on=all-intl; }; dependencies = { module=all-binutils; on=all-gas; }; dependencies = { module=all-binutils; on=all-libctf; }; +dependencies = { module=all-ld; on=all-libctf; }; // We put install-opcodes before install-binutils because the installed // binutils might be on PATH, and they might need the shared opcodes diff --git a/Makefile.in b/Makefile.in index 7a6700a..eeba51e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -51159,6 +51159,13 @@ all-stage3-binutils: maybe-all-stage3-libctf all-stage4-binutils: maybe-all-stage4-libctf all-stageprofile-binutils: maybe-all-stageprofile-libctf all-stagefeedback-binutils: maybe-all-stagefeedback-libctf +all-ld: maybe-all-libctf +all-stage1-ld: maybe-all-stage1-libctf +all-stage2-ld: maybe-all-stage2-libctf +all-stage3-ld: maybe-all-stage3-libctf +all-stage4-ld: maybe-all-stage4-libctf +all-stageprofile-ld: maybe-all-stageprofile-libctf +all-stagefeedback-ld: maybe-all-stagefeedback-libctf install-binutils: maybe-install-opcodes install-strip-binutils: maybe-install-strip-opcodes install-opcodes: maybe-install-bfd diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 420b13d..fcb645b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,26 @@ +2019-09-30 Nick Alcock <nick.alcock@oracle.com> + + * elf-bfd.h (bfd_section_is_ctf): New inline function. + * elf.c (special_sections_c): Add ".ctf". + (assign_file_positions_for_non_load_sections): Note that + compressed debugging sections etc are not assigned here. Treat + CTF sections like SEC_ELF_COMPRESS sections when is_linker_output: + sh_offset -1. + (assign_file_positions_except_relocs): Likewise. + (find_section_in_list): Note that debugging and CTF sections, as + well as reloc sections, are assigned later. + (_bfd_elf_assign_file_positions_for_non_load): CTF sections get + their size and contents updated. + (_bfd_elf_set_section_contents): Skip CTF sections: unlike + compressed sections, they have no uncompressed content to copy at + this stage. + * elflink.c (elf_link_swap_symbols_out): Call the examine_strtab + callback right before the strtab is written out. + (bfd_elf_final_link): Don't cache the section contents of CTF + sections: they are not populated yet. Call the emit_ctf callback + right at the end, after all the symbols and strings are flushed + out. + 2019-07-13 Nick Alcock <nick.alcock@oracle.com> * elf-strtab.c (_bfd_elf_strtab_len): New. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 4240d97..ccd2c35 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2257,7 +2257,7 @@ extern bfd_size_type _bfd_elf_strtab_len extern bfd_size_type _bfd_elf_strtab_offset (struct elf_strtab_hash *, size_t); extern const char * _bfd_elf_strtab_str - (struct elf_strtab_hash *, size_t idx, size_t *offset); + (struct elf_strtab_hash *, size_t idx, bfd_size_type *offset); extern bfd_boolean _bfd_elf_strtab_emit (bfd *, struct elf_strtab_hash *); extern void _bfd_elf_strtab_finalize @@ -2965,6 +2965,14 @@ extern asection _bfd_elf_large_com_section; || (H)->start_stop \ || ((INFO)->dynamic && !(H)->dynamic))) +/* Determine if a section contains CTF data, using its name. */ +static inline bfd_boolean +bfd_section_is_ctf (const asection *sec) +{ + const char *name = bfd_section_name (sec); + return strncmp (name, ".ctf", 4) == 0 && (name[4] == 0 || name[4] == '.'); +} + #ifdef __cplusplus } #endif @@ -2671,6 +2671,7 @@ static const struct bfd_elf_special_section special_sections_b[] = static const struct bfd_elf_special_section special_sections_c[] = { { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 }, + { STRING_COMMA_LEN (".ctf"), 0, SHT_PROGBITS, 0 }, { NULL, 0, 0, 0, 0 } }; @@ -5893,7 +5894,8 @@ is_debuginfo_file (bfd *abfd) return TRUE; } -/* Assign file positions for the other sections. */ +/* Assign file positions for the other sections, except for compressed debugging + and other sections assigned in _bfd_elf_assign_file_positions_for_non_load(). */ static bfd_boolean assign_file_positions_for_non_load_sections (bfd *abfd, @@ -5952,9 +5954,12 @@ assign_file_positions_for_non_load_sections (bfd *abfd, } else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) && hdr->bfd_section == NULL) + /* We don't know the offset of these sections yet: their size has + not been decided. */ || (hdr->bfd_section != NULL - && (hdr->bfd_section->flags & SEC_ELF_COMPRESS)) - /* Compress DWARF debug sections. */ + && (hdr->bfd_section->flags & SEC_ELF_COMPRESS + || (bfd_section_is_ctf (hdr->bfd_section) + && abfd->is_linker_output))) || hdr == i_shdrpp[elf_onesymtab (abfd)] || (elf_symtab_shndx_list (abfd) != NULL && hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx]) @@ -6222,11 +6227,12 @@ find_section_in_list (unsigned int i, elf_section_list * list) 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 will be handled later by + "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. We also don't set the positions of the .symtab and .strtab here. */ @@ -6261,9 +6267,12 @@ assign_file_positions_except_relocs (bfd *abfd, hdr = *hdrpp; if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) && hdr->bfd_section == NULL) + /* Do not assign offsets for these sections yet: we don't know + their sizes. */ || (hdr->bfd_section != NULL - && (hdr->bfd_section->flags & SEC_ELF_COMPRESS)) - /* Compress DWARF debug sections. */ + && (hdr->bfd_section->flags & SEC_ELF_COMPRESS + || (bfd_section_is_ctf (hdr->bfd_section) + && abfd->is_linker_output))) || i == elf_onesymtab (abfd) || (elf_symtab_shndx_list (abfd) != NULL && hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx]) @@ -6471,10 +6480,12 @@ _bfd_elf_assign_file_positions_for_non_load (bfd *abfd) asection *sec = shdrp->bfd_section; bfd_boolean is_rel = (shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA); + bfd_boolean is_ctf = sec && bfd_section_is_ctf (sec); if (is_rel + || is_ctf || (sec != NULL && (sec->flags & SEC_ELF_COMPRESS))) { - if (!is_rel) + if (!is_rel && !is_ctf) { const char *name = sec->name; struct bfd_elf_section_data *d; @@ -6520,6 +6531,13 @@ _bfd_elf_assign_file_positions_for_non_load (bfd *abfd) shdrp->contents = sec->contents; shdrp->bfd_section->contents = NULL; } + else if (is_ctf) + { + /* Update section size and contents. */ + shdrp->sh_size = sec->size; + shdrp->contents = sec->contents; + } + off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE); @@ -9099,6 +9117,11 @@ _bfd_elf_set_section_contents (bfd *abfd, hdr = &elf_section_data (section)->this_hdr; if (hdr->sh_offset == (file_ptr) -1) { + if (bfd_section_is_ctf (section)) + /* Nothing to do with this section: the contents are generated + later. */ + return TRUE; + /* We must compress this section. Write output to the buffer. */ unsigned char *contents = hdr->contents; if ((offset + count) > hdr->sh_size diff --git a/bfd/elflink.c b/bfd/elflink.c index 2169e2b..371c096 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -9539,6 +9539,14 @@ 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; @@ -11810,7 +11818,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* The object attributes have been merged. Remove the input sections from the link, and set the contents of the output - secton. */ + section. */ std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section; for (o = abfd->sections; o != NULL; o = o->next) { @@ -12032,7 +12040,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) esdo->rel.count = 0; esdo->rela.count = 0; - if (esdo->this_hdr.sh_offset == (file_ptr) -1) + if ((esdo->this_hdr.sh_offset == (file_ptr) -1) + && !bfd_section_is_ctf (o)) { /* Cache the section contents so that they can be compressed later. Use bfd_malloc since it will be freed by @@ -12048,10 +12057,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) } } - /* We have now assigned file positions for all the sections except - .symtab, .strtab, and non-loaded reloc sections. We start the - .symtab section at the current file position, and write directly - to it. We build the .strtab section in memory. */ + /* We have now assigned file positions for all the sections except .symtab, + .strtab, and non-loaded reloc and compressed debugging sections. We start + the .symtab section at the current file position, and write directly to it. + We build the .strtab section in memory. */ abfd->symcount = 0; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; /* sh_name is set in prep_headers. */ @@ -12837,6 +12846,9 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info)) goto error_return; + if (info->callbacks->emit_ctf) + info->callbacks->emit_ctf (); + elf_final_link_free (abfd, &flinfo); if (attr_section) diff --git a/include/ChangeLog b/include/ChangeLog index b53956f..184cbce 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,5 +1,12 @@ 2019-07-13 Nick Alcock <nick.alcock@oracle.com> + * bfdlink.h (elf_strtab_hash): New forward. + (elf_sym_strtab): Likewise. + (struct bfd_link_callbacks <examine_strtab>): New. + (struct bfd_link_callbacks <emit_ctf>): Likewise. + +2019-07-13 Nick Alcock <nick.alcock@oracle.com> + * ctf-api.h (includes): No longer include <sys/param.h>. 2019-07-30 Nick Alcock <nick.alcock@oracle.com> diff --git a/include/bfdlink.h b/include/bfdlink.h index 68fc17f..76355a3 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -636,6 +636,11 @@ struct bfd_link_info struct bfd_elf_version_tree *version_info; }; +/* Some forward-definitions used by some callbacks. */ + +struct elf_strtab_hash; +struct elf_sym_strtab; + /* This structures holds a set of callback functions. These are called by the BFD linker routines. */ @@ -757,6 +762,16 @@ struct bfd_link_callbacks (struct bfd_link_info *, bfd * abfd, 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. */ + void (*examine_strtab) + (struct elf_sym_strtab *syms, bfd_size_type symcount, + struct elf_strtab_hash *symstrtab); + /* 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) + (void); }; /* The linker builds link_order structures which tell the code how to diff --git a/ld/ChangeLog b/ld/ChangeLog index 8e5ae31..dd0ba41 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,97 @@ +2019-09-30 Nick Alcock <nick.alcock@oracle.com> + + * ldlang.h: (struct lang_input_statement_struct): Add the_ctf. + (struct elf_sym_strtab): Add forward. + (struct elf_strtab_hash): Likewise. + (ldlang_ctf_apply_strsym): Declare. + (ldlang_write_ctf_late): Likewise. + * ldemul.h (ldemul_emit_ctf_early): New. + (ldemul_examine_strtab_for_ctf): Likewise. + (ld_emulation_xfer_type) <emit_ctf_early>: Likewise. + (ld_emulation_xfer_type) <examine_strtab_for_ctf>: Likewise. + * ldemul.c (ldemul_emit_ctf_early): New. + (ldemul_examine_strtab_for_ctf): Likewise. + * ldlang.c: Include ctf-api.h. + (CTF_COMPRESSION_THRESHOLD): New. + (ctf_output): New. Initialized in... + (ldlang_open_ctf): ... this new function. Open all the CTF + sections in the input files: mark them non-loaded and empty + so as not to copy their contents to the output, but linker-created + so the section gets created in the target. + (ldlang_merge_ctf): New, merge types via ctf_link_add_ctf and + ctf_link. + (ldlang_ctf_apply_strsym): New, an examine_strtab callback: wrap + ldemul_examine_strtab_for_ctf. + (lang_write_ctf): New, write out the CTF section. + (ldlang_write_ctf_late): New, late call via bfd's emit_ctf hook. + (lang_process): Call ldlang_open_ctf, ldlang_merge_ctf, and + lang_write_ctf. + * ldmain.c (link_callbacks): Add ldlang_ctf_apply_strsym, + ldlang_write_ctf_late. + * emultempl/aix.em: Add ctf-api.h. + * emultempl/armcoff.em: Likewise. + * emultempl/beos.em: Likewise. + * emultempl/elf.em: Likewise. + * emultempl/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. + * ldcref.c: Likewise. + * ldctor.c: Likewise. + * ldelf.c: Likewise. + * ldelfgen.c: Likewise. + * ldemul.c: Likewise. + * ldexp.c: Likewise. + * ldfile.c: Likewise. + * ldgram.c: Likewise. + * ldlex.l: Likewise. + * ldmain.c: Likewise. + * ldmisc.c: Likewise. + * ldver.c: Likewise. + * ldwrite.c: Likewise. + * lexsup.c: Likewise. + * mri.c: Likewise. + * pe-dll.c: Likewise. + * plugin.c: Likewise. + + * ldelfgen.c (ldelf_emit_ctf_early): New. + (ldelf_examine_strtab_for_ctf): tell libctf about the symtab and + strtab. + (struct ctf_strsym_iter_cb_arg): New, state to do so. + (ldelf_ctf_strtab_iter_cb): New: tell libctf about + each string in the strtab in turn. + (ldelf_ctf_symbols_iter_cb): New, tell libctf + about each symbol in the symtab in turn. + * ldelfgen.h (struct elf_sym_strtab): Add forward. + (struct elf_strtab_hash): Likewise. + (struct ctf_file): Likewise. + (ldelf_emit_ctf_early): Declare. + (ldelf_examine_strtab_for_ctf): Likewise. + * emultempl/elf-generic.em (LDEMUL_EMIT_CTF_EARLY): Set it. + (LDEMUL_EXAMINE_STRTAB_FOR_CTF): Likewise. + * emultempl/aix.em (ld_${EMULATION_NAME}_emulation): Add + emit_ctf_early and examine_strtab_for_ctf, NULL by default. + * emultempl/armcoff.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/beos.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/elf.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/generic.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/linux.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/msp430.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/pe.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/pep.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/ticoff.em (ld_${EMULATION_NAME}_emulation): Likewise. + * emultempl/vanilla.em (ld_vanilla_emulation): Likewise. + + * Makefile.am: Pull in libctf (and zlib, a transitive requirement + for compressed CTF section emission). Pass it on to DejaGNU. + * configure.ac: Add AM_ZLIB. + * aclocal.m4: Added zlib.m4. + * Makefile.in: Regenerated. + * testsuite/ld-bootstrap/bootstrap.exp: Use it when relinking ld. + 2019-10-02 Alan Modra <amodra@gmail.com> * ld.texi (-Bsymbolic, -Bsymbolic-functions): Don't mention PIEs. diff --git a/ld/Makefile.am b/ld/Makefile.am index c56559d..00a2dc9 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -34,6 +34,12 @@ LEX = `if [ -f ../flex/flex ]; then echo ../flex/flex; else echo @LEX@; fi` am__skiplex = am__skipyacc = +# This is where we get zlib from. zlibdir is -L../zlib and zlibinc is +# -I../zlib, unless we were configured with --with-system-zlib, in which +# case both are empty. +ZLIB = @zlibdir@ -lz +ZLIBINC = @zlibinc@ + ELF_CLFAGS=-DELF_LIST_OPTIONS=@elf_list_options@ \ -DELF_SHLIB_LIST_OPTIONS=@elf_shlib_list_options@ \ -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@ @@ -145,12 +151,13 @@ AM_MAKEINFOFLAGS = -I $(srcdir) -I $(BFDDIR)/doc -I ../bfd/doc \ TEXI2DVI = texi2dvi -I $(srcdir) -I $(BFDDIR)/doc -I ../bfd/doc \ -I $(top_srcdir)/../libiberty -AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) \ +AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) @zlibinc@ \ @INCINTL@ $(HDEFINES) $(CFLAGS) $(PLUGIN_CFLAGS) \ -DLOCALEDIR="\"$(datadir)/locale\"" BFDLIB = ../bfd/libbfd.la LIBIBERTY = ../libiberty/libiberty.a +LIBCTF = ../libctf/libctf.a # These all start with e so 'make clean' can find them. ALL_EMULATION_SOURCES = \ @@ -959,8 +966,8 @@ ld_new_SOURCES = ldgram.y ldlex-wrapper.c lexsup.c ldlang.c mri.c ldctor.c ldmai ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c $(PLUGIN_C) \ ldbuildid.c ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) \ - $(BFDLIB) $(LIBIBERTY) $(LIBINTL_DEP) -ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) + $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL_DEP) +ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL) $(ZLIB) # Dependency tracking for the generated emulation files. EXTRA_ld_new_SOURCES += $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES) @@ -979,7 +986,7 @@ check-DEJAGNU: site.exp CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS_FOR_TARGET)" \ CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \ CC_FOR_HOST="$(CC)" CFLAGS_FOR_HOST="$(CFLAGS)" \ - OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" \ + OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" CTFLIB="$(LIBCTF) $(ZLIB)" \ LIBIBERTY="$(LIBIBERTY) $(LIBINTL)" LIBS="$(LIBS)" \ DO_COMPARE="`echo '$(do_compare)' | sed -e 's,\\$$,,g'`" \ $(RUNTESTFLAGS); \ diff --git a/ld/Makefile.in b/ld/Makefile.in index d509f62..8b4753b 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -122,9 +122,9 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ $(top_srcdir)/../config/plugins.m4 \ $(top_srcdir)/../config/po.m4 \ $(top_srcdir)/../config/progtest.m4 \ - $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ - $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ - $(top_srcdir)/../lt~obsolete.m4 \ + $(top_srcdir)/../config/zlib.m4 $(top_srcdir)/../libtool.m4 \ + $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ + $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ $(top_srcdir)/../bfd/version.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) @@ -534,6 +534,8 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ use_sysroot = @use_sysroot@ +zlibdir = @zlibdir@ +zlibinc = @zlibinc@ AUTOMAKE_OPTIONS = dejagnu no-texinfo.tex no-dist foreign info-in-builddir ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd TEXINFO_TEX = ../texinfo/texinfo.tex @@ -544,6 +546,12 @@ tooldir = $(exec_prefix)/$(target_alias) # maintainer mode is disabled. Avoid this. am__skiplex = am__skipyacc = + +# This is where we get zlib from. zlibdir is -L../zlib and zlibinc is +# -I../zlib, unless we were configured with --with-system-zlib, in which +# case both are empty. +ZLIB = @zlibdir@ -lz +ZLIBINC = @zlibinc@ ELF_CLFAGS = -DELF_LIST_OPTIONS=@elf_list_options@ \ -DELF_SHLIB_LIST_OPTIONS=@elf_shlib_list_options@ \ -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@ @@ -632,12 +640,13 @@ AM_MAKEINFOFLAGS = -I $(srcdir) -I $(BFDDIR)/doc -I ../bfd/doc \ TEXI2DVI = texi2dvi -I $(srcdir) -I $(BFDDIR)/doc -I ../bfd/doc \ -I $(top_srcdir)/../libiberty -AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) \ +AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) @zlibinc@ \ @INCINTL@ $(HDEFINES) $(CFLAGS) $(PLUGIN_CFLAGS) \ -DLOCALEDIR="\"$(datadir)/locale\"" BFDLIB = ../bfd/libbfd.la LIBIBERTY = ../libiberty/libiberty.a +LIBCTF = ../libctf/libctf.a # These all start with e so 'make clean' can find them. ALL_EMULATION_SOURCES = \ @@ -1001,9 +1010,9 @@ ld_new_SOURCES = ldgram.y ldlex-wrapper.c lexsup.c ldlang.c mri.c ldctor.c ldmai ldbuildid.c ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) \ - $(BFDLIB) $(LIBIBERTY) $(LIBINTL_DEP) + $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL_DEP) -ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) +ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL) $(ZLIB) # # # Build a dummy plugin using libtool. @@ -2565,7 +2574,7 @@ check-DEJAGNU: site.exp CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS_FOR_TARGET)" \ CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \ CC_FOR_HOST="$(CC)" CFLAGS_FOR_HOST="$(CFLAGS)" \ - OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" \ + OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" CTFLIB="$(LIBCTF) $(ZLIB)" \ LIBIBERTY="$(LIBIBERTY) $(LIBINTL)" LIBS="$(LIBS)" \ DO_COMPARE="`echo '$(do_compare)' | sed -e 's,\\$$,,g'`" \ $(RUNTESTFLAGS); \ diff --git a/ld/aclocal.m4 b/ld/aclocal.m4 index 4408082..7df8bf6 100644 --- a/ld/aclocal.m4 +++ b/ld/aclocal.m4 @@ -1198,6 +1198,7 @@ m4_include([../config/override.m4]) m4_include([../config/plugins.m4]) m4_include([../config/po.m4]) m4_include([../config/progtest.m4]) +m4_include([../config/zlib.m4]) m4_include([../libtool.m4]) m4_include([../ltoptions.m4]) m4_include([../ltsugar.m4]) diff --git a/ld/configure b/ld/configure index 2d6ca5c..9ae333f 100755 --- a/ld/configure +++ b/ld/configure @@ -645,6 +645,8 @@ elf_plt_unwind_list_options elf_shlib_list_options elf_list_options STRINGIFY +zlibinc +zlibdir enable_initfini_array ENABLE_PLUGINS_FALSE ENABLE_PLUGINS_TRUE @@ -834,6 +836,7 @@ enable_werror enable_build_warnings enable_nls enable_initfini_array +with_system_zlib ' ac_precious_vars='build_alias host_alias @@ -1510,6 +1513,7 @@ Optional Packages: --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-lib-path=dir1:dir2... set default LIB_PATH --with-sysroot=DIR Search for usr/lib et al within DIR. + --with-system-zlib use installed libz Some influential environment variables: CC C compiler command @@ -12027,7 +12031,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12030 "configure" +#line 12034 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12133,7 +12137,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12136 "configure" +#line 12140 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17385,6 +17389,26 @@ cat >>confdefs.h <<_ACEOF _ACEOF +# Link in zlib if we can. This allows us to read and write +# compressed CTF sections. + + # Use the system's zlib library. + zlibdir="-L\$(top_builddir)/../zlib" + zlibinc="-I\$(top_srcdir)/../zlib" + +# Check whether --with-system-zlib was given. +if test "${with_system_zlib+set}" = set; then : + withval=$with_system_zlib; if test x$with_system_zlib = xyes ; then + zlibdir= + zlibinc= + fi + +fi + + + + + # When converting linker scripts into strings for use in emulation # files, use astring.sed if the compiler supports ANSI string # concatenation, or ostring.sed otherwise. This is to support the diff --git a/ld/configure.ac b/ld/configure.ac index 41a51bb..200d9d4 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -293,6 +293,10 @@ BFD_BINARY_FOPEN AC_CHECK_DECLS([strstr, free, sbrk, getenv, environ]) +# Link in zlib if we can. This allows us to read and write +# compressed CTF sections. +AM_ZLIB + # When converting linker scripts into strings for use in emulation # files, use astring.sed if the compiler supports ANSI string # concatenation, or ostring.sed otherwise. This is to support the diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index 96e84f9..f444110 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -40,6 +40,7 @@ fragment <<EOF #include "getopt.h" #include "obstack.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" @@ -1560,6 +1561,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { NULL, /* recognized_file */ NULL, /* find potential_libraries */ NULL, /* new_vers_pattern */ - NULL /* extra_map_file_text */ + NULL, /* extra_map_file_text */ + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF diff --git a/ld/emultempl/armcoff.em b/ld/emultempl/armcoff.em index 180e1fa..0eda136 100644 --- a/ld/emultempl/armcoff.em +++ b/ld/emultempl/armcoff.em @@ -29,6 +29,7 @@ fragment <<EOF #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "getopt.h" #include "ld.h" @@ -282,6 +283,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* recognized file */ NULL, /* find_potential_libraries */ NULL, /* new_vers_pattern */ - NULL /* extra_map_file_text */ + NULL, /* extra_map_file_text */ + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em index 3ec285b..4dbccf1 100644 --- a/ld/emultempl/beos.em +++ b/ld/emultempl/beos.em @@ -37,6 +37,7 @@ fragment <<EOF #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "getopt.h" #include "libiberty.h" #include "filenames.h" @@ -782,6 +783,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* recognized file */ NULL, /* find_potential_libraries */ NULL, /* new_vers_pattern */ - NULL /* extra_map_file_text */ + NULL, /* extra_map_file_text */ + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF diff --git a/ld/emultempl/elf-generic.em b/ld/emultempl/elf-generic.em index 29af264..9ff544a 100644 --- a/ld/emultempl/elf-generic.em +++ b/ld/emultempl/elf-generic.em @@ -25,3 +25,7 @@ fragment <<EOF 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 diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index 5fec4d4..dcd9523 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -38,6 +38,7 @@ fragment <<EOF #include "libiberty.h" #include "getopt.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" #include "ldmisc.h" @@ -899,6 +900,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_RECOGNIZED_FILE-ldelf_load_symbols}, ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL}, ${LDEMUL_NEW_VERS_PATTERN-NULL}, - ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL} + ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL}, + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF diff --git a/ld/emultempl/generic.em b/ld/emultempl/generic.em index 5cfe5a7..17c9eb1 100644 --- a/ld/emultempl/generic.em +++ b/ld/emultempl/generic.em @@ -29,6 +29,7 @@ fragment <<EOF #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" @@ -157,6 +158,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_RECOGNIZED_FILE-NULL}, ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL}, ${LDEMUL_NEW_VERS_PATTERN-NULL}, - ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL} + ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL}, + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF diff --git a/ld/emultempl/linux.em b/ld/emultempl/linux.em index 5a01155..e32c74a 100644 --- a/ld/emultempl/linux.em +++ b/ld/emultempl/linux.em @@ -35,6 +35,7 @@ fragment <<EOF #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" @@ -209,6 +210,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* recognized file */ NULL, /* find_potential_libraries */ NULL, /* new_vers_pattern */ - NULL /* extra_map_file_text */ + NULL, /* extra_map_file_text */ + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF diff --git a/ld/emultempl/msp430.em b/ld/emultempl/msp430.em index 8f25489..96d42c8 100644 --- a/ld/emultempl/msp430.em +++ b/ld/emultempl/msp430.em @@ -30,6 +30,7 @@ fragment <<EOF #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "getopt.h" @@ -844,7 +845,9 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_RECOGNIZED_FILE-NULL}, ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL}, ${LDEMUL_NEW_VERS_PATTERN-NULL}, - ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL} + ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL}, + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF # diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index c1932d7..c4c6464 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -40,6 +40,7 @@ fragment <<EOF #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "getopt.h" #include "libiberty.h" #include "filenames.h" @@ -2366,6 +2367,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_recognized_file, gld_${EMULATION_NAME}_find_potential_libraries, NULL, /* new_vers_pattern. */ - NULL /* extra_map_file_text. */ + NULL, /* extra_map_file_text. */ + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index ab2a989..ec2d83f 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -51,6 +51,7 @@ fragment <<EOF #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "getopt.h" #include "libiberty.h" #include "filenames.h" @@ -2165,6 +2166,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_recognized_file, gld_${EMULATION_NAME}_find_potential_libraries, NULL, /* new_vers_pattern. */ - NULL /* extra_map_file_text */ + NULL, /* extra_map_file_text */ + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF diff --git a/ld/emultempl/ticoff.em b/ld/emultempl/ticoff.em index 65b03b6..09f1953 100644 --- a/ld/emultempl/ticoff.em +++ b/ld/emultempl/ticoff.em @@ -30,6 +30,7 @@ fragment <<EOF #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "getopt.h" #include "ld.h" @@ -182,6 +183,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* recognized file */ NULL, /* find_potential_libraries */ NULL, /* new_vers_pattern */ - NULL /* extra_map_file_text */ + NULL, /* extra_map_file_text */ + ${LDEMUL_EMIT_CTF_EARLY-NULL}, + ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL} }; EOF diff --git a/ld/emultempl/vanilla.em b/ld/emultempl/vanilla.em index c57950a..1e2955f 100644 --- a/ld/emultempl/vanilla.em +++ b/ld/emultempl/vanilla.em @@ -25,6 +25,7 @@ fragment <<EOF #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmisc.h" @@ -83,6 +84,8 @@ struct ld_emulation_xfer_struct ld_vanilla_emulation = NULL, /* recognized file */ NULL, /* find_potential_libraries */ NULL, /* new_vers_pattern */ - NULL /* extra_map_file_text */ + NULL, /* extra_map_file_text */ + NULL, /* emit_ctf_early */ + NULL /* examine_strtab_for_ctf */ }; EOF diff --git a/ld/ldcref.c b/ld/ldcref.c index 576cf7e..367b5ba 100644 --- a/ld/ldcref.c +++ b/ld/ldcref.c @@ -27,6 +27,7 @@ #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "libiberty.h" #include "demangle.h" #include "objalloc.h" diff --git a/ld/ldctor.c b/ld/ldctor.c index a6a6aa9..ba8cac1 100644 --- a/ld/ldctor.c +++ b/ld/ldctor.c @@ -23,6 +23,7 @@ #include "bfd.h" #include "bfdlink.h" #include "safe-ctype.h" +#include "ctf-api.h" #include "ld.h" #include "ldexp.h" @@ -24,6 +24,7 @@ #include "filenames.h" #include "safe-ctype.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" #include "ldmisc.h" diff --git a/ld/ldelfgen.c b/ld/ldelfgen.c index 142a669..682872f 100644 --- a/ld/ldelfgen.c +++ b/ld/ldelfgen.c @@ -21,6 +21,7 @@ #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" #include "ldmisc.h" @@ -73,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))); + } +} diff --git a/ld/ldelfgen.h b/ld/ldelfgen.h index 3284460..1ec6b66 100644 --- a/ld/ldelfgen.h +++ b/ld/ldelfgen.h @@ -18,4 +18,12 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ +struct elf_sym_strtab; +struct elf_strtab_hash; +struct ctf_file; + extern void ldelf_map_segments (bfd_boolean); +extern int ldelf_emit_ctf_early (void); +extern 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); diff --git a/ld/ldemul.c b/ld/ldemul.c index 16ddb6d..ab23dee 100644 --- a/ld/ldemul.c +++ b/ld/ldemul.c @@ -22,6 +22,7 @@ #include "bfd.h" #include "getopt.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmisc.h" @@ -371,3 +372,25 @@ ldemul_extra_map_file_text (bfd *abfd, struct bfd_link_info *info, FILE *mapf) if (ld_emulation->extra_map_file_text) ld_emulation->extra_map_file_text (abfd, info, mapf); } + +int +ldemul_emit_ctf_early (void) +{ + if (ld_emulation->emit_ctf_early) + return ld_emulation->emit_ctf_early (); + /* If the emulation doesn't know if it wants to emit CTF early, it is going + to do so. */ + return 1; +} + +void +ldemul_examine_strtab_for_ctf (struct ctf_file *ctf_output, + struct elf_sym_strtab *syms, + bfd_size_type symcount, + struct elf_strtab_hash *symstrtab) + +{ + if (ld_emulation->examine_strtab_for_ctf) + ld_emulation->examine_strtab_for_ctf (ctf_output, syms, + symcount, symstrtab); +} diff --git a/ld/ldemul.h b/ld/ldemul.h index 5b6549f..bc12b3e 100644 --- a/ld/ldemul.h +++ b/ld/ldemul.h @@ -100,6 +100,14 @@ extern struct bfd_elf_version_expr *ldemul_new_vers_pattern (struct bfd_elf_version_expr *); extern void ldemul_extra_map_file_text (bfd *, struct bfd_link_info *, FILE *); +/* Return 1 if we are emitting CTF early, and 0 if ldemul_examine_strtab_for_ctf + will be called by the target. */ +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_file *, struct elf_sym_strtab *, bfd_size_type, + struct elf_strtab_hash *); typedef struct ld_emulation_xfer_struct { /* Run before parsing the command line and script file. @@ -208,6 +216,19 @@ typedef struct ld_emulation_xfer_struct { void (*extra_map_file_text) (bfd *, struct bfd_link_info *, FILE *); + /* If this returns true, we emit CTF as early as possible: if false, we emit + CTF once the strtab and symtab are laid out. */ + 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 + bfd_link_callback is invoked by per-target code. */ + void (*examine_strtab_for_ctf) (struct ctf_file *, struct elf_sym_strtab *, + bfd_size_type, struct elf_strtab_hash *); } ld_emulation_xfer_type; typedef enum { @@ -30,6 +30,7 @@ #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" diff --git a/ld/ldfile.c b/ld/ldfile.c index 7f60319..9f0398a 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -21,6 +21,7 @@ #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "safe-ctype.h" #include "ld.h" #include "ldmisc.h" diff --git a/ld/ldgram.y b/ld/ldgram.y index c3eadeb..595b89f 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -29,6 +29,7 @@ #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldexp.h" #include "ldver.h" diff --git a/ld/ldlang.c b/ld/ldlang.c index a28e9a0..2f72a7c 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -26,6 +26,7 @@ #include "safe-ctype.h" #include "obstack.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" @@ -128,6 +129,7 @@ bfd_boolean delete_output_file_on_failure = FALSE; struct lang_phdr *lang_phdr_list; struct lang_nocrossrefs *nocrossref_list; struct asneeded_minfo **asneeded_list_tail; +static ctf_file_t *ctf_output; /* Functions that traverse the linker script and might evaluate DEFINED() need to increment this at the start of the traversal. */ @@ -151,6 +153,12 @@ int lang_statement_iteration = 0; #define SECTION_NAME_MAP_LENGTH (16) +/* CTF sections smaller than this are not compressed: compression of + dictionaries this small doesn't gain much, and this lets consumers mmap the + sections directly out of the ELF file and use them with no decompression + overhead if they want to. */ +#define CTF_COMPRESSION_THRESHOLD 4096 + void * stat_alloc (size_t size) { @@ -3597,6 +3605,186 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) einfo ("%F"); } +/* Open the CTF sections in the input files with libctf: if any were opened, + create a fake input file that we'll write the merged CTF data to later + on. */ + +static void +ldlang_open_ctf (void) +{ + int any_ctf = 0; + int err; + + LANG_FOR_EACH_INPUT_STATEMENT (file) + { + asection *sect; + + /* Incoming files from the compiler have a single ctf_file_t in them + (which is presented to us by the libctf API in a ctf_archive_t + wrapper): files derived from a previous relocatable link have a CTF + archive containing possibly many CTF files. */ + + if ((file->the_ctf = ctf_bfdopen (file->the_bfd, &err)) == NULL) + { + if (err != ECTF_NOCTFDATA) + einfo (_("%P: warning: CTF section in `%pI' not loaded: " + "its types will be discarded: `%s'\n"), file, + ctf_errmsg (err)); + continue; + } + + /* Prevent the contents of this section from being written, while + requiring the section itself to be duplicated in the output. */ + /* This section must exist if ctf_bfdopen() succeeded. */ + sect = bfd_get_section_by_name (file->the_bfd, ".ctf"); + sect->size = 0; + sect->flags |= SEC_NEVER_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED; + + any_ctf = 1; + } + + if (!any_ctf) + { + ctf_output = NULL; + return; + } + + if ((ctf_output = ctf_create (&err)) != NULL) + return; + + einfo (_("%P: warning: CTF output not created: `s'\n"), + ctf_errmsg (err)); + + LANG_FOR_EACH_INPUT_STATEMENT (errfile) + ctf_close (errfile->the_ctf); +} + +/* Merge together CTF sections. After this, only the symtab-dependent + function and data object sections need adjustment. */ + +static void +lang_merge_ctf (void) +{ + asection *output_sect; + + if (!ctf_output) + return; + + output_sect = bfd_get_section_by_name (link_info.output_bfd, ".ctf"); + + /* If the section was discarded, don't waste time merging. */ + if (output_sect == NULL) + { + ctf_file_close (ctf_output); + ctf_output = NULL; + + LANG_FOR_EACH_INPUT_STATEMENT (file) + { + ctf_close (file->the_ctf); + file->the_ctf = NULL; + } + return; + } + + LANG_FOR_EACH_INPUT_STATEMENT (file) + { + if (!file->the_ctf) + continue; + + /* Takes ownership of file->u.the_ctfa. */ + if (ctf_link_add_ctf (ctf_output, file->the_ctf, file->filename) < 0) + { + einfo (_("%F%P: cannot link with CTF in %pB: %s\n"), file->the_bfd, + ctf_errmsg (ctf_errno (ctf_output))); + ctf_close (file->the_ctf); + file->the_ctf = NULL; + continue; + } + } + + if (ctf_link (ctf_output, CTF_LINK_SHARE_UNCONFLICTED) < 0) + { + einfo (_("%F%P: CTF linking failed; output will have no CTF section: %s\n"), + ctf_errmsg (ctf_errno (ctf_output))); + if (output_sect) + { + output_sect->size = 0; + output_sect->flags |= SEC_EXCLUDE; + } + } +} + +/* Let the emulation examine the symbol table and 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) +{ + ldemul_examine_strtab_for_ctf (ctf_output, syms, symcount, symstrtab); +} + +/* Write out the CTF section. Called early, if the emulation isn't going to + need to dedup against the strtab and symtab, then possibly called from the + target linker code if the dedup has happened. */ +static void +lang_write_ctf (int late) +{ + size_t output_size; + asection *output_sect; + + if (!ctf_output) + return; + + if (late) + { + /* Emit CTF late if this emulation says it can do so. */ + if (ldemul_emit_ctf_early ()) + return; + } + else + { + if (!ldemul_emit_ctf_early ()) + return; + } + + /* Emit CTF. */ + + output_sect = bfd_get_section_by_name (link_info.output_bfd, ".ctf"); + if (output_sect) + { + output_sect->contents = ctf_link_write (ctf_output, &output_size, + CTF_COMPRESSION_THRESHOLD); + output_sect->size = output_size; + output_sect->flags |= SEC_IN_MEMORY | SEC_KEEP; + + if (!output_sect->contents) + { + einfo (_("%F%P: CTF section emission failed; output will have no " + "CTF section: %s\n"), ctf_errmsg (ctf_errno (ctf_output))); + output_sect->size = 0; + output_sect->flags |= SEC_EXCLUDE; + } + } + + /* This also closes every CTF input file used in the link. */ + ctf_file_close (ctf_output); + ctf_output = NULL; + + LANG_FOR_EACH_INPUT_STATEMENT (file) + file->the_ctf = NULL; +} + +/* Write out the CTF section late, if the emulation needs that. */ + +void +ldlang_write_ctf_late (void) +{ + /* Trigger a "late call", if the emulation needs one. */ + + lang_write_ctf (1); +} + /* Add the supplied name to the symbol table as an undefined reference. This is a two step process as the symbol table doesn't even exist at the time the ld command line is processed. First we put the name @@ -7585,6 +7773,8 @@ lang_process (void) if (config.map_file != NULL) lang_print_asneeded (); + ldlang_open_ctf (); + bfd_section_already_linked_table_free (); /* Make sure that we're not mixing architectures. We call this @@ -7661,6 +7851,14 @@ lang_process (void) } } + /* Merge together CTF sections. After this, only the symtab-dependent + function and data object sections need adjustment. */ + lang_merge_ctf (); + + /* Emit the CTF, iff the emulation doesn't need to do late emission after + examining things laid out late, like the strtab. */ + lang_write_ctf (0); + /* Copy forward lma regions for output sections in same lma region. */ lang_propagate_lma_regions (); diff --git a/ld/ldlang.h b/ld/ldlang.h index 5ab62e3..8cc5cf7 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -296,6 +296,8 @@ typedef struct lang_input_statement_struct bfd *the_bfd; + ctf_archive_t *the_ctf; + struct flag_info *section_flag_list; /* Next pointer for file_chain statement list. */ @@ -677,6 +679,12 @@ extern void add_excluded_libs (const char *); extern bfd_boolean load_symbols (lang_input_statement_type *, lang_statement_list_type *); +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_write_ctf_late + (void); extern bfd_boolean ldlang_override_segment_assignment (struct bfd_link_info *, bfd *, asection *, asection *, bfd_boolean); @@ -25,6 +25,7 @@ #include "bfd.h" #include "safe-ctype.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmisc.h" #include "ldexp.h" diff --git a/ld/ldmain.c b/ld/ldmain.c index 34c1922..2fbd8b9 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -25,6 +25,7 @@ #include "libiberty.h" #include "progress.h" #include "bfdlink.h" +#include "ctf-api.h" #include "filenames.h" #include "ld.h" @@ -148,7 +149,9 @@ static struct bfd_link_callbacks link_callbacks = einfo, info_msg, minfo, - ldlang_override_segment_assignment + ldlang_override_segment_assignment, + ldlang_ctf_apply_strsym, + ldlang_write_ctf_late }; static bfd_assert_handler_type default_bfd_assert_handler; diff --git a/ld/ldmisc.c b/ld/ldmisc.c index 319f247..848e227 100644 --- a/ld/ldmisc.c +++ b/ld/ldmisc.c @@ -23,6 +23,7 @@ #include "bfd.h" #include "bfdlink.h" #include "libiberty.h" +#include "ctf-api.h" #include "safe-ctype.h" #include "filenames.h" #include "demangle.h" @@ -22,6 +22,7 @@ #include "bfd.h" #include "bfdver.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldver.h" #include "ldexp.h" diff --git a/ld/ldwrite.c b/ld/ldwrite.c index 02b1cc7..f2d6950 100644 --- a/ld/ldwrite.c +++ b/ld/ldwrite.c @@ -23,6 +23,7 @@ #include "bfd.h" #include "bfdlink.h" #include "libiberty.h" +#include "ctf-api.h" #include "safe-ctype.h" #include "ld.h" diff --git a/ld/lexsup.c b/ld/lexsup.c index f915496..d7766c3 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -27,6 +27,7 @@ #include "safe-ctype.h" #include "getopt.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" #include "ldmisc.h" @@ -26,6 +26,7 @@ #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" +#include "ctf-api.h" #include "ld.h" #include "ldexp.h" #include "ldlang.h" diff --git a/ld/pe-dll.c b/ld/pe-dll.c index 3cfbc39..6daf984 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -25,6 +25,7 @@ #include "libiberty.h" #include "filenames.h" #include "safe-ctype.h" +#include "ctf-api.h" #include <time.h> diff --git a/ld/plugin.c b/ld/plugin.c index c8ad732..e253e1a 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -23,6 +23,7 @@ #include "bfd.h" #include "bfdlink.h" #include "bfdver.h" +#include "ctf-api.h" #include "ld.h" #include "ldmain.h" #include "ldmisc.h" diff --git a/ld/testsuite/ld-bootstrap/bootstrap.exp b/ld/testsuite/ld-bootstrap/bootstrap.exp index ee9442d..7ab4a6a 100644 --- a/ld/testsuite/ld-bootstrap/bootstrap.exp +++ b/ld/testsuite/ld-bootstrap/bootstrap.exp @@ -160,7 +160,7 @@ foreach flags $test_flags { setup_xfail "mips*-*-irix5*" } - if ![ld_link $CC tmpdir/ld1 "$flags tmpdir/ld-partial.o $BFDLIB $LIBIBERTY $extralibs"] { + if ![ld_link $CC tmpdir/ld1 "$flags tmpdir/ld-partial.o $CTFLIB $BFDLIB $LIBIBERTY $extralibs"] { fail $testname continue } @@ -177,13 +177,13 @@ foreach flags $test_flags { } regsub /tmpdir/ld/ $gcc_B_opt_save /tmpdir/gccld1/ gcc_B_opt - if ![ld_link $CC tmpdir/ld2 "$flags $OFILES $BFDLIB $LIBIBERTY $extralibs"] { + if ![ld_link $CC tmpdir/ld2 "$flags $OFILES $CTFLIB $BFDLIB $LIBIBERTY $extralibs"] { fail $testname continue } regsub /tmpdir/ld/ $gcc_B_opt_save /tmpdir/gccld2/ gcc_B_opt - if ![ld_link $CC tmpdir/ld3 "$flags $OFILES $BFDLIB $LIBIBERTY $extralibs"] { + if ![ld_link $CC tmpdir/ld3 "$flags $OFILES $CTFLIB $BFDLIB $LIBIBERTY $extralibs"] { fail $testname continue } @@ -196,7 +196,7 @@ foreach flags $test_flags { # generated by different linkers, tmpdir/ld1 and tmpdir/ld2. # So we rebuild tmpdir/ld2 with tmpdir/ld3. regsub /tmpdir/ld/ $gcc_B_opt_save /tmpdir/gccld3/ gcc_B_opt - if ![ld_link $CC tmpdir/ld2 "$flags $OFILES $BFDLIB $LIBIBERTY $extralibs"] { + if ![ld_link $CC tmpdir/ld2 "$flags $OFILES $CTFLIB $BFDLIB $LIBIBERTY $extralibs"] { fail $testname continue } |