diff options
author | Richard Henderson <rth@redhat.com> | 1999-05-03 07:29:11 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 1999-05-03 07:29:11 +0000 |
commit | 252b5132c753830d5fd56823373aed85f2a0db63 (patch) | |
tree | 1af963bfd8d3e55167b81def4207f175eaff3a56 /ld | |
download | binutils-252b5132c753830d5fd56823373aed85f2a0db63.zip binutils-252b5132c753830d5fd56823373aed85f2a0db63.tar.gz binutils-252b5132c753830d5fd56823373aed85f2a0db63.tar.bz2 |
19990502 sourceware importbinu_ss_19990502
Diffstat (limited to 'ld')
376 files changed, 67293 insertions, 0 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog new file mode 100644 index 0000000..2302da3 --- /dev/null +++ b/ld/ChangeLog @@ -0,0 +1,8933 @@ +1999-04-29 Nick Clifton <nickc@cygnus.com> + + * emulparams/elf32mcore.sh (OTHER_BSS_SYMBOLS): Define. + (OTHER_BSS_END_SYMBOLS): Define. + + * scripttempl/mcorepe.sc: New file: Duplicte of pe.sc with stack + section added. + +1999-04-26 Tom Tromey <tromey@cygnus.com> + + * aclocal.m4, configure: Updated for new version of libtool. + +1999-04-22 Nick Clifton <nickc@cygnus.com> + + * emulparams/elf32mcore.sh (OTHER_RELOCATING_SECTIONS): Define to + generate _stack section. + +1999-04-12 Philip Blundell <pb@nexus.co.uk> + + * emulparams/armelf_linux.sh: New file. Support for ARM + GNU/Linux ELF ABI. + * emulparams/armelf_linux26.sh: New file. APCS-26 version of above. + * configure.tgt: For arm*-*-linux-gnu*, set default emulation to + `armelf_linux', and also include `armelf_linux26' and `armelf'. + * Makefile.am: Add rules to make earmlinux.c and earmlinux26.c. + (ALL_EMULATIONS): Add earmlinux.o and earmlinux26.o. + * Makefile.in: Regenerate. + +1999-04-11 Richard Henderson <rth@cygnus.com> + + * Makefile.am (ALL_EMULATIONS): Add elf_i386_be.o. + * configure.tgt (i[3456]86-*-beos*): Use it. + * emulparams/elf_i386_be.sh: New file. + * Makefile.in: Rebuild. + + * configure.in (environ): Detect declaration. + * ldmain.c (main): Don't declare environ. + * sysdep.h (environ): Declare if needed. + * configure, config.in: Rebuild. + +1999-04-11 Richard Henderson <rth@cygnus.com> + + * ldgram.y (ldgram_vers_current_lang): New. + (vers_defns): Accept `extern "lang" { }' syntax. + * ldlex.l (vers_node_nesting): New. + (V_IDENTIFIER): Accept . and $ in symbols. + (VERS_NODE): Accept `extern "lang" { }' tokens. Nest VERS_NODE states. + * ldlang.c (lang_new_vers_regex): New `lang' argument. Update callers. + (lang_vers_match_lang_c): New function. + (lang_vers_match_lang_cplusplus): New function. + (lang_vers_match_lang_java): New function. + (lang_do_version_exports_section): Fix iteration. Don't free + section contents, as it is still in use by the patterns. + +1999-04-10 Richard Henderson <rth@cygnus.com> + + * ldmain.c (main): Init link_info.no_undefined. + * lexsup.c: Add command-line option --no-undefined. + +1999-04-08 Nick Clifton <nickc@cygnus.com> + + * configure.tgt: Add support for MCore targets. + * Makefile.am: Add support for MCore targets. + * Makefile.in: Regenerate. + + * emulparams/elf32mcore.sh: New file: Definitions for mcore-elf + target. + * emulparams/mcorepe.sh: New file: Definitions for mcore-pe + target. + +1999-04-06 Ian Lance Taylor <ian@zembu.com> + + * ld.h (LC_MESSAGES): Never define. + * ldmain.c (main): Don't pass LC_MESSAGES to setlocale if the + system does not define it. + +1999-04-06 H.J. Lu <hjl@gnu.org> + + * ldmain.h (demangling): Declare. + * ldmain.c (demangling): New global variable. + (main): Initialize demangling. + * ldmisc.c (vfinfo): Don't demangle symbol if ! demangling. + * lexsup.c (ld_options, parse_args): Handle --demangle and + --no-demangle. + * ld.texinfo, ld.1: Document --demangle/--no-demangle. + + * ldlex.l (V_IDENTIFIER): Allow '.' in symbol. + +1999-04-05 Chris Torek <torek@BSDI.COM> + + * emultempl/sunos.em (gld${EMULATION_NAME}_search_dir): Check that + a shared library really exists, avoiding broken symlinks. + + * ldfile.c (ldfile_open_file): Generate a better error message if + we can't find a -l file. + +1999-04-05 DJ Delorie <dj@cygnus.com> + + * configure.tgt (i386-*-pe): add targ_extra_ofiles for other PE + targets (i386-pe and i386-winnt) + +1999-04-04 Ian Lance Taylor <ian@zembu.com> + + * deffilep.y: Include "sysdep.h" and "ldmisc.h". + (def_file_add_directive): Change return type to void. Remove + unused locals sh_reserve, sh_commit, and j. + (def_ungetc): Always return a value. + (def_lex): Correct parenthesization of || within &&. + * deffile.h (def_file_add_directive): Update declaration. + * pe-dll.c: Include <time.h>, <ctype.h>, and "ldemul.h". + (generate_edata): Remove unused local i. + (quoteput): Add cast to avoid warning. + (pe_dll_generate_def_file): Fix type in format string. + (quick_symbol): Remove unused local blhe. + (pe_dll_generate_implib): Add cast to avoid warning. + (pe_process_import_defs): Remove unused locals ar_head, ar_tail, + and n. + (pe_as16): Comment out. + +1999-04-04 Don Bowman <don@pixsci.com> + + * configure.tgt: Add mips*-*-vxworks* target. + +1999-03-31 Nick Clifton <nickc@cygnus.com> + + * Makefile.in (ALL_EMULATIONS): Add earm_epoc_pe.o + Add build rule and dependencies for earm_epoc_pe.c. + + * emulparams/arm_epoc_pe.sh: New file. + + * configure.tgt: Add 'targ_extra_ofiles' for ARM based PE + targets. + +1999-03-31 Philip Blundell <pb@nexus.co.uk> + + * configure.tgt: Match `arm*-*-linux-gnu*' not + `armv*-*-linux-gnu'. + +1999-03-26 Andreas Schwab <schwab@issan.cs.uni-dortmund.de> + + * scripttempl/elf.sc: Put the .eh_frame and .gcc_except_table + sections in the data segment. + +Fri Mar 26 12:05:51 1999 Catherine Moore <clm@cygnus.com> + + * ld.h (wildcard_spec): Add exclude_name. + * ldgram.y (EXCLUDE_FILE): New token. + (wildcard_spec): Set exclude_name. + (file_NAME_list): Recognize EXCLUDE_FILE. + * ldlang.c (wild_section): Check for excluded files. + (print_wild_statement): Print excluded files. + (lang_add_wild): New argument exclude_filename. + Set exclude_filename. + * ldlang.h (lang_wild_statement_type): Add exclude_filename. + * ldlex.l: New token EXCLUDE_FILE. + * mri.c (mri_draw_tree): Add argument to lang_add_wild. + * scripttempl/elf.sc (CTOR, DTOR): Exclude crtend.o from ctor wildcard. + Reorder sorted and unsorted ctors. + * scripttempl/elfd10v.sc (CTOR, DTOR): Likewise. + * scripttempl/elfd30v.sc (CTOR, DTOR): Likewise. + * scripttempl/elfppc.sc (CTOR, DTOR): Likewise. + +1999-03-26 Nick Clifton <nickc@cygnus.com> + + * ldlang.c (lang_gc_sections): If entry_symbol is not defined, + default to "start". + +1999-03-03 Nick Clifton <nickc@cygnus.com> + + * scripttempl/elf.sc: Add explicit placements for the .eh_frame + and .gcc_except_table sections. + +Wed Mar 3 09:13:34 1999 Catherine Moore <clm@cygnus.clm> + + * scripttempl/elf.sc: Remove .end.ctors and .end.dtors + sections. Reorder .ctors section entries. + * scripttempl/elfd10v.sc: Likewise. + * scripttempl/elfd30v.sc: Likewise. + * scripttempl/elfppc.sc: Likewise. + +1999-02-26 Jim Lemke <jlemke@cygnus.com> + + * ldmain.c (main): Wrong error msg for -r and --mpc860c0. + +1999-02-25 Nick Clifton <nickc@cygnus.com> + + * ldlang.c (lang_check_section_addresses): Remove extraneous + backslash. + +Thu Feb 25 15:07:24 1999 Catherine Moore <clm@cygnus.com> + + * scripttempl/elf.sc: Don't gather .ctor and .dtor sections + for relocateable links. + * scripttempl/elfd10v.sc: Likewise. + * scripttempl/elfd30v.sc: Likewise. + * scripttempl/elfppc.sc: Likewise. + +1999-02-22 Jim Lemke <jlemke@cygnus.com> + + * ldint.texinfo: remove extraneous right brace. + * ldmain.c (main): initialize and check option "mpc860c0". + * lexsup.c (ld_options, parse_args): add option "mpc860c0". + +Wed Feb 17 12:10:06 1999 Stan Cox <scox@cygnus.com> + + * mpw-elfmips.c (gldelf32ebmip_before_allocation): Remove special + .reginfo section handling. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Likewise. + * emulparams/elf32elmip.sh (INITIAL_READONLY_SECTIONS): Removed + * emulparams/elf32ebmip.sh (INITIAL_READONLY_SECTIONS): Removed + +1999-02-17 Nick Clifton <nickc@cygnus.com> + + Patch from: Scott Bambrough <scottb@corelcomputer.com> + + * configure.tgt: Added armv*-*-linux-gnu to $targ_emul + recognition. + +Wed Feb 17 Andreas Schwab <schwab@issan.cs.uni-dortmund.de> + + * emultempl/armelf_oabi.em + (bfd_elf32_arm_allocate_interworking_sections, + bfd_elf32_arm_get_bfd_for_interworking, + bfd_elf32_arm_process_before_allocation): Define them to use the + old ABI versions of the functions. + +Tue Feb 16 16:48:19 1999 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Change AC_PREREQ to 2.13. Change AM_PROG_INSTALL + to AC_PROG_INSTALL. Change AM_EXEEXT to AC_EXEEXT. + * Makefile.am (earmelf_oabi.c): Changes spaces to tab. + * acconfig.h: Remove. + * aclocal.m4: Rebuild. + * configure: Rebuild. + * Makefile.in: Rebuild. + +Mon Feb 15 18:21:48 1999 Vladimir N. Makarov <vmakarov@cygnus.com> + + * ldexp.h (struct etree_value_type): Change valid onto valid_p. + + * ldexp.c (new_abs): Ditto. + (new_rel, new_rel_from_section, fold_binary, invalid, fold_name, + exp_fold_tree, exp_binop, exp_trinop, stat_alloc, + exp_get_abs_int): Ditto + + * ldlang.c (print_assignment, lang_size_sections, + lang_do_assignments): Ditto. + +1999-02-11 Nick Clifton <nickc@cygnus.com> + + * ldlang.c (lang_check_section_addresses): New function: Check + addresses assigned to section for overlaps. + (lang_process): Call lang_check_section_addresses if suitable. + + * ld.h: Add new boolean field to args_type structure: + 'check_section_addresses'. + + * ldmain.c: Initialise check_section_addresses field to true. + + * lexsup.c: Add new command line options '--no-check-sections' and + '--check-sections'. + + * ld.texinfo: Document new command line options '--check-sections' + and '--no-check-sections'. + +1999-02-08 Nick Clifton <nickc@cygnus.com> + + * configure.tgt: Add support for StrongARM target. + +Wed Feb 3 19:41:01 1999 Ian Lance Taylor <ian@cygnus.com> + + * ldctor.c (ldctor_build_sets): Just set SEC_KEEP once. Check for + an owner of a section before using it to look up a reloc type. + Don't set SEC_KEEP for the absolute section. + +Mon Feb 1 11:39:46 1999 Catherine Moore <clm@cygnus.com> + + * Makefile.am (earmelf_oabi.o): New. + * Makefile.in: Regenerate. + * configure.tgt (arm-*-oabi): New. + (thumb-*-oabi): New. + * emulparams/armelf_oabi.sh: New. + * emultempl/armelf_oabi.em: New. + +1999-01-31 17:57:31 1998 Michael Meissner <meissner@cygnus.com> + + * scripttempl/elfppc.sc: Add support for -fleading-underscores + switch in all linker generated symbols. + + * configure.tgt (powerpc{,le}*-*-vxworks): Add as aliases for + powerpc{,le}-*-eabi. + +Wed Jan 20 17:01:48 1999 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (i[3456]86-*-solaris2*): New target. From Pavel + Roskin <pavel_roskin@geocities.com>. + +1999-01-19 Nick Clifton <nickc@cygnus.com> + + * ldlang.c (lang_size_sections): Count loadable sections as + contributing to the size of the current segment. + +1999-01-15 Nick Clifton <nickc@cygnus.com> + + * ldlang.c (lang_size_sections): Only update the current + address of a region if the section just placed into it is an + allocated section. + +1999-01-12 Nick Clifton <nickc@cygnus.com> + + * Makefile.am: Replace efr30.o with eelf32fr30.o. + * Makefile.in: Regenerate. + + * configure.tgt: Replace fr30 with elf32fr30. + + * emulparams/elf32fr30.sh: New file: Replaces fr30.sh, and uses + generic elf.sc script. Also replaces the .stack section with a + user definable symbol __stack. + +1999-01-11 Nick Clifton <nickc@cygnus.com> + + * scripttempl/fr30.sc: Fill .init and .fini sections with NOP + pattern. + +1999-01-03 Ken Raeburn <raeburn@cygnus.com> + + * Makefile.am (check-DEJAGNU): No longer provide HOSTING_EMU, + HOSTING_CRT0, HOSTING_LIBS; the test suite can extract them from + configure.host and configure.tgt now. + * Makefile.in: Rebuild. + +1998-12-27 Ulrich Drepper <drepper@cygnus.com> + + * lexsup.c (parse_args, case OPTION_RPATH): Avoid adding duplicate + elements to rpath. + +Thu Dec 10 11:12:28 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de> + + * Makefile.am (ALL_EMULATIONS): Remove pe-dll.o and deffilep.o. + (ALL_EMUL_EXTRA_OFILES): New variable. Put them here instead. + * configure.in: Set EMUL_EXTRA_OFILES to $(ALL_EMUL_EXTRA_OFILES) + if configuring with all targets. + * configure, Makefile.in, aclocal.m4: Rebuild. + + * emultempl/pe.em (pe_enable_stdcall_fixup): Make static. + (pe_dll_do_default_excludes): Removed, unused. + (pe_def_file, pe_dll_export_everything, pe_dll_kill_ats, + pe_dll_stdcall_aliases): Don't initialize them, this file may be + compiled more than once. + * pe-dll.c (pe_def_file, pe_dll_export_everything, + pe_dll_do_default_excludes, pe_dll_kill_ats, + pe_dll_stdcall_aliases): Define and initialize them here instead. + (generate_reloc): Fix allocation of reloc_addresses array to use + bfd_vma instead of unsigned long. Fix element size in qsort call. + (reloc_sort): Compare pointers to bfd_vma instead of unsigned + long. + +Mon Dec 7 21:10:09 1998 J.J. van der Heijden <j.j.vanderheijden@student.utwente.nl> + + * configure.tgt (i[3456]86-*-mingw32*): Add cygwin target specific + files. + +Sun Dec 6 16:33:33 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (m68*-*-gnu*): New target. From Aymeric Vincent + <aymeric.vincent@emi.u-bordeaux.fr>. + +1998-12-04 Nick Clifton <nickc@cygnus.com> + + * emulparams/fr30.sh (TEXT_START_ADDR): Change TEXT_START_ADDR + from 0x100000 to 0x10000 so that it fits in 20 bits. + +Sat Nov 28 22:32:20 1998 Ian Lance Taylor <ian@cygnus.com> + + * ldemul.h (ldemul_recognized_file): Declare. + +Sat Nov 28 22:30:55 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de> + + * ldlang.c (lang_add_wild): Don't pretend that there is an input + file if the filename is a wildcard pattern. + +1998-11-25 DJ Delorie <dj@cygnus.com> + + * ldemul.h (ld_emulation_xfer_struct): new hook "recognized_file" + * ldemul.c (ldemul_recognized_file): new function, new hook + * ldint.texinfo: document new hook. + * ldlang.c (load_symbols): call recognized_hook for all objects we + do recognize, in case the emulation needs to handle them + specially. PE DLLs use this. + * pe-dll.c (pe_dll_generate_def_file): take out hack and debug + printfs + * emultempl/pe.em (gld_i386_recognized_file): new function + (gld_i486_unrecognized_file): take out hack + +1998-11-23 DJ Delorie <dj@cygnus.com> + + * pe-dll.c (fill_edata): fill in timestamp + (make_head): name object files sequentially to ensure + they link in the right order. + (make_tail): same here + (pe_process_import_defs): use sequential names for bfds to ensure + proper link order. + (pe_implied_import_dll): new function; handles linking directly + against DLLs by simulating IMPORTS directives. * emultempl/pe.em + (gld_i386pe_before_parse): hack bfd to not recognize .dll files + via bfd_pe_dll_not_recognized_hack + +1998-11-23 DJ Delorie <dj@cygnus.com> + + * emultempl/pe.em (gld_i386pe_parse_args): Conditionalize call to + pe_dll_add_excludes + +Mon Nov 23 14:36:18 1998 Nick Clifton <nickc@cygnus.com> + + * emultempl/pe.em (after_parse): Only create an undefined entry + symbol if one has been specified. + +1998-11-23 DJ Delorie <dj@cygnus.com> + + * emultempl/pe.em (gld_i386pe_after_open): call + pe_process_import_defs + * pe-dll.c (pe_dll_generate_def_file): calculate BASE from + pe_data, only print if actually set. Print version only if + set. + (save_relocs): save relocs for both input and output. + (make_one): support internal/external different names. + (pe_dll_generate_implib): support new make_one + (pe_process_import_defs): new function; handles IMPORT + directives in .def files. + +Fri Nov 20 13:06:49 1998 Nick Clifton <nickc@cygnus.com> + + * ldmisc.c (vfinfo): Cope with empty symbol names. + +Thu Nov 19 13:31:15 1998 Nick Clifton <nickc@cygnus.com> + + * scripttempl/pe.sc: Add provision of '_end' symbol. + +Wed Nov 18 18:18:43 1998 Geoffrey Noer <noer@cygnus.com> + + * configure.tgt: change refs from cygwin32* to cygwin*. + * aclocal.m4: regenerate + * configure.in: don't need to call AM_CYGWIN32. + * configure: regenerate + +Mon Nov 16 22:14:07 1998 DJ Delorie <dj@cygnus.com> + + * emultempl/pe.em (gld_i386_finish): generate import library + * deffile.h: add hint member. + * pe-dll.c (pe_dll_generate_implib): New function with helpers; + generates the import library directly from the export table. + (fill_edata): remember the actual hint for the import library. + +Sat Nov 14 14:36:24 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld.1: Some cleanups from NOKUBI Hirotaka <hnokubi@yyy.or.jp>. + +Thu Nov 12 19:21:57 1998 Dave Brolley <brolley@cygnus.com> + + * po/ld.pot: Regenerated. + * po/POTFILES.in: Regenerated. + * configure: Regenerated. + * aclocal.m4: Regenerated. + * Makefile.in: Regenerated. + +Wed Nov 11 18:10:15 1998 DJ Delorie <dj@cygnus.com> + + * pe-dll.c (generate_reloc): don't output PE relocs for sections + that won't be loaded. + +Wed Nov 11 13:44:54 1998 DJ Delorie <dj@cygnus.com> + + * pe-dll.c (fill_edata): don't strip underscores + +Tue Nov 10 21:28:19 1998 DJ Delorie <dj@cygnus.com> + + * ld.texinfo: added i386pe option summary + +Tue Nov 10 17:53:17 1998 DJ Delorie <dj@cygnus.com> + + * pe-dll.c (process_def_file): properly note undefined exported + symbols, clean up old code. + (pe_dll_generate_def_file): don't crash if pe_def_file is NULL + * emultempl/pe.em (gld_i386_parse_args): add + (en/dis)able-stdcall-fixups + (pe_fixup_stdcalls): warn about stdcall fixups + (gld_i386_unrecognized_file): make exported symbols undefs so that + archive members get pulled in + +Tue Nov 10 14:50:51 1998 Catherine Moore <clm@cygnus.com> + + * scripttempl/elfd10v.sc: Add KEEP attribute to .init, + .fini, .dtors and .ctors. Add .data and .text + wildcards to support section garbage collection. + +Mon Nov 9 22:52:50 1998 DJ Delorie <dj@indy.delorie.com> + + * deffilep.y: properly handle relocs with multiple def_files, + cache import module names + +Mon Nov 9 22:44:58 1998 DJ Delorie <dj@cygnus.com> + + * pe-dll.c (process_def_file): don't assume exports won't move + during a realloc + +Mon Nov 9 16:41:30 1998 DJ Delorie <dj@cygnus.com> + + * pe-dll.c: New file; direct support for PE DLLs + * deffile.h: New file; direct support for PE DLLs + * deffilep.y: New file; direct support for PE DLLs + * emultempl/pe.em: add direct support for PE DLLs + * configure.tgt: allow target-specific extra files + * configure.in: allow target-specific extra files + * ldlang.c (lang_add_assignment): return the assignment so that + one can change the value later based on the object files (pe-dll + DEF files do this) + * ldint.texinfo: add section for emulation walkthrough + * Makefile.am: add new files and target-specific extra files + * emultempl/pe.em (gld_i386_list_options): list dll-specific + options. + * pe-dll.c (process_def_file): auto-export everything if + nothing is otherwise exported. + +Wed Nov 4 16:39:18 1998 Nick Clifton <nickc@cygnus.com> + + * Makefile.am: Add support for FR30 target. + * configure.tgt: Add support for FR30 target. + * Makefile.in: Regenerate. + * emulparams/fr30.sh: New file. + * scripttemp/fr30.sc: New file. + +Mon Nov 2 14:47:15 1998 Catherine Moore <clm@cygnus.com> + + * ldmain.c (main): Don't report error for dynamic links and + --gc-sections. + +1998-10-26 16:05 Ulrich Drepper <drepper@cygnus.com> + + * lexsup.c (ld_options): Change text of -O to Optimize output file". + (parse_args): Set link_info.optimize based on -O argument. + * ldmain.c (main): Initialize link_info.optimze to false. + * ld.texinfo: Describe -O option. + * ld.1: Likewise. + +Mon Oct 12 14:29:56 1998 Nick Clifton <nickc@cygnus.com> + + * scripttempl/v850.sc: Move .sbss and .scommon sections into their + own segment, so that they can be next to the .bss section and so + initialised by the same piece of code. + +Fri Oct 9 15:59:52 1998 Catherine Moore <clm@cygnus.com> + + * scripttempl/elf.sc: Merge .sdata.* etc sections. + * ldctor.c (ldctor_build_sets): Set SEC_KEEP for + ctor sections. + +Mon Oct 5 09:40:43 1998 Catherine Moore <clm@cygnus.com> + + * ldmain.c (main): Error if --gc-sections and + dyanmic linking. + * scripttempl/v850.sc: Add KEEP attribute to .init, + .fini, .dtors and .ctors. Add .data and .text + wildcards to support section garbage collection. + +Wed Sep 30 11:19:15 1998 Nick Clifton <nickc@cygnus.com> + + * scripttempl/v850.sc: Rename .call_table section to + .call_table_data and create a new section called + .call_table_text. + +Sun Sep 20 00:43:26 1998 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elf.sc: Add alignment at the end of the .bss + section, so that it is included in the memsize of the segment. + +Fri Sep 18 13:42:42 1998 Catherine Moore <clm@cygnus.com> + + * emultempl/elf32.em (gld_place_orphan): Don't process for + sections with SEC_EXCLUDE flag. + +Fri Sep 4 09:24:02 1998 Nick Clifton <nickc@cygnus.com> + + * emulparams/d30velf.sh (TEXT_SIZE): Increased to 2000K. + (DATA_SIZE): Increased to 2000K. + +Thu Sep 3 17:30:58 1998 Richard Henderson <rth@cygnus.com> + + * emulparams/d10velf.sh (TEMPLATE_NAME): Use elf32. + +Mon Aug 31 01:06:00 1998 Catherine Moore <clm@cygnus.com> + + * Makefile.am: Change armelf.sc to elf.sc + * Makefile.in: Regenerate. + +Mon Aug 31 11:12:04 1998 Catherine Moore <clm@cygnus.com> + + * emulparams/armelf.sh: Change SCRIPT_NAME to + elf. Change TEXT_START_ADDR to 0x8000. Define + OTHER_TEXT_SECTIONS, OTHER_BSS_SYMBOLS and + OTHER_BSS_END_SYMBOLS. + * scripttempl/elf.sc: Modify to use + OTHER_BSS_END_SYMBOLS. + * scripttempl/elfarm.sc: Remove file. + +Tue Aug 18 12:05:34 1998 Catherine Moore <clm@cygnus.com> + + * emultempl/armelf.em (gld_armelf_before_allocation): + Add bfd_ prefix to elf32_arm_process_before_allocation + and elf32_arm_allocate_interworking_sections. + (gld_armelf_after_open): Add bfd_ prefix to + elf32_arm_get_bfd_for_interworking. + +Fri Aug 14 15:34:29 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am: Rebuild dependencies. + * Makefile.in: Rebuild. + + * ldgram.y: Include "ldctor.h". + (statement): Accept SORT around CONSTRUCTORS. + * ldctor.c: Include <ctype.h>. + (constructors_sorted): New global variable. + (ctor_prio, ctor_cmp): New static functions. + (ldctor_build_sets): Sort constructors if requested. + * ldctor.h (constructors_sorted): Declare. + * ldlang.c (print_statement): Print sorted CONSTRUCTORS + correctly. + * scripttempl/elf.sc: Add sort around CONSTRUCTORS. + * ld.texinfo (Output Section Keywords): Document SORT + (CONSTRUCTORS). + +Thu Aug 13 12:20:39 1998 Catherine Moore <clm@cygnus.com> + + * emulparams/armelf.sh: Define TEMPLATE_NAME to armelf. + * scripttempl/elfarm.sc: Include .glue_7t and .glue7 + sections. + * emultempl/armelf.em: New file. + +Thu Aug 13 12:52:45 1998 H.J. Lu <hjl@gnu.org> + + * Makefile.am (ld.dvi): Use " instead of ' for MAKEINFO. + * Makefile.in: Rebuild. + +Tue Aug 11 16:17:01 1998 Catherine Moore <clm@cygnus.com> + + * scripttempl/elfarm.sc: Change text start address + back to zero. + +Tue Aug 11 10:01:12 1998 Jeffrey A Law (law@cygnus.com) + + * emulparms/mn10200.sh (MAX_PAGESIZE): Define to 1. + * emulparms/mn10300.sh (MAX_PAGESIZE): Define to 1. + +Sun Aug 9 20:31:27 1998 Catherine Moore <clm@cygnus.com> + + * scripttempl/elfarm.sc: Set text start address to + 0x8000. Add __bss_end definition. + +Sat Aug 1 11:47:37 1998 Catherine Moore <clm@cygnus.com> + + * scripttempl/elfarm.sc: New file. + * emulparams/armelf.sh: Set SCRIPT_NAME to elfarm. + +Fri Jul 31 15:56:16 1998 Catherine Moore <clm@cygnus.com> + + * emulparams/armelf.sh: New file. + * configure.tgt: Recognize thumb-elf and arm-elf. + * Makefile.am (earmelf.o): New. + * Makefile.in: Rebuild. + +Fri Jul 24 12:00:57 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (install-exec-local): Don't remove the file before + checking whether $(bindir) == $(tooldir)/bin. From Maciej + W. Rozycki <macro@ds2.pg.gda.pl>. + * Makefile.in: Rebuild. + + * configure.tgt: Recognize h8[35]00*-coff* as well as -hms*. + +Thu Jul 23 11:15:12 1998 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/aout.sc: If ALIGNMENT is defined, use it to set + alignment of end symbol. + * scripttempl/elf.sc: Likewise. + * emulparams/sun4.sh (ALIGNMENT): Define. + * emulparams/elf32_sparc.sh (ALIGNMENT): Define. + * ldint.texinfo (emulation parameters): Document ALIGNMENT. + + * lexsup.c (parse_args): Add missing break statement. + + * ldlang.c (lang_gc_sections_1): Add default case to switch to + avoid warnings. + +Tue Jul 14 15:42:17 1998 Richard Henderson <rth@cygnus.com> + + * configure.tgt (i?86-*-beos{pe,elf,}*): Recognize. + * Makefile.am (ei386beos.o): New. + * emulparams/i386beos.sh: New file. + * emultempl/beos.em, scripttempl/i386beos.sc: New file. + +Tue Jul 14 15:35:42 1998 Richard Henderson <rth@cygnus.com> + + * lexsup.c: New option --version-exports-section. + * ld.h (struct args_type): Add version_exports_section. + * ldlang.c (lang_do_version_exports_section): New function. + (lang_process): Call it. + +Mon Jul 13 13:20:23 1998 Steve Chamberlain <sac@transmeta.com> + + * ldlex.l: Accept ASSERT. + * ldgram.y (exp): Add ASSERT_K case. + * ldexp.h (node_type): Add etree_assert to node_class enum. + (etree_type): Add assert_s field. + (exp_assert): Declare. + * ldexp.c (exp_fold_tree): Handle etree_assert. + (exp_assert): New function. + (exp_print_tree): Handle etree_assert. + * ld.texinfo (Miscellaneous Commands): Document ASSERT. + +Wed Jul 8 14:03:12 1998 Ian Lance Taylor <ian@cygnus.com> + + * ldgram.y: Change MAX to MAX_K and MIN to MIN_K, to avoid + conflicts with system header files. Change all uses. + + * Makefile.am (MAINTAINERCLEANFILES): Define. + * Makefile.in: Rebuild. + +Tue Jul 7 18:03:22 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (ldver.texi): New target. + (ld.info, ld.dvi): Depend upon ldver.texi. + * ld.texinfo: Include ldver.texi. Mention version number on title + page and in top node. + * Makefile.in: Rebuild. + +Mon Jul 6 14:55:13 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (i[3456]86-*-solaris*): New target. + +Fri Jul 3 14:19:06 1998 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (wild_section): Don't get an assertion failure if the + section is discarded. + + * scripttempl/pe.sc: Use SORT to sort sections appropriately. + * emultempl/pe.em (sort_by_file_name): Remove. + (sort_by_section_name): Remove. + (sort_sections_1, sort_sections): Remove. + (gld_${EMULATION_NAME}_before_allocation): Don't call + sort_sections. + (hold_section, hold_section_name): New static variables. + (hold_use, hold_text, hold_rdata, hold_data, hold_bss): Likewise. + (gld_${EMULATION_NAME}_place_orphan): Rewrite. Look for a good + place to put the section. Align the section. Sort the input + sections by name. + (gld_${EMULATION_NAME}_place_section): New static function. + + * ldlang.c (wild_sort): When sorting by file name, sort by archive + name first. + + * emultempl/pe.em (set_pe_subsystem): Don't call + ldlang_add_undef. + (gld_${EMULATION_NAME}_after_parse): New static function. + (ld_${EMULATION_NAME}_emulation): Use new after_parse function + rather than after_parse_default. + + * ldgram.y (extern_name_list): Do not require symbols to be + separated by commas. + (ifile_p1): Add EXTERN. + * ldlex.l: Accept EXTERN in BOTH and SCRIPT mode as well as MRI + mode. + * ld.texinfo (Options): Mention that EXTERN is equivalent to -u. + (Miscellaneous Commands): Document EXTERN. + +Wed Jul 1 19:40:34 1998 Richard Henderson <rth@cygnus.com> + + * ld.h (args_type): Add gc_sections. + * ldgram.y (ldgram_had_keep, KEEP): New. + (input_section_spec_no_keep): Rename from old input_section_spec. + (input_section_spec): New. Recognize KEEP. + * ldlang.c (wild_section): Handle keep sections. + (lang_gc_wild_section, lang_gc_wild_file, lang_gc_wild): New. + (lang_gc_sections_1, lang_gc_sections): New. + (lang_process): Invoke lang_gc_sections. + (lang_add_wild): Add keep argument. Update all callers. + * ldlang.h (lang_wild_statement_struct): Add keep_sections. + * ldlex.l (KEEP): Match it. + * ldmain.c (main): Error on -r and --gc-sections. + * lexsup.c: Add --gc-sections. + + * scripttempl/elf.sc: Merge .text.* etc sections appropriately. + Mark startup sections with KEEP. + * scripttempl/elfppc.sc: Likewise. + + * ld.texinfo: Update for --gc-sections and KEEP. + +Wed Jul 1 15:21:20 1998 Ian Lance Taylor <ian@cygnus.com> + + From Peter Jordan <pjordan@chla.usc.edu>: + * scripttempl/i386go32.sc: Correct constructor handling for -u. + +Tue Jun 23 15:17:27 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (install-data-local): Make ldscripts subdirectory. + * Makefile.in: Rebuild. + +Tue Jun 23 15:17:04 1998 Mike Stump <mrs@wrs.com> + + * Makefile.am (install-exec-local): Don't let EXEEXT interfere + with the program transform name. + * Makefile.in: Rebuild. + +Sun Jun 21 23:55:16 1998 Jeffrey A Law (law@cygnus.com) + + * ld.texinfo: Note that -relax may make symbolic debugging + impossible on some platforms. + +Tue Jun 16 12:51:13 1998 Geoff Keating <geoffk@ozemail.com.au> + + * Makefile.am (Makefile): Remove target. + (config.status): New target. + * Makefile.in: Rebuild. + + * configure.host (powerpc*-*-linux-gnu*): New host. + +Fri Jun 12 17:38:07 1998 Doug Evans <devans@seba.cygnus.com> + + * scripttempl/elf.sc (INPUT_FILES): Optional INPUT spec. + + * emulparams/m32relf.sh (OTHER_RELOCATING_SECTIONS): Change top of + stack to 8MB. + +Fri Jun 12 19:33:17 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (HFILES): Remove config.h. + (EMULATION_OFILES, POTFILES): Move patch of May 14 from + Makefile.in to Makefile.am. + (earmcoff.c): Depend upon armcoff.em, not generic.em. + * po/Make-in (all-yes): Correct misspelling in $(PACKAGE). + ($(srcdir)/$(PACKAGE).pot): Pass -C to $(XGETTEXT). + * Makefile.in, po/POTFILES.in, po/ld.pot: Rebuild. + +Fri Jun 12 13:43:17 1998 Tom Tromey <tromey@cygnus.com> + + * po/Make-in (all-yes): If maintainer mode, depend on .pot file. + ($(PACKAGE).pot): Unconditionally depend on POTFILES. + +Tue Jun 9 09:36:48 1998 Nick Clifton <nickc@cygnus.com> + + * ldlang.c (lang_finish): Add CONST type modifier to declaration + of 'send'. + +Fri Jun 5 18:19:59 1998 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_before_parse): Set + config.has_shared to true. + * emultempl/linux.em (gld${EMULATION_NAME}_before_parse): + Likewise. + * emultempl/sunos.em (gld${EMULATION_NAME}_before_parse): + Likewise. + +Tue Jun 2 12:55:03 1998 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_finish): If the entry symbol is not found, try + parsing it as a number. + * ld.texinfo (Options): Document this. + +Mon Jun 1 14:01:20 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo (Input Section Wildcards): Document SORT keyword. + +Mon May 18 12:42:53 1998 Doug Evans <devans@canuck.cygnus.com> + + * ld.h (ld_config_type): New member has_shared. + * ldmain.c (main): Initialize it. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_parse): Set it. + * lexsup.c (parse_args): Treat -shared as error if not supported. + +Mon May 18 13:14:43 1998 Ian Lance Taylor <ian@cygnus.com> + + From Jason Merrill <jason@cygnus.com>: + * ldlang.c (wild_sort): Correct order of sort. + * scripttempl/elf.sc: Put *crtbegin.o before other .ctors and + .dtors. + * scripttempl/elfd10v.sc: Likewise. + * scripttempl/elfd30v.sc: Likewise. + * scripttempl/elfppc.sc: Likewise. + +Fri May 15 00:22:35 1998 Ian Lance Taylor <ian@cygnus.com> + + * ldlex.l: Recognize keyword SORT. + * ldgram.y (current_file): Change to struct wildcard_spec. + (%union): Add new fields cname and wildcard. + (wildcard_name, wildcard_spec): New nonterminals. + (file_NAME_list): Use wildcard_spec. + (input_section_spec): Change current_file usage. + * ld.h (struct wildcard_spec): Define. + * ldlang.h (lang_wild_statement_struct): Add new fields + sections_sorted and filenames_sorted. + (lang_add_wild): Update declaration. + * ldlang.c (wild_sort): New static function. + (wild_section): Use wild_sort. + (print_wild_statement): Print sorting information. + (lang_add_wild): Add new parameters sections_sorted and + filenames_sorted. Change all callers. + * mri.c (mri_draw_tree): Update calls to lang_add_wild. + * scripttempl/elf.sc: Sort .ctors.* and .dtors.* by section name. + * scripttempl/elfd10v.sc: Likewise. + * scripttempl/elfd30v.sc: Likewise. + * scripttempl/elfppc.sc: Likewise. + +Thu May 14 18:39:16 1998 Richard Henderson <rth@cygnus.com> + + * emulparams/m32relf.sh (TEMPLATE_NAME): Define. + +Thu May 14 14:51:24 1998 Nick Clifton <nickc@cygnus.com> + + * ldemul.h: Add new prototype: ldemul_list_emulation_options. + (ld_emulation_xfer_struct): Add new field: list_options. + * ldemul.c (ldemul_list_options): New function. Call the + list_options field of the ld_emulation_xfer_struct for each + supported emulation, if such a function is present. + * lexsup.c (help): Call ldemul_list_emulation_options. + * emultempl/pe.em (gld_<>_list_options): New function. Describe + the pe emulation specific command line options. + * emultempl/armcoff.em (gld<>_list_options): New function. + Describe the armcoff emulation specific command line options. + + * emultempl/pe.em: Add a new command line option: + --support-old-code. + * emultempl/armcoff.em: Ditto. + * ld.texinfo: Document the --support-old-code option. + + * Makefile.in: Add emulation files for POTFILES.in target. + * emultempl/pe.em: Internationalise suitable strings. + * emultempl/armcoff.em: Internationalise suitable strings. + * po/POTFILES.in: Rebuilt. + +Sun May 10 22:36:30 1998 Jeffrey A Law (law@cygnus.com) + + * po/Make-in (install-info): New target. + +Tue Apr 28 19:18:30 1998 Tom Tromey <tromey@cygnus.com> + + * ldmain.c (main): Conditionally call setlocale. + * ld.h: Include <locale.h> if HAVE_LOCALE_H. + (LC_MESSAGES): Now can be defined even when ENABLE_NLS. + +Mon Apr 27 11:56:21 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Change version number to 2.9.4 + * configure: Rebuild. + + * ld.texinfo (Options) [-rpath-link]: Mention ld.so.conf. + + Based on patch from H.J. Lu <hjl@gnu.org>: + * emultempl/elf32.em (global_vercheck_needed): New file static + variable. + (global_vercheck_failed): New file static variable. + (gld${EMULATION_NAME}_after_open): Check for shared libraries + twice, once with force set to 0 and once with it set to 1. + (gld${EMULATION_NAME}_check_ld_so_conf): Add force parameter. + Change all callers. + (gld${EMULATION_NAME}_search_needed): Likewise. + (gld${EMULATION_NAME}_try_needed): Likewise. If not force, check + whether the libraries needs any incompatible versions. + (gld${EMULATION_NAME}_vercheck): New static function. + +Wed Apr 22 16:01:35 1998 Tom Tromey <tromey@cygnus.com> + + * po/Make-in (MKINSTALLDIRS): Don't look in $(top_srcdir). + +Wed Apr 22 12:40:56 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (check-DEJAGNU): Add $(INTLLIBS) to LIBIBERTY when + invoking runtest. + * Makefile.in: Rebuild. + + * lexsup.c (parse_args): Change -l options into --library options + to avoid confusion between -li and -library. + + * ld.texinfo (MEMORY): Clarify use of >REGION. + +Tue Apr 21 23:12:40 1998 Tom Tromey <tromey@scribbles.cygnus.com> + + * Many files: Added gettext invocations around user-visible + strings. + * ld.h: Added gettext-related includes and defines. + * ldmain.c: Call setlocale, bindtextdomain, textdomain. + * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_STPCPY, + HAVE_LC_MESSAGES): Define. + * configure.in: Call CY_GNU_GETTEXT. Create po/Makefile.in and + po/Makefile. Use AM_PROG_LEX. + (TDIRS): AC_SUBST early on, to avoid having value split when it + happens to cross line 90 of the generated sed script. + * Makefile.am (SUBDIRS): New macro. + (POTFILES): Likewise. + (po/POTFILES.in): New target. + (ld_new_LDADD): Added INTLLIBS. + (ld_new_DEPENDENCIES): Added INTLDEPS. + * po/Make-in, po/POTFILES.in, po/gas.pot: New files. + +Tue Apr 21 23:07:07 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo (Simple Example): Rewrite a few things as suggested + by Nick Clifton <nickc@cygnus.com>. + (PROVIDE): Likewise. + +Tue Apr 21 09:55:06 1998 Nick Clifton <nickc@cygnus.com> + + * emultempl/pe.em: Rename external arm interworking functions + to conform to BFD naming conventions. Add code to _after_open() + function to obtain a bfd for use by the interworking code. + + * emultempl/armcoff.em: Rename external arm interworking functions + to conform to BFD naming conventions. Add new _after_open() + function to obtain a bfd for use by the interworking code. + +Sun Apr 19 19:23:09 1998 Richard Henderson <rth@cygnus.com> + + * ldlang.c (lang_size_sections) [case lang_assignment_statement_enum]: + Update dot and the default memory section even when relaxing. + +Sat Apr 18 18:41:12 1998 Richard Henderson <rth@cygnus.com> + + * ldlang.c (lang_one_common): Manipulate the section's cooked size + rather than its raw size. + +Tue Apr 7 13:35:29 1998 H.J. Lu <hjl@gnu.org> + + * configure.in (TESTBFDLIB): New. Defined and substituted. + * Makefile.am (TESTBFDLIB): Changed to @TESTBFDLIB@. + * configure, Makefile.in: Rebuild. + +Mon Apr 6 15:33:39 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (ld.info): Invoke makeinfo with -I options directly + rather than relying on default rule. Don't depend upon + bfdsumm.texi. + (ld.dvi): Likewise. + (bfdsumm.texi): Remove target. + (CLEANFILES): Take bfdsumm.texi out of value. + * Makefile.in: Rebuild. + +Sun Apr 5 13:07:57 1998 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/pe.sc: Use shell variables to avoid depending upon + how $ is handled when expanding a shell substitution. + +Fri Apr 3 00:56:50 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (MOSTLYCLEANFILES): Add ld.log and ld.sum. + (DISTCLEANFILES): Add site.exp and site.bak. + * Makefile.in: Rebuild. + + * configure.in: Put the tdirs in a file and use AC_SUBST_FILE, + rather than in a shell variable and using AC_SUBST. + * Makefile.am (DISTCLEANFILES): Remove ldscripts. Add tdirs. + (distclean-local): New target. + * configure, Makefile.in: Rebuild. + + * ld.texinfo: Completely rewrite linker script documentation. + +Mon Mar 30 12:47:33 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Set version to 2.9.1. + * configure: Rebuild. + + * Branched binutils 2.9. + +Sat Mar 28 16:48:19 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (MOSTLYCLEANFILES): Remove tmpdir. + (mostlyclean-local): New target to remove tmpdir. + * Makefile.in: Rebuild. + + Fix some gcc -Wall warnings: + * ldcref.c (output_cref): Add casts to avoid warnings. + * ldfile.c (ldfile_add_arch): Likewise. + * ldlang.c (lang_leave_overlay_section): Likewise. + * lexsup.c (OPTION_COUNT): Likewise. + (parse_args): Likewise. + * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): + Likewise. + * emultempl/sunos.em (gld${EMULATION_NAME}_search_dir): Likewise. + * ldlang.c (lang_check): Initialize variables to avoid warnings. + * ldwrite.c (build_link_order): Likewise. + * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Likewise. + * emultempl/armcoff.em (gld${EMULATION_NAME}_before_allocation): + Remove unused variables. + + * Makefile.am (MOSTLYCLEANFILES): Correct name (was + MOSTCLEANFILES). + * Makefile.in: Rebuild. + +Fri Mar 27 16:39:25 1998 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/pe.em (gld_${EMULATION_NAME}_before_allocation): Put + ARM code inside ifdef TARGET_IS_armpe. + +Wed Mar 25 11:34:13 1998 Ian Lance Taylor <ian@cygnus.com> + + Based on patch from H.J. Lu <hjl@gnu.org>: + * Makefile.am (LDDISTSTUFF): New variable. + (diststuff): New target. + * Makefile.in: Rebuild. + + * scripttempl/pe.sc: Only include .idata\$[0-7] in .idata when + relocating. + +Tue Mar 24 15:59:29 1998 Nick Clifton <nickc@cygnus.com> + + * scripttempl/pe.sc (.text): Add .glue_7 and .glue_7t sections to + hold Arm/Thumb stubs. + + * emultempl/pe.em (gld_pe_before_allocation): Call + arm_process_before_allocation (for ARM/Thumb targets) in order to + gather interworking stb information. + +Mon Mar 23 18:54:15 1998 Joel Sherrill <joel@OARcorp.com> + + * configure.tgt: (sh*-*-rtems*): Switched from ELF to COFF. + +Fri Mar 20 19:17:13 1998 Ian Lance Taylor <ian@cygnus.com> + + * aclocal.m4, configure: Rebuild with libtool 1.2. + +Thu Mar 19 14:54:45 1998 Geoffrey Noer <noer@cygnus.com> + + * scripttempl/pe.sc: The Cygwin32 library uses a .data$nocopy + section to avoid copying certain data on fork. The linker used to + include this between __data_start__ and __data_end__, but that + breaks building the cygwin32 dll. The fix is to rename the + section ".data_cygwin_nocopy" and explictly include it after + __data_end__. + +Wed Mar 18 09:42:24 1998 Nick Clifton <nickc@cygnus.com> + + * configure.tgt (targ_extra_emuls): Add thumb-pe target. + +Sun Mar 8 23:34:14 1998 Stan Cox <scox@equinox.cygnus.com> + + * configure.tgt (sparclite*-*-elf): Added. + +Mon Mar 2 19:24:08 1998 Michael Meissner <meissner@cygnus.com> + + * ldlang.c (lang_size_sections): If the default memory region is + *default*, see if there is a memory region that could be used. + +Thu Feb 26 17:09:53 1998 Michael Meissner <meissner@cygnus.com> + + * scripttempl/elfd30v.sc: Add support for .eit_v section and put + it at 0xfffff020. + * emulparams/d30v{elf,_o,_e}.sh: Ditto. + +Mon Feb 23 17:46:51 1998 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/pe.em (sort_sections): Permit the wildcard to include + a trailing '*' when sorting grouped sections. + * scripttempl/pe.sc: Include grouped sections using NAME\$*. Only + include them when relocating. + +Wed Feb 18 23:39:46 1998 Richard Henderson <rth@cygnus.com> + + * Makefile.am (install-exec-local): Install properly when ln + fails or tooldir == prefix. + +Fri Feb 13 15:24:06 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (AUTOMAKE_OPTIONS): Define. + * configure, Makefile.in, aclocal.m4: Rebuild with automake 1.2e. + +Thu Feb 12 14:10:44 1998 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elf.sc: Align the _end symbol according to the ELF + format size. From Gordon W. Ross <gwr@mc.com>. + + NetBSD patches from Gordon W. Ross <gwr@mc.com>: + * configure.host (alpha*-*-netbsd*): New host. + * configure.tgt (alpha*-*-netbsd*, powerpc-*-netbsd*): New + targets. + + * lexsup.c (help): Update bug-gnu-utils address. + * ld.texinfo (Bug Reporting): Likewise. + +Tue Feb 10 18:05:56 1998 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_size_sections): Warn if some memory regions were + defined, but a loadable section is going into the default memory + region. + +Tue Feb 10 16:17:20 1998 H.J. Lu <hjl@gnu.org> + + * ldlex.l (V_IDENTIFIER): Allow '.' as symbol prefix. + +Tue Feb 10 15:09:45 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (Makefile): Add target, for dependencies on + configure.host and configure.tgt. + * configure.host, configure.tgt: Change -linux* to -linux-gnu*. + * Makefile.in: Rebuild. + +Mon Feb 9 13:44:40 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * scripttempl/elfd10v.sc (.stack): Move stack to 0x00..7FFE. + + * emulparams/d10velf.sh (READONLY_START_ADDR): Read only section + moved to 0x00.....4. + +Sat Feb 7 15:41:26 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure, aclocal.m4: Rebuild with new libtool. + +Thu Feb 5 12:16:11 1998 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/pe.sc: Remove ${RELOCATING-0} from all sections. + From Thomas de Lellis <tdel@wrs.com>. + + * configure, Makefile.in, aclocal.m4: Rebuild with new libtool. + +Wed Feb 4 13:02:32 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (ld_new_LDADD): Remove @LEXLIB@. + * Makefile.in: Rebuild. + +Mon Feb 2 19:34:54 1998 Steve Haworth <steve@pm.cse.rmit.EDU.AU> + + Add tms320c30 support: + * configure.tgt (tic30-*-*aout*, tic30-*-*coff*): New targets. + * emulparams/tic30aout.sh: New file. + * emulparams/tic30coff.sh: New file. + * scripttempl/tic30aout.sc: New file. + * scripttempl/tic30coff.sc: New file. + * Makefile.am (ALL_EMULATIONS): Add etic30aout.o and + etic30coff.o. + (etic30aout.c, etic30coff.c): New targets. + * Makefile.in: Rebuild. + +Mon Feb 2 14:10:59 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure.host: Correct HOSTING_CRT0 in alpha*-*-linux* case to + accept either ld.so or ld-linux.so. + +Fri Jan 30 19:16:28 1998 Doug Evans <devans@canuck.cygnus.com> + + * Makefile.am ({CC,CXX}_FOR_TARGET): Change program_transform_name + to transform. + * Makefile.in: Regenerate. + +Fri Jan 30 19:15:17 1998 Geoff Keating <geoffk@ozemail.com.au> + + * scripttempl/elfppc.sc: Put .dynsbss in .sbss. + +Fri Jan 30 11:43:49 1998 H.J. Lu <hjl@gnu.ai.mit.edu> + + * Makefile.am (eelf32bsmip.c, eelf32lsmip.c): New targets. + * Makefile.in: Rebuild. + +Thu Jan 29 16:04:21 1998 Mumit Khan <khan@xraylith.wisc.edu> + + * ldfile.c (slash): Set to backslash if _WIN32 but not + __CYGWIN32__. + (ldfile_open_file_search): If __MSDOS__ or _WIN32, accept a + leading backslash or a leading x: as an absolute path. + (ldfile_find_command_file): Use slash rather than / when + generating name to try. + * lexsup.c (PATH_SEPARATOR): Define. + (set_default_dirlist): Use PATH_SEPARATOR rather than ':'. + +Wed Jan 28 14:06:30 1998 Richard Henderson <rth@cygnus.com> + + * emulparams/elf64_sparc.sh (ELFSIZE): 64 + (TEXT_START_ADDR): Round off, since SIZEOF_HEADERS is added later. + (DATA_PLT): Needed by v9 abi. + +Wed Jan 28 16:37:27 1998 J.J. van der Heijden <J.J.vanderHeijden@student.utwente.nl> + + * configure.tgt (i[3456]86-*-mingw32*): New entry. + +Wed Jan 28 15:51:58 1998 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elf.sc: Only include linkonce sections in final + sections when relocating. + +Wed Jan 28 14:10:01 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo (Options): Add a brief description of the types of + information included in a link map. + + * ld.texinfo (Options): Mention LDEMULATION in description of -m. + (Environment): Mention LDEMULATION. + + * ld.texinfo (Options): Clarify --export-dynamic a bit. + +Thu Jan 22 16:07:23 1998 Richard Henderson <rth@cygnus.com> + + * ldlex.l (<SCRIPT>{WILDCHAR}*): Take care for the comments this + pattern could match. + +Wed Jan 21 22:26:46 1998 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/pe.em (gld_${EMULATION_NAME}_set_symbols): When doing + a relocateable link, set the image base to 0, and don't define the + various symbols. + * emulparams/i386pe.sh (RELOCATEABLE_OUTPUT_FORMAT): Define. + * scripttempl/pe.sc: Swap the .data and .bss sections so that + .data comes first. If doing a relocateable link, use + RELOCATEABLE_OUTPUT_FORMAT if it is defined, and start the + sections at 0, and don't define any symbols. + + * ldlang.c (lang_memory_default): Correct parenthisization of + expression. + +Wed Jan 21 21:20:32 1998 Manfred Hollstein <manfred@s-direktnet.de> + + * emultempl/sunos.em: Don't include sys/types.h and sys/stat.h + here; they are included already via sysdep.h. + +Tue Jan 6 13:40:02 1998 Richard Henderson <rth@cygnus.com> + + * scripttempl/i960.sc: Don't explicitly set .data and .bss start. + +Fri Jan 2 20:15:37 1998 Michael Meissner <meissner@cygnus.com> + + * ldgram.y (attributes_opt): Pass region pointer to + lang_set_flags, not ®ion->flags. + + * ldlang.c (lang_memory_default): New function to figure out a + default memory region for a section if it was not specified. + (lang_memory_region_lookup): Zero flags, not_flags field. + (lang_map{,_flags}): Print attribute flags in memory map. + (lang_size_sections): Call lang_memory_default to get default + memory region. + (lang_set_flags): Implement attribute flags for real. Take new + argument to give the flags we are to skip for this region. + + * ldlang.h (memory_region_struct): Add not_flags field, make both + flags fields flagword type. + (lang_output_section_state): Make flags field flagword type. + (lang_set_flags): Update prototype to match new calling sequence. + (lang_memory_region_default): Add prototype. + + * emulparams/d30v{_e,_o,elf}.sh ({TEXT,DATA,EMEM}_DEF_SECTION): + Define whether or not the region gets default sections, and if so, + what sections. + + * scripttempl/elfd30v.sc (MEMORY): Set up which of the regions get + default sections. + +Thu Jan 1 22:58:04 1998 Michael Meissner <meissner@cygnus.com> + + * scripttempl/elfd30v.sc (.eh_frame): Link into the data section. + +Thu Jan 1 18:04:51 1998 Jeffrey A Law (law@cygnus.com) + + * scripttempl/h8300h.sc: Fix typo. + * scripttempl/h8300s.sc: Likewise. + +Sun Dec 21 12:51:49 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldexp.c (fold_name): Don't crash if the symbol is defined in a + section with no output section, such as a shared library section. + +Wed Dec 17 12:14:11 1997 Ian Lance Taylor <ian@cygnus.com> + + * lexsup.c (parse_args): Keep track of where we are in the option + parsing before calling ldemul_parse_args, so that we don't call it + multiple times on the same argument and confuse the getopt + internals. + +Thu Dec 11 09:00:15 1997 Michael Meissner <meissner@cygnus.com> + + * configure.tgt (d30v-elf-*): Rename d30velf_e to d30v_e and + d30velf_o to d30v_o to work in DOS environments. + * Makefile.{am,in}: Ditto. + + * emulparams/d30v_{o,e}: Rename from d30velf_{o,e}. + * emulparams/d30velf_{o,e}: Deleted. + +Wed Dec 10 17:40:08 1997 Nick Clifton <nickc@cygnus.com> + + * scripttempl/armcoff.sc: Add glue sections (code taken from Arm + branch). + + * emulparams/armcoff.sh (TEMPLATE_NAME): Set to armcoff. + + * emultempl/armcoff.em: New file, imported from Arm branch. + +Wed Dec 10 14:10:44 1997 Michael Meissner <meissner@cygnus.com> + + * scripttempl/elfd30v.sc: Add .rel and .rela sections for all + defined sections. Set up __{D,C}TOR_{LIST,END}__. Add onchip and + external memory sections for rodata. Delete .string, .rodata1, + and .data1 sections. + +Tue Dec 9 15:28:17 1997 Michael Meissner <meissner@cygnus.com> + + * Makefile.am: Add Oct 23 changes to Makefile.in here. + + * Makefile.{am,in}: (ALL_EMULATIONS): Add ed10velf.o. + + * Makefile.{am,in}: (ALL_EMULATIONS): Add etic80coff.o. + + * Makefile.{am,in}: (ALL_EMULATIONS): Add ed30velf{,_e,_o}.o. + (ed30velf_e.c): Like d30velf, except .text/.data/etc always go in + external memory. + (ed30velf_o.c): Like d30velf, except .text/.data/etc always go in + onchip memory. + + * emulparams/d30velf.sh (STACK_START_ADDR): Top of default + stack. + ({TEXT,DATA,EMEM}_SIZE): Sizes of the 3 memory areas. + ({TEXT,DATA,BSS}_MEMORY): Which memory region .text, .data, and + .bss should go in. + + * emulparams/d30velf_{e,o}.sh: New files to be explicit whether + .text, .data, etc go in external memory or onchip memory. + + * configure.tgt (d30v-*-*ext*): New configuration to default + .text, .data, etc. in external memory. + (d30v-*-*onchip*): New configuration to default .text, .data, + etc. in onchip memory. + (d30v-*-*): Add d30velf_{e,o} emulations. + + * scripttempl/elfd30v.sc: Allow .text, .data, .bss to be put in + either the onchip text/data areas or the external memory area. + (MEMORY): Get sizes from d30velf.sh. + (.e{data,text,bss}): Put sections in the external memory region. + (.stext): Put section in the onchip text region. + (.s{data,bss}): Put sections in the onchip data region. + (__stack): Assign from ${STACK_START_ADDR}. + (.text): Put in ${TEXT_MEMORY} memory region. + (.data{,1}/.strings/.rodata{,1}): Put in ${DATA_MEMORY} memory + region. + (.bss): Put in ${BSS_MEMORY} memory region. + +Tue Dec 2 10:14:47 1997 Nick Clifton <nickc@cygnus.com> + + * configure.tgt (targ_extra_emuls): Add support for Thumb target. + +Sat Nov 22 15:23:19 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldlex.l: Don't define hex_mode. Correct number regexp to not + accept hex digits without a leading $ or 0x. Handle leading $ + correctly. Pass 0 rather than hex_mode to bfd_scan_vma. + * ldlex.h (hex_mode): Don't declare. + +Sun Nov 16 20:16:45 1997 Michael Meissner <meissner@cygnus.com> + + * emulparams/d30velf.sh ({DATA,EMEM}_START_ADDR): Define as start + of internal data area and external memory on chip. + + * scripttempl/elfd30v.sc: Define a MEMORY region that describes + the 3 regions of memory on the chip. Put .text/.init/.fini into + the text memory region, put other segments into the data memory + region. Add more of the standard elf sections. Default __stack + to be 0x20008000, which is 1 byte beyond end of the internal data + region. + +Thu Nov 13 13:45:00 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure.tgt (targ_extra_emuls): Make FreeBSD a i386bsd + variant. + +Sun Nov 2 14:51:36 1997 H.J. Lu <hjl@gnu.ai.mit.edu> + + * configure.host (alpha*-*-linux*): Correct HOSTING_CRT0. Set + HOSTING_LIBS. + +Thu Oct 30 12:25:55 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld.h (args_type): Add warn_mismatch field. + * ldmain.c (main): Initialize warn_mismatch field. + * lexsup.c (parse_args): Handle --no-warn-mismatch option. + * ldlang.c (ignore_bfd_error): New static function. + (lang_check): If warn_mismatch is false, don't warn about + mismatched input files. + * ld.texinfo, ld.1: Document new option. + +Thu Oct 23 14:38:18 1997 Nick Clifton <nickc@cygnus.com> + + * scripttempl/v850.sc: Rename linker symbol '_stack' to '__stack' + to avoid conflicts with C code which is defining a variable called + 'stack'. + +Thu Oct 23 00:57:45 1997 Richard Henderson <rth@dot.cygnus.com> + + * Makefile.in (ALL_EMULATIONS): Move eelf64_sparc.o ... + (ALL_64_EMULATIONS): ... here. + (eelf64_sparc.c): Template should be elf32 not generic. + * emulparams/elf64_sparc.sh (TEMPLATE_NAME): New definition. + +Thu Oct 23 00:44:20 1997 Richard Henderson <rth@dot.cygnus.com> + + * configure.tgt: Add sparc64-*-linux*. + * emulparams/elf64_sparc.sh (GENERATE_SHLIB_SCRIPT, NOP): New. + +Wed Oct 22 11:29:25 1997 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/pe.sc: Put .eh_frame in .rdata. + +Fri Oct 17 00:00:13 1997 Richard Henderson <rth@cygnus.com> + + * ldlang.c (lang_register_vers_node): Only check globals<=>locals, + since we need to be able to export different versions of the same + symbol. + +Wed Oct 15 14:52:36 1997 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/pe.sc: Put .stab and .stabstr sections at end. + +Wed Oct 8 12:37:05 1997 Richard Henderson <rth@cygnus.com> + + * configure.tgt, configure.host: Change alpha-*-* to alpha*-*-*; + config.guess now recognizes alphaev5 etc. + +Fri Oct 3 14:23:02 1997 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Don't treat + -s and -u as -static and -unix. + +Thu Oct 2 18:40:28 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (wild_doit): Rewrite flag handling for clarity. If we + are not adding the first input section, and SEC_READONLY is clear + on the output section, then don't copy it from the input section. + If SEC_READONLY is not set on the input section, then clear it on + the output section. + + * configure.tgt (mips*-sgi-irix[56]*): Use elf32bsmip rather than + elf32bmip. + (mips*el-*-linux*): Change elf32lmip to elf32lsmip and elf32bmip + to elf32bsmip. + (mips*-*-linux*): Likewise. + * emulparams/elf32bsmip.sh: New file; just like elf32bmip.sh, but + setting ENTRY to __start. + * emulparams/elf32lsmip.sh: New file; just like elf32lmip.sh, but + setting ENTRY to __start. + * scripttempl/elf.sc: Always set ENTRY to _start if it was not + already set. + +Wed Oct 1 16:41:00 1997 Nick Clifton <nickc@cygnus.com> + + * emulparams/v850.sh (ROZDATA_START_ADDR, ROSDATA_START_ADDR): New + Variables. + + * scripttempl/v850.sc: Move read only areas out of zero and small + data sections and into their own sections. + +Wed Sep 24 16:59:15 1997 Joel Sherrill <joel@oarcorp.com> + + * configure.tgt (sh*-*-rtems*): New target, like sh-*-elf*. + +Wed Sep 24 11:33:14 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo (Section Options): Improve documentation of NOLOAD + directive. + + * aclocal.m4: Rebuild with new libtool. + * configure: Rebuild. + +Mon Sep 22 17:24:06 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (wild_doit): Revert patch of September 3. + +Wed Sep 17 16:45:34 1997 Nick Clifton <nickc@cygnus.com> + + * Makefile.am, Makefile.in: Add rule for ev850.c + * configure.tgt (targ_extra_emuls): Add v850 target. + +Wed Sep 17 16:43:39 1997 Nick Clifton <nickc@cygnus.com> + + * emulparams/v850.sh (CALL_TABLE_START_ADDR): New entry. + * scripttempl/v850.sc: Add call table data area + +Mon Sep 15 11:29:13 1997 Ken Raeburn <raeburn@cygnus.com> + + Merge change from Martin Hunt: + + * scripttempl/elfd30v.sc: Put .rodata in the .text section. + +Tue Sep 9 07:49:56 1997 Fred Fish <fnf@ninemoons.com> + + * ldlang.c (lang_memory_region_lookup): Remove extraneous + initialization of p. + +Thu Sep 4 09:03:33 1997 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): In + expression produced for -bpT and -bpD options, align to a 32 byte + boundary rather than an 8 byte boundary. + * scripttempl/aix.sc: Put .tocbss at start of .bss section. + + * ldmisc.h, ldmisc.c, ldcref.c: Rename finfo to lfinfo, to avoid + function name conflict with AIX 4.2 unistd.h header file. + +Wed Sep 3 15:12:32 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (wild_doit): Clear SEC_HAS_CONTENTS from a + noload_section. + +Fri Aug 29 00:32:31 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (ld_new_DEPENDENCIES): Remove @LEXLIB@. + * Makefile.in: Rebuild. + +Thu Aug 28 10:12:10 1997 Doug Evans <dje@canuck.cygnus.com> + + * configure.tgt (arc-*-elf*): Recognize. + * Makefile.am (ALL_EMULATIONS): Add earcelf.o. + * Makefile.in: Regenerate. + * emulparams/arcelf.sh: New file. + +Wed Aug 20 11:14:13 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (wildcardp): Don't let a backslash by itself cause a + pattern to be treated as a wildcard pattern. + + * ldgram.y (atype): Accept parentheses with no type. + + * ld.texinfo (Section Definition): Clarify use of whitespace. + (Section Placement): Likewise. + +Mon Aug 18 11:12:03 1997 Nick Clifton <nickc@cygnus.com> + + * configure.tgt (targ_extra_emuls): Add support for v850e target. + +Mon Aug 18 11:12:03 1997 Nick Clifton <nickc@cygnus.com> + + * configure.tgt (targ_extra_emuls): Add support for v850e target. + +Sat Aug 9 00:42:27 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.am (ld.info): Change dependency from + $(BFDDIR)/doc/bfdsumm.texi to bfdsumm.texi. + (ld.dvi): Likewise. + (bfdsumm.texi): New target. + (CLEANFILES): Add bfdsumm.texi. + * Makefile.in: Rebuild. + + * Makefile.am: New file, based on old Makefile.in. + * acinclude.m4: New file, from old aclocal.m4. + * configure.in: Call AM_INIT_AUTOMAKE and AM_PROG_LIBTOOL. Remove + shared library handling; now handled by libtool. Replace + AC_CONFIG_HEADER with AM_CONFIG_HEADER. Call AC_PROG_YACC, + AC_PROG_LEX, and AC_DECL_YYTEXT. Call AM_MAINTAINER_MODE, + AM_CYGWIN32, and AM_EXEEXT. Don't call CY_CYGWIN32 or CY_EXEEXT. + * configure.host: Don't set HLDFLAGS, HLDENV, or RPATH_ENVVAR. + * acconfig.h: Mention PACKAGE and VERSION. + * stamp-h.in: New file. + * ldver.c (ld_program_version): Set ld_program_version from + VERSION. + * ldgram.y, ldlex.l: Replace VERSION with VERSIONK. + * Makefile.in: Now built with automake. + * aclocal.m4: Now built with aclocal. + * configure, config.in: Rebuild. + +Mon Jul 28 19:04:50 1997 Rob Savoye <rob@chinadoll.cygnus.com> + + * configure.in: Use CYGWIN and EXEEXT autoconf macro to look for + win32 dependencies. + * configure: Regenerated with autoconf 2.12. + * Makefile.in: Add $(EXEEXT) to executable. + +Tue Jul 22 18:50:38 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE> + + * emulparams/i386go32.sh (OUTPUT_FORMAT): Set to "coff-go32". + (SEGMENT_SIZE): Set to 0x200. + * scripttempl/i386go32.sc: Rewrite. + * configure.tgt (i[3456]86-*-msdosdjgpp*): New target. + +Mon Jul 7 12:39:42 1997 Ian Lance Taylor <ian@cygnus.com> + + From Manfred Hollstein <manfred@s-direktnet.de>: + * configure.host (i[3456]86-*-linux*libc1*): Renamed from + i[3456]86-*-linux*. + (i[3456]86-*-linux*): New host. + +Thu Jun 26 13:54:03 1997 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/pe.sc: Put .rsrc after .reloc. Put input .rsrc + sections in the output .rsrc section. + +Wed Jun 25 12:48:41 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * configure.host (m68*-*-linux*libc1*): Renamed from + `m68*-*-linux*'. + (m68*-*-linux*): New configuration for use with GNU libc 2. + +Mon Jun 16 19:18:21 1997 Geoff Keating <geoffk@ozemail.com.au> + + * scripttempl/elfppc.sc: Correct .rela.sdata entries. + + * scripttempl/elfppc.sc: Put the PLT between the small and large + BSS segments. + * emulparams/elf32ppc.sh (TEXT_START_ADDR): The ABI says `A + program base of 0x02000000 is recommended...' because otherwise + shared libraries are less efficient. We use 0x01800000 because + otherwise it's impossible to branch to location 0, for instance if + you have an undefined weak symbol. + +Mon Jun 16 12:49:36 1997 H.J. Lu <hjl@gnu.ai.mit.edu> + + * ldlang.c (lang_place_undefineds): Add \n in einfo call. + (lang_size_sections): Likewise. + * ldlex.l: Likewise. + * emultempl/aix.em (gld${EMULATION_NAME}_read_file): Likewise. + * emultempl/mipsecoff.em (gld${EMULATION_NAME}_after_open): + Likewise. + (check_sections): Likewise. + (gld${EMULATION_NAME}_after_allocation): Likewise. + * emultempl/pe.em (gld_$${EMULATION_NAME}_before_allocation): + Likewise. + * mpw-eppcmac.c (gldppcmacos_read_file): Likewise. + * mpw-idtmips.c (gldmipsidt_after_open): Likewise. + (check_sections): Likewise. + (gldmipsidt_after_allocation): Likewise. + + * ldemul.c (ldemul_choose_mode): Remove unused einfo argument. + +Fri Jun 6 23:47:42 1997 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/pe.sc: Add zeroes after .idata$3 to mark the end of + the import list. + +Thu May 29 13:13:22 1997 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_place_section): Don't + crash if an output section has no BFD section. + +Fri May 23 15:23:25 1997 Fred Fish <fnf@cygnus.com> + + * lexsup.c (ld_options): Add entry for the new "task-link" option. + (parse_args): Handle the "task-link" option. + (OPTION_TASK_LINK): Add define. + +Wed May 21 17:44:15 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (main): Correct check of fclose return value when + handling --force-exe-suffix. + +Thu May 15 11:35:29 1997 Nick Clifton <nickc@cygnus.com> + + * ldlang.c (lang_check): Add test of the return value from the + call to bfd_merge_private_bfd_data(). + +Mon May 12 23:22:58 1997 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elfmips.sc: Remove. + * scripttempl/elf.sc: Set ENTRY based on target. Permit + TEXT_DYNAMIC to control .dynamic segment. Permit + SHLIB_TEXT_START_ADDR to set start of shared object. Support + INITIAL_READONLY_SECTIONS. Put .stub in .text. Only put + .gnu.linkonce.t* in .text when relocating. Support + OTHER_TEXT_SECTIONS. Support SHLIB_DATA_ADDR as well as + DATA_ADDR. Support OTHER_GOT_SYMBOLS and OTHER_GOT_SECTIONS. + * emulparams/elf32b4300.sh (SCRIPT_NAME): Set to elf. + (DATA_ADDR): Don't set. + (INITIAL_READONLY_SECTIONS): Rename from OTHER_READONLY_SECTIONS. + (OTHER_TEXT_SECTIONS): Set. + (OTHER_GOT_SECTIONS): Rename from OTHER_READWRITE_SECTIONS. + (MACHINE): Set to empty string. + * emulparams/elf32l4300.sh: Likewise. + * emulparams/elf32ebmip.sh: Likewise. + * emulparams/elf32elmip.sh: Likewise. + * emulparams/elf32bmip.sh: Likewise. Also: + (TEXT_DYNAMIC): Set. + * emulparams/elf32lmips.sh: Likewise. + * Makefile.in (eelf32bmips.c): Depend upon elf.sc rather than + elfmips.sc. + (eelf32ebmips.c, eelf32elmips.c, eelf32lmip.c): Likewise. + +Mon May 12 11:11:06 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * scripttempl/elf.sc: Don't align the data segment on the next 8 + byte boundary, instead let the linker use whatever the individual + sections require. + +Fri May 9 17:45:46 1997 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (i[3456]86-*-gnu*): Don't include Mach support. + +Tue May 6 13:21:19 1997 Ian Lance Taylor <ian@cygnus.com> + + From Sean McNeil <sean@mcneil.com>: + * emultempl/pe.em (sort_by_file_name): Sort by archive name + first. + (sort_sections): Sort all sections, not just sections in the same + archive. + +Mon May 5 18:19:55 1997 Philip Blundell <pjb27@cam.ac.uk> + + * configure.tgt, configure.host: cope with '*-*-linux-gnuaout' + targets. + +Fri May 2 15:54:28 1997 Mike Meissner <meissner@cygnus.com> + + * scripttempl/tic80coff.sc (.text): Add a leading underscore to + __{D,C}TOR_{LIST,END}__ definations. Rearrange the order of items + in the .text section. Move .const, .ctors, .dtors into separate + sections. + +Wed Apr 30 12:23:21 1997 Manfred Hollstein <manfred@s-direktnet.de> + + * scripttempl/m88kbcs.sc (__.initp.end, _etext): Added whitespace + around assignment of current location pointer. + +Thu Apr 17 13:07:18 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldctor.c (ldctor_build_sets): Make sure the set is aligned + appropriately. + +Tue Apr 15 13:19:26 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (INSTALL): Set to @INSTALL@. + (INSTALL_XFORM, INSTALL_XFORM1): Remove. + (install): Depend upon ld.new and installdirs. Use + $(program_transform_name) directly, rather than using + $(INSTALL_XFORM) and $(INSTALL_XFORM1). + (installdirs): New target. + (install-info): Run mkinstalldirs. + +Mon Apr 14 12:06:15 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (INSTALL): Change install.sh to install-sh. + + From Thomas Graichen <graichen@rzpd.de>: + * configure.in: Use ${CONFIG_SHELL} when running $ac_config_sub. + * configure: Rebuild. + +Fri Apr 4 11:42:41 1997 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/pe.em: Include "libiberty.h". + (sort_sections_1): Use xmalloc rather than alloca. + + * ldlex.l: Recognize SQUAD. + * ldgram.y (length): Add SQUAD. + * ldctor.c (ldctor_build_sets): Use SQUAD for a signed 8 byte + reloc. + * ldlang.c (print_data_statement): Handle SQUAD. + (lang_size_sections, lang_do_assignments): Likewise. + * ldexp.c (exp_print_token): Add SQUAD to table. + * ldwrite.c (build_link_order): Handle SQUAD. + * ld.texinfo (Section Data Expressions): Document SQUAD. + +Thu Apr 3 13:19:40 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldver.c (ld_program_version): Set to 2.8.1. + + * Branched binutils 2.8. + +Wed Apr 2 11:55:27 1997 Ian Lance Taylor <ian@cygnus.com> + + * mpw-idtmips.c: Rename from mpw-emipsidt.c. + * mpw-elfmips.c: Rename from mpw-emipself.c. + * mpw-config.in: Update accordingly. + + * ldlang.c (lang_process): Call lang_check immediately after + opening the input files, rather than at the end of the link. + +Mon Mar 31 23:44:00 1997 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/pe.em (init): Fully bracket initializer. + (set_pe_stack_heap): Remove locals begin_commit and end. + (gld_${EMULATION_NAME}_after_open): Remove unused local i. + (gld${EMULATION_NAME}_place_orphan): Remove unused local ptr. + +Mon Mar 31 16:35:51 1997 Joel Sherrill <joel@oarcorp.com> + + * configure.tgt (hppa*-*-rtems*): New target, like hppa-*-*elf*. + +Fri Mar 28 15:29:23 1997 H.J. Lu <hjl@gnu.ai.mit.edu> + + Contributed by David S. Miller <davem@caip.rutgers.edu>: + * configure.tgt (sparc*-*-linuxaout*): New target. + (sparc*-*-linux*): New target. + * emulparams/sparclinux.sh: New file. + * Makefile.in (ALL_EMULATIONS): Add esparclinux.o. + (esparclinux.c): New target. + +Fri Mar 28 14:30:12 1997 Ian Lance Taylor <ian@cygnus.com> + + From Ralf Baechle <ralf@gnu.ai.mit.edu>: + * configure.tgt: Set targ_extra_emuls for mips*el-*-linux* and + mips*-*-linux*. Use elf32bmip and elf32lmip, not elf32ebmip and + elf32elmip. + +Thu Mar 27 17:14:32 1997 Ian Lance Taylor <ian@cygnus.com> + + * lexsup.c (parse_args): Update copyright date in version + message. + +Fri Mar 21 12:28:41 1997 Philippe De Muyter <phdm@info.ucl.ac.be> + + * emulparams/delta68.sh (OUTPUT_FORMAT): Set to "coff-m68k-sysv". + +Tue Mar 18 11:16:23 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in: Rebuild dependencies. + + * emultempl/aix.em: Include "obstack.h". + +Mon Mar 17 19:26:06 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c: Include "obstack.h". + +Sat Mar 15 23:23:46 1997 Fred Fish <fnf@cygnus.com> + + * configure.tgt (powerpc-*-beos*): Use aixppc for targ_emul. + +Sat Mar 15 18:10:38 1997 H.J. Lu <hjl@lucon.org> + + * ldemul.h (ldemul_list_emulations): Use full prototype. + * ldlang.c (print_one_symbol): Add declaration. + * ldlang.h (dprint_statements): Declare. + * ldmain.c (remove_output): Declare. + * ldmisc.c (vfinfo): Declare. + * ldwrite.c (clone_section): Declare. + (split_sections): Make static. Declare. + * mri.c: Include libiberty.h. + (strdup): Don't declare. + (mri_alias): Use xstrdup rather than strdup. + +Fri Mar 14 21:30:06 1997 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elfmips.sc: Change handling of data area when + generating a shared library to not skip a large block of memory. + From Per Fogelstrom <pefo@cvs.openbsd.org>. + +Wed Mar 12 21:33:09 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (multiple_definition): Only skip the warning if the + output section is absolute when the input section is not + absolute. + + * ldlex.l: Accept whitespace in VERS_START state. Warn about + invalid characters in VERS_* states. + +Tue Mar 11 13:51:31 1997 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_read_file): Don't let a + trailing space lead us to think that there is a zero address. + +Sun Mar 9 23:06:35 1997 Eric Youngdale <eric@andante.jic.com> + + * ldgram.y (vers_node): Correct typo of '(' for '{'. + +Fri Mar 7 18:40:12 1997 Fred Fish <fnf@cygnus.com> + + * scripttempl/tic80coff.sc (ENTRY): Entry symbol is __start + rather than _start. + (__edata): Define this rather than "edata". + (__end): Define this rather than "end". + +Tue Mar 4 17:18:35 1997 Michael Meissner <meissner@cygnus.com> + + * configure.tgt (tic80-*-*): Allow dropping of -coff. + +Sun Mar 2 22:59:49 1997 Fred Fish <fnf@cygnus.com> + + * Makefile.in (ld.dvi): Set MAKEINFO environment variable as well + as TEXINPUTS. Needed for building in separate build dir. + * ldint.texinfo (SCRIPT_NAME): Fix typo. + * emulparams/tic80coff.sh: Rewrite to include internal documentation + about each shell variable that is set (or not set). + * scripttempl/tic80coff.sc: Complete rewrite. + +Fri Feb 28 17:42:27 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (main): Call bfd_set_default_target. + * Makefile.in (ldmain.o): Define TARGET when compiling. + +Thu Feb 27 11:41:03 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (main): Don't initialize link_info.lprefix or + link_info.lprefix_len. + * emultempl/hppaelf.em (hppaelf_before_parse): Likewise. + + * emultempl/m88kbcs.em: Remove. + * emulparams/m88kbcs.sh (TEMPLATE_NAME): Don't set. + * Makefile.in (em88kbcs.c): Depend upon generic.em rather than + m88kbcs.em. + + * mri.c (mri_draw_tree): Pass noload_section, not SEC_NEVER_LOAD, + to lang_enter_output_section_statement. From Mark Rasin + <mark.rasin@telrad.co.il>. + +Wed Feb 26 11:51:44 1997 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_one_common): Clear SEC_IS_COMMON from common + section. + +Tue Feb 25 20:38:11 1997 Stan Shebs <shebs@andros.cygnus.com> + + * configure.tgt (mips*-*-lnews*): New target. + * Makefile.in (emipslnews.c): New target. + * emulparams/mipslnews.sh: New file. + +Tue Feb 25 16:04:09 1997 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (hold_interp): New static variable. + (gld${EMULATION_NAME}_place_orphan): Put loadable .note sections + after hold_interp. Choose a unique output section name. + (gld${EMULATION_NAME}_place_section): Don't set hold_use if the + SEC_LOAD or SEC_ALLOC flags differ. Set hold_interp. + +Mon Feb 24 18:16:09 1997 Ian Lance Taylor <ian@cygnus.com> + + From Eric Youngdale <eric@andante.jic.com>: + * ldlex.l (V_TAG, V_IDENTIFIER): New macros. + (VERS_START, VERS_SCRIPT, VERS_NODE): New states to parse version + information. + (ldlex_version_script, ldlex_version_file): New functions. + * ldlex.h (enum input_enum): Add input_version_script. + (ldlex_version_script): Declare. + (ldlex_version_file): Declare. + * ldgram.y (%union): Add deflist, versyms, and versnode. + (VERS_TAG, VERS_IDENTIFIER): New terminals. + (GLOBAL, LOCAL, VERSION, INPUT_VERSION_SCRIPT): New terminals. + (file): Accept INPUT_VERSION_SCRIPT. + (ifile_p1): Accept version. + (version_script_file): New nonterminal. + (version, vers_nodes, vers_node): Likewise. + (verdep, vers_tag, ver_defns): Likewise. + * ldlang.c (lang_elf_version_info): New global variable. + (lang_new_vers_regex): New function. + (lang_new_vers_node): New function. + (version_index): New static variable. + (lang_register_vers_node): New function. + (lang_add_vers_depend): New function. + * ldlang.h (lang_elf_version_info): Declare. + (lang_new_vers_regex, lang_new_vers_node): Declare. + (lang_add_vers_depend, lang_register_vers_node): Declare. + * lexsup.c (OPTION_VERSION_SCRIPT): Define. + (ld_options): Add "version-script". + (parse_args): Handle OPTION_VERSION_SCRIPT. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): + Pass lang_elf_version_info to size_dynamic_sections. + * scripttempl/elf.sc: Add .gnu.version sections. + * ld.texinfo: Document symbol versioning. + +Fri Feb 21 17:37:51 1997 Martin M. Hunt <hunt@pizza.cygnus.com> + + * Makefile.in (ed30velf.c): New target. + * configure.tgt (d30v-*-*): New target. + * emulparams/d30velf.sh: New file. + * scripttempl/elfd30v.sc: New file. + +Fri Feb 14 18:28:31 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo (Option Commands): Document the INCLUDE command. + +Thu Feb 13 20:31:37 1997 Philippe De Muyter <phdm@info.ucl.ac.be> + + * configure.in: Call BFD_NEED_DECLARATION on getenv. + * acconfig.h (NEED_DECLARATION_GETENV): New macro. + * sysdep.h (getenv): Declare if NEED_DECLARATION_GETENV. + * ldemul.c (ld_emul_default_target): Do not cast getenv return + value. + * ldmain.c (get_emulation): Likewise. + * configure, config.in: Rebuild. + +Tue Feb 11 15:34:26 1997 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elfmips.sc: When relocating, put .mips16.fn.* and + .mips16.call.* in .text. + +Sun Feb 9 18:09:13 1997 Fred Fish <fnf@cygnus.com> + + * emulparams/tic80coff.sh: New (dummy) file for TIc80. + * scripttempl/tic80coff.sc: New (dummy) file for TIc80. + * Makefile.in (etic80coff.c): Add target and rule to build it. + * configure.tgt (tic80-*-coff): Set targ_emul to tic80coff. + +Fri Jan 31 13:16:53 1997 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Search for + ".so" in the name, not ".so.". + (gld${EMULATION_NAME}_search_dir): Accept a plain .so file. + + * Makefile.in (ld.info): Add -I$(srcdir). From Alan Modra + <alan@spri.levels.unisa.edu.au>. + +Thu Jan 30 11:31:52 1997 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/sunos.em: Include <ctype.h>. + (gld${EMULATION_NAME}_find_so): Skip the directory name when + searching for ".so.". + (gld${EMULATION_NAME}_search_dir): Make sure that the library name + has a version number, and that only version numbers follow .so. + +Wed Jan 29 18:15:00 1997 Geoffrey Noer <noer@cygnus.com> + + * scripttempl/pe.sc: + * scripttempl/ppcpe.sc: add *(.gcc_except_table) to the text + section so Win32 executables are valid. + +Mon Jan 27 12:28:43 1997 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elf.sc: Put linkonce reloc section in other + appropriate reloc sections. + * scripttempl/elfmips.sc: Add linkonce support. + * scripttempl/elfppc.sc: Likewise. + +Fri Jan 24 10:44:09 1997 Jeffrey A Law (law@cygnus.com) + + * emulparms/mn10200.sh (OTHER_RELOCATING_SECTIONS): Move the + stack up to 0x80000. + * emulparms/mn10300.sh (OTHER_RELOCATING_SECTIONS): Likewise. + +Tue Jan 21 12:11:10 1997 Doug Evans <dje@seba.cygnus.com> + + * emulparams/m32relf.sh (OTHER_RELOCATING_SECTIONS): Use PROVIDE + to define `_stack'. + +Thu Jan 16 17:07:52 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld.h (args_type): Rename auxiliary_filter_shlib to + auxiliary_filters, and make it char **. + * lexsup.c (parse_args): Handle -f by setting up an array. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Use + new name of auxiliary_filters. + + * ld.texinfo (Options): Improve documentation of --filter and + --auxiliary. + +Tue Jan 14 15:44:28 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo (Options): Clarify that the normal usage is -T. + (Commands): Likewise. + +Thu Jan 9 11:26:27 1997 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/armcoff.sc: Correct mask used for .data address. + +Wed Jan 8 15:14:59 1997 Geoffrey Noer <noer@cygnus.com> + + * emultempl/pe.em: make default executable a.exe instead of + a.out + +Fri Jan 3 17:33:34 1997 Richard Henderson <rth@tamu.edu> + + * scripttempl/elf.sc: Move .got closer to .sdata and .sbss by + shifting .plt back. Rumour has it that the NetBSD ld.so depends + on .dynamic being after .got, so we leave that. + +Fri Jan 3 14:04:40 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (clean): Don't remove configdoc.texi. + (maintainer-clean): Do remove configdoc.texi. + + * ld.texinfo (Operators): Remove '@' from @smallexmple in comment + to avoid confusing texi2roff. + +Fri Jan 3 11:27:02 1997 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/v850.sc (.zdata): Add .zcommon section. + (.tdata): Add .tcommon and .tcommon_byte sections. + +Thu Jan 2 18:14:32 1997 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (mips*el-*-linux*, mips*-*-linux*): New targets. + * scripttempl/elfmips.sc: Use __start as the entry address for + mips*-*-linux*. + +Tue Dec 31 14:48:30 1996 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (ALL_CFLAGS): Add -D_GNU_SOURCE. + + * ld.h (args_type): Add filter_shlib and auxiliary_filter_shlib + fields. + * lexsup.c (parse_args): Recognize --auxiliary/-f and + --filter/-F. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): + Pass filter_shlib and auxiliary_filter_shlib to + size_dynamic_sections. + * ld.texinfo, ld.1: Document --filter/-F and --auxiliary/-f. + +Mon Dec 30 13:55:57 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/v850.sc (.tdata) Add .tbss and .tbyte sections. + +Wed Dec 18 22:57:35 1996 Stan Shebs <shebs@andros.cygnus.com> + + * mpw-make.sed: Use NewFolderRecursive for installation. + +Fri Dec 13 14:08:50 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/v850.sc: Make sure __{e,g}p start relative to the + {s,t}data sections. Do not emit any linker generated symbols if + -r. Use {TEXT,{Z,S,T}DATA}_START_ADDR variables to initialize + where the different sections go. Change some whitespace. + + * emulparams/v850.sh ({TEXT,{Z,S,T}DATA}_START_ADDR): Define + appropriately. Remove crud not used anymore. + +Fri Dec 13 10:19:57 1996 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (emn10200.c): Add dependencies. + * configure.tgt: Handle mn10200. + * emulparms/mn10200.sh: New file. + +Thu Dec 12 17:04:55 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/gld960c.em: Include <ctype.h>. + (gld960_set_output_arch): Get the machine type from the -A option + if there is one, rather than always using core. + +Sat Dec 7 10:07:51 1996 Jeffrey A Law (law@cygnus.com) + + * emulparms/mn10300.sh: Handle leading underscores. + +Thu Dec 5 13:45:58 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_place_section): Only + set hold_rel if SEC_ALLOC is set. + +Tue Dec 3 11:29:20 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (section_already_linked): Set the output_offset as well + as the output_section when only reading symbols from a file. + +Mon Dec 2 11:43:50 1996 Ian Lance Taylor <ian@cygnus.com> + + * emulparams/*.sh: Make sure that each set of parameters which + uses the elf.sc script sets MACHINE. + +Wed Nov 27 03:22:05 1996 Jason Merrill <jason@yorick.cygnus.com> + + * scripttempl/elf{,mips,ppc}.sc: Add the remaining DWARF sections. + * scripttempl/elfd10v.sc: Likewise. + * scripttempl/v850.sc: Likewise. + +Tue Nov 26 16:58:33 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure: Rebuild with autoconf 2.12. + +Mon Nov 25 12:17:55 1996 Jim Wilson <wilson@cygnus.com> + + * emultempl/pe.em (gld_${EMULATION_NAME}_set_symbols): Add case + for bfd_vma to init loop. + +Mon Nov 25 09:55:07 1996 Jeffrey A Law (law@cygnus.com) + + * emulparms/mn10300.sh: Remove bogus '_' prefix for + entry symbol and ctor/dtor stuff. + +Fri Nov 15 13:00:18 1996 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (emn10300.c): Add dependencies. + * configure.tgt: Handle mn10300. + * emulparms/mn10300.sh: New file. + +Tue Nov 5 10:57:50 1996 Martin M. Hunt <hunt@pizza.cygnus.com> + + * emulparams/d10velf.sh (READONLY_START_ADDR): Changed to 0x2000004. + (EMBEDDED): Define. + +Fri Nov 1 10:01:27 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo: Add section on reporting bugs. + + * scripttempl/m68kcoff.sc: Make sure the etext and __CTOR_LIST__ + symbols are correctly aligned. + +Thu Oct 31 09:28:59 1996 Jeffrey A Law (law@cygnus.com) + + * scriptempl/v850.sc (zdata): Handle reszdata, romzdata and + romzbss too. + +Tue Oct 29 12:33:05 1996 Martin M. Hunt <hunt@pizza.cygnus.com> + + * emulparams/d10velf.sh: Changes needed for D10V-EVA board. + Set TEXT_START_ADDR to 0x1000000. Set READONLY_START_ADDR to + 0x2000000. + + * scripttempl/elfd10v.sc: Fix calculation of .text. Change + .stack to start at 0x2007ffe. + +Mon Oct 28 15:37:00 1996 Doug Evans <dje@canuck.cygnus.com> + + * configure.tgt (sparclet*-*-aout*): Delete, use sparc*-*-aout*. + +Wed Oct 23 16:17:22 1996 Jeffrey A Law (law@cygnus.com) + + * scriptempl/v850.sc (zdata): Fix typo "zrodata" -> "rozdata". + + * scriptempl/v850.sc (zdata): Make sure this stays + in lo-memory. + +Tue Oct 22 11:36:47 1996 Jeffrey A Law (law@cygnus.com) + + * scripttempl/v850.sc (__ep): Put it at the start + of the tda section. + + * scriptempl/v850.sc: Move all "normal" sections into + the external memory region (0x100000 - 0x200000). + +Mon Oct 21 17:16:59 1996 Michael Meissner <meissner@wogglebug.tiac.net> + + * scripttempl/elfd10v.sc: Clone from elf.sc, move .text to + 0x10000, so that is more room for data. + + * emulparams/d10velf.sh (TEXT_START_ADDR): Now 0x100000. + (READONLY_START_ADDR): Now 0x0. + (SCRIPT_NAME): Now elfd10v. + + * Makefile.in (ed10velf.c): Depend on elfd10v.sc, not elf.sc. + +Fri Oct 18 22:12:49 1996 Doug Evans <dje@canuck.cygnus.com> + + * emulparams/m32relf.sh (TEXT_START_ADDR): Change from 0 to 0x100. + +Fri Oct 18 15:43:38 1996 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (ALL_EMULATIONS): Remove eelf64alpha.o. + (ALL_64_EMULATIONS): New variable. + * configure.in: Accept --enable-64-bit-bfd option. If it is set + with --enable-targets=all, include ALL_64_EMULATIONS in + EMULATION_OFILES. + * configure: Rebuild. + +Fri Oct 18 12:58:35 1996 Jeffrey A Law (law@cygnus.com) + + * scripttempl/v850.sc (__gp, __ep): Define. + +Thu Oct 17 18:14:07 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo: Try to consistently use a single or a double dash + for each option. + +Thu Oct 17 10:17:20 1996 Doug Evans <dje@canuck.cygnus.com> + + * emulparams/m32relf.sh (EMBEDDED): Define. + +Thu Oct 17 10:56:49 1996 Jeffrey A Law (law@cygnus.com) + + * scripttempl/v850.sc (.zdata): Add this before .text. + (.sdata): Also include .rosdata as part of the .sdata. + (.tdata): Include this just before .sdata. + + * emulparms/v850.sh (SCRIPT_NAME): Use "v850" not "elf". + * scripttempl/v850.sc: Wrap script with a "cat << EOF". + +Wed Oct 16 23:10:01 1996 Jeffrey A Law (law@cygnus.com) + + * scripttempl/v850.sc: New linker script for the V850. + * Makefile.in: Use it. + +Thu Oct 10 17:57:00 1996 Ian Lance Taylor <ian@cygnus.com> + + * emulparams/elf32b4300.sh: Define _gp in OTHER_GOT_SYMBOLS, not + OTHER_READWRITE_SECTIONS. + * emulparams/elf32l4300.sh: Likewise. + +Wed Oct 9 14:36:18 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.h (ld_config_type): Add warn_section_align field. + * lexsup.c (OPTION_WARN_SECTION_ALIGN): Define. + (ld_options): Add --warn-section-align. + (parse_args): Handle --warn-section-align. + * ldlang.c (lang_size_sections): If warn_section_align, warn if + the start of a section changes due to alignment. + * ld.texinfo, ld.1: Document --warn-section-align. + * ld.texinfo: Change some single dashes to double dashes. + + * emultempl/pe.em (set_pe_subsystem): Record entry symbol for each + subsystem type. Ifdef out os2 type. Recognize a version number. + +Tue Oct 8 12:07:13 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/pe.em (set_pe_subsystem): When setting the subsystem + to windows, set the entry point. + + * Makefile.in (ldlex.c): Don't pass any options to $(LEX). + +Mon Oct 7 17:29:05 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo (Options): Mention .so extensions for shared + libraries. + +Sun Oct 6 22:35:36 1996 Jason Merrill <jason@yorick.cygnus.com> + + * scripttempl/elf{,mips,ppc}.sc: Add DWARF 2 sections. + +Fri Oct 4 18:49:31 1996 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/m68kcoff.sc: Only set the address of .text if + RELOCATING. + +Fri Oct 4 10:59:52 1996 Doug Evans <dje@canuck.cygnus.com> + + * emulparams/sparcaout.sh ({BIG,LITTLE}_OUTPUT_FORMAT): Define. + * scripttempl/aout.sc ({BIG,LITTLE}_OUTPUT_FORMAT): Provide default. + (OUTPUT_FORMAT): Support bi-endian targets. + +Thu Oct 3 13:52:03 1996 Ian Lance Taylor <ian@cygnus.com> + + * fnmatch.h, fnmatch.c: Remove (now in libiberty). + * Makefile.in: Rebuild dependencies. + (CFILES): Remove fnmatch.c. + (HFILES): Remove fnmatch.h. + (OFILES): Remove fnmatch.o. + +Thu Oct 3 15:41:24 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (mostlyclean): Move config.log to distclean. + +Wed Oct 2 23:45:25 1996 Geoffrey Noer <noer@cygnus.com> + + * emultmpl/pe.em: increase size of stack reserve to 0x2000000 + (necessary in order to compile parse.c in gcc sources under NT) + +Wed Oct 2 14:49:10 1996 Ian Lance Taylor <ian@cygnus.com> + + * lexsup.c (ld_options): Fix typo in --rpath-link description. + * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Suggest + --rpath if a needed library is not found. + +Tue Oct 1 16:17:33 1996 Joel Sherrill <joel@oarcorp.com> + + * configure.tgt (mips*-*-rtems*): New target, like mips*-*-elf*. + +Tue Oct 1 15:50:34 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo (Options): Give more detail on -l option. + + * scripttempl/elfmips.sc: Handle CREATE_SHLIB the same way that + elf.sc does, so that glibc works better. + + * ldver.c (ld_program_version): New variable. + (ldversion): Use it. + * ldver.h (ld_program_version): Declare. + * lexsup.c (ld_options): Handle --dll-verbose like --verbose, not + --version. Change --version handling to match current GNU + standards. + (help): Print bug report address. + +Mon Sep 30 12:14:43 1996 Doug Evans <dje@canuck.cygnus.com> + + * Makefile.in (em32relf.c): Add rule for. + * configure.tgt (m32r-*-*): Recognize. + * emulparams/m32relf.sh: New file. + +Thu Sep 26 13:58:47 1996 Stan Shebs <shebs@andros.cygnus.com> + + * mpw-make.sed: Add symbolic doublequoting to ldmain compile edit. + * mpw-config.in: Add mips-*-* case as mips-elf, and use more + wildcards in matching. + * mpw-emipself.c: New file, pregenerated mips elf emulation. + +Tue Sep 17 12:18:21 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldint.texinfo: Rewrote. + + * configure.tgt: Add cases for MIPS 5000 like MIPS 4300. + +Mon Sep 16 17:55:21 1996 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/armcoff.sc: Only define symbols if RELOCATING. Fix + syntax error on __end__ line. + + * scripttempl/armcoff.sc: For -N or -n, don't align .data. From + Chris Hadley <Christopher.Hadley@cl.cam.ac.uk> + +Sun Sep 15 22:09:56 1996 Jeffrey A Law (law@cygnus.com) + + * emulparms/v850.sh: Fix OTHER_RELOCATING_SECTIONS. + +Sun Sep 15 10:38:16 1996 Mark Alexander <marka@cygnus.com> + + * emulparms/d10v.sh: Set OTHER_RELOCATING_SECTIONS to put + stack at top of simulator memory. + +Fri Sep 13 15:49:45 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlex.l (SYMBOLCHARN): Add $, _, and ~. + +Wed Sep 11 23:30:42 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (get_emulation): Check for -mips4 like -mips1, et. al. + +Thu Sep 5 15:24:12 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (section_already_linked): Accept a lang_input_statement + as the PTR argument. If the file is symbols only, discard all + input sections. + (ldlang_add_file): Pass entry to bfd_map_over_sections. + +Wed Sep 4 15:53:43 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (alpha-*-gnu*): New target. From Fila Kolodny + <fila@ibi.com>. + +Tue Sep 3 00:52:54 1996 Jeffrey A Law (law@cygnus.com) + + * emulparms/v850.sh: Set OTHER_RELOCATING_SECTIONS + +Sun Sep 1 21:48:58 1996 Jeffrey A Law (law@cygnus.com) + + * emulparms/v850.sh: Set EMBEDDED. + +Fri Aug 30 22:30:30 1996 Jeffrey A Law (law@cygnus.com) + + * emulparms/v850.sh: Entry symbol is "_start", tweak + ctor/dtor support. + +Fri Aug 30 18:32:31 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (sh-*-elf*): New target. + * emulparams/shelf.sh: New file. + * emulparams/shlelf.sh: New file. + * Makefile.in (ALL_EMULATIONS): Add eshelf.o and eshlelf.o. + (eshelf.c, eshlelf.c): New targets. + * scripttempl/elf.sc: If EMBEDDED is defined, then don't add + SIZEOF_HEADERS to TEXT_START_ADDR. Expand CTOR_START and CTOR_END + around .ctors, and DTOR_START and DTOR_END around .dtors. Expand + OTHER_RELOCATING_SECTIONS if RELOCATING. + +Thu Aug 29 16:57:46 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * configure.{host,tgt} (i[345]86-*-*): Recognize i686 for pentium + pro. + +Mon Aug 26 12:58:11 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldgram.y (section): Add opt_nocrossrefs; pass value to + lang_enter_overlay. + (opt_nocrossrefs): New nonterminal. + * ldlex.l: Recognize NOCROSSREFS keyword in EXPRESSION mode. + * ldlang.c (overlay_nocrossrefs): New static variable. + (lang_enter_overlay): Add nocrossrefs parameter. + (lang_leave_overlay): Only add nocrossrefs if overlay_nocrossrefs + is set. Initialize overlay_nocrossrefs. + * ldlang.h (lang_enter_overlay): Update declaration. + * ld.texinfo (Overlays): Update documentation. + + * ldver.c (ldversion): Print GNU ld in the version message. + +Thu Aug 22 17:10:40 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.host: Set HLDENV. + * configure.in: Substitute HLDENV. + * configure: Rebuild. + * Makefile.in (HLDENV): New variable. + ($(LD_PROG)): Use $(HLDENV). + +Thu Aug 22 16:29:28 1996 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (ev850.c): New target. + * configure.tgt (v850-*-*): New target. + * emulparams/v850.sh: New file. + +Thu Aug 22 11:16:02 1996 Stan Shebs <shebs@andros.cygnus.com> + + * mpw-make.sed: Add @DASH_C_FLAG@ to compiler edit. + +Wed Aug 21 11:26:37 1996 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elf.sc: Put .gnu.linkonce* sections in appropriate + containing sections. + +Mon Aug 19 13:01:42 1996 Ian Lance Taylor <ian@cygnus.com> + + * fnmatch.c: Include sysdep.h. + +Mon Aug 19 11:28:29 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * genscripts.sh: Undo 8/16 change. + + * emulparams/d10velf.sh (MACHINE): Explicitly set to nothing. + +Fri Aug 16 19:18:08 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * genscripts.sh: Explicitly reset any shell variables set or used + by the various .sc scripts to allow inadvertant use of these + names as normal environment variables by the person running + configure. + + * Makefile.in (ed10velf.c): Use tdir_d10v, not tdir_arcelf. + +Fri Aug 16 14:15:41 1996 James G. Smith <jsmith@cygnus.co.uk> + + * scripttempl/armcoff.sc (__bss_start__, __bss_end__, + __data_start__, __data_end__): Added to keep in sync. with the + default ARM crt0.s. Added __CTOR_LIST__ and __DTOR_LIST__ support. + +Thu Aug 8 14:24:56 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldcref.c (check_reloc_refs): If info->same, look for any symbol + defined in info->defsec, not just the section symbol. + +Wed Aug 7 14:40:48 1996 Philippe De Muyter <phdm@info.ucl.ac.be> + + * configure.in: Call BFD_NEED_DECLARATION on strstr and sbrk. + * acconfig.h (NEED_DECLARATION_STRSTR): New macro. + (NEED_DECLARATION_SBRK): New macro. + * configure, config.in: Rebuild. + * sysdep.h (strstr): Declare if NEED_DECLARATION_STRSTR. + * ldmain.c (sbrk): Declare if HAVE_SBRK and + NEED_DECLARATION_SBRK. + + * ldlang.c (lang_record_phdrs): Cast xmalloc and xrealloc return. + +Mon Aug 5 16:26:14 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlex.l: Recognize OVERLAY. + * ldgram.y: Add section_phdr field to %union. + (section): Handle phdr_opt result. Add OVERLAY case. + (opt_exp_without_type): New nonterminal. + (phdr_opt): Return list of phdrs. + (overlay_section): New nonterminal. + * ldlang.c: Include <ctype.h>. + (lang_leave_output_section_statement): Add phdrs parameter. + Change all callers. + (lang_section_in_phdr): Remove. + (overlay_vma, overlay_lmn, overlay_max): New static variables. + (struct overlay_list): Define. + (overlay_list): New static variable. + (lang_enter_overlay, lang_enter_overlay_section): New functions. + (lang_leave_overlay_section, lang_leave_overlay): New functions. + * ldlang.h (lang_leave_output_section_statement): Update + declaration for new parameter. + (lang_section_in_phdr): Don't declare. + (lang_enter_overlay, lang_enter_overlay_section): Declare. + (lang_leave_overlay_section, lang_leave_overlay): Declare. + * ld.texinfo (Overlays): New node under SECTIONS, documenting + overlays. + + * ldlex.l: Recognize MAX and MIN. + * ldgram.y (MAX, MIN): New terminals. + (exp): Recognize MAX and MIN. + * ldexp.c (fold_binary): Handle MAX and MIN. + * ld.texinfo (Arithmetic Functions): Document MAX and MIN. + + * ld.texinfo (PHDRS): Use @cindex, not @kindex, for program header + index entries. + + * ldgram.y (SIZEOF, ADDR): Do not specify type. + + * ldcref.c (check_nocrossref): Skip symbols with no output + sections. + +Fri Aug 2 14:57:49 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldgram.y (LOADADDR): New terminal. + (exp): Handle LOADADDR. + * ldlex.l: Recognize LOADADDR. + * ldexp.c (exp_print_token): Add LOADADDR. + (fold_name): Implement LOADADDR. + * ldlang.c (exp_init_os): Treat LOADADDR like ADDR. + * ld.texinfo (Arithmetic Functions): Document LOADADDR. + +Thu Aug 1 12:52:19 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.h (check_nocrossrefs): Declare. + * ldlang.h (struct lang_nocrossref): Define. + (struct lang_nocrossrefs): Define. + (nocrossref_list): Declare. + (lang_add_nocrossref): Declare. + * ldlex.l: Recognize NOCROSSREFS keyword. + * ldgram.y (%union): Add nocrossref field. + (NOCROSSREFS): New terminal. + (ifile_p1): Recognize NOCROSSREFS. + (nocrossref_list): New nonterminal. + * ldlang.c (nocrossref_list): Define. + (lang_add_nocrossref): New function. + * ldmain.c (main): If nocrossref_list is not NULL, call + check_nocrossrefs. + (warning_callback): Free symbols if there is no place to store + them. + (notice): Call add_cref if nocrossref_list is not NULL. + * ldcref.c: Include "ldexp.h" and "ldlang.h". + (check_nocrossrefs): New function. + (check_nocrossref): New static function. + (struct check_refs_info): Define. + (check_refs, check_reloc_refs): New static functions. + * Makefile.in: Rebuild dependencies. + * ld.texinfo (Option Commands): Document NOCROSSREFS. + + * ld.texinfo (Section Placement): Improve the wording of the + wildcard documentation. Mention that wildcards are only searched + for on the command line, not in the file system. + + * emultempl/sunos.em (gld${EMULATION_NAME}_after_open): Move + definition of lib_path inside condition where it is used. + +Wed Jul 31 13:17:10 1996 Martin M. Hunt <hunt@pizza.cygnus.com> + + * emulparams/d10velf.sh: Now works with elf.sc. + +Wed Jul 31 11:52:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com> + + * emulparams/d10velf.sh (SCRIPT_NAME): Change to vanilla. + +Tue Jul 30 14:46:42 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_size_sections): Add the section VMA to the result + value when computing the address of a section. + + * ld.h (args_type): Add cref field. + * lexsup.c (parse_args): Set command_line.cref. + * ldmain.c (main): Check command_line.cref rather than + link_info.notice_all. + (notice): Likewise. + + * ldcref.c (output_one_cref): Don't crash if a symbol is defined + in a section without an owner. + +Mon Jul 29 17:23:33 1996 Ian Lance Taylor <ian@cygnus.com> + + * fnmatch.h, fnmatch.c: New files. + * ldlex.l: Remove unused definition of FILENAME. Add definition + of WILDCHAR. In SCRIPT mode, accept any sequence of WILDCHAR as a + NAME. + * ldgram.y (file_NAME_list): Accept '*' and '?' specially. + (input_section_spec): Accept '?' specially. + (statement): Change exp to mustbe_exp in length and FILL cases. + (section): Call ldlex_script before section statements, and call + ldlex_popstate after them. + * ldlang.c: Include "fnmatch.h". + (wildcardp): New static function. + (wild_section): Permit the section name to be a wildcard. + (wild_file): New static function, broken out of wild. + (wild): Call wild_file. Permit the file name to be a wildcard. + (open_input_bfds): Don't call lookup_name for a wildcard pattern. + * Makefile.in: Rebuild dependencies. + (CFILES): Add fnmatch.c. + (HFILES): Add fnmatch.h. + (OFILES): Add fnmatch.o. + * ld.texinfo: Document that file and section names can now be + wildcard patterns. + + * ldlang.c (lang_place_orphans): Correct condition: place a common + section if not relocateable or if common definitions are forced. + +Wed Jul 24 12:16:38 1996 Martin M. Hunt <hunt@pizza.cygnus.com> + + * emulparams/d10velf.sh (SCRIPT_NAME): Change to elf. + +Wed Jul 24 13:38:22 1996 Michael Meissner <meissner@wogglebug.tiac.net> + + * configure.tgt (d10v-*-*): Don't require the -elf, allow plain d10v. + +Tue Jul 23 10:36:19 1996 Martin M. Hunt <hunt@pizza.cygnus.com> + + * Makefile.in (ed10velf.c): New target. + * configure.tgt (d10v-*-elf*): New target. + * emulparams/d10velf.sh: New file. + +Thu Jul 18 16:25:39 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (sparc*-*-sysv4*): New target. From Andrew Gierth + <ANDREWG@microlise.co.uk>. + + * configure.host: Change irix5 to irix[56]*. + * configure.tgt: Likewise. + +Wed Jul 17 10:52:46 1996 Kim Knuttila <krk@cygnus.com> + + * emultempl/pe.em (sort_sections): Pay attention to return code. + + * ldmisc.c (demangle): Remove all prefix '.'s from a name. + +Mon Jul 15 11:49:49 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Round + the value of __start_SECNAME to the alignment required by the + section to be placed. + +Tue Jul 9 12:09:02 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (mips*el-*-elf*): Use elf32elmip. + (mips*-*-elf*): Use elf32ebmip. + * emulparams/elf32bmip.sh (EMBEDDED): Don't define. + * emulparams/elf32lmip.sh (EMBEDDED): Don't define. + * emulparams/elf32elmip.sh: New file; copy of elf32lmip.sh with + EMBEDDED defined. + * emulparams/elf32ebmip.sh: New file; copy of elf32bmip.sh with + EMBEDDED defined. + * emulparams/elf32b4300.sh (EMBEDDED): Define. + * emulparams/elf32l4300.sh (EMBEDDED): Define. + * Makefile.in (ALL_EMULATIONS): Add eelf32ebmip.o eelf32elmip.o. + (eelf32ebmip.c, eelf32elmip.c): New targets. + +Thu Jul 4 12:01:03 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldver.c (ldversion): Set version to cygnus-2.7.1. + + * Released binutils 2.7. + + * emulparams/pc532macha.sh: Rename from pc532machaout.sh to avoid + System V file name limitations. + * configure.tgt (nc32k-pc532-mach*, ns32k-pc532-ux*): Use + pc532macha rather than pc532machaout. + * Makefile.in (ALL_EMULATIONS): Change epc532machaout.o to + epc532macha.o. + (epc532macha.c): Rename target from epc532machaout.c. + +Wed Jul 3 11:40:10 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (print_padding_statement): Use %u, not %x, to print + fill value. + +Sun Jun 30 11:16:43 1996 Stan Shebs <shebs@andros.cygnus.com> + + * mpw-eppcmac.c: Update to reflect May 23 change to aix.em. + +Thu Jun 27 14:03:42 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Put the .sa + file just before the .so file, rather than just after. + + * configure.host: Use -print-file-name=FILE rather than piping + -print-libgcc-file-name through sed. + (i[345]86*-*-sco*, i[345]86-*-isc*): Create crtbegin.o and + crtend.o files, in case gcc doesn't use them. + * Makefile.in (mostlyclean): Remove crtbegin.o and crtend.o. + +Wed Jun 26 15:57:21 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (mips*-dec-osf*): New target. + +Tue Jun 25 22:15:29 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir, + INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set values. + (docdir): Removed. + * configure.in (AC_PREREQ): autoconf 2.5 or higher. + (AC_PROG_INSTALL): Added. + * configure: Rebuilt. + +Mon Jun 24 18:48:16 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/elfppc.sc (_GLOBAL_OFFSET_TABLE_): Don't do a + PROVIDE of _GLOBAL_OFFSET_TABLE_, since it needs to be at a + non-fixed location. + +Mon Jun 24 17:55:31 1996 Jouke Numan <jnuman@bazis.nl> + + * ldlang.h (enum section_type): Define. + (lang_output_section_statement_type): Remove loadable field. Add + sectype field. + (lang_enter_output_section_statement): Change flags parameter in + prototype to sectype. + * ldgram.y (typebits): Remove. + (sectype): New static variable. + (opt_at): Use sectype rather than typebits. + (type): Set sectype rather than typebits. + (atype): Likewise. + * ldlex.l: Recognize DSECT, COPY, INFO, and OVERLAY in + EXPRESSION mode. + * ldlang.c (lang_output_section_statement_lookup): Set sectype + field rather than loadable field. + (wild_doit): Check sectype rather than loadable. + (lang_record_phdrs): Likewise. + (lang_enter_output_section_statement): Rename flags parameter to + sectype. Set sectype field rather than loadable field. Set flags + field based on sectype. + +Mon Jun 24 12:00:32 1996 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elf.sc: Force .stab* and .comment sections to start + at 0. + + * configure.in: On alpha*-*-osf*, link against libbfd.a if not + using shared libraries. + * configure: Rebuild with autoconf 2.10. + +Fri Jun 21 17:40:56 1996 Joel Sherrill <joel@merlin.gcs.redstone.army.mil> + + * configure.tgt: Add support for *-*-rtems* configurations. + +Fri Jun 21 13:05:51 1996 Richard Henderson <rth@tamu.edu> + + * configure.tgt (alpha-*-linuxecoff*): New target. + (alpha-*-linux*): Use elf64alpha. + * emulparams/elf64alpha.sh: New file. + * emultempl/elf32.em: If ELFSIZE is not set, set it to 32. Use + ${ELFSIZE} rather than 32 when calling BFD routines. + (hold_rodata): New static variable. + (gld${EMULATION_NAME}_place_orphan): Use hold_rodata for a + readonly section that is not code. + (gld${EMULATION_NAME}_place_section): Set hold_rodata. Don't use + a .rel section unless its bfd_section field is not NULL. + * Makefile.in (ALL_EMULATIONS): Add eelf64alpha.o. + (eelf64alpha.c): New target. + +Fri Jun 21 12:45:46 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldmisc.c (vfinfo): Correct handling of 0 in %W case. + +Thu Jun 20 13:55:28 1996 Ian Lance Taylor <ian@cygnus.com> + + Add enough support to understand the gcc svr3.ifile script: + * ldlex.l: Recognize BLOCK and GROUP in EXPRESSION context. Add + BIND keyword. + * ldgram.y: Add BIND token. + (section): Recognize GROUP. + (opt_ext_with_type): Recognize a couple of cases of BIND. + * ldlang.c (init_os): Don't do anything if section is already + initialized. Call exp_init_os on addr_tree field. + (exp_init_os): New static function. + (map_input_to_output_sections): Call exp_init_os on assignment + expression. + (lang_place_orphans): Check for common sections by name COMMON + rather than by common_section field. Don't warn about absence of + [COMMON] command. + + * ldlang.h (lang_input_statement_type): Remove useless fields + common_section, common_output_section, and complained, as well as + all references to them. + + * ldexp.c: Reindent a lot of code. + (exp_fold_tree): Call FAIL rather than einfo in default case. + +Wed Jun 19 11:40:14 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.host (m88*-*-dgux*): Quote HOSTING_CRT0. From + <randall.hron@medaphis.com>. + +Tue Jun 18 15:53:09 1996 Jeffrey A. Law <law@rtl.cygnus.com> + + * scripttempl/h8300s.sc: New file for H8/S. + * emulpararms/h8300s.sh: New file for H8/S. + * Makefile.in (ALL_EMULATIONS): Add H8/S. + (e_h8300s.c): Add dependencies. + * configure.tgt: Add H8/S to targ_extra_emuls. + +Tue Jun 18 17:55:39 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (i[345]86*-*-isc*): New target. From + <uddeborg@carmen.se>. + +Wed Jun 12 12:46:21 1996 Ian Lance Taylor <ian@cygnus.com> + + * lexsup.c: Include "libiberty.h". + (parse_args): Copy the -Y argument into memory. + (set_default_dirlist): Don't put the ':' back into the directory + list. + +Fri Jun 7 11:27:42 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/sunos.em: Include libiberty.h. + (gld${EMULATION_NAME}_set_symbols): New static function to add + LD_LIBRARY_PATH to the list of search directories. + (ld_${EMULATION_NAME}_emulation): Add new set_symbols routine. + +Thu Jun 6 11:50:31 1996 Ian Lance Taylor <ian@cygnus.com> + + * emulparams/elf32bmip.sh (OTHER_GOT_SYMBOLS): Use ALIGN(16) + rather than . when computing _gp value. From Per Fogelstrom. + * emulparams/elf32lmip.sh (OTHER_GOT_SYMBOLS): Likewise. + + * ldmain.c (main): Don't close and unlink the file on error, since + remove_output will do it anyhow. + * ldlang.c (open_output): Set boolean variable to true, not 1. + +Wed Jun 5 18:34:14 1996 James G. Smith <jsmith@cygnus.co.uk> + + * emulparams/{elf32b4300.sh,elf32l4300.sh} (SCRIPT_NAME): Use + elfmips instead of elf. + +Tue Jun 4 18:43:07 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldcref.c: New file. + * ld.h (add_cref, output_cref): Declare. + * ldmain.c (main): Initialize notice_all field. If it is set at + end of link, call output_cref. + (notice): Rename from notice_ysym. Check notice_all. + * ldmisc.c (finfo): Make globally visible. + * ldmisc.h (finfo): Declare. + * lexsup.c (OPTION_CREF): Define. + (ld_options): Add "cref". + (parse_args): Handle OPTION_CREF. + * Makefile.in: Rebuild dependencies. + (CFILES): Add ldcref.c. + (OFILES): Add ldcref.o. + * ld.texinfo, ld.1: Document --cref. + +Tue Jun 4 12:12:25 1996 Tom Tromey <tromey@csk3.cygnus.com> + + * Makefile.in (install): Make $(tooldir) and $(tooldir)/bin. + +Fri May 31 12:40:55 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/pe.em (sort_sections): Don't assume that a + wild_statement has a section name. + +Wed May 29 13:13:35 1996 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/elfmips.sc: Quote test -z argument. + + * ld.texinfo: Clarify the CONSTRUCTORS command. + +Thu May 23 16:07:44 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_read_file): Initialize + file, not impfile. + +Wed May 22 11:31:30 1996 Doug Evans <dje@seba.cygnus.com> + + * ldlang.c (wild_doit): Don't copy over SEC_LINK_{ONCE,DUPLICATES} + if final link. + * emultempl/pe.em (sfunc): Renamed to sort_by_file_name. + (sort_by_section_name, sort_sections_1): New functions. + (sort_sections): Only sort by file name sections in .idata. + Add "Grouped Sections" support. + (gld${EMULATION_NAME}_place_orphan): Rewrite to support Grouped + Sections. + (gld${EMULATION_NAME}_place_section): Delete. + * scripttempl/pe.sc (.text,.data,.rdata): Add *(.foo\$). + (.CRT,.rsrc): Rewrite to use Grouped Section support. + +Tue May 21 14:31:48 1996 Stan Shebs <shebs@andros.cygnus.com> + + * mpw-eppcmac.c: Update to reflect changes to aix.em. + +Sun May 19 16:59:44 1996 Doug Evans <dje@seba.cygnus.com> + + * ldlang.c (dprint_statement): Stop printing at end of list. + +Sat May 18 13:12:05 1996 Steve Chamberlain <sac@slash.cygnus.com> + + Support for --force-exe-suffix + * ld.h (args_type): Add force_exe_suffix. + * ld.texinfo: Add documentation. + * ldmain.c (main): Add support for option. + * lexsup.c (OPTION_FORCE_EXE_SUFFIX): New. + (ld_options, parse_args): Add support for option. + +Wed May 15 12:50:25 1996 Jim Wilson <wilson@chestnut.cygnus.com> + + * emultempl/pe.em (set_pe_value): Pass 0 not 16 to strtoul call. + +Fri May 10 16:28:44 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/elfppc.sc (__stack): Make __stack 0 if it was + referenced but not defined. + +Thu May 9 08:52:23 1996 Rob Savoye <rob@chinadoll.cygnus.com> + + * emulparams/{elf32bmip.sh,elf32lmip.sh,mipsidt.sh,mipsidtl.sh}: + Set a new variable to signify if the final target is an embedded + system. + * scripttempl/{mips.sc,elfmips.sc}: Don't add SIZEOF_HEADERS to + .text for an embedded system. + +Tue May 7 10:56:11 1996 Doug Evans <dje@canuck.cygnus.com> + + * scripttempl/pe.em (gld${EMULATION_NAME}_place_orphan): New function. + (gld${EMULATION_NAME}_place_section): New function. + (hold_{section,use,text,rdata,data}): New static locals. + (ld_${EMULATION_NAME}_emulation): Update orphan field. + * scripttempl/pe.sc: Whitespace cleanup. Semicolon usage cleanup. + (INIT,FINI): Delete, unused. + (.text): Document orphan .text.foo sections. + (.rdata): Document orphan .rdata.foo sections. + (.data): Document orphan .data.foo sections. + +Tue May 7 11:35:46 1996 Jeffrey A Law (law@cygnus.com) + + * scripttempl/h8300.sc: Place ".tiny" sections right + after ".data" sections. + * scripttempl/h8300h.sc: Place ".tiny" sections into + the "tiny" memory region, 0xff8000 through 0xffff00. + + * scripttempl/h8300.sc: Set the entry point to the value of + "_start" rather than the start of the text segment. + * scripttempl/h8300h.sc: Likewise. + + * scripttempl/h8300.sc: Place .rodata sections before .text + sections in main ram. + * scripttempl/h8300h.sc: Likewise. + +Mon May 6 23:32:30 1996 Jeffrey A Law (law@cygnus.com) + + * scripttempl/h8300h.sc: Use "eight", not "eightbit" for the + 8-bit region and 8-bit sections. + +Wed May 1 17:50:06 1996 Doug Evans <dje@canuck.cygnus.com> + + * ldlang.c (section_already_linked): Fix typos. + +Mon Apr 29 20:31:06 1996 Doug Evans <dje@canuck.cygnus.com> + + * scripttempl/pe.sc (.endjunk): Define __end__. + +Mon Apr 29 17:05:13 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (longest_section_name): Remove. + (SECTION_NAME_MAP_LENGTH): Define. + (print_size, print_alignment, print_fill, print_section): Remove. + (print_flags): Remove. + (lang_map): Rewrite. + (print_output_section_statement): Rewrite. + (print_assignment): Rewrite. + (print_one_symbol): Rewrite. + (print_input_section): Rewrite. + (print_fill_statement): Rewrite. + (print_data_statement): Rewrite. + (print_address_statement): New static function. + (print_reloc_statement): Rewrite. + (print_padding_statement): Rewrite. + (print_wild_statement): Rewrite. + (print_statement_list): Clean up. + (print_statement): Clean up. Some minor output changes. + (print_statements): Clean up. + (load_symbols): Put another - before -whole-archive. + * ldexp.c (exp_print_tree): Change etree_value and etree_rel to + print 0x and to omit leading zeroes. For etree_rel, use %B to + print the BFD. For etree_assign, remove the space after the + destination name. + * ldwrite.c: Include "libiberty.h". + (clone_section): Call xstrdup, not strdup. + (ldwrite): Don't print any map information. + (print_symbol_table, print_file_stuff, print_symbol): Remove. + * ldmain.c (main): Call lang_map when appropriate. + * ldmisc.c (vfinfo): Add support for %W. + (print_address): Remove. + * ldmisc.h (print_address): Don't declare. + * Makefile.in: Rebuild dependencies. + +Mon Apr 29 10:29:07 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * configure.host (m68*-*-linux*): Add -dynamic-linker to + HOSTING_CRT0. Search -lgcc both before and after -lc in + HOSTING_LIBS. Look for crt{begin,end}.o in the compiler directory + at first. + (i[345]86-*-linux*): Look for crt{begin,end}.o in the compiler + directory at first. + +Fri Apr 26 14:42:27 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldmisc.h (demangle): Declare. + * ldmisc.c: Include "libiberty.h". Include demangle.h with "", + not <>. + (demangle): Make non-static. Remove remove_underscore paramter. + Always return an allocated string. + (vfinfo): Free result of demangle. Add case 'G'. Use %T to print + functionname, rather than calling demangle. Print a colon between + the BFD(section+offset) and the line number. + * ldmain.c (add_archive_element): Improve format of archive + information in map file. + (constructor_callback): Don't print anything to the map file. + * ldlang.c (lang_one_common): Improve format of common symbol + information in map file. + * ldctor.c (ldctor_build_sets): If producing a map file, print set + information. + * ldwrite.c (print_symbol_table): Print a newline before the + header in the map file. + * Makefile.in: Rebuild dependencies. + + * ldmisc.c (vfinfo): Reindent. + +Mon Apr 22 12:07:32 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_size_sections): If _cooked_size is not 0, then + don't clobber it when not relaxing. + + * ld.h (ld_config_type): Remove traditional_format field. + * ldmain.c (main): Use link_info.traditional_format rather than + config.traditional_format. + * ldlang.c (ldlang_open_output): Likewise. + * lexsup.c (parse_args): Likewise. + * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Likewise. + * mpw-eppcmac.c (gldppcmacos_parse_args): Likewise. + + * ldlang.c (wild_doit): Discard debugging sections if we are + stripping debugging information. + + * emulparams/z8002.sh (ARCH): Set to z8002, not z8k. + +Tue Apr 16 16:38:32 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldexp.c (fold_binary): Correct handling of subtraction with + absolute values. + (fold_name): Permit symbols in lang_allocating_phase_enum. + + * scripttempl/aout.sc: Only PROVIDE __stack when RELOCATING. Undo + accidental changes in last patch. + +Tue Apr 16 10:25:42 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * configure.tgt (powerpc*-*-{sysv,linux}): Add aliases. + (powerpcle*-*-{sysv,solaris}): Ditto. + +Mon Apr 15 14:50:56 1996 Rob Savoye <rob@chinadoll.cygnus.com> + + * scripttempl/aout.sc: Add PROVIDE (__stack = 0) so I can use it + in m68k/crt0.S without things blowing up. + +Fri Apr 12 16:40:56 1996 Rob Savoye <rob@chinadoll.cygnus.com> + + * scripttempl/m68kcoff.sc: Remove default address for .data so + .text, .data, and .bss are all sequential. + +Thu Apr 11 12:05:35 1996 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/m68kcoff.sc: Remove regions and simplify. + +Wed Apr 10 14:41:53 1996 Jeffrey A Law (law@cygnus.com) + + * scripttempl/h8300.sc: Add the "8-bit area" in the upper 256 + bytes of the address space. Put data from the ".eight" sections + into the 8-bit area. + * scripttempl/h8300h.sc: Likewise. + +Tue Apr 9 14:10:42 1996 Doug Evans <dje@canuck.cygnus.com> + + * emultempl/generic.em (gld${EMULATION_NAME}_before_parse): + Pass $ARCH to ldfile_set_output_arch instead of setting + ldfile_output_architecture directly. + +Tue Apr 9 14:22:15 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/elfppc.sc (.init,.fini): Put .init, .fini section + next to .text. Put _etext after .text, .init, .fini, and + .rodata{,2} sections. + +Tue Apr 9 12:18:57 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo: Rearrange option documentation. + + * lexsup.c (ld_options): New static array. + (parse_args): Build shortopts and longopts from ld_options array. + (help): New static function. + * ldver.h (help): Don't declare. + * ldver.c (ldversion): Reindent. + (help): Remove. + + * ld.texinfo, ld.1: Mention -E as a synonym for -export-dynamic. + +Mon Apr 8 11:56:23 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em: When checking for a native emulation, check + that the current emulation is the default emulation. + * emultempl/sunos.em: Likewise. + + * configure.in: Permit --enable-shared to specify a list of + directories. + * configure: Rebuild. + + * lexsup.c (parse_args): Add -E as a synonym for -export-dynamic, + for HP/UX compatibility. + +Fri Apr 5 14:30:14 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_check_ld_so_conf): New + static function, if ${host} = ${target}. + (gld${EMULATION_NAME}_after_open): Call check_ld_so_conf to find a + needed shared library if ${host} = $[target}. + + * configure.host (i[345]86-*-linux*): Add -dynamic-linker to + HOSTING_CRT0. Search -lgcc both before and after -lc in + HOSTING_LIBS. + + * configure.tgt: Add i[345]86-*-freebsdelf* target; from John + Polstra <jdp@polstra.com>. + +Fri Apr 5 18:11:25 1996 James G. Smith <jsmith@cygnus.co.uk> + + * emulparams/elf32{b,l}4300.sh (MACHINE): Add explicit + architecture number. + * scripttempl/elf.sc: Use $MACHINE definition if present. + * configure.tgt (targ_extra_emuls): Force 4100 build to use same + template as 4300. + +Mon Apr 1 17:35:40 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_size_sections): Change region check to handle + regions which end at the highest possible address correctly. + From Roland Weber <roweber@ira.uka.de>. + + * ldlang.c (section_already_linked): New static function. + (wild_doit): Discard sections with SEC_EXCLUDE set if not doing a + relocateable link. Don't worry about section being NULL, since it + never should be. Don't call init_os unless the section is going + to be added. + (ldlang_add_file): Call section_already_linked for each section. + * ldmain.c (multiple_definition): Don't warn about multiple + definitions in sections which are being discarded. + +Sun Mar 31 00:30:47 1996 steve chamberlain <sac@slash.cygnus.com> + + * scripttempl/{ppcpe.sc, pe.sc} (.junk): Remove and use /DISCARD/. + * emultempl/pe.em (init): Remove special case PPC code. + +Fri Mar 29 00:01:29 1996 Jeffrey A Law (law@cygnus.com) + + * scripttempl/h8300.sc: Make vectors section 0xc4 bytes long + so as not to overwrite the magic syscall entry at 0xc4. + * scripttempl/h8300h.sc: Likewise. + +Thu Mar 28 11:05:47 1996 Doug Evans <dje@canuck.cygnus.com> + + * configure.tgt (sparc64-*-solaris2*): Delete. + Stick with sparc-*-solaris2*. + +Wed Mar 27 12:33:24 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.h (DISCARD_SECTION_NAME): Define to "/DISCARD/". + * ldlang.c (init_os): Fail on an attempt to initialize any section + named DISCARD_SECTION_NAME. + (wild_doit): Discard input sections assigned to an output section + named DISCARD_SECTION_NAME. + * ld.texinfo: Document use of /DISCARD/. + + * ldlang.c: Fix some indentation and comments. + +Tue Mar 26 18:14:49 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (main): Call bfd_set_error_program_name. + +Thu Mar 21 13:17:34 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo: Fix a couple of indexing entries. Mention that + --verbose displays builtin linker scripts. + + * ldmisc.c (vfinfo): case 'I': If the file is not in an archive, + and the local symbol name does not match the filename, print the + filename as well. + + Patches from John Polstra <jdp@polstra.com> for FreeBSD ELF: + * lexsup.c (parse_args): -Bshareable is a synonym for -shared. + * emulparams/elf_i386.sh (NONPAGED_TEXT_START_ADDR): Make the same + as TEXT_START_ADDR. + +Wed Mar 20 18:18:25 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * ld.texinfo: Fix typos. Use @pxref only inside parentheses. + +Wed Mar 20 16:56:15 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (add_wrap): New function. + * ldmain.h (add_wrap): Declare. + * lexsup.c (parse_args): Call add_wrap. + +Tue Mar 19 16:44:20 1996 Doug Evans <dje@canuck.cygnus.com> + + * configure.host (sparc*-*-solaris2* host): Accept any sparc variant. + +Wed Mar 13 17:47:31 1996 Jeffrey A Law (law@cygnus.com) + + * scripttempl/h8300.sc: Change name of page zero memory + from "null" to "vectors". Create an output section for + vectors. Add comments on how to explicitly place items + in the vector table. + * scripttempl/h8300h.sc: Likewise. + +Wed Mar 13 12:40:18 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/lnk960.em (machine_table): Add jx and hx. + + * genscripts.sh: Don't use ${9:-xx}, since Ultrix /bin/sh doesn't + support it. + +Tue Mar 12 12:43:59 1996 David Mosberger-Tang <davidm@koala.azstarnet.com> + + * ld.h (ld_config_type): Add warn_multiple_gp field. + * lexsup.c (parse_args): Handle --warn-multiple-gp. + * ldmain.c (warning_callback): Suppress multiple gp values warning + if --warn_multiple_gp was not used. + * ld.texinfo, ld.1: Document --warn-multiple-gp. + +Tue Mar 12 12:02:21 1996 Ian Lance Taylor <ian@cygnus.com> + + * lexsup.c (parse_args): Handle --wrap. + * ldmain.c (main): Initialize link_info.wrap_hash. + * ldexp.c (fold_name): Use bfd_wrapped_link_hash_lookup in DEFINED + and NAME cases. + * ld.texinfo, ld.1: Document --wrap. + + * configure: Rebuild with autoconf 2.8. + + Don't do SunOS style dynamic linking for sparc-aout: + * configure.tgt (sparc64-*-aout*): Use sparcaout, not sun4. + (sparclite*-fujitsu-*, sparc*-*-aout): Likewise. + (sparc*-wrs-vxworks*): Likewise. + * emulparams/sparcaout.sh: New file. + * Makefile.in (ALL_EMULATIONS): Add esparcaout.o. + (esparcaout.c): New target. + +Wed Mar 6 16:06:52 1996 J.T. Conklin <jtc@rtl.cygnus.com> + + * scripttempl/elfppc.sc (.sdata2, .sbss2): Implement Feb 2 change + in a different manner to work around differences in shell variable + expansion. + +Wed Mar 6 18:08:18 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldemul.h (ldemul_unrecognized_file): Declare. + (ldemulation_xfer_type): Add unrecognized_file field. + * ldemul.c (ldemul_unrecognized_file): New function. + * ldlang.c (load_symbols): If a file can not be recognized, call + ldemul_unrecognized_file before trying it as a linker script. + * aix.em (gld${EMULATION_NAME}_unrecognized_file): New static + function. + (gld${EMULATION_NAME}_read_file): Use FOPEN_RT, not "r". + (ld_${EMULATION_NAME}_emulation): Initialize unrecognized_file. + +Mon Mar 4 14:11:17 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (wild): Handle foo.a(.text) by mapping each included + member of foo.a separately. From Jouke Numan <jnuman@bazis.nl>. + +Fri Mar 1 10:24:59 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * emultempl/elf32.em (gld${EMULATION_NAME}_find_exp_assignment): + Search trinary.cond rather than searching trinary.lhs twice. + +Tue Feb 27 15:08:43 1996 Stan Shebs <shebs@andros.cygnus.com> + + * mpw-make.sed: Edit out shared library support. + (@TDIRS@): Edit out, can't use genscripts. + +Tue Feb 27 15:09:21 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * configure.tgt (m68k-*-linuxaout*, m68k-*-linux*): New targets. + * emulparams/m68klinux.sh: New file. + * emultempl/linux.em (gld${EMULATION_NAME}_before_allocation): + Call bfd_${EMULATION_NAME}_size_dynamic_sections instead of + bfd_linux_size_dynamic_sections. + * Makefile.in (ALL_EMULATIONS): Add em68klinux.o. + (em68klinux.c): New target. + * configure.host (m68*-*-linuxaout*, m68*-*-linux*): New hosts. + +Tue Feb 27 12:55:46 1996 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (ALL_EMULATIONS): Sort into alphabetical order. + Fill in missing entries. + + * lexsup.c (parse_args): Recognize --no-whole-archive. + * ldlang.h (lang_input_statement_type): Add whole_archive field. + * ldlang.c (new_afile): Set whole_archive field. + (load_symbols): Check input file specific whole_archive field + rather than global variable. + * ld.texinfo, ld.1: Document --no-whole-archive. + +Tue Feb 20 16:07:00 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt: Correct gldi960 to gld960. + +Mon Feb 19 11:16:44 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_check_needed): Check + the SONAME if it is available. + (gld${EMULATION_NAME}_stat_needed): Use the SONAME, not the + filename, when checking for conflicting library versions. Don't + assume that the suffix is only numbers and dots. + + * ld.texinfo: Mention that -R can be used for -rpath. + +Sun Feb 18 15:05:17 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.host: Check for 'do not mix' from native linker before + trying to use -rpath. + +Thu Feb 15 13:58:06 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Remove explicit substitution of CFLAGS; autoconf + does it anyhow. + * configure: Rebuild. + * Makefile.in (LDFLAGS): Set to @LDFLAGS@. + + * configure.in: Call AC_PROG_CC before configure.host. + * configure: Rebuild. + * configure.host: Remove go32 host, since it should no longer be + necessary. Don't set CC for romp host. + + * scripttempl/elf.sc: Don't skip a page in virtual memory space if + the text segment ends exactly on a page boundary. + + * configure.in: Substitute RPATH_ENVVAR. + * configure: Rebuild. + * configure.host: Set RPATH_ENVVAR. + * Makefile.in (RPATH_ENVVAR): New variable. + (check): Use $(RPATH_ENVVAR) rather than LD_LIBRARY_PATH. + +Wed Feb 14 18:49:01 1996 Alan Modra <alan@spri.levels.unisa.edu.au> + + * configure.in: Redo emulation handling so that each emulation + searches the correct tool directory, based on the target alias. + For example, "configure --enable-targets=m68k-coff i386-linux" + will search /usr/local/i386-linux/lib for linux and + /usr/local/m68k-coff/lib for m68k-coff. + * configure: Rebuild. + * configure.tgt: Add special tdir settings for Linux. + * Makefile.in: Add @TDIRS@. Pass "$(tdir_EMUL)" to ${GENSCRIPTS} + for each eEMUL.c target. + * genscripts.sh: Accept specific alias as 9th argument, and use it + in LIB_PATH. + +Wed Feb 14 16:38:36 1996 Martin Anantharaman <martin@mail.imech.uni-duisburg.de> + + * ldlang.c (lang_set_startof): Don't do anything for a + relocateable link. + + * ldgram.y (mri_script_file): Call mri_draw_tree. + * mri.c (mri_draw_tree): Make globally visible. Don't bother to + create memory regions. + (mri_load): Don't call mri_draw_tree. + * mri.h (mri_draw_tree): Declare. + + * configure.tgt (m68*-*-psos): New target. + * emulparams/m68kpsos.sh: New file. + * scripttempl/psos.sc: New file. + * Makefile.in (ALL_EMULATIONS): Add em68kpsos.o. + (em68kpsos.c): New target. + +Wed Feb 14 11:09:25 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.tgt (*-*-ieee*): New target; use vanilla. + + * emultempl/elf32.em (gld${EMULATION_NAME}_before_parse): Strip + `:foo' from ${ARCH}. + +Tue Feb 13 15:58:58 1996 Bryan Ford <baford@snake.cs.utah.edu> + + * scripttempl/i386msdos.sc: Don't pad the .text section. Put + .rodata in .data. + +Tue Feb 13 14:04:19 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.host: Set HDLFLAGS for *-*-hpux with --enable-shared. + + * emultempl/elf32.em (gld${EMULATION_NAME}_stat_needed): Warn if + it looks like we might be linking in two different versions of the + same shared library. Based on a patch from H J Lu <hjl@zoom.com>. + +Thu Feb 8 19:25:54 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_size_sections): Increment the section size when a + padding statement is encountered. + +Wed Feb 7 14:01:33 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Look for --enable-shared. Change the value of + BFDLIB when linking against a shared library on SunOS. + * configure: Rebuild. + * configure.host: If using a shared BFD library, try to pass a + reasonable -rpath option when linking. + * Makefile.in (BFDLIB): Set to @BFDLIB@. + +Tue Feb 6 12:29:14 1996 Doug Evans <dje@charmed.cygnus.com> + + * emulparams/elf64_sparc.sh (ARCH): Change to `sparc:v9'. + * emultempl/generic.em: Strip `:foo' from ${ARCH}. + +Mon Feb 5 16:25:30 1996 Ian Lance Taylor <ian@cygnus.com> + + Support for building bfd and opcodes as shared libraries, based on + patches from Alan Modra <alan@spri.levels.unisa.edu.au>: + * configure.in (HLDFLAGS): New substitution. + * configure: Rebuild. + * configure.host: Set HLDFLAGS on SunOS. + * Makefile.in (HLDFLAGS): New variable. + (BFDDEP): New variable. + (BFDLIB): Change to -L../bfd -lbfd. + ($(LD_PROG)): Depend upon $(BFDDEP) rathern than $(BFDLIB). Use + $(HLDFLAGS) in link. + (check): Set LD_LIBRARY_PATH in the environment. + +Fri Feb 2 19:26:25 1996 Michael Meissner <meissner@wogglebug.tiac.net> + + * scripttempl/elfppc.sc (.sdata2, .sbss2): Put .sdata2 and .sbss + in the read-only section, not read/write unless we are making a + shared library. + (.debug*): Add dwarf debug sections. + (.rela.{sdata*,sbss*}): Add sections. + +Fri Feb 2 16:50:21 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure: Regenerate. + +Thu Feb 1 10:50:46 1996 Ian Lance Taylor <ian@cygnus.com> + + * emulparams/elf_i386.sh (TEXT_START_ADDR): Change to 0x8048000, + for SVR4 compatibility. + + * ldexp.c (exp_fold_tree): Correct handling of ABSOLUTE. + +Wed Jan 31 17:30:19 1996 Steve Chamberlain <sac@slash.cygnus.com> + + * configure.tgt (i[345]86-*-cygwin32, powerpcle-*-cygwin32): New. + * emultempl/pe.em (definfo init): Make the default stack reserve + of a PPC larger. + +Wed Jan 31 14:34:23 1996 Richard Henderson <rth@tamu.edu> + + * configure.tgt (m68*-apple-aux*): New target. + * emulparams/m68kaux.sh: New file. + * scripttempl/m68kaux.sc: New file. + * Makefile.in (ALL_EMULATIONS): Add em68kaux.o. + (em68kaux.c): New target. + +Tue Jan 30 13:18:56 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Ignore + -bnoentry, since the right thing tends to happen anyhow. + +Mon Jan 29 12:29:26 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo, ld.1: Document -export-dynamic. + +Fri Jan 26 11:11:55 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * emultempl/sunos.em: Check for native compile by comparing + ${target} and ${host}. + +Thu Jan 25 16:46:58 1996 James G. Smith <jsmith@cygnus.co.uk> + + * emulparams/{elf32b4300.sh, elf32l4300.sh}: Changed + TEXT_START_ADDR to allow use on IDT and PMON systems. + +Wed Jan 24 20:59:40 1996 Steve Chamberlain <sac@slash.cygnus.com> + + * emultempl/pe.em (gld_${EMULATION_NAME}_parse_args): + correct spelling. + +Wed Jan 24 16:59:19 1996 Doug Evans <dje@charmed.cygnus.com> + + * configure.tgt (sparc64-*-solaris2*): New configuration. + (sparc64-*-aout*): Renamed from sparc64*. + +Mon Jan 22 13:01:35 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * Makefile.in (GENSCRIPTS): Pass @host@ @target@ @target_alias@. + * genscripts.sh: Set host, target and target_alias variables. + Check for native compile by comparing ${target} and ${host}. + * emultempl/elf32.em: Likewise. + * scripttempl/elfmips.sc: Test ${target}, not ${target_alias}. + +Mon Jan 22 11:03:23 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/elfppc.sc: Refine eabi support to better support + .sdata, .sdata2, .sbss, etc. sections. + +Tue Jan 16 15:16:58 1996 Ian Lance Taylor <ian@cygnus.com> + + * ldgram.y (%union): Add phdr field. + (phdr): Use phdr_qualifiers rather than opt_hdrs and opt_at. + (phdr_qualifiers): New nonterminal. Add support for FLAGS. + (opt_hdrs, hdr): Remove. + (phdr_val): New nonterminal. + * ldlang.c (lang_new_phdr): Replace hdrs parameter with filehdr + and phdrs parameters. Add flags parameter. + (lang_record_phdrs): Update for changes to lang_phdr. Pass flags + to bfd_record_phdr. + * ldlang.h (struct lang_phdr): Replace hdrs field with filehdr and + phdrs fields. Add flags field. + (LANG_PHDR_FILEHDR, LANG_PHDR_PHDRS): Remove. + (lang_new_phdr): Update declaration. + * ld.texinfo: Document FLAGS. + +Mon Jan 15 15:07:19 1996 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation): + Don't make a shared library because of an undefined reference to + __GLOBAL_OFFSET_TABLE_. + + Add some Irix 5 support, mostly from Kazumoto Kojima + <kkojima@info.kanagawa-u.ac.jp>: + * emulparams/elf32bmip.sh (SCRIPT_NAME): Change to elfmips. + (SHLIB_TEXT_START_ADDR): Define. + (OTHER_GOT_SYMBOLS): Define. + (OTHER_READWRITE_SECTIONS): Remove initialization of _gp. + (EXECUTABLE_SYMBOLS): Don't define. + (DYNAMIC_LINK): Don't define. + * emulparams/elf32lmip.sh: Same changes as elf32bmip.sh. + * scripttempl/elfmips.sc: New file. + * configure.host (mips*-dec-bsd*): Change mips to mips*. + (mips*-sgi-irix4*): Likewise. + (mips*-sgi-irix5*): New entry. + * Makefile.in (eelf32bmip.c): Depend upon elfmips.sc rather than + elf.sc. + (eelf32lmip.c): Likewise. + +Sat Jan 13 09:41:43 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/elfppc.sc: Remove support for .rel.* sections. Add + .rela.got.neg section. + +Fri Jan 12 14:56:19 1996 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/sh.sc: Only build constructors when CONSTRUCTING. + + * ldmisc.c: Include <stdarg.h> rather than <varargs.h> if + ANSI_PROTOTYPES is defined. Remove special handling of + WINDOWS_NT. Various indendation fixes. + (vfinfo): Change fmt parameter to const char *. + (info_msg): Write <stdarg.h> version. + (einfo, minfo, finfo): Likewise. + (info_assert): Change file parameter to const char *. + * ldmisc.h (einfo, minfo, info_msg): If ANSI_PROTOTYPES is + defined, use a real prototype. + (info_assert): Change first parameter to be const char *. + +Fri Jan 12 13:29:55 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/elfppc.sc: Add support for .sdata2/.sbss2, etc. Add + in old support that 2.7.2 needs, but the current compiler does + not. + + * Makefile.in (eelf32{,l}ppc.c): Fix up dependencies to use the + correct Linker script template. + + * emulparams/elf32{,l}ppc.sh (TEXT_START_ADDR): Set to 0x40000, + not 0x400000. + (DATA_ADDR,NONPAGED_TEXT_START_ADDR): Delete. + +Tue Jan 9 15:53:02 1996 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/alpha.sc: Put .rconst right after .rdata. + +Fri Jan 5 14:07:45 1996 Steve Chamberlain <sac@slash.cygnus.com> + + * emultempl/pe.em (gld_${EMULATION_NAME}_before_allocation): + sort using right pointer. + +Fri Jan 5 12:25:47 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/elfppc.sc: Remove support for creating special + labels for eabi section begin/end here. The compiler now uses + crt{i,n}.o to create these symbols. + +Thu Jan 4 17:08:58 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.host: Change existing Linux HOSTING_CRT0 to be used + for a.out only, and put in appropriate HOSTING_CRT0 and + HOSTING_LIBS values for Linux ELF. + +Thu Jan 4 12:02:05 1996 Doug Evans <dje@canuck.cygnus.com> + + * scripttempl/h8300.sc: Use all 64K for ram. + * scripttempl/h8300h.sc: Define 256K ram size. + +Thu Dec 21 15:57:18 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_before_allocation): Pass + export_defines as true to bfd_xcoff_size_dynamic_sections if -unix + was used, regardless of whether -bE was used. + +Tue Dec 19 17:35:38 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_after_open): Only set + relocateable before calling ldctor_build_sets if the output file + is in an XCOFF format. + +Fri Dec 15 16:34:36 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldwrite.c (build_link_order): When handling a data statement, if + the endianness of the output file is unknown, use the endianness + of the input file. + +Tue Dec 12 13:55:41 1995 Stan Shebs <shebs@andros.cygnus.com> + + * mpw-config.in: Recognize mips-*-* as equivalent to + mips-idt-ecoff. + * mpw-eppcmacos.c: Rename to shorter mpw-eppcmac.c. + * mpw-ld.r: Add version resources. + (cfrg): Use symbolic instead of literal name for executable. + +Mon Dec 11 15:13:41 1995 Kim Knuttila <krk@cygnus.com> + + * scripttempl/ppcpe.sc (FINI): Moved the .reloc section. + +Wed Dec 6 14:33:50 1995 Doug Evans <dje@canuck.cygnus.com> + + * ldlang.c (print_statement{,s}): Delete duplicate prototype. + (print_statement_list): Renamed from print_statement. All callers + updated. + (print_statement): New function to print just one statement. + (print_{data,reloc,padding}_statement): Don't crash if + output_section == NULL. + (dprint_statement): New function. + + * emultempl/pe.em (gld_${EMULATION_NAME}_before_allocation): Fix + call to sort_sections. + +Wed Dec 6 14:59:06 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (unix_ld): New static variable. + (gld${EMULATION_NAME}_parse_args): Handle -unix. + (gld${EMULATION_NAME}_before_allocation): If unix_ld, pass + gc as false and export_defineds as true to size_dynamic_sections. + + * ldexp.c (exp_fold_tree): Permit assignments to dot in the final + phase if the current section is abs_output_section. + + +Tue Dec 5 09:49:39 1995 Doug Evans <dje@canuck.cygnus.com> + + * emultempl/pe.em (gld_${EMULATION_NAME}_before_allocation): Fix call + to sort_sections. + +Fri Dec 1 16:48:36 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldgram.y (PHDRS): New token. + (ifile_p1): Accept phdrs. + (section): Accept phdr_opt at the end of the section definition. + (phdr_op): New nonterminal. + (phdrs, phdr_list, phdr, phdr_type, opt_hdrs, hdr): Likewise. + * ldlex.l: Accept PHDRS. + * ldlang.h (struct lang_output_section_phdr_list): Define. + (lang_output_section_statement_type): Add phdrs field. + (struct lang_phdr): Define. + (LANG_PHDR_FILEHDR, LANG_PHDR_PHDRS): Define. + (lang_new_phdr): Declare. + * ldlang.c (lang_phdr_list): New static variable. + (lang_output_section_statement_lookup): Initialize phdrs field. + (lang_process): Call lang_record_phdrs. + (lang_new_phdr): New function. + (lang_section_in_phdr): New function. + (lang_record_phdrs): New static function. + * ld.texinfo: Document PHDRS. + +Thu Nov 30 13:14:30 1995 Kim Knuttila <krk@cygnus.com> + + * scripttempl/ppcpe.sc: Moved .edata into its own section to + expose it. + +Thu Nov 30 11:32:34 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de> + + * configure.host (m68*-motorola-sysv): Define HOSTING_CRT0 and + HOSTING_LIBS for testing. + (m88*-motorola-sysv3): Define HOSTING_CRT0 and HOSTING_LIBS for + testing. + +Tue Nov 28 12:14:53 1995 Ian Lance Taylor <ian@cygnus.com> + + * lexsup.c (parse_args): Set config.dynamic_link to false for -N + and -n. + +Mon Nov 27 13:12:09 1995 Ian Lance Taylor <ian@cygnus.com> + + * configure: Rebuild with autoconf 2.7. + +Fri Nov 24 18:35:35 1995 Doug Evans <dje@canuck.cygnus.com> + + * scripttempl/pe.sc: Two .junk's is too much junk. + +Tue Nov 21 16:14:32 1995 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Use BFD_NEED_DECLARATION. + * acconfig.h: Put NEED_DECLARATION_FREE in @TOP@ section. + * configure, config.in: Rebuild with autoconf 2.6. + + * ldmain.c (constructor_callback): Don't warn about BFD_RELOC_CTOR + being unsupported if this is not a relocateable link and the input + BFD supports it, since ldctor_build_sets can cope with that case. + +Fri Nov 17 16:23:15 1995 Stan Shebs <shebs@andros.cygnus.com> + + * configure.tgt (powerpc-*-macos*): New target. + * emulparams/ppcmacos.sh: New file, PowerMac emulation. + * Makefile.in (ALL_EMULATIONS): Add eppcmacos.o. + (eppcmacos.c): New target. + * mpw-eppcmacos.c: Update. + * mpw-make.sed: Edit out attempts to use {GENSCRIPTS}. + +Fri Nov 17 10:37:27 1995 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (CC_FOR_TARGET): Use @host@ and @target@, not + $(host_canonical) and $(target_canonical). + (CXX_FOR_TARGET): Likewise. + +Thu Nov 16 11:23:42 1995 Doug Evans <dje@canuck.cygnus.com> + + * scripttempl/pe.sc (.endjunk): Move definition of `end' to here + so the malloc heap begins at a sane place. + +Thu Nov 16 03:09:32 1995 Ken Raeburn <raeburn@cygnus.com> + + Version 2.6 released. + * ldver.c (ldversion): Update to 2.6. + + * Makefile.in (mostlyclean): Delete ldemul-list.h here, but not + $(GENERATED_*FILES), since they need to be retained by distclean. + (maintainer-clean, realclean): Delete them here. + +Tue Nov 14 17:08:06 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/pe.em (gld_${EMULATION_NAME}_parse_args): Open the + base file with FOPEN_WB, not "w". + + * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Use the + environment variable LD_RUN_PATH if neither -rpath nor -rpath-link + were used. + (gld${EMULATION_NAME}_before_allocation): Use the environment + variable LD_RUN_PATH if -rpath was not used. + * ld.texinfo, ld.1: Document LD_RUN_PATH. + +Thu Nov 9 13:09:29 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Recognize + -bl and -bloadmap options. + + * ldfile.c (ldfile_try_open_bfd): If bfd_error_invalid_target, + report a better error. + + * emultempl/aix.em (gld${EMULATION_NAME}_before_allocation): Add + new local variable special_sections, and pass it to + size_dynamic_sections. Look through the results, and move the + sections around in the mapping so that they are defined correctly. + +Wed Nov 8 11:40:59 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldemul.c (ldemul_default_target): Cast getenv return value. + +Tue Nov 7 11:15:36 1995 Kim Knuttila <krk@cygnus.com> + + * emulparams/ppcpe.sh (ARCH): New file for PowerPC Portable + Executable support. + * scripttempl/ppcpe.sc: New file for PowerPC Portable Executable + support. + + * configure.tgt (targ_extra_emuls): Added powerpcle-pe target. + * Makefile.in (ALL_EMULATIONS): Added eppcpe.o target. + + * emultempl/pe.em (TARGET_IS_ppcpe): file tailoring macro + (gld_$_before_allocation): added hooks for toc construction based + on the above macro. + +Tue Nov 7 11:47:23 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld.texinfo: The linker does not use _main as an entry point. + +Tue Nov 7 11:46:11 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de> + + * scripttempl/m88kbcs.sc (.data): Calculate next boundary modulo + 0x2000 not 0x200. + +Mon Nov 6 10:59:21 1995 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Add test for whether free must be declared. + * sysdep.h: Declare free if necessary. Include "ansidecl.h". + * acconfig.h: Explain NEED_DECLARATION_FREE. + * configure, config.in: Rebuild. + + * lexsup.c (parse_args): Take B:: out of shortopts. + +Sun Nov 5 03:08:28 1995 Ken Raeburn <raeburn@cygnus.com> + + * emulparams/i386nbsd.sh (EXECUTABLE_SYMBOLS): Set __DYNAMIC to 0 + for now, as with m68k4kbsd, until shared library support gets + done. + + * configure.host: For i386 BSD variants, crt0.o lives in + /usr/lib. (True for NetBSD at least, unconfirmed for others.) + +Wed Nov 1 15:42:45 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de> + + * Makefile.in (ALL_EMULATIONS): Add edelta68.o. + (edelta68.c): New target. + * configure.tgt (m68*-motorola-sysv*): New target. + * emulparams/delta68.sh: New file. + * scripttempl/delta68.sc: New file. + + * scripttempl/m88kbcs.sc: Handle .init and .fini. Change section + addresses. + +Wed Nov 1 11:41:56 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldgram.y (mri_script_command): Accept ',' as well as '=' in + ALIGN and ALIGNMOD statements. + + * emultempl/aix.em: Include ldgram.h. + (gld${EMULATION_NAME}_parse_args): Handle -pD and -pT, as used on + AIX 4.1. + * Makefile.in ($(EMULATION_OFILES)): Depend upon ldgram.h. + +Tue Oct 31 18:22:24 1995 David Mosberger-Tang <davidm@azstarnet.com> + + * configure.host (alpha-*-linux*): New host. + * configure.tgt (alpha-*-linux*): New target. + +Tue Oct 31 12:36:52 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (export_files): Remove. + (import_files): Make static. + (struct export_symbol_list): Define. + (export_symbols): New static variable. + (gld${EMULATION_NAME}_parse_args): Handle an initial -b option + correctly. Call read_file for an export file. + (gld${EMULATION_NAME}_before_allocation): Call + bfd_xcoff_export_symbol for each export symbol, rather than + calling read_file for each export file. + (gld${EMULATION_NAME}_read_file): For an export file, make the + exported symbols undefined, and store them on the export_symbols + list. + +Sat Oct 28 00:10:03 1995 steve chamberlain <sac@slash.cygnus.com> + + * emultempl/pe.em (gld_${EMULATION_NAME}_parse_args): + Don't hang if last option is unrecognised. + (gld_${EMULATION_NAME}_set_symbols): Insert created + symbols into ABS output section. + +Fri Oct 27 18:03:17 1995 Niklas Hallqvist <niklas@appli.se> + + * Makefile.in (ALL_EMULATIONS): Added support for the NetBSD + m68k4k arch. + (em68k4knbsd.c): New rule. + + * configure.tgt: Added support for the NetBSD m68k4k arch. + + * genscripts.sh, ldint.texinfo, + emulparams/{a29k,armaoutb,armaoutl,coff_sparc,ebmon29k,gld960, + gld960coff,go32,h8300,h8300h,h8500,h8500b,h8500c,h8500m,h8500s, + hp300bsd,hp3hpux,hppaelf.sh,i386aout,i386bsd,i386coff,i386go32, + i386linux,i386lynx,i386nbsd,lnk960,m68kaout,m68kcoff,m68klynx, + m88kbcs,mipsbig,mipsbsd,mipsidt,mipsidtl,mipslit,news,ns32knbsd, + pc532machaout,riscix,sa29200,sh,shl,sparclynx,sparcnbsd, + st2000,sun3,sun4,vanilla,vax,vsta,w65,z8001,z8002}.sh: Changed + PAGE_SIZE to TARGET_PAGE_SIZE. + + * emulparams/m68knbsd.h: Ditto. + (TEXT_START_ADDR, NONPAGED_TEXT_START_ADDR): We have 8K pagesize. + (EXECUTABLE_SYMBOLS): Hardcode __DYNAMIC to zero for the time + being. + + * emulparams/m68k4knbsd.sh: New file. + + * scripttempl/aout.sc: Expand EXECUTABLE_SYMBOLS if relocating. + +Fri Oct 27 17:59:09 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em: Include ldctor.h. + (gld${EMULATION_NAME}_after_open): New static function. + (gld${EMULATION_NAME}_before_allocation): Call find_relocs. + (gld${EMULATION_NAME}_find_relocs): New static function. + (gld${EMULATION_NAME}_find_exp_assignment): New static function. + (ld_${EMULATION_NAME}_emulation): Use new after_open function. + * scripttempl/aix.sc: Use CONSTRUCTORS in .data. + * ldctor.c (struct set_info): Move definition into ldctor.h. + (struct set_element): Likewise. + (sets): Make non-static. + (ldctor_add_set_entry): Add name parameter. Save it in the new + set element. + (ldctor_build_sets): Avoid being called twice. Pass set element + name to lang_add_reloc. + * ldctor.h (struct set_info): Move definition here from ldctor.c. + (struct set_element): Likewise. Add new field name. + (sets): Declare. + (ldctor_add_set_entry): Declare new name parameter. + * ldwrite.c (build_link_order): Don't insist that either name or + section be NULL in a lang_reloc_statement. + * ldmain.c (add_to_set): Pass NULL to ldctor_add_new_set_entry for + new name parameter. + (constructor_callback): Pass name to ldctor_add_new_set_entry for + new name parameter. + + * ldmisc.c (demangle): Fix indentation. Remove a leading period. + +Thu Oct 26 22:22:49 1995 Stan Shebs <shebs@andros.cygnus.com> + + * mpw-config.in: Add PowerMac target support, generate config.h. + * mac-ld.r: New file, Mac resources. + * mpw-make.sed: New file, edits Makefile.in into MPW syntax. + * mpw-make.in: Remove. + * mpw-eppcmacos.c: Prebuilt version of PowerMac linking script. + +Thu Oct 26 14:11:26 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Treat + -static as a synonym for -bnso. + + * scripttempl/aix.sc: Move special symbols inside sections. + Always start .data at 0. + +Wed Oct 25 11:52:12 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * Makefile.in (diststuff): Also make info. + (maintainer-clean realclean): Also delete *.info*. + +Wed Oct 25 11:27:25 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/aix.em: Add support for various AIX linker options, + for AIX import and export files, and for AIX shared objects. + * scripttempl/aix.sc: Add .pad. Put .ds just before the TOC. + + * ldmain.c (main): Initialize new field link_info.static_link. + + * ldmain.c (add_keepsyms_file): Add \n at end of einfo calls. + (constructor_callback): Likewise. + * ldmisc.c (vfinfo): Likewise. + * ldwrite.c (build_link_order): Likewise. + + * ld.texinfo: The MRI ALIGN directive is supported. + +Mon Oct 23 11:46:43 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk> + + * emulparams/elf32vr4300.sh: Deleted. + * emulparams/elf32vr4300el.sh: Deleted. + * emulparams/elf32b4300.sh: Added. + * emulparams/elf32l4300.sh: Added. + * configure.tgt, Makefile.in: Updated the build to use the + new 8.3 unique names. + +Thu Oct 19 17:41:46 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (entry_symbol): Make non-static. + * ldlang.h (entry_symbol): Declare. + + * ldlex.l: Treat PROVIDE as a keyword in expression state. + +Wed Oct 18 17:34:06 1995 steve chamberlain <sac@slash.cygnus.com> + + * scripttempl/pe.sc (.bss): Move to be after .text + +Tue Oct 17 12:22:05 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/sunos.em (gld${EMULATION_NAME}_find_exp_assignment): + Search trinary.cond rather than searching trinary.lhs twice. From + linli@ihp.PHys.ethz.CH. + + * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Move + directory searching code into gld${EMULATION_NAME}_search_dir. + (gld${EMULATION_NAME}_search_dir): New static function, extracted + from gld${EMULATION_NAME}_find_so. + (global_needed, global_found): New static variables. + (gld${EMULATION_NAME}_after_open): New static function. + (gld${EMULATION_NAME}_search_needed): New static function. + (gld${EMULATION_NAME}_try_needed): New static function. + (gld${EMULATION_NAME}_check_needed): New static function. + (ld_${EMULATION_NAME}_emulation): Use new after_open function. + * ld.texinfo, ld.1: Mention -rpath-link on SunOS. + + * Makefile.in (eelf32ppc.c): Depend upon elf32.em, not generic.em. + (eelf32lppc.c): Likewise. + * emulparams/elf32lppc.sh (TEMPLATE_NAME): Define as elf32. + (GENERATE_SHLIB_SCRIPT): Define as yes. + +Mon Oct 16 19:11:13 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em: Struct bfd_elf_link_needed_list is now named + bfd_link_needed-list; make appropriate changes. + + * configure.tgt (powerpc-*-aix*): New target; use aixppc. + (rs6000-*-aix*): New target; use aixrs6. + * emulparams/aixppc.sh, emulparams/aixrs6.sh: New files. + * emultempl/aix.em: New file. + * scripttempl/aix.sc: New file. + * Makefile.in (ALL_EMULATIONS): Add eaixppc.o and eaixrs6.o. + (eaixppc.c, eaixrs6.c): New targets. + +Fri Oct 13 14:00:37 1995 steve chamberlain <sac@slash.cygnus.com> + + * scripttemp/pe.sc (.reloc): Move to the end. + +Tue Oct 10 17:53:22 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_finish): Don't try to use an entry_symbol from a + section which was not linked into the final output. + +Tue Oct 10 10:17:22 1995 steve chamberlain <sac@slash.cygnus.com> + + * emultempl/pe.em (gld_${EMULATION_NAME}_parse_args): Fix + fatal typos. + +Tue Oct 10 01:01:51 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld.h (args_type): Add rpath_link field. + * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Search for + required dependencies in rpath_link path. Only search + LD_LIBRARY_PATH when configured native. + * lexsup.c (parse_args): Recognize -rpath-link. + * ld.1, ld.texinfo: Document -rpath-link. + +Sat Oct 7 17:07:17 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Don't + bother searching for needed libraries unless doing a final link. + +Fri Oct 6 16:26:16 1995 Ken Raeburn <raeburn@cygnus.com> + + Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * ld/ld.1: Fix formatting bugs. + +Wed Oct 4 17:37:46 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldexp.c (exp_get_abs_int): Return bfd_vma, not int. + * ldexp.h (exp_get_abs_int): Update declaration. + * ldlang.c (print_output_section_statement): Use fprintf_vma to + print return value of exp_get_abs_int. + +Mon Oct 2 13:56:09 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (global_stat): New file static variable. + (gld${EMULATION_NAME}_try_needed): Call stat_needed to make sure + that the file has not already been included under another name. + (gld${EMULATION_NAME}_stat_needed): New static function. + +Fri Sep 29 12:00:18 1995 Doug Evans <dje@deneb.cygnus.com> + + * scripttempl/armcoff.sc: Start .text at 0x8000. + Start .data at 0x40000. + +Fri Sep 29 11:09:46 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation): If + command_line.rpath is set, use it, rather than the -L options, to + build the rules section. + * ld.texinfo: Document this use of -rpath. + + * lexsup.c (parse_args): Don't set link_info.shared for -assert + pure-text. Pass true, not 1, to lang_add_entry. + * emultempl/sunos.em (find_assign): New static variable. + (found_assign): New static variable. + (gld${EMULATION_NAME}_before_allocation): Rename local h to hdyn. + If not a relocateable link, and no start symbol was specified on + the command line, and there are any undefined symbols, set + link_info.shared. If link_info.shared is set, set the address of + the .text section to 0x20. + (gld${EMULATION_NAME}_find_assignment): Rename from + gld${EMULATION_NAME}_find_statement_assignment. If find_assign is + set, then just set found_assign based on whether an assignment is + found to find_assign. + (gld${EMULATION_NAME}_get_script): Don't use a special script when + producing a shared library. + * emulparams/sun4.sh (GENERATE_SHLIB_SCRIPT): Remove. + * scripttempl/aout.sc: Remove CREATE_SHLIB tests. + * ldlang.c (entry_from_cmdline): New global variable. + (lang_add_entry): Change cmdline parameter from int to boolean. + Use global entry_from_cmdline rather than function static + from_cmdline. + * ldlang.h (entry_from_cmdline): Declare. + (lang_add_entry): Change declaration of second parameter from int + to boolean. + * ldgram.y: Pass false, not 0, to lang_add_entry. + +Thu Sep 28 12:34:13 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld.h (parsing_defsym): Declare. + * ldlex.h (lex_string): Declare. + * ldlex.l (lex_string): Define. + * lexsup.c (parsing_defsym): Define. + (parse_args): In OPTION_DEFSYM case, set lex_string before calling + lex_redirect, and clear it after calling yyparse. Set + parsing_defsym around call to yyparse. + * ldmain.c (main): Set lex_string before calling lex_redirect, and + clear it after calling yyparse. + * ldmisc.c (vfinfo): For %S, handle --defsym arguments and built + in linker scripts correctly. + + * scripttempl/sparccoff.sc: Add .ctors/.dtors handling like other + COFF targets, allowing for the leading underscore used on SPARC + COFF. + + * lexsup.c (parse_args): Handle -assert. + * emulparams/sun4.sh (GENERATE_SHLIB_SCRIPT): Define. + * emultempl/sunos.em (gld${EMULATION_NAME}_get_script): Use the + shared library script when appropriate. + * scripttempl/aout.sc: If CREATE_SHLIB is set, start the .text + section at SIZEOF_HEADERS. + +Thu Sep 28 01:40:37 1995 Doug Evans <dje@deneb.cygnus.com> + + * Makefile.in (earmcoff.c): Build. + * configure.tgt (arm-*-coff): New target + * emulparms/armcoff.sh: New file. + * scripttempl/armcoff.sc: New file. + +Tue Sep 26 10:59:32 1995 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/i386coff.sc: Remove .data2; no longer needed. + +Fri Sep 22 18:09:02 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldfile.c (ldfile_set_output_arch): Make arch const. + +Thu Sep 21 17:55:24 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/elfppc.sc: Correctly locate __bss_start at the + beginning of the .bss area, not at the end of data. Add + __sbss_{start,end} symbols. + +Wed Sep 20 12:29:36 1995 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (CC_FOR_TARGET): Quote $(program_transform_name). + (CXX_FOR_TARGET, install): Likewise. + +Mon Sep 18 14:53:22 1995 Ian Lance Taylor <ian@cygnus.com> + + Based on patches by Alan Modra <alan@spri.levels.unisa.edu.au>: + * Makefile.in (CC_FOR_TARGET): Remove brokensed stuff. + (CXX_FOR_TARGET): Likewise. + (install): Likewise. + (GENERATED_HFILES): Remove config.h. + (.dep): Depend upon config.h. + +Mon Sep 18 14:39:38 1995 Arne H. Juul <arnej@pvv.unit.no> + + * configure.tgt (mips*-dec-netbsd*): New target. + +Fri Sep 15 20:01:52 1995 Ken Raeburn <raeburn@cygnus.com> + + * configure.host (m88*-*-dgux*): Fix another shell syntax error. + +Fri Sep 15 23:28:05 1995 Andrew Cagney <cagney@highland.com.au> + + * configure.host (i[345]86-*-bsd*): Fix shell syntax error. + +Thu Sep 12 12:50:49 1995 steve chamberlain <sac@slash.cygnus.com> + + * scripttemp/pe.sc: Allow both spellings of .ctors/.dtors. + Start .text section on the right boundary. Always align + stabs. + +Tue Sep 12 12:24:17 1995 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (maintainer-clean): New target. + + * ldmain.c (struct warning_callback_info): Define. + (warning_callback): Add new parameter symbol. Call + warning_find_reloc to try to find the section and VMA. + (warning_find_reloc): New static function. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): + Pass NULL as symbol parameter to warning callback. + + * ld.texinfo: Clarify -L option. + + * ldlang.c (lang_one_common): Add cast to avoid warning. + (topower): Likewise. Also, reindent. + * ldwrite.c (clone_section): Change i to unsigned int. + * emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation): Add + cast to avoid warning. + +Fri Sep 8 16:32:43 1995 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (config.status): Depend upon configure.tgt. + + * ldemul.h (ldemul_set_symbols): Declare. + (ldemul_parse_args): Declare. + * ldemul.c (ldemul_parse_args): Fix indentation. + + * configure.in: Call AC_HEADER_DIRENT. + * configure, config.in: Rebuild. + * emultempl/sunos.em: Use autoconf recommend mechanism to define + DIR and struct dirent. + + * configure.tgt (mips*-*-bsd*): New case. + + * configure.host (i[345]86-sequent-ptx* | i[345]86-sequent-sysv*) + New case. + * configure.tgt (i[345]86-*-ptx*): New case. + +Thu Sep 7 10:48:26 1995 Ian Lance Taylor <ian@cygnus.com> + + * config.in: Rename from config.h.in. + * configure.in: Call AC_CONFIG_HEADER with config.h:config.in. + Check for config.h:config.in when creating stamp-h. + * configure: Rebuild. + * Makefile.in (stamp-h): Depend upon config.in rather than + config.h.in. Set CONFIG_HEADERS to config.h:config.in when + calling config.status. + + * Makefile.in (distclean): Remove config.h and stamp-h. + + * configure.host (sparc-*-sunos64*): Remove. + * ldlang.c (lang_map): Check BFD64, not HOST_64_BIT. + + * ldexp.c (exp_fold_tree): Don't warn about moving the location + counter backward in the absolute section. + +Wed Sep 6 14:42:11 1995 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Rewrite to use autoconf. + * configure.host: New file. + * configure.tgt: New file. + * aclocal.m4: New file. + * configure: New file, built by autoconf. + * acconfig.h: New file. + * config.h.in: New file, built by autoheader. + * sysdep.h: New file. + * ld.h: Incorporate old contents of config.h. + * config.h: Remove. + * Makefile.in: Various changes for new configure script. Also: + (CC_FOR_BUILD): Remove. + (ldmain.o): Don't bother to ensure that EMUL is non-empty. + (dep.sed): Use @SRCDIR@, not @srcdir@. + * dep-in.sed: Use @SRCDIR@, not @srcdir@. + * genscripts.sh: Create ldscripts if it does not exist. + * ldemul.c, lexsup.c, mpw-emipsidt.c: Don't include "config.h". + * mpw-esh.c, emultemp/*.em: Likewise. + * ldmain.c: Likewise. Include <ctype.h>. Don't try to set + HAVE_SBRK here. + * config/*.mt, config/*.mh: Remove. + +Tue Sep 5 14:55:24 1995 Ken Raeburn <raeburn@cygnus.com> + + * configure.in: Treat ns32k-pc532-ux* like ns32k-pc532-mach*, and + ns32k-pc532-lites* like ns32k-pc532-netbsd*. From Ian Dall. + +Fri Sep 1 22:29:52 1995 Doug Evans <dje@canuck.cygnus.com> + + * scripttempl/pe.sc: Fix typo in spelling of .ctors/.dtors. + +Fri Sep 1 13:13:29 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (warning_callback): Add abfd, section, and address + parameters. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): + Change call to warning accordingly. + + * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): If not + relocateable and not shared, put .gnu.warning.SYMBOL sections into + the .text section. + +Fri Sep 1 08:35:16 1995 James G. Smith <jsmith@beauty.cygnus.com> + + * configure.in: Added mips*vr4300-idt-elf* and + mips*vr4300el-idt-elf* targets. + * Makefile.in: Added eelf32vr4300* targets. + * emulparams/{elf32vr4300.sh, elf32vr4300el.sh}: Added. + * config/{mips-vr4300.mt, mips-vr4300el.mt}: Added. + +Fri Sep 1 10:51:45 1995 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/a29k.sc: Fix to be reasonable. From Brendan Kehoe + <brendan@cygnus.com>. + +Thu Aug 31 16:37:07 1995 steve chamberlain <sac@slash.cygnus.com> + + * ldemul.c (ldemul_parse_args): New. + * ldemul.h (ld_emulation_xfer_struct): Add parse_args. + * lexsup.c (all pe stuff): Moved into pe.em + (parse_args): Call emulation arg parser. + * emultempl/pe.em (parse_args): handle PE specfic args. + +Thu Aug 31 17:01:37 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_memory_region_lookup): Don't use the first region + as the default region. Create a new region instead. + +Tue Aug 29 14:21:41 1995 steve chamberlain <sac@slash.cygnus.com> + + * ldemul.c (ldemul_set_symbols): New function. + * ldemul.h (ld_emulation_xfer_struct): Add set_symbols. + * ldmain.c (main): Add call to ldemul_set_symbols. + * lexsup.c (set_pe_value): New args. + (set_pe_name): New. + (parse_args): Cope with new set_pe_value args. + * emultempl/pe.em (set_symbols): New function. + (ld_emulation_xfer_struct): Add set_symbols. + * scripttempl/pe.sc: Use new symbols. + +Thu Aug 24 18:12:18 1995 Ian Lance Taylor (ian@cygnus.com) + + * lexsup.c (parse_args): Don't call set_default_dirlist for -O. + For -Y, ignore a leading `P,', and only call set_default_dirlist + after processing all the other arguments. + +Tue Aug 22 07:36:58 1995 steve chamberlain <sac@slash.cygnus.com> + + * scripttempl/pe.sc: Keep .edata, don't base stabs at 0. + * emulparams/armpe.sh: Run PE script. + +Mon Aug 21 18:30:42 1995 steve chamberlain <sac@slash.cygnus.com> + + * ldmain.c (main): Remove PE stuff. + * lexsup.c (options): Load more PE options. + (set_pe_value): New function. + +Thu Aug 17 13:35:49 1995 steve chamberlain <sac@slash.cygnus.com> + + + * emultempl/{armpe.sc, i386pe.sc}: Deleted. + * emultempl/pe.sc: New file performs generic PE support and sorts + archive members. + * emulparams/{armpe.sh,i386pe.sh}: Use new file. + * scripttempl/{armpe.sc, i386pe.sc}: Deleted + * scripttempl/pe.sc: New. + * Makefile.in: Use new files. + +Thu Aug 17 14:46:34 1995 Doug Evans <dje@canuck.cygnus.com> + + * scripttempl/h8500s.sc (.rdata): All data must go in data segment. + (.strings,.ctors,.dtors): Likewise. + +Wed Aug 16 11:38:59 1995 steve chamberlain <sac@slash.cygnus.com> + + * scripttempl/armpe.sc: Always start code at 0x401000, even + if -r. + * ldwrite.c (strdup): New extern declaration. + * ldgram.y (atype): New rule to clarify type parsing. + * ldlang.c (init_os): Remove commented out code. + (lang_size_sections): Set SEC_ALLOC and SEC_LOAD bits + unless told not to by the link script. + +Wed Aug 16 11:45:11 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_set_startof): New static function. + (lang_process): Call it. + + * ldgram.y: Tweak casesymlist to avoid bison errors. + + * lexsup.c (parse_args): Accept -h as a synonym for --soname, for + Solaris compatibility. + +Tue Aug 15 17:31:16 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldgram.y (YYDEBUG): If not defined, define as 1. + (CASE, EXTERN, START): New tokens. + (mri_script_command): Handle CASE, EXTERN, INCLUDE, START. + (casesymlist): New nonterminal. + (extern_name_list): New nonterminal. + * ldlex.l: Accept lower case trailing base specifiers. Don't + ignore the first digit when the base is a suffix. Accept many + EXPRESSION state tokens in MRI state. Support MRI continuation + lines and MRI semicolon comments. Accept all MRI keywords in + lower case. Add CASE, EXTERN, and START MRI keywords. + +Tue Aug 8 19:14:58 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com> + + * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Use xmalloc + instead of alloca. + +Tue Aug 8 15:24:05 1995 J.T. Conklin <jtc@rtl.cygnus.com> + + * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Don't use + $r/../gcc/xgcc unless it is present. + +Thu Aug 3 11:56:22 1995 Ian Lance Taylor <ian@cygnus.com> + + * scripttempl/m68kcoff.sc: Only put .ctors and .dtors in .text + when CONSTRUCTING. + * scripttempl/m68klynx.sc: Likewise. + * scripttempl/nw.sc: Likewise. + * scripttempl/sa29200.sc: Likewise. + * scripttempl/sparclynx.sc: Likewise. + +Fri Jul 28 12:02:23 1995 steve chamberlain <sac@slash.cygnus.com> + + * emulparams/{z8001.sh, z8002.sh}: Fix typo. + +Thu Jul 27 21:06:21 1995 Ken Raeburn <raeburn@cygnus.com> + + * configure.in (i[345]86-*-linuxoldld): Treat like linuxaout*. + +Thu Jul 27 15:26:28 1995 steve chamberlain <sac@slash.cygnus.com> + + * scripttempl/i386pe.sc: Cope with constructors. + * scripttempl/z8ksim.sc: Deleted. + * scripttempl/z8000.sc: Resurrected as this, but + can handle z8001 and z8002 formats. + * emulparams/z8ksim.sh: Deleted. + * emulparams/{z8001.sh, z8002.sh}: New files. + * config/z8ksim.mt: Deleted + * config/z8k-coff.mt: New, generates both emulations. + +Tue Jul 25 14:53:02 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldmisc.c (vfinfo): In %C and %D case, always print the BFD using + %B, in case it is in an archive. + +Mon Jul 24 15:23:39 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_process): Call reset_memory_regions for each + relaxation pass. + +Fri Jul 21 22:49:44 1995 Michael Meissner <meissner@cygnus.com> + + * scripttempl/elfppc.sc: Add support for .sdata, .sbss, and + _SDA_BASE. + +Thu Jul 20 16:26:55 1995 Ken Raeburn <raeburn@cygnus.com> + + * ldmain.c (constructor_callback): Allocate set_name in stack + frame, rather than always calling alloca with a fixed size. + +Wed Jul 19 16:21:43 1995 Doug Evans <dje@canuck.cygnus.com> + + * emulparams/armpe.sh (OUTPUT_FORMAT): Change to pei-arm-little. + (LITTLE_OUTPUT_FORMAT, BIG_OUTPUT_FORMAT): Define. + +Mon Jul 17 13:57:00 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldwrite.c (clone_section): Set the alignment of the clone + section to that of the section being cloned. + + * ldwrite.c (split_sections): Don't split the first input section + into a new output section. + +Sat Jul 15 00:26:35 1995 Michael Meissner <meissner@cygnus.com> + + * emulparams/elf32ppc.sh (TEMPLATE_NAME): Define as elf32. + (GENERATE_SHLIB_SCRIPT): Define as yes. + +Fri Jul 14 12:11:46 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/mipsecoff.em (check_sections): Use %P, not %F. + + * ldver.c (help): Update list of options to match currently + supported list. + +Thu Jul 13 13:52:10 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/lnk960.em (ld_lnk960_emulation): Initialize + after_open field. + + * ldexp.c (exp_intop): Don't cast stat_alloc arg to bfd_size_type; + it takes a size_t anyhow. + (exp_binop): Likewise. + (exp_trinop): Likewise. + (exp_unop): Likewise. + (exp_nameop): Likewise. + (exp_assop): Likewise. + * ldlang.c (lang_memory_region_lookup): Likewise. + (init_os): Likewise. + (ldlang_add_undef): Likewise. + (insert_pad): Likewise. + * ldfile.c (ldfile_add_arch): Don't cast xmalloc arg to + bfd_size_type. + + * Makefile.in (ALL_EMULATIONS): It's earmaoutb.o, not earmoutb.o. + +Wed Jul 12 11:32:22 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldemul.h (ldemul_open_dynamic_archive): Add search parameter to + declaration. + (ld_emulation_xfer_type): Add search parameter to + open_dynamic_archive entry point. + * ldemul.c (ldemul_open_dynamic_archive): Add search parameter. + * ldfile.c (ldfile_try_open_bfd): Rename from try_open_bfd, and + make non-static. Change all callers to use new name. + (ldfile_open_file_search): Make static. If entry is dynamic, call + ldemul_open_dynamic_archive. + (ldfile_open_file): Don't call ldemul_open_dynamic_archive. + * ldfile.h (ldfile_open_file_search): Don't declare. + (ldfile_try_open_bfd): Declare. + * emultempl/elf32.em (gld${EMULATION_NAME}_open_dynamic_archive): + Accept search parameter. Don't search for a library, just look in + a single place. + * emultempl/linux.em (gld${EMULATION_NAME}_open_dynamic_archive): + Likewise. + +Tue Jul 11 16:44:21 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (set_scripts_dir): Don't base script directory on + current directory. + +Tue Jul 11 12:29:02 1995 Rick Sladkey <jrs@world.std.com> + + * ldmisc.c (vfinfo): Don't print the line number if it isn't + meaningful. + +Mon Jul 10 13:38:28 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld.h (ld_config_type): Add field warn_constructors. + * ldmain.c (add_to_set): Warn if config.warn_constructors. + (constructor_callback): Likewise. + * lexsup.c (parse_args): Handle -warn-constructors. + * ld.texinfo, ld.1: Document -warn-constructors. + + * emultempl/elf32.em (gld${EMULATION_NAME}_check_needed): Don't + get confused by directory names if we searched for the file. + + Based on patches from H.J. Lu <hjl@nynexst.com>: + * ldlang.h (lang_input_statement_type): Add new field dynamic. + * ldlang.c (new_afile): Set dynamic from config.dynamic_link. + * ldfile.c: Include bfdlink.h. + (ldfile_open_file): Check dynamic field of entry, not global + dynamic_link field. Don't do a dynamic search when doing a + relocateable link. + * ldmain.c (main): Don't warn about dynamic_link for a + relocateable link. + * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Skip file if + dynamic is false. + (gld${EMULATION_NAME}_create_output_section_statements): Always + loop over input files. + * Makefile.in: Rebuild dependencies. + + * ld.texinfo, ld.1: Document -Bstatic, -Bdynamic, -Bshared, and + -shared. + +Mon Jul 10 13:29:43 1995 Eric Youngdale <eric@aib.com> + + * ldmain.c (main): Set link_info.symbolic to false. + * lexsup.c (parse_args): Handle -Bsymbolic. + +Wed Jul 5 00:12:11 1995 Fred Fish (fnf@cygnus.com) + + * ldmain.c (HAVE_SBRK): Define for everything except + specific systems that are known to not support sbrk. + (main): Use HAVE_SBRK to decide whether or not to use sbrk. + +Tue Jul 4 12:55:48 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_find_exp_assignment): + Handle etree_provide. + + * emultempl/elf32.em (global_needed): New static variable. + (global_found): Likewise. + (gld${EMULATION_NAME}_after_open): New static function. + (gld${EMULATION_NAME}_search_needed): Likewise. + (gld${EMULATION_NAME}_try_needed): Likewise. + (gld${EMULATION_NAME}_check_needed): Likewise. + (ld_${EMULATION_NAME}_emulation): Replace after_open_default with + gld${EMULATION_NAME}_after_open. + +Mon Jul 3 14:26:37 1995 Steve Chamberlain <sac@slash.cygnus.com> + + * configure.in (i386-*-win32): New target. + +Mon Jul 3 14:39:22 1995 Ian Lance Taylor <ian@cygnus.com> + + * lexsup.c (parse_args): Let -G either set the small data size or + be equivalent to --shared, depending on the next argument. Accept + and ignore -z for Solaris compatibility. + +Sun Jul 2 17:52:34 1995 Ian Lance Taylor <ian@cygnus.com> + + * lexsup.c (parse_args): Cast fopen result to PTR before storing + it in link_info.base_file. Fix indentation. + +Wed Jun 28 17:11:25 1995 Steve Chamberlain <sac@slash.cygnus.com> + + * ldmain.c (main): Always initialize PE info in link_info. + * lexsup.c (OPTION_BASE_FILE): New option. + (parse_args): Handle new option. + * emulparams/armpe.sh: Output pei. + * emultempl/i386pe.em: Add newline to end. + * scripttempl/armpe.sc: Change output and quote the $s. + * scripttempl/i386pe.sc: Change output and quote the $s. + +Thu Jun 22 19:55:41 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + Sun May 7 11:53:41 MDT 1995 Bryan Ford <baford@cs.utah.edu> + + * configure.in (i386-*-msdos*, i386-*-moss*): New targets. + * Makefile.in (ALL_EMULATIONS): Added i386msdos.o. + (i386msdos.o): New target. + * config/i386-msdos.mt: Created. + * emulparams/i386msdos.sh: Created. + * scripttempl/i386msdos.sc: Created. + +Thu Jun 22 15:06:35 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * scripttempl/elfppc.sc (.fixup): Add support for a .fixup section + that contains pointers to be relocated. + +Tue Jun 20 17:47:20 1995 Stan Shebs <shebs@andros.cygnus.com> + + * mpw-esh.c: New file, modified for MPW from esh.c. + * scripttempl/sh.sc: Reformatted to simplify MPWification, + use *() to concat stab sections instead of []. + +Thu Jun 15 08:48:16 1995 Steve Chamberlain <sac@slash.cygnus.com> + + * scripttempl/armpe.sc: Add constructor support. + +Tue Jun 13 09:11:20 1995 Steve Chamberlain <sac@slash.cygnus.com> + + * ldlang.c (lang_size_sections): Any section with a DATA + statement has contents. + +Sun Jun 11 15:20:46 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * emulparams/m68kelf.sh (NOP): Define. + (DYNAMIC_LINK): Don't define. + (TEXT_START_ADDR): Set to 0x80000000; the extra 0x100 for headers + will come from the linker script. + +Thu Jun 8 14:17:33 1995 Steve Chamberlain <sac@slash.cygnus.com> + + * emulparams/armpe.sh, scriptempl/armpe.sc: Add end and stack. + +Mon Jun 5 02:16:24 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com> + + * configure.in (i[345]86-*-gnu*): Use GNU elf config. + +Thu May 25 11:49:28 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + From Andrew Cagney <cagney@highland.com.au> + * Makefile.in: Fixup more gotchas from renaming elf32ppcle to + elf32lppc. + +Wed May 24 11:23:21 1995 Steve Chamberlain <sac@slash.cygnus.com> + + Add support for ARM-PE. + * Makefile.in (ALL_EMULATIONS): Add armpe.o + * configure.in: Recognize armpe. + * config/arm-pe.mt: New file. + * emulparams/armpe.sh: New file. + * scripttempl/armpe.sc: New file. + + +Mon May 22 15:19:26 1995 Doug Evans <dje@chestnut.cygnus.com> + + * configure.in (h8300h-*-hms): Deleted + * config/cf-h8300h.mt: Deleted. + +Thu May 18 04:26:10 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com> + + Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk) + + From David Taylor (dtaylor@armltd.co.uk) + * Makefile.in (ALL_EMULATIONS): Add earmout[lb].o + * configure.in: Recognize arm{,e[lb]-*-aout. + * config/arm[lb]-aout.mt: New files. + * emulparams/armaout[lb].sh: New files. + * scripttempl/armaout.sc: New file. + +Tue May 16 18:27:11 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * config/ppcle-elf32.mt (EMUL): Use elf32lppc, not elf32ppcle, to + be unique in 8 characters for DOS. + + * emulparams/elf32lppc.sh: New file, renamed from elf32ppcle.sh. + * emulparams/elf32ppcle.sh: Deleted. + +Fri May 12 11:03:55 1995 Steve Chamberlain <sac@slash.cygnus.com> + Tom Griest <griest@cs.yale.edu> + + Initial support for PE executables (eg NT, win32) + + * Makefile.in (configure.in, ei386pe): Add support. + * ldmain.c (main): Initialize PE argument info. + * ldwrite.c (print_file_stuff): Don't print out .drectve + and .debug section info. + * lexsup.c (set_subsystem, set_stack_heap, OPTION_HEAP, + OPTION_SUBSYSTEM, parse_argsm set_subsystem, set_stack_heap): + Handle new arguments. + * config/i386-pe.mt, emultempl/i386pe.em, scripttempl/i386pe.sc: + New files + +Wed May 10 18:37:59 1995 Stu Grossman (grossman@andros.cygnus.com) + + * scripttempl/hppaelf.sc: Remove .PARISC.unwind section from text + segment. This allows ld -r to preserve unwind sections. + +Tue May 9 17:19:57 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * configure.in: Add little endian PowerPC support. + + * Makefile.in (ALL_EMULATIONS): Add eelf32ppcle.o. + (eelf32ppcle.c): Support for little endian PowerPC. + + * config/ppcle-elf32.mt: New file for little endian PowerPC. + * emulparams/elf32ppcle.sh: Ditto. + +Wed May 3 12:56:32 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * ldlang.c (print_output_section_statement): Check + subsection_alignment, instead of checking section_alignment twice. + Noticed by Alan Modra <alan@spri.levels.unisa.edu.au>. + +Tue May 2 16:36:07 1995 Jeff Law (law@snake.cs.utah.edu) + + * configure.in (hppa*-*-lites*): Handle like hppa*-*-*elf*. + +Mon Apr 24 19:21:02 1995 Michael Meissner <meissner@cygnus.com> + + * ldwrite.c (ldwrite): Before doing anything, reset the error + code. If bfd_final_link returns an error, but the error code is + unset, don't issue an extra message. Assume a correct error + message was already set. + +Fri Apr 14 16:31:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * Makefile.in (ALL_EMULATIONS): Added em68kelf.o. + (em68kelf.o): New target. + * config/m68k-elf.mt, emulparams/m68kelf.sh: New files. + * configure.in: Use them for m68*-*-elf. + +Tue Apr 11 12:02:03 1995 Stan Shebs <shebs@andros.cygnus.com> + + Merge in support for Mac MPW as a host. + (Old change descriptions retained for informational value.) + + * mpw-config.in (i386-unknown-aout): Change to i386-unknown-go32. + (i386-unknown-coff): Remove. + (sh-hitachi-hms): New target. + (emulation_ofiles): Set correctly for each target. + (version, TDEFINES): Add to makefile fragment. + * mpw-make.in (BISON): Use byacc instead of bison. + (em_*.c): Replace with e*.c everywhere. + (ldgram.h): Separate action from ldgram.c generation. + (LD_PROG): Depend on Version.r. + (Version.r): generate from version info. + * mpw-emipsidt.c: New file, modified for MPW from emipsidt.c. + + * mpw-config.in (m68k-apple-macos, ppc-apple-macos, + i386-unknown-aout, i386-unknown-coff): New targets. + (m68k-aout, m68k-coff): Remove targets. + (mk.tmp): Add definition of EMUL. + + * mpw-config.in (emulname): Set based on target. + (ldemul-list.h): Construct. + * mpw-make.in (install-only): New target. + (install): Depend on install-only. + + * mpw-make.in (bindir): Fix pathname. + (install): Move here from mpw-build.in. + + * mpw-config.in: New file, MPW configuration fragment. + * mpw-make.in: New file, MPW makefile fragment. + (This file is semi-automatically generated from Makefile.in.) + * ldfile.c (slash): If MPW, set to `:'. + * ldlex.l (TRUE_FALSE_ALREADY_DEFINED): If MPW, set this to + prevent redefinition errors. + +Tue Apr 4 17:55:18 1995 Steve Chamberlain <sac@bang.hack.com> + + * ldwrite.c (clone_section): Align clone sections on even + boundaries. + +Thu Mar 30 14:32:26 1995 H.J. Lu (hjl@nynexst.com) + + * configure.in: Change linux to default to elf. Using + i[345]86-*-linuxaout will build a linker which defaults to a.out. + * config/i386-laout.mt: Rename from old config/i386-linux.mt. + * config/i386-linux.mt: Rename from old config/i386-lelf.mt. + * config/i386-lelf.mt: Remove. + +Thu Mar 30 13:09:46 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (main): If opening the map file fails, call + bfd_set_error before calling einfo. + + * ld.texinfo, ld.1: Document the -no-keep-memory option. + +Mon Mar 27 11:10:08 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (main): Revert patch of March 10, since the SVR4 linker + does mark shared libraries as executable. + +Tue Mar 21 15:15:38 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_common): Change power to int. Pass larger values + before smaller values. + (lang_one_common): Treat info as int *. Don't bother to check for + last value, since it is now zero. + +Sat Mar 18 01:49:14 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (load_symbols): An empty archive is OK. + +Fri Mar 17 16:15:31 1995 Stan Shebs <shebs@andros.cygnus.com> + + * ldmain.c (progress.h): Include. + (main): Call START_PROGRESS and END_PROGRESS. + +Thu Mar 16 17:17:33 1995 Michael Meissner <meissner@cygnus.com> + + * scripttempl/elfppc.sc: Move _GOT2_END_ after the .ctors and + .dtors sections, so that these pointers get relocated also. + Define the symbols __{C,D}TOR_{LIST,END}__ to mark the beginning + and end of the constructors/destructors. + +Thu Mar 16 13:59:14 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * ldlang.c (load_symbols): If whole_archive is true and ENTRY + describes an archive, call bfd_link_add_symbols on each member. + * ldmain.c (whole_archive): New variable. + (main): Initialize it to false. + * ldmain.h: Declare whole_archive. + * lexsup.c (parse_args): Grok --whole-archive switch. + * ld.texinfo, ld.1: Document --whole-archive. + +Thu Mar 16 11:38:48 1995 Ian Lance Taylor <ian@cygnus.com> + + * genscripts.sh (EMULATION_NAME): Set LIB_PATH to empty when not + using the default emulation. + + * config/dgux.mh (HOSTING_EMU): Use -m rather than trying to set + LDEMULATION. + * config/hppaelf.mh (HOSTING_EMU): Likewise. + +Tue Mar 14 12:28:03 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Set force_maj + for -lc.N. From H.J. Lu <hjl@nynexst.com>. + +Fri Mar 10 14:43:48 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (main): Don't set EXEC_P if link_info.shared is set. + + * ldlex.l: Return -lFILENAME as the token LNAME. + * ldgram.y: Add token LNAME. + (input_list): Treat LNAME like NAME, but pass it to + lang_add_input_file as lang_input_file_is_l_enum. + * ld.texinfo: Document using -lFILENAME in INPUT. + +Thu Mar 9 12:21:51 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * ldlang.c (lang_check): If the architectures are compatible call + bfd_merge_private_bfd_data to let the backend do additional + checks. + +Tue Mar 7 00:53:08 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldemul.c (ldemul_choose_mode): If emulation not recognized, list + all supported emulations. + +Mon Mar 6 14:03:50 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldemul.c (ldemul_list_emulations): New function. + * ldemul.h (ldemul_list_emulations): Declare. + * ldver.c (help): List supported targets and emulations. + +Fri Mar 3 15:40:36 1995 Doug Evans <dje@canuck.cygnus.com> + + * scripttempl/elf.sc (.debug): Relocate to address 0. + (.debug_srcinfo, .debug_aranges, .debug_pubnames, + .debug_sfnames, .line): Likewise. + +Fri Mar 3 17:07:14 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (hold_rel): New static variable. + (gld${EMULATION_NAME}_place_orphan): Place readonly sections with + contents whose names begin with ".rel" after hold_rel. Remove the + assertion which checked for unplaced .rel sections. Don't try to + sort the section into place if place->bfd_section is NULL. + (gld${EMULATION_NAME}_place_section): Set hold_rel to the first + section beginning with ".rel". + +Thu Mar 2 14:34:43 1995 Ian Lance Taylor <ian@cygnus.com> + + Doc note from pierre@phi.la.tce.com (Pierre Willard): + * ld.texinfo: -X and -x work even if -s or -S are not specified. + * ld.1: Similar change. + +Wed Mar 1 13:51:16 1995 Ian Lance Taylor <ian@cygnus.com> + + * emulparams/gld960coff.sh (COFF_CTORS): Define. + * scripttempl/i960.sc: Use COFF_CTORS if CONSTRUCTING. + +Tue Feb 28 12:42:56 1995 Ian Lance Taylor <ian@cygnus.com> + + * configure.in (i[345]86-*-linuxelf*): New target. Use i386-lelf. + (i[345]86-*-gnuelf*): New target. Use i386-gelf. + * config/i386-lelf.mt: New file. + * config/i386-gelf.mt: New file. + +Tue Feb 28 10:27:54 1995 Rob Savoye <rob@darkstar.cygnus.com> + + * configure.in: Match on mips-ecoff, and default to the IDT + configuration. + +Fri Feb 17 13:06:47 1995 Michael Meissner <meissner@cygnus.com> + + * scripttempl/elfppc.sc: Add support for .got1 and .got2 sections. + Offset _GLOBAL_OFFSET_TABLE_ 32768 from the start of the GOT area + to double the size of the table. + +Thu Feb 9 18:29:43 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * Makefile.in (distclean): Do recursive deletion, since ldscripts + is a directory. + +Thu Feb 9 11:38:22 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (main): If trace_file_tries is true, and we are using + an internal linker script, print out the script. + * ldfile.c (try_open): Reindent function. Make the messages about + opening script files more informative. + + * lexsup.c (parse_args): For -V, call ldversion with 1, not 0. + * ld.texinfo, ld.1: Update accordingly. + +Wed Feb 8 17:34:45 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldlang.c (lang_one_common): Adjust references to common symbol + information for new structure. + +Mon Feb 6 12:17:24 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldmain.c (undefined_symbol): Handle section being NULL. + + * ldctor.c (ldctor_build_sets): Handle bfd_link_hash_defweak. + * ldexp.c (fold_name): Likewise. + * ldlang.c (print_one_symbol): Likewise. + (lang_finish): Likewise. + * ldmain.c (multiple_common): Likewise. + * ldwrite.c (print_symbol): Likewise. Also, bfd_link_hash_weak + renamed to bfd_link_hash_undefweak. + + * scripttempl/alpha.sc: Set address of .data section correctly + when -n or -N is used. Patch from Chris G Demetriou + <Chris_G_Demetriou@LAGAVULIN.PDL.CS.CMU.EDU>. + * scripttempl/mips.sc: Similar change. + +Tue Jan 31 16:20:52 1995 Doug Evans <dje@canuck.cygnus.com> + + * ldlang.c (lang_size_sections): Clarify error message when user + specified start addr conflicts with region. Fix resetting of + region pointer. + +Tue Jan 31 12:37:09 1995 Ian Lance Taylor <ian@cygnus.com> + + * ldexp.c (fold_name): In case NAME, permit an absolute symbol + in lang_allocating_phase_enum. + +Mon Jan 30 11:33:25 1995 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (distclean): Depend upon clean. Don't bother to + remove files which will be removed by clean. From patch by + alan@SPRI.Levels.UniSA.Edu.Au (Alan Modra). + +Fri Jan 27 16:27:34 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): For + a MIPS target, clobber the size of all but the first input + .reginfo section to be 0, so that lang_size_sections sets the + correct size for the output .reginfo section. + +Thu Jan 26 19:53:37 1995 Ian Lance Taylor <ian@cygnus.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): + Remove unused variable is. + +Thu Jan 26 12:33:05 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * configure.in: Add support for powerpc-*-eabi. + + * scripttempl/elfppc.sc: New file for PowerPC embedded ABI + support. + + * emulparams/elf32ppc.sh (SCRIPT_NAME): Use elfppc.sc instead of + elf.sc, which defines some new symbols PowerPC elf needs. + +Tue Jan 24 10:32:15 1995 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ldctor.c (ldctor_add_set_entry): Don't dump core if a + constructor entry is in the absolute section. + +Mon Jan 23 13:58:13 1995 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * configure.in (i[345]86-*-gnu*): Set ld_target to i386-gnu. + * config/i386-gnu.mt: New file. Include ELF support. + +Thu Jan 19 16:22:11 1995 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): If + there are any input sections named .gnu.warning, treat them as + containing a warning message to be printed by the linker, and + clobber the size so that the message is not copied into the output + file. + * scripttempl/elf.sc: Put .gnu.warning sections into the .text + section. + +Sun Jan 15 16:45:00 1995 Steve Chamberlain <sac@splat> + + * configure.in (w65-*-*): New target. + * Makefile.in: Update. + * scripttempl/w65.sc: New. + * config/coff-w65.mt: New. + +Thu Jan 12 01:32:25 1995 Ian Lance Taylor <ian@tweedledumb.cygnus.com> + + * ldlang.c (lang_place_orphans): Don't ignore files with + just_syms_flag set. Instead, put all their sections in + bfd_abs_section_ptr, using the section VMA as the output_offset. + +Wed Jan 11 22:59:09 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * ldctor.c (ldctor_build_sets): Don't use `const' with typedef + name `reloc_howto_type', since it's now defined to be const. + * ldlang.c (lang_add_reloc): Ditto. + * ldlang.h (lang_reloc_statement_type, lang_add_reloc): Ditto. + +Wed Jan 11 11:24:45 1995 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ldexp.c (fold_binary): Adding or subtracting an absolute value + to a relative value does not require forcing the relative value to + be absolute. Also, reindent function. + +Wed Dec 28 22:05:52 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * ldwrite.c (clone_section): Create a symbol with the + same name as the section. + +Mon Dec 19 14:02:13 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * ld.h (split_by_reloc, split_by_file): New flags. + * ldwrite.c (clone_section, split_sections): New functions. + * lexsup.c (parse_args): Understand new split options. + +Fri Dec 9 17:22:55 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * scripttempl/elf.sc: Move .ctors and .dtors from .text segment to + .data segment. They must be writable when creating a shared + library. From H.J. Lu <hjl@nynexst.com>. + +Fri Dec 2 14:09:00 1994 Ian Lance Taylor <ian@rtl.cygnus.com> + + * emultempl/miposecoff.em: New file. + * emulparams/mipsidt.sh (TEMPLATE_NAME): Set to mipsecoff. + * emulparams/mipsidtl.sh (TEMPLATE_NAME): Likewise. + * scripttempl/mips.sc: Put .rel.sdata sections in .text, and + provide __runtime_reloc_start and __runtime_reloc_stop if they are + used. Align _fdata to a 16 byte boundary. + * Makefile.in (emipsidt.c): Depend upon mipsecoff.em rather than + generic.em. + (emipsidtl.c): Likewise. + (check): Pass CC_FOR_HOST and CFLAGS_FOR_HOST to runtest. + + * ld.h (args_type): Add new field embedded_relocs. + * ldemul.h (ldemul_after_open, after_open_default): Declare. + (ld_emulation_xfer_struct): Add new field after_open. + * ldemul.c (ldemul_after_open): New function. + (after_open_default): New function. + * ldlang.c (lang_process): Call ldemul_after_open. + * lexsup.c (parse_args): Handle --embedded-relocs. + * emultempl/elf32.em (ld_${EMULATION_NAME}_emulation): Initialize + new after_open field to after_open_default. + * emultempl/generic.em, emultempl/gld960.em: Likewise. + * emultempl/gld960c.em, emultempl/hppaelf.em: Likewise. + * emultempl/linux.em, emultempl/m88kbcs.em: Likewise. + * emultempl/sunos.em, emultempl/vanilla.em: Likewise. + * ld.texinfo, ld.1: Mention -embedded-relocs. + +Wed Nov 23 22:04:47 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * Makefile.in: Add eshl.o. + * config/coff-sh.mt: Add shl emulation. + +Tue Nov 22 11:55:37 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * scripttempl/elf.sc: Fill .text section with NOPS. From Eric + Youngdale <eric@aib.com>. + +Thu Nov 17 14:39:48 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + Patches from pirker@eiunix.tuwien.ac.at (Martin Pirker). + * config/i386linux.mh: New file; set HOSTING_CRT0. + * genscripts.sh: Don't put ${libdir} in LIB_PATH if it is + /usr/lib, since that is already in LIB_PATH. + +Wed Nov 16 10:03:03 1994 Jeff Law (law@snake.cs.utah.edu) + + * scripttempl/hppaelf.sc (.text): Handle a use rdefined text start + address. + (.data, .bss): If "-N", then place the data/bss just after the end + of the .text section rather than at the default 0x40000000. + + * scripttempl/hppaelf.sc (.text): Place unwind descriptors in the + text segment. + +Sat Nov 12 15:55:56 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + Patches from Eric Youngdale <eric@aib.com>: + * ldlang.c (lang_finish): Don't warn if entry symbol not found + when generating a shared library. + * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Warn if + attempting to place an orphaned relocation section when generating + a dynamically linked object. + + * scripttempl/elf.sc: Add ENTRY(${ENTRY}), and default ${ENTRY} to + _start. + +Fri Nov 11 14:27:23 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ld.h (args_type): Add field export_dynamic. + * lexsup.c (parse_args): Recognize --export-dynamic. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): + Pass export_dynamic argument to bfd_elf32_size_dynamic_sections. + +Wed Nov 9 12:47:11 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ldlang.c (lang_one_common): Set SEC_ALLOC in any section where + we allocate common symbols. + +Tue Nov 8 17:50:43 1994 Eric Youngdale (eric@aib.com) + + * scripttempl/elf.sc: Add .rel.init, .rela.init, .rel.fini, and + .rela.fini to the list of .rel* sections. + +Tue Nov 8 17:47:45 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ldlang.c (load_symbols): Add new argument place. Only accept + linker scripts if place is not NULL. Put commands found in an + assumed linker script into place. + (lookup_name): Pass NULL as place argument to load_symbols. + (open_input_bfds): In lang_input_statement_enum case, pass a place + argument to load_symbols, and store any new statements after the + current one. + +Mon Nov 7 15:53:02 1994 Ken Raeburn <raeburn@cujo.cygnus.com> + + * ldver.c (ldversion): Bump to 2.5.3. + +Fri Nov 4 15:11:26 1994 Ken Raeburn <raeburn@cujo.cygnus.com> + + * Makefile.in (e*nbsd.c): Fix typo in dependencies. + +Thu Nov 3 19:35:44 1994 Ken Raeburn <raeburn@cujo.cygnus.com> + + * Makefile.in (check): Add missing "else true" clause. + + * emulparams/vax.sh (OUTPUT_FORMAT): Use "a.out". + + * scripttempl/go32coff.sc: Changes from DJ Delorie: Change default + entry point to "start". Align at end of each section to 0x200. + Start .text section 0x1000 later. Add _etext, _edata, _end + symbols. + +Wed Nov 2 12:17:49 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ldctor.c (ldctor_add_set_entry): Don't permit a set to be + composed of different object file formats. + (ldctor_build_sets): If the output format does not support the + reloc, and we are not generating a relocateable link, try getting + the reloc from the input format. + +Tue Nov 1 10:30:19 1994 J.T. Conklin (jtc@rtl.cygnus.com) + + * Makefile.in (ALL_EMULATIONS): Added em68knbsd.o. + (em68knbsd.c): New target. + + * config/m68k-nbsd.mt: New file. + * emulparams/m68knbsd.sh: New file. + * configure.in (m68*-*-netbsd*): Use above configs. + +Mon Oct 31 19:35:17 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): If we find an + appropriately named static library, stop the search at that + directory. + +Wed Oct 26 13:59:12 1994 J.T. Conklin (jtc@phishhead.cygnus.com) + + * Makefile.in (ALL_EMULATIONS): Added ei386nbsd.o, ens32knbsd.o + and esparcnbsd.o; sorted entries. + (ei386nbsd.c,ens32knbsd.c,esparcnbsd.c): New targets. + + * config/netbsd532.mt: Removed. + * emulparams/netbsd532.sh: Removed. + + * config/{i386-nbsd.mt,ns32k-nbsd.mt,sparc-nbsd.mt}: New files. + * emulparams/{i386nbsd.sh,ns32knbsd.sh,sparcnbsd.sh}: New files. + * configure.in (i[345]86-*-netbsd*, ns32k-pc532-netbsd*, + sparc*-*-netbsd*): Use above configs. + +Tue Oct 25 11:47:10 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ldmain.c (multiple_common): One of the types may now be + bfd_link_hash_indirect. The old BFD argument may be NULL. + +Thu Oct 20 22:01:39 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * configure.in: Add * at the end of m68k-hp-hpux. + +Tue Oct 18 15:58:39 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ldlex.l: Cast assignment to yy_ch_buf field to char *, not to + YY_CHAR *. + +Mon Oct 17 14:53:16 1994 J.T. Conklin (jtc@phishhead.cygnus.com) + + * scripttempl/nw.sc: Gather constructors and destructors and + define __CTOR__LIST__ and __DTOR_LIST__ appropriately. + +Fri Oct 14 14:35:38 1994 J.T. Conklin (jtc@rtl.cygnus.com) + + * Makefile.in (ALL_EMULATIONS): Add ei386nw.o and eppcnw.o. + (ei386nw.c, eppcnw.c): New targets. + + * config/{i386,ppc}-nw.mt, emulparams/{i386,ppc}nw.sh, + scripttempl/nw.sc: New files, for i386 and powerpc netware. + + * configure.in: Changed netware ld_target name to be {i386,ppc}-nw + instead of {i386,ppc}-elf. + + * configure.in (sparc*-*-netware): Removed. There is no such + thing anymore. + + * ldint.texinfo: Move misplaced `@end iftex'. + +Fri Oct 14 12:02:18 1994 Eric Youngdale (eric@aib.com) + + * scripttempl/elf.sc: Add .rel.ctors, .rela.ctors, .rel.dtors, and + .rela.dtors to the list of .rel* sections. + +Thu Oct 13 14:16:27 1994 Ken Raeburn <raeburn@cujo.cygnus.com> + + * ldver.c (ldversion): Update to version 2.5. + * Version 2.5 released. + + * configure.in (all_targets): Handle i386-linux*. + +Thu Oct 13 11:24:33 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * scripttempl/aout.sc: Set _etext and __etext to ., not + ${DATA_ALIGNMENT}. This is compatible with SunOS, and, with luck, + will not break any other system. From Eric Valette + <ev@chorus.fr>. + +Wed Oct 12 16:22:58 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * lexsup.c (parse_args): Change -V to be a synonym for -v. Add + --verbose to get the old -V behaviour. + * ld.1, ld.texinfo: Document this change. + +Tue Sep 27 14:56:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Remove + assertion, since it could fail with a user defined linker script. + + * ldexp.c (fold_name): For DEFINED case, don't try to look up the + name in the hash table during the first phase--the hash table does + not even exist at that point, much less have the right value. + + * Makefile.in (CC): Define. + (CXX): Move definition, change from g++ to gcc. + (EXPECT, RUNTEST): Copy definitions from top level Makefile.in. + (RUNTEST_CC, RUNTEST_CFLAGS): Remove. + (RUNTEST_CXX, RUNTEST_CXXFLAGS): Remove. + (CC_FOR_TARGET, CXX_FOR_TARGET): Copy from top level Makefile.in. + (.cc.o): Comment out. + (testdir): Remove. + (site.exp): Don't create testdir or set tmpdir. + (check): Run checks even if not running native. Use CC_FOR_TARGET + instead of RUNTEST_CC, and likewise for CXX. + (cdtest targets): Comment out. + * config/solaris2.mh (HOSTING_LIBS): Only mention crtend.o once. + * cdtest-bar.cc, cdtest-foo.cc, cdtest-foo.h: Remove. + * cdtest-main.cc, cdtest.exp: Remove. + +Mon Sep 26 11:40:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * emulparams/elf32bmip.sh: Rename from elf32mipb.sh to avoid DOS + file naming problems. + * emulparams/elf32lmip.sh: Rename from elf32mipl.sh. + * Makefile.in (ALL_EMULATIONS): Rename eelf32mipb.o to + eelf32bmip.o and eelf32mipl.o to eelf32lmip.o. + (eelf32bmip.c): Rename from eelf32mipb.c. Use elf32bmip.sh. + (eelf32lmip.c): Rename from eelf32mipl.c. Use elf32lmip.sh. + * config/mipsb-elf32.mt (EMUL): Use elf32bmip, not elf32mipb. + * config/mipsl-elf32.mt (EMUL): Use elf32lmip, not elf32mipl. + + * genscripts.sh: Always search /usr/local/TARGET/lib. + + * scripttempl/elf.sc: If -N is set, force DATA_ADDR to be ".". + +Fri Sep 23 15:05:49 1994 Ken Raeburn <raeburn@cujo.cygnus.com> + + * configure.in: Handle i386-bsdi* targets like i386-bsd. + +Fri Sep 23 00:06:59 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * lexsup.c (parse_args): Add support for -a for HP/UX + compatibility. + + * lexsup.c (parse_args): -c takes an argument. + +Tue Sep 20 14:35:27 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ld.h (args_type): Add new field endian. + * lexsup.c (parse_args): Handle -EB and -EL by setting + command_line.endian. + * ldgram.y (ifile_p1): Accept OUTPUT_FORMAT with three arguments. + * ldlang.c (lang_add_output_format): Add arguments big and little. + If command_line.endian is set, use it to select big or little + rather than the default. Changed all callers. + * ldlang.h (lang_add_output_format): Update declaration. + * emulparams/elf32mipb.sh: Define BIG_OUTPUT_FORMAT and + LITTLE_OUTPUT_FORMAT. + * emulparams/elf32mipl.sh: Likewise. + * emulparams/mipsbig.sh: Likewise. + * emulparams/mipsbsd.sh: Likewise. + * emulparams/mipsidt.sh: Likewise. + * emulparams/mipsidtl.sh: Likewise. + * emulparams/mipslit.sh: Likewise. + * scripttempl/elf.sc: Define BIG_OUTPUT_FORMAT and + LITTLE_OUTPUT_FORMAT if not already defined. Pass them to + OUTPUT_FORMAT. + * scripttempl/mips.sc: Pass BIG_OUTPUT_FORMAT and + LITTLE_OUTPUT_FORMAT to OUTPUT_FORMAT. + * scripttempl/mipsbsd.sc: Likewise. + + * Makefile.in (ldgram.h): Make separate target from ldgram.c, + depending upon ldgram.c, so that a parallel make does not try to + build both at once. + + * configure.in (mips*el-elf*): New target. + * Makefile.in (ALL_EMULATIONS): Add eelf32mipb.o and eelf32mipl.o. + (eelf32mipl.c): New target. + + * config/mipsl-elf32.mt: New file. + * emulparams/elf32mipl.sh: New file. + +Fri Sep 16 12:16:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ldmain.c (main): Rather than prohibiting ld -r -s, treat it as + ld -r -S -x. + +Thu Sep 15 13:05:44 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ldmisc.c (vfinfo): Print BFD file name as well as file name + returned by find_nearest_line, in case the file name is something + unhelpful such as a .h file. Handle %u. + +Wed Sep 14 12:49:12 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * ldlang.c (lang_do_assignments): Make sure output statement + has an attached bfd_section before trying to dereference it. + +Wed Sep 14 12:48:09 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ld.h (ld_config_type): Add new field warn_once. + * ldmain.c (undefined_symbol): Handle -warn-once. + * lexsup.c (parse_args): Recognize -warn-once. + * ld.texinfo (Options): Document -warn-once. + * ld.1: Likewise. + + * ldmisc.c (vfinfo): Handle %D as %C, but never print the function + name. For %C, print the function name on a separate line, to keep + the length of error messages under control. + * ldmain.c (multiple_definition): Use %D for ``first defined + here.'' + (undefined_symbol): Use %D for ``more undefined references + follow''. + + * ldmisc.c (multiple_warn): Remove; no longer used. + * ldmisc.h (multiple_warn): Don't declare. + +Tue Sep 13 20:47:58 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * ldlang.c (print_output_section_statement): Print all lines + to the map file. + +Tue Sep 13 16:30:11 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ldlang.c (load_symbols): Check for archive before object. Use + bfd_check_format_matches, and, if ambiguous, print a list of + matching formats. If file format is not recognized, treat file as + a linker script. + * ldgram.y (yyerror): If assuming an object file is a script, + mention that. Tweak the format of the error messages. + * ldlex.l (lex_warn_invalid): If assuming an object is a script, + guess that this is not actually a script, and just report that the + file format was not recognized. + * ld.texinfo (Options): Admit that -( may be used more than once. + Add note that unrecognized object files are now treated as linker + scripts. + + * ldfile.c (ldfile_input_filename): Make const. + (ldfile_assumed_script): New variable. + (try_open): Change arguments types to const. + (ldfile_find_command_file): Likewise. + (ldfile_open_command_file): Likewise. Also, set lineno to 1. + * ldfile.h: Update declarations for ldfile.c changes. + * ldlex.l: Include <ctype.h>. + (file_name_stack): Change to be const char *. + (lineno_stack): New static variable. + (<<EOF>>): Set lineno as well as ldfile_input_filename. + (lex_push_file): Make name argument const. Initialize + lineno_stack entry. + (lex_redirect): Initialize lineno_stack entry. + (lex_warn_invalid): Handle non printable characters nicely. + * ldlex.h (lex_push_file): Declare second argument as const. + + * ldgram.y (ifile_p1): Recognize GROUP. + * ldlex.l: Recognize GROUP. + * ld.texinfo (Option Commands): Document GROUP. + +Mon Sep 12 17:04:27 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * config/m68klynx.mh: New file. + +Mon Sep 12 01:50:03 1994 Jeff Law (law@snake.cs.utah.edu) + + * emultempl/hppaelf.em: Add newlines to the error messages. + +Sat Sep 10 16:05:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * config/i386lynx.mh: New file. + * scripttempl/i386lynx.sc: Don't put .ctors and .dtors in .text + unless CONSTRUCTING. + +Thu Sep 8 13:25:24 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * emulparams/elf32mipb.sh (TEMPLATE_NAME): Define as elf32. + (GENERATE_SHLIB_SCRIPT): Define as yes. + (DYNAMIC_LINK): Define as false. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_parse): + Initialize config.dynamic_link to DYNAMIC_LINK if it is defined. + (gld${EMULATION_NAME}_place_orphan): Reset stat_ptr at end. + * Makefile.in (eelf32mipb.c): Depend upon elf32.em rather than + generic.em. + +Thu Sep 8 16:30:37 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * scripttempl/h8500b.sc: Put rdata stuff into own segment. + +Thu Sep 8 13:25:24 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * emulparams/elf32ppc.sh (OTHER_READWRITE_SECTIONS): Don't define; + .got section is now explicitly handled in elf.sc. + +Wed Sep 7 13:08:34 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * scripttempl/alpha.sc: Redo script to set . outside of sections + and not bother to explicitly specify section addresses. + Explicitly place .sdata section. + +Tue Sep 6 23:51:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * scripttempl/m68kcoff.sc: Put .bss in data segment. + + * scripttempl/h8300.sc: Change .stab and .stabstr to use a VMA of + 0, and to only be marked as NOLOAD if relocating. + * scripttempl/h8500.sc, scripttempl/h8500b.sc: Likewise. + * scripttempl/h8500c.sc, scripttempl/h8500m.sc: Likewise. + * scripttempl/h8500s.sc, scripttempl/i386coff.sc: Likewise. + * scripttempl/i386go32.sc, scripttempl/i386lynx.sc: Likewise. + * scripttempl/m68kcoff.sc, scripttempl/m68klynx.sc: Likewise. + * scripttempl/sh.sc, scripttempl/sparccoff.sc: Likewise. + * scripttempl/sparclynx.sc: Likewise. + +Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org) + + * Makefile.in, configure.in: Add support (disabled) the ARM/RISCiX. + * config/riscix.mt, emulparams/riscix.sh, scripttempl/riscix.sc: + New files. + +Tue Aug 30 11:48:08 1994 Eric Youngdale (ericy@cais.cais.com) + + * ld.h (args_type): Add field soname. + * lexsup.c (parse_args): Handle -soname argument. + * emultempl/elf32.em: In call to bfd_elf32_size_dynamic_sections, + pass soname. + * ld.texinfo: Document -soname. + +Mon Aug 29 15:21:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ldlang.c (lang_check): Don't try to set the architecture if the + input and output files are incompatible. Just warn. + +Wed Aug 24 12:52:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * configure.in: Change i[34]86 to i[345]86. + +Sun Aug 21 16:17:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * emulparams/hp3hpux.sh: Define __DYNAMIC to be 0. + +Thu Aug 18 15:37:45 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + Make the ELF linker handle orphaned sections reasonably. Also, + define __start_SECNAME and __stop_SECNAME around sections whose + names can be represented in C, for the benefit of symbol sets in + glibc. + * ldemul.h (ldemul_place_orphan): Declare. + (ld_emulation_xfer_type): Add place_orphan field. + * ldemul.c (ldemul_place_orphan): New function. + * ldlang.h (wild_doit): Declare. + * ldlang.c (wild_doit): Make nonstatic. + (lang_place_orphans): Call ldemul_place_orphan. + * emultempl/elf32.em: Include <ctype.h> and "ldgram.h". + (hold_section, hold_use, hold_text, hold_data, hold_bss): New + static variables. + (gld${EMULATION_NAME}_place_orphan): New static function. + (gld${EMULATION_NAME}_place_section): New static function. + (ld_${EMULATION_NAME}_emulation): Initialize place_orphan field. + +Tue Aug 16 00:17:20 1994 Eric Youngdale (ericy@cais.cais.com) + + * scripttempl/aout.sc: Add .linux-dynamic after .data. + +Tue Aug 16 00:08:22 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * lexsup.c (parse_args) Treat --dll-verbose as --version, for + Linux compatibility. From hjl@nynexst.com (H.J. Lu). + +Mon Aug 15 17:17:33 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ldexp.h (exp_get_abs_int): Declare. + +Sat Aug 6 01:45:39 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * ldlang.c (lang_do_assignments): Handle complex AT's better. + * ldexp.c (exp_get_abs_int): New function. + +Fri Aug 5 20:55:55 1994 Jason Molenda (crash@phydeaux.cygnus.com) + + * configure.in: add i960-nindy-coff support. + +Thu Aug 4 14:45:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ldlex.l (yy_create_string_buffer): Handle change to internal + interface in flex 2.4.7. + +Tue Aug 2 11:52:06 1994 Eric Youngdale (ericy@cais.cais.com) + + * emultempl/linux.em (gld${EMULATION_NAME}_find_address_statement): + New function; add 0x20 to any use of -Ttext. + (gld${EMULATION_NAME}_create_output_section_statements): New + function. + (ld_${EMULATION_NAME}_emulation): Use the new function + gld${EMULATION_NAME}_create_output_section_statements. + +Mon Aug 1 15:50:44 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * scripttempl/mips.sc: Redo script to set . outside of sections + and not bother to explicitly specify section addresses. + +Tue Jul 26 11:02:35 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * scripttempl/elf.sc: Copy several more relocation sections into + the output. Put .got.plt sections into .got. + +Fri Jul 22 12:15:36 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * scripttempl/elf.sc: Use PROVIDE to define etext, edata, and end. + + Add a new script operator, PROVIDE, to define a symbol only if it + is needed. + * ldgram.y (PROVIDE): New token. + (assignment): Accept PROVIDE. + * ldlex.l (PROVIDE): New token. + * ldexp.h (node_type): Add etree_provide to node_class enum. + (exp_provide): Declare. + * ldexp.c (exp_fold_tree): Handle etree_provide. + (exp_provide): New function. + (exp_print_tree): Handle etree_provide. + * ld.texinfo: Document PROVIDE. + + * ldlang.c (lang_common): Pass desired alignment to + lang_one_common as power of two. + (lang_one_common): Get common symbol alignment from linker hash + table entry. Treat desired alignment as a power of two. + + * ldlang.c (wild_section): Attach all section with the given name, + not just the first one. If there is no name, attach all sections + even if the SEC_IS_COMMON flag is set. + +Wed Jul 20 15:49:27 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ld.h (args_type): Add field rpath. + * lexsup.c (S_ISDIR): Define if not already defined. + (parse_args): Add support for -rpath. If -R is used to name a + directory, treat it as -rpath for Solaris compatibility. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): + Pass command_line.rpath to bfd_elf32_size_dynamic_sections. + * ldmain.c (main): Initialize command_line.rpath to NULL. + * ld.texinfo: Document -rpath option. + +Sun Jul 10 00:33:24 1994 Ian Dall (dall@hfrd.dsto.gov.au) + + * emulparams/pc532machaout.sh: New file. Pc532 mach script + parameters. + + * emulparams/netbsd532.sh: New file. Netbsd 532 script parameters. + + * config/pc532mach.mt: New file. Pc532 mach target support. + + * config/pc532mach.mh: New file. Pc532 mach host support. + + * config/netbsd532.mt: New file. Netbsd 532 target support. + + * configure.in: Add ns32k-pc532-mach and ns32k-pc532-netbsd support. + + * Makefile.in: Add epcmachaout.c dependency and enetbsd532.c + dependency. + +Fri Jul 8 10:57:02 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation): Use + bfd_abs_section_ptr, not &bfd_abs_section. + + * lexsup.c (parse_args): Changed "retain-symbols-file" from + no_argument to required_argument. From djm. + +Thu Jul 7 12:29:53 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * scripttempl/elf.sc: Explicitly mention .stab and .stabstr + sections to force a VMA of 0; needed for ELF backends which have + not been converted to the new linker style. + +Mon Jul 4 19:35:45 1994 Jeff Law (law@snake.cs.utah.edu) + + * scripttempl/hppaelf.sc (__stack_zero): Don't define this name, + it was for the HPUX dynamic loader's use and it creates problems + with ELF GDB. + +Fri Jul 1 12:53:47 1994 Jeff Law (law@snake.cs.utah.edu) + + * ldlang.c (lang_do_assignments): No longer static. Delete decl. + * ldlang.h (lang_do_assignments): Put external decl here. + * emultempl/hppaelf.em: Minor cleanups throughout file. + (hppa_elf_create_output_section_statements): Rewrite. + (hppaelf_finish): Rewrite. + +Wed Jun 29 16:50:00 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * config/solaris2.mh (NATIVE_LIB_DIRS): Define as /usr/ccs/lib. + + * lexsup.c (parse_args): Accept -Bstatic and -Bdynamic. Do not + accept plain -B. + * ld.texinfo: -Bstatic is not ignored. + +Tue Jun 28 12:13:34 1994 Stan Shebs (shebs@andros.cygnus.com) + + * ldlex.l: Recognize \r the same as \n. + +Thu Jun 23 17:53:04 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + Preliminary support for generating shared libraries, from Eric + Youngdale <ericy@cais.cais.com>. + * genscripts.sh: If the emulation parameter file sets + GENERATE_SHLIB_SCRIPT, generate a .xs script file with + CREATE_SHLIB defined. + * emultempl/elf32.em (gld${EMULATION_NAME}_get_script): If + link_info.shared is set, use the .xs script file. + * scripttempl/elf.sc: If CREATE_SHLIB is set, don't create a + .interp section, and don't include TEXT_START_ADDR in the starting + address of the first section. + * emulparams/elf_i386.sh (GENERATE_SHLIB_SCRIPT): Likewise. + * emulparams/elf32_sparc.sh (GENERATE_SHLIB_SCRIPT): Define. + +Thu Jun 23 12:52:22 1994 David J. Mackenzie (djm@rtl.cygnus.com) + + * configure.in: Change --with-targets to --enable-targets. + +Wed Jun 22 13:42:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * lexsup.c (parse_args): Add support for new options -( -) with + synonyms --start-group --end-group. + * ldlang.h (enum statement_enum): Add lang_group_statement_enum. + (lang_group_statement_type): Define new struct. + (lang_statement_union_type): Add group_statement field. + (lang_enter_group, lang_leave_group): Declare. + * ldlang.c (lang_for_each_statement_worker): Handle + lang_group_statement_enum. + (map_input_to_output_sections, print_statement): Likewise. + (lang_size_sections, lang_do_assignments): Likewise. + (open_input_bfds): Completely rewrite. Now does its own looping, + rather than using lang_for_each_statement. Handle groups. + (lang_process): Update call to open_input_bfds. + (print_group): New static function. + (lang_enter_group, lang_leave_group): New static functions. + * ldfile.c (ldfile_open_file): If the file has already been + opened, just return rather than taking an assertion failure. + * ldver.c (help): Mention new options. + * ld.texinfo: Document new options. + + * ldlang.c (end_of_data_section_statement_list): Don't define. + (lang_leave_output_section_statement): Don't set obsolete variable + end_of_data_section_statement_list. + + * scripttempl/go32coff.sc: Don't put ${DATA_ALIGNMENT} inside an + ALIGN. + + * ldlang.c (lang_size_sections): Adjust current region address + even for sections with an explicit address. From + ralphc@pyramid.com (Ralph Campbell). + + * emulparams/i386linux.sh (NONPAGED_TEXT_START_ADDR): Set to 0. + From jrs@world.std.com (Rick Sladkey). + + * scripttempl/mipsbsd.sc: Let sections align to their natural + boundaries. + +Tue Jun 21 11:27:04 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ldlang.c (lang_init): Use new bfd_abs_section_ptr, not + &bfd_abs_section. + (lang_abs_symbol_at_beginning_of): Likewise. + (lang_abs_symbol_at_end_of): Likewise. + (lang_size_sections): Use bfd_is_abs_section to check for the + absolute section. Don't try to set the VMA or output_offset or + size of the absolute section. + * ldmain.c (notice_ysym): Use bfd_is_und_section to check for the + undefined section. + +Thu Jun 16 22:48:41 1994 Jeff Law (law@snake.cs.utah.edu) + + * scripttempl/hppaelf.sc: Place .data and .bss at 0x40000000 + when generating relocatable objects. + +Thu Jun 16 14:25:22 1994 Eric Youngdale (ericy@cais.cais.com) + + * emultempl/linux.em: New file providing support for linking + against Linux shared libraries. + * config/i386-linux.mt (ei386linux.c): Depend upon linux.em. + * emulparams/i386linux.sh (TEMPLATE_NAME): Define as linux. + +Thu Jun 16 12:22:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * lexsup.c (parse_args): Add -shared to longopts, and handle it. + * ldmain.c (main): Initialize link_info.shared to false. Give + error if link_info.relocateable and link_info.shared are both set. + + * configure.in: If EMUL_EXTRA* is defined in a config file, treat + it as naming an emulation to be added to EMULATION_OFILES. + * config/i386-linux.mt (EMUL_EXTRA1): Define as elf_i386. + + * Makefile.in: Rebuilt dependencies. + (ALL_EMULATIONS): Add ei386linux.o, eelf32_sparc.o, + eelf64_sparc.o. Remove $(OTHER_EMULATIONS). + (ei386linux.c, eelf32_sparc.c, eelf64_sparc.c): New targets. + * config/i386-linux.mt (OTHER_EMULATIONS): Don't define. + (ei386linux.c): Remove; now in Makefile.in. + * config/i386-lynx.mt (OTHER_EMULATIONS): Don't define. + * config/m68k-lynx.mt (OTHER_EMULATIONS): Don't define. + * config/sparc-lynx.mt (OTHER_EMULATIONS): Don't define. + * config/sparc64-elf.mt (OTHER_EMULATIONS): Don't define. + (eelf64_sparc.c): Remove; now in Makefile.in. + * config/sun4sol2.mt (OTHER_EMULATIONS): Don't define. + (eelf32_sparc.c): Remove; now in Makefile.in. + + * ldexp.c (exp_print_tree): Don't crash if etree_rel section has + no owner--it might be bfd_abs_section. From Eric Youngdale + <ericy@cais.cais.com>. + + * scripttempl/aout.sc: Let sections align to their natural + boundaries. + +Wed Jun 15 01:54:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldemul.h (ldemul_open_dynamic_archive): Declare. + (ld_emulation_xfer_type): Add new field open_dynamic_archive. + * ldemul.c: Include ldexp.h and ldlang.h. + (ldemul_open_dynamic_archive): New function. + * ldfile.h (ldfile_open_file_search): Declare. + * ldfile.c: Include ldemul.h. + (try_open_bfd): Rename from cache_bfd_openr. Return boolean + argument, not bfd *. Change all callers. + (ldfile_open_file_search): Rename from open_a. Return boolean + argument, not bfd *. Clean up. Change all callers. + (ldfile_open_file): If doing a dynamic link, call + ldemul_open_dynamic_archive rather than assuming the extension of + a dynamic object is ".so". + * emultempl/elf32.em (gld${EMULATION_NAME}_open_dynamic_archive): + New function. + (ld_${EMULATION_NAME}_emulation): Initialize open_dynamic_archive + field. + * emultempl/sunos.em (ld_${EMULATION_NAME}_emulation): Likewise. + + * ldmain.c (get_emulation): Ignore -m486 for Linux compatibility. + * lexsup.c (parse_args): Ignore -qmagic for Linux compatibility. + Accept -static as a synonym for -non_shared. + + Let the user change the dynamic linker used by ELF code. + * ld.h (args_type): Add new field interpreter. + * lexsup.c (parse_args): Add dynamic-linker to longopts, and + handle it. + * ldmain.c (main): Initialize command_line.interpreter to NULL. + * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Get + the ELF backend to return the .interp section. If + command_line.interpreter is not NULL, set the contents of .interp + to it. + * ld.texinfo: Mention -dynamic-linker. + + * config/sun4sol2.mt (eelf32_sparc.c): Depend upon elf32.em, not + generic.em. + + * lexsup.c (parse_args): Sort out the option macros and change the + definitions to make it easier to add a new option. + + * scripttempl/aout.sc: Define __etext and __edata to go along with + _etext and _edata. + + * ld.h (ld_config_type): Add new field traditional_format. + * lexsup.c (parse_args): Add traditional-format to longopts, and + handle it. + * ldmain.c (main): Initialize config.traditional_format to false. + * ldlang.c (ldlang_open_output): Set BFD_TRADITIONAL_FORMAT in BFD + flags of output_bfd according to config.traditional_format. + * ldver.c (help): Mention -traditional-format. + * ld.texinfo: Document -traditional-format. + +Tue Jun 14 23:10:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldctor.c (ldctor_add_entry): Add entries to a set in the order + they are encountered. + +Tue Jun 14 18:05:09 1994 Eric Youngdale (ericy@cais.cais.com) + + * emulparams/i386linux.sh (TEXT_START_ADDR): Define as 0x1000. + (NONPAGED_TEXT_START_ADDR): Define as 0x20. + +Mon Jun 13 15:46:09 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * scripttempl/alpha.sc: Define _ftext, _etext and _fdata insted of + _FTEXT, _ETEXT and _FDATA. Dont define _END. + + * ldfile.c (open_a): If this is not an archive, try to open it in + the current directory before searching for it. + + * lexsup.c (parse_args): Treat -i as a synonym for -r. + + * ldgram.y (exp): Treat BLOCK as a synonym for ALIGN, so that + BLOCK works in a section address as documented. + + * ldgram.y (YYDEBUG): Don't define. + +Fri Jun 10 16:45:39 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * emultempl/gld960.em: Pass false for new argument to + ldfile_add_library_path. + * emultempl/gld960c.em, emultempl/lnk960.em: Likewise. + + * emultempl/sunos.em: Only look for .so files if doing a dynamic + link. + +Thu Jun 9 08:35:17 1994 Ian Lance Taylor (ian@cygnus.com) + + * scripttempl/i960.sc: Add CONSTRUCTORS to .data. + +Thu Jun 9 06:52:29 1994 Bill Cox (bill@rtl.cygnus.com) + + * Makefile.in (check): Delete ld.new dependency so that a regression + test doesn't trigger a rebuild of the linker. + +Thu Jun 9 00:17:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (map_input_to_output_sections): For lang_address, call + init_os if it hasn't already been called. + +Thu Jun 2 17:24:08 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + Add support for SunOS shared libraries. + * aout.sc: Don't define __DYNAMIC here. Add new sections used by + shared library support code. + * emultempl/sunos.em: New file. + * emulparams/sun4.sh (TEMPLATE_NAME): Define as sunos. + * emulparams/sun3.sh (TEMPLATE_NAME): Likewise. + * Makefile.in (esun4.c): Depend upon sunos.em, not generic.em. + (esun3.c): Likewise. + + * ldlang.c: Minor formatting cleanups. + (lang_for_each_input_file): New function. + * ldlang.h (lang_for_each_input_file): Declare. + + * ldfile.h (search_dirs_type): Move from ldfile.c, and add cmdline + field. + (search_head): Declare. + (ldfile_add_library_path): Add new cmdline argument in prototype. + * ldfile.c (search_head): Make non-static. + (search_dirs_type): Move to ldfile.h. + (ldfile_add_library_path): Accept cmdline argument, and save it. + * lexsup.c (parse_args): Pass true for new cmdline argument of + ldfile_add_library_path. + (set_default_dirlist): Likewise. + * ldmain.c (check_for_scripts_dir): Pass false for new cmdline + argument of ldfile_add_library_path. + * ldgram.y (ifile_p1): Likewise. + +Wed Jun 1 14:24:08 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.h (lang_input_statement_type): Remove fields subfiles, + total_size, superfile and chain. + * ldfile.c (open_a): Don't clear search_dirs_flag. + (ldfile_open_file): Don't try to open superfile. Assert that file + has not already been opened. + * ldlang.c (new_afile): Don't initialize superfile. + * ldmain.c (add_archive_element): Don't initialize subfiles or + chain or superfile. Initialize search_dirs_flag to false. + +Fri May 27 12:25:33 1994 Ken Raeburn (raeburn@cujo.cygnus.com) + + * ldver.c (ldversion): Changed version to "cygnus-2.4.1". + + Changes from binutils-2.4 release: + + * genscripts.sh (RELOCATING, CONSTRUCTING): When setting + variables, use whitespace, so scripts don't break. + + * config/alphaosf.mh (HDEFINES, CFLAGS): Deleted. + + * emultempl/generic.em: Find emultempl/stringify.sed in ${srcdir}. + + * cdtest-bar.cc: Renamed from cdtest-func.cc. + * Makefile.in: Noted change. + + * scripttempl/a29k.sc: Don't include /lab3/u3/..../segments.o; I + don't know where that's supposed to come from, or why it's + necessary. + + Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com) + + * configure.bat: update to latest makefile.in + * emulpara/go32.sh: set to coff-go32 not aout + * emultemp/generic.em: strength-reduce the structure of + this shell script, since the only available shell for + DOS can't handle complex syntax. + * emultemp/stringify.sed: for "sed -f" instead of inline. + * makefile.in: depend on stringify.sed as well as genscripts.sh + * scripttemp/go32coff.sc: correct for djgpp 1.11's COFF format + * genscripts.sh: empty variables aren't always considered "set", + so set them to "y" instead. + +Fri May 27 01:08:14 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (entry_symbol): Make static. + (lang_add_entry): Add cmdline argument. + * ldlang.h (lang_add_entry): Change prototype. + * ldgram.y (statement_anywhere): Change lang_add_entry call. + * lexsup.c (parse_args): Likewise. + +Tue May 24 16:13:43 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * emulparams/elf32mipb.sh (OTHER_READONLY_SECTIONS): Don't give + .reginfo an address. + (OTHER_READWRITE_SECTIONS): Don't give .lit4 or .lit8 an address. + (OTHER_SECTIONS): Define for .gptab.sdata and .gptab.sbss. + * scripttempl/elf.sc: Use OTHER_SECTIONS at end of script. + +Thu May 19 13:31:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + Add support for ELF shared libraries. + * ld.h (ld_config_type): Add field dynamic_link. + * ldmain.c (main): Initialize config.dynamic_link to false. Warn + on attempts to use -r with -relax, -call_shared or -s. + * lexsup.c (longopts): Separate OPTION_CALL_SHARED from + OPTION_NON_SHARED. Add OPTION_IGNORE. Adjust macro values + accordingly. Add "dy" and "non_shared" options. Change "Qy" to + OPTION_IGNORE for now. Handle OPTION_CALL_SHARED and + OPTION_NON_SHARED by setting dynamic_link field accordingly. + Handle OPTION_IGNORE by ignoring it. Clear dynamic_link field for + -r and -Ur. + * ldfile.c (ldfile_open_file): If config.dynamic_link is true, try + opening a file with a .so extension first. + * emultempl/elf32.em: New file. + * emulparams/elf32_sparc.sh (TEXT_START_ADDR): Change to 0x10000. + (NONPAGED_TEXT_START_ADDR): Likewise. + (TEMPLATE_NAME): Define as elf32. + (DATA_PLT): Define. + * emulparams/elf_i386.sh (TEMPLATE_NAME): Define as elf32. + * scripttempl/elf.sc: Add placement for new dynamic sections. + Don't use CREATE_OBJECT_SYMBOLS. Define _etext, _edata and _end + outside of any section. Don't use ALIGN(8); just let one section + VMA follow another. Put .dynbss in .bss. Don't mention debugging + sections; they'll be handled correctly anyhow. + * Makefile.in (eelf_i386.c): Depend upon elf32.em, not generic.em. + +Wed May 18 10:15:39 1994 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in (install): Redirect output of ln to /dev/null. + +Mon May 16 13:35:08 1994 Jeff Law (law@snake.cs.utah.edu) + + * emultempl/hppaelf.em: Change all references of + .hppa_linker_stubs to .PARISC.stubs. + * scripttempl/hppaelf.sc: Likewise. + +Fri May 13 13:00:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (print_output_section_statement): Change ``no attached + output section'' message slightly. + (lang_do_assignments): Don't recurse down if there is no real + section. + + * config/i386-linux.mt (OTHER_EMULATIONS): Change em_ to e to + match corresponding change in emulation templates. + * config/i386-lynx.mt, config/m68k-lynx.mt: Likewise. + * config/sparc-lynx.mt, config/sun4sol2.mt: Likewise. + +Wed May 11 18:16:46 1994 Ken Raeburn (raeburn@cujo.cygnus.com) + + * ldver.c (ldversion): Updated version number. + + * cdtest-foo.cc: Use explicit "#pragma implementation". + * cdtest-bar.cc: Renamed from cdtest-func.cc. + * Makefile.in: References to cdtest-func.o changed to + cdtest-bar.o. + +Wed May 11 16:24:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + Don't create unnecessary output sections. + * ldlang.c (out_bfd_get_section_by_name): Remove. + (wild_section): Call bfd_get_section_by_name rather than + our_bfd_get_section_by_name. Don't call wild_doit if there is no + section. + (lang_create_output_section_statements): Remove. + (map_input_to_output_sections): For several cases, call init_os if + it has not already been called. + (lang_size_sections): If output section was not created, skip it. + (lang_process): Don't call lan_create_output_section_statements. + (lang_place_orphans): Skip files with just_syms_flags set to true. + * ld.texinfo: Document change. + +Tue May 10 14:31:16 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (wild_doit): Don't bother initializing the vma and + section size. Don't special case SEC_SHARED_LIBRARY. + (lang_size_sections): Handle SEC_COFF_SHARED_LIBRARY sections + specially. + +Fri May 6 12:24:27 1994 Steve Chamberlain (sac@cygnus.com) + + * config/go32.mh : New file for Xgo32X. + +Fri May 6 15:15:35 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldfile.c (ldfile_open_command_file): Set bfd_error_system_call + before calling einfo, since we are reporting an fopen failure. + From jrs@world.std.com (Rick Sladkey). + + * configure.in: Use "e" rather than "em_" as prefix for + emulations. + +Fri May 6 01:08:14 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com) + + * emultempl/generic.em: Use "e" rather than "em_" as prefix for + filename. + * emultempl/gld960.em, emultempl/gld960c.em, emultempl/lnk960.em, + emultempl/hppaelf.em, emultempl/m88kbcs.em, emultempl/vanilla.em: + Ditto. + * Makefile.in: Changed all generated file names. + (ldemul-list.h): Depend on Makefile, not config.status. Changed + sed patterns to handle new filenames. + + * config/mipsl-idt.mt: Renamed from mips-idtl.mt. + * configure.in: Adjusted. + +Thu May 5 15:07:32 1994 Ken Raeburn (raeburn@cujo.cygnus.com) + + * Makefile.in (install-info): Don't use "$<*", it doesn't always + work. Instead, check build dir and $srcdir explicitly, and use + `echo' to get all the filenames. + + * configure.in (h8300h-*-hms): Changed ld_target name to + cf-h8300h. + * config/cf-h8300h.mt: Renamed from coff-h8300h.mt, to make it + unique in 8.3. + + * config/i960coff.mt: New file. + * emulparams/gld960coff.sh: New file. + * emultempl/gld960c.em: New file. + * configure.in (i960-*-vxworks5* except -vxworks5.0*): Use + i960coff configuration. + * Makefile.in (em_gld960coff.c): Added dependencies, build rule. + + * Makefile.in (ALL_EMULATIONS): Remove em_delta68.o, since the + code isn't included in FSF releases, and it can still be + explicitly selected. + (distclean): Remove site.bak and tmpdir. + (STAGESTUFF): Removed $(GENERATED_CFILES) $(GENERATED_HFILES). + (mostlyclean): Delete them explicitly here. Also remove tmpdir. + + Patches from Ralph Campbell: + * config/mipsbsd.mh: New file. + * Makefile.in (em_mipsbsd.c): Use mipsbsd.sc, not aout.sc. + * scripttempl/mipsbsd.sc: Don't define __DYNAMIC. + * emulparams/mipsbsd.sh (OUTPUT_FORMAT): Fix name to have `a.out' + instead of `aout'. + + * configure.in (i386-*-gnu*): Treat like i386-*-mach*. + +Wed May 4 11:59:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * config/m68k.mt (EMUL): Set to m68kaout. + * emulparams/m68kaout.sh: New file. + * Makefile.in (ALL_EMULATIONS): Add em_m68kaout.o. + (em_m68kaout.c): New target. + + * ldlang.c (lang_size_sections): If dot moves because of an + assignment, don't try to insert a pad into the absolute output + section, just change the address of the default memory region + instead. + + * Makefile.in (mostlyclean): Remove cdtest.tmp, cdtest-ur, + cdtest-ur.out, and cdtest-ur.tmp. + +Wed Apr 27 16:03:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * scripttempl/sa29200.sc: Align all sections to four byte + boundaries. + +Wed Apr 27 10:48:03 1994 Steve Chamberlain (sac@cygnus.com) + + * Makefile.in, configure.in: Support for go32 coff. + * config/i386-go32.mt: New file + * emulparams/i386go32.sh: New file + * scripttempl/i386go32.sc: New file + +Tue Apr 26 17:20:03 1994 Stan Shebs (shebs@andros.cygnus.com) + + * Makefile.in (em_m68klynx.c, em_i386lynx.c, em_sparclynx.c): Use + Lynx-specific script templates. + * configure.in (sparclite*-*-coff): Use coff-sparc. + * emulparams/i386lynx.sh (SCRIPT_NAME): Set to i386lynx. + * emulparams/sparclynx.sh (SCRIPT_NAME): Set to sparclynx. + (ENTRY): Set to __main. + * scripttempl/i386lynx.sc: New file, script for I386 Lynx. + * scripttempl/m68klynx.sc: Add insertion of ctor/dtor sections. + * scripttempl/sparclynx.sc: New file, script for uSparc Lynx. + +Tue Apr 26 12:41:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * scripttempl/mips.sc: Force _gp and .lit8 to be aligned to a 16 + byte boundary, in case the global constructors do not take up an + even 16 bytes. + + * config/i386v4.mh (HOSTING_CRT0): If ../gcc/crtbegin.o does not + exist, get crtbegin based on gcc -print-libgcc-file-name. + (HOSTING_LIBS): Similar change for ../gcc/crtend.o. + +Mon Apr 25 15:27:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (lang_size_sections): When no address is given for a + section, align it according to its requirements. + +Thu Apr 21 17:24:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * Makefile.in (clean, distclean): Remove configdoc.texi. + +Tue Apr 19 12:12:15 1994 Bill Cox (bill@rtl.cygnus.com) + + * configure.in: Add i[34]86-*-bsd386 to the patterns recognized. + +Fri Apr 15 14:35:42 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (lang_size_sections): When relaxing, adjust the + position of a padding statement, and adjust dot accordingly. + +Mon Apr 11 17:37:09 1994 Bill Cox (bill@rtl.cygnus.com) + + * Makefile.in (EXPECT, RUNTEST): Set these for the check goal. + +Mon Apr 11 12:32:57 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * scripttempl/i386coff.sc: If relocating, don't put .init and + .fini sections into .text; keep them separate. + * config/i386sco.mh (HOSTING_CRT0): If ../gcc/crtbegin.o does not + exist, get crtbegin based on gcc -print-libgcc-file-name. + (HOSTING_LIBS): Similar change for ../gcc/crtend.o. + +Mon Apr 11 10:31:00 1994 Bill Cox (bill@rtl.cygnus.com) + + * Makefile.in (check): Set TCL_LIBRARY for runtest. + +Wed Apr 6 00:09:37 1994 Jeffrey A. Law (law@snake.cs.utah.edu) + + * configure.in (hppa*-*-*elf*): Don't require "-hp-" for the + manufacturer. + + * emultempl/hppaelf.em (hppaelf_finish): Only resize sections + if building a final executable. + +Tue Apr 5 12:17:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldmain.c (main): Check the return value of bfd_close. + +Thu Mar 31 18:07:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * scripttempl/alpha.sc: Clean up section alignment to ensure that + sections never overlap when using -r. + +Wed Mar 30 15:51:15 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldmisc.c (vfinfo): Change symbol reading slightly for recent BFD + changes: get_symtab_upper_bound renamed and returns long, + bfd_canonicalize_symtab returns long, check for error indications. + +Fri Mar 25 17:20:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (print_input_section): For section size, use + _cooked_size if it is non-zero, size otherwise. + (size_input_section): Likewise. + (lang_do_assignments): Likewise (case lang_input_section_enum). + +Thu Mar 24 15:20:47 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (new_afile): Add new argument add_to_list. Don't set + real to true for lang_input_file_is_marker_enum. Clear the_bfd. + (lang_add_input_file): Pass true to new_afile for add_to_list. + (lookup_name): Remove force_load argument. Changed all callers. + Pass false to new_afile for add_to_list. Split loading of symbols + out into separate function. + (load_symbols): New function split out of lookup_name. Don't load + the symbols if they are already loaded. + (open_input_bfds): For lang_input_statement_enum call load_symbols + rather than lookup_name. + (lang_process): Pass abs_output_section rather than NULL to + lang_size_sections. + (lang_startup): Set real field of first_file to true. + +Wed Mar 23 14:15:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (had_relax): Removed. + (relax_again): New static variable. + (lang_size_sections): Change call to bfd_relax_section to + correspond to BFD changes. Set relax_again appropriately. + (lang_process): Remove #if 0 code. When relaxing, keep calling + lang_do_assignments and lang_size_sections until relax_again + becomes false. + + * emultemp/gld960.em: Include libiberty.h + (gld960_before_parse): Pass NULL as final argument to concat. + +Tue Mar 22 13:08:28 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * scripttempl/aout.sc: Force _end and __end to be aligned to a + four byte boundary. + + * ldwrite.c (build_link_order): Handle lang_data_statement_enum by + building a bfd_data_link_order, rather than by setting the section + contents immediately. + +Mon Mar 21 18:28:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + Changes to make -Ur work again. + * ldmain.c (add_to_set): Now takes reloc argument rather than + bitsize. Check config.build_constructors here. If an new hash + table entry is created, mark it as undefined. + (constructor_callback): No longer takes bitsize argument. Pass + BFD_RELOC_CTOR to ldctor_add_set_entry, but first make sure the + BFD backend supports it. + (reloc_overflow): Handle a NULL abfd argument. + (reloc_dangerous, unattached_reloc): Likewise. + * ldctor.c: Include ldmain.h. + (struct set_info): Change bitsize field to reloc. + (ldctor_add_set_entry): Now takes reloc argument rather than + bitsize. Don't bother to check config.build_constructors here. + (ldctor_build_sets): Get the size from the reloc howto. If + generating relocateable output, call lang_add_reloc rather than + lang_add_data. + * ldctor.h (ldctor_add_set_entry): Change declaration to use reloc + instead of bitsize. + * ldlang.h (statement_enum): Add lang_reloc_statement_enum. + (lang_reloc_statement_type): New structure. + (lang_statement_union_type): Add reloc_statement field. + (lang_add_reloc): Declare new function. + * ldlang.c (lang_for_each_statement_worker): Handle + lang_reloc_statement_enum. + (map_input_to_output_sections, print_statement): Likewise. + (lang_size_sections, lang_do_assignments): Likewise. + (print_reloc_statement): New function. + (lang_add_reloc): New function. + * ldwrite.c (build_link_order): Handle lang_reloc_statement_enum. + + * Makefile.in (cdtest.out, cdtest-ur.o): New targets. + (cdtest-ur, cdtest-ur.out): New targets. + (check-cdtest): Now also check that -Ur works correctly. + + * scripttemp/alpha.sc: Align all sections to 16 byte boundaries. + +Thu Mar 17 12:45:41 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (lang_process): Move lang_common call before + map_input_to_output_sections, to ensure that any alignment + constraints set by common symbols are copied over to the output + sections. + +Fri Mar 11 22:17:34 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * emulparams/elf32ppc.sh (TEMPLATE_NAME): Don't define. + (OTHER_READWRITE_SECTIONS): Rename .toc to .got. + * Makefile.in (em_elf32ppc.c): Depend upon generic.em, not ppc.em. + * emultempl/ppc.em: Remove ugly stub code; turns out not to be + needed for ELF. + +Tue Mar 8 04:22:27 1994 David J. Mackenzie (djm@rtl.cygnus.com) + + * config/i386bsd.mh: New file. + +Mon Mar 7 15:23:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * elf.sc: Permit TEXT_START_SYMBOLS and DATA_START_SYMBOLS to be + defined. + * emulparams/elf32mipb.s (TEXT_START_SYMBOLS): Define _ftext. + (DATA_START_SYMBOLS): Define _fdata. + +Mon Feb 28 10:59:14 1994 Stan Shebs (shebs@andros.cygnus.com) + + * ldlang.c (cat): Define using ANSI style if ALMOST_STDC defined. + +Sun Feb 27 16:29:38 1994 Jeffrey A. Law (law@snake.cs.utah.edu) + + * emultempl/hppaelf.em (hppaelf_finish): Update comments. This + works again. Attach some output symbols to the stub file bfd. + + * emultempl/hppaelf.em: Include elf32-hppa.h. + (file_chain): Add decl. + (hppa_look_for_stubs_in_section): Delete decl. + (hppaelf_finish): Reenable code. Do not pass symbols + down to hppa_look_for_stubs_in_section. + +Sat Feb 26 10:58:25 1994 Ian Lance Taylor (ian@cygnus.com) + + * ldmain.c (write_map): Don't define. Removed all references. + Just use map_file or map_filename instead. + (add_archive_element): Use minfo to write map information, not + info_msg. + (constructor_callback): Use fprintf to write map information, not + info_msg. + * ldmain.h (write_map): Don't declare. + * ldgram.y (mri_script_command): Removed reference to write_map. + * ldlang.c (lang_one_common): Likewise. + * lexsup.c (parse_args): Likewise. + +Fri Feb 25 19:12:03 1994 Ian Lance Taylor (ian@cygnus.com) + + * scripttempl/elf.sc: Force all sections to be aligned. + + * ldgram.y (section): Reverse the order of memspec_opt and + fill_opt to avoid an ambiguity when both are used. + * ld.texinfo: Changed accordingly. + + * ldgram.y: Move include of ldlex.h back with other includes. + * ldlex.h (input_type): Don't initialize enum constants to + particular values. + * ldlex.l: Use a switch to return the right token based on + input_type, rather than knowing that input_type has a value based + on a token type. + + * ldgram.y (dirlist_ptr): Removed; not used. + * lexsup.c: Include ldver.h. + * Makefile.in: Rebuilt dependencies. + +Fri Feb 25 18:55:54 1994 Ted Lemon (mellon@pepper.ncd.com) + + * ldlang.c (lookup_name): don't call bfd_set_gp_size. + (ldlang_add_file): call it here instead. + +Fri Feb 25 18:13:46 1994 David J. Mackenzie (djm@rtl.cygnus.com) + + * ldgram.y: Include ldlex.h after %token decls, for byacc. + +Fri Feb 25 10:47:25 1994 Jeffrey A. Law (law@snake.cs.utah.edu) + + * emultempl/hppaelf.em: First attempt to clean this file up. + Add comments in several functions as to their purpose and + how they function (or my current best guess). Clean up horrible + spacing and indention that never should have been accepted in the + first place. Add FIXMEs for issues which need to be resolved. + Disable linker-stub generation until it gets fixed. This allows + the linker to at least work on simple code for testing purposes. + + * ldlang.c (lang_size_sections): No longer static (PA ELF calls + it via hppaelf_finish). Prototype moved into ldlang.h. + (lang_process): Move problematic extra call to lang_size_sections + into the PA ELF specific code. + * emultempl/hppaelf.em (hppaelf_finish): Extra call to + lang_size_sections moved here. + +Thu Feb 24 16:47:33 1994 Ian Lance Taylor (ian@cygnus.com) + + * configure.in (powerpc-*-elf*): New target; use ppc-elf32. + * config/ppc-elf32.mt: New file. + * emulparams/elf32ppc.sh: New file. + * emultempl/ppc.em: New file. + * Makefile.in (ALL_EMULATIONS): Added em_elf32ppc.o. + (em_elf32ppc.c): New target; uses elf32ppc.sh, ppc.em and elf.sc. + (EMULATION_OFILES): Added dependencies on ldexp.h and ldlang.h. + +Thu Feb 24 12:27:07 1994 David J. Mackenzie (djm@rtl.cygnus.com) + + * lexsup.c (parse_args): Use symbolic numbers for long options. + Fix misunderstanding in -Y and -call_shared et al. + + Use getopt instead of lex and yacc to parse the command line. + + * ld.texinfo (Options): Document changes to option syntax. + * Makefile.in: Update dependencies. + * ldver.c (help): Tweak dashes in usage message. + * ldgram.y (%union): Remove unused members. + Remove %tokens for command line options; add ones for input types. + (command_line): Rules removed. + (file): Instead of command line, recognize an + input type indicator, then use the nonterminal for that type. + (defsym_expr): New nonterminal from code formerly in command_line. + * ldlex.h: Declare parser input type enum and variable. + Don't declare parse_line. + * ldlex.l: Remove unused variables. Make some used ones static + and comment them. + (COMMAND): Start state and its rules removed. + At start of yylex, return input state token if at start of input. + (lex_redirect): Don't need to set yyout. + (ldlex_command): Function removed. + * ldmain.c (main): Instead of calling parse_line, set up the + redirections and call yyparse directly. + * ldmisc.c (vfinfo): If there's no input filename, print nothing, not + "command line". + * lexsup.c: Remove #if 0'd code. + (parse_line): Function removed. + (parse_args): Rewrite to use getopt_long_only. + (set_default_dirlist): New function from code formerly in + ldgram.y:command_line. + (set_section_start): New function. + * emultempl/generic.em, emultempl/gld960.em, emultempl/hppaelf.em, + emultempl/lnk960.em, emultempl/m88kbcs.em: Don't enclose + compiled-in link scripts in "{" and "}", as the grammar no longer + wants them to be. + +Thu Feb 24 08:43:26 1994 Ken Raeburn (raeburn@rtl.cygnus.com) + + * Makefile.in (ld.dvi): Depend on configdoc.texi, but don't + require that it be in $(srcdir). + +Tue Feb 22 09:21:18 1994 Ian Lance Taylor (ian@cygnus.com) + + * ldlang.c (lang_size_sections): Only align section to alignment + required by linker script, not to maximum alignment of input + sections. + + * ldlang.h (largest_section): Don't declare. + * ldlang.c (largest_section): Don't define. + (size_input_section): Don't set largest_section; not used. + +Mon Feb 21 15:15:29 1994 Ian Lance Taylor (ian@cygnus.com) + + * ldlang.c (new_afile): Pass NULL as last argument to concat. + +Thu Feb 17 15:51:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c, ldmain.c: Include libiberty.h. + + * ldmisc.h (concat): Don't declare. + * ldmisc.c (concat): Don't define; just use the one in libiberty. + + * ld.h (as_output_section_statement): Removed; not used. + +Thu Feb 17 09:32:14 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldlang.c, ldmain.c, ldmisc.c: Use bfd_get_error and + bfd_set_error and new error names. + +Tue Feb 15 20:14:53 1994 Ken Raeburn (raeburn@cujo.cygnus.com) + + * ldwrite.c (build_link_order): If the cooked size of the section + has been set, use it, for determining link_order size. + (ldwrite): In the error message displayed if bfd_final_link fails, + indicate that it was in fact the final link step that failed. + + * ldlang.c (lang_size_sections): Clear bfd_error before calling + bfd_relax_section, in case it returns false but doesn't flag an + error. If an error is returned, indicate which one it is in the + error message. + + * Makefile.in (install-info): Depend on ld.info, and use "$<*" so + it'll get picked up from $(srcdir) if appropriate. + +Tue Feb 15 16:32:04 1994 David J. Mackenzie (djm@rtl.cygnus.com) + + * scripttempl/aout.sc: Only pad .text if PAD_TEXT is set. + * emulparams/i386mach.sh (PAD_TEXT): Set PAD_TEXT. + +Fri Feb 11 17:02:49 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldlex.l (comment): Increment line number when newline is read. + +Fri Feb 11 17:36:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (lookup_name): Take new argument, force_load. If true, + reload the file even if it is already loaded. + (wild): Call lookup_name with force_load argument of 0. + (open_input_bfds): Call lookup_name with force_load argument of 1. + (print_symbol): Remove declaration of non-existent function. + (print_one_symbol): Return true rather than falling off end. + +Thu Feb 10 11:52:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldmain.c (main): Use %ld when printing long values. + + * scripttempl/elf.sc: Move _edata after the .sdata section. + Permit OTHER_BSS_SYMBOLS to be defined. + * emulparams/elf32mipb.s (OTHER_BSS_SYMBOLS): Define _fbss. + +Mon Feb 7 16:31:15 1994 Jeffrey A. Law (law@snake.cs.utah.edu) + + * Rename all "hppaosf" files to "hppaelf". + * Change all "osf" references to "elf" in hppaelf files. + * Makefile.in: Likewise. + * configure.in: Likewise. + +Sun Feb 6 20:31:56 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldmain.c (main): Call xatexit, not atexit. + Call xmalloc_set_program_name. + + * ldlang.c (lang_size_sections): Check if bfd_relax_section set + bfd_errno. + +Sat Feb 5 03:54:34 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * emultempl/lnk960.em (append), emultempl/hppaosf.em + (hppaosf_finish): Call xmalloc, not ldmalloc. + * ldmain.c (preserve_output): Function removed. + (main): Do it here instead. + +Fri Feb 4 23:02:19 1994 Jeffrey A. Law (law@snake.cs.utah.edu) + + * ldlang.h (LANG_FOR_EACH_{INPUT,OUTPUT}_SECTION): Delete (unused) + GNU C specific macros. + + * emultempl/hppaosf.em (hppaosf_finish): Expand the only remaining + call to LANG_FOR_EACH_INPUT_SECTION. + +Fri Feb 4 16:26:08 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldmisc.c (ldmalloc, xmalloc, ldrealloc, xrealloc): Functions + deleted; will use libiberty versions instead. + * ldctor.c ldfile.c ldlang.c ldmain.c ldmisc.c ldmisc.h lexsup.c + mri.c Makefile.in: Change callers. + + * ldmisc.c (vfinfo): Remove cleanup code. + * ldmain.c (remove_output): Put it here (new function). + (preserve_output): New function. + (main): Register remove_output and preserve_output with atexit. + * ldmain.c ldgram.y: Call xexit instead of exit. + * ldmisc.h: Declare xexit. + +Fri Feb 4 15:19:01 1994 Steve Chamberlain (sac@cygnus.com) + + * Makefile.in: Lots of new H8/500 memory models. + +Sun Jan 30 14:33:40 1994 Ken Raeburn (raeburn@cujo.cygnus.com) + + * ldlex.l: Removed duplicate rules. + (yywrap): Provide default definition, needed with some versions of + flex. + +Fri Jan 28 09:12:56 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldmisc.c (vfinfo): For `%I', if the file is in an archive, print + the archive filename too. + + * ldlex.l: Add rule to catch invalid input characters instead of + printing them. Include "ldmain.h" for program_name decl. + (lex_warn_invalid): New function. + * Makefile.in: Add dependency. + +Fri Jan 28 12:58:45 1994 Ken Raeburn (raeburn@cujo.cygnus.com) + + * Makefile.in (check): Don't bother running any tests of + cross-linker until the test suite no longer assumes native mode. + +Thu Jan 27 17:19:54 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * ldlang.c (print_one_symbol, print_input_section): Print + global symbols in symbol table again. + +Thu Jan 27 12:35:01 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldmain.c ldmain.h ldgram.y: If -v -V or --version was given, + exit successfully instead of complaining if no input files are + given. + +Tue Jan 25 13:19:41 1994 Stan Shebs (shebs@andros.cygnus.com) + + * Makefile.in: Format variable definitions consistently. + (LD_PROG): Remove unnecessary variables from link command, + change variable LOADLIBES to EXTRALIBS. + + * ldmain.c (main): Compute and display total execution time. + * ld.texinfo (-stats): Document the option. + +Mon Jan 24 12:56:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldmain.c (reloc_overflow): Added name, reloc_name and addend + arguments. + + * ldlang.c (lookup_name): Set BFD GP size to -G argument value + after opening BFD. + + * ldlang.c (relaxing): Removed global variable. + (lang_size_sections): If the canonical symbols have not already + been read in, read them in before relaxing. + * ldlang.h (relaxing): Removed declaration. + +Fri Jan 21 00:44:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (new_afile): Initialize loaded field to false. + (lookup_name): If file was already loaded, don't call the + add_symbols entry point again. + +Wed Jan 19 13:57:00 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * ld.texinfo: Clarify what -T option does. + +Tue Jan 18 16:18:15 1994 Steve Chamberlain (sac@jonny.cygnus.com) + + * scripttempl/m88kbcs.sc: Don't use CREATE_OBJECT_SYMBOLS, that's + for a.out. + +Tue Jan 11 13:22:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldmain.c (add_archive_element): If trace_files or + trace_file_tries, print file name. + * ldlang.c (lookup_name): Likewise. + (ldlang_add_file): Don't put files on input_bfds list in reverse + order. + + * scripttempl/elf.sc: Correct typo. + +Mon Jan 10 19:49:05 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldgram.y, ldlex.l: Make the space between -e, -u, and -y and + their arguments optional, for compatibility with the old GNU ld. + +Fri Jan 7 20:00:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * scripttempl/elf.c: Define __bss_start before the .sbss section. + +Thu Jan 6 00:13:10 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldmain.c (add_to_set): Add bitsize argument. + (constructor_callback): New function. + (link_callbacks): Add constructor_callback. + * ldctor.c (struct set_info): Add bitsize field. + (ldctor_add_set_entry): Add bitsize argument. + (ldctor_build_sets): Base the size of the elements of the set on + the bitsize, rather than always using LONG. + * ldctor.h (ldctor_add_set_entry): Add bitsize to declaration. + + * ld.h (QUAD_SIZE): Define. + * ldgram.y (QUAD): New token. + (length): Handle it. + * ldlex.l: Return QUAD. + * lexsup.c (keywords): Add QUAD. + * ldwrite.c (build_link_order): Handle QUAD. + * ldlang.c (print_data_statement): Handle QUAD. + (lang_size_sections): Likewise. + (lang_do_assignments): Likewise. + * ldexp.c (exp_print_token): Add QUAD to table. + * ld.texinfo: Describe QUAD. + + * scripttempl/alpha.sc: Don't create .lit4 or .sdata sections, + since the Alpha doesn't use them. + +Wed Jan 5 17:42:16 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldemul.h (ld_emulation_xfer_struct): Comment the members. + +Sat Jan 1 13:39:31 1994 Rob Savoye (rob@darkstar.cygnus.com) + + * Makefile.in, configure.in: Add support for VSTa micro-kernel. + * config/vsta.mt, emulparams/vsta.sh: New files for VSTa. + +Sat Jan 1 10:53:35 1994 David J. Mackenzie (djm@thepub.cygnus.com) + + * scripttempl/aout.sc: Pad .text to DATA_ALIGNMENT if relocating; + needed for i386mach. (Should be a no-op on other systems.) + + * emulparams/i386mach.sh (SEGMENT_SIZE): Fix again. + (PAGE_SIZE): Don't define; not used. + +Fri Dec 31 16:12:06 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldgram.y (yyerror): Make argument const char *, and actually + print it out rather than assuming it is a syntax error. + * ldmisc.h: Change declaration of yyerror. + * ldemul.c, ldwrite.c: Add /*ARGSUSED*/ as appropriate. + +Fri Dec 31 11:37:28 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * emulparams/i386mach.sh (NONPAGED_TEXT_START_ADDR): Don't include + exec header offset, since the exec header isn't loaded. + (PAGE_SIZE, SEGMENT_SIZE): Agree with bfd/i386mach3.c. + +Thu Dec 30 13:01:43 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + A major rewrite to move the bulk of the linker into BFD so that + more efficient backend code can be written for specific object + files. + * lderror.c, lderror.h, ldindr.c, ldindr.h, ldsym.c, ldsym.h, + ldwarn.c, ldwarn.h, relax.c, relax.h: Removed. + * ldctor.c, ldctor.h: Complete rewrite. + * ldwrite.c, ldwrite.h: Complete rewrite. + * ld.h (strip_symbols_type, strip_symbols): Removed. Use + link_info.strip instead. Changed all uses. + (discard_locals_type, discard_locals): Removed. Use + link_info.discard instead. Changed all uses. + (ld_config_type): Removed relocateable_output field; use + link_info.relocateable instead; changed all uses. Added stats + field. + (set_asymbol_chain, get_asymbol_chain, get_loader_symbol, + set_loader_symbol): Removed. + * ldexp.h (node_class): Added etree_rel. + (etree_type): Added rel field. + * ldexp.c (exp_print_token): Bracketed table initialization. + (exp_relop): New function. + (fold_name): Use linker hash table rather than ldsym functions. + (exp_fold_tree): Likewise. Also, handle etree_rel case. + (exp_print_tree): Handle etree_rel. + * ldgram.y (strip_symbols, discard_locals): Removed. + (OPTION_stats, OPTION_no_keep_memory): New tokens. Handle them. + (REL): New token. Does not appear in grammar, but needed for + expression code. + (file): Don't call lang_final; it's called by main anyhow. + * ldlex.l: Accept -stats and -no-keep-memory options. + * ldlang.h (fill_type): Make unsigned int, not unsigned short. + * ldlang.c: Consistently use fill_type for fill argument. + (lang_init_script_file, script_file): Removed. + (create_object_symbols): Removed. Use + link_info.create_object_symbols_section instead. Changed all + uses. + (lang_add_keepsyms_file): Removed. + (lookup_name): Call bfd_link_add_symbols instead of + ldmain_open_file_read_symbol. + (wild): Don't iterate over script_file. + (open_output): Create link hash table. + (lang_place_undefineds): Rewrote. + (lang_size_sections): Handle relaxing (doesn't work yet). + (lang_relocate_globals): Removed. + (lang_finish): Use link hash table rather than ldsym functions. + (lang_common): Rewrote. + (lang_one_common): New function. + (ldlang_add_file): Add file to link_info.input_bfds list. Set + usrdata. + (create_symbol): Removed. + (lang_process): Don't call lang_init_script_file. Call + ldctor_build_sets rather than find_constructors. Don't call + lang_relocate_globals. + (lang_abs_symbol_at_beginning_of): Rewrote. + (lang_abs_symbol_at_end_of): Rewrote. + * ldmain.c (had_y): Removed. + (lprefix, lprefix_len): Removed; use link_info fields instead. + Changed all uses. + (multiple_def_count, commons_pending, undefined_global_sym_count, + total_symbols_seen, total_files_seen): Removed. + (link_callbacks, link_info): New variables. + (main): Initialize link_info. Don't call init_bfd_error_vector or + ldsym_init. Don't set now unused variables. Handle -stats. + (get_emulation): Removed obsolete and nonfunctional GNU960 code. + (add_ysym): Rewrote. + (read_entry_symbols, refize, enter_global_ref, enter_file_symbols, + search_library, gnu960_check_format, decode_library_subfile, + linear_library, symdef_library, clear_syms, subfile_wanted_p): + Removed. + (add_keepsyms_file, add_archive_element, multiple_definition, + multiple_common, add_to_set, warning_callback, undefined_symbol, + reloc_overflow, reloc_dangerous, unattached_reloc, notice_ysym): + New functions. + * ldmisc.c (vfinfo): Accept a string for %T, not a symbol. Don't + require symbols for %C; look them up instead. + * emultempl/hppaosf.em: Pass link_info to + hppa_look_for_stubs_in_section. + * Makefile.in: Rebuilt dependencies. + (CFILES): Removed lderror.c, ldindr.c, ldsym.c, ldwarn.c, and + relax.c. + (HFILES): Removed lderror.h, ldindr.h, ldsym.h, ldwarn.h, and + relax.h. + (EMULATION_OFILES): Depend on bfdlink.h, ldmain.h, ldexp.h, + ldlang.h and ldctor.h. + + * Makefile.in (ldlex.c): Don't depend on ldgram.h. Remove + declarations of free and malloc from flex output. Change malloc + to ldmalloc in flex output. + +Thu Dec 16 21:19:57 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * ldmain.c (lprefix): Change default from a char to a string + with only one character. + (lprefix_len): Set default to one. + + * ldmain.h (lprefix_len): Declare. + + * ldsym.c (write_file_locals): Use strncmp rather than a character + comparison for lprefix. + + * emultmpl/m88kbcs.em (before_parse): Set lprefix and lprefix_len + correctly. + + * emultmpl/hppaosf.em: Include ldexp.h. + (before_parse): Set lprefix and lprefix_len correctly. + +Tue Dec 14 17:19:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlex.h: Don't declare yywrap if it is a macro. + * ldlex.l: Include sysdep.h. + * ldlang.c (lang_for_each_statement_worker, + lang_for_each_statement): Forgot to use PARAMS. + +Mon Dec 13 14:30:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * Makefile.in: Added .PHONY targets where appropriate. Added some + comments. Also: + (gcclibdir, version): Removed unused variables. + (DEP): New variable, set to mkdep. + (ALL_CFLAGS): New variable. Used in .c.o target. + (CFILES, HFILES, GENERATED_CFILES, GENERATED_HFILES): New + variables. + (HEADERS, MANSOURCES, LDCSOURCES, GENERATED_SOURCES, + GENERATED_HEADERS, LDSOURCES, BFD_SOURCES, SOURCES): Removed + mostly obsolete variables. Adjusted remaining uses. + (DEF_EMUL): Removed variable. + (ldmain.o): Handle undefined EMUL error correctly. + (ldemul-list.h): Depend on config.status rather than Makefile. + Create via temporary file. + (ver960.c, roll, make): Removed obsolete targets. + (.dep, .dep1, dep.sed, dep, dep-in): New targets. Used to rebuild + dependencies. + * dep-in.sed: New file, used when rebuilding dependencies. + +Sat Dec 11 14:43:44 1993 Ian Lance Taylor (ian@deneb.cygnus.com) + + Made many changes to eliminate gcc warnings. Made various + cosmetic changes, declared various things in header files, removed + various extern declarations from .c files. No substantive + changes. + + * ldlang.c (lang_process): Ifdef out final call to + lang_size_sections again (reverting change of Nove 2), since it + breaks the Sun4 linker. + +Thu Dec 2 16:31:47 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * configure.in (alpha-*-netware*): New target; use alpha. + +Wed Dec 1 14:04:20 1993 Ken Raeburn (raeburn@cygnus.com) + + * configure.in: Group targets by CPU. Merge some m68k target + entries with different CPU specs that use the same ld_target + values. + + * configure.in: Add sparc*-*-coff. + * config/coff-sparc.mt, emulparams/coff_sparc.sh: New files. + * Makefile.in (ALL_EMULATIONS): Add em_coff_sparc.o. + (em_coff_sparc.c): Add dependencies and build rules. + + * ldmisc.c (errno, sys_nerr, sys_errlist): Don't declare. + +Wed Dec 1 12:19:55 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldgram.y (OPTION_call_shared, OPTION_non_shared, OPTION_Oval): + New tokens. + (command_line_option): Accept and ignore them (for now). + * ldlex.l (<COMMAND>): Handle -non_shared, -call_shared, and -On + where n is a number. + +Mon Nov 22 14:14:29 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldmain.c (subfile_wanted_p): If merging a common symbol which is + not in bfd_com_section, create the section in the BFD so that it + can be placed in the right output section. + +Fri Nov 19 14:12:39 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * configure.in (mips*-sgi-irix5*): New target. Use mipsb-elf32. + * emulparams/elf32mipsb.sh (DATA_ADDR): Define. + (OTHER_READONLY_SECTIONS): Define for .reginfo. + (EXECUTABLE_SYMBOLS): Define for _DYNAMIC_LINK. + * scripttempl/elf.sc: Use EXECUTABLE_SYMBOLS when not relocating. + Move OTHER_READONLY_SECTIONS after all the other readonly + sections. Don't use DATA_ADDR twice. + + * ldmain.c (enter_file_symbols): Removed duplicate tests of p. If + p is in a common section, make sure the BFD has a section of that + name. + + * ldlang.c (lang_common): Add newline to error message. + +Thu Nov 11 15:54:41 1993 Stan Shebs (shebs@rtl.cygnus.com) + + * emulparams/m68klynx.sh (SCRIPT_NAME): Define to use a + Lynx-specific script instead of m68kcoff. + (OUTPUT_FORMAT): Define as "coff-m68k-lynx". + (ENTRY): Define as __main. + (TEXT_START_ADDR): Define as 0. + (PAGE_SIZE): Define as 0x1000. + * emulparams/i386lynx.sh, emulparams/sparclynx.sh: Fix comment. + * scripttempl/m68klynx.sc: New file. + +Mon Nov 8 12:00:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldmain.c (get_emulation): Ignore -mips1, -mips2 and -mips3 + arguments rather than treating them as emulation names. + +Fri Nov 5 09:02:52 1993 D. V. Henkel-Wallace (gumby@blues.cygnus.com) + + * configure.in: Support x86 unixware and netware plus generic netware. + +Fri Nov 5 21:47:55 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * emulparams/i386mach.sh (TEXT_START_ADDR, NONPAGED_TEXT_START_ADDR): + Correct values (?). + +Wed Nov 3 15:10:15 1993 Ken Raeburn (raeburn@rover.cygnus.com) + + * Makefile.in (distclean): Don't delete dvi or info files. + (ld.info): Update dependency list. + (ld.dvi): Ditto. Extend TEXINPUTS to get bfdsumm.texi. + +Wed Nov 3 12:07:39 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldlang.c (lang_add_output): Take new arg, FROM_SCRIPT. + Set output_filename instead of creating a new node. + (open_output): Don't set output_filename. + (lang_final): Create the new node here. + * ldlang.c, ldlang.h, ldgram.y, mri.c: pass FROM_SCRIPT. + +Tue Nov 2 15:45:51 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + From Pete Hoogenboom (hoogen@cs.utah.edu): + + * scripttempl/hppaosf.sc: (___stack_zero, etext, _etext, + edata, _edata, end): Add definitions of these symbols. + (__end): Remove definition of this symbol. + (__data_start): Move definition of this symbol. + + * emultempl/hppaosf.em: Various fixes and support for linker stub + generation. + (hppaosf_finish, hppaosf_search_for_padding_statements, + hppaosf_create_output_section_statements): New functions in + support of linker stub generation. + (ld_hppaosf_emulation): Redefine to include new + emulation-specific routines. + + * ldlang.c (lang_process): Re-enable last call lang_size_sections. + Pass abs_output_section rather than NULL to avoid invalidating + absolute symbols. + +Thu Oct 28 21:16:42 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * Makefile.in (ALL_EMULATIONS): Add em_i386mach.o. + (em_i386mach.c): New rule. + * configure.in (i[34]86-*-mach*): New case. + * config/i386-mach.mt: New file. + * emulparams/i386mach.sh: New file. + +Fri Oct 29 14:55:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ld.h (flag_is_*): Removed macros. + * ldmain.c (enter_global_ref), ldsym.c (write_file_locals): + Consistently check the BFD symbol flags directly, rather than + using file_is_* macros. + +Thu Oct 28 19:08:42 1993 Stan Shebs (shebs@rtl.cygnus.com) + + * configure.in (sparc*-*-lynxos*): New target. + * Makefile.in: Add rule for em_sparclynx.c. + (ALL_EMULATIONS): Add Lynx emulations. + * config/sparc-lynx.mt: New file. + * emulparams/sparclynx.sh: New file. + * scripttempl/sparccoff.sc: New file. + +Thu Oct 28 13:50:25 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * Makefile.in: Add dependency for $(EMULATION_OFILES). + +Mon Oct 25 16:09:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * relax.c (write_relax): Check return value of bfd_seclet_link. + +Mon Oct 25 09:31:21 1993 Ken Raeburn (raeburn@cygnus.com) + + * ldlang.c (delete_output_file_on_failure): New variable. + (open_output): Set it after bfd open succeeds. + * ldmisc.c (vfinfo): Test it. + + Changes from Peter Hoogenboom, hoogen@cs.utah.edu: + + * ldsym.c (write_file_locals): Set the BSF_FILE flag for object + symbols. + + * ldemul.c: Support was added to allow emulation-specific + processing to occur. This support was added primarily for linker + stub generation in the elf32-hppa gld. + (ldemul_finish, ldemul_create_output_section_statements): New + functions. + * ldemul.h: Support was added to allow emulation-specific + processing to occur. (As described above.) Added finish and + create_output_section_statements fields to + ld_emulation_xfer_struct structure. + * ldlang.c: Add calls to emulation-specific routines. + (lang_process): Add call to + ldemul_create_output_section_statements function. + (lang_process): Add call to a emulation-specific routine (and + some processing after the call). + +Fri Oct 22 20:54:13 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) + + * configure.in: mips*- instead of mips-, mips*el changes + +Tue Oct 19 15:46:28 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * configure.in (alpha-*-osf*): New target; use alpha.mt. + * Makefile.in (ALL_EMULATIONS): Added em_alpha.o. + (em_alpha.c): New target; use alpha.sh and alpha.sc. + * config/alphaosf.mh (NATIVE_LIB_DIRS, HOSTING_CRT0): Define. + * config/alpha.mt: New file. + * emulparams/alpha.sh: New file. + * scripttempl/alpha.sc: New file. + +Fri Oct 15 02:20:04 1993 Doug Evans (dje@canuck.cygnus.com) + + * ldlang.c (lang_size_sections, lang_common): ALIGN_N can't handle + types of different sizes (eg: 64 and 32 bits), so coerce. + * ld.h (ALIGN_N): Add warning about usage. + +Wed Oct 13 16:02:39 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldmain.c (enter_global_ref): Just ignore any weak symbol for + which we already have a definition, rather than checking in + several different places whether the symbol is weak. + +Tue Oct 12 17:30:51 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * configure.in (mips-*-elf*): New target; use mipsb-elf32. + * scripttempl/elf.sc: Only use OTHER_READONLY_SECTIONS and + OTHER_READWRITE_SECTIONS if relocating. Shell variables are not + expanded within them. + * config/mipsb-elf32.mt: New file. + * emulparams/elf32mipb.sh: New file. + * Makefile.in (em_elf32mipb.c): New target. + +Thu Sep 30 17:00:36 1993 Rob Savoye (rob@darkstar.cygnus.com) + + * ldgram.y: In input_list, change lang_input_file_is_file_enum to + lang_input_file_is_search_file_enum so objects brought in using + INPUT() do a path lookup. + +Tue Sep 28 13:31:23 1993 Stan Shebs (shebs@rtl.cygnus.com) + + * configure.in: Change Lynx ld_target to be {i386,m68k}-lynx + instead of {i386,m68k}-coff. + * Makefile.in (em_i386lynx.c, em_m68klynx.c): New targets. + * config/i386-lynx.mt: New file. + * config/m68k-lynx.mt: New file. + * emulparams/i386lynx.sh: New file. + * emulparams/m68klynx.sh: New file. + + * scripttempl/i386coff.sc: Make ENTRY get its value from ${ENTRY}, + but defaulting to _start. + + * ldemul.c, ldfile.c, ldlang.c, ldmain.c, ldmisc.c, ldmisc.h, + ldsym.c, ldwarn.c: Rename info to info_msg, to avoid conflict with + LynxOS libc. + +Thu Sep 23 14:51:03 1993 Ian Lance Taylor (ian@cygnus.com) + + * config/solaris2.mh: New file. Define HOSTING_CRT0 and + HOSTING_LIBS for testing. + +Fri Sep 17 17:52:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + Finish up support for i386-sysv4 (without shared libraries): + * ld.h (flag_is_weak): Define. + * ldlang.c (print_symbol): Mention whether symbol is weak. + (print_input_section): Print weak symbols as globals. + * ldmain.c (refize): Do not zero out BSF_WEAK flag. + (enter_global_ref): Do not warn if a weak symbol redefines a + global symbol. Do not let a weak symbol redefine a common symbol. + (enter_file_symbols): Treat weak symbols as global symbols. + (subfile_wanted_p): Do not pull in an object file from a archive + just to resolve an undefined weak symbol. + * ldmisc.c (vfinfo): Don't needlessly malloc space after a fatal + error; the error might be that malloc has run out of space. + * ldsym.c (write_file_locals): Treat weak symbols as global. + * configure.in (i[34]86-*-sysv4*, i[34]86-*-elf*): New targets; + use i386-elf. + * config/i386v4.mh: New file; set NATIVE_LIB_DIRS to /usr/ccs/lib. + * config/i386-elf.mt: New file; set EMUL to elf_i386. + * emulparams/elf_i386.sh: New file. + * scripttempl/elf.sc: Use ${NOP} as filler (defaults to 0). + * Makefile.in (NATIVE_LIB_DIRS): Define to be empty. + (ALL_EMULATIONS): Add em_elf_i386.o. + (GENSCRIPTS): Pass NATIVE_LIB_DIRS as sixth argument. + (em_elf_i386.c): New target, like other em_*.c targets. + ($(LD_PROG)): Pass $(CFLAGS) to $(CC). + * genscripts.sh: Accept NATIVE_LIB_DIRS as sixth argument. If + nonempty, and configured for native, add it to LIB_PATH. + +Fri Sep 17 13:07:39 1993 Stan Shebs (shebs@rtl.cygnus.com) + + * scripttempl/{h8300.sc,h8500.sc,i386coff.sc,m68kcoff.sc,sh.sc}: + Added statements to pass stab and stabstr sections through and + mark them as NOLOAD, which makes GDB happier. + +Wed Sep 15 16:02:29 1993 Stan Shebs (shebs@rtl.cygnus.com) + + * configure.in: Accept m68k-lynx-lynxos config. + + * Makefile.in: Use $(SHELL) to run genscripts.sh. + +Sun Sep 12 16:04:40 1993 Doug Evans (dje@cygnus.com) + + * config/coff-h8300.mt: Add EMUL=h8300h. + + * ldmain.c (main): Call set_scripts_dir after argv has been processed. + +Fri Sep 10 09:36:29 1993 Jeffrey Wheat (cassidy@cygnus.com) + + * Makefile.in: Changed CXX back to g++. + +Fri Sep 10 09:34:29 1993 Jeffrey Wheat (cassidy@cygnus.com) + + * Makefile.in: Fixed RUNTEST* CXX CXXFLAGS macros and check rule. + +Fri Sep 10 07:26:57 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * Makefile.in (TAGS): Use shell wildcards. + +Tue Sep 7 18:04:54 1993 Jeffrey Osier (jeffrey@cygnus.com) + + * Makefile.in: add TEXINPUTS variable and use it in ld.dvi target + +Fri Sep 3 16:46:41 1993 Roland H. Pesch (pesch@fowanton.cygnus.com) + + * ld.texinfo: re-enable included config file; conditionalize doc + for -oformat to interact properly with SingleFormat doc config + var; rename @up/@down to @raisesections/@lowersections. + +Wed Aug 25 16:29:56 1993 K. Richard Pixley (rich@sendai.cygnus.com) + + * configure.in: recognize m88110. + +Tue Aug 24 18:49:40 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + From Peter Hoogenboom <hoogen@shafer.cs.utah.edu>: + * emultempl/hppaosf.em (ld_hppaosf_emulation): Correct name for PA + ELF emulation is "elf32-hppa" not "elf-big". + (hppaosf_before_parse): Remove unneeded processing of environment + variables. + * scripttempl/hppaosf.sc: Include .hppa_linker_stubs sections in + .text segment of output file. + * emulparams/hppaosf.sh (OUTPUT_FORMAT): Use elf32-hppa. + +Tue Aug 24 16:17:00 1993 K. Richard Pixley (rich@sendai.cygnus.com) + + * ld.h: define BYTE_SIZE, SHORT_SIZE, and LONG_SIZE which are no + longer in bfd.h. + + * ldlang.c, ld.h: updated copyright. + +Tue Aug 17 15:22:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldlang.c (open_output, lang_check): Check return value of + bfd_set_arch_mach. + +Tue Aug 17 07:02:19 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) + + * scripttempl/h8500.sc: Start all sections in a different segment. + * scripttempl/z8ksim.sc: Handle constructors + +Thu Aug 12 16:05:37 1993 Jeffrey Wheat (cassidy@cygnus.com) + + * Makefile.in: revert earlier changes back to execute runtest + with make check. cdtest and bootstrap now function as they + did within the Makefile. + +Thu Aug 12 10:20:05 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * Makefile.in: Update dependencies. + + * configure.in: Set EMULATION_OFILES in Makefile based on + --with-targets option. + +Thu Aug 12 08:52:29 1993 Jeffrey Wheat (cassidy@cygnus.com) + + * Makefile.in: check targets reimplemented to old way. + +Wed Aug 11 08:26:11 1993 Ian Lance Taylor (ian@cygnus.com) + + * config/i386v.mh, config/irix4.mh: Use gcc + -print-libgcc-file-name rather than $(libdir)/libgcc.a. + * config/i386sco.mh: New file; copy of i386v.mh to correspond to + bfd/configure.host change. + +Mon Aug 9 14:25:35 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * scripttempl/elf.sc: Handle .line and .debug* sections. + + * ldlex.l: Use bfd_scan_vma, not strtoul. + +Fri Aug 6 08:57:39 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldexp.c, ldfile.c, ldlang.c, lexsup.c, ldmain.c, ldemul.c: + Remove inital caps in some error messages, change "can't" to + "cannot", add missing colons. + * ldmisc.c (vfinfo): Print "%%" as a single %. + For '%' followed by unrecognized character, print them both + verbatim instead of expecting a char * arg. + For '%C', don't put the function name in parens. + + * ldexp.c (invalid): Pass "%%", not "% ". + +Fri Aug 6 14:31:22 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * scripttempl/mips.sc: Always define _ftext, _fdata, _fbss. + (BSS_VAR): Removed; now always define _fbss. + * emulparams/mipsidt.sh, emulparams/mipsidtl.sh (BSS_VAR): + Removed. + +Thu Aug 5 15:55:19 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) + + * configure.in: z8k-coff is the same as z8k-sim + +Wed Aug 4 21:00:18 1993 Jeffrey Wheat (cassidy@cygnus.com) + + * testsuite/lib/ld.exp: new file + * testsuite/config/unix-ld.exp: new file + * testsuite/ld.bootstrap/bootstrap.exp: new file + * Makefile.in: add dejagnu support for make check + +Wed Aug 4 17:52:32 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldlex.l (comment): Add missing newline in message. + * ldindr.c (add_indirect): Ditto. + * ldexp.c (exp_fold_tree): Ditto. + +Tue Aug 3 10:57:41 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldgram.y, ldlex.l, mri.c, ldwrite.c: Change multiple commons + into externs. + + * ldmisc.c (multiple_warn): New function. + * ldmisc.h: Declare it. + * ldmain.c (enter_global_ref): Call it. + * ld.h (ld_config_type): Add warn_common. + * ldlex.l, ldgram.y: Set it with -warn-common option. + * ldver.c (help): Document it. + +Mon Aug 2 12:04:36 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * scripttempl/elf.sc: Add hooks for .sdata, .sbss, and + target-specific sections, and for changing data section vma. + +Mon Jul 26 14:00:02 1993 Ken Raeburn (raeburn@deneb.cygnus.com) + + * ldgram.y (OPTION_Qy, OPTION_Y, OPTION_dn, OPTION_YP): New + terminals, for Solaris. + (dirlist_ptr): New static variable. + (command_line_option): Accept new options. + + * ldlex.l: Accept command-line options "-Qy", "-dn", "-Y", and + "-YP,...". + + * config/sun4sol2.mt: Pass emulation name without ".sh". + + * emulparams/elf32_sparc.c: Renamed from elf32-sparc.c. + * config/sun4sol2.mt (em_elf32_sparc.c): Adjusted accordingly. + +Fri Jul 23 13:51:09 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * scripttempl/elf.sc: Add support for .init, .fini, .ctors, + .dtors, .data1, .rodata1 sections, instead of combining them into + other sections. For `-r', set all section start addresses to + zero. + + * emulparams/elf32-sparc.sh (TEXT_START_ADDR, + NONPAGED_TEXT_START_ADDR): Value should be 0x10100. + (MAXPAGESIZE): Renamed from PAGE_SIZE. + +Wed Jul 21 14:28:42 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * genscripts.sh: If this is the default emulation, set + COMPILE_IN. + * emultempl/*.em: Use it to determine whether to compile in the + scripts. + + * Makefile.in (GENSCRIPTS): Pass the default emulation name to + genscripts.sh. Pass the current emulation name without ".sh" on + the end. + * genscripts.sh: Take an default emulation arg. + Use the current emulation name as EMULATION_NAME. + Make default lib path for cross-compiling ':', not null. + * emulparams/*.sh: Don't set EMULATION_NAME. + * ldemul.c (ldemul_get_script): Take isfile arg. + Pass it to emulation's get_script function. + * ldemul.h: Adjust get_script prototypes. + * ldfile.c (ldfile_find_command_file): Renamed from find_a_name. + No longer static. + * ldfile.h: Declare it. + * ldgram.y: Accept a script on the command line again, + for parsing compiled-in scripts. + * ldmain.c (main): If ld script is a file, parse it as a -T + option, otherwise parse it directly. + * emultempl/*.em (*get_script): Return the scripts themselves if + this is the default emulation; otherwise return their file names. + * emultempl/m88kbcs.em: New file, to take m88kbcs #ifdef out of + generic.em. + * emulparams/m88kbcs.sh: Use it. + + * ld.h (ld_config_type::unix_relocate): Remove unused element. + +Tue Jul 20 12:01:49 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * Makefile.in (ALL_EMULATIONS): Delete em_i386linux.o (for which + there's no change log entry yet, tsk tsk) from the list of + emulations compiled in until Mark gets around to checking in + emulparams/i386linux.sh. + (ldemul-list.h): Depend on Makefile, so if EMULATION_OFILES is + changed, this file gets updated. + +Fri Jul 16 14:14:32 1993 Ian Lance Taylor (ian@cygnus.com) + + * ldgram.y (OPTION_Lfile): New token. + (command_line_option): Accept OPTION_L NAME (whitespace after -L). + * ldlex.l (<COMMAND>): Accept -L without FILENAME. + +Fri Jul 16 13:44:26 1993 Doug Evans (dje@canuck.cygnus.com) + + * configure.in: h8/300h support needs own .mt file. + config/coff-h8300h.mt: New file. + +Thu Jul 15 12:44:35 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldmain.c: Don't include sys/stat.h; it already got included + somewhere along the way. + +Thu Jul 15 14:43:34 1993 Doug Evans (dje@canuck.cygnus.com) + + * Makefile.in: Add h8300h support. + emulparams/h8300h.sh: New file. + scripttempl/h8300h.sc: New file. + +Thu Jul 15 12:44:35 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldfile.c (ldfile_open_file): In error message, use the name the + user gave (e.g., "-lc"), rather than the base file name. + + * ldexp.c (exp_fold_tree): Don't assign an int to an enum. + + * ldmain.[ch]: Remove initial Q_ from function names. + * ldexp.c, ldindr.c, ldlang.c: Change callers. + + * ldfile.c, ldmain.c, ldgram.y: Rename option_v to trace_file_tries. + + * ldlang.c (lang_process): Move loading of default script from + here to main. Add a "/" to start of script name to prevent + finding it in "." first. + + * ldmain.c (set_scripts_dir): Don't look in "." first. + + * ldgram.y, ldlang.c, ldsym.c: Remove traces of unused var + option_longmap. + +Thu Jul 15 10:55:59 1993 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in (em_m88kbcs.c): Correct dependency. + * scripttempl/m88kbcs.sc: It's ARCH, not arch. Removed TARGET + statement. Changed OUTPUT_FORMAT to use ${OUTPUT_FORMAT}. + * emulparams/m88kbcs.sh: It's coff-m88kbcs, not m88kbcs. + +Wed Jul 14 21:42:53 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldfile.c (ldlang_open_file, ldfile_open_command_file), + main.c (main): Print the errno string in the error message. + +Tue Jul 13 20:00:30 1993 Doug Evans (dje@canuck.cygnus.com) + + * configure.in: Accept h8300h for target cpu. + + * ldmisc.c (vfinfo): Have demangle remove leading underscore if + present (demangle is smart enough to know whether to do it or not). + +Mon Jul 12 11:45:48 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldmain.c (set_scripts_dir): Check . and <ld bin dir>/../lib for + ldscripts, as well as <ld bin dir> and SCRIPTDIR. + + * ldlang.c (lang_process): Use sizeof instead of magic constant. + + * ldmain.c (get_emulation, check_for_scripts_dir, + set_scripts_dir): New functions. + (main): Call them. + +Mon Jul 12 10:57:03 1993 Ken Raeburn (raeburn@deneb.cygnus.com) + + * scripttempl/elf.sc: Include .init, .fini, .rodata sections. + Create symbol "end" instead of "__end". Comment out some parts + that may not be needed (yet) for elf. + + * configure.in: Accept sparc-elf and sparc-solaris2 configs. + +Thu Jul 8 15:33:32 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * Makefile.in (ALL_EMULATIONS): Include $(OTHER_EMULATIONS). + + * ldmisc.h (einfo, minfo, info): Don't bother with PARAMS macro + when no prototype is being supplied. + (ldmalloc, ldrealloc): Size argument is now size_t. + + * ldmisc.c (finfo): New function, accepts FILE* argument. + (vfinfo, case 'v'): New format character; displays bfd_vma in hex + without leading zeros. + (vfinfo, cases 'R' and 'C'): Use finfo(%v) when displaying a + bfd_vma value, instead of fprintf(%x) which won't hold a long long + value. + (concat, buystring): String lengths are size_t. + (ldmalloc, ldrealloc, xrealloc): Size argument is now size_t. + + * ldlang.c (new_statement): Size argument is now size_t. Added + forward declaration with prototype. + +Thu Jul 8 10:53:47 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldgram.y (OPTION_v): Don't turn on verbose output. + +Wed Jul 7 17:10:45 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * ldlex.l: Get rid of local typedef for bfd_vma! Get it from + bfd.h instead. + +Wed Jul 7 11:33:12 1993 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in (install): Don't install as $(tooldir)/bin/gld; + collect2 doesn't look for gld any more anyhow. + +Mon Jul 5 14:29:48 1993 Ian Lance Taylor (ian@cygnus.com) + + * ldlang.c (lang_relocate_globals): Skip indirect symbols, which + now have a non NULL srefs_chain. + + * config/hp300hpux.mt: Use emulation hp3hpux rather than + hp300hpux, since the latter does not exist. + +Fri Jul 2 18:06:05 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * genscripts.sh: Put the scripts in the ldscripts directory, not + emulations. + * configure.in (ldscripts): Make, instead of emulations. + * Makefile.in (scriptdir): Take off the "ld" part. + (install, clean, distclean): Use ldscripts, not emulations. + In tests, don't pass -Lemulations. + Don't pass tooldir/lib to genscripts.sh. + * genscripts.sh: Don't take tooldir/lib arg. + * ldlang.c (lang_process): Add "ldscripts/" to the name of the + default script file. + +Fri Jul 2 17:13:35 1993 Doug Evans (dje@canuck.cygnus.com) + + * scripttempl/h8300.sc: Add .tors section for constructor/destructors. + +Thu Jul 1 16:38:45 1993 Doug Evans (dje@canuck.cygnus.com) + + * config/coff-h8300.mt: EMUL=h8300hms -> h8300. + +Wed Jun 30 15:45:55 1993 K. Richard Pixley (rich@sendai.cygnus.com) + + * Makefile.in (.y.c): skip default .y.c rules. gnu make can now + run in parallel without colliding on yacc's static file names. + Without the stub rule, make will try to start two yacc's + concurrently which fails because of yacc's static file names. + +Tue Jun 29 12:20:36 1993 Ian Lance Taylor (ian@cygnus.com) + + * ldmain.c (subfile_wanted_p): Don't dump core if there are no + symbols. + +Mon Jun 28 12:22:11 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * genscripts.sh (LIB_PATH): Only add /usr/local/lib if it's + different from libdir. + + * Makefile.in (scriptdir): Base on tooldir, not datadir. + +Sat Jun 26 12:03:57 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldver.c (help): New function. + * ldver.h: Declare it. + * ldlex.l, ldgram.y: Recognize new options --help and --version. + +Mon Jun 21 20:39:48 1993 Ken Raeburn (raeburn@poseidon.cygnus.com) + + * Makefile.in (INCLUDES): Don't need ../include any more. + +Mon Jun 21 16:38:35 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldlex.l, ldgram.y: Support new -oformat option. + Remove attempt at supporting script fragments on the command line. + * ldlang.c (lang_add_output_format): Take new arg, FROM_SCRIPT. + * mri.c (mri_format), ldgram.y: Change callers. + * ldlang.h: Change prototype. + +Thu Jun 17 16:53:56 1993 david d `zoo' zuhn (zoo@cygnus.com) + + * Makefile.in: canonicalize install.sh; for use within + this directory (and subdirs) + +Thu Jun 17 14:33:09 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldgram.y: Tweak grammar to make reporting of invalid options work. + + * Makefile.in (.cc.o): Restore .SUFFIXES entry for .cc + and .cc.o rule. + +Wed Jun 16 11:45:32 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldfile.c (ldfile_open_command): Don't try .ld extension. + It wasn't documented (or likely used) and wastes time. + (try_open): If EXTEN is empty, don't try it. + + * ldctor.c, lderror.c, ldexp.c, ldfile.c, ldindr.c, ldlang.c, + ldlex.l, ldmain.c, ldmisc.c, ldsym.c, ldver.c, ldwarn.c, + ldwrite.c, lexsup.c, mri.c, relax.c: Replace DEFUN macro calls + with normal function declarations. + + * Move *.em to emultempl/*.em. Move *.sh to emulparams/*.sh. + Move *.sc-sh to scripttempl/*.sc. + * {emultempl,emulparams,scripttempl}/README: New files. + * sh.em, st2000.em, z8ksim.em, h8300hms.em, h8500hms.em: Files + removed, replaced with generic.em. + * h8300.sh, h8500.sh, h8300.sc, h8500.sc: Renamed from + h8[35]00hms.s[ch]. Change their contents to omit the "hms". + + * *.em (*_get_script): Return script name instead of script contents. + * ldlang.c (lang_process): Change caller. + + * ldlex.l, ldgram.y: Recognize -m option. + Check for input files after *all* options in grammar. + * ldmain.c (main): Check for -m options. Add default directory + for -m. + + * mkscript.c: File removed. + * genscripts.sh: Take two more parameters, tooldirlib and libdir, + to add to the default LIB_PATH. + Look for input files in the new subdirectories. + Create the scripts in emulations subdirectory and don't filter + them through mkscript. + * configure.in: Make the emulations subdirectory. + + * Makefile.in: Account for all of the above changes. + Remove unused .SUFFIXES. Get libgcc.a path with gcc + -print-libgcc-file-name instead of $(libdir)/libgcc.a. + Put CFLAGS last in the compilation rules. + Add -I../bfd to INCLUDES so sysdep.h is found. + +Tue Jun 15 23:04:46 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * Makefile.in (INCLUDES): Look in ../include, not ../bfd. + + * aout.sc-sh: Add SHLIB_PATH like STACKZERO. Make STACKZERO + dependent on RELOCATING, not RELOCATION. + * hp3hpux.sh (SHLIB_PATH): Define it. + +Mon Jun 14 19:06:15 1993 David J. Mackenzie (djm@thepub.cygnus.com) + + * ldfile.c (try_open): If opening without the extension fails, + try with the extension even if -v or -V was given. + had_script is imported (from ldgram.y), not exported. + +Mon Jun 14 16:26:10 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com) + + * Makefile.in: remove parentdir support, use INSTALL_XFORM + +Thu Jun 10 14:00:06 1993 Ian Lance Taylor (ian@cygnus.com) + + * ldexp.c (exp_fold_tree): Don't lose the old flag bits. + * ldgram.y (statement_list_opt): New nonterminal, either empty or + statement_list. + (section): Use statement_list_opt, not statement_list. + * m68kcoff.sc-sh: Gather constructors and destructors and define + __CTOR_LIST__ and __DTOR_LIST__ appropriately. + * sa29200.sc-sh: Gather constructors and destructors and define + ___CTOR_LIST__ and ___DTOR_LIST__ appropriately. + +Mon Jun 7 12:53:28 1993 Per Bothner (bothner@rtl.cygnus.com) + + * Makefile.in (INCLUDES): Add -I../bfd for sysdep.h and bfd.h. + * configure.in: No longer need to configure to get sysdep.h. + +Fri Jun 4 16:18:24 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in: remove install:all and install-info:info + dependencies (these cause some spurious rebuilds at 'make install' + time) + +Fri Jun 4 08:50:14 1993 Ian Lance Taylor (ian@cygnus.com) + + * configure.in (mips-idt-ecoffl*): New target; use mips-idtl. + (mips-idt-ecoff*): Added trailing '*'. + * config/mips-idtl.mt: New file; use EMUL of mipsidtl. + * mipsidtl.sh: New file; like mipsidt.sh, but little endian. + * Makefile.in (ALL_EMULATIONS): Added em_mipsidtl.o. + + * config/sun3.mh (HOSTING_LIBS, HOSTING_EMU): Removed obsolete and + incorrect definitions. + +Tue Jun 1 14:56:10 1993 Per Bothner (bothner@rtl.cygnus.com) + + * ldsym.c (write_file_locals): Write BSF_CONSTRUCTOR + symbols, unless stripping. + +Tue May 25 15:34:25 1993 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in: configure looks for ####, so remove lines with many + '#' characters. + * config/irix4.mh, config/i386v.mh: New files; set HOSTING_CRT0 + and HOSTING_LIBS correctly so that ``make check'' will work. + +Thu May 20 13:56:16 1993 Per Bothner (bothner@deneb.cygnus.com) + + * mips.sc-sh: Define _etext, _edata, and _end, in addition + to etext, edata, and end. Needed for IRIX 4.0.5F. + Patch from mwp@iconix.oz.au (Michael Paddon). + + * Version 2.2.1 released. + +Thu May 20 11:42:06 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * mipsbsd.sc-sh: Renamed from aout-mipsbsd.sc-sh. + * mipsbsd.sh (EMULATION_NAME): Use new file name. + +Tue May 18 17:10:24 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * Makefile.in (LDDISTSTUFF): Remove ld.mm since we can't build it + properly right now. + + * Version 2.2 released. + +Mon May 17 15:37:28 1993 Ken Raeburn (raeburn@deneb.cygnus.com) + + * ldver.c (ldversion): Bump version number to 2.2. + +Mon May 17 12:44:31 1993 Per Bothner (bothner@cygnus.com) + + * NEWS: New file. + +Fri May 14 11:26:24 1993 Ian Lance Taylor (ian@cygnus.com) + + * mips.sc-sh: Don't define BSS_VAR unless relocating. + +Wed May 12 13:33:29 1993 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in (mkscript.o, mkscript): Build mkscript via + mkscript.o, rather than directly from mkscript.c. + +Tue May 4 21:58:56 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * configure.in: Look for ${target_makefile_frag} relative to + ${srcdir}, not relative to build directory. + + * hppaosf.em, hppaosf.sc-sh, hppaosf.sh: New files. + * configure.in: Recognize hppa*-hp-osf. + * Makefile.in (ALL_EMULATIONS): Include hppaosf emulation. + (em_hppaosf.c): Build it. + * config/hppaosf.mh, hppaosf.mt: New files. + + * ld.h (ALIGN_N): Renamed from ALIGN, because that conflicted with + some system header files. All uses changed. + + * configure.in: Recognize i386-aix configurations as i386-coff + targets. + + * configure.in: Recognize m68*-*-hpux. + * aout.sc-sh: If STACKZERO and RELOCATING are both defined, output + the value of STACKZERO. + * Makefile.in (ALL_EMULATIONS): Include hp300-hpux emulation. + (em_hp3hpux.c): Build it. + * hp3hpux.sh, config/hp300hpux.mt: New files. + +Tue May 4 12:37:35 1993 Ian Lance Taylor (ian@cygnus.com) + + * mips.sc-sh: Put constructors in the .data section. + * Makefile.in (cdtest): Added dependency on ld.new. + +Mon May 3 19:43:39 1993 Per Bothner (bothner@cygnus.com) + + * Makefile.in: Change definition of $(tooldir) to match FSF. + * vax.sh, config/vax.mt, configure.in, Makefile.in: + Support VAX Ultrix and BSD. + +Mon Apr 26 18:35:47 1993 Steve Chamberlain (sac@thepub.cygnus.com) + + * sh.em, sh.sh, sh.sc-sh: New files supporting Hitachi SH. + +Wed Apr 14 21:01:51 1993 John Gilmore (gnu@cygnus.com) + + * ldlang.h (struct memory_region): Change `length' and + `old_length' fields to bfd_size_type. Eliminate use of bfd_offset. + * ldlang.c, mri.c: Corresponding changes, plus lint. + +Thu Apr 8 22:08:18 1993 Ian Lance Taylor (ian@cygnus.com) + + * configure.in: For all i386 targets, accept i486 as well. + +Mon Apr 5 17:33:39 1993 Ian Lance Taylor (ian@cygnus.com) + + * ldlang.c (wild_doit): Preserve all flags for a + SEC_SHARED_LIBRARY section. + (size_input_section): Consider any SEC_HAS_CONTENTS section when + computing largest_section. + +Fri Apr 2 14:33:52 1993 Ian Lance Taylor (ian@cygnus.com) + + * ldlang.c (lang_output_section_statement_lookup): Initialize all + fields of newly created structure. + +Wed Mar 31 18:19:15 1993 Ian Lance Taylor (ian@cygnus.com) + + * ldmain.c (g_switch_value): New variable. + * ldgram.y (OPTION_G, OPTION_Gval): New tokens. + (command_line_option): Accept -G and set g_switch_value. + * ldlex.l (COMMAND): Accept -G. + * ldlang.c (open_output): Call bfd_set_gp_size on new BFD. + +Tue Mar 30 09:40:25 1993 Steve Chamberlain (sac@thepub.cygnus.com) + + Support for linking and loading at different places: + + * ldlex.l: Add "AT" keyword. + * ldgram.y: Cleanup, and parse AT. + * ldlang.c (print_output_section_statement): Print output address + of section in map. (lang_size_sections): Fill sections' lma with + load address. + * ldlang.h (lang_output_section_statement_type): Add load_base + information. + + * ldindr.c (add_indirect): Keep more information in the alias + symbol chain. + * ldlang.c (wild_doit): Don't inherit NEVER_LOAD section + attribute from an input section. + * ldmain.c (Q_enter_file_symbols): Common section is NEVER_LOAD by + default. (Q_enter_file_symbos): Indirect symbols now are known by + their section, not a special symbol flag. + * ldsym.c (write_file_locals): Indirect symbols aren't local. + (write_file_globals): Write the mapping for an indirect symbol. + * relax.c (build_it): When forced to write a NEVER_LOAD section, + fill it with zeros. + +Tue Mar 23 13:24:10 1993 Jeffrey Osier (jeffrey@fowanton.cygnus.com) + + * ld.texinfo: changes for q1 + +Tue Mar 23 00:13:29 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in: add dvi target, define & use TEXI2DVI, add installcheck + +Mon Mar 8 20:30:35 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in: rename HOST_CC to CC_FOR_BUILD + +Thu Mar 4 12:44:33 1993 Ian Lance Taylor (ian@cygnus.com) + + * mips.sc-sh: Added variables which may be overridden by a + specific emulation. + * mipsidt.sh: New file; emulation for IDT MIPS board. + * Makefile.in (ALL_EMULATIONS): Added em_mipsidt.o. + (em_mipsidt.c): New target. Uses mipsidt.sh and mips.sc-sh. + * config/mips-idt.mt: New file; sets EMUL to mipsidt. + * configure.in (mips-idt-ecoff): New target; uses mips-idt. + +Sat Feb 27 00:00:14 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * aout-mipsbsd.sc-sh, mipsbsd.sh: New files from Ralph Campbell, + ralphc@pyramid.com. + * i386bsd.sh, config/i386bsd.mt: New files. + * configure.in, Makefile.in: Added support for mipsbsd and 386bsd. + +Thu Feb 25 15:33:10 1993 Per Bothner (bothner@rtl.cygnus.com) + + * mri.c: Add extern declaration of strdup. + * ldsym.c (KEEP macro): Add spaces around '=' for the + sake of old (e.g. PCC) compilers. + +Wed Feb 24 19:49:31 1993 Per Bothner (bothner@rtl.cygnus.com) + + * ldver.c: Bump to version 2.1. + +Fri Feb 12 08:09:11 1993 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldgram.y: allow section types without address expressions. + * ldlang.c (lang_relocate_globals): avoid possible hang with + undefined but unreferenced symbols. + * relax.c (relax_section): don't complain if the script file isn't + relaxable but -relax is set + +Thu Feb 18 17:58:45 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * configure.in: go32 is the 3rd part of the triple, not the 2nd + +Wed Feb 3 09:05:56 1993 Ian Lance Taylor (ian@cygnus.com) + + * mipsbig.sh: New file. Big endian MIPS emulation. + * config/mips-big.mt: New file. Use mipsbig emulation. + * configure.in (mips-sgi-irix*): Use target mips-big. + * Makefile.in (ALL_EMULATIONS): Added em_mipsbig.o. + (em_mipsbig.c): New target. Uses mipsbig.sh. + +Tue Feb 2 11:32:27 1993 Ian Lance Taylor (ian@cygnus.com) + + * mips.sc-sh: Put .scommon sections into .sbss section. + + * ldmain.c (subfile_wanted_p): Preserve section of common symbols, + rather than always putting them in bfd_com_section. + * ldlang.c (lang_common): If a common symbol is not in + bfd_com_section, put in a section of the same name, rather than + always putting it in section COMMON. + +Fri Jan 29 09:57:58 1993 Ian Lance Taylor (ian@cygnus.com) + + * ldmain.c (subfile_wanted_p): If we already have a common + definition of a symbol, don't necessarily pull in an object file + that provides a non-common definition. + + * ldlex.l (COMMAND): Accept -EB and -EL command line arguments, + returning OPTION_EB and OPTION_EL. gcc passes these to a MIPS + linker. + * ldgram.y (OPTION_EB, OPTION_EL): New tokens. + (command_line_option): Accept and ignore OPTION_EB and OPTION_EL. + +Thu Jan 28 15:12:04 1993 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in (install): Remove $(tooldir)/bin/gld before creating + the link to it. + +Tue Jan 26 11:49:50 1993 Ian Lance Taylor (ian@cygnus.com) + + * ldmain.c, ldsym.c: Use new bfd_is_com_section macro rather than + checking for equality to bfd_com_section. + +Fri Jan 22 14:22:44 1993 Ian Lance Taylor (ian@cygnus.com) + + * mips.sc-sh: New file. Ultrix, and hopefully other MIPS ECOFF + targets, linker script. + * mipslit.sh: New file. Little endian MIPS emulation. + * config/mips-lit.mt: New file. Use mipslit emulation. + * configure.in (mips-dec-ultrix*): Use target mips-lit. + * Makefile.in (ALL_EMULATIONS): Added em_mipslit.o. + (em_mipslit.c): New target. Uses mipslit.sh. + +Thu Jan 14 15:30:27 1993 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in (install): Install ld as both $(tooldir)/bin/ld and + $(tooldir)/bin/gld, so that gcc can find it with or without + collect2. + +Mon Jan 11 18:50:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * ldwrite.c: Removed perform_relocation, copy_and_relocate, and + write_norel. All linking is now done via write_relax. Call + ldsym_write before calling write_relax. + * relax.c: Added copyright. + (write_relax): Renamed from write_relaxnorel. Added relocateable + argument. seclet_dump renamed to bfd_seclet_link. + * relax.h: Added copyright. + +Mon Jan 11 15:41:56 1993 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldmain.c (decode_library_subfile): Patch from + hoogen@shafer.cs.utah.edu, don't reread library symbol tables. + +Fri Jan 8 18:04:33 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * config/vxworks960.mt renamed to config/i960.mt + + * configure.in: sparc-aout emulates a sun4, as does + sparc*-vxworks, i960-nindy uses gld960 emulation + +Fri Jan 8 14:39:07 1993 Steve Chamberlain (sac@thepub.cygnus.com) + + Fix support for NOLOAD, add INCLUDE + * ldfile.c (ldfile_open_command_file): pass file name to + lex_push_file. + * ldlex.l, ldgram.y: tidy up, parse INCLUDE and NOLOAD + * ldlang.c (wild_doit): make output sections inherit NEVER_LOAD + attribute. + +Thu Jan 7 10:22:19 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in, config.h: no more default emulation. Make the lack + of emulation a compile time error + +Wed Jan 6 01:08:37 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * configure.in: recognise all sparclite variants, not just 'sparclite' + +Mon Dec 28 11:15:35 1992 Ian Lance Taylor (ian@cygnus.com) + + * m68kcoff.sc-sh: define _end as well as end, for consistency with + aout.sc-sh. + + * configure.in: accept *-ericsson-ose for any m68k CPU. + + * ldwrite.c (write_rel): don't always set SEC_HAS_CONTENTS flag + for each output section. + +Mon Dec 21 16:06:59 1992 Per Bothner (bothner@rtl.cygnus.com) + + * ldexp.c, ldlang.c, ldmain.c, ldsym.c, ldwarn.c: Use new + macro bfd_asymbol_bfd as appropriate. + * Makefile.in: Un-duplicate ldlex.c dependency. + * condigure.in: Replace my_host case table by sourcing + ../bfd/configure.host. Allow std-host as the default. + * ldmisc.c: Change logic for C++ name demangling: There is + no initial '_' to remove from stab-derived function names. + +Sun Dec 13 16:31:26 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldlang.c (lang_init_script_file): don't attach the output file + sections to the script file. + +Wed Dec 9 08:38:05 1992 Steve Chamberlain (sac@thepub.cygnus.com) + * ldlang.c (wild): run expansion loop over command line bfd too. + (lang_ini_script_file): initialize more parts of the command line + bfd. + * ldlex.l: fix DEFINED start states. + +Mon Dec 7 08:43:41 1992 Steve Chamberlain (sac@thepub.cygnus.com) + -y support + * ld.texinfo: new doc. + * ldgram.y, ldlex.l: understand -y<symbol> + * ldmain.c (Q_enter_file_symbols): if had -y, lookup symbol and + print info. (add_ysym): new function. + * ldsym.h: (ldsym_type): new define SYM_Y. + +Sat Nov 21 03:15:27 1992 John Gilmore (gnu@cygnus.com) + + * ldctor.h, lderror.h, ldexp.h, ldfile.h, ldindr.h, ldlang.c, + ldlang.h, ldlex.h, ldmain.h, ldmisc.h, ldsym.h, ldver.h, ldwarn.h, + ldwrite.h, relax.h: Replace all uses of EXFUN and PROTO ansi-glue + macros with PARAMS. Recreational cleanup. Update copyrights. + +Tue Nov 10 00:23:37 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in: pass down the bfd source directory for includes + +Thu Nov 5 15:41:55 1992 Ian Lance Taylor (ian@cygnus.com) + + * ldlang.c (lang_size_sections): don't change size and address for + SEC_SHARED_LIBRARY sections rather than for SEC_NEVER_LOAD + sections. + +Thu Nov 5 11:33:57 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * relax.c (build_it): re-enable the processing of data_statements + in scripts, makes counted contructor lists work again. + +Thu Nov 5 05:43:01 1992 John Gilmore (gnu@cygnus.com) + + * ldemul.h: Remove uses of SDEF and PROTO macros (use PARAMS). + +Tue Oct 20 10:56:06 1992 Ian Lance Taylor (ian@cygnus.com) + + * m68kcoff.sc-sh: don't use initial underscores for etext, edata + and end. + +Mon Oct 19 09:45:38 1992 Ian Lance Taylor (ian@cygnus.com) + + * Support for i386-sysv. + configure.in: check for i386-*-sysv* and i386-*-sco*. + i386coff.sc-sh: rewrote to support SVR3 by default. + ldctor.c (find_constructors): preserve stat_ptr. + ldlang.c (wild_doit): initialize vma and size of new output + section to corresponding input section. This is required for + shared library support. + (lang_size_sections): don't modify vma and size of sections which + are never loaded (for shared libraries). + ldwrite.c (copy_and_relocate): copy the contents of any section + which has contents, not just sections which are loaded (for shared + libraries). + +Thu Oct 15 15:20:26 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldlang.c (size_input_section): count the sizes of all sections + we allocate. + +Thu Oct 8 09:05:25 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldmisc.c (demangle,vfinfo): use the new underscore in bfd to + to demangle symbols better + +Tue Oct 6 13:08:54 1992 Ian Lance Taylor (ian@cygnus.com) + + * ldlang.c (lang_finish): don't warn if -e start symbol does not + exist when linking with -r. + +Mon Oct 5 14:07:37 1992 Ian Lance Taylor (ian@cygnus.com) + + * aout.sc-sh, m68kcoff.sc-sh: set __bss_start to the start of the + .bss segment. + +Mon Oct 5 08:55:14 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldmain.c (linear_library): don't even think about processing + an object file if it's already been done + +Thu Oct 1 23:14:59 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * configure.in: the hp9000/300 config file is now hp300 + +Wed Sep 30 07:34:09 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * config/z8ksim.mt: new file + +Fri Sep 25 13:49:52 1992 Ken Raeburn (raeburn@kyriath.cygnus.com) + + * Makefile.in (ldexp.o, ldctor.o, ldlang.o, ldmain.o, ldwrite.o, + lexsup.o, mri.o, relax.o): Indicate dependence on ldgram.h. + + * ld.h (strip_symbols_type): Add value STRIP_SOME. + * ldgram.y (OPTION_RETAIN_SYMBOLS_FILE): New terminal token. + * ldlang.c (lang_add_keepsyms_file): New function. + * ldlex.l: Handle "-retain-symbols-file". + * ldsym.c (keepsyms_file, kept_syms): New vars. + (process_keepsyms): New functihon; reads file, marks symbols for + saving. + (write_file_locals): File symbols should always be kept. + (ldsym_write): Warn about "-retain-symbols-file" overriding "-S" + and "-s". Process retain-symbols file before setting symtab. + * ldsym.h (SYM_KEEP): New flag for ldsym_type flags. + (keepsyms_file, kept_syms): Declare them. + + * ldmain.c (main): Non-fatal errors should still cause non-zero + exit status even with -r. + +Fri Sep 25 11:08:01 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + Added initial support for the z8k + * z8ksim.em, z8ksim.sc-sh, z8ksim.sh: new files + * configure.in, Makefile.in: modified to reflect above + + * ldlang.c (lang_check): when linking conflicting architectures, + make the output file reflect at least one of the bad inputs. + +Tue Sep 15 15:35:38 1992 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in (install): if $(tooldir) exists, install ld in + $(tooldir)/bin. + +Fri Sep 11 10:24:22 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * Makefile.in, configure.in: modified to support i386-coff + * i386coff.sh: new file + +Wed Sep 9 11:52:58 1992 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in, m68kcoff.sh, m68kcoff.sc-sh, config/m68k-coff.mt: + added m68k-coff emulation mode, stolen from a29k emulation. + Almost certainly wrong, but perhaps better than sun3. + +Thu Sep 3 14:19:30 1992 Per Bothner (bothner@rtl.cygnus.com) + + * Makefile.in, Makefile.dos, generic.em, genscripts.sh, + gld960.em, h8300hms.em, h8300xray.em, lnk960.em, st2000.em, + vanilla.em: Rename all (generated) ld__*.c files to em_.c. + This is one character shorter, and lets people build on + SVR3 system. (ld__h8300xray.[co] was the killer there; + h8300xray.sc-sh is also overlong, but seems harmless.) + Based on a patch from Jonathan Ryshpan <hitachi!amito!jon>. + * Makefile.in (clean): Fix typo mostclean -> mostlyclean. + * configure.in: Add host isc. + + * ldver.c: Call it version 2.0. + +Wed Sep 2 00:21:33 1992 Per Bothner (bothner@rtl.cygnus.com) + + * ldver.c: Bump to version 0.98. + * TODO: New file. + + * Makefile.in: Added mostlyclean, distclean, realclean rules. + +Tue Sep 1 23:42:16 1992 Per Bothner (bothner@rtl.cygnus.com) + + * ldmisc.c (xrealloc): New (needed by ../libiberty/cplus.dem.c). + * ldlex.l: Moved comment() to end, since some compilers + otherwise have problems with input() used before it is defined. + +Tue Sep 1 17:45:51 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * configure.in: added Solaris 2 and Irix 4 host support. + +Mon Aug 31 19:27:11 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in: remove -S flag from the FLEX definition + + * configure.in: rewrote, using new style case statement. use + m68k.mt for m68k-aout systems + +Sun Aug 30 21:38:53 1992 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in: map "ld" through program_transform_name when + installing. + +Sun Aug 30 18:12:13 1992 Per Bothner (bothner@rtl.cygnus.com) + + * cplus-dem.c: Removed. Use the version in libiberty now. + * ldmisc.c: Use new libiberty version of cplus_demangle(). + +Thu Aug 27 16:38:42 1992 Ian Lance Taylor (ian@cygnus.com) + + * gld960.em (gld960_choose_target): default to little endian, not + big endian. + +Wed Aug 26 17:28:51 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldlang.c (lang_process): don't pass null pointers when + abs_output_section is what is required. + * ldwrite.c (ldwrite): use malloc to allocate the largest space + used, and pass that down. + * relax.c,relax.h (write_relaxnorel): use the passed malloc area rather + than alloca. + +Mon Aug 24 14:42:06 1992 Ian Lance Taylor (ian@cygnus.com) + + * configure.in, config/ose68.mt: renamed OSE to ose. + +Thu Aug 20 19:55:22 1992 Ken Raeburn (raeburn@cygnus.com) + + * ldsym.c (write_file_locals): Reorder check for common or + undefined symbols so that it works. + +Tue Aug 18 13:41:36 1992 Ian Lance Taylor (ian@cygnus.com) + + * configure.in: accept all m68K family members. + + * Makefile.in: always create installation directories. + +Thu Aug 13 11:49:34 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldlex.l: now parses comment correctly, added ~ to acceptable + chars in filenames + + * ldexp.c (exp_unop): pass down abs_output_section - now can have + unary -ve constants. + + * ldlang.c (lang_finish): warn when an entry symbol supplied on + the command line can't be found. + +Fri Aug 7 12:31:10 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldlang.h: add new field "loadable" to output_section_statement. + * ldlang.c (lang_output_section_statement_lookup): initilize new + field. (wild_doit): if new field is not set, then stop output + section from being loadable. + (lang_enter_output_section_statement): set the field from the + NOLOAD keyword + * ldgram.y: new synax for NOLOAD. Removes a shift/reduce too. + * h8300hms.sc-sh, h8300hms.em: get -r right. + +Thu Aug 6 18:35:21 1992 Per Bothner (bothner@rtl.cygnus.com) + + * ldint.texinfo: New internals manual (beginnings thereof). + * PORTING: Removed, merged into ldint.texinfo. + +Tue Aug 4 21:12:29 1992 Per Bothner (bothner@rtl.cygnus.com) + + * cdtest-main.cc, cdtest-func.cc, cdtest-foo.h, cdtest-foo.cc, + cdtest.exp: A test program (copied from libg++/test-install) + that tests that constructor and destructors are handled + corrrectly. + +Mon Aug 3 14:58:19 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * Makefile.in (install): install from ld.new, renaming during the + copy, or else the next 'make install' needs to re-link ld. + +Mon Jul 20 03:37:06 1992 D. V. Henkel-Wallace (gumby@cygnus.com) + + * configure.in: generalise hp recognition (from sef). + +Sat Jul 18 14:46:04 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) + + * configure.in: recognize bsd and hpux hppa configurations. + error messages echo to stderr, not stdout + +Fri Jul 17 22:06:11 1992 K. Richard Pixley (rich@rtl.cygnus.com) + + * Makefile.dos, gld.1, ld.texinfo, ldemul.c, ldfile.c, ldlang.c, + ldmisc.c: removed rcsid's. + +Tue Jul 14 08:34:34 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldlang.c (lang_map): print changes in sizes due to relaxing + (size_input_section): maintain the delta information. + * ldlang.h: add new field to struct to contain delta info. + * relax.c (relax_section): complain if input not relaxable. + * ldlex.l : add '_', ',' and '$' to chars which can appear at the + start of a filename + +Mon Jul 13 17:33:00 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldmain.c(main): prevent -r and -relax from being on at the same + time. + +Wed Jul 1 17:51:19 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldmain.c (Q_enter_global_ref), ldindr.c (add_indirect): fix for + aliasing problems + + +Thu Jun 18 09:38:56 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * h8300hms.em, h8300hms.sc-sh: do the right thing for -r + * ldexp.c: lint + * ldlang.c(open_output): set the target arch and machine as soon + as we can. (lang_size_sections): use new macros for setting vma + * ldwrite.c: lint + +Mon Jun 15 08:47:43 1992 Michael Tiemann (tiemann@rtl.cygnus.com) + + * configure.in (my_target): Accept m680?0 for wrs as vxworks68. + Also deleted an unreachable path to wrs. + +Wed May 27 23:24:19 1992 Michael Tiemann (tiemann@rtl.cygnus.com) + + * Makefile.in (install): use -d test for $tooldir before + installing ld there so that $tooldir can be inherited from + top-level Makefile. + +Wed May 27 16:56:48 1992 Per Bothner (bothner@rtl.cygnus.com) + + * ldlang.c: Two non-substantial changes for the sake of + the old Portable C Compiler. + +Wed May 27 15:15:58 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldgram.y, ldlex.l: parse ABSOLUTE + * ldexp.c: add support for ABSOLUTE + +Wed May 27 13:07:20 1992 Per Bothner (bothner@rtl.cygnus.com) + + * Makefile.in: Added default definitions for HOSTING_CRT0, + HOSTING_LIBS, and HOSTING_EMU, based on those in config/*.mh. + * config/*.mh: Miscellaneous clean-up: Removed definitions + of YACC (since it is not longer used in the Makefile). + Remove HOSTING_* definitions that are subsumed by the + ones added to Makefile.in. Removed most definitions of CC. + * config/{sparc,news,hp300bsd,decstation}.mh: Removed; + These are no longer needed. + +Fri May 22 13:47:19 1992 Per Bothner (bothner@cygnus.com) + + * Makefile.in: Use srcdir instead of VPATH in ldgram/ldlex + rules, since these are used when building a distribution. + * Makefile.in (ldlex.c): Don't re-direct output, since that + leaves a bogus output files if it fails. + + * config/sparc.mh: Fix HOSTING_LIBS so it has a chance of working. + * ldlex.c: Fix some unnecessary flex-specific-isms. + +Fri May 8 11:49:43 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldgram.y: move spurious semicolon + * ldexp.h: fix prototype + +Thu May 7 17:01:12 1992 Roland H. Pesch (pesch@fowanton.cygnus.com) + + * ld.texinfo: references to linker now say "ld" not "gld". + +Wed May 6 13:26:19 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + changed calling convention for Q_enter_global_ref + * ldexp.c, ldlang.c, ldmain.c: reflect this + * ldver.c: bump version to 1.97.1 + * ldindr.c (add_indirect): when an edict declaring an indirect + symbol is found, make sure that any ideas about the symbol being + common are changed if it now known to be defined. + * ldmain.c (linear_library): complain once if archive isn't + ranlibbed. + * ldlang.h, ldlang.c: make room for and initialize the complain + once field. + +Wed May 6 11:07:35 1992 K. Richard Pixley (rich@rtl.cygnus.com) + + * Makefile.in: use flex & bison from ../ if they exist. + +Tue May 5 17:47:33 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * relax.c (build_it): don't allocate space in the output file for + stuff if -R flag applys to it. + * ldfile.c: merge in VMS filename support + * ldmain.c (main): take out ./ from library path, and close file + before unlinking. Make multiple defs of a symbol create an + unexecable file. + * ldmisc.c: fatal errosrs delete output file + +Tue May 5 14:05:05 1992 Per Bothner (bothner@rtl.cygnus.com) + + * ldver.c: Increase version number to 1.97, for consistency + with ../binutils. + +Tue May 5 12:12:24 1992 K. Richard Pixley (rich@cygnus.com) + + * Makefile.in: FLEX -> LEX. + + * ld.texinfo: {} -> @{@}. + +Mon May 4 17:52:41 1992 Roland H. Pesch (pesch@fowanton.cygnus.com) + + * ld.texinfo: describe alternate, MRI-compatible linker scripts + (and associated change in -c option, now used for these scripts) + +Mon May 4 16:10:10 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldver.c: Bumped version to 1.96 - new release, resync with the + bfd too #. + * ldexp.c, ldlang.c: now build memory shape tree in obstacks + rather than with raw malloc, makes it easier to track where memory + is going. + * ldsym.h, ldsym.c: create obstack for all global symbols too. + * ldwrite.c (ldwrite): moved malloc so only used when needed. + * sa29200-sc.sh: added support for .lit, data1 and data2 sections. + + +Fri May 1 18:17:52 1992 K. Richard Pixley (rich@cygnus.com) + + * config/sparc.mh: use ../gcc/libgcc.a on check if it exists. + + * Makefile.in: use bootstrap for check. + +Fri May 1 13:03:41 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldgram.y, ldlex.c, mri.c: added more compatible words; BASE, ALIAS and + PUBLIC. + * Makefile.in: now use flex, not lex + * ldlex.l, ldlang.c, ldctor.c: lint + +Wed Apr 22 12:48:42 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldlex.l: added CMDFILENAMECHAR state so that you can lex + different sorts of filenames on the command line than in a script. + +Mon Apr 20 22:37:04 1992 K. Richard Pixley (rich@rtl.cygnus.com) + + * Makefile.in: rework CFLAGS so that they can be passed on the + make command line. Remove MINUS_G. Default CFLAGS to -g. + +Fri Apr 17 08:57:17 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * relax.c: added handling for new "padding" seclet type, used to + fill out gaps between section. + * ldgram.y, ldlex.l: now -defsym on the command line is done + properly. + +Wed Apr 15 21:20:07 1992 K. Richard Pixley (rich@rtl.cygnus.com) + + * Makefile.in: the tooldir copy of ld goes directly in tooldir. + +Wed Apr 15 16:09:33 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * mri.c, ldgram.y, ldlex.l: added support for minimal strange link + scripts. + +Thu Apr 9 05:52:02 1992 Ken Raeburn (Raeburn@Cygnus.COM) + + * Makefile.in (install): Install second copy in $(tooldir)/bin + without $(program_prefix), since that's what gcc expects. + +Sat Apr 4 17:44:06 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldlex.l, ldgram.y, ldlex.h: Rewrote lexer. Now it's much nicer. + * h8300*: fix bit rot and add support for h8300xray target + * go32.sh: target emulation for go32. + +Mon Mar 16 14:53:29 1992 Steve Chamberlain (sac@rtl.cygnus.com) + + * gld960.em, i960.sc-sh. Fix i960 bit rot + +Fri Mar 13 19:47:22 1992 K. Richard Pixley (rich@cygnus.com) + + * Makefile.in: install man page. + +Fri Mar 13 08:23:59 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * config/mt-<foo> renamed to <foo>.mt + * config/mh-<foo> renamed to <foo>.mt + * configure.in changed to reflect this + * genscripts.sh now make .xbn files rather than .xN files + +Sat Mar 7 03:40:40 1992 K. Richard Pixley (rich@cygnus.com) + + * ldver.h: fix decl of ldversion. + +Fri Mar 6 22:00:35 1992 K. Richard Pixley (rich@cygnus.com) + + * Makefile.in: added check target. + +Fri Mar 6 06:59:04 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldmain.c (Q_enter_file_symbols): now aliases work again + +Thu Mar 5 21:39:29 1992 K. Richard Pixley (rich@cygnus.com) + + * Makefile.in: added clean-info target. + +Thu Mar 5 16:55:56 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + * ldexp.c (exp_print_tree): don't try and follow null pointers + around. + * ldgram.y: remove 11 shift reduce errors + +Tue Mar 3 15:46:39 1992 K. Richard Pixley (rich@rtl.cygnus.com) + + * Makefile.in: added tooldir and program_prefix. + +Fri Feb 28 08:17:45 1992 Steve Chamberlain (sac at thepub.cygnus.com) + + * ldlang.c (size_input_section): don't move absolute sections + around! + + +Thu Feb 27 09:20:41 1992 Steve Chamberlain (sac at thepub.cygnus.com) + + * cplus-dem.c: yet another copy of this - maybe it should go into + libiberty ? + * ldgram.y: now -V and -v have different actions + * ldver.c: if -V, prints list of emulations compiled in + * ldmisc.c: support for cplus demangling + + +Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) + + * Makefile.in, configure.in: removed traces of namesubdir, + -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced + copyrights to '92, changed some from Cygnus to FSF. + +Thu Feb 20 17:43:46 1992 Per Bothner (bothner at cygnus.com) + + * Makefile.in: Change mkscript rule into one for ./mkscript + (for the sake of makes that don't realize they're the same). + * PORTING: Add more details. + * genscripts.sh: Add more tailorability of DATA_ALIGNMENT. + +Mon Feb 17 12:04:36 1992 Per Bothner (bothner at cygnus.com) + + * Makefile.in, and new files hp300bsd.sh, config/mh-hp300bsd, + config/mt-hp300bsd: New port to hp300 running BSD. + +Sat Feb 15 13:59:54 1992 Per Bothner (bothner at cygnus.com) + + Major rewrite of how ld is configured. The major idea + is to use shell scripts to generate everything. + * generic.em replaces ldtemplate. + * Other *.em files replace various *.c files. + A *.em file is a shell script that generates the corresponding + ld__*.c file that implements an emulation. This is usually + a straight 'cat' of a here-document, possibly with substitutions. + * Script files (*.sc) are places by *.sc-sh scripts. + Again, these are simple shell scripts that 'cat' + here-documents, usually with some substitutions. + The output a *.sc-sh is a script file. + * Each emulation is defined by a short shell script with + extension *.sh that specifies the emulation-specific + parameters (such as the name of the *.sh-sc and *.em + files to use). + * genscript.sh is the master shell script used to generate + an emulation. It is passed various argument, including + the name a the emulation-speciic *.sh file that it + "sources" to set variables to emulation-specifc parameters. + * config/mt-foo: Changed EMUL=GLDFOO_EMULATION_NAME + to EMUL=foo. (The GLDFOO_EMULATION_NAMEs have bee removed.) + * config/mh-foo: Rename LDEMULATION names as appropriate + (usually 'gldfoo' -> plain 'foo'). + * ldwrite.c: Fixed a typo in a comment. + * Makefile.in: Major changes. Removed some the sed + magic to converts scripts, since that is now handled + by genscripts.sh and the *.sc-sh scipt generators. + * config.h: Remove a bunch of macros defining emulations + and targets. This becomes one less file to edit when + adding emulations or targets. + * ldemul.h (struct ld_emulation_xfer_struct): Add + emulation_name and target_name fields. + * ldemul.c, ldemul.h: Define some default functions used + by most emulations (and remove from the *.em scripts). + * ldemul.c (ldemul_choose_target): Search the new + ld_emulations array using a loop (instead of a hardwired + nested if statement). + Define the ld_emulation from the automatically-geenrated + ldemul-list.h. This means you no longer have to edit ldemul.c + to add a new emulation. + * ldmain.c: Replace {GLD,LNK}960_EMULATION_NAME by + their expansions, since the former no longer exist. + * PORTING: A very rough first draft of a porting guide. + + * ldgram.y, ldlex.l, lexsup.c: Changes to allow an assignment + to be terminated by a new-line (instead of requiring a semicolon). + +Mon Feb 10 16:21:02 1992 Steve Chamberlain (sac at rtl.cygnus.com) + + * ldexp.c, ldlang.c: added new idea "abs_output_section", removes + tests for NULL pointers all over the place. + * ldlang.c (lang_process): remember to relocate global symbols + *after* relaxing has done it stuff. + +Thu Feb 6 11:40:15 1992 Steve Chamberlain (sac at rtl.cygnus.com) + + * config/mt-coff-h8300: use EMUL like everything else + * ldlang.c: (print_padding_statement): print the right address. + * Makefile.in, config.h, ldemul.c: renamed h8300hds to h8300hms + + +Tue Feb 4 15:28:01 1992 Steve Chamberlain (sac at rtl.cygnus.com) + + * ldlex.l: Put pack -noinhibit-exec and -sort-common + * ldlang.c (print_data_statement): print the right address. + +Thu Jan 30 17:51:53 1992 Per Bothner (bothner at cygnus.com) + + * Makefile.in: The rule for testing ld by re-linking itself + via an intermediate -r link was moved to the ld1 rule + instead of the ld2 rule. This allows ld2 and ld3 to be identical, + which allows the bootstrap rule to work. + * ldctor.c (find_constructors): Don't create a constructor + list if it is already defined (as would happen if ld is + invoked by collect). + +Wed Jan 29 08:35:39 1992 Steve Chamberlain (sac at rtl.cygnus.com) + + * config/mh-sparc.h: now uses libgcc.a + * ldmain.c: quit using exit + * *sc: use *(COMMON) rather than [COMMON] + * ldlex.l, lexsup.c: much thinking moved from .l and put into .c, + to allow preprocessing of .l file. + * Makefile.in: New ldlex.l mangling + * ldexp.c (fold_binary): perform expressions with % and / in + integer. + * ldfile.c (open_a): open archives on VMS in a special way + + +Tue Jan 28 10:18:16 1992 Steve Chamberlain (sac at rtl.cygnus.com) + + * ldgram.y: map -M behave in the same way as -Map (sets file name + to be "-". + * ldsym.c, ldlang.c: remember that size of a section is dependent on + whether or not relaxing has been done. + * ldmain.c: don't open a map file if it doesn't have a name + * relax.c: all the brains have moved into bfd. + * ldwrite.c: ammend comment + +Fri Jan 24 14:23:46 1992 Steve Chamberlain (sac at rtl.cygnus.com) + + * Makefile.in: added relax, also made three stage go through a + partial link stage. + * relax.c : added + * config.h: if GNU960 defined, then default emulation mode is + GLD960 + * ldexp.h, ldexp.c: map to file hooks + * ldlang.c: map to file hooks + * ldgram.y: added -Map -relax + * ldlex.l: added -relax, -Map + * ldmain.c: open map file + * ldmisc.c: support for map file + * ldwrite.c: new relax magic + +Thu Dec 19 18:49:51 1991 John Gilmore (gnu at cygnus.com) + + * Makefile.in, config/tm-*.h: Clean up make output, only + pass DEFAULT_EMULATION to ldmain.c. + +Wed Dec 18 15:02:47 1991 Per Bothner (bothner at cygnus.com) + + * ldver.c: Bump to version 1.94. + +Tue Dec 10 04:07:23 1991 K. Richard Pixley (rich at rtl.cygnus.com) + + * Makefile.in: infodir belongs in datadir. + +Mon Dec 9 16:26:43 1991 Per Bothner (bothner at cygnus.com) + + * Makefile.in: Pass -y to bison. (Again; + accidentally deleted by Rich.) + * news.sc, ldgld68k.sc: Define __end as well as _end. + +Sat Dec 7 17:19:26 1991 Steve Chamberlain (sac at rtl.cygnus.com) + + * ldindr.h: added to contain prototypes of ldindr.c + * ldfile.c: include ctype.h + * ldmain.c: include the requried prototype headers + * ldwrite.c: get_reloc_upper_bound has been renamed + bfd_get_reloc_upper_bound + +Fri Dec 6 23:29:26 1991 K. Richard Pixley (rich at rtl.cygnus.com) + + * Makefile.in: punt "fundamental" mode because it breaks my emacs + macros. install using INSTALL_PROGRAM and INSTALL_DATA. remove + spaces following hyphens, bsd make can't cope. added + standards.text support and made it look like all the other + makefiles. + + * configure.in: configure now runs entirely in objdir so make file + existence checks against ${srcdir}. Mark this directory as + target dependent. + +Thu Dec 5 22:46:16 1991 K. Richard Pixley (rich at rtl.cygnus.com) + + * Makefile.in: idestdir and ddestdir go away. Added copyrights + and shift gpl to v2. Added ChangeLog if it didn't exist. docdir + and mandir now keyed off datadir by default. + +Wed Dec 4 23:36:55 1991 Per Bothner (bothner at cygnus.com) + + * ldver.c: Bumped version to 1.93. + * Makefile.in: Pass -y to bison. + +Mon Nov 25 18:28:40 1991 Steve Chamberlain (sac at cygnus.com) + + * config.h: h8 is now coff, not ieee + * h8300hds.sc: reflect the same + +Thu Nov 14 19:55:09 1991 Per Bothner (bothner at cygnus.com) + + * ldver.c (ldversion()): Update to 1.92. + * ldctor.c: There are two places constructor sets + can be defined. One of them checked for an existing + duplicate, the other didn't. Unfortunately, the latter + was called after the former ... + So, factor out code for inserting a new element into + constructor_name_list (after checking for a duplicate) + into a new function add_constructor_name, and call + it from both aforementioned places (ldlang_add_constructor + and ldlang_check_for_constructors). + +Wed Nov 13 15:17:43 1991 Per Bothner (bothner at cygnus.com) + + * Makefile.in: Rename .c files generated from ldtemplate + to have names starting with ld__. This helps 'make clean'. + +Tue Nov 12 18:36:50 1991 Steve Chamberlain (sac at cygnus.com) + + * Makefile.in: Take out the version number for install + * m88kbcs.sc: put in contructor blocks. + +Mon Nov 11 18:47:33 1991 Per Bothner (bothner at cygnus.com) + + * ldmisc.c, ldmisc.h: Re-write info() to take a filename + parameter, a format, and an arg pointer, and rename it to + vfinfo(). Write info() in terms of new vfinfo(). + New einfo() is the same as info(), except it writes to stderr. + * ldemul.c, ldexp.c, ldlang.c, ldlnk960.c, ldmain.c, ldwrite.c, + ldmisc.c: Replace "error" calls to info() by new einfo(). + +Mon Nov 11 09:57:32 1991 Steve Chamberlain (steve at cygnus.com) + + * ldlex.l ldgram.y: made -V option do same as -v + * Makefile.in: Added $(MINUS_G) flag so debugging can be + turned off + +Sun Nov 3 16:37:37 1991 Steve Chamberlain (steve at cygnus.com) + i386 aout changes from Bob Kukura + * Makefile.in, config.h: added i386aout support + * configure.in: fixed /h-{myhost} typo + * ldgram.y: -MM now gives more boring map. + * ldlang.c: now does D_PAGED flag the right way. + * ldsym.c: -MM flags does the right thing. + +Sun Nov 3 15:00:03 1991 Per Bothner (bothner at cygnus.com) + + * configure.in: Fixed typo. Also, a fix for hp300bsd. + * ldlang.c (init_os): Compensate for BFD change, + where bfd_make_section now returns NULL for a duplicate + section request, instead of the old section. + +Thu Oct 17 15:27:13 1991 Per Bothner (bothner at cygnus.com) + + * ldver.c: Bump to version 1.91 (consistent with binutils). + +Wed Oct 16 12:27:08 1991 Per Bothner (bothner at cygnus.com) + + * Makefile.in, config.h, ld.h, ldemul.c, ldexp.c, ldexp.h, + ldgram.y, ldlex.l, ldlnk960.c, ldmain.c, ldmisc.c, ldmisc.h, + ldsym.c, ldsym.h, ldtemplate, ldvanilla.c, ldver.c, ldver.h, + ldwarn.c, ldwarn.h, ldwrite.c, ldwrite.h, mkscript.c: + Add or update copyright notices. + +Mon Oct 14 23:55:27 1991 Per Bothner (bothner at cygnus.com) + + * README: New file. + * Makefile.in: Changed installation directory name scheme + to be consistent with gcc. Also changed 'install'. + +Mon Oct 14 17:30:02 1991 Roland H. Pesch (pesch at cygnus.com) + + * Makefile.in: new targets ld.mm, ld.me + +Mon Oct 14 17:27:24 1991 Per Bothner (bothner at cygnus.com) + + * Makefile.in, ldtemplate: Need to use separate scripts + for -n and -N options. Yet more complication. + +Fri Oct 11 22:40:46 1991 John Gilmore (gnu at cygnus.com) + + * Makefile.in: Avoid using $< in explicit Make rules (it doesn't + work). Add some lines to avoid Sun Make VPATH bugs. + +Fri Oct 11 16:42:22 1991 Per Bothner (bothner at cygnus.com) + + * news.sc: Add alignment for data segment. + * ldtemplate: Add (yet another) script to get for -n or -N + options. (These need different alignment than ZMAGIC files.) + * Makefile.in: Add stuff for new foo.xn scripts. + These are generated by replacing "ALIGN(0x...00)" by ".". + +Fri Oct 11 15:43:04 1991 Roland H. Pesch (pesch at cygnus.com) + + * Makefile.in: new targets ld.ms, ld-index.ms + ld.texinfo: remove tabs, other cleanups for texi2roff + +Fri Oct 11 13:51:54 1991 Per Bothner (bothner at cygnus.com) + + * ldmain.c (main): Make config.magic_demand_paged be true + by default. Don't the WP_TEXT and D_PAGED flags of + output_bfd here; it's too late, so set it when output_bfd + is created (in ldlang.c). Also fix setting of EXEC_P flag + * ldlang.c (ldlang_open_output): Set output_bfd->flags here. + * ldlang.c: Remove some duplicate extern declarations. + * ldgram.y: Fixes to -N and -n options. + * Makefile.in: Recognize upper case letters in sed script + to remove assignments from script files. + * ldtemplate: Don't assukme that -N or -n options + imply use of -r script. + * mkscript.c: Tweaking to correctly handle \n and \\ in input. + +Fri Oct 11 10:29:27 1991 Steve Chamberlain (steve at cygnus.com) + + * ldtemplate: include bfd.h before sysdep.h. + +Fri Oct 11 04:24:45 1991 John Gilmore (gnu at cygnus.com) + + Restructure configuration scheme for bfd, binutils, ld. + + * include/sys/h-*.h: Move to bfd/hosts/h-*.h. + * configure.in: Revise to symlink sysdep.h to ../bfd/hosts/h-xxx.h. + Change some config names to match other dirs. + * *.c: Include bfd.h before sysdep.h, so ansidecl and PROTO() + get defined first. + * config/: Rename some config files to match up h-*.h names. + Remove all the HOST_SYS definitions from the config files. + +Tue Oct 8 16:00:57 1991 Per Bothner (bothner at cygnus.com) + + * ldexp.h, ldlang.h: Change enum boolean -> enum bfd_boolean. + * ldtemplate: Remove ldfile_add_library_path calls; + just use the SEARCH_DIR commands in the script files. + * Makefile.in: Add LIB_PATH macro, which if set is used to replace + the SEARCH_DIR commands in the scripts (using ugly sed magic). + This is primarily intended for cross-linking, where you would + place libaries in a different place than native libraries. + Also, emulations made from ldtemplate now use $(srcdir). + * ldglda29k.sc: Change SEARCH_DIR commands to a conventional + form; people can use the Makefile's LIB_PATH to override. + +Tue Oct 8 14:51:21 1991 Roland H. Pesch (pesch at cygnus.com) + + * Makefile.in: fix target ld.dvi, add target ld.info + ld.texinfo: make info filename ld.info + +Fri Oct 4 21:51:58 1991 John Gilmore (gnu at cygnus.com) + + * Makefile.in: Avoid using $< in non-suffix rules (breaks on Sun + Make). + * ldfile.c, ldlang.c, ldmain.c, ldwrite.c: Cope with renames of a + few BFD types & enums. + + +Local Variables: +mode: change-log +left-margin: 8 +fill-column: 74 +version-control: never +End: diff --git a/ld/Makefile.am b/ld/Makefile.am new file mode 100644 index 0000000..1f02098 --- /dev/null +++ b/ld/Makefile.am @@ -0,0 +1,863 @@ +## Process this file with automake to generate Makefile.in + +## FIXME: work around apparent automake bug. +INTLLIBS = @INTLLIBS@ + +AUTOMAKE_OPTIONS = cygnus dejagnu + +SUBDIRS = po + +tooldir = $(exec_prefix)/$(target_alias) + +YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L$(srcdir)/../bison/ ; else echo bison -y ; fi` +YFLAGS = -d +LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi` + +# We put the scripts in the directory $(scriptdir)/ldscripts. +# We can't put the scripts in $(datadir) because the SEARCH_DIR +# directives need to be different for native and cross linkers. +scriptdir = $(tooldir)/lib + +EMUL = @EMUL@ +EMULATION_OFILES = @EMULATION_OFILES@ +EMUL_EXTRA_OFILES = @EMUL_EXTRA_OFILES@ + +# Search path to override the default search path for -lfoo libraries. +# If LIB_PATH is empty, the ones in the script (if any) are left alone. +# (The default is usually /lib:/usr/lib:/usr/local/lib, unless building +# a cross-linker, in which case the default is empty. See genscripts.sh.) +# Otherwise, they are replaced with the ones given in LIB_PATH, +# which may have the form: LIB_PATH=/lib:/usr/local/lib +LIB_PATH = + +BASEDIR = $(srcdir)/.. +BFDDIR = $(BASEDIR)/bfd +INCDIR = $(BASEDIR)/include +DEP = mkdep + +# What version of the manual to build +DOCVER = gen + +#stuff for self hosting (can be overridden in config file). +HOSTING_CRT0 = @HOSTING_CRT0@ +HOSTING_LIBS = @HOSTING_LIBS@ +HOSTING_EMU = -m $(EMUL) + +# Setup the testing framework, if you have one +EXPECT = `if [ -f $$r/../expect/expect ] ; \ + then echo $$r/../expect/expect ; \ + else echo expect ; fi` + +RUNTEST = `if [ -f $${srcroot}/../dejagnu/runtest ] ; \ + then echo $${srcroot}/../dejagnu/runtest ; \ + else echo runtest ; fi` + +RUNTESTFLAGS = + +CC_FOR_TARGET = ` \ + if [ -f $$r/../gcc/xgcc ] ; then \ + if [ -f $$r/../newlib/Makefile ] ; then \ + echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \ + else \ + echo $$r/../gcc/xgcc -B$$r/../gcc/; \ + fi; \ + else \ + if [ "@host@" = "@target@" ] ; then \ + echo $(CC); \ + else \ + echo gcc | sed '$(transform)'; \ + fi; \ + fi` + +CXX = gcc +CXX_FOR_TARGET = ` \ + if [ -f $$r/../gcc/xgcc ] ; then \ + if [ -f $$r/../newlib/Makefile ] ; then \ + echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \ + else \ + echo $$r/../gcc/xgcc -B$$r/../gcc/; \ + fi; \ + else \ + if [ "@host@" = "@target@" ] ; then \ + echo $(CXX); \ + else \ + echo gcc | sed '$(transform)'; \ + fi; \ + fi` + +noinst_PROGRAMS = ld-new +info_TEXINFOS = ld.texinfo +noinst_TEXINFOS = ldint.texinfo +man_MANS = ld.1 + +INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) -I$(top_srcdir)/../intl -I../intl $(HDEFINES) $(CFLAGS) -DLOCALEDIR="\"$(prefix)/share/locale\"" + +BFDLIB = ../bfd/libbfd.la +LIBIBERTY = ../libiberty/libiberty.a + +ALL_EMULATIONS = \ + ea29k.o \ + eaixppc.o \ + eaixrs6.o \ + ealpha.o \ + earcelf.o \ + earmelf.o \ + earmelf_oabi.o \ + earmlinux.o \ + earm26linux.o \ + earmaoutb.o \ + earmaoutl.o \ + earmcoff.o \ + earmpe.o \ + ecoff_sparc.o \ + ed10velf.o \ + ed30velf.o \ + ed30v_e.o \ + ed30v_o.o \ + edelta68.o \ + eebmon29k.o \ + eelf32_sparc.o \ + eelf32b4300.o \ + eelf32bmip.o \ + eelf32ebmip.o \ + eelf32elmip.o \ + eelf32l4300.o \ + eelf32lmip.o \ + eelf32lppc.o \ + eelf32ppc.o \ + eelf_i386.o \ + eelf_i386_be.o \ + egld960.o \ + egld960coff.o \ + eelf32fr30.o \ + eelf32mcore.o \ + ego32.o \ + eh8300.o \ + eh8300h.o \ + eh8300s.o \ + eh8500.o \ + eh8500b.o \ + eh8500c.o \ + eh8500m.o \ + eh8500s.o \ + ehp300bsd.o \ + ehp3hpux.o \ + ehppaelf.o \ + ei386aout.o \ + ei386beos.o \ + ei386bsd.o \ + ei386coff.o \ + ei386go32.o \ + ei386linux.o \ + ei386lynx.o \ + ei386mach.o \ + ei386moss.o \ + ei386msdos.o \ + ei386nbsd.o \ + ei386nw.o \ + ei386pe.o \ + elnk960.o \ + em68k4knbsd.o \ + em68kaout.o \ + em68kaux.o \ + em68kcoff.o \ + em68kelf.o \ + em68klinux.o \ + em68klynx.o \ + em68knbsd.o \ + em68kpsos.o \ + em88kbcs.o \ + emcorepe.o \ + emipsbig.o \ + emipsbsd.o \ + emipsidt.o \ + emipsidtl.o \ + emipslit.o \ + emipslnews.o \ + enews.o \ + ens32knbsd.o \ + epc532macha.o \ + eppcmacos.o \ + eppcnw.o \ + eppcpe.o \ + eriscix.o \ + esa29200.o \ + esh.o \ + eshelf.o \ + eshlelf.o \ + eshl.o \ + esparcaout.o \ + esparclinux.o \ + esparclynx.o \ + esparcnbsd.o \ + est2000.o \ + esun3.o \ + esun4.o \ + etic30aout.o \ + etic30coff.o \ + etic80coff.o \ + evanilla.o \ + evax.o \ + evsta.o \ + ew65.o \ + ez8001.o \ + ez8002.o + +ALL_64_EMULATIONS = \ + eelf64_sparc.o \ + eelf64alpha.o + +ALL_EMUL_EXTRA_OFILES = \ + pe-dll.o \ + deffilep.o + +CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \ + ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \ + mri.c ldcref.c pe-dll.c + +HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \ + ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \ + ldwrite.h mri.h deffile.h + +GENERATED_CFILES = ldgram.c ldlex.c deffilep.c +GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h + +OFILES = ldgram.o ldlex.o lexsup.o ldlang.o mri.o ldctor.o ldmain.o \ + ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o \ + ldfile.o ldcref.o ${EMULATION_OFILES} ${EMUL_EXTRA_OFILES} + +STAGESTUFF = *.o ldscripts/* e*.c + +# At the moment this is just a list of those emulation template files +# that contain internationalised strings. +EMULATION_FILES = emultempl/pe.em emultempl/armcoff.em + +POTFILES = $(CFILES) $(HFILES) $(EMULATION_FILES) + +po/POTFILES.in: @MAINT@ Makefile + for file in $(POTFILES); do echo $$file; done | sort > tmp \ + && mv tmp $(srcdir)/po/POTFILES.in + +ldmain.o: ldmain.c config.status + $(COMPILE) -c -DDEFAULT_EMULATION='"$(EMUL)"' -DSCRIPTDIR='"$(scriptdir)"' -DTARGET='"@target@"' $(srcdir)/ldmain.c + +ldemul-list.h: Makefile + (echo "/* This file is automatically generated. DO NOT EDIT! */";\ + for f in `echo " " ${EMULATION_OFILES} "" \ + | sed -e 's/ e/ ld/g' -e 's/ ld/ /g' -e 's/[.]o//g'`; do \ + echo "extern ld_emulation_xfer_type ld_$${f}_emulation;"; \ + done;\ + echo "";\ + echo "#define EMULATION_LIST \\";\ + for f in `echo " " ${EMULATION_OFILES} "" \ + | sed -e 's/ e/ ld/g' -e 's/ ld/ /g' -e 's/[.]o//g'`; do \ + echo " &ld_$${f}_emulation, \\"; \ + done;\ + echo " 0") >ldemul-tmp.h + mv ldemul-tmp.h ldemul-list.h + +# These all start with e so 'make clean' can find them. + +GENSCRIPTS = $(SHELL) $(srcdir)/genscripts.sh ${srcdir} ${libdir} @host@ @target@ @target_alias@ ${EMUL} "@NATIVE_LIB_DIRS@" +GEN_DEPENDS = $(srcdir)/genscripts.sh $(srcdir)/emultempl/stringify.sed +@TDIRS@ + +ea29k.c: $(srcdir)/emulparams/a29k.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/a29k.sc ${GEN_DEPENDS} + ${GENSCRIPTS} a29k "$(tdir_a29k)" +eaixppc.c: $(srcdir)/emulparams/aixppc.sh \ + $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS} + ${GENSCRIPTS} aixppc "$(tdir_aixppc)" +eaixrs6.c: $(srcdir)/emulparams/aixrs6.sh \ + $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS} + ${GENSCRIPTS} aixrs6 "$(tdir_aixrs6)" +ealpha.c: $(srcdir)/emulparams/alpha.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/alpha.sc ${GEN_DEPENDS} + ${GENSCRIPTS} alpha "$(tdir_alpha)" +earcelf.c: $(srcdir)/emulparams/arcelf.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} arcelf "$(tdir_arcelf)" +earmelf.c: $(srcdir)/emulparams/armelf.sh \ + $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf "$(tdir_armelf)" +earmelf_oabi.c: $(srcdir)/emulparams/armelf_oabi.sh \ + $(srcdir)/emultempl/armelf_oabi.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf_oabi "$(tdir_armelf)" +earmelf_linux.c: $(srcdir)/emulparams/armelf_linux.sh \ + $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf_linux "$(tdir_armelf_linux)" +earmelf_linux26.c: $(srcdir)/emulparams/armelf_linux26.sh \ + $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf_linux26 "$(tdir_armelf_linux26)" +earmaoutb.c: $(srcdir)/emulparams/armaoutb.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/armaout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armaoutb "$(tdir_armaoutb)" +earmaoutl.c: $(srcdir)/emulparams/armaoutl.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/armaout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armaoutl "$(tdir_armaoutl)" +earmcoff.c: $(srcdir)/emulparams/armcoff.sh \ + $(srcdir)/emultempl/armcoff.em $(srcdir)/scripttempl/armcoff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armcoff "$(tdir_armcoff)" +earmpe.c: $(srcdir)/emulparams/armpe.sh \ + $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armpe "$(tdir_armpe)" +ecoff_sparc.c: $(srcdir)/emulparams/coff_sparc.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparccoff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} coff_sparc "$(tdir_coff_sparc)" +ed10velf.c: $(srcdir)/emulparams/d10velf.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd10v.sc ${GEN_DEPENDS} + ${GENSCRIPTS} d10velf "$(tdir_d10v)" +ed30velf.c: $(srcdir)/emulparams/d30velf.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS} + ${GENSCRIPTS} d30velf "$(tdir_d30v)" +ed30v_o.c: $(srcdir)/emulparams/d30v_o.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS} + ${GENSCRIPTS} d30v_o "$(tdir_d30v)" +ed30v_e.c: $(srcdir)/emulparams/d30v_e.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS} + ${GENSCRIPTS} d30v_e "$(tdir_d30v)" +edelta68.c: $(srcdir)/emulparams/delta68.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/delta68.sc ${GEN_DEPENDS} + ${GENSCRIPTS} delta68 "$(tdir_delta68)" +eebmon29k.c: $(srcdir)/emulparams/ebmon29k.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/ebmon29k.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ebmon29k "$(tdir_ebmon29k)" +eelf32fr30.c: $(srcdir)/emulparams/elf32fr30.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32fr30 "$(tdir_fr30)" +eelf32mcore.c: $(srcdir)/emulparams/elf32mcore.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32mcore "$(tdir_mcore)" +em32relf.c: $(srcdir)/emulparams/m32relf.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m32relf "$(tdir_m32r)" +eelf32_sparc.c: $(srcdir)/emulparams/elf32_sparc.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32_sparc "$(tdir_elf32_sparc)" +eelf32b4300.c: $(srcdir)/emulparams/elf32b4300.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32b4300 "$(tdir_elf32b4300)" +eelf32bmip.c: $(srcdir)/emulparams/elf32bmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32bmip "$(tdir_elf32bmip)" +eelf32bsmip.c: $(srcdir)/emulparams/elf32bsmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32bsmip "$(tdir_elf32bsmip)" +eelf32ebmip.c: $(srcdir)/emulparams/elf32ebmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32ebmip "$(tdir_elf32ebmip)" +eelf32elmip.c: $(srcdir)/emulparams/elf32elmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32elmip "$(tdir_elf32elmip)" +eelf32l4300.c: $(srcdir)/emulparams/elf32l4300.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32l4300 "$(tdir_elf32l4300)" +eelf32lmip.c: $(srcdir)/emulparams/elf32lmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32lmip "$(tdir_elf32lmip)" +eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfppc.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32lppc "$(tdir_elf32lppc)" +eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32lsmip "$(tdir_elf32lsmip)" +eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfppc.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32ppc "$(tdir_elf32ppc)" +eelf64alpha.c: $(srcdir)/emulparams/elf64alpha.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf64alpha "$(tdir_elf64alpha)" +eelf64_sparc.c: $(srcdir)/emulparams/elf64_sparc.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf64_sparc "$(tdir_elf64_sparc)" +eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_i386 "$(tdir_elf_i386)" +eelf_i386_be.c: $(srcdir)/emulparams/elf_i386_be.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_i386_be "$(tdir_elf_i386_be)" +egld960.c: $(srcdir)/emulparams/gld960.sh \ + $(srcdir)/emultempl/gld960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS} + ${GENSCRIPTS} gld960 "$(tdir_gld960)" +egld960coff.c: $(srcdir)/emulparams/gld960coff.sh \ + $(srcdir)/emultempl/gld960c.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS} + ${GENSCRIPTS} gld960coff "$(tdir_gld960coff)" +ego32.c: $(srcdir)/emulparams/go32.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} go32 "$(tdir_go32)" +eh8300.c: $(srcdir)/emulparams/h8300.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8300 "$(tdir_h8300)" +eh8300h.c: $(srcdir)/emulparams/h8300h.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300h.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8300h "$(tdir_h8300h)" +eh8300s.c: $(srcdir)/emulparams/h8300s.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300s.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8300s "$(tdir_h8300s)" +eh8500.c: $(srcdir)/emulparams/h8500.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500 "$(tdir_h8500)" +eh8500b.c: $(srcdir)/emulparams/h8500b.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500b.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500b "$(tdir_h8500b)" +eh8500c.c: $(srcdir)/emulparams/h8500c.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500c.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500c "$(tdir_h8500c)" +eh8500m.c: $(srcdir)/emulparams/h8500m.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500m.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500m "$(tdir_h8500m)" +eh8500s.c: $(srcdir)/emulparams/h8500s.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500s.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500s "$(tdir_h8500s)" +ehp300bsd.c: $(srcdir)/emulparams/hp300bsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} hp300bsd "$(tdir_hp300bsd)" +ehp3hpux.c: $(srcdir)/emulparams/hp3hpux.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} hp3hpux "$(tdir_hp3hpux)" +ehppaelf.c: $(srcdir)/emulparams/hppaelf.sh \ + $(srcdir)/emultempl/hppaelf.em $(srcdir)/scripttempl/hppaelf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} hppaelf "$(tdir_hppaelf)" +ei386aout.c: $(srcdir)/emulparams/i386aout.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386aout "$(tdir_i386aout)" +ei386beos.c: $(srcdir)/emulparams/i386beos.sh \ + $(srcdir)/emultempl/beos.em $(srcdir)/scripttempl/i386beos.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386beos "$(tdir_i386beos)" +ei386bsd.c: $(srcdir)/emulparams/i386bsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386bsd "$(tdir_i386bsd)" +ei386coff.c: $(srcdir)/emulparams/i386coff.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386coff "$(tdir_i386coff)" +ei386go32.c: $(srcdir)/emulparams/i386go32.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386go32.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386go32 "$(tdir_i386go32)" +ei386linux.c: $(srcdir)/emulparams/i386linux.sh \ + $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386linux "$(tdir_i386linux)" +ei386lynx.c: $(srcdir)/emulparams/i386lynx.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386lynx.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386lynx "$(tdir_i386lynx)" +ei386mach.c: $(srcdir)/emulparams/i386mach.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386mach "$(tdir_i386mach)" +ei386moss.c: $(srcdir)/emulparams/i386moss.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386moss "$(tdir_i386moss)" +ei386msdos.c: $(srcdir)/emulparams/i386msdos.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386msdos.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386msdos "$(tdir_i386msdos)" +ei386nbsd.c: $(srcdir)/emulparams/i386nbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386nbsd "$(tdir_i386nbsd)" +ei386nw.c: $(srcdir)/emulparams/i386nw.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/nw.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386nw "$(tdir_i386nw)" +ei386pe.c: $(srcdir)/emulparams/i386pe.sh \ + $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386pe "$(tdir_i386pe)" +elnk960.c: $(srcdir)/emulparams/lnk960.sh \ + $(srcdir)/emultempl/lnk960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS} + ${GENSCRIPTS} lnk960 "$(tdir_lnk960)" +em68k4knbsd.c: $(srcdir)/emulparams/m68k4knbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68k4knbsd "$(tdir_m68k4knbsd)" +em68kaout.c: $(srcdir)/emulparams/m68kaout.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kaout "$(tdir_m68kaout)" +em68kaux.c: $(srcdir)/emulparams/m68kaux.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kaux.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kaux "$(tdir_m68kaux)" +em68kcoff.c: $(srcdir)/emulparams/m68kcoff.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kcoff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kcoff "$(tdir_m68kcoff)" +em68kelf.c: $(srcdir)/emulparams/m68kelf.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kelf "$(tdir_m68kelf)" +em68klinux.c: $(srcdir)/emulparams/m68klinux.sh \ + $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68klinux "$(tdir_m68klinux)" +em68klynx.c: $(srcdir)/emulparams/m68klynx.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68klynx.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68klynx "$(tdir_m68klynx)" +em68knbsd.c: $(srcdir)/emulparams/m68knbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68knbsd "$(tdir_m68knbsd)" +em68kpsos.c: $(srcdir)/emulparams/m68kpsos.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/psos.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kpsos "$(tdir_m68kpsos)" +em88kbcs.c: $(srcdir)/emulparams/m88kbcs.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m88kbcs.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m88kbcs "$(tdir_m88kbcs)" +emcorepe.c: $(srcdir)/emulparams/mcorepe.sh \ + $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mcorepe "$(tdir_mcorepe)" +emipsbig.c: $(srcdir)/emulparams/mipsbig.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipsbig +emipsbsd.c: $(srcdir)/emulparams/mipsbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mipsbsd.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipsbsd +emipsidt.c: $(srcdir)/emulparams/mipsidt.sh \ + $(srcdir)/emultempl/mipsecoff.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipsidt "$(tdir_mipsidt)" +emipsidtl.c: $(srcdir)/emulparams/mipsidtl.sh \ + $(srcdir)/emultempl/mipsecoff.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipsidtl "$(tdir_mipsidtl)" +emipslit.c: $(srcdir)/emulparams/mipslit.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipslit "$(tdir_mipslit)" +emipslnews.c: $(srcdir)/emulparams/mipslnews.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipslnews +emn10300.c: $(srcdir)/emulparams/mn10300.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mn10300 "$(tdir_mn10300)" +emn10200.c: $(srcdir)/emulparams/mn10200.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mn10200 "$(tdir_mn10200)" +enews.c: $(srcdir)/emulparams/news.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} news "$(tdir_news)" +ens32knbsd.c: $(srcdir)/emulparams/ns32knbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ns32knbsd "$(tdir_ns32knbsd)" +epc532macha.c: $(srcdir)/emulparams/pc532macha.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} pc532macha "$(tdir_pc532macha)" +eppcmacos.c: $(srcdir)/emulparams/ppcmacos.sh \ + $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ppcmacos "$(tdir_ppcmacos)" +eppcnw.c: $(srcdir)/emulparams/ppcnw.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/nw.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ppcnw "$(tdir_ppcnw)" +eppcpe.c: $(srcdir)/emulparams/ppcpe.sh \ + $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/ppcpe.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ppcpe "$(tdir_ppcpe)" +eriscix.c: $(srcdir)/emulparams/riscix.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} riscix "$(tdir_riscix)" +esa29200.c: $(srcdir)/emulparams/sa29200.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sa29200.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sa29200 "$(tdir_sa29200)" +esh.c: $(srcdir)/emulparams/sh.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sh "$(tdir_sh)" +eshelf.c: $(srcdir)/emulparams/shelf.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} shelf "$(tdir_shelf)" +eshlelf.c: $(srcdir)/emulparams/shlelf.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} shlelf "$(tdir_shlelf)" +eshl.c: $(srcdir)/emulparams/shl.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS} + ${GENSCRIPTS} shl "$(tdir_shl)" +esparcaout.c: $(srcdir)/emulparams/sparcaout.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sparcaout "$(tdir_sparcaout)" +esparclinux.c: $(srcdir)/emulparams/sparclinux.sh \ + $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sparclinux "$(tdir_sparclinux)" +esparclynx.c: $(srcdir)/emulparams/sparclynx.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparclynx.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sparclynx "$(tdir_sparclynx)" +esparcnbsd.c: $(srcdir)/emulparams/sparcnbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sparcnbsd "$(tdir_sparcnbsd)" +est2000.c: $(srcdir)/emulparams/st2000.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/st2000.sc ${GEN_DEPENDS} + ${GENSCRIPTS} st2000 "$(tdir_st2000)" +esun3.c: $(srcdir)/emulparams/sun3.sh \ + $(srcdir)/emultempl/sunos.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sun3 "$(tdir_sun3)" +esun4.c: $(srcdir)/emulparams/sun4.sh \ + $(srcdir)/emultempl/sunos.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sun4 "$(tdir_sun4)" +etic30aout.c: $(srcdir)/emulparams/tic30aout.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic30aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} tic30aout "$(tdir_tic30aout)" +etic30coff.c: $(srcdir)/emulparams/tic30coff.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic30coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} tic30coff "$(tdir_tic30coff)" +etic80coff.c: $(srcdir)/emulparams/tic80coff.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic80coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} tic80coff "$(tdir_tic80coff)" +evanilla.c: $(srcdir)/emulparams/vanilla.sh \ + $(srcdir)/emultempl/vanilla.em $(srcdir)/scripttempl/vanilla.sc ${GEN_DEPENDS} + ${GENSCRIPTS} vanilla "$(tdir_vanilla)" +evax.c: $(srcdir)/emulparams/vax.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} vax "$(tdir_vax)" +evsta.c: $(srcdir)/emulparams/vsta.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} vsta "$(tdir_vsta)" +ev850.c: $(srcdir)/emulparams/v850.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/v850.sc ${GEN_DEPENDS} + ${GENSCRIPTS} v850 "$(tdir_v850)" +ew65.c: $(srcdir)/emulparams/w65.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS} + ${GENSCRIPTS} w65 "$(tdir_w65)" +ez8001.c: $(srcdir)/emulparams/z8001.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS} + ${GENSCRIPTS} z8001 "$(tdir_z8001)" +ez8002.c: $(srcdir)/emulparams/z8002.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS} + ${GENSCRIPTS} z8002 "$(tdir_z8002)" + +ld_new_SOURCES = ldgram.y ldlex.l lexsup.c ldlang.c mri.c ldctor.c ldmain.c \ + ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c +ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLDEPS) +ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLLIBS) + +# The generated emulation files mostly have the same dependencies. +$(EMULATION_OFILES): ../bfd/bfd.h sysdep.h config.h $(INCDIR)/bfdlink.h \ + ld.h ldmain.h ldemul.h ldfile.h ldmisc.h ldexp.h ldlang.h \ + ldctor.h ldexp.h ldlang.h ldgram.h + +# This is the real libbfd.a created by libtool. +TESTBFDLIB = @TESTBFDLIB@ + +check-DEJAGNU: site.exp + srcroot=`cd $(srcdir) && pwd`; export srcroot; \ + r=`pwd`; export r; \ + EXPECT=$(EXPECT); export EXPECT; \ + if [ -f $(top_builddir)/../expect/expect ]; then \ + TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \ + export TCL_LIBRARY; \ + fi; \ + runtest=$(RUNTEST); \ + if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \ + $$runtest --tool $(DEJATOOL) --srcdir $${srcroot}/testsuite \ + CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS)" \ + CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS)" \ + CC_FOR_HOST="$(CC)" CFLAGS_FOR_HOST="$(CFLAGS)" \ + OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" \ + LIBIBERTY="$(LIBIBERTY) $(INTLLIBS)" \ + $(RUNTESTFLAGS); \ + else echo "WARNING: could not find \`runtest'" 1>&2; :;\ + fi + +# Rules for testing by relinking ld itself. +# A similar test is in the testsuite. This target is for ease of use +# when porting ld. + +ld-partial.o: ld-new$(EXEEXT) + ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld-partial.o -r $(OFILES) +ld1$(EXEEXT): ld-partial.o + ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld1$(EXEEXT) $(HOSTING_CRT0) ld-partial.o $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + +ld1-full$(EXEEXT): ld-new + ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld1-full$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + +ld2$(EXEEXT): ld1$(EXEEXT) + ./ld1$(EXEEXT) $(HOSTING_EMU) -o ld2$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + +ld3$(EXEEXT): ld2$(EXEEXT) + ./ld2$(EXEEXT) $(HOSTING_EMU) -o ld3$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + +bootstrap: ld3$(EXEEXT) + cmp ld2$(EXEEXT) ld3$(EXEEXT) + +.PHONY: bootstrap + +# A test program for C++ constructors and destructors. +# This test is now in the testsuite. +# +#cdtest: cdtest-main.o cdtest-bar.o cdtest-foo.o ld.new +# ./ld.new $(HOSTING_EMU) -o cdtest $(HOSTING_CRT0) \ +# cdtest-main.o cdtest-bar.o cdtest-foo.o $(HOSTING_LIBS) +# +#cdtest.out: cdtest +# ./cdtest > cdtest.tmp +# mv cdtest.tmp cdtest.out +# +#cdtest-ur.o: cdtest-main.o cdtest-bar.o cdtest-foo.o ld.new +# ./ld.new $(HOSTING_EMU) -o cdtest-ur.o -Ur cdtest-main.o \ +# cdtest-bar.o cdtest-foo.o +# +#cdtest-ur: cdtest-ur.o +# ./ld.new $(HOSTING_EMU) -o cdtest-ur $(HOSTING_CRT0) cdtest-ur.o \ +# $(HOSTING_LIBS) +# +#cdtest-ur.out: cdtest-ur +# ./cdtest-ur > cdtest-ur.tmp +# mv cdtest-ur.tmp cdtest-ur.out +# +#check-cdtest: cdtest.out cdtest-ur.out $(srcdir)/cdtest.exp +# diff $(srcdir)/cdtest.exp cdtest.out +# diff $(srcdir)/cdtest.exp cdtest-ur.out +# +#.PHONY: check-cdtest + +# END OF CHECK TARGETS + +# DOCUMENTATION TARGETS +# Manual configuration file; not usually attached to normal configuration, +# because almost all configs use "gen" version of manual. +# Set DOCVER above to change. +configdoc.texi: ${DOCVER}-doc.texi + ln -s ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi >/dev/null 2>&1 \ + || ln ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi >/dev/null 2>&1 \ + || cp ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi + +ldver.texi: Makefile + rm -f $@ + echo '@set VERSION $(VERSION)' > $@ + +ld.info: $(srcdir)/ld.texinfo configdoc.texi ldver.texi + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) -I $(BFDDIR)/doc $(srcdir)/ld.texinfo + +ld.dvi: $(srcdir)/ld.texinfo configdoc.texi ldver.texi + TEXINPUTS=$(top_srcdir)/../texinfo:$$TEXINPUTS \ + MAKEINFO="$(MAKEINFO) -I $(srcdir) -I $(BFDDIR)/doc" $(TEXI2DVI) $(srcdir)/ld.texinfo + +MAINTAINERCLEANFILES = ldver.texi + +# We want to reconfigure if configure.host or configure.tgt changes. +config.status: $(srcdir)/configure $(srcdir)/configure.host $(srcdir)/configure.tgt + $(SHELL) ./config.status --recheck + +MOSTLYCLEANFILES = $(STAGESTUFF) ld1$(EXEEXT) ld2$(EXEEXT) ld3$(EXEEXT) \ + ldemul-list.h crtbegin.o crtend.o ld.log ld.sum +mostlyclean-local: + -rm -rf tmpdir +CLEANFILES = dep.sed .dep .dep1 + +.PHONY: install-exec-local install-data-local + +install-exec-local: ld-new$(EXEEXT) + $(mkinstalldirs) $(bindir) $(tooldir)/bin + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + n=`echo ld | sed '$(transform)'`; \ + if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/ld$(EXEEXT)" ]; then \ + rm -f $(tooldir)/bin/ld$(EXEEXT); \ + ln $(bindir)/$$n$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT); \ + fi + +install-data-local: + $(mkinstalldirs) $(scriptdir)/ldscripts + for f in ldscripts/*; do \ + $(INSTALL_DATA) $$f $(scriptdir)/$$f ; \ + done + +# Stuff that should be included in a distribution. The diststuff +# target is run by the taz target in ../Makefile.in. +LDDISTSTUFF = ldgram.c ldgram.h ldlex.c +diststuff: $(LDDISTSTUFF) info + +DISTCLEANFILES = tdirs site.exp site.bak +distclean-local: + rm -rf ldscripts + +# Targets to rebuild dependencies in this Makefile. +# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES). +.dep: dep.sed $(CFILES) $(HFILES) $(GENERATED_CFILES) $(GENERATED_HFILES) config.h + rm -f .dep1 + $(MAKE) DEP=$(DEP) .dep1 + sed -f dep.sed <.dep1 >.dep + +# This rule really wants a mkdep that runs "gcc -MM". +.dep1: $(CFILES) $(GENERATED_CFILES) + rm -f .dep2 + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2 + $(DEP) -f .dep2 $(INCLUDES) $? + $(srcdir)/../move-if-change .dep2 .dep1 + +dep.sed: dep-in.sed config.status + sed <$(srcdir)/dep-in.sed >dep.sed \ + -e 's!@INCDIR@!$(INCDIR)!' \ + -e 's!@SRCDIR@!$(srcdir)!' + +dep: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile + cat .dep >> tmp-Makefile + $(srcdir)/../move-if-change tmp-Makefile Makefile + +dep-in: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in + cat .dep >> tmp-Makefile.in + $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in + +dep-am: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am + cat .dep >> tmp-Makefile.am + $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am + +.PHONY: dep dep-in dep-am + +# What appears below is generated by a hacked mkdep using gcc -MM. + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +ldctor.o: ldctor.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + ld.h ldexp.h ldlang.h ldmisc.h ldgram.h ldmain.h ldctor.h +ldemul.o: ldemul.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldemul.h \ + ldmisc.h ldexp.h ldlang.h ldfile.h ldmain.h ldemul-list.h +ldexp.o: ldexp.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + ld.h ldmain.h ldmisc.h ldexp.h ldgram.h ldlang.h +ldfile.o: ldfile.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + ld.h ldmisc.h ldexp.h ldlang.h ldfile.h ldmain.h ldgram.h \ + ldlex.h ldemul.h +ldlang.o: ldlang.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \ + $(INCDIR)/obstack.h $(INCDIR)/bfdlink.h ld.h ldmain.h \ + ldgram.h ldexp.h ldlang.h ldemul.h ldlex.h ldmisc.h \ + ldctor.h ldfile.h $(INCDIR)/fnmatch.h +ldmain.o: ldmain.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \ + $(INCDIR)/progress.h $(INCDIR)/bfdlink.h ld.h ldmain.h \ + ldmisc.h ldwrite.h ldgram.h ldexp.h ldlang.h ldemul.h \ + ldlex.h ldfile.h ldctor.h +ldmisc.o: ldmisc.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \ + $(INCDIR)/demangle.h ld.h ldmisc.h ldexp.h ldlang.h \ + ldgram.h ldlex.h ldmain.h ldfile.h +ldver.o: ldver.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldver.h \ + ldemul.h ldmain.h +ldwrite.o: ldwrite.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/libiberty.h ld.h ldexp.h ldlang.h ldwrite.h \ + ldmisc.h ldgram.h ldmain.h +lexsup.o: lexsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \ + $(INCDIR)/getopt.h $(INCDIR)/bfdlink.h ld.h ldmain.h \ + ldmisc.h ldexp.h ldlang.h ldgram.h ldlex.h ldfile.h \ + ldver.h ldemul.h +mri.o: mri.c ../bfd/bfd.h $(INCDIR)/ansidecl.h sysdep.h \ + config.h $(INCDIR)/fopen-same.h ld.h ldexp.h ldlang.h \ + ldmisc.h mri.h ldgram.h $(INCDIR)/libiberty.h +ldcref.o: ldcref.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/libiberty.h ld.h ldmain.h ldmisc.h ldexp.h \ + ldlang.h +pe-dll.o: pe-dll.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/libiberty.h ld.h ldexp.h ldlang.h ldwrite.h \ + ldmisc.h ldgram.h ldmain.h ldemul.h $(INCDIR)/coff/internal.h \ + ../bfd/libcoff.h deffile.h +ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + ld.h ldexp.h ldver.h ldlang.h ldemul.h ldfile.h ldmisc.h \ + ldmain.h mri.h ldctor.h ldlex.h +ldlex.o: ldlex.c ../bfd/bfd.h sysdep.h config.h $(INCDIR)/fopen-same.h \ + ld.h ldgram.h ldmisc.h ldexp.h ldlang.h ldfile.h ldlex.h \ + ldmain.h +deffilep.o: deffilep.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + ../bfd/bfd.h sysdep.h config.h $(INCDIR)/fopen-same.h \ + ld.h ldmisc.h deffile.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/ld/Makefile.in b/ld/Makefile.in new file mode 100644 index 0000000..e5961ae --- /dev/null +++ b/ld/Makefile.in @@ -0,0 +1,1546 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +EXEEXT = @EXEEXT@ +EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +HDEFINES = @HDEFINES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NATIVE_LIB_DIRS = @NATIVE_LIB_DIRS@ +NM = @NM@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@ +VERSION = @VERSION@ +l = @l@ + +INTLLIBS = @INTLLIBS@ + +AUTOMAKE_OPTIONS = cygnus dejagnu + +SUBDIRS = po + +tooldir = $(exec_prefix)/$(target_alias) + +YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L$(srcdir)/../bison/ ; else echo bison -y ; fi` +YFLAGS = -d +LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi` + +# We put the scripts in the directory $(scriptdir)/ldscripts. +# We can't put the scripts in $(datadir) because the SEARCH_DIR +# directives need to be different for native and cross linkers. +scriptdir = $(tooldir)/lib + +EMUL = @EMUL@ +EMULATION_OFILES = @EMULATION_OFILES@ +EMUL_EXTRA_OFILES = @EMUL_EXTRA_OFILES@ + +# Search path to override the default search path for -lfoo libraries. +# If LIB_PATH is empty, the ones in the script (if any) are left alone. +# (The default is usually /lib:/usr/lib:/usr/local/lib, unless building +# a cross-linker, in which case the default is empty. See genscripts.sh.) +# Otherwise, they are replaced with the ones given in LIB_PATH, +# which may have the form: LIB_PATH=/lib:/usr/local/lib +LIB_PATH = + +BASEDIR = $(srcdir)/.. +BFDDIR = $(BASEDIR)/bfd +INCDIR = $(BASEDIR)/include +DEP = mkdep + +# What version of the manual to build +DOCVER = gen + +#stuff for self hosting (can be overridden in config file). +HOSTING_CRT0 = @HOSTING_CRT0@ +HOSTING_LIBS = @HOSTING_LIBS@ +HOSTING_EMU = -m $(EMUL) + +# Setup the testing framework, if you have one +EXPECT = `if [ -f $$r/../expect/expect ] ; \ + then echo $$r/../expect/expect ; \ + else echo expect ; fi` + + +RUNTEST = `if [ -f $${srcroot}/../dejagnu/runtest ] ; \ + then echo $${srcroot}/../dejagnu/runtest ; \ + else echo runtest ; fi` + + +RUNTESTFLAGS = + +CC_FOR_TARGET = ` \ + if [ -f $$r/../gcc/xgcc ] ; then \ + if [ -f $$r/../newlib/Makefile ] ; then \ + echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \ + else \ + echo $$r/../gcc/xgcc -B$$r/../gcc/; \ + fi; \ + else \ + if [ "@host@" = "@target@" ] ; then \ + echo $(CC); \ + else \ + echo gcc | sed '$(transform)'; \ + fi; \ + fi` + + +CXX = gcc +CXX_FOR_TARGET = ` \ + if [ -f $$r/../gcc/xgcc ] ; then \ + if [ -f $$r/../newlib/Makefile ] ; then \ + echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \ + else \ + echo $$r/../gcc/xgcc -B$$r/../gcc/; \ + fi; \ + else \ + if [ "@host@" = "@target@" ] ; then \ + echo $(CXX); \ + else \ + echo gcc | sed '$(transform)'; \ + fi; \ + fi` + + +noinst_PROGRAMS = ld-new +info_TEXINFOS = ld.texinfo +noinst_TEXINFOS = ldint.texinfo +man_MANS = ld.1 + +INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) -I$(top_srcdir)/../intl -I../intl $(HDEFINES) $(CFLAGS) -DLOCALEDIR="\"$(prefix)/share/locale\"" + +BFDLIB = ../bfd/libbfd.la +LIBIBERTY = ../libiberty/libiberty.a + +ALL_EMULATIONS = \ + ea29k.o \ + eaixppc.o \ + eaixrs6.o \ + ealpha.o \ + earcelf.o \ + earmelf.o \ + earmelf_oabi.o \ + earmlinux.o \ + earm26linux.o \ + earmaoutb.o \ + earmaoutl.o \ + earmcoff.o \ + earmpe.o \ + ecoff_sparc.o \ + ed10velf.o \ + ed30velf.o \ + ed30v_e.o \ + ed30v_o.o \ + edelta68.o \ + eebmon29k.o \ + eelf32_sparc.o \ + eelf32b4300.o \ + eelf32bmip.o \ + eelf32ebmip.o \ + eelf32elmip.o \ + eelf32l4300.o \ + eelf32lmip.o \ + eelf32lppc.o \ + eelf32ppc.o \ + eelf_i386.o \ + eelf_i386_be.o \ + egld960.o \ + egld960coff.o \ + eelf32fr30.o \ + eelf32mcore.o \ + ego32.o \ + eh8300.o \ + eh8300h.o \ + eh8300s.o \ + eh8500.o \ + eh8500b.o \ + eh8500c.o \ + eh8500m.o \ + eh8500s.o \ + ehp300bsd.o \ + ehp3hpux.o \ + ehppaelf.o \ + ei386aout.o \ + ei386beos.o \ + ei386bsd.o \ + ei386coff.o \ + ei386go32.o \ + ei386linux.o \ + ei386lynx.o \ + ei386mach.o \ + ei386moss.o \ + ei386msdos.o \ + ei386nbsd.o \ + ei386nw.o \ + ei386pe.o \ + elnk960.o \ + em68k4knbsd.o \ + em68kaout.o \ + em68kaux.o \ + em68kcoff.o \ + em68kelf.o \ + em68klinux.o \ + em68klynx.o \ + em68knbsd.o \ + em68kpsos.o \ + em88kbcs.o \ + emcorepe.o \ + emipsbig.o \ + emipsbsd.o \ + emipsidt.o \ + emipsidtl.o \ + emipslit.o \ + emipslnews.o \ + enews.o \ + ens32knbsd.o \ + epc532macha.o \ + eppcmacos.o \ + eppcnw.o \ + eppcpe.o \ + eriscix.o \ + esa29200.o \ + esh.o \ + eshelf.o \ + eshlelf.o \ + eshl.o \ + esparcaout.o \ + esparclinux.o \ + esparclynx.o \ + esparcnbsd.o \ + est2000.o \ + esun3.o \ + esun4.o \ + etic30aout.o \ + etic30coff.o \ + etic80coff.o \ + evanilla.o \ + evax.o \ + evsta.o \ + ew65.o \ + ez8001.o \ + ez8002.o + + +ALL_64_EMULATIONS = \ + eelf64_sparc.o \ + eelf64alpha.o + + +ALL_EMUL_EXTRA_OFILES = \ + pe-dll.o \ + deffilep.o + + +CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \ + ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \ + mri.c ldcref.c pe-dll.c + + +HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \ + ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \ + ldwrite.h mri.h deffile.h + + +GENERATED_CFILES = ldgram.c ldlex.c deffilep.c +GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h + +OFILES = ldgram.o ldlex.o lexsup.o ldlang.o mri.o ldctor.o ldmain.o \ + ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o \ + ldfile.o ldcref.o ${EMULATION_OFILES} ${EMUL_EXTRA_OFILES} + + +STAGESTUFF = *.o ldscripts/* e*.c + +# At the moment this is just a list of those emulation template files +# that contain internationalised strings. +EMULATION_FILES = emultempl/pe.em emultempl/armcoff.em + +POTFILES = $(CFILES) $(HFILES) $(EMULATION_FILES) + +# These all start with e so 'make clean' can find them. + +GENSCRIPTS = $(SHELL) $(srcdir)/genscripts.sh ${srcdir} ${libdir} @host@ @target@ @target_alias@ ${EMUL} "@NATIVE_LIB_DIRS@" +GEN_DEPENDS = $(srcdir)/genscripts.sh $(srcdir)/emultempl/stringify.sed + +ld_new_SOURCES = ldgram.y ldlex.l lexsup.c ldlang.c mri.c ldctor.c ldmain.c \ + ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c + +ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLDEPS) +ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLLIBS) + +# This is the real libbfd.a created by libtool. +TESTBFDLIB = @TESTBFDLIB@ + +MAINTAINERCLEANFILES = ldver.texi + +MOSTLYCLEANFILES = $(STAGESTUFF) ld1$(EXEEXT) ld2$(EXEEXT) ld3$(EXEEXT) \ + ldemul-list.h crtbegin.o crtend.o ld.log ld.sum + +CLEANFILES = dep.sed .dep .dep1 + +# Stuff that should be included in a distribution. The diststuff +# target is run by the taz target in ../Makefile.in. +LDDISTSTUFF = ldgram.c ldgram.h ldlex.c + +DISTCLEANFILES = tdirs site.exp site.bak +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +noinst_PROGRAMS = ld-new$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +ld_new_OBJECTS = ldgram.o ldlex.o lexsup.o ldlang.o mri.o ldctor.o \ +ldmain.o ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o ldfile.o ldcref.o +ld_new_LDFLAGS = +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LEXLIB = @LEXLIB@ +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then echo $(top_srcdir)/../texinfo/util/texi2dvi; else echo texi2dvi; fi` +TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex +INFO_DEPS = ld.info +DVIS = ld.dvi +TEXINFOS = ld.texinfo +man1dir = $(mandir)/man1 +MANS = $(man_MANS) + +NROFF = nroff +DIST_COMMON = README ./stamp-h.in ChangeLog Makefile.am Makefile.in \ +NEWS TODO acinclude.m4 aclocal.m4 config.in configure configure.in \ +ldgram.c ldlex.c + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(ld_new_SOURCES) +OBJECTS = $(ld_new_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .dvi .info .l .lo .o .ps .s .texi .texinfo .txi .y +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +config.h: stamp-h + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi +stamp-h: $(srcdir)/config.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \ + $(SHELL) ./config.status + @echo timestamp > stamp-h 2> /dev/null +$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f config.h + +maintainer-clean-hdr: + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +ld-new$(EXEEXT): $(ld_new_OBJECTS) $(ld_new_DEPENDENCIES) + @rm -f ld-new$(EXEEXT) + $(LINK) $(ld_new_LDFLAGS) $(ld_new_OBJECTS) $(ld_new_LDADD) $(LIBS) +.l.c: + $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@ +.y.c: + $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c + if test -f y.tab.h; then \ + if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \ + else :; fi +ldgram.h: ldgram.c + + +ld.info: ld.texinfo +ld.dvi: ld.texinfo + + +DVIPS = dvips + +.texi.info: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.texi.dvi: + TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.texi: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.texinfo.info: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.texinfo: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.texinfo.dvi: + TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi.info: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< + +.txi.dvi: + TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) $< +.dvi.ps: + $(DVIPS) $< -o $@ + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(infodir) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ + if test -f $$d/$$ifile; then \ + echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \ + $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \ + else : ; fi; \ + done; \ + done + @$(POST_INSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\ + install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\ + done; \ + else : ; fi + +uninstall-info: + $(PRE_UNINSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + ii=yes; \ + else ii=; fi; \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + test -z "$ii" \ + || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \ + done + @$(NORMAL_UNINSTALL) + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \ + done + +dist-info: $(INFO_DEPS) + list='$(INFO_DEPS)'; \ + for base in $$list; do \ + if test -f $$base; then d=.; else d=$(srcdir); fi; \ + for file in `cd $$d && eval echo $$base*`; do \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done; \ + done + +mostlyclean-aminfo: + -rm -f ld.aux ld.cp ld.cps ld.dvi ld.fn ld.fns ld.ky ld.kys ld.ps \ + ld.log ld.pg ld.toc ld.tp ld.tps ld.vr ld.vrs ld.op ld.tr \ + ld.cv ld.cn + +clean-aminfo: + +distclean-aminfo: + +maintainer-clean-aminfo: + for i in $(INFO_DEPS); do \ + rm -f $$i; \ + if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \ + rm -f $$i-[0-9]*; \ + fi; \ + done +clean-info: mostlyclean-aminfo + +install-man1: + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done + +uninstall-man1: + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-man1 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-man1 + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive install-info-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info + +DEJATOOL = $(PACKAGE) + +RUNTESTDEFAULTFLAGS = --tool $(DEJATOOL) --srcdir $$srcdir +site.exp: Makefile + @echo 'Making a new site.exp file...' + @test ! -f site.bak || rm -f site.bak + @echo '## these variables are automatically generated by make ##' > $@-t + @echo '# Do not edit here. If you wish to override these values' >> $@-t + @echo '# edit the last section' >> $@-t + @echo 'set tool $(DEJATOOL)' >> $@-t + @echo 'set srcdir $(srcdir)' >> $@-t + @echo 'set objdir' `pwd` >> $@-t + @echo 'set host_alias $(host_alias)' >> $@-t + @echo 'set host_triplet $(host_triplet)' >> $@-t + @echo 'set target_alias $(target_alias)' >> $@-t + @echo 'set target_triplet $(target_triplet)' >> $@-t + @echo 'set build_alias $(build_alias)' >> $@-t + @echo 'set build_triplet $(build_triplet)' >> $@-t + @echo '## All variables above are generated by configure. Do Not Edit ##' >> $@-t + @test ! -f site.exp || sed '1,/^## All variables above are.*##/ d' site.exp >> $@-t + @test ! -f site.exp || mv site.exp site.bak + @mv $@-t site.exp +info-am: $(INFO_DEPS) +info: info-recursive +dvi-am: $(DVIS) +dvi: dvi-recursive +check-am: + $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-info-am: +install-info: install-info-recursive +all-recursive-am: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +install-exec-am: install-exec-local +install-exec: install-exec-recursive + +install-data-am: install-man install-data-local +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-man +uninstall: uninstall-recursive +all-am: Makefile $(PROGRAMS) $(MANS) config.h +all-redirect: all-recursive-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(mandir)/man1 + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + -test -z "ldlexlldgramhldgramc$(MAINTAINERCLEANFILES)" || rm -f ldlexl ldgramh ldgramc $(MAINTAINERCLEANFILES) +mostlyclean-am: mostlyclean-hdr mostlyclean-noinstPROGRAMS \ + mostlyclean-compile mostlyclean-libtool \ + mostlyclean-aminfo mostlyclean-tags mostlyclean-generic \ + mostlyclean-local + +mostlyclean: mostlyclean-recursive + +clean-am: clean-hdr clean-noinstPROGRAMS clean-compile clean-libtool \ + clean-aminfo clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-hdr distclean-noinstPROGRAMS distclean-compile \ + distclean-libtool distclean-aminfo distclean-tags \ + distclean-generic clean-am distclean-local + -rm -f libtool + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-hdr \ + maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-aminfo maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool install-info-am uninstall-info \ +mostlyclean-aminfo distclean-aminfo clean-aminfo \ +maintainer-clean-aminfo install-man1 uninstall-man1 install-man \ +uninstall-man install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir check-DEJAGNU \ +info-am info dvi-am dvi check check-am installcheck-am installcheck \ +install-info-am install-info all-recursive-am install-exec-local \ +install-exec-am install-exec install-data-local install-data-am \ +install-data install-am install uninstall-am uninstall all-redirect \ +all-am all installdirs-am installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +po/POTFILES.in: @MAINT@ Makefile + for file in $(POTFILES); do echo $$file; done | sort > tmp \ + && mv tmp $(srcdir)/po/POTFILES.in + +ldmain.o: ldmain.c config.status + $(COMPILE) -c -DDEFAULT_EMULATION='"$(EMUL)"' -DSCRIPTDIR='"$(scriptdir)"' -DTARGET='"@target@"' $(srcdir)/ldmain.c + +ldemul-list.h: Makefile + (echo "/* This file is automatically generated. DO NOT EDIT! */";\ + for f in `echo " " ${EMULATION_OFILES} "" \ + | sed -e 's/ e/ ld/g' -e 's/ ld/ /g' -e 's/[.]o//g'`; do \ + echo "extern ld_emulation_xfer_type ld_$${f}_emulation;"; \ + done;\ + echo "";\ + echo "#define EMULATION_LIST \\";\ + for f in `echo " " ${EMULATION_OFILES} "" \ + | sed -e 's/ e/ ld/g' -e 's/ ld/ /g' -e 's/[.]o//g'`; do \ + echo " &ld_$${f}_emulation, \\"; \ + done;\ + echo " 0") >ldemul-tmp.h + mv ldemul-tmp.h ldemul-list.h +@TDIRS@ + +ea29k.c: $(srcdir)/emulparams/a29k.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/a29k.sc ${GEN_DEPENDS} + ${GENSCRIPTS} a29k "$(tdir_a29k)" +eaixppc.c: $(srcdir)/emulparams/aixppc.sh \ + $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS} + ${GENSCRIPTS} aixppc "$(tdir_aixppc)" +eaixrs6.c: $(srcdir)/emulparams/aixrs6.sh \ + $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS} + ${GENSCRIPTS} aixrs6 "$(tdir_aixrs6)" +ealpha.c: $(srcdir)/emulparams/alpha.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/alpha.sc ${GEN_DEPENDS} + ${GENSCRIPTS} alpha "$(tdir_alpha)" +earcelf.c: $(srcdir)/emulparams/arcelf.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} arcelf "$(tdir_arcelf)" +earmelf.c: $(srcdir)/emulparams/armelf.sh \ + $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf "$(tdir_armelf)" +earmelf_oabi.c: $(srcdir)/emulparams/armelf_oabi.sh \ + $(srcdir)/emultempl/armelf_oabi.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf_oabi "$(tdir_armelf)" +earmelf_linux.c: $(srcdir)/emulparams/armelf_linux.sh \ + $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf_linux "$(tdir_armelf_linux)" +earmelf_linux26.c: $(srcdir)/emulparams/armelf_linux26.sh \ + $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armelf_linux26 "$(tdir_armelf_linux26)" +earmaoutb.c: $(srcdir)/emulparams/armaoutb.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/armaout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armaoutb "$(tdir_armaoutb)" +earmaoutl.c: $(srcdir)/emulparams/armaoutl.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/armaout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armaoutl "$(tdir_armaoutl)" +earmcoff.c: $(srcdir)/emulparams/armcoff.sh \ + $(srcdir)/emultempl/armcoff.em $(srcdir)/scripttempl/armcoff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armcoff "$(tdir_armcoff)" +earmpe.c: $(srcdir)/emulparams/armpe.sh \ + $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS} + ${GENSCRIPTS} armpe "$(tdir_armpe)" +ecoff_sparc.c: $(srcdir)/emulparams/coff_sparc.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparccoff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} coff_sparc "$(tdir_coff_sparc)" +ed10velf.c: $(srcdir)/emulparams/d10velf.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd10v.sc ${GEN_DEPENDS} + ${GENSCRIPTS} d10velf "$(tdir_d10v)" +ed30velf.c: $(srcdir)/emulparams/d30velf.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS} + ${GENSCRIPTS} d30velf "$(tdir_d30v)" +ed30v_o.c: $(srcdir)/emulparams/d30v_o.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS} + ${GENSCRIPTS} d30v_o "$(tdir_d30v)" +ed30v_e.c: $(srcdir)/emulparams/d30v_e.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS} + ${GENSCRIPTS} d30v_e "$(tdir_d30v)" +edelta68.c: $(srcdir)/emulparams/delta68.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/delta68.sc ${GEN_DEPENDS} + ${GENSCRIPTS} delta68 "$(tdir_delta68)" +eebmon29k.c: $(srcdir)/emulparams/ebmon29k.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/ebmon29k.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ebmon29k "$(tdir_ebmon29k)" +eelf32fr30.c: $(srcdir)/emulparams/elf32fr30.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32fr30 "$(tdir_fr30)" +eelf32mcore.c: $(srcdir)/emulparams/elf32mcore.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32mcore "$(tdir_mcore)" +em32relf.c: $(srcdir)/emulparams/m32relf.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m32relf "$(tdir_m32r)" +eelf32_sparc.c: $(srcdir)/emulparams/elf32_sparc.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32_sparc "$(tdir_elf32_sparc)" +eelf32b4300.c: $(srcdir)/emulparams/elf32b4300.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32b4300 "$(tdir_elf32b4300)" +eelf32bmip.c: $(srcdir)/emulparams/elf32bmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32bmip "$(tdir_elf32bmip)" +eelf32bsmip.c: $(srcdir)/emulparams/elf32bsmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32bsmip "$(tdir_elf32bsmip)" +eelf32ebmip.c: $(srcdir)/emulparams/elf32ebmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32ebmip "$(tdir_elf32ebmip)" +eelf32elmip.c: $(srcdir)/emulparams/elf32elmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32elmip "$(tdir_elf32elmip)" +eelf32l4300.c: $(srcdir)/emulparams/elf32l4300.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32l4300 "$(tdir_elf32l4300)" +eelf32lmip.c: $(srcdir)/emulparams/elf32lmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32lmip "$(tdir_elf32lmip)" +eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfppc.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32lppc "$(tdir_elf32lppc)" +eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32lsmip "$(tdir_elf32lsmip)" +eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfppc.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32ppc "$(tdir_elf32ppc)" +eelf64alpha.c: $(srcdir)/emulparams/elf64alpha.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf64alpha "$(tdir_elf64alpha)" +eelf64_sparc.c: $(srcdir)/emulparams/elf64_sparc.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf64_sparc "$(tdir_elf64_sparc)" +eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_i386 "$(tdir_elf_i386)" +eelf_i386_be.c: $(srcdir)/emulparams/elf_i386_be.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_i386_be "$(tdir_elf_i386_be)" +egld960.c: $(srcdir)/emulparams/gld960.sh \ + $(srcdir)/emultempl/gld960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS} + ${GENSCRIPTS} gld960 "$(tdir_gld960)" +egld960coff.c: $(srcdir)/emulparams/gld960coff.sh \ + $(srcdir)/emultempl/gld960c.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS} + ${GENSCRIPTS} gld960coff "$(tdir_gld960coff)" +ego32.c: $(srcdir)/emulparams/go32.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} go32 "$(tdir_go32)" +eh8300.c: $(srcdir)/emulparams/h8300.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8300 "$(tdir_h8300)" +eh8300h.c: $(srcdir)/emulparams/h8300h.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300h.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8300h "$(tdir_h8300h)" +eh8300s.c: $(srcdir)/emulparams/h8300s.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300s.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8300s "$(tdir_h8300s)" +eh8500.c: $(srcdir)/emulparams/h8500.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500 "$(tdir_h8500)" +eh8500b.c: $(srcdir)/emulparams/h8500b.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500b.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500b "$(tdir_h8500b)" +eh8500c.c: $(srcdir)/emulparams/h8500c.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500c.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500c "$(tdir_h8500c)" +eh8500m.c: $(srcdir)/emulparams/h8500m.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500m.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500m "$(tdir_h8500m)" +eh8500s.c: $(srcdir)/emulparams/h8500s.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500s.sc ${GEN_DEPENDS} + ${GENSCRIPTS} h8500s "$(tdir_h8500s)" +ehp300bsd.c: $(srcdir)/emulparams/hp300bsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} hp300bsd "$(tdir_hp300bsd)" +ehp3hpux.c: $(srcdir)/emulparams/hp3hpux.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} hp3hpux "$(tdir_hp3hpux)" +ehppaelf.c: $(srcdir)/emulparams/hppaelf.sh \ + $(srcdir)/emultempl/hppaelf.em $(srcdir)/scripttempl/hppaelf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} hppaelf "$(tdir_hppaelf)" +ei386aout.c: $(srcdir)/emulparams/i386aout.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386aout "$(tdir_i386aout)" +ei386beos.c: $(srcdir)/emulparams/i386beos.sh \ + $(srcdir)/emultempl/beos.em $(srcdir)/scripttempl/i386beos.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386beos "$(tdir_i386beos)" +ei386bsd.c: $(srcdir)/emulparams/i386bsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386bsd "$(tdir_i386bsd)" +ei386coff.c: $(srcdir)/emulparams/i386coff.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386coff "$(tdir_i386coff)" +ei386go32.c: $(srcdir)/emulparams/i386go32.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386go32.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386go32 "$(tdir_i386go32)" +ei386linux.c: $(srcdir)/emulparams/i386linux.sh \ + $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386linux "$(tdir_i386linux)" +ei386lynx.c: $(srcdir)/emulparams/i386lynx.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386lynx.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386lynx "$(tdir_i386lynx)" +ei386mach.c: $(srcdir)/emulparams/i386mach.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386mach "$(tdir_i386mach)" +ei386moss.c: $(srcdir)/emulparams/i386moss.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386moss "$(tdir_i386moss)" +ei386msdos.c: $(srcdir)/emulparams/i386msdos.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386msdos.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386msdos "$(tdir_i386msdos)" +ei386nbsd.c: $(srcdir)/emulparams/i386nbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386nbsd "$(tdir_i386nbsd)" +ei386nw.c: $(srcdir)/emulparams/i386nw.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/nw.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386nw "$(tdir_i386nw)" +ei386pe.c: $(srcdir)/emulparams/i386pe.sh \ + $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386pe "$(tdir_i386pe)" +elnk960.c: $(srcdir)/emulparams/lnk960.sh \ + $(srcdir)/emultempl/lnk960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS} + ${GENSCRIPTS} lnk960 "$(tdir_lnk960)" +em68k4knbsd.c: $(srcdir)/emulparams/m68k4knbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68k4knbsd "$(tdir_m68k4knbsd)" +em68kaout.c: $(srcdir)/emulparams/m68kaout.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kaout "$(tdir_m68kaout)" +em68kaux.c: $(srcdir)/emulparams/m68kaux.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kaux.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kaux "$(tdir_m68kaux)" +em68kcoff.c: $(srcdir)/emulparams/m68kcoff.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kcoff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kcoff "$(tdir_m68kcoff)" +em68kelf.c: $(srcdir)/emulparams/m68kelf.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kelf "$(tdir_m68kelf)" +em68klinux.c: $(srcdir)/emulparams/m68klinux.sh \ + $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68klinux "$(tdir_m68klinux)" +em68klynx.c: $(srcdir)/emulparams/m68klynx.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68klynx.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68klynx "$(tdir_m68klynx)" +em68knbsd.c: $(srcdir)/emulparams/m68knbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68knbsd "$(tdir_m68knbsd)" +em68kpsos.c: $(srcdir)/emulparams/m68kpsos.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/psos.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kpsos "$(tdir_m68kpsos)" +em88kbcs.c: $(srcdir)/emulparams/m88kbcs.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m88kbcs.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m88kbcs "$(tdir_m88kbcs)" +emcorepe.c: $(srcdir)/emulparams/mcorepe.sh \ + $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mcorepe "$(tdir_mcorepe)" +emipsbig.c: $(srcdir)/emulparams/mipsbig.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipsbig +emipsbsd.c: $(srcdir)/emulparams/mipsbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mipsbsd.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipsbsd +emipsidt.c: $(srcdir)/emulparams/mipsidt.sh \ + $(srcdir)/emultempl/mipsecoff.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipsidt "$(tdir_mipsidt)" +emipsidtl.c: $(srcdir)/emulparams/mipsidtl.sh \ + $(srcdir)/emultempl/mipsecoff.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipsidtl "$(tdir_mipsidtl)" +emipslit.c: $(srcdir)/emulparams/mipslit.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipslit "$(tdir_mipslit)" +emipslnews.c: $(srcdir)/emulparams/mipslnews.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mipslnews +emn10300.c: $(srcdir)/emulparams/mn10300.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mn10300 "$(tdir_mn10300)" +emn10200.c: $(srcdir)/emulparams/mn10200.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} mn10200 "$(tdir_mn10200)" +enews.c: $(srcdir)/emulparams/news.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} news "$(tdir_news)" +ens32knbsd.c: $(srcdir)/emulparams/ns32knbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ns32knbsd "$(tdir_ns32knbsd)" +epc532macha.c: $(srcdir)/emulparams/pc532macha.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} pc532macha "$(tdir_pc532macha)" +eppcmacos.c: $(srcdir)/emulparams/ppcmacos.sh \ + $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ppcmacos "$(tdir_ppcmacos)" +eppcnw.c: $(srcdir)/emulparams/ppcnw.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/nw.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ppcnw "$(tdir_ppcnw)" +eppcpe.c: $(srcdir)/emulparams/ppcpe.sh \ + $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/ppcpe.sc ${GEN_DEPENDS} + ${GENSCRIPTS} ppcpe "$(tdir_ppcpe)" +eriscix.c: $(srcdir)/emulparams/riscix.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} riscix "$(tdir_riscix)" +esa29200.c: $(srcdir)/emulparams/sa29200.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sa29200.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sa29200 "$(tdir_sa29200)" +esh.c: $(srcdir)/emulparams/sh.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sh "$(tdir_sh)" +eshelf.c: $(srcdir)/emulparams/shelf.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} shelf "$(tdir_shelf)" +eshlelf.c: $(srcdir)/emulparams/shlelf.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} shlelf "$(tdir_shlelf)" +eshl.c: $(srcdir)/emulparams/shl.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS} + ${GENSCRIPTS} shl "$(tdir_shl)" +esparcaout.c: $(srcdir)/emulparams/sparcaout.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sparcaout "$(tdir_sparcaout)" +esparclinux.c: $(srcdir)/emulparams/sparclinux.sh \ + $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sparclinux "$(tdir_sparclinux)" +esparclynx.c: $(srcdir)/emulparams/sparclynx.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparclynx.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sparclynx "$(tdir_sparclynx)" +esparcnbsd.c: $(srcdir)/emulparams/sparcnbsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sparcnbsd "$(tdir_sparcnbsd)" +est2000.c: $(srcdir)/emulparams/st2000.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/st2000.sc ${GEN_DEPENDS} + ${GENSCRIPTS} st2000 "$(tdir_st2000)" +esun3.c: $(srcdir)/emulparams/sun3.sh \ + $(srcdir)/emultempl/sunos.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sun3 "$(tdir_sun3)" +esun4.c: $(srcdir)/emulparams/sun4.sh \ + $(srcdir)/emultempl/sunos.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} sun4 "$(tdir_sun4)" +etic30aout.c: $(srcdir)/emulparams/tic30aout.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic30aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} tic30aout "$(tdir_tic30aout)" +etic30coff.c: $(srcdir)/emulparams/tic30coff.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic30coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} tic30coff "$(tdir_tic30coff)" +etic80coff.c: $(srcdir)/emulparams/tic80coff.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic80coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} tic80coff "$(tdir_tic80coff)" +evanilla.c: $(srcdir)/emulparams/vanilla.sh \ + $(srcdir)/emultempl/vanilla.em $(srcdir)/scripttempl/vanilla.sc ${GEN_DEPENDS} + ${GENSCRIPTS} vanilla "$(tdir_vanilla)" +evax.c: $(srcdir)/emulparams/vax.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} vax "$(tdir_vax)" +evsta.c: $(srcdir)/emulparams/vsta.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} vsta "$(tdir_vsta)" +ev850.c: $(srcdir)/emulparams/v850.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/v850.sc ${GEN_DEPENDS} + ${GENSCRIPTS} v850 "$(tdir_v850)" +ew65.c: $(srcdir)/emulparams/w65.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS} + ${GENSCRIPTS} w65 "$(tdir_w65)" +ez8001.c: $(srcdir)/emulparams/z8001.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS} + ${GENSCRIPTS} z8001 "$(tdir_z8001)" +ez8002.c: $(srcdir)/emulparams/z8002.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS} + ${GENSCRIPTS} z8002 "$(tdir_z8002)" + +# The generated emulation files mostly have the same dependencies. +$(EMULATION_OFILES): ../bfd/bfd.h sysdep.h config.h $(INCDIR)/bfdlink.h \ + ld.h ldmain.h ldemul.h ldfile.h ldmisc.h ldexp.h ldlang.h \ + ldctor.h ldexp.h ldlang.h ldgram.h + +check-DEJAGNU: site.exp + srcroot=`cd $(srcdir) && pwd`; export srcroot; \ + r=`pwd`; export r; \ + EXPECT=$(EXPECT); export EXPECT; \ + if [ -f $(top_builddir)/../expect/expect ]; then \ + TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \ + export TCL_LIBRARY; \ + fi; \ + runtest=$(RUNTEST); \ + if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \ + $$runtest --tool $(DEJATOOL) --srcdir $${srcroot}/testsuite \ + CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS)" \ + CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS)" \ + CC_FOR_HOST="$(CC)" CFLAGS_FOR_HOST="$(CFLAGS)" \ + OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" \ + LIBIBERTY="$(LIBIBERTY) $(INTLLIBS)" \ + $(RUNTESTFLAGS); \ + else echo "WARNING: could not find \`runtest'" 1>&2; :;\ + fi + +# Rules for testing by relinking ld itself. +# A similar test is in the testsuite. This target is for ease of use +# when porting ld. + +ld-partial.o: ld-new$(EXEEXT) + ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld-partial.o -r $(OFILES) +ld1$(EXEEXT): ld-partial.o + ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld1$(EXEEXT) $(HOSTING_CRT0) ld-partial.o $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + +ld1-full$(EXEEXT): ld-new + ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld1-full$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + +ld2$(EXEEXT): ld1$(EXEEXT) + ./ld1$(EXEEXT) $(HOSTING_EMU) -o ld2$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + +ld3$(EXEEXT): ld2$(EXEEXT) + ./ld2$(EXEEXT) $(HOSTING_EMU) -o ld3$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + +bootstrap: ld3$(EXEEXT) + cmp ld2$(EXEEXT) ld3$(EXEEXT) + +.PHONY: bootstrap + +# A test program for C++ constructors and destructors. +# This test is now in the testsuite. +# +#cdtest: cdtest-main.o cdtest-bar.o cdtest-foo.o ld.new +# ./ld.new $(HOSTING_EMU) -o cdtest $(HOSTING_CRT0) \ +# cdtest-main.o cdtest-bar.o cdtest-foo.o $(HOSTING_LIBS) +# +#cdtest.out: cdtest +# ./cdtest > cdtest.tmp +# mv cdtest.tmp cdtest.out +# +#cdtest-ur.o: cdtest-main.o cdtest-bar.o cdtest-foo.o ld.new +# ./ld.new $(HOSTING_EMU) -o cdtest-ur.o -Ur cdtest-main.o \ +# cdtest-bar.o cdtest-foo.o +# +#cdtest-ur: cdtest-ur.o +# ./ld.new $(HOSTING_EMU) -o cdtest-ur $(HOSTING_CRT0) cdtest-ur.o \ +# $(HOSTING_LIBS) +# +#cdtest-ur.out: cdtest-ur +# ./cdtest-ur > cdtest-ur.tmp +# mv cdtest-ur.tmp cdtest-ur.out +# +#check-cdtest: cdtest.out cdtest-ur.out $(srcdir)/cdtest.exp +# diff $(srcdir)/cdtest.exp cdtest.out +# diff $(srcdir)/cdtest.exp cdtest-ur.out +# +#.PHONY: check-cdtest + +# END OF CHECK TARGETS + +# DOCUMENTATION TARGETS +# Manual configuration file; not usually attached to normal configuration, +# because almost all configs use "gen" version of manual. +# Set DOCVER above to change. +configdoc.texi: ${DOCVER}-doc.texi + ln -s ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi >/dev/null 2>&1 \ + || ln ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi >/dev/null 2>&1 \ + || cp ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi + +ldver.texi: Makefile + rm -f $@ + echo '@set VERSION $(VERSION)' > $@ + +ld.info: $(srcdir)/ld.texinfo configdoc.texi ldver.texi + @rm -f $@ $@-[0-9] $@-[0-9][0-9] + $(MAKEINFO) -I $(srcdir) -I $(BFDDIR)/doc $(srcdir)/ld.texinfo + +ld.dvi: $(srcdir)/ld.texinfo configdoc.texi ldver.texi + TEXINPUTS=$(top_srcdir)/../texinfo:$$TEXINPUTS \ + MAKEINFO="$(MAKEINFO) -I $(srcdir) -I $(BFDDIR)/doc" $(TEXI2DVI) $(srcdir)/ld.texinfo + +# We want to reconfigure if configure.host or configure.tgt changes. +config.status: $(srcdir)/configure $(srcdir)/configure.host $(srcdir)/configure.tgt + $(SHELL) ./config.status --recheck +mostlyclean-local: + -rm -rf tmpdir + +.PHONY: install-exec-local install-data-local + +install-exec-local: ld-new$(EXEEXT) + $(mkinstalldirs) $(bindir) $(tooldir)/bin + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + n=`echo ld | sed '$(transform)'`; \ + if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/ld$(EXEEXT)" ]; then \ + rm -f $(tooldir)/bin/ld$(EXEEXT); \ + ln $(bindir)/$$n$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT); \ + fi + +install-data-local: + $(mkinstalldirs) $(scriptdir)/ldscripts + for f in ldscripts/*; do \ + $(INSTALL_DATA) $$f $(scriptdir)/$$f ; \ + done +diststuff: $(LDDISTSTUFF) info +distclean-local: + rm -rf ldscripts + +# Targets to rebuild dependencies in this Makefile. +# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES). +.dep: dep.sed $(CFILES) $(HFILES) $(GENERATED_CFILES) $(GENERATED_HFILES) config.h + rm -f .dep1 + $(MAKE) DEP=$(DEP) .dep1 + sed -f dep.sed <.dep1 >.dep + +# This rule really wants a mkdep that runs "gcc -MM". +.dep1: $(CFILES) $(GENERATED_CFILES) + rm -f .dep2 + echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2 + $(DEP) -f .dep2 $(INCLUDES) $? + $(srcdir)/../move-if-change .dep2 .dep1 + +dep.sed: dep-in.sed config.status + sed <$(srcdir)/dep-in.sed >dep.sed \ + -e 's!@INCDIR@!$(INCDIR)!' \ + -e 's!@SRCDIR@!$(srcdir)!' + +dep: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile + cat .dep >> tmp-Makefile + $(srcdir)/../move-if-change tmp-Makefile Makefile + +dep-in: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in + cat .dep >> tmp-Makefile.in + $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in + +dep-am: .dep + sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am + cat .dep >> tmp-Makefile.am + $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am + +.PHONY: dep dep-in dep-am + +# What appears below is generated by a hacked mkdep using gcc -MM. + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +ldctor.o: ldctor.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + ld.h ldexp.h ldlang.h ldmisc.h ldgram.h ldmain.h ldctor.h +ldemul.o: ldemul.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldemul.h \ + ldmisc.h ldexp.h ldlang.h ldfile.h ldmain.h ldemul-list.h +ldexp.o: ldexp.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + ld.h ldmain.h ldmisc.h ldexp.h ldgram.h ldlang.h +ldfile.o: ldfile.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + ld.h ldmisc.h ldexp.h ldlang.h ldfile.h ldmain.h ldgram.h \ + ldlex.h ldemul.h +ldlang.o: ldlang.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \ + $(INCDIR)/obstack.h $(INCDIR)/bfdlink.h ld.h ldmain.h \ + ldgram.h ldexp.h ldlang.h ldemul.h ldlex.h ldmisc.h \ + ldctor.h ldfile.h $(INCDIR)/fnmatch.h +ldmain.o: ldmain.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \ + $(INCDIR)/progress.h $(INCDIR)/bfdlink.h ld.h ldmain.h \ + ldmisc.h ldwrite.h ldgram.h ldexp.h ldlang.h ldemul.h \ + ldlex.h ldfile.h ldctor.h +ldmisc.o: ldmisc.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \ + $(INCDIR)/demangle.h ld.h ldmisc.h ldexp.h ldlang.h \ + ldgram.h ldlex.h ldmain.h ldfile.h +ldver.o: ldver.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldver.h \ + ldemul.h ldmain.h +ldwrite.o: ldwrite.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/libiberty.h ld.h ldexp.h ldlang.h ldwrite.h \ + ldmisc.h ldgram.h ldmain.h +lexsup.o: lexsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \ + $(INCDIR)/getopt.h $(INCDIR)/bfdlink.h ld.h ldmain.h \ + ldmisc.h ldexp.h ldlang.h ldgram.h ldlex.h ldfile.h \ + ldver.h ldemul.h +mri.o: mri.c ../bfd/bfd.h $(INCDIR)/ansidecl.h sysdep.h \ + config.h $(INCDIR)/fopen-same.h ld.h ldexp.h ldlang.h \ + ldmisc.h mri.h ldgram.h $(INCDIR)/libiberty.h +ldcref.o: ldcref.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/libiberty.h ld.h ldmain.h ldmisc.h ldexp.h \ + ldlang.h +pe-dll.o: pe-dll.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + $(INCDIR)/libiberty.h ld.h ldexp.h ldlang.h ldwrite.h \ + ldmisc.h ldgram.h ldmain.h ldemul.h $(INCDIR)/coff/internal.h \ + ../bfd/libcoff.h deffile.h +ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ + sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \ + ld.h ldexp.h ldver.h ldlang.h ldemul.h ldfile.h ldmisc.h \ + ldmain.h mri.h ldctor.h ldlex.h +ldlex.o: ldlex.c ../bfd/bfd.h sysdep.h config.h $(INCDIR)/fopen-same.h \ + ld.h ldgram.h ldmisc.h ldexp.h ldlang.h ldfile.h ldlex.h \ + ldmain.h +deffilep.o: deffilep.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \ + ../bfd/bfd.h sysdep.h config.h $(INCDIR)/fopen-same.h \ + ld.h ldmisc.h deffile.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: @@ -0,0 +1,190 @@ +-*- text -*- + +Changes in version 2.10: + +* Added garbage collection of unused sections, enabled by --gc-sections. + It does require a bit of backend support; currently implemented are + ppc-elf, mips-elf, and mn10300-elf. Others will ignore the option. + +* Added SORT to the linker script language to permit sorting sections by file + name or section name. + +* Added EXTERN to the linker script language as an equivalent to the -u + command-line option. + +* Added ASSERT to the linker script language. + +* Added -O option to optimize linker output (as of this writing, this only +affects ELF shared library generation). + +* The -e option now accepts a number as well as a symbol name. + +* Added --demangle and --no-demangle options. + +Changes in version 2.9: + +* Added SQUAD to the linker script language. + +* New option --no-warn-mismatch. + +* The MEMORY command now parses the attributes to determine where sections that + are not placed in a specific memory region are placed. + +Changes in version 2.8: + +* Linker scripts may now contain shell wildcard characters for file and section + names. + +* The linker now supports symbol versions in ELF. + +* The NOCROSSREFS command was added to the linker script language. + +* The LOADADDR expression was added to the linker script language. + +* MAX and MIN functions were added to the linker script language. + +* The OVERLAY construct was added to the linker script language. + +* New option --warn-section-align to warn when the address of an output section + changes due to alignment of an input section. + +* New options --filter/-F and --auxiliary/-f. + +Changes in version 2.7: + +* New option --cref to print out a cross reference table. + +* New option --wrap SYMBOL. + +* New option --no-whole-archive, to turn off the effect of --whole-archive. + +* Input sections assigned to the output section /DISCARD/ in the linker script + are not included in the output file. + +* The SunOS and ELF linkers now merge stabs debugging information which uses + the N_BINCL and N_EINCL stab types. This reduces the amount of debugging + information generated. + +Changes in version 2.6: + +* When an ELF section name is representable as a C identifier (this is not true +of most ELF section names), the linker will automatically define symbols +__start_SECNAME and __stop_SECNAME, where SECNAME is the section name, at the +beginning and the end of the section. This is used by glibc. + +* When an ELF section named .gnu.warning is encountered in an input file, the +contents of the section are displayed as an error message, and the section is +not copied into the output file. This is used by glibc. + +* When an ELF section named .gnu.warning.SYMBOL is encountered in an input +file, and the symbol SYMBOL is referenced by some object file, the contents of +the section are displayed as an error message. The section is not copied into +the output file, unless doing a relocateable or shared link. This is used by +glibc. + +* New options -split-by-reloc and -split-by-file. + +* The linker now supports linking PIC compiled code on SPARC SunOS. It can +also create SPARC SunOS shared libraries, and, like the native SunOS linker, +will do so whenever there is an undefined symbol in the link and neither the -e +nor the -r option was used. + +* The -rpath option may be used on SunOS to set the list of directories to be +searched at run time. This overrides the default of building the list from the +-L options. + +* The COFF linker now combines debugging information for structs, unions, and +enums, so that even if the same type is defined in multiple input files it will +only be defined once in the output file. The --traditional-format switch will +prevent this optimization. + +Changes in version 2.5: + +* The linker now supports linking against SunOS shared libraries. It still can +not link SunOS PIC (Position Independent Code) files, so it can not be used to +generate shared libaries. + +* The linker now supports linking against ELF shared libraries for the i386 +(UnixWare) and SPARC (Solaris). It can also link ELF PIC files, and can be +used to generate shared libraries. Shared library generation is not well +tested; please report any problems encountered. The linker is now enabled for +Solaris again. + +* Eric Youngdale has contributed Linux support code, including linking against +Linux a.out shared libraries. The linker produces Linux QMAGIC binaries. + +* The ELF backend has been converted to the new linker code. To use the new +ELF linker, each particular target requires a relocation function. So far, +this function has been written for i386 (UnixWare), SPARC (Solaris) MIPS (Irix +5), and HPPA ELF targets. + +* The -( (--start-group) and -) (--end-group) options have been added to +support searching a group of archives as though they were a single archive. +This can also be used in a linker script, as GROUP ( files ). + +* When a file is named on the command line, and the linker does not recognize +it as an object file, the linker will now treat the file as a linker script +file. A linker script named in this way augments, but does not replace, the +default linker script. + +* The -warn-once option was added. It causes the linker to only warn once per +undefined symbol, rather than once per reference. + +* The COFF backend has been converted to the new linker code. As with ELF, to +use the new linker, each particular target requires a relocation function. So +far, this function has been written for the i386, m68k, a29k and SH targets. + +* The -V flag was made a synonym for -v, for SVR4 compatibility. The old -V +behaviour is available via --verbose. + +Changes in version 2.4: + +* New linker code, by Steve Chamberlain and Ian Taylor. For a.out and ecoff + formats (so far), this should result in considerable savings in time + and memory used while linking; slightly poorer performance than + before for formats not converted yet. + +* Command-line parsing is no longer done with flex. This means + oddball characters in filenames won't get treated as argument + separators. + +* HP-PA ELF support, by Jeff Law. (No SOM support yet.) + +* Mach i386 support, by David Mackenzie. + +* Irix 4 shared libraries are now supported (Irix 5 uses ELF, and ELF shared + libraries are not yet supported). + +* COFF shared libraries (as on SCO) should work as well. + +* The linker is disabled for Solaris. (Actually, it was in 2.3 also, I just + forgot to note it.) Some of their C library routines don't work when + statically linked, and the GNU linker doesn't support dynamic linking yet. + +Changes in version 2.3: + +* Weak symbols are now supported. + +* ELF support has been added. The linker has been bootstrapped on + UnixWare and Solaris. + +* Alpha OSF/1 support has been added (non dynamic linking only). + +Changes in version 2.2: + +* The `bfd' library has been updated to reduce a.out-format string + table size. The effect of this is that files linked from many input + files with duplicate symbols (`-g' debugging records, or identical + static symbols) should be much smaller. + +Changes in version 2.1: + +* The ld -ySYMBOL flag (to trace references to SYMBOL) is now implemented. + +* There is now support for writing ECOFF files, so ld and the + other utilities should work on Risc/Ultrix and Irix. + + +Local variables: +fill-column: 79 +End: diff --git a/ld/README b/ld/README new file mode 100644 index 0000000..8947d04 --- /dev/null +++ b/ld/README @@ -0,0 +1,64 @@ +This is the GNU linker. It is distributed with other "binary +utilities" which should be in ../binutils. See ../binutils/README for +more general notes, including where to send bug reports. + +There are many features of the linker: + +* The linker uses a Binary File Descriptor library (../bfd) + that it uses to read and write object files. This helps + insulate the linker itself from the format of object files. + +* The linker supports a number of different object file + formats. It can even handle multiple formats at once: + Read two input formats and write a third. + +* The linker can be configured for cross-linking. + +* The linker supports a control language. + +* There is a user manual (ld.texinfo), as well as the + beginnings of an internals manual (ldint.texinfo). + +Installation +============ + +See ../binutils/README. + +If you want to make a cross-linker, you may want to specify +a different search path of -lfoo libraries than the default. +You can do this by setting the LIB_PATH variable in ./Makefile. + +To build just the linker, make the target all-ld from the top level +directory (one directory above this one). + +Porting to a new target +======================= + +See the ldint.texinfo manual. + +Reporting bugs etc +=========================== + +See ../binutils/README. + +Known problems +============== + +The Solaris linker normally exports all dynamic symbols from an +executable. The GNU linker does not do this by default. This is +because the GNU linker tries to present the same interface for all +similar targets (in this case, all native ELF targets). This does not +matter for normal programs, but it can make a difference for programs +which try to dlopen an executable, such as PERL or Tcl. You can make +the GNU linker export all dynamic symbols with the -E or +--export-dynamic command line option. + +HP/UX 9.01 has a shell bug that causes the linker scripts to be +generated incorrectly. The symptom of this appears to be "fatal error +- scanner input buffer overflow" error messages. There are various +workarounds to this: + * Build and install bash, and build with "make SHELL=bash". + * Update to a version of HP/UX with a working shell (e.g., 9.05). + * Replace "(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc)" in + genscripts.sh with "sh ${srcdir}..." (no parens) and make sure the + emulparams script used exports any shell variables it sets. @@ -0,0 +1,9 @@ +Volunteers to tackle some of the following would be welcome: + +Support the "traditional" BSD -A flag (incremental loading). +(There is a -A flag in ld now, but it is used to specify the +architecture. That should probably be changed.) + +Support for dynamic loading (a la dld, but bfd-based) would be nice. + +Avoid re-open (and re-seeking) output bfd and archives. diff --git a/ld/acinclude.m4 b/ld/acinclude.m4 new file mode 100644 index 0000000..71b09b9 --- /dev/null +++ b/ld/acinclude.m4 @@ -0,0 +1 @@ +sinclude(../bfd/acinclude.m4) diff --git a/ld/aclocal.m4 b/ld/aclocal.m4 new file mode 100644 index 0000000..11934b0 --- /dev/null +++ b/ld/aclocal.m4 @@ -0,0 +1,1120 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +sinclude(../bfd/acinclude.m4) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + + +# serial 35 AC_PROG_LIBTOOL +AC_DEFUN(AC_PROG_LIBTOOL, +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# Save cache, so that ltconfig can load it +AC_CACHE_SAVE + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \ +DLLTOOL="$DLLTOOL" AS="$AS" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Reload cache, that may have been modified by ltconfig +AC_CACHE_LOAD + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +AC_DEFUN(AC_LIBTOOL_SETUP, +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_RANLIB])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_SYS_NM_PARSE])dnl +AC_REQUIRE([AC_SYS_SYMBOL_UNDERSCORE])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +dnl + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen" +test "$silent" = yes && libtool_flags="$libtool_flags --silent" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +*-*-cygwin*) + AC_SYS_LIBTOOL_CYGWIN + ;; + +esac + +# enable the --disable-libtool-lock switch + +AC_ARG_ENABLE(libtool-lock, +[ --disable-libtool-lock force libtool not to do file locking], +need_locks=$enableval, +need_locks=yes) + +if test x"$need_locks" = xno; then + libtool_flags="$libtool_flags --disable-lock" +fi +]) + +# AC_LIBTOOL_DLOPEN - check for dlopen support +AC_DEFUN(AC_LIBTOOL_DLOPEN, [lt_dlopen=yes]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_SHARED, +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN(AC_DISABLE_SHARED, +[AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_STATIC, +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN(AC_DISABLE_STATIC, +[AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_FAST_INSTALL, +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN(AC_DISABLE_FAST_INSTALL, +[AC_ENABLE_FAST_INSTALL(no)]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN(AC_PROG_LD, +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. +changequote(,)dnl + /* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' +changequote([,])dnl + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(ac_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$ac_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_SUBST(LD) +AC_PROG_LD_GNU +]) + +AC_DEFUN(AC_PROG_LD_GNU, +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi]) +]) + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN(AC_PROG_NM, +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(ac_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi]) +NM="$ac_cv_path_NM" +AC_MSG_RESULT([$NM]) +AC_SUBST(NM) +]) + +# AC_SYS_NM_PARSE - Check for command to grab the raw symbol name followed +# by C symbol name from nm. +AC_DEFUN(AC_SYS_NM_PARSE, +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_NM])dnl +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output]) +AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe, +[# These are sane defaults that work on at least a few old systems. +# {They come from Ultrix. What could be older than Ultrix?!! ;)} + +changequote(,)dnl +# Character class describing NM global symbol codes. +ac_symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +ac_symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Define system-specific variables. +case "$host_os" in +aix*) + ac_symcode='[BCDT]' + ;; +cygwin* | mingw*) + ac_symcode='[ABCDGISTW]' + ;; +hpux*) + ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" + ;; +irix*) + ac_symcode='[BCDEGRST]' + ;; +solaris*) + ac_symcode='[BDT]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + ac_symcode='[ABCDGISTW]' +fi +changequote([,])dnl + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($ac_symcode\)[ ][ ]*\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'" + + # Check to see that the pipe works correctly. + ac_pipe_works=no + rm -f conftest.$ac_ext + cat > conftest.$ac_ext <<EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func;return 0;} +EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + ac_nlist=conftest.nm + + if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then + + # Try sorting and uniquifying the output. + if sort "$ac_nlist" | uniq > "$ac_nlist"T; then + mv -f "$ac_nlist"T "$ac_nlist" + else + rm -f "$ac_nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then + if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then + cat <<EOF > conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c' + + cat <<EOF >> conftest.c +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +changequote(,)dnl +lt_preloaded_symbols[] = +changequote([,])dnl +{ +EOF + sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c + cat <<\EOF >> conftest.c + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftestm.$ac_objext + ac_save_LIBS="$LIBS" + ac_save_CFLAGS="$CFLAGS" + LIBS="conftestm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if AC_TRY_EVAL(ac_link) && test -s conftest; then + ac_pipe_works=yes + else + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC + fi + LIBS="$ac_save_LIBS" + CFLAGS="$ac_save_CFLAGS" + else + echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC + fi + else + echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC + fi + else + echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "$progname: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC + fi + rm -rf conftest* + + # Do not use the global_symbol_pipe unless it works. + if test "$ac_pipe_works" = yes; then + if test x"$ac_symprfx" = x"_"; then + ac_cv_sys_symbol_underscore=yes + else + ac_cv_sys_symbol_underscore=no + fi + break + else + ac_cv_sys_global_symbol_pipe= + fi +done +]) + +ac_result=yes +if test -z "$ac_cv_sys_global_symbol_pipe"; then + ac_result=no +fi +AC_MSG_RESULT($ac_result) +]) + +# AC_SYS_LIBTOOL_CYGWIN - find tools needed on cygwin +AC_DEFUN(AC_SYS_LIBTOOL_CYGWIN, +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +AC_CHECK_TOOL(AS, as, false) +]) + +# AC_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols +# with an underscore? +AC_DEFUN(AC_SYS_SYMBOL_UNDERSCORE, +[AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_SYS_NM_PARSE])dnl +AC_MSG_CHECKING([for _ prefix in compiled symbols]) +AC_CACHE_VAL(ac_cv_sys_symbol_underscore, +[ac_cv_sys_symbol_underscore=no +cat > conftest.$ac_ext <<EOF +void nm_test_func(){} +int main(){nm_test_func;return 0;} +EOF +if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + ac_nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + ac_cv_sys_symbol_underscore=yes + else + if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC + fi + fi + else + echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi +else + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC +fi +rm -rf conftest* +]) +AC_MSG_RESULT($ac_cv_sys_symbol_underscore) +USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no} +AC_SUBST(USE_SYMBOL_UNDERSCORE)dnl +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN(AC_CHECK_LIBM, [ +AC_CHECK_LIB(mw, _mwvalidcheckl) +AC_CHECK_LIB(m, cos) +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library, adds --enable-ltdl-convenience to +# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor +# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed +# to be `${top_builddir}/libltdl'. Make sure you start DIR with +# '${top_builddir}/' (note the single quotes!) if your package is not +# flat, and, if you're not using automake, define top_builddir as +# appropriate in the Makefiles. +AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [ + case "$enable_ltdl_convenience" in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library, and adds --enable-ltdl-install to +# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor +# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed +# to be `${top_builddir}/libltdl'. Make sure you start DIR with +# '${top_builddir}/' (note the single quotes!) if your package is not +# flat, and, if you're not using automake, define top_builddir as +# appropriate in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [ + AC_CHECK_LIB(ltdl, main, LIBLTDL="-lltdl", [ + case "$enable_ltdl_install" in + no) AC_MSG_WARN([libltdl not installed, but installation disabled]) ;; + "") enable_ltdl_install=yes + ac_configure_args="$ac_configure_args --enable-ltdl-install" ;; + esac + ]) + if test x"$enable_ltdl_install" != x"no"; then + LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la + fi +]) + +dnl old names +AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl +AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl +AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl +AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl +AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl +AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl +AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl +AC_DEFUN(AM_SYS_NM_PARSE, [indir([AC_SYS_NM_PARSE])])dnl +AC_DEFUN(AM_SYS_SYMBOL_UNDERSCORE, [indir([AC_SYS_SYMBOL_UNDERSCORE])])dnl +AC_DEFUN(AM_SYS_LIBTOOL_CYGWIN, [indir([AC_SYS_LIBTOOL_CYGWIN])])dnl + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN(AM_CONFIG_HEADER, +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<<am_indx=1 +for am_file in <<$1>>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + +# This file is derived from `gettext.m4'. The difference is that the +# included macros assume Cygnus-style source and build trees. + +# Macro to add for using GNU gettext. +# Ulrich Drepper <drepper@cygnus.com>, 1995. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 3 + +AC_DEFUN(CY_WITH_NLS, + [AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) + + USE_INCLUDED_LIBINTL=no + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested]) + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If gettext or catgets are available (in this order) we + dnl use this. Else we have to fall back to GNU NLS library. + dnl catgets is only used if permitted by option --with-catgets. + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + AC_CHECK_HEADER(libintl.h, + [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, + [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")], + gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) + + if test "$gt_cv_func_gettext_libc" != "yes"; then + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CACHE_CHECK([for gettext in libintl], + gt_cv_func_gettext_libintl, + [AC_TRY_LINK([], [return (int) gettext ("")], + gt_cv_func_gettext_libintl=yes, + gt_cv_func_gettext_libintl=no)])]) + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + AC_DEFINE(HAVE_GETTEXT, 1, + [Define as 1 if you have gettext and don't want to use GNU gettext.]) + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + fi + ]) + + dnl In the standard gettext, we would now check for catgets. + dnl However, we never want to use catgets for our releases. + + if test "$CATOBJEXT" = "NONE"; then + dnl Neither gettext nor catgets in included in the C library. + dnl Fall back on GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_SUBST(MSGFMT) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/../intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext programs is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLDEPS) + AC_SUBST(INTLLIBS) + AC_SUBST(INTLOBJS) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +AC_DEFUN(CY_GNU_GETTEXT, + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h values.h sys/param.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ +__argz_count __argz_stringify __argz_next]) + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + AC_CHECK_FUNCS(stpcpy) + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function]) + fi + + AM_LC_MESSAGES + CY_WITH_NLS + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl The reference to <locale.h> in the installed <libintl.h> file + dnl must be resolved because we cannot expect the users of this + dnl to define HAVE_LOCALE_H. + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include <locale.h>" + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header <locale.h>. Take care yourself. */" + fi + AC_SUBST(INCLUDE_LOCALE_H) + + dnl Determine which catalog format we have (if any is needed) + dnl For now we know about two different formats: + dnl Linux libc-5 and the normal X/Open format + if test -f $srcdir/po2tbl.sed.in; then + if test "$CATOBJEXT" = ".cat"; then + AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) + + dnl Transform the SED scripts while copying because some dumb SEDs + dnl cannot handle comments. + sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed + fi + dnl po2tbl.sed is always needed. + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/po2tbl.sed.in > po2tbl.sed + fi + + dnl In the intl/Makefile.in we have a special dependency which makes + dnl only sense for gettext. We comment this out for non-gettext + dnl packages. + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + AC_SUBST(GT_NO) + AC_SUBST(GT_YES) + + MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs" + AC_SUBST(MKINSTALLDIRS) + + dnl *** For now the libtool support in intl/Makefile is not for real. + l= + AC_SUBST(l) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. But only do this if the po directory + dnl exists in srcdir. + if test -d $srcdir/po; then + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + fi + ]) + +# Search path for a program which passes the given test. +# Ulrich Drepper <drepper@cygnus.com>, 1996. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN(AM_PATH_PROG_WITH_TEST, +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test -n "[$]$1"; then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# Check whether LC_MESSAGES is available in <locale.h>. +# Ulrich Drepper <drepper@cygnus.com>, 1995. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +AC_DEFUN(AM_LC_MESSAGES, + [if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your locale.h file contains LC_MESSAGES.]) + fi + fi]) + + +dnl AM_PROG_LEX +dnl Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT +AC_DEFUN(AM_PROG_LEX, +[missing_dir=ifelse([$1],,`cd $ac_aux_dir && pwd`,$1) +AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex") +AC_PROG_LEX +AC_DECL_YYTEXT]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN(AM_MAINTAINER_MODE, +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +# Define a conditional. + +AC_DEFUN(AM_CONDITIONAL, +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + diff --git a/ld/config.in b/ld/config.in new file mode 100644 index 0000000..a415046 --- /dev/null +++ b/ld/config.in @@ -0,0 +1,171 @@ +/* config.in. Generated automatically from configure.in by autoheader. */ + +/* Define if using alloca.c. */ +#undef C_ALLOCA + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +#undef CRAY_STACKSEG_END + +/* Define if you have alloca, as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define if you have <alloca.h> and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define to `long' if <sys/types.h> doesn't define. */ +#undef off_t + +/* Define if you need to in order for stat and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to `unsigned' if <sys/types.h> doesn't define. */ +#undef size_t + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#undef STACK_DIRECTION + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if lex declares yytext as a char * by default, not a char[]. */ +#undef YYTEXT_POINTER + +/* Define if you have the __argz_count function. */ +#undef HAVE___ARGZ_COUNT + +/* Define if you have the __argz_next function. */ +#undef HAVE___ARGZ_NEXT + +/* Define if you have the __argz_stringify function. */ +#undef HAVE___ARGZ_STRINGIFY + +/* Define if you have the dcgettext function. */ +#undef HAVE_DCGETTEXT + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the munmap function. */ +#undef HAVE_MUNMAP + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + +/* Define if you have the sbrk function. */ +#undef HAVE_SBRK + +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the setlocale function. */ +#undef HAVE_SETLOCALE + +/* Define if you have the stpcpy function. */ +#undef HAVE_STPCPY + +/* Define if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the strchr function. */ +#undef HAVE_STRCHR + +/* Define if you have the <argz.h> header file. */ +#undef HAVE_ARGZ_H + +/* Define if you have the <dirent.h> header file. */ +#undef HAVE_DIRENT_H + +/* Define if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the <locale.h> header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the <malloc.h> header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the <ndir.h> header file. */ +#undef HAVE_NDIR_H + +/* Define if you have the <nl_types.h> header file. */ +#undef HAVE_NL_TYPES_H + +/* Define if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the <sys/dir.h> header file. */ +#undef HAVE_SYS_DIR_H + +/* Define if you have the <sys/ndir.h> header file. */ +#undef HAVE_SYS_NDIR_H + +/* Define if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the <values.h> header file. */ +#undef HAVE_VALUES_H + +/* Name of package */ +#undef PACKAGE + +/* Version number of package */ +#undef VERSION + +/* Define if you have the stpcpy function */ +#undef HAVE_STPCPY + +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define to 1 if NLS is requested */ +#undef ENABLE_NLS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + +/* Use b modifier when opening binary files? */ +#undef USE_BINARY_FOPEN + +/* Define if strstr is not declared in system header files. */ +#undef NEED_DECLARATION_STRSTR + +/* Define if free is not declared in system header files. */ +#undef NEED_DECLARATION_FREE + +/* Define if sbrk is not declared in system header files. */ +#undef NEED_DECLARATION_SBRK + +/* Define if getenv is not declared in system header files. */ +#undef NEED_DECLARATION_GETENV + +/* Define if environ is not declared in system header files. */ +#undef NEED_DECLARATION_ENVIRON + diff --git a/ld/configure b/ld/configure new file mode 100755 index 0000000..9d573b2 --- /dev/null +++ b/ld/configure @@ -0,0 +1,5214 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-shared[=PKGS] build shared libraries [default=yes]" +ac_help="$ac_help + --enable-static[=PKGS] build static libraries [default=yes]" +ac_help="$ac_help + --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" +ac_help="$ac_help + --with-gnu-ld assume the C compiler uses GNU ld [default=no]" +ac_help="$ac_help + --disable-libtool-lock force libtool not to do file locking" +ac_help="$ac_help + --enable-targets alternative target configurations" +ac_help="$ac_help + --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes)" +ac_help="$ac_help + --disable-nls do not use Native Language Support" +ac_help="$ac_help + --with-included-gettext use the GNU gettext library included here" +ac_help="$ac_help + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=ldmain.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:594: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:615: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:633: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:668: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:721: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:778: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=ld + +VERSION=2.9.4 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <<EOF +#define PACKAGE "$PACKAGE" +EOF + +cat >> confdefs.h <<EOF +#define VERSION "$VERSION" +EOF + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +echo "configure:824: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:837: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:850: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:863: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:876: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=yes +fi + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:962: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:992: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1022: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1073: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1105: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 1116 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:1121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1147: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1152: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1161: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1180: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 +echo "configure:1223: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + /* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 +echo "configure:1247: checking for GNU ld" >&5 +else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 +echo "configure:1250: checking for non-GNU ld" >&5 +fi +if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$ac_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } + +echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 +echo "configure:1286: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 + + +echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 +echo "configure:1302: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi +fi + +NM="$ac_cv_path_NM" +echo "$ac_t""$NM" 1>&6 + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6 +echo "configure:1340: checking command to parse $NM output" >&5 +if eval "test \"`echo '$''{'ac_cv_sys_global_symbol_pipe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # These are sane defaults that work on at least a few old systems. +# {They come from Ultrix. What could be older than Ultrix?!! ;)} + +# Character class describing NM global symbol codes. +ac_symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +ac_symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Define system-specific variables. +case "$host_os" in +aix*) + ac_symcode='[BCDT]' + ;; +cygwin* | mingw*) + ac_symcode='[ABCDGISTW]' + ;; +hpux*) + ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" + ;; +irix*) + ac_symcode='[BCDEGRST]' + ;; +solaris*) + ac_symcode='[BDT]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + ac_symcode='[ABCDGISTW]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* \($ac_symcode\) *\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'" + + # Check to see that the pipe works correctly. + ac_pipe_works=no + rm -f conftest.$ac_ext + cat > conftest.$ac_ext <<EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func;return 0;} +EOF + + if { (eval echo configure:1403: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + # Now try to grab the symbols. + ac_nlist=conftest.nm + + if { (eval echo configure:1407: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then + + # Try sorting and uniquifying the output. + if sort "$ac_nlist" | uniq > "$ac_nlist"T; then + mv -f "$ac_nlist"T "$ac_nlist" + else + rm -f "$ac_nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then + if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then + cat <<EOF > conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c' + + cat <<EOF >> conftest.c +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c + cat <<\EOF >> conftest.c + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftestm.$ac_objext + ac_save_LIBS="$LIBS" + ac_save_CFLAGS="$CFLAGS" + LIBS="conftestm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo configure:1459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + ac_pipe_works=yes + else + echo "configure: failed program was:" >&5 + cat conftest.c >&5 + fi + LIBS="$ac_save_LIBS" + CFLAGS="$ac_save_CFLAGS" + else + echo "cannot find nm_test_func in $ac_nlist" >&5 + fi + else + echo "cannot find nm_test_var in $ac_nlist" >&5 + fi + else + echo "cannot run $ac_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + rm -rf conftest* + + # Do not use the global_symbol_pipe unless it works. + if test "$ac_pipe_works" = yes; then + if test x"$ac_symprfx" = x"_"; then + ac_cv_sys_symbol_underscore=yes + else + ac_cv_sys_symbol_underscore=no + fi + break + else + ac_cv_sys_global_symbol_pipe= + fi +done + +fi + + +ac_result=yes +if test -z "$ac_cv_sys_global_symbol_pipe"; then + ac_result=no +fi +echo "$ac_t""$ac_result" 1>&6 + +echo $ac_n "checking for _ prefix in compiled symbols""... $ac_c" 1>&6 +echo "configure:1505: checking for _ prefix in compiled symbols" >&5 +if eval "test \"`echo '$''{'ac_cv_sys_symbol_underscore'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_sys_symbol_underscore=no +cat > conftest.$ac_ext <<EOF +void nm_test_func(){} +int main(){nm_test_func;return 0;} +EOF +if { (eval echo configure:1514: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + # Now try to grab the symbols. + ac_nlist=conftest.nm + if { (eval echo configure:1517: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + ac_cv_sys_symbol_underscore=yes + else + if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&5 + fi + fi + else + echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&5 + fi +else + echo "configure: failed program was:" >&5 + cat conftest.c >&5 +fi +rm -rf conftest* + +fi + +echo "$ac_t""$ac_cv_sys_symbol_underscore" 1>&6 +USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no} + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1543: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test $host != $build; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen" +test "$silent" = yes && libtool_flags="$libtool_flags --silent" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 1585 "configure"' > conftest.$ac_ext + if { (eval echo configure:1586: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 +echo "configure:1607: checking whether the C compiler needs -belf" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1612 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:1619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_needs_belf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_needs_belf=no +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +*-*-cygwin*) + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1642: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +DLLTOOL="$ac_cv_prog_DLLTOOL" +if test -n "$DLLTOOL"; then + echo "$ac_t""$DLLTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_DLLTOOL"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1674: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_DLLTOOL="dlltool" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false" +fi +fi +DLLTOOL="$ac_cv_prog_DLLTOOL" +if test -n "$DLLTOOL"; then + echo "$ac_t""$DLLTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + DLLTOOL="false" +fi +fi + +# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1709: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="${ac_tool_prefix}as" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_AS"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1741: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="as" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + AS="false" +fi +fi + + + ;; + +esac + +# enable the --disable-libtool-lock switch + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + need_locks=$enableval +else + need_locks=yes +fi + + +if test x"$need_locks" = xno; then + libtool_flags="$libtool_flags --disable-lock" +fi + + +# Save cache, so that ltconfig can load it +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \ +DLLTOOL="$DLLTOOL" AS="$AS" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; } + +# Reload cache, that may have been modified by ltconfig +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log + + +# Check whether --enable-targets or --disable-targets was given. +if test "${enable_targets+set}" = set; then + enableval="$enable_targets" + case "${enableval}" in + yes | "") { echo "configure: error: enable-targets option must specify target names or 'all'" 1>&2; exit 1; } + ;; + no) enable_targets= ;; + *) enable_targets=$enableval ;; +esac +fi +# Check whether --enable-64-bit-bfd or --disable-64-bit-bfd was given. +if test "${enable_64_bit_bfd+set}" = set; then + enableval="$enable_64_bit_bfd" + case "${enableval}" in + yes) want64=true ;; + no) want64=false ;; + *) { echo "configure: error: bad value ${enableval} for 64-bit-bfd option" 1>&2; exit 1; } ;; +esac +else + want64=false +fi + + + + + +if test -z "$target" ; then + { echo "configure: error: Unrecognized target system type; please check config.sub." 1>&2; exit 1; } +fi +if test -z "$host" ; then + { echo "configure: error: Unrecognized host system type; please check config.sub." 1>&2; exit 1; } +fi + +# host-specific stuff: + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1910: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1940: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1991: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:2023: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 2034 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:2039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:2065: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:2070: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2079: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:2098: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:2141: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +ALL_LINGUAS= +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:2196: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 2211 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2217: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 2228 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2234: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 2245 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2251: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 +echo "configure:2276: checking for POSIXized ISC" >&5 +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 +then + echo "$ac_t""yes" 1>&6 + ISC=yes # If later tests want to check for ISC. + cat >> confdefs.h <<\EOF +#define _POSIX_SOURCE 1 +EOF + + if test "$GCC" = yes; then + CC="$CC -posix" + else + CC="$CC -Xp" + fi +else + echo "$ac_t""no" 1>&6 + ISC= +fi + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:2297: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2302 "configure" +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2310: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 2327 "configure" +#include "confdefs.h" +#include <string.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 2345 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext <<EOF +#line 2366 "configure" +#include "confdefs.h" +#include <ctype.h> +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:2377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:2401: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2406 "configure" +#include "confdefs.h" + +int main() { + +/* Ultrix mips cc rejects this. */ +typedef int charset[2]; const charset x; +/* SunOS 4.1.1 cc rejects this. */ +char const *const *ccp; +char **p; +/* NEC SVR4.0.2 mips cc rejects this. */ +struct point {int x, y;}; +static struct point const zero = {0,0}; +/* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in an arm + of an if-expression whose if-part is not a constant expression */ +const char *g = "string"; +ccp = &g + (g ? g-g : 0); +/* HPUX 7.0 cc rejects these. */ +++ccp; +p = (char**) ccp; +ccp = (char const *const *) p; +{ /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; +} +{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; +} +{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; +} +{ /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:2455: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:2476: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <<EOF +#line 2483 "configure" +#include "confdefs.h" + +int main() { +} $ac_kw foo() { +; return 0; } +EOF +if { (eval echo configure:2490: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <<EOF +#define inline $ac_cv_c_inline +EOF + ;; +esac + +echo $ac_n "checking for off_t""... $ac_c" 1>&6 +echo "configure:2516: checking for off_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2521 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_off_t=yes +else + rm -rf conftest* + ac_cv_type_off_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_off_t" 1>&6 +if test $ac_cv_type_off_t = no; then + cat >> confdefs.h <<\EOF +#define off_t long +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:2549: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2554 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 +echo "configure:2584: checking for working alloca.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2589 "configure" +#include "confdefs.h" +#include <alloca.h> +int main() { +char *p = alloca(2 * sizeof(int)); +; return 0; } +EOF +if { (eval echo configure:2596: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_header_alloca_h=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_alloca_h=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 +if test $ac_cv_header_alloca_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA_H 1 +EOF + +fi + +echo $ac_n "checking for alloca""... $ac_c" 1>&6 +echo "configure:2617: checking for alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2622 "configure" +#include "confdefs.h" + +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include <malloc.h> +# define alloca _alloca +# else +# if HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int main() { +char *p = (char *) alloca(1); +; return 0; } +EOF +if { (eval echo configure:2650: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_func_alloca_works=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_func_alloca_works=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 +if test $ac_cv_func_alloca_works = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA 1 +EOF + +fi + +if test $ac_cv_func_alloca_works = no; then + # The SVR3 libPW and SVR4 libucb both contain incompatible functions + # that cause trouble. Some versions do not even contain alloca or + # contain a buggy version. If you still want to use their alloca, + # use ar to extract alloca.o from them instead of compiling alloca.c. + ALLOCA=alloca.${ac_objext} + cat >> confdefs.h <<\EOF +#define C_ALLOCA 1 +EOF + + +echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 +echo "configure:2682: checking whether alloca needs Cray hooks" >&5 +if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2687 "configure" +#include "confdefs.h" +#if defined(CRAY) && ! defined(CRAY2) +webecray +#else +wenotbecray +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "webecray" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_os_cray=yes +else + rm -rf conftest* + ac_cv_os_cray=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_os_cray" 1>&6 +if test $ac_cv_os_cray = yes; then +for ac_func in _getb67 GETB67 getb67; do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2712: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2717 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<EOF +#define CRAY_STACKSEG_END $ac_func +EOF + + break +else + echo "$ac_t""no" 1>&6 +fi + +done +fi + +echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 +echo "configure:2767: checking stack direction for C alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat > conftest.$ac_ext <<EOF +#line 2775 "configure" +#include "confdefs.h" +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} +main () +{ + exit (find_stack_direction() < 0); +} +EOF +if { (eval echo configure:2794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_c_stack_direction=1 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_stack_direction=-1 +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 +cat >> confdefs.h <<EOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +EOF + +fi + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2819: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2824 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2829: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in getpagesize +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2858: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2863 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +echo $ac_n "checking for working mmap""... $ac_c" 1>&6 +echo "configure:2911: checking for working mmap" >&5 +if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat > conftest.$ac_ext <<EOF +#line 2919 "configure" +#include "confdefs.h" + +/* Thanks to Mike Haertel and Jim Avera for this test. + Here is a matrix of mmap possibilities: + mmap private not fixed + mmap private fixed at somewhere currently unmapped + mmap private fixed at somewhere already mapped + mmap shared not fixed + mmap shared fixed at somewhere currently unmapped + mmap shared fixed at somewhere already mapped + For private mappings, we should verify that changes cannot be read() + back from the file, nor mmap's back from the file at a different + address. (There have been systems where private was not correctly + implemented like the infamous i386 svr4.0, and systems where the + VM page cache was not coherent with the filesystem buffer cache + like early versions of FreeBSD and possibly contemporary NetBSD.) + For shared mappings, we should conversely verify that changes get + propogated back to all the places they're supposed to be. + + Grep wants private fixed already mapped. + The main things grep needs to know about mmap are: + * does it exist and is it safe to write into the mmap'd area + * how to use it (BSD variants) */ +#include <sys/types.h> +#include <fcntl.h> +#include <sys/mman.h> + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef HAVE_UNISTD_H +# include <unistd.h> +# endif + +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +#ifdef __cplusplus +extern "C" { void *malloc(unsigned); } +#else +char *malloc(); +#endif + +int +main() +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize(); + + /* + * First, make a file with some known garbage in it. + */ + data = malloc(pagesize); + if (!data) + exit(1); + for (i = 0; i < pagesize; ++i) + *(data + i) = rand(); + umask(0); + fd = creat("conftestmmap", 0600); + if (fd < 0) + exit(1); + if (write(fd, data, pagesize) != pagesize) + exit(1); + close(fd); + + /* + * Next, try to mmap the file at a fixed address which + * already has something else allocated at it. If we can, + * also make sure that we see the same garbage. + */ + fd = open("conftestmmap", O_RDWR); + if (fd < 0) + exit(1); + data2 = malloc(2 * pagesize); + if (!data2) + exit(1); + data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + exit(1); + + /* + * Finally, make sure that changes to the mapped area + * do not percolate back to the file as seen by read(). + * (This is a bug on some variants of i386 svr4.0.) + */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = malloc(pagesize); + if (!data3) + exit(1); + if (read(fd, data3, pagesize) != pagesize) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + exit(1); + close(fd); + unlink("conftestmmap"); + exit(0); +} + +EOF +if { (eval echo configure:3059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_mmap_fixed_mapped=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 +if test $ac_cv_func_mmap_fixed_mapped = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MMAP 1 +EOF + +fi + + + for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h values.h sys/param.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:3087: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3092 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3097: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \ +__argz_count __argz_stringify __argz_next +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3127: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3132 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3155: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + for ac_func in stpcpy +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3184: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3189 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3212: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_STPCPY 1 +EOF + + fi + + if test $ac_cv_header_locale_h = yes; then + echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 +echo "configure:3246: checking for LC_MESSAGES" >&5 +if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3251 "configure" +#include "confdefs.h" +#include <locale.h> +int main() { +return LC_MESSAGES +; return 0; } +EOF +if { (eval echo configure:3258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + am_cv_val_LC_MESSAGES=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + am_cv_val_LC_MESSAGES=no +fi +rm -f conftest* +fi + +echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6 + if test $am_cv_val_LC_MESSAGES = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_LC_MESSAGES 1 +EOF + + fi + fi + echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 +echo "configure:3279: checking whether NLS is requested" >&5 + # Check whether --enable-nls or --disable-nls was given. +if test "${enable_nls+set}" = set; then + enableval="$enable_nls" + USE_NLS=$enableval +else + USE_NLS=yes +fi + + echo "$ac_t""$USE_NLS" 1>&6 + + + USE_INCLUDED_LIBINTL=no + + if test "$USE_NLS" = "yes"; then + cat >> confdefs.h <<\EOF +#define ENABLE_NLS 1 +EOF + + echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 +echo "configure:3299: checking whether included gettext is requested" >&5 + # Check whether --with-included-gettext or --without-included-gettext was given. +if test "${with_included_gettext+set}" = set; then + withval="$with_included_gettext" + nls_cv_force_use_gnu_gettext=$withval +else + nls_cv_force_use_gnu_gettext=no +fi + + echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6 + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 +echo "configure:3318: checking for libintl.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3323 "configure" +#include "confdefs.h" +#include <libintl.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3328: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 +echo "configure:3345: checking for gettext in libc" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3350 "configure" +#include "confdefs.h" +#include <libintl.h> +int main() { +return (int) gettext ("") +; return 0; } +EOF +if { (eval echo configure:3357: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + gt_cv_func_gettext_libc=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gt_cv_func_gettext_libc=no +fi +rm -f conftest* +fi + +echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 + + if test "$gt_cv_func_gettext_libc" != "yes"; then + echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 +echo "configure:3373: checking for bindtextdomain in -lintl" >&5 +ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3381 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char bindtextdomain(); + +int main() { +bindtextdomain() +; return 0; } +EOF +if { (eval echo configure:3392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 +echo "configure:3408: checking for gettext in libintl" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3413 "configure" +#include "confdefs.h" + +int main() { +return (int) gettext ("") +; return 0; } +EOF +if { (eval echo configure:3420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + gt_cv_func_gettext_libintl=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gt_cv_func_gettext_libintl=no +fi +rm -f conftest* +fi + +echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_GETTEXT 1 +EOF + + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3448: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + if test "$MSGFMT" != "no"; then + for ac_func in dcgettext +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3482: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3487 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3510: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3537: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3573: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + cat > conftest.$ac_ext <<EOF +#line 3605 "configure" +#include "confdefs.h" + +int main() { +extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr +; return 0; } +EOF +if { (eval echo configure:3613: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + CATOBJEXT=.gmo + DATADIRNAME=share +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CATOBJEXT=.mo + DATADIRNAME=lib +fi +rm -f conftest* + INSTOBJEXT=.mo + fi + fi + +else + echo "$ac_t""no" 1>&6 +fi + + + + if test "$CATOBJEXT" = "NONE"; then + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + INTLOBJS="\$(GETTOBJS)" + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3645: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3679: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3715: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/../intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + if test "$XGETTEXT" != ":"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6 + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi + + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + + + + + + + + + + + + + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 +echo "configure:3805: checking for catalogs to be installed" >&5 + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + echo "$ac_t""$LINGUAS" 1>&6 + fi + + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include <locale.h>" + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header <locale.h>. Take care yourself. */" + fi + + + if test -f $srcdir/po2tbl.sed.in; then + if test "$CATOBJEXT" = ".cat"; then + ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 +echo "configure:3833: checking for linux/version.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3838 "configure" +#include "confdefs.h" +#include <linux/version.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3843: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + msgformat=linux +else + echo "$ac_t""no" 1>&6 +msgformat=xopen +fi + + + sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed + fi + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/po2tbl.sed.in > po2tbl.sed + fi + + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + + + + MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs" + + + l= + + + if test -d $srcdir/po; then + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + fi + + +echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 +echo "configure:3906: checking for Cygwin environment" >&5 +if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3911 "configure" +#include "confdefs.h" + +int main() { + +#ifndef __CYGWIN__ +#define __CYGWIN__ __CYGWIN32__ +#endif +return __CYGWIN__; +; return 0; } +EOF +if { (eval echo configure:3922: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_cygwin=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_cygwin=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_cygwin" 1>&6 +CYGWIN= +test "$ac_cv_cygwin" = yes && CYGWIN=yes +echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 +echo "configure:3939: checking for mingw32 environment" >&5 +if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3944 "configure" +#include "confdefs.h" + +int main() { +return __MINGW32__; +; return 0; } +EOF +if { (eval echo configure:3951: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_mingw32=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_mingw32=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_mingw32" 1>&6 +MINGW32= +test "$ac_cv_mingw32" = yes && MINGW32=yes + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:3970: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN" = yes || test "$MINGW32" = yes; then + ac_cv_exeext=.exe +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= + if { (eval echo configure:3980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + else + { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } + fi + rm -f conftest* + test x"${ac_cv_exeext}" = x && ac_cv_exeext=no +fi +fi + +EXEEXT="" +test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} +echo "$ac_t""${ac_cv_exeext}" 1>&6 +ac_exeext=$EXEEXT + + +for ac_prog in 'bison -y' byacc +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4006: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_YACC="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +YACC="$ac_cv_prog_YACC" +if test -n "$YACC"; then + echo "$ac_t""$YACC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$YACC" && break +done +test -n "$YACC" || YACC="yacc" + +missing_dir=`cd $ac_aux_dir && pwd` +for ac_prog in flex lex +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4042: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$LEX"; then + ac_cv_prog_LEX="$LEX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_LEX="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +LEX="$ac_cv_prog_LEX" +if test -n "$LEX"; then + echo "$ac_t""$LEX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$LEX" && break +done +test -n "$LEX" || LEX=""$missing_dir/missing flex"" + +# Extract the first word of "flex", so it can be a program name with args. +set dummy flex; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4075: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$LEX"; then + ac_cv_prog_LEX="$LEX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_LEX="flex" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex" +fi +fi +LEX="$ac_cv_prog_LEX" +if test -n "$LEX"; then + echo "$ac_t""$LEX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$LEXLIB" +then + case "$LEX" in + flex*) ac_lib=fl ;; + *) ac_lib=l ;; + esac + echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 +echo "configure:4109: checking for yywrap in -l$ac_lib" >&5 +ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-l$ac_lib $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4117 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char yywrap(); + +int main() { +yywrap() +; return 0; } +EOF +if { (eval echo configure:4128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LEXLIB="-l$ac_lib" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +echo $ac_n "checking lex output file root""... $ac_c" 1>&6 +echo "configure:4151: checking lex output file root" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # The minimal lex program is just a single line: %%. But some broken lexes +# (Solaris, I think it was) want two %% lines, so accommodate them. +echo '%% +%%' | $LEX +if test -f lex.yy.c; then + ac_cv_prog_lex_root=lex.yy +elif test -f lexyy.c; then + ac_cv_prog_lex_root=lexyy +else + { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; } +fi +fi + +echo "$ac_t""$ac_cv_prog_lex_root" 1>&6 +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root + +echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6 +echo "configure:4172: checking whether yytext is a pointer" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # POSIX says lex can declare yytext either as a pointer or an array; the +# default is implementation-dependent. Figure out which it is, since +# not all implementations provide the %pointer and %array declarations. +ac_cv_prog_lex_yytext_pointer=no +echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c +ac_save_LIBS="$LIBS" +LIBS="$LIBS $LEXLIB" +cat > conftest.$ac_ext <<EOF +#line 4184 "configure" +#include "confdefs.h" +`cat $LEX_OUTPUT_ROOT.c` +int main() { + +; return 0; } +EOF +if { (eval echo configure:4191: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_prog_lex_yytext_pointer=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +LIBS="$ac_save_LIBS" +rm -f "${LEX_OUTPUT_ROOT}.c" + +fi + +echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6 +if test $ac_cv_prog_lex_yytext_pointer = yes; then + cat >> confdefs.h <<\EOF +#define YYTEXT_POINTER 1 +EOF + +fi + + +echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 +echo "configure:4214: checking whether to enable maintainer-specific portions of Makefiles" >&5 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + + +. ${srcdir}/configure.host + + + + + + +for ac_hdr in string.h strings.h stdlib.h unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:4248: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4253 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4258: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in sbrk +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4287: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4292 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 +echo "configure:4344: checking for $ac_hdr that defines DIR" >&5 +if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4349 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <$ac_hdr> +int main() { +DIR *dirp = 0; +; return 0; } +EOF +if { (eval echo configure:4357: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + ac_header_dirent=$ac_hdr; break +else + echo "$ac_t""no" 1>&6 +fi +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then +echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 +echo "configure:4382: checking for opendir in -ldir" >&5 +ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldir $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4390 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char opendir(); + +int main() { +opendir() +; return 0; } +EOF +if { (eval echo configure:4401: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -ldir" +else + echo "$ac_t""no" 1>&6 +fi + +else +echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 +echo "configure:4423: checking for opendir in -lx" >&5 +ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lx $LIBS" +cat > conftest.$ac_ext <<EOF +#line 4431 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char opendir(); + +int main() { +opendir() +; return 0; } +EOF +if { (eval echo configure:4442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lx" +else + echo "$ac_t""no" 1>&6 +fi + +fi + + + +case "${host}" in +*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows) + cat >> confdefs.h <<\EOF +#define USE_BINARY_FOPEN 1 +EOF + ;; +esac + +echo $ac_n "checking whether strstr must be declared""... $ac_c" 1>&6 +echo "configure:4475: checking whether strstr must be declared" >&5 +if eval "test \"`echo '$''{'bfd_cv_decl_needed_strstr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4480 "configure" +#include "confdefs.h" + +#include <stdio.h> +#ifdef HAVE_STRING_H +#include <string.h> +#else +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +int main() { +char *(*pfn) = (char *(*)) strstr +; return 0; } +EOF +if { (eval echo configure:4501: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + bfd_cv_decl_needed_strstr=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + bfd_cv_decl_needed_strstr=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$bfd_cv_decl_needed_strstr" 1>&6 +if test $bfd_cv_decl_needed_strstr = yes; then + cat >> confdefs.h <<\EOF +#define NEED_DECLARATION_STRSTR 1 +EOF + +fi + +echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6 +echo "configure:4522: checking whether free must be declared" >&5 +if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4527 "configure" +#include "confdefs.h" + +#include <stdio.h> +#ifdef HAVE_STRING_H +#include <string.h> +#else +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +int main() { +char *(*pfn) = (char *(*)) free +; return 0; } +EOF +if { (eval echo configure:4548: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + bfd_cv_decl_needed_free=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + bfd_cv_decl_needed_free=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$bfd_cv_decl_needed_free" 1>&6 +if test $bfd_cv_decl_needed_free = yes; then + cat >> confdefs.h <<\EOF +#define NEED_DECLARATION_FREE 1 +EOF + +fi + +echo $ac_n "checking whether sbrk must be declared""... $ac_c" 1>&6 +echo "configure:4569: checking whether sbrk must be declared" >&5 +if eval "test \"`echo '$''{'bfd_cv_decl_needed_sbrk'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4574 "configure" +#include "confdefs.h" + +#include <stdio.h> +#ifdef HAVE_STRING_H +#include <string.h> +#else +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +int main() { +char *(*pfn) = (char *(*)) sbrk +; return 0; } +EOF +if { (eval echo configure:4595: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + bfd_cv_decl_needed_sbrk=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + bfd_cv_decl_needed_sbrk=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$bfd_cv_decl_needed_sbrk" 1>&6 +if test $bfd_cv_decl_needed_sbrk = yes; then + cat >> confdefs.h <<\EOF +#define NEED_DECLARATION_SBRK 1 +EOF + +fi + +echo $ac_n "checking whether getenv must be declared""... $ac_c" 1>&6 +echo "configure:4616: checking whether getenv must be declared" >&5 +if eval "test \"`echo '$''{'bfd_cv_decl_needed_getenv'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4621 "configure" +#include "confdefs.h" + +#include <stdio.h> +#ifdef HAVE_STRING_H +#include <string.h> +#else +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +int main() { +char *(*pfn) = (char *(*)) getenv +; return 0; } +EOF +if { (eval echo configure:4642: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + bfd_cv_decl_needed_getenv=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + bfd_cv_decl_needed_getenv=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$bfd_cv_decl_needed_getenv" 1>&6 +if test $bfd_cv_decl_needed_getenv = yes; then + cat >> confdefs.h <<\EOF +#define NEED_DECLARATION_GETENV 1 +EOF + +fi + +echo $ac_n "checking whether environ must be declared""... $ac_c" 1>&6 +echo "configure:4663: checking whether environ must be declared" >&5 +if eval "test \"`echo '$''{'bfd_cv_decl_needed_environ'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 4668 "configure" +#include "confdefs.h" + +#include <stdio.h> +#ifdef HAVE_STRING_H +#include <string.h> +#else +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +int main() { +char *(*pfn) = (char *(*)) environ +; return 0; } +EOF +if { (eval echo configure:4689: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + bfd_cv_decl_needed_environ=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + bfd_cv_decl_needed_environ=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$bfd_cv_decl_needed_environ" 1>&6 +if test $bfd_cv_decl_needed_environ = yes; then + cat >> confdefs.h <<\EOF +#define NEED_DECLARATION_ENVIRON 1 +EOF + +fi + + +# target-specific stuff: + +all_targets= +EMUL= +all_emuls= +all_emul_extras= + +rm -f tdirs + +for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'` +do + if test "$targ_alias" = "all"; then + all_targets=true + else + # Canonicalize the secondary target names. + result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ_alias 2>/dev/null` + if test -n "$result"; then + targ=$result + else + targ=$targ_alias + fi + + . ${srcdir}/configure.tgt + + if test "$targ" = "$target"; then + EMUL=$targ_emul + fi + + for i in $targ_emul $targ_extra_emuls; do + case " $all_emuls " in + *" e${i}.o "*) ;; + *) + all_emuls="$all_emuls e${i}.o" + eval result=\$tdir_$i + test -z "$result" && result=$targ_alias + echo tdir_$i=$result >> tdirs + ;; + esac + done + + for i in $targ_extra_ofiles; do + case " $all_emul_extras " in + *" ${i} "*) ;; + *) + all_emul_extras="$all_emul_extras ${i}" + ;; + esac + done + fi +done + + + +TDIRS=tdirs + + +if test x${all_targets} = xtrue; then + if test x${want64} = xtrue; then + EMULATION_OFILES='$(ALL_EMULATIONS) $(ALL_64_EMULATIONS)' + else + EMULATION_OFILES='$(ALL_EMULATIONS)' + fi + EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES)' +else + EMULATION_OFILES=$all_emuls + EMUL_EXTRA_OFILES=$all_emul_extras +fi + + + +if test x${enable_static} = xno; then + TESTBFDLIB="--rpath ../bfd/.libs ../bfd/.libs/libbfd.so" +else + TESTBFDLIB="../bfd/.libs/libbfd.a" +fi + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile po/Makefile.in:po/Make-in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@RANLIB@%$RANLIB%g +s%@CC@%$CC%g +s%@LD@%$LD%g +s%@NM@%$NM%g +s%@USE_SYMBOL_UNDERSCORE@%$USE_SYMBOL_UNDERSCORE%g +s%@LN_S@%$LN_S%g +s%@DLLTOOL@%$DLLTOOL%g +s%@AS@%$AS%g +s%@LIBTOOL@%$LIBTOOL%g +s%@CPP@%$CPP%g +s%@ALLOCA@%$ALLOCA%g +s%@USE_NLS@%$USE_NLS%g +s%@MSGFMT@%$MSGFMT%g +s%@GMSGFMT@%$GMSGFMT%g +s%@XGETTEXT@%$XGETTEXT%g +s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g +s%@CATALOGS@%$CATALOGS%g +s%@CATOBJEXT@%$CATOBJEXT%g +s%@DATADIRNAME@%$DATADIRNAME%g +s%@GMOFILES@%$GMOFILES%g +s%@INSTOBJEXT@%$INSTOBJEXT%g +s%@INTLDEPS@%$INTLDEPS%g +s%@INTLLIBS@%$INTLLIBS%g +s%@INTLOBJS@%$INTLOBJS%g +s%@POFILES@%$POFILES%g +s%@POSUB@%$POSUB%g +s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g +s%@GT_NO@%$GT_NO%g +s%@GT_YES@%$GT_YES%g +s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g +s%@l@%$l%g +s%@EXEEXT@%$EXEEXT%g +s%@YACC@%$YACC%g +s%@LEX@%$LEX%g +s%@LEXLIB@%$LEXLIB%g +s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g +s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g +s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g +s%@MAINT@%$MAINT%g +s%@HDEFINES@%$HDEFINES%g +s%@HOSTING_CRT0@%$HOSTING_CRT0%g +s%@HOSTING_LIBS@%$HOSTING_LIBS%g +s%@NATIVE_LIB_DIRS@%$NATIVE_LIB_DIRS%g +s%@EMUL@%$EMUL%g +/@TDIRS@/r $TDIRS +s%@TDIRS@%%g +s%@EMULATION_OFILES@%$EMULATION_OFILES%g +s%@EMUL_EXTRA_OFILES@%$EMUL_EXTRA_OFILES%g +s%@TESTBFDLIB@%$TESTBFDLIB%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile po/Makefile.in:po/Make-in"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS="config.h:config.in" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <<EOF + + +EOF +cat >> $CONFIG_STATUS <<\EOF +test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h +sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/ld/configure.bat b/ld/configure.bat new file mode 100644 index 0000000..4643bdb --- /dev/null +++ b/ld/configure.bat @@ -0,0 +1,72 @@ +@echo off
+echo Configuring ld for go32
+echo This makefile will be built for GNUISH make
+rem This batch file assumes a unix-type "sed" program
+
+update ..\bfd\hosts\go32.h sysdep.h
+
+echo # Makefile generated by "configure.bat"> Makefile
+echo LONGARGS = gcc:ar >> Makefile
+echo CC=gcc >> Makefile
+echo host_alias=go32 >> Makefile
+echo target_alias=go32 >> Makefile
+
+update ../bfd/hosts/go32.h sysdep.h
+
+if exist config.sed del config.sed
+
+echo "s/^ \$(srcdir)\/move-if-change/ update/ ">> config.sed
+echo "s/:\([^ ]\)/: \1/g ">> config.sed
+echo "s/^ \ *\.\// go32 / ">> config.sed
+echo "s/`echo \$(srcdir)\///g ">> config.sed
+echo "s/ | sed 's,\^\\\.\/,,'`//g ">> config.sed
+echo "s/^ cd \$(srcdir)[ ]*;// ">> config.sed
+
+echo "/^####$/ i\ ">> config.sed
+echo "CC = gcc\ ">> config.sed
+echo "EMUL=go32\ ">> config.sed
+echo "EMULATION_OFILES=ego32.o ei386aout.o ">> config.sed
+
+echo "/^SHELL *=/ d ">> config.sed
+echo "s/$(SHELL)/sh.exe/g ">> config.sed
+
+echo "s/'"/\\"/g ">> config.sed
+echo "s/"'/\\"/g ">> config.sed
+
+echo "/^ldmain.o: ldmain.c/,/fi/ { ">> config.sed
+echo " s/; *\\$// ">> config.sed
+echo " s/-DSCRIPTDIR[^ ]*/-DSCRIPTDIR=\\".\\"/ ">> config.sed
+echo " s/config.status// ">> config.sed
+echo " /ldmain.o:/ p ">> config.sed
+echo " /(CC)/ p ">> config.sed
+echo " d ">> config.sed
+echo "} ">> config.sed
+
+echo "s/^SHELL.*$/SHELL=sh.exe/ ">> config.sed
+echo "s/genscripts.sh/genscripts.dos/g ">> config.sed
+
+echo "s/^ldemul-list.h/not-ldemul-list.h/ ">> config.sed
+
+sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
+sed -f config2.sed Makefile.in >> Makefile
+del config.sed
+del config2.sed
+
+echo set -a > genscripts.dj
+sed -e "/^[a-zA-Z0-9_]*=/ s/^/export /" -e "s/(. \(.*\))/sh \1/" -e "/\.em/ d" genscripts.sh >> genscripts.dj
+type emultempl\generic.em >> genscripts.dj
+update genscripts.dj genscripts.dos
+
+echo extern ld_emulation_xfer_type ld_go32_emulation; > ldemul-list.h2
+echo extern ld_emulation_xfer_type ld_i386aout_emulation; >> ldemul-list.h2
+echo #define EMULATION_LIST \>>ldemul-list.h2
+echo &ld_go32_emulation,\>>ldemul-list.h2
+echo &ld_i386aout_emulation,\>>ldemul-list.h2
+echo 0>>ldemul-list.h2
+
+update ldemul-list.h2 ldemul-list.h
+
+if exist ldscripts\dostest goto ldscripts
+mkdir ldscripts
+dir > ldscripts\dostest
+:ldscripts
diff --git a/ld/configure.host b/ld/configure.host new file mode 100644 index 0000000..88eb311 --- /dev/null +++ b/ld/configure.host @@ -0,0 +1,171 @@ +# This is the linker host specific file. This is invoked by the +# autoconf generated configure script. Putting it in a separate shell +# file lets us skip running autoconf when modifying host specific +# information. + +# This file sets the following shell variables: +# HDEFINES host specific compiler flags +# HOSTING_CRT0 crt0.o file used for bootstrapping +# HOSTING_LIBS libraries used for bootstrapping +# NATIVE_LIB_DIRS library directories to search on this host + +HDEFINES= +HOSTING_CRT0=/lib/crt0.o +HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc' +NATIVE_LIB_DIRS= + +case "${host}" in + +alpha*-*-linux-gnu*) + HOSTING_CRT0='-dynamic-linker `egrep "ld[^ ]*\.so" \`gcc --print-file-name=specs\` | sed -e "s,.*-dynamic-linker[ ][ ]*\(.*/ld[^ ]*.so..\).*,\1,"` `gcc --print-file-name=crt1.o` `gcc --print-file-name=crti.o` `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -L`dirname \`gcc --print-file-name=libc.so\`` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc --print-file-name=crtend.o; fi` `gcc --print-file-name=crtn.o`' + ;; + +alpha*-*-netbsd*) + # The new BSD `make' has a bug: it doesn't pass empty arguments in + # shell commands. So we need to make this value non-empty in order + # for the genscripts.sh call to work. There's nothing magic about + # the value `/lib'; it's just a dummy. + NATIVE_LIB_DIRS=/lib + HOSTING_CRT0=/usr/lib/crt0.o + ;; + +alpha*-*-*) + HOSTING_CRT0=/usr/ccs/lib/crt0.o + NATIVE_LIB_DIRS=/usr/ccs/lib + ;; + +i[3456]86-*-bsd* | i[3456]86-*-freebsd* | i[3456]86-*-netbsd*) + # The new BSD `make' has a bug: it doesn't pass empty arguments in + # shell commands. So we need to make this value non-empty in order + # for the genscripts.sh call to work. There's nothing magic about + # the value `/lib'; it's just a dummy. + NATIVE_LIB_DIRS=/lib + HOSTING_CRT0=/usr/lib/crt0.o + ;; + +i[3456]86-*-sysv4*) + HOSTING_CRT0='/usr/ccs/lib/crt1.o /usr/ccs/lib/crti.o /usr/ccs/lib/values-Xa.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` /usr/ccs/lib/crtn.o' + NATIVE_LIB_DIRS=/usr/ccs/lib + ;; + +i[3456]86-sequent-ptx* | i[3456]86-sequent-sysv*) + HOSTING_CRT0='/lib/crt0.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi`' + ;; + +i[3456]86-*-sysv*) + HOSTING_CRT0='/lib/crt1.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; fi` /lib/crtn.o' + ;; + +i[3456]86-*-solaris*) + HOSTING_CRT0='`if [ -f ../gcc/crt1.o ]; then echo ../gcc/crt1.o; else gcc -print-file-name=crt1.o; fi` `if [ -f ../gcc/crti.o ]; then echo ../gcc/crti.o; else gcc -print-file-name=crti.o; fi` /usr/ccs/lib/values-Xa.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` `if [ -f ../gcc/crtn.o ]; then echo ../gcc/crtn.o; else gcc -print-file-name=crtn.o; fi`' + NATIVE_LIB_DIRS=/usr/ccs/lib + ;; + +i[3456]86-*-sco* | i[3456]86-*-isc*) + # In some configurations gcc does not use crtbegin.o and crtend.o. + # In that case gcc -print-file-name=crtbegin.o will simply print + # crtbegin.o. We create dummy crtbegin.o and crtend.o files to + # handle this. + echo "int dummy_crtbegin () { return 0; }" > crtbegin.c + ${CC} -c crtbegin.c -o crtbegin.o + rm -f crtbegin.c + echo "int dummy_crteng () { return 0; }" > crtend.c + ${CC} -c crtend.c -o crtend.o + rm -f crtend.c + HOSTING_CRT0='/lib/crt1.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` /lib/crtn.o' + ;; + +i[3456]86-*-linux*aout* | i[3456]86-*-linuxoldld) + HOSTING_CRT0=/usr/lib/crt0.o + ;; + +i[3456]86-*-linux*libc1*) + HOSTING_CRT0='-dynamic-linker /lib/ld-linux.so.1 /usr/lib/crt1.o /usr/lib/crti.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; elif [ -f /usr/lib/crtbegin.o ]; then echo /usr/lib/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; elif [ -f /usr/lib/crtend.o ]; then echo /usr/lib/crtend.o; else gcc --print-file-name=crtend.o; fi` /usr/lib/crtn.o' + ;; + +i[3456]86-*-linux-gnu*) + HOSTING_CRT0='-dynamic-linker `fgrep ld-linux.so \`gcc --print-file-name=specs\` | sed -e "s,.*-dynamic-linker[ ][ ]*\(.*/ld-linux.so..\).*,\1,"` `gcc --print-file-name=crt1.o` `gcc --print-file-name=crti.o` `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -L`dirname \`gcc --print-file-name=libc.so\`` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc --print-file-name=crtend.o; fi` `gcc --print-file-name=crtn.o`' + ;; + +i[3456]86-*-lynxos*) + HOSTING_CRT0=/lib/init1.o + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc -lm /lib/initn.o' + ;; + +mips*-dec-bsd*) + HOSTING_CRT0=/usr/lib/crt0.o + ;; + +mips*-sgi-irix4*) + HOSTING_CRT0=/usr/lib/crt1.o + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc /usr/lib/crtn.o' + ;; + +mips*-sgi-irix[56]*) + HOSTING_CRT0=/usr/lib/crt1.o + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc /usr/lib/crtn.o' + ;; + +m68*-*-linux*aout*) + HOSTING_CRT0=/usr/lib/crt0.o + ;; + +m68*-*-linux*libc1*) + HOSTING_CRT0='-dynamic-linker /lib/ld-linux.so.1 /usr/lib/crt1.o /usr/lib/crti.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; elif [ -f /usr/lib/crtbegin.o ]; then echo /usr/lib/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; elif [ -f /usr/lib/crtend.o ]; then echo /usr/lib/crtend.o; else gcc --print-file-name=crtend.o; fi` /usr/lib/crtn.o' + ;; + +m68*-*-linux-gnu*) + HOSTING_CRT0='-dynamic-linker /lib/ld.so.1 /usr/lib/crt1.o /usr/lib/crti.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc --print-file-name=crtend.o; fi` /usr/lib/crtn.o' + ;; + +m68*-*-lynxos*) + HOSTING_CRT0=/lib/init1.o + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc -lm /lib/initn.o' + ;; + +m68*-motorola-sysv) + HOSTING_CRT0='`if [ -f ../gcc/crt0.o ]; then echo ../gcc/crt0.o; elif [ -f \`gcc -print-file-name=\`crt0.o ]; then echo \`gcc -print-file-name=\`crt0.o; else echo /lib/crt0.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc881 `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi`' + ;; + +m68*-sun-*) + HOSTING_CRT0='/usr/lib/crt0.o /usr/lib/Fcrt1.o -L/usr/lib/fsoft.o' + ;; + +m88*-*-dgux*) + HDEFINES=-D__using_DGUX + HOSTING_CRT0='/lib/crt0.o -X' + HOSTING_LIBS=/usr/sde/m88kbcs/lib/libc.a + ;; + +m88*-motorola-sysv3) + HOSTING_CRT0='/lib/crt0.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi`' + ;; + +powerpc*-*-linux-gnu*) + HOSTING_CRT0='-dynamic-linker /lib/ld.so.1 /usr/lib/crt1.o /usr/lib/crti.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc --print-file-name=crtend.o; fi` /usr/lib/crtn.o' + ;; + +romp-*-*) + HDEFINES=-DNO_VARARGS + ;; + +sparc*-*-solaris2*) + HOSTING_CRT0='`if [ -f ../gcc/crt1.o ]; then echo ../gcc/crt1.o; else gcc -print-file-name=crt1.o; fi` `if [ -f ../gcc/crti.o ]; then echo ../gcc/crti.o; else gcc -print-file-name=crti.o; fi` /usr/ccs/lib/values-Xa.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` `if [ -f ../gcc/crtn.o ]; then echo ../gcc/crtn.o; else gcc -print-file-name=crtn.o; fi`' + NATIVE_LIB_DIRS=/usr/ccs/lib + ;; + +esac diff --git a/ld/configure.in b/ld/configure.in new file mode 100644 index 0000000..7f3c1da --- /dev/null +++ b/ld/configure.in @@ -0,0 +1,156 @@ +dnl Process this file with autoconf to produce a configure script +dnl +AC_PREREG(2.13) +AC_INIT(ldmain.c) + +AC_CANONICAL_SYSTEM + +AM_INIT_AUTOMAKE(ld, 2.9.4) + +AM_PROG_LIBTOOL + +AC_ARG_ENABLE(targets, +[ --enable-targets alternative target configurations], +[case "${enableval}" in + yes | "") AC_ERROR(enable-targets option must specify target names or 'all') + ;; + no) enable_targets= ;; + *) enable_targets=$enableval ;; +esac])dnl +AC_ARG_ENABLE(64-bit-bfd, +[ --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes)], +[case "${enableval}" in + yes) want64=true ;; + no) want64=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for 64-bit-bfd option) ;; +esac],[want64=false])dnl + +AM_CONFIG_HEADER(config.h:config.in) + +if test -z "$target" ; then + AC_MSG_ERROR(Unrecognized target system type; please check config.sub.) +fi +if test -z "$host" ; then + AC_MSG_ERROR(Unrecognized host system type; please check config.sub.) +fi + +# host-specific stuff: + +AC_PROG_CC +AC_PROG_INSTALL + +ALL_LINGUAS= +CY_GNU_GETTEXT + +AC_EXEEXT + +AC_PROG_YACC +AM_PROG_LEX + +AM_MAINTAINER_MODE + +. ${srcdir}/configure.host + +AC_SUBST(HDEFINES) +AC_SUBST(HOSTING_CRT0) +AC_SUBST(HOSTING_LIBS) +AC_SUBST(NATIVE_LIB_DIRS) + +AC_CHECK_HEADERS(string.h strings.h stdlib.h unistd.h) +AC_CHECK_FUNCS(sbrk) +AC_HEADER_DIRENT + +BFD_BINARY_FOPEN + +BFD_NEED_DECLARATION(strstr) +BFD_NEED_DECLARATION(free) +BFD_NEED_DECLARATION(sbrk) +BFD_NEED_DECLARATION(getenv) +BFD_NEED_DECLARATION(environ) + +# target-specific stuff: + +all_targets= +EMUL= +all_emuls= +all_emul_extras= + +dnl We need to get an arbitrary number of tdir definitions into +dnl Makefile. We can't do it using AC_SUBST, because autoconf does +dnl not permit literal newlines in an AC_SUBST variables. So we use a +dnl file. +rm -f tdirs + +for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'` +do + if test "$targ_alias" = "all"; then + all_targets=true + else + # Canonicalize the secondary target names. + result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ_alias 2>/dev/null` + if test -n "$result"; then + targ=$result + else + targ=$targ_alias + fi + + . ${srcdir}/configure.tgt + + if test "$targ" = "$target"; then + EMUL=$targ_emul + fi + + for i in $targ_emul $targ_extra_emuls; do + case " $all_emuls " in + *" e${i}.o "*) ;; + *) + all_emuls="$all_emuls e${i}.o" + eval result=\$tdir_$i + test -z "$result" && result=$targ_alias + echo tdir_$i=$result >> tdirs + ;; + esac + done + + for i in $targ_extra_ofiles; do + case " $all_emul_extras " in + *" ${i} "*) ;; + *) + all_emul_extras="$all_emul_extras ${i}" + ;; + esac + done + fi +done + +AC_SUBST(EMUL) + +TDIRS=tdirs +AC_SUBST_FILE(TDIRS) + +dnl FIXME: We will build a 64 bit BFD for a 64 bit host or a 64 bit +dnl target, and in those cases we should also build the 64 bit +dnl emulations. +if test x${all_targets} = xtrue; then + if test x${want64} = xtrue; then + EMULATION_OFILES='$(ALL_EMULATIONS) $(ALL_64_EMULATIONS)' + else + EMULATION_OFILES='$(ALL_EMULATIONS)' + fi + EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES)' +else + EMULATION_OFILES=$all_emuls + EMUL_EXTRA_OFILES=$all_emul_extras +fi +AC_SUBST(EMULATION_OFILES) +AC_SUBST(EMUL_EXTRA_OFILES) + +if test x${enable_static} = xno; then + TESTBFDLIB="--rpath ../bfd/.libs ../bfd/.libs/libbfd.so" +else + TESTBFDLIB="../bfd/.libs/libbfd.a" +fi +AC_SUBST(TESTBFDLIB) + +AC_OUTPUT(Makefile po/Makefile.in:po/Make-in, +[sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile]) diff --git a/ld/configure.tgt b/ld/configure.tgt new file mode 100644 index 0000000..d0555ce --- /dev/null +++ b/ld/configure.tgt @@ -0,0 +1,249 @@ +# This is the linker target specific file. This is invoked by the +# autoconf generated configure script. Putting it in a separate shell +# file lets us skip running autoconf when modifying target specific +# information. + +# This file switches on the shell variable ${targ}, and sets the +# following shell variables: +# targ_emul name of linker emulation to use +# targ_extra_emuls additional linker emulations to provide +# targ_extra_ofiles additional objects needed by the emulation + +targ_extra_emuls= +targ_extra_ofiles= + +case "${targ}" in +arm-epoc-pe) targ_emul=arm_epoc_pe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; +arm-*-pe) targ_emul=armpe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; +arc-*-elf*) targ_emul=arcelf ;; +d10v-*-*) targ_emul=d10velf ;; +d30v-*-*ext*) targ_emul=d30v_e; targ_extra_emuls="d30velf d30v_o" ;; +d30v-*-*onchip*) targ_emul=d30v_o; targ_extra_emuls="d30velf d30v_e" ;; +d30v-*-*) targ_emul=d30velf; targ_extra_emuls="d30v_e d30v_o" ;; +sparc64-*-aout*) targ_emul=sparcaout ;; +sparc64-*-elf*) targ_emul=elf64_sparc ;; +sparc-sun-sunos4*) targ_emul=sun4 ;; +sparclite*-*-elf) targ_emul=elf32_sparc ;; +sparclite*-*-coff) targ_emul=coff_sparc ;; +sparclite*-fujitsu-*) targ_emul=sparcaout ;; +sparc*-*-aout) targ_emul=sparcaout ;; +sparc*-*-coff) targ_emul=coff_sparc ;; +sparc*-*-elf) targ_emul=elf32_sparc ;; +sparc*-*-sysv4*) targ_emul=elf32_sparc ;; +sparc*-*-linux*aout*) targ_emul=sparclinux + targ_extra_emuls="elf32_sparc sun4" + tdir_elf32_sparc=`echo ${targ_alias} | sed -e 's/aout//'` + tdir_sun4=sparc-sun-sunos4 + ;; +sparc64-*-linux-gnu*) targ_emul=elf64_sparc + targ_extra_emuls="elf32_sparc sparclinux sun4" + tdir_elf32_sparc=`echo ${targ_alias} | sed -e 's/64//'` + tdir_sparclinux=${tdir_elf32_sparc}aout + tdir_sun4=sparc-sun-sunos4 + ;; +sparc*-*-linux-gnu*) targ_emul=elf32_sparc + targ_extra_emuls="sparclinux sun4" + tdir_sparclinux=${targ_alias}aout + tdir_sun4=sparc-sun-sunos4 + ;; +sparc*-*-lynxos*) targ_emul=sparclynx ;; +sparc*-*-netbsd*) targ_emul=sparcnbsd ;; +sparc*-*-solaris2*) targ_emul=elf32_sparc ;; +sparc*-wrs-vxworks*) targ_emul=sparcaout ;; +sparc*-*-rtems*) targ_emul=sparcaout ;; +i960-wrs-vxworks5.0*) targ_emul=gld960 ;; +i960-wrs-vxworks5*) targ_emul=gld960coff ;; +i960-wrs-vxworks*) targ_emul=gld960 ;; +i960-*-coff) targ_emul=gld960coff ;; +i960-intel-nindy) targ_emul=gld960 ;; +i960-*-rtems*) targ_emul=gld960coff ;; +m32r-*-*) targ_emul=m32relf ;; +m68*-sun-sunos[34]*) targ_emul=sun3 ;; +m68*-wrs-vxworks*) targ_emul=sun3 ;; +m68*-ericsson-ose) targ_emul=sun3 ;; +m68*-apple-aux*) targ_emul=m68kaux ;; +*-tandem-none) targ_emul=st2000 ;; +i[3456]86-*-vsta) targ_emul=vsta ;; +i[3456]86-go32-rtems*) targ_emul=i386go32 ;; +i[3456]86-*-go32) targ_emul=i386go32 ;; +i[3456]86-*-msdosdjgpp*) targ_emul=i386go32 ;; +i[3456]86-*-aix*) targ_emul=i386coff ;; +i[3456]86-*-sco*) targ_emul=i386coff ;; +i[3456]86-*-isc*) targ_emul=i386coff ;; +i[3456]86-*-lynxos*) targ_emul=i386lynx ;; +i[3456]86-*-coff) targ_emul=i386coff ;; +i[3456]86-*-rtems*) targ_emul=i386coff ;; +i[3456]86-*-bsd) targ_emul=i386bsd ;; +i[3456]86-*-bsd386) targ_emul=i386bsd ;; +i[3456]86-*-bsdi*) targ_emul=i386bsd ;; +i[3456]86-*-aout) targ_emul=i386aout ;; +i[3456]86-*-linux*aout*) targ_emul=i386linux + targ_extra_emuls=elf_i386 + tdir_elf_i386=`echo ${targ_alias} | sed -e 's/aout//'` + ;; +i[3456]86-*-linuxoldld) targ_emul=i386linux; targ_extra_emuls=elf_i386 ;; +i[3456]86-*-linux-gnu*) targ_emul=elf_i386 + targ_extra_emuls=i386linux + tdir_i386linux=${targ_alias}aout + ;; +i[3456]86-*-sysv4*) targ_emul=elf_i386 ;; +i[3456]86-*-solaris2*) targ_emul=elf_i386 ;; +i[3456]86-*-unixware) targ_emul=elf_i386 ;; +i[3456]86-*-solaris*) targ_emul=elf_i386 ;; +i[3456]86-*-netbsd*) targ_emul=i386nbsd ;; +i[3456]86-*-netware) targ_emul=i386nw ;; +i[3456]86-*-elf*) targ_emul=elf_i386 ;; +i[3456]86-*-freebsdelf*) targ_emul=elf_i386 ;; +i[3456]86-*-freebsd*) targ_emul=i386bsd ;; +i[3456]86-*-sysv*) targ_emul=i386coff ;; +i[3456]86-*-ptx*) targ_emul=i386coff ;; +i[3456]86-*-mach*) targ_emul=i386mach ;; +i[3456]86-*-gnu*) targ_emul=elf_i386 ;; +i[3456]86-*-msdos*) targ_emul=i386msdos; targ_extra_emuls=i386aout ;; +i[3456]86-*-moss*) targ_emul=i386moss; targ_extra_emuls=i386msdos ;; +i[3456]86-*-winnt*) targ_emul=i386pe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; +i[3456]86-*-pe) targ_emul=i386pe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; +i[3456]86-*-cygwin*) targ_emul=i386pe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; +i[3456]86-*-mingw32*) targ_emul=i386pe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; +i[3456]86-*-beospe*) targ_emul=i386beos ;; +i[3456]86-*-beos*) targ_emul=elf_i386_be ;; +m8*-*-*) targ_emul=m88kbcs ;; +a29k-*-udi) targ_emul=sa29200 ;; +a29k-*-ebmon) targ_emul=ebmon29k ;; +a29k-*-*) targ_emul=a29k ;; +# arm-*-riscix*) targ_emul=riscix ;; +arm-*-aout | armel-*-aout) targ_emul=armaoutl ;; +armeb-*-aout) targ_emul=armaoutb ;; +arm-*-coff) targ_emul=armcoff ;; +arm-*-elf) targ_emul=armelf ;; +arm-*-oabi) targ_emul=armelf_oabi ;; +arm*-*-linux-gnu*) targ_emul=armelf_linux; targ_extra_emuls="armelf_linux26 armelf";; +strongarm-*-coff) targ_emul=armcoff ;; +strongarm-*-elf) targ_emul=armelf ;; +thumb-*-coff) targ_emul=armcoff ;; +thumb-*-elf) targ_emul=armelf ;; +thumb-*-oabi) targ_emul=armelf_oabi ;; +thumb-epoc-pe) targ_emul=arm_epoc_pe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; +thumb-*-pe) targ_emul=armpe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; +h8300-*-hms* | h8300-*-coff*) + targ_emul=h8300; targ_extra_emuls="h8300h h8300s" + ;; +h8500-*-hms* | h8500-*-coff*) + targ_emul=h8500 + targ_extra_emuls="h8500s h8500b h8500m h8500c" + ;; +sh-*-elf*) targ_emul=shelf + targ_extra_emuls="shlelf sh shl" + ;; +sh-*-*|sh-*-rtems*) targ_emul=sh; targ_extra_emuls=shl ;; +m68k-sony-*) targ_emul=news ;; +m68k-hp-bsd*) targ_emul=hp300bsd ;; +m68*-motorola-sysv*) targ_emul=delta68 ;; +m68*-*-aout) targ_emul=m68kaout ;; +m68*-*-coff) targ_emul=m68kcoff ;; +m68*-*-elf) targ_emul=m68kelf ;; +m68*-*-hpux*) targ_emul=hp3hpux ;; +m68k-*-linux*aout*) targ_emul=m68klinux + targ_extra_emuls=m68kelf + tdir_m68kelf=`echo ${targ_alias} | sed -e 's/aout//'` + ;; +m68k-*-linux-gnu*) targ_emul=m68kelf + targ_extra_emuls=m68klinux + tdir_m68klinux=`echo ${targ_alias} | sed -e 's/linux/linuxaout/'` + ;; +m68*-*-gnu*) targ_emul=m68kelf ;; +m68*-*-lynxos*) targ_emul=m68klynx ;; +m68*-hp*-netbsd*) targ_emul=m68k4knbsd ;; +m68*-*-netbsd*) targ_emul=m68knbsd ;; +m68*-*-psos*) targ_emul=m68kpsos ;; +m68*-*-rtems*) targ_emul=m68kcoff ;; +hppa*-*-*elf*) targ_emul=hppaelf ;; +hppa*-*-lites*) targ_emul=hppaelf ;; +hppa*-*-rtems*) targ_emul=hppaelf ;; +vax-dec-ultrix* | vax-dec-bsd*) targ_emul=vax ;; +mips*-dec-ultrix*) targ_emul=mipslit ;; +mips*-dec-osf*) targ_emul=mipslit ;; +mips*-sgi-irix[56]*) targ_emul=elf32bsmip ;; +mips*-sgi-irix*) targ_emul=mipsbig ;; +mips*el-*-ecoff*) targ_emul=mipsidtl ;; +mips*-*-ecoff*) targ_emul=mipsidt ;; +mips*-dec-bsd*) targ_emul=mipsbsd ;; +mips*-dec-netbsd*) targ_emul=elf32lmip ;; +mips*-*-bsd*) targ_emul=mipsbig ;; +mips*vr4300el-*-elf*) targ_emul=elf32l4300 ;; +mips*vr4300-*-elf*) targ_emul=elf32b4300 ;; +mips*vr4100el-*-elf*) targ_emul=elf32l4300 ;; +mips*vr4100-*-elf*) targ_emul=elf32b4300 ;; +mips*vr5000el-*-elf*) targ_emul=elf32l4300 ;; +mips*vr5000-*-elf*) targ_emul=elf32b4300 ;; +mips*el-*-elf*) targ_emul=elf32elmip ;; +mips*-*-elf*) targ_emul=elf32ebmip ;; +mips*-*-rtems*) targ_emul=elf32ebmip ;; +mips*-*-vxworks*) targ_emul=elf32ebmip ;; +mips*el-*-linux-gnu*) targ_emul=elf32lsmip + targ_extra_emuls="elf32bsmip mipslit mipsbig" + ;; +mips*-*-linux-gnu*) targ_emul=elf32bsmip + targ_extra_emuls="elf32lsmip mipsbig mipslit" + ;; +mips*-*-lnews*) targ_emul=mipslnews ;; +mn10200-*-*) targ_emul=mn10200 ;; +mn10300-*-*) targ_emul=mn10300 ;; +alpha*-*-linuxecoff*) targ_emul=alpha targ_extra_emuls=elf64alpha + tdir_elf64alpha=`echo ${targ_alias} | sed -e 's/ecoff//'` + ;; +alpha*-*-linux-gnu*) targ_emul=elf64alpha targ_extra_emuls=alpha + tdir_alpha=`echo ${targ_alias} | sed -e 's/linux/linuxecoff/'` + ;; +alpha*-*-osf*) targ_emul=alpha ;; +alpha*-*-gnu*) targ_emul=elf64alpha ;; +alpha*-*-netware*) targ_emul=alpha ;; +alpha*-*-netbsd*) targ_emul=elf64alpha ;; +z8k-*-coff) targ_emul=z8002; targ_extra_emuls=z8001 ;; +ns32k-pc532-mach* | ns32k-pc532-ux*) targ_emul=pc532macha ;; +ns32k-pc532-netbsd* | ns32k-pc532-lites*) targ_emul=ns32knbsd ;; +powerpc-*-elf* | powerpc-*-eabi* | powerpc-*-linux-gnu* | powerpc-*-sysv* \ + | powerpc-*-netbsd* | powerpc-*-vxworks*) + targ_emul=elf32ppc ;; +powerpcle-*-elf* | powerpcle-*-eabi* | powerpcle-*-solaris* \ + | powerpcle-*-sysv* | powerpcle-*-vxworks*) + targ_emul=elf32lppc ;; +powerpc-*-rtems*) targ_emul=elf32ppc ;; +powerpc-*-macos*) targ_emul=ppcmacos ;; +powerpc-*-netware*) targ_emul=ppcnw ;; +powerpcle-*-pe) targ_emul=ppcpe ;; +powerpcle-*-winnt*) targ_emul=ppcpe ;; +powerpcle-*-cygwin*) targ_emul=ppcpe ;; +powerpc-*-aix*) targ_emul=aixppc ;; +powerpc-*-beos*) targ_emul=aixppc ;; +rs6000-*-aix*) targ_emul=aixrs6 ;; +tic30-*-*aout*) targ_emul=tic30aout ;; +tic30-*-*coff*) targ_emul=tic30coff ;; +tic80-*-*) targ_emul=tic80coff ;; +v850-*-*) targ_emul=v850 ;; +v850e-*-*) targ_emul=v850 ;; +v850ea-*-*) targ_emul=v850 ;; +w65-*-*) targ_emul=w65 ;; +fr30-*-*) targ_emul=elf32fr30 ;; +mcore-*-pe) targ_emul=mcorepe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; +mcore-*-elf) targ_emul=elf32mcore ;; +*-*-aout) targ_emul=${target_cpu}-${target_vendor} ;; +*-*-coff) targ_emul=${target_cpu}-${target_vendor} ;; +*-*-netware) targ_emul=${target_cpu}-nw ;; +*-*-ieee*) targ_emul=vanilla ;; + +*) + echo 2>&1 "*** ld does not support target ${targ}" + echo 2>&1 "*** see ld/configure.tgt for supported targets" + exit 1 + +esac diff --git a/ld/deffile.h b/ld/deffile.h new file mode 100644 index 0000000..3c6c1ce --- /dev/null +++ b/ld/deffile.h @@ -0,0 +1,123 @@ +/* deffile.h - header for .DEF file parser + Copyright (C) 1998, 1999 Free Software Foundation, Inc. + Written by DJ Delorie dj@cygnus.com + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "ansidecl.h" + +/* DEF storage definitions. Note that any ordinal may be zero, and + any pointer may be NULL, if not defined by the DEF file. */ + +typedef struct def_file_section + { + char *name; /* always set */ + char *class; /* may be NULL */ + char flag_read, flag_write, flag_execute, flag_shared; + } +def_file_section; + +typedef struct def_file_export + { + char *name; /* always set */ + char *internal_name; /* always set, may == name */ + int ordinal; /* -1 if not specified */ + int hint; + char flag_private, flag_constant, flag_noname, flag_data; + } +def_file_export; + +typedef struct def_file_module + { + struct def_file_module *next; + void *user_data; + char name[1]; /* extended via malloc */ + } +def_file_module; + +typedef struct def_file_import + { + char *internal_name; /* always set */ + def_file_module *module; /* always set */ + char *name; /* may be NULL; either this or ordinal will be set */ + int ordinal; /* may be -1 */ + } +def_file_import; + +typedef struct def_file + { + + /* from the NAME or LIBRARY command */ + char *name; + int is_dll; /* -1 if NAME/LIBRARY not given */ + bfd_vma base_address; /* (bfd_vma)(-1) if unspecified */ + + /* from the DESCRIPTION command */ + char *description; + + /* from the STACK/HEAP command, -1 if unspecified */ + int stack_reserve, stack_commit; + int heap_reserve, heap_commit; + + /* from the SECTION/SEGMENT commands */ + int num_section_defs; + def_file_section *section_defs; + + /* from the EXPORTS commands */ + int num_exports; + def_file_export *exports; + + /* used by imports for module names */ + def_file_module *modules; + + /* from the IMPORTS commands */ + int num_imports; + def_file_import *imports; + + /* from the VERSION command, -1 if not specified */ + int version_major, version_minor; + } +def_file; + +extern def_file *def_file_empty PARAMS ((void)); + +/* add_to may be NULL. If not, this .def is appended to it */ +extern def_file *def_file_parse PARAMS ((const char *_filename, + def_file * _add_to)); + +extern void def_file_free PARAMS ((def_file * _def)); + +extern def_file_export *def_file_add_export PARAMS ((def_file * _def, + const char *_name, + const char *_internal_name, + int _ordinal)); + +extern def_file_import *def_file_add_import PARAMS ((def_file * _def, + const char *_name, + const char *_from, + int _ordinal, + const char *_imported_name)); + +extern void def_file_add_directive PARAMS ((def_file * _def, + const char *param, + int len)); + +#ifdef DEF_FILE_PRINT +extern void def_file_print PARAMS ((FILE * _file, + def_file * _def)); +#endif diff --git a/ld/deffilep.y b/ld/deffilep.y new file mode 100644 index 0000000..aacde6b --- /dev/null +++ b/ld/deffilep.y @@ -0,0 +1,1004 @@ +%{ /* deffilep.y - parser for .def files */ + +/* Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include <stdio.h> +#include <ctype.h> +#include "libiberty.h" +#include "bfd.h" +#include "sysdep.h" +#include "ld.h" +#include "ldmisc.h" +#include "deffile.h" + +#define TRACE 0 + +#define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1)) + +/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), + as well as gratuitiously global symbol names, so we can have multiple + yacc generated parsers in ld. Note that these are only the variables + produced by yacc. If other parser generators (bison, byacc, etc) produce + additional global names that conflict at link time, then those parser + generators need to be fixed instead of adding those names to this list. */ + +#define yymaxdepth def_maxdepth +#define yyparse def_parse +#define yylex def_lex +#define yyerror def_error +#define yylval def_lval +#define yychar def_char +#define yydebug def_debug +#define yypact def_pact +#define yyr1 def_r1 +#define yyr2 def_r2 +#define yydef def_def +#define yychk def_chk +#define yypgo def_pgo +#define yyact def_act +#define yyexca def_exca +#define yyerrflag def_errflag +#define yynerrs def_nerrs +#define yyps def_ps +#define yypv def_pv +#define yys def_s +#define yy_yys def_yys +#define yystate def_state +#define yytmp def_tmp +#define yyv def_v +#define yy_yyv def_yyv +#define yyval def_val +#define yylloc def_lloc +#define yyreds def_reds /* With YYDEBUG defined */ +#define yytoks def_toks /* With YYDEBUG defined */ +#define yylhs def_yylhs +#define yylen def_yylen +#define yydefred def_yydefred +#define yydgoto def_yydgoto +#define yysindex def_yysindex +#define yyrindex def_yyrindex +#define yygindex def_yygindex +#define yytable def_yytable +#define yycheck def_yycheck + +static int def_lex (); + +static void def_description PARAMS ((const char *)); +static void def_exports PARAMS ((const char *, const char *, int, int)); +static void def_heapsize PARAMS ((int, int)); +static void def_import + PARAMS ((const char *, const char *, const char *, const char *, int)); +static void def_library PARAMS ((const char *, int)); +static void def_name PARAMS ((const char *, int)); +static void def_section PARAMS ((const char *, int)); +static void def_section_alt PARAMS ((const char *, const char *)); +static void def_stacksize PARAMS ((int, int)); +static void def_version PARAMS ((int, int)); +static void def_directive PARAMS ((char *)); +static int def_parse PARAMS ((void)); +static int def_error PARAMS ((const char *)); +static int def_debug; +static int def_lex PARAMS ((void)); + +static int lex_forced_token = 0; +static const char *lex_parse_string = 0; +static const char *lex_parse_string_end = 0; + +%} + +%union { + char *id; + int number; +}; + +%token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATA +%token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANT, PRIVATE +%token READ WRITE EXECUTE SHARED NONAME DIRECTIVE +%token <id> ID +%token <number> NUMBER +%type <number> opt_base opt_ordinal +%type <number> attr attr_list opt_number exp_opt_list exp_opt +%type <id> opt_name opt_equal_name + +%% + +start: start command + | command + ; + +command: + NAME opt_name opt_base { def_name ($2, $3); } + | LIBRARY opt_name opt_base { def_library ($2, $3); } + | DESCRIPTION ID { def_description ($2);} + | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);} + | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);} + | CODE attr_list { def_section ("CODE", $2);} + | DATA attr_list { def_section ("DATA", $2);} + | SECTIONS seclist + | EXPORTS explist + | IMPORTS implist + | VERSIONK NUMBER { def_version ($2, 0);} + | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);} + | DIRECTIVE ID { def_directive ($2);} + ; + + +explist: + /* EMPTY */ + | expline + | explist expline + ; + +expline: + ID opt_equal_name opt_ordinal exp_opt_list + { def_exports ($1, $2, $3, $4); } + ; +exp_opt_list: + exp_opt exp_opt_list { $$ = $1 | $2; } + | { $$ = 0; } + ; +exp_opt: + NONAME { $$ = 1; } + | CONSTANT { $$ = 2; } + | DATA { $$ = 4; } + | PRIVATE { $$ = 8; } + ; +implist: + implist impline + | impline + ; + +impline: + ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); } + | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); } + | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); } + | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); } + | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); } + | ID '.' ID { def_import ( 0, $1, 0, $3, -1); } +; + +seclist: + seclist secline + | secline + ; + +secline: + ID attr_list { def_section ($1, $2);} + | ID ID { def_section_alt ($1, $2);} + ; + +attr_list: + attr_list opt_comma attr { $$ = $1 | $3; } + | attr { $$ = $1; } + ; + +opt_comma: + ',' + | + ; +opt_number: ',' NUMBER { $$=$2;} + | { $$=-1;} + ; + +attr: + READ { $$ = 1;} + | WRITE { $$ = 2;} + | EXECUTE { $$=4;} + | SHARED { $$=8;} + ; + +opt_name: ID { $$ = $1; } + | { $$ = 0; } + ; + +opt_ordinal: + '@' NUMBER { $$ = $2;} + | { $$ = -1;} + ; + +opt_equal_name: + '=' ID { $$ = $2; } + | { $$ = 0; } + ; + +opt_base: BASE '=' NUMBER { $$ = $3;} + | { $$ = 0;} + ; + + + +%% + +/***************************************************************************** + API + *****************************************************************************/ + +static FILE *the_file; +static const char *def_filename; +static int linenumber; +static def_file *def; +static int saw_newline; + +struct directive + { + struct directive *next; + char *name; + int len; + }; + +static struct directive *directives = 0; + +def_file * +def_file_empty () +{ + def_file *rv = (def_file *) xmalloc (sizeof (def_file)); + memset (rv, 0, sizeof (def_file)); + rv->is_dll = -1; + rv->base_address = (bfd_vma) (-1); + rv->stack_reserve = rv->stack_commit = -1; + rv->heap_reserve = rv->heap_commit = -1; + rv->version_major = rv->version_minor = -1; + return rv; +} + +def_file * +def_file_parse (filename, add_to) + const char *filename; + def_file *add_to; +{ + struct directive *d; + + the_file = fopen (filename, "r"); + def_filename = filename; + linenumber = 1; + if (!the_file) + { + perror (filename); + return 0; + } + if (add_to) + { + def = add_to; + } + else + { + def = def_file_empty (); + } + + saw_newline = 1; + if (def_parse ()) + { + def_file_free (def); + fclose (the_file); + return 0; + } + + fclose (the_file); + + for (d = directives; d; d = d->next) + { +#if TRACE + printf ("Adding directive %08x `%s'\n", d->name, d->name); +#endif + def_file_add_directive (def, d->name, d->len); + } + + return def; +} + +void +def_file_free (def) + def_file *def; +{ + int i; + if (!def) + return; + if (def->name) + free (def->name); + if (def->description) + free (def->description); + + if (def->section_defs) + { + for (i = 0; i < def->num_section_defs; i++) + { + if (def->section_defs[i].name) + free (def->section_defs[i].name); + if (def->section_defs[i].class) + free (def->section_defs[i].class); + } + free (def->section_defs); + } + + if (def->exports) + { + for (i = 0; i < def->num_exports; i++) + { + if (def->exports[i].internal_name + && def->exports[i].internal_name != def->exports[i].name) + free (def->exports[i].internal_name); + if (def->exports[i].name) + free (def->exports[i].name); + } + free (def->exports); + } + + if (def->imports) + { + for (i = 0; i < def->num_imports; i++) + { + if (def->imports[i].internal_name + && def->imports[i].internal_name != def->imports[i].name) + free (def->imports[i].internal_name); + if (def->imports[i].name) + free (def->imports[i].name); + } + free (def->imports); + } + + while (def->modules) + { + def_file_module *m = def->modules; + def->modules = def->modules->next; + free (m); + } + + free (def); +} + +#ifdef DEF_FILE_PRINT +void +def_file_print (file, def) + FILE *file; + def_file *def; +{ + int i; + fprintf (file, ">>>> def_file at 0x%08x\n", def); + if (def->name) + fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)"); + if (def->is_dll != -1) + fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no"); + if (def->base_address != (bfd_vma) (-1)) + fprintf (file, " base address: 0x%08x\n", def->base_address); + if (def->description) + fprintf (file, " description: `%s'\n", def->description); + if (def->stack_reserve != -1) + fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve); + if (def->stack_commit != -1) + fprintf (file, " stack commit: 0x%08x\n", def->stack_commit); + if (def->heap_reserve != -1) + fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve); + if (def->heap_commit != -1) + fprintf (file, " heap commit: 0x%08x\n", def->heap_commit); + + if (def->num_section_defs > 0) + { + fprintf (file, " section defs:\n"); + for (i = 0; i < def->num_section_defs; i++) + { + fprintf (file, " name: `%s', class: `%s', flags:", + def->section_defs[i].name, def->section_defs[i].class); + if (def->section_defs[i].flag_read) + fprintf (file, " R"); + if (def->section_defs[i].flag_write) + fprintf (file, " W"); + if (def->section_defs[i].flag_execute) + fprintf (file, " X"); + if (def->section_defs[i].flag_shared) + fprintf (file, " S"); + fprintf (file, "\n"); + } + } + + if (def->num_exports > 0) + { + fprintf (file, " exports:\n"); + for (i = 0; i < def->num_exports; i++) + { + fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:", + def->exports[i].name, def->exports[i].internal_name, + def->exports[i].ordinal); + if (def->exports[i].flag_private) + fprintf (file, " P"); + if (def->exports[i].flag_constant) + fprintf (file, " C"); + if (def->exports[i].flag_noname) + fprintf (file, " N"); + if (def->exports[i].flag_data) + fprintf (file, " D"); + fprintf (file, "\n"); + } + } + + if (def->num_imports > 0) + { + fprintf (file, " imports:\n"); + for (i = 0; i < def->num_imports; i++) + { + fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n", + def->imports[i].internal_name, + def->imports[i].module, + def->imports[i].name, + def->imports[i].ordinal); + } + } + if (def->version_major != -1) + fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor); + fprintf (file, "<<<< def_file at 0x%08x\n", def); +} +#endif + +def_file_export * +def_file_add_export (def, external_name, internal_name, ordinal) + def_file *def; + const char *external_name; + const char *internal_name; + int ordinal; +{ + def_file_export *e; + int max_exports = ROUND_UP(def->num_exports, 32); + if (def->num_exports >= max_exports) + { + max_exports = ROUND_UP(def->num_exports+1, 32); + if (def->exports) + def->exports = (def_file_export *) xrealloc (def->exports, max_exports * sizeof (def_file_export)); + else + def->exports = (def_file_export *) xmalloc (max_exports * sizeof (def_file_export)); + } + e = def->exports + def->num_exports; + memset (e, 0, sizeof (def_file_export)); + if (internal_name && !external_name) + external_name = internal_name; + if (external_name && !internal_name) + internal_name = external_name; + e->name = xstrdup (external_name); + e->internal_name = xstrdup (internal_name); + e->ordinal = ordinal; + def->num_exports++; + return e; +} + +static def_file_module * +def_stash_module (def, name) + def_file *def; + char *name; +{ + def_file_module *s; + for (s=def->modules; s; s=s->next) + if (strcmp (s->name, name) == 0) + return s; + s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name)); + s->next = def->modules; + def->modules = s; + s->user_data = 0; + strcpy (s->name, name); + return s; +} + +def_file_import * +def_file_add_import (def, name, module, ordinal, internal_name) + def_file *def; + const char *name; + const char *module; + int ordinal; + const char *internal_name; +{ + def_file_import *i; + int max_imports = ROUND_UP(def->num_imports, 16); + if (def->num_imports >= max_imports) + { + max_imports = ROUND_UP(def->num_imports+1, 16); + if (def->imports) + def->imports = (def_file_import *) xrealloc (def->imports, max_imports * sizeof (def_file_import)); + else + def->imports = (def_file_import *) xmalloc (max_imports * sizeof (def_file_import)); + } + i = def->imports + def->num_imports; + memset (i, 0, sizeof (def_file_import)); + if (name) + i->name = xstrdup (name); + if (module) + i->module = def_stash_module(def, module); + i->ordinal = ordinal; + if (internal_name) + i->internal_name = xstrdup (internal_name); + else + i->internal_name = i->name; + def->num_imports++; + return i; +} + +struct +{ + char *param; + int token; +} +diropts[] = +{ + { "-heap", HEAPSIZE }, + { "-stack", STACKSIZE }, + { "-attr", SECTIONS }, + { "-export", EXPORTS }, + { 0, 0 } +}; + +void +def_file_add_directive (my_def, param, len) + def_file *my_def; + const char *param; + int len; +{ + def_file *save_def = def; + const char *pend = param + len; + const char *tend = param; + int i; + + def = my_def; + + while (param < pend) + { + while (param < pend && isspace (*param)) + param++; + for (tend = param + 1; + tend < pend && !(isspace (tend[-1]) && *tend == '-'); + tend++); + + for (i = 0; diropts[i].param; i++) + { + int len = strlen (diropts[i].param); + if (tend - param >= len + && strncmp (param, diropts[i].param, len) == 0 + && (param[len] == ':' || param[len] == ' ')) + { + lex_parse_string_end = tend; + lex_parse_string = param + len + 1; + lex_forced_token = diropts[i].token; + saw_newline = 0; + def_parse (); + break; + } + } + + if (!diropts[i].param) + { + /* xgettext:c-format */ + einfo (_("Warning: .drectve `%.*s' unrecognized\n"), + tend - param, param); + } + lex_parse_string = 0; + param = tend; + } + + def = save_def; +} + +/***************************************************************************** + Parser Callbacks + *****************************************************************************/ + +static void +def_name (name, base) + const char *name; + int base; +{ + if (def->name) + free (def->name); + def->name = xstrdup (name); + def->base_address = base; + def->is_dll = 0; +} + +static void +def_library (name, base) + const char *name; + int base; +{ + if (def->name) + free (def->name); + def->name = xstrdup (name); + def->base_address = base; + def->is_dll = 1; +} + +static void +def_description (text) + const char *text; +{ + int len = def->description ? strlen (def->description) : 0; + len += strlen (text) + 1; + if (def->description) + { + def->description = (char *) xrealloc (def->description, len); + strcat (def->description, text); + } + else + { + def->description = (char *) xmalloc (len); + strcpy (def->description, text); + } +} + +static void +def_stacksize (reserve, commit) + int reserve; + int commit; +{ + def->stack_reserve = reserve; + def->stack_commit = commit; +} + +static void +def_heapsize (reserve, commit) + int reserve; + int commit; +{ + def->heap_reserve = reserve; + def->heap_commit = commit; +} + +static void +def_section (name, attr) + const char *name; + int attr; +{ + def_file_section *s; + int max_sections = ROUND_UP(def->num_section_defs, 4); + if (def->num_section_defs >= max_sections) + { + max_sections = ROUND_UP(def->num_section_defs+1, 4); + if (def->section_defs) + def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import)); + else + def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import)); + } + s = def->section_defs + def->num_section_defs; + memset (s, 0, sizeof (def_file_section)); + s->name = xstrdup (name); + if (attr & 1) + s->flag_read = 1; + if (attr & 2) + s->flag_write = 1; + if (attr & 4) + s->flag_execute = 1; + if (attr & 8) + s->flag_shared = 1; + + def->num_section_defs++; +} + +static void +def_section_alt (name, attr) + const char *name; + const char *attr; +{ + int aval = 0; + for (; *attr; attr++) + { + switch (*attr) + { + case 'R': + case 'r': + aval |= 1; + break; + case 'W': + case 'w': + aval |= 2; + break; + case 'X': + case 'x': + aval |= 4; + break; + case 'S': + case 's': + aval |= 8; + break; + } + } + def_section (name, aval); +} + +static void +def_exports (external_name, internal_name, ordinal, flags) + const char *external_name; + const char *internal_name; + int ordinal; + int flags; +{ + def_file_export *dfe; + + if (!internal_name && external_name) + internal_name = external_name; +#if TRACE + printf ("def_exports, ext=%s int=%s\n", external_name, internal_name); +#endif + + dfe = def_file_add_export (def, external_name, internal_name, ordinal); + if (flags & 1) + dfe->flag_noname = 1; + if (flags & 2) + dfe->flag_constant = 1; + if (flags & 4) + dfe->flag_data = 1; + if (flags & 8) + dfe->flag_private = 1; +} + +static void +def_import (internal_name, module, dllext, name, ordinal) + const char *internal_name; + const char *module; + const char *dllext; + const char *name; + int ordinal; +{ + char *buf = 0; + + if (dllext != NULL) + { + buf = (char *) xmalloc (strlen (module) + strlen (dllext) + 2); + sprintf (buf, "%s.%s", module, dllext); + module = buf; + } + + def_file_add_import (def, name, module, ordinal, internal_name); + if (buf) + free (buf); +} + +static void +def_version (major, minor) + int major; + int minor; +{ + def->version_major = major; + def->version_minor = minor; +} + +static void +def_directive (str) + char *str; +{ + struct directive *d = (struct directive *) xmalloc (sizeof (struct directive)); + d->next = directives; + directives = d; + d->name = xstrdup (str); + d->len = strlen (str); +} + +static int +def_error (err) + const char *err; +{ + einfo ("%P: %s:%d: %s\n", def_filename, linenumber, err); + + return 0; +} + + +/***************************************************************************** + Lexical Scanner + *****************************************************************************/ + +#undef TRACE +#define TRACE 0 + +/* Never freed, but always reused as needed, so no real leak */ +static char *buffer = 0; +static int buflen = 0; +static int bufptr = 0; + +static void +put_buf (c) + char c; +{ + if (bufptr == buflen) + { + buflen += 50; /* overly reasonable, eh? */ + if (buffer) + buffer = (char *) xrealloc (buffer, buflen + 1); + else + buffer = (char *) xmalloc (buflen + 1); + } + buffer[bufptr++] = c; + buffer[bufptr] = 0; /* not optimal, but very convenient */ +} + +static struct +{ + char *name; + int token; +} +tokens[] = +{ + { "BASE", BASE }, + { "CODE", CODE }, + { "CONSTANT", CONSTANT }, + { "DATA", DATA }, + { "DESCRIPTION", DESCRIPTION }, + { "DIRECTIVE", DIRECTIVE }, + { "EXECUTE", EXECUTE }, + { "EXPORTS", EXPORTS }, + { "HEAPSIZE", HEAPSIZE }, + { "IMPORTS", IMPORTS }, + { "LIBRARY", LIBRARY }, + { "NAME", NAME }, + { "NONAME", NONAME }, + { "PRIVATE", PRIVATE }, + { "READ", READ }, + { "SECTIONS", SECTIONS }, + { "SEGMENTS", SECTIONS }, + { "SHARED", SHARED }, + { "STACKSIZE", STACKSIZE }, + { "VERSION", VERSIONK }, + { "WRITE", WRITE }, + { 0, 0 } +}; + +static int +def_getc () +{ + int rv; + if (lex_parse_string) + { + if (lex_parse_string >= lex_parse_string_end) + rv = EOF; + else + rv = *lex_parse_string++; + } + else + { + rv = fgetc (the_file); + } + if (rv == '\n') + saw_newline = 1; + return rv; +} + +static int +def_ungetc (c) + int c; +{ + if (lex_parse_string) + { + lex_parse_string--; + return c; + } + else + return ungetc (c, the_file); +} + +static int +def_lex () +{ + int c, i, q; + + if (lex_forced_token) + { + i = lex_forced_token; + lex_forced_token = 0; +#if TRACE + printf ("lex: forcing token %d\n", i); +#endif + return i; + } + + c = def_getc (); + + /* trim leading whitespace */ + while (c != EOF && (c == ' ' || c == '\t') && saw_newline) + c = def_getc (); + + if (c == EOF) + { +#if TRACE + printf ("lex: EOF\n"); +#endif + return 0; + } + + if (saw_newline && c == ';') + { + do + { + c = def_getc (); + } + while (c != EOF && c != '\n'); + if (c == '\n') + return def_lex (); + return 0; + } + /* must be something else */ + saw_newline = 0; + + if (isdigit (c)) + { + bufptr = 0; + while (c != EOF && (isxdigit (c) || (c == 'x'))) + { + put_buf (c); + c = def_getc (); + } + if (c != EOF) + def_ungetc (c); + yylval.number = strtoul (buffer, 0, 0); +#if TRACE + printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number); +#endif + return NUMBER; + } + + if (isalpha (c) || strchr ("$:-_?", c)) + { + bufptr = 0; + while (c != EOF && (isalnum (c) || strchr ("$:-_?/@", c))) + { + put_buf (c); + c = def_getc (); + } + if (c != EOF) + def_ungetc (c); + for (i = 0; tokens[i].name; i++) + if (strcmp (tokens[i].name, buffer) == 0) + { +#if TRACE + printf ("lex: `%s' is a string token\n", buffer); +#endif + return tokens[i].token; + } +#if TRACE + printf ("lex: `%s' returns ID\n", buffer); +#endif + yylval.id = xstrdup (buffer); + return ID; + } + + if (c == '\'' || c == '"') + { + q = c; + c = def_getc (); + bufptr = 0; + while (c != EOF && c != q) + { + put_buf (c); + c = def_getc (); + } + yylval.id = xstrdup (buffer); +#if TRACE + printf ("lex: `%s' returns ID\n", buffer); +#endif + return ID; + } + + if (c == '=' || c == '.' || c == '@' || c == ',') + { +#if TRACE + printf ("lex: `%c' returns itself\n", c); +#endif + return c; + } + + if (c == '\n') + { + linenumber++; + saw_newline = 1; + } + + /*printf ("lex: 0x%02x ignored\n", c); */ + return def_lex (); +} diff --git a/ld/dep-in.sed b/ld/dep-in.sed new file mode 100644 index 0000000..8c80eb0 --- /dev/null +++ b/ld/dep-in.sed @@ -0,0 +1,16 @@ +:loop +/\\$/N +/\\$/b loop + +s!@INCDIR@!$(INCDIR)!g +s!@SRCDIR@/!!g +s!\.\./bfd/hosts/[^ ]*\.h ! !g + +s/\\\n */ /g + +s/ *$// +s/ */ /g +/:$/d + +s/\(.\{50\}[^ ]*\) /\1 \\\ + /g diff --git a/ld/emulparams/README b/ld/emulparams/README new file mode 100644 index 0000000..b3d6d26 --- /dev/null +++ b/ld/emulparams/README @@ -0,0 +1,2 @@ +The files in this directory are read by genscripts.sh as shell commands. +They set parameters for the emulations. diff --git a/ld/emulparams/a29k.sh b/ld/emulparams/a29k.sh new file mode 100644 index 0000000..89c8e85 --- /dev/null +++ b/ld/emulparams/a29k.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=a29k +OUTPUT_FORMAT="coff-a29k-big" +TEXT_START_ADDR=0x1000000 +TARGET_PAGE_SIZE=0x1000000 +ARCH=a29k diff --git a/ld/emulparams/aixppc.sh b/ld/emulparams/aixppc.sh new file mode 100644 index 0000000..f92e686 --- /dev/null +++ b/ld/emulparams/aixppc.sh @@ -0,0 +1,4 @@ +TEMPLATE_NAME=aix +SCRIPT_NAME=aix +OUTPUT_FORMAT="aixcoff-rs6000" +ARCH=powerpc diff --git a/ld/emulparams/aixrs6.sh b/ld/emulparams/aixrs6.sh new file mode 100644 index 0000000..733c3f7 --- /dev/null +++ b/ld/emulparams/aixrs6.sh @@ -0,0 +1,4 @@ +TEMPLATE_NAME=aix +SCRIPT_NAME=aix +OUTPUT_FORMAT="aixcoff-rs6000" +ARCH=rs6000 diff --git a/ld/emulparams/alpha.sh b/ld/emulparams/alpha.sh new file mode 100644 index 0000000..141923f --- /dev/null +++ b/ld/emulparams/alpha.sh @@ -0,0 +1,3 @@ +SCRIPT_NAME=alpha +OUTPUT_FORMAT="ecoff-littlealpha" +ARCH=alpha diff --git a/ld/emulparams/arcelf.sh b/ld/emulparams/arcelf.sh new file mode 100644 index 0000000..b1c9c17 --- /dev/null +++ b/ld/emulparams/arcelf.sh @@ -0,0 +1,11 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-littlearc" +LITTLE_OUTPUT_FORMAT="elf32-littlearc" +BIG_OUTPUT_FORMAT="elf32-bigarc" +TEXT_START_ADDR=0x0 +MAXPAGESIZE=0x1000 +NONPAGED_TEXT_START_ADDR=0x0 +ARCH=arc +MACHINE= +ENTRY=start +#TEMPLATE_NAME=elf32 diff --git a/ld/emulparams/arm_epoc_pe.sh b/ld/emulparams/arm_epoc_pe.sh new file mode 100644 index 0000000..816fa2a --- /dev/null +++ b/ld/emulparams/arm_epoc_pe.sh @@ -0,0 +1,6 @@ +ARCH=arm +SCRIPT_NAME=pe +OUTPUT_FORMAT="epoc-pei-arm-little" +LITTLE_OUTPUT_FORMAT="epoc-pei-arm-little" +BIG_OUTPUT_FORMAT="epoc-pei-arm-big" +TEMPLATE_NAME=pe diff --git a/ld/emulparams/armaoutb.sh b/ld/emulparams/armaoutb.sh new file mode 100644 index 0000000..59ab6f1 --- /dev/null +++ b/ld/emulparams/armaoutb.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=armaout +OUTPUT_FORMAT="a.out-arm-big" +HEADER_START_ADDR=0x8000 +TEXT_START_ADDR=0x8000 +NONPAGED_TEXT_START_ADDRESS=0x8000 +TARGET_PAGE_SIZE=32768 +ARCH=arm diff --git a/ld/emulparams/armaoutl.sh b/ld/emulparams/armaoutl.sh new file mode 100644 index 0000000..9501f33 --- /dev/null +++ b/ld/emulparams/armaoutl.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=armaout +OUTPUT_FORMAT="a.out-arm-little" +HEADER_START_ADDR=0x8000 +TEXT_START_ADDR=0x8000 +NONPAGED_TEXT_START_ADDRESS=0x8000 +TARGET_PAGE_SIZE=32768 +ARCH=arm diff --git a/ld/emulparams/armcoff.sh b/ld/emulparams/armcoff.sh new file mode 100644 index 0000000..91df7d3 --- /dev/null +++ b/ld/emulparams/armcoff.sh @@ -0,0 +1,6 @@ +ARCH=arm +SCRIPT_NAME=armcoff +OUTPUT_FORMAT="coff-arm-little" +LITTLE_OUTPUT_FORMAT="coff-arm-little" +BIG_OUTPUT_FORMAT="coff-arm-big" +TEMPLATE_NAME=armcoff diff --git a/ld/emulparams/armelf.sh b/ld/emulparams/armelf.sh new file mode 100644 index 0000000..2b8b02b --- /dev/null +++ b/ld/emulparams/armelf.sh @@ -0,0 +1,21 @@ +MACHINE= +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-littlearm" +BIG_OUTPUT_FORMAT="elf32-bigarm" +LITTLE_OUTPUT_FORMAT="elf32-littlearm" +TEXT_START_ADDR=0x8000 +TEMPLATE_NAME=armelf +OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)' +OTHER_BSS_SYMBOLS='__bss_start__ = .;' +OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;' + + +ARCH=arm +MACHINE= +MAXPAGESIZE=256 +ENTRY=_start +EMBEDDED=yes + +# Hmmm, there's got to be a better way. This sets the stack to the +# top of the simulator memory (2^19 bytes). +OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }' diff --git a/ld/emulparams/armelf_linux.sh b/ld/emulparams/armelf_linux.sh new file mode 100644 index 0000000..2d7d57b --- /dev/null +++ b/ld/emulparams/armelf_linux.sh @@ -0,0 +1,17 @@ +ARCH=arm +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-littlearm" +BIG_OUTPUT_FORMAT="elf32-bigarm" +LITTLE_OUTPUT_FORMAT="elf32-littlearm" +MAXPAGESIZE=0x8000 +TEMPLATE_NAME=armelf + +OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)' +OTHER_BSS_SYMBOLS='__bss_start__ = .;' +OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;' + +# This needs to be high enough so that we can load ld.so below it, +# yet low enough to stay away from the mmap area 0x40000000. +# Also, it is small enough so that relocs which are pointing +# at absolute 0 will still be fixed up. +TEXT_START_ADDR=0x02000000 diff --git a/ld/emulparams/armelf_linux26.sh b/ld/emulparams/armelf_linux26.sh new file mode 100644 index 0000000..7153ddc --- /dev/null +++ b/ld/emulparams/armelf_linux26.sh @@ -0,0 +1,16 @@ +ARCH=arm +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-littlearm" +BIG_OUTPUT_FORMAT="elf32-bigarm" +LITTLE_OUTPUT_FORMAT="elf32-littlearm" +MAXPAGESIZE=0x8000 +TEMPLATE_NAME=armelf +GENERATE_SHLIB_SCRIPT=yes + +# This needs to be high enough so that we can load ld.so below it, +# yet low enough to stay away from the mmap area at 0x01100000. +# Also, it is small enough so that relocs which are pointing +# at absolute 0 will still be fixed up. +# These values give us about 0.5MB for ld.so, 16.5MB for user +# programs, and 15MB for mmap which seems a reasonable compromise. +TEXT_START_ADDR=0x00080000 diff --git a/ld/emulparams/armelf_oabi.sh b/ld/emulparams/armelf_oabi.sh new file mode 100644 index 0000000..257753e --- /dev/null +++ b/ld/emulparams/armelf_oabi.sh @@ -0,0 +1,21 @@ +MACHINE= +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-littlearm-oabi" +BIG_OUTPUT_FORMAT="elf32-bigarm-oabi" +LITTLE_OUTPUT_FORMAT="elf32-littlearm-oabi" +TEXT_START_ADDR=0x8000 +TEMPLATE_NAME=armelf +OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)' +OTHER_BSS_SYMBOLS='__bss_start__ = .;' +OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;' + + +ARCH=arm +MACHINE= +MAXPAGESIZE=256 +ENTRY=_start +EMBEDDED=yes + +# Hmmm, there's got to be a better way. This sets the stack to the +# top of the simulator memory (2^19 bytes). +OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }' diff --git a/ld/emulparams/armpe.sh b/ld/emulparams/armpe.sh new file mode 100644 index 0000000..2246805 --- /dev/null +++ b/ld/emulparams/armpe.sh @@ -0,0 +1,6 @@ +ARCH=arm +SCRIPT_NAME=pe +OUTPUT_FORMAT="pei-arm-little" +LITTLE_OUTPUT_FORMAT="pei-arm-little" +BIG_OUTPUT_FORMAT="pei-arm-big" +TEMPLATE_NAME=pe diff --git a/ld/emulparams/coff_sparc.sh b/ld/emulparams/coff_sparc.sh new file mode 100644 index 0000000..0cf852a --- /dev/null +++ b/ld/emulparams/coff_sparc.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=sparccoff +OUTPUT_FORMAT="coff-sparc" +# following are dubious (borrowed from sparc lynx) +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR=0 +NONPAGED_TEXT_START_ADDR=0x1000 +ARCH=sparc diff --git a/ld/emulparams/d10velf.sh b/ld/emulparams/d10velf.sh new file mode 100644 index 0000000..bcce51f --- /dev/null +++ b/ld/emulparams/d10velf.sh @@ -0,0 +1,9 @@ +MACHINE= +SCRIPT_NAME=elfd10v +OUTPUT_FORMAT="elf32-d10v" +TEXT_START_ADDR=0x01000000 +READONLY_START_ADDR=0x00000004 +ARCH=d10v +MAXPAGESIZE=32 +EMBEDDED=t +TEMPLATE_NAME=elf32 diff --git a/ld/emulparams/d30v_e.sh b/ld/emulparams/d30v_e.sh new file mode 100644 index 0000000..a8ab5a2 --- /dev/null +++ b/ld/emulparams/d30v_e.sh @@ -0,0 +1,20 @@ +MACHINE= +SCRIPT_NAME=elfd30v +OUTPUT_FORMAT="elf32-d30v" +TEXT_START_ADDR=0x00000000 +DATA_START_ADDR=0x20000000 +EMEM_START_ADDR=0x80000000 +STACK_START_ADDR=0x20008000 +EIT_START_ADDR=0xfffff020 +TEXT_SIZE=64K +DATA_SIZE=32K +EMEM_SIZE=8M +EIT_SIZE=320 +TEXT_MEMORY=emem +DATA_MEMORY=emem +BSS_MEMORY=emem +TEXT_DEF_SECTION="" +DATA_DEF_SECTION="" +EMEM_DEF_SECTION="(rwx)" +ARCH=d30v +EMBEDDED=t diff --git a/ld/emulparams/d30v_o.sh b/ld/emulparams/d30v_o.sh new file mode 100644 index 0000000..6cbcb42 --- /dev/null +++ b/ld/emulparams/d30v_o.sh @@ -0,0 +1,20 @@ +MACHINE= +SCRIPT_NAME=elfd30v +OUTPUT_FORMAT="elf32-d30v" +TEXT_START_ADDR=0x00000000 +DATA_START_ADDR=0x20000000 +EMEM_START_ADDR=0x80000000 +STACK_START_ADDR=0x20008000 +EIT_START_ADDR=0xfffff020 +TEXT_SIZE=64K +DATA_SIZE=32K +EMEM_SIZE=8M +EIT_SIZE=320 +TEXT_MEMORY=text +DATA_MEMORY=data +BSS_MEMORY=data +TEXT_DEF_SECTION="(x)" +DATA_DEF_SECTION="(rw)" +EMEM_DEF_SECTION="" +ARCH=d30v +EMBEDDED=t diff --git a/ld/emulparams/d30velf.sh b/ld/emulparams/d30velf.sh new file mode 100644 index 0000000..949de78 --- /dev/null +++ b/ld/emulparams/d30velf.sh @@ -0,0 +1,20 @@ +MACHINE= +SCRIPT_NAME=elfd30v +OUTPUT_FORMAT="elf32-d30v" +TEXT_START_ADDR=0x00000000 +DATA_START_ADDR=0x20000000 +EMEM_START_ADDR=0x80000000 +STACK_START_ADDR=0x20008000 +EIT_START_ADDR=0xfffff020 +TEXT_SIZE=2000K +DATA_SIZE=2000K +EMEM_SIZE=8M +EIT_SIZE=320 +TEXT_MEMORY=text +DATA_MEMORY=data +BSS_MEMORY=data +TEXT_DEF_SECTION="(x)" +DATA_DEF_SECTION="(rw)" +EMEM_DEF_SECTION="" +ARCH=d30v +EMBEDDED=t diff --git a/ld/emulparams/delta68.sh b/ld/emulparams/delta68.sh new file mode 100644 index 0000000..e3c5909 --- /dev/null +++ b/ld/emulparams/delta68.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=delta68 +OUTPUT_FORMAT="coff-m68k-sysv" +TEXT_START_ADDR=0x2000 +PAGE_SIZE=0x1000000 +ARCH=m68k diff --git a/ld/emulparams/ebmon29k.sh b/ld/emulparams/ebmon29k.sh new file mode 100644 index 0000000..fbc2bd1 --- /dev/null +++ b/ld/emulparams/ebmon29k.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=ebmon29k +OUTPUT_FORMAT="coff-a29k-big" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=0x1000 +ARCH=a29k diff --git a/ld/emulparams/elf32_sparc.sh b/ld/emulparams/elf32_sparc.sh new file mode 100644 index 0000000..74e2326 --- /dev/null +++ b/ld/emulparams/elf32_sparc.sh @@ -0,0 +1,11 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-sparc" +TEXT_START_ADDR=0x10000 +MAXPAGESIZE=0x10000 +NONPAGED_TEXT_START_ADDR=0x10000 +ALIGNMENT=8 +ARCH=sparc +MACHINE= +TEMPLATE_NAME=elf32 +DATA_PLT= +GENERATE_SHLIB_SCRIPT=yes diff --git a/ld/emulparams/elf32b4300.sh b/ld/emulparams/elf32b4300.sh new file mode 100644 index 0000000..24f8d98 --- /dev/null +++ b/ld/emulparams/elf32b4300.sh @@ -0,0 +1,29 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-bigmips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0xa0020000 +MAXPAGESIZE=0x40000 +INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' +OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_GOT_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +EXECUTABLE_SYMBOLS='_DYNAMIC_LINK = 0;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +DYNAMIC_LINK=false +EMBEDDED=yes diff --git a/ld/emulparams/elf32bmip.sh b/ld/emulparams/elf32bmip.sh new file mode 100644 index 0000000..473c411 --- /dev/null +++ b/ld/emulparams/elf32bmip.sh @@ -0,0 +1,30 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-bigmips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0x0400000 +DATA_ADDR=0x10000000 +MAXPAGESIZE=0x40000 +NONPAGED_TEXT_START_ADDR=0x0400000 +SHLIB_TEXT_START_ADDR=0x5ffe0000 +TEXT_DYNAMIC= +INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' +OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_GOT_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes diff --git a/ld/emulparams/elf32bsmip.sh b/ld/emulparams/elf32bsmip.sh new file mode 100644 index 0000000..09f1307 --- /dev/null +++ b/ld/emulparams/elf32bsmip.sh @@ -0,0 +1,31 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-bigmips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0x0400000 +DATA_ADDR=0x10000000 +MAXPAGESIZE=0x40000 +NONPAGED_TEXT_START_ADDR=0x0400000 +SHLIB_TEXT_START_ADDR=0x5ffe0000 +TEXT_DYNAMIC= +INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' +OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_GOT_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +ENTRY=__start diff --git a/ld/emulparams/elf32ebmip.sh b/ld/emulparams/elf32ebmip.sh new file mode 100644 index 0000000..00ea8fd --- /dev/null +++ b/ld/emulparams/elf32ebmip.sh @@ -0,0 +1,28 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-bigmips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0x0400000 +MAXPAGESIZE=0x40000 +NONPAGED_TEXT_START_ADDR=0x0400000 +SHLIB_TEXT_START_ADDR=0x5ffe0000 +OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_GOT_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +EMBEDDED=yes diff --git a/ld/emulparams/elf32elmip.sh b/ld/emulparams/elf32elmip.sh new file mode 100644 index 0000000..cf008c8 --- /dev/null +++ b/ld/emulparams/elf32elmip.sh @@ -0,0 +1,28 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-littlemips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0x0400000 +MAXPAGESIZE=0x40000 +NONPAGED_TEXT_START_ADDR=0x0400000 +SHLIB_TEXT_START_ADDR=0x5ffe0000 +OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_GOT_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +EMBEDDED=yes diff --git a/ld/emulparams/elf32fr30.sh b/ld/emulparams/elf32fr30.sh new file mode 100755 index 0000000..1be1f53 --- /dev/null +++ b/ld/emulparams/elf32fr30.sh @@ -0,0 +1,10 @@ +MACHINE= +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-fr30" +TEXT_START_ADDR=0x10000 +ARCH=fr30 +MAXPAGESIZE=256 +ENTRY=_start +EMBEDDED=yes +NOP=0x9fa0 +OTHER_RELOCATING_SECTIONS='PROVIDE (__stack = 0x200000);'
\ No newline at end of file diff --git a/ld/emulparams/elf32l4300.sh b/ld/emulparams/elf32l4300.sh new file mode 100644 index 0000000..690de88 --- /dev/null +++ b/ld/emulparams/elf32l4300.sh @@ -0,0 +1,29 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-littlemips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0xa0020000 +MAXPAGESIZE=0x40000 +INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' +OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_GOT_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +EXECUTABLE_SYMBOLS='_DYNAMIC_LINK = 0;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +DYNAMIC_LINK=false +EMBEDDED=yes diff --git a/ld/emulparams/elf32lmip.sh b/ld/emulparams/elf32lmip.sh new file mode 100644 index 0000000..23312f4 --- /dev/null +++ b/ld/emulparams/elf32lmip.sh @@ -0,0 +1,30 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-littlemips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0x0400000 +DATA_ADDR=0x10000000 +MAXPAGESIZE=0x40000 +NONPAGED_TEXT_START_ADDR=0x0400000 +SHLIB_TEXT_START_ADDR=0x5ffe0000 +TEXT_DYNAMIC= +INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' +OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_GOT_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes diff --git a/ld/emulparams/elf32lppc.sh b/ld/emulparams/elf32lppc.sh new file mode 100644 index 0000000..edffc61 --- /dev/null +++ b/ld/emulparams/elf32lppc.sh @@ -0,0 +1,8 @@ +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +SCRIPT_NAME=elfppc +OUTPUT_FORMAT="elf32-powerpcle" +TEXT_START_ADDR=0x40000 +MAXPAGESIZE=0x40000 +ARCH=powerpc +MACHINE= diff --git a/ld/emulparams/elf32lsmip.sh b/ld/emulparams/elf32lsmip.sh new file mode 100644 index 0000000..4bdc8a1 --- /dev/null +++ b/ld/emulparams/elf32lsmip.sh @@ -0,0 +1,31 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-littlemips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0x0400000 +DATA_ADDR=0x10000000 +MAXPAGESIZE=0x40000 +NONPAGED_TEXT_START_ADDR=0x0400000 +SHLIB_TEXT_START_ADDR=0x5ffe0000 +TEXT_DYNAMIC= +INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' +OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_GOT_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +ENTRY=__start diff --git a/ld/emulparams/elf32mcore.sh b/ld/emulparams/elf32mcore.sh new file mode 100644 index 0000000..47d960f --- /dev/null +++ b/ld/emulparams/elf32mcore.sh @@ -0,0 +1,20 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-mcore-big" +BIG_OUTPUT_FORMAT="elf32-mcore-big" +LITTLE_OUTPUT_FORMAT="elf32-mcore-little" +PAGE_SIZE=0x1000 +TARGET_PAGE_SIZE=0x400 +MAXPAGESIZE=0x1000 +TEXT_START_ADDR=0 +NONPAGED_TEXT_START_ADDR=0 +ARCH=mcore +# 1211 == mov r1,r1 +NOP=0x1211 +EMBEDDED=yes + +OTHER_BSS_SYMBOLS="__bss_start__ = . ;" +OTHER_BSS_END_SYMBOLS="__bss_end__ = . ;" + +# Hmmm, there's got to be a better way. This sets the stack to the +# top of the simulator memory (2^19 bytes). +OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }' diff --git a/ld/emulparams/elf32ppc.sh b/ld/emulparams/elf32ppc.sh new file mode 100644 index 0000000..8af42f1 --- /dev/null +++ b/ld/emulparams/elf32ppc.sh @@ -0,0 +1,8 @@ +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +SCRIPT_NAME=elfppc +OUTPUT_FORMAT="elf32-powerpc" +TEXT_START_ADDR=0x01800000 +MAXPAGESIZE=0x40000 +ARCH=powerpc +MACHINE= diff --git a/ld/emulparams/elf64_sparc.sh b/ld/emulparams/elf64_sparc.sh new file mode 100644 index 0000000..d0fbdfd --- /dev/null +++ b/ld/emulparams/elf64_sparc.sh @@ -0,0 +1,12 @@ +SCRIPT_NAME=elf +ELFSIZE=64 +TEMPLATE_NAME=elf32 +OUTPUT_FORMAT="elf64-sparc" +TEXT_START_ADDR=0x100000 +MAXPAGESIZE=0x100000 +NONPAGED_TEXT_START_ADDR=0x100000 +ARCH="sparc:v9" +MACHINE= +DATA_PLT= +GENERATE_SHLIB_SCRIPT=yes +NOP=0x01000000 diff --git a/ld/emulparams/elf64alpha.sh b/ld/emulparams/elf64alpha.sh new file mode 100644 index 0000000..afa21f2 --- /dev/null +++ b/ld/emulparams/elf64alpha.sh @@ -0,0 +1,15 @@ +ENTRY=__start +SCRIPT_NAME=elf +ELFSIZE=64 +TEMPLATE_NAME=elf32 +OUTPUT_FORMAT="elf64-alpha" +TEXT_START_ADDR="0x120000000" +MAXPAGESIZE=0x100000 +NONPAGED_TEXT_START_ADDR="0x120000000" +ARCH=alpha +MACHINE= +GENERATE_SHLIB_SCRIPT=yes +DATA_PLT= +NOP=0x47ff041f + +OTHER_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh new file mode 100644 index 0000000..dff567b --- /dev/null +++ b/ld/emulparams/elf_i386.sh @@ -0,0 +1,10 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-i386" +TEXT_START_ADDR=0x08048000 +MAXPAGESIZE=0x1000 +NONPAGED_TEXT_START_ADDR=0x08048000 +ARCH=i386 +MACHINE= +NOP=0x9090 +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes diff --git a/ld/emulparams/elf_i386_be.sh b/ld/emulparams/elf_i386_be.sh new file mode 100644 index 0000000..9977a06 --- /dev/null +++ b/ld/emulparams/elf_i386_be.sh @@ -0,0 +1,11 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-i386" +TEXT_START_ADDR=0x80000000 +#SHLIB_TEXT_START_ADDR=0x80000000 +NONPAGED_TEXT_START_ADDR=0x80000000 +MAXPAGESIZE=0x1000 +ARCH=i386 +MACHINE= +NOP=0x9090 +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes diff --git a/ld/emulparams/gld960.sh b/ld/emulparams/gld960.sh new file mode 100644 index 0000000..ef81a78 --- /dev/null +++ b/ld/emulparams/gld960.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=i960 +OUTPUT_FORMAT="" +TEXT_START_ADDR=?? +TARGET_PAGE_SIZE=?? +ARCH=i960 +TEMPLATE_NAME=gld960 +GLD_STYLE=1 diff --git a/ld/emulparams/gld960coff.sh b/ld/emulparams/gld960coff.sh new file mode 100644 index 0000000..7820220 --- /dev/null +++ b/ld/emulparams/gld960coff.sh @@ -0,0 +1,19 @@ +SCRIPT_NAME=i960 +OUTPUT_FORMAT="" +TEXT_START_ADDR=?? +TARGET_PAGE_SIZE=?? +ARCH=i960 +TEMPLATE_NAME=gld960c +GLD_STYLE=1 +COFF_CTORS=' + ___CTOR_LIST__ = .; + LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + ___CTOR_END__ = .; + ___DTOR_LIST__ = .; + LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + ___DTOR_END__ = .; +' diff --git a/ld/emulparams/go32.sh b/ld/emulparams/go32.sh new file mode 100644 index 0000000..d13357f --- /dev/null +++ b/ld/emulparams/go32.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=go32coff +OUTPUT_FORMAT="coff-go32" +TEXT_START_ADDR=0x10a8 +TARGET_PAGE_SIZE=0x1000 +SEGMENT_SIZE=0x1000 +NONPAGED_TEXT_START_ADDR=0x0 +ARCH=i386 diff --git a/ld/emulparams/h8300.sh b/ld/emulparams/h8300.sh new file mode 100644 index 0000000..49eb3c4 --- /dev/null +++ b/ld/emulparams/h8300.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=h8300 +OUTPUT_FORMAT="coff-h8300" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=h8300 diff --git a/ld/emulparams/h8300h.sh b/ld/emulparams/h8300h.sh new file mode 100644 index 0000000..3ab794e --- /dev/null +++ b/ld/emulparams/h8300h.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=h8300h +OUTPUT_FORMAT="coff-h8300" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=h8300 diff --git a/ld/emulparams/h8300s.sh b/ld/emulparams/h8300s.sh new file mode 100644 index 0000000..e27b4f5 --- /dev/null +++ b/ld/emulparams/h8300s.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=h8300s +OUTPUT_FORMAT="coff-h8300" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=h8300 diff --git a/ld/emulparams/h8500.sh b/ld/emulparams/h8500.sh new file mode 100644 index 0000000..6f4ca80 --- /dev/null +++ b/ld/emulparams/h8500.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=h8500 +OUTPUT_FORMAT="coff-h8500" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=h8500 diff --git a/ld/emulparams/h8500b.sh b/ld/emulparams/h8500b.sh new file mode 100644 index 0000000..d2d3fee --- /dev/null +++ b/ld/emulparams/h8500b.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=h8500b +OUTPUT_FORMAT="coff-h8500" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=h8500 diff --git a/ld/emulparams/h8500c.sh b/ld/emulparams/h8500c.sh new file mode 100644 index 0000000..240a065 --- /dev/null +++ b/ld/emulparams/h8500c.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=h8500c +OUTPUT_FORMAT="coff-h8500" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=h8500 diff --git a/ld/emulparams/h8500m.sh b/ld/emulparams/h8500m.sh new file mode 100644 index 0000000..cd9f7b6 --- /dev/null +++ b/ld/emulparams/h8500m.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=h8500m +OUTPUT_FORMAT="coff-h8500" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=h8500 diff --git a/ld/emulparams/h8500s.sh b/ld/emulparams/h8500s.sh new file mode 100644 index 0000000..b9e294a --- /dev/null +++ b/ld/emulparams/h8500s.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=h8500s +OUTPUT_FORMAT="coff-h8500" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=h8500 diff --git a/ld/emulparams/hp300bsd.sh b/ld/emulparams/hp300bsd.sh new file mode 100644 index 0000000..8f5c50b --- /dev/null +++ b/ld/emulparams/hp300bsd.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-hp300bsd" +TEXT_START_ADDR=0 +TARGET_PAGE_SIZE=4096 +ARCH=m68k diff --git a/ld/emulparams/hp3hpux.sh b/ld/emulparams/hp3hpux.sh new file mode 100644 index 0000000..b7badd8 --- /dev/null +++ b/ld/emulparams/hp3hpux.sh @@ -0,0 +1,8 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-hp300hpux" +TEXT_START_ADDR=0 +TARGET_PAGE_SIZE=4096 +ARCH=m68k +STACKZERO="___stack_zero = 0x2000; __DYNAMIC = 0;" +# This is needed for HPUX 9.0; it is unnecessary but harmless for 8.0. +SHLIB_PATH="___dld_shlib_path = 0;" diff --git a/ld/emulparams/hppaelf.sh b/ld/emulparams/hppaelf.sh new file mode 100644 index 0000000..47b89ea --- /dev/null +++ b/ld/emulparams/hppaelf.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=hppaelf +OUTPUT_FORMAT="elf32-hppa" +TEXT_START_ADDR=0x1000 +TARGET_PAGE_SIZE=4096 +ARCH=hppa +START="$START$" +TEMPLATE_NAME=hppaelf diff --git a/ld/emulparams/i386aout.sh b/ld/emulparams/i386aout.sh new file mode 100644 index 0000000..dc9e554 --- /dev/null +++ b/ld/emulparams/i386aout.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-i386" +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR=0 +NONPAGED_TEXT_START_ADDR=0x1000 +ARCH=i386 diff --git a/ld/emulparams/i386beos.sh b/ld/emulparams/i386beos.sh new file mode 100755 index 0000000..869da5f --- /dev/null +++ b/ld/emulparams/i386beos.sh @@ -0,0 +1,5 @@ +ARCH=i386 +SCRIPT_NAME=i386beos +OUTPUT_FORMAT="pei-i386" +RELOCATEABLE_OUTPUT_FORMAT="pe-i386" +TEMPLATE_NAME=beos diff --git a/ld/emulparams/i386bsd.sh b/ld/emulparams/i386bsd.sh new file mode 100644 index 0000000..e0c0e2f --- /dev/null +++ b/ld/emulparams/i386bsd.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-i386-bsd" +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR=0 +NONPAGED_TEXT_START_ADDR=0x1000 +ARCH=i386 diff --git a/ld/emulparams/i386coff.sh b/ld/emulparams/i386coff.sh new file mode 100644 index 0000000..3417b7d --- /dev/null +++ b/ld/emulparams/i386coff.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=i386coff +OUTPUT_FORMAT="coff-i386" +TEXT_START_ADDR=0x1000000 +TARGET_PAGE_SIZE=0x1000000 +ARCH=i386 diff --git a/ld/emulparams/i386go32.sh b/ld/emulparams/i386go32.sh new file mode 100644 index 0000000..0ef16c4 --- /dev/null +++ b/ld/emulparams/i386go32.sh @@ -0,0 +1,8 @@ +SCRIPT_NAME=i386go32 +OUTPUT_FORMAT="coff-go32" +TEXT_START_ADDR=0x10a8 +TARGET_PAGE_SIZE=0x1000 +SEGMENT_SIZE=0x200 +NONPAGED_TEXT_START_ADDR=0x0 +ARCH=i386 + diff --git a/ld/emulparams/i386linux.sh b/ld/emulparams/i386linux.sh new file mode 100644 index 0000000..a416422 --- /dev/null +++ b/ld/emulparams/i386linux.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-i386-linux" +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR=0x1020 +NONPAGED_TEXT_START_ADDR=0 +ARCH=i386 +TEMPLATE_NAME=linux diff --git a/ld/emulparams/i386lynx.sh b/ld/emulparams/i386lynx.sh new file mode 100644 index 0000000..988c175 --- /dev/null +++ b/ld/emulparams/i386lynx.sh @@ -0,0 +1,9 @@ +SCRIPT_NAME=i386lynx +OUTPUT_FORMAT="coff-i386-lynx" +# This is what LynxOS /lib/init1.o wants. +ENTRY=_main +# following are dubious +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR=0 +NONPAGED_TEXT_START_ADDR=0x1000 +ARCH=i386 diff --git a/ld/emulparams/i386mach.sh b/ld/emulparams/i386mach.sh new file mode 100644 index 0000000..b7cb276 --- /dev/null +++ b/ld/emulparams/i386mach.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-mach3" +TEXT_START_ADDR=0x10020 +NONPAGED_TEXT_START_ADDR=0x10000 +SEGMENT_SIZE=0x1000 +PAD_TEXT=t +ARCH=i386 diff --git a/ld/emulparams/i386moss.sh b/ld/emulparams/i386moss.sh new file mode 100644 index 0000000..a5e0e05 --- /dev/null +++ b/ld/emulparams/i386moss.sh @@ -0,0 +1,10 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-i386" +TEXT_START_ADDR=0x00002000 +MAXPAGESIZE=0x1000 +NONPAGED_TEXT_START_ADDR=0x00002000 +ARCH=i386 +MACHINE= +NOP=0x9090 +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes diff --git a/ld/emulparams/i386msdos.sh b/ld/emulparams/i386msdos.sh new file mode 100644 index 0000000..9311fa1 --- /dev/null +++ b/ld/emulparams/i386msdos.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=i386msdos +OUTPUT_FORMAT="msdos" +TEXT_START_ADDR=0x0 +NONPAGED_TEXT_START_ADDR=0x0 +SEGMENT_SIZE=0x10 +PAD_TEXT=t +ARCH=i386 diff --git a/ld/emulparams/i386nbsd.sh b/ld/emulparams/i386nbsd.sh new file mode 100644 index 0000000..a9e6a38 --- /dev/null +++ b/ld/emulparams/i386nbsd.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=aout +TEXT_START_ADDR=0x1020 +OUTPUT_FORMAT="a.out-i386-netbsd" +TARGET_PAGE_SIZE=0x1000 +ARCH=i386 +EXECUTABLE_SYMBOLS='__DYNAMIC = 0;' diff --git a/ld/emulparams/i386nw.sh b/ld/emulparams/i386nw.sh new file mode 100644 index 0000000..e70ed67 --- /dev/null +++ b/ld/emulparams/i386nw.sh @@ -0,0 +1,9 @@ +SCRIPT_NAME=nw +OUTPUT_FORMAT="elf32-i386" +TEXT_START_ADDR=0x08000000 +MAXPAGESIZE=0x1000 +NONPAGED_TEXT_START_ADDR=0x08000000 +ARCH=i386 +NOP=0x9090 +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes diff --git a/ld/emulparams/i386pe.sh b/ld/emulparams/i386pe.sh new file mode 100644 index 0000000..188a8ad --- /dev/null +++ b/ld/emulparams/i386pe.sh @@ -0,0 +1,5 @@ +ARCH=i386 +SCRIPT_NAME=pe +OUTPUT_FORMAT="pei-i386" +RELOCATEABLE_OUTPUT_FORMAT="pe-i386" +TEMPLATE_NAME=pe diff --git a/ld/emulparams/lnk960.sh b/ld/emulparams/lnk960.sh new file mode 100644 index 0000000..3cf3fc4 --- /dev/null +++ b/ld/emulparams/lnk960.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=i960 +OUTPUT_FORMAT="" +TEXT_START_ADDR=?? +TARGET_PAGE_SIZE=?? +ARCH=i960 +TEMPLATE_NAME=lnk960 diff --git a/ld/emulparams/m32relf.sh b/ld/emulparams/m32relf.sh new file mode 100644 index 0000000..cd7705a --- /dev/null +++ b/ld/emulparams/m32relf.sh @@ -0,0 +1,13 @@ +MACHINE= +SCRIPT_NAME=elf +TEMPLATE_NAME=elf32 +OUTPUT_FORMAT="elf32-m32r" +TEXT_START_ADDR=0x100 +ARCH=m32r +MACHINE= +MAXPAGESIZE=32 +EMBEDDED=yes + +# Hmmm, there's got to be a better way. This sets the stack to the +# top of simulator memory (8MB). +OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = 0x800000);' diff --git a/ld/emulparams/m68k4knbsd.sh b/ld/emulparams/m68k4knbsd.sh new file mode 100644 index 0000000..1bc24c0e --- /dev/null +++ b/ld/emulparams/m68k4knbsd.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=aout +TEXT_START_ADDR=0x1020 +NONPAGED_TEXT_START_ADDR=0x1000 +OUTPUT_FORMAT="a.out-m68k4k-netbsd" +TARGET_PAGE_SIZE=0x1000 +ARCH=m68k +EXECUTABLE_SYMBOLS='__DYNAMIC = 0;' diff --git a/ld/emulparams/m68kaout.sh b/ld/emulparams/m68kaout.sh new file mode 100644 index 0000000..9bfaaf7 --- /dev/null +++ b/ld/emulparams/m68kaout.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-zero-big" +TEXT_START_ADDR=0x2020 +TARGET_PAGE_SIZE=0x2000 +SEGMENT_SIZE=0x20000 +NONPAGED_TEXT_START_ADDR=0x2000 +ARCH=m68k diff --git a/ld/emulparams/m68kaux.sh b/ld/emulparams/m68kaux.sh new file mode 100644 index 0000000..19e86cc --- /dev/null +++ b/ld/emulparams/m68kaux.sh @@ -0,0 +1,8 @@ +SCRIPT_NAME=m68kaux +OUTPUT_FORMAT="coff-m68k-aux" +SEGMENT_SIZE=0x40000 +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR="$SEGMENT_SIZE + SIZEOF_HEADERS" +NON_PAGED_TEXT_START_ADDR=SIZEOF_HEADERS +DATA_ALIGNMENT_="(. & (-$SEGMENT_SIZE | $TARGET_PAGE_SIZE-1)) + $SEGMENT_SIZE" +ARCH=m68k diff --git a/ld/emulparams/m68kcoff.sh b/ld/emulparams/m68kcoff.sh new file mode 100644 index 0000000..b417c0d --- /dev/null +++ b/ld/emulparams/m68kcoff.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=m68kcoff +OUTPUT_FORMAT="coff-m68k" +TEXT_START_ADDR=0x1000000 +TARGET_PAGE_SIZE=0x1000000 +ARCH=m68k diff --git a/ld/emulparams/m68kelf.sh b/ld/emulparams/m68kelf.sh new file mode 100644 index 0000000..ad352c5 --- /dev/null +++ b/ld/emulparams/m68kelf.sh @@ -0,0 +1,10 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-m68k" +TEXT_START_ADDR=0x80000000 +MAXPAGESIZE=0x2000 +NONPAGED_TEXT_START_ADDR=${TEXT_START_ADDR} +ARCH=m68k +MACHINE= +NOP=0x4e75 +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes diff --git a/ld/emulparams/m68klinux.sh b/ld/emulparams/m68klinux.sh new file mode 100644 index 0000000..56c3dad --- /dev/null +++ b/ld/emulparams/m68klinux.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-m68k-linux" +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR=0x1020 +NONPAGED_TEXT_START_ADDR=0 +ARCH=m68k +TEMPLATE_NAME=linux diff --git a/ld/emulparams/m68klynx.sh b/ld/emulparams/m68klynx.sh new file mode 100644 index 0000000..b020feb --- /dev/null +++ b/ld/emulparams/m68klynx.sh @@ -0,0 +1,8 @@ +SCRIPT_NAME=m68klynx +OUTPUT_FORMAT="coff-m68k-lynx" +# This is what LynxOS /lib/init1.o wants. +ENTRY=__main +# following are dubious +TEXT_START_ADDR=0 +TARGET_PAGE_SIZE=0x1000 +ARCH=m68k diff --git a/ld/emulparams/m68knbsd.sh b/ld/emulparams/m68knbsd.sh new file mode 100644 index 0000000..a742807 --- /dev/null +++ b/ld/emulparams/m68knbsd.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=aout +TEXT_START_ADDR=0x2020 +NONPAGED_TEXT_START_ADDR=0x2000 +OUTPUT_FORMAT="a.out-m68k-netbsd" +TARGET_PAGE_SIZE=0x2000 +ARCH=m68k +EXECUTABLE_SYMBOLS='__DYNAMIC = 0;' diff --git a/ld/emulparams/m68kpsos.sh b/ld/emulparams/m68kpsos.sh new file mode 100644 index 0000000..34eb8ca --- /dev/null +++ b/ld/emulparams/m68kpsos.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=psos +OUTPUT_FORMAT="elf32-m68k" +TEXT_START_ADDR=0x20000 +MAXPAGESIZE=0x1000 +ARCH=m68k +TEMPLATE_NAME=elf32 diff --git a/ld/emulparams/m88kbcs.sh b/ld/emulparams/m88kbcs.sh new file mode 100644 index 0000000..6c6737c --- /dev/null +++ b/ld/emulparams/m88kbcs.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=m88kbcs +OUTPUT_FORMAT="coff-m88kbcs" +TEXT_START_ADDR=?? +TARGET_PAGE_SIZE=?? +ARCH=m88k diff --git a/ld/emulparams/mcorepe.sh b/ld/emulparams/mcorepe.sh new file mode 100644 index 0000000..b5baee9 --- /dev/null +++ b/ld/emulparams/mcorepe.sh @@ -0,0 +1,6 @@ +ARCH=mcore +SCRIPT_NAME=mcorepe +OUTPUT_FORMAT="pei-mcore-big" +LITTLE_OUTPUT_FORMAT="pei-mcore-little" +BIG_OUTPUT_FORMAT="pei-mcore-big" +TEMPLATE_NAME=pe diff --git a/ld/emulparams/mipsbig.sh b/ld/emulparams/mipsbig.sh new file mode 100644 index 0000000..9fe2953 --- /dev/null +++ b/ld/emulparams/mipsbig.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=mips +OUTPUT_FORMAT="ecoff-bigmips" +BIG_OUTPUT_FORMAT="ecoff-bigmips" +LITTLE_OUTPUT_FORMAT="ecoff-littlemips" +TARGET_PAGE_SIZE=0x1000000 +ARCH=mips diff --git a/ld/emulparams/mipsbsd.sh b/ld/emulparams/mipsbsd.sh new file mode 100644 index 0000000..e8fb35b --- /dev/null +++ b/ld/emulparams/mipsbsd.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=mipsbsd +OUTPUT_FORMAT="a.out-mips-little" +BIG_OUTPUT_FORMAT="a.out-mips-big" +LITTLE_OUTPUT_FORMAT="a.out-mips-little" +TEXT_START_ADDR=0x1020 +TARGET_PAGE_SIZE=4096 +ARCH=mips diff --git a/ld/emulparams/mipsidt.sh b/ld/emulparams/mipsidt.sh new file mode 100644 index 0000000..63176f5 --- /dev/null +++ b/ld/emulparams/mipsidt.sh @@ -0,0 +1,11 @@ +SCRIPT_NAME=mips +OUTPUT_FORMAT="ecoff-bigmips" +BIG_OUTPUT_FORMAT="ecoff-bigmips" +LITTLE_OUTPUT_FORMAT="ecoff-littlemips" +TARGET_PAGE_SIZE=0x1000000 +ARCH=mips +ENTRY=start +TEXT_START_ADDR=0xa0012000 +DATA_ADDR=. +TEMPLATE_NAME=mipsecoff +EMBEDDED=yes diff --git a/ld/emulparams/mipsidtl.sh b/ld/emulparams/mipsidtl.sh new file mode 100644 index 0000000..02279de --- /dev/null +++ b/ld/emulparams/mipsidtl.sh @@ -0,0 +1,11 @@ +SCRIPT_NAME=mips +OUTPUT_FORMAT="ecoff-littlemips" +BIG_OUTPUT_FORMAT="ecoff-bigmips" +LITTLE_OUTPUT_FORMAT="ecoff-littlemips" +TARGET_PAGE_SIZE=0x1000000 +ARCH=mips +ENTRY=start +TEXT_START_ADDR=0xa0012000 +DATA_ADDR=. +TEMPLATE_NAME=mipsecoff +EMBEDDED=yes diff --git a/ld/emulparams/mipslit.sh b/ld/emulparams/mipslit.sh new file mode 100644 index 0000000..acb2344 --- /dev/null +++ b/ld/emulparams/mipslit.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=mips +OUTPUT_FORMAT="ecoff-littlemips" +BIG_OUTPUT_FORMAT="ecoff-bigmips" +LITTLE_OUTPUT_FORMAT="ecoff-littlemips" +TARGET_PAGE_SIZE=0x1000000 +ARCH=mips diff --git a/ld/emulparams/mipslnews.sh b/ld/emulparams/mipslnews.sh new file mode 100644 index 0000000..d0bb91c --- /dev/null +++ b/ld/emulparams/mipslnews.sh @@ -0,0 +1,9 @@ +SCRIPT_NAME=mips +OUTPUT_FORMAT="ecoff-littlemips" +BIG_OUTPUT_FORMAT="ecoff-bigmips" +LITTLE_OUTPUT_FORMAT="ecoff-littlemips" +TARGET_PAGE_SIZE=0x1000000 +ARCH=mips +TEXT_START_ADDR=0x80080000 +DATA_ADDR=. +EMBEDDED=yes diff --git a/ld/emulparams/mn10200.sh b/ld/emulparams/mn10200.sh new file mode 100644 index 0000000..6324322 --- /dev/null +++ b/ld/emulparams/mn10200.sh @@ -0,0 +1,20 @@ +MACHINE= +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-mn10200" +TEXT_START_ADDR=0x0 +ARCH=mn10200 +MACHINE= +MAXPAGESIZE=1 +ENTRY=_start +EMBEDDED=yes + +# Hmmm, there's got to be a better way. This sets the stack to the +# top of the simulator memory (2^19 bytes). +OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }' + +# These are for compatibility with the COFF toolchain. +# XXX These should definitely disappear. +CTOR_START='___ctors = .;' +CTOR_END='___ctors_end = .;' +DTOR_START='___dtors = .;' +DTOR_END='___dtors_end = .;' diff --git a/ld/emulparams/mn10300.sh b/ld/emulparams/mn10300.sh new file mode 100644 index 0000000..44a40e5 --- /dev/null +++ b/ld/emulparams/mn10300.sh @@ -0,0 +1,20 @@ +MACHINE= +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-mn10300" +TEXT_START_ADDR=0x0 +ARCH=mn10300 +MACHINE= +MAXPAGESIZE=1 +ENTRY=_start +EMBEDDED=yes + +# Hmmm, there's got to be a better way. This sets the stack to the +# top of the simulator memory (2^19 bytes). +OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }' + +# These are for compatibility with the COFF toolchain. +# XXX These should definitely disappear. +CTOR_START='___ctors = .;' +CTOR_END='___ctors_end = .;' +DTOR_START='___dtors = .;' +DTOR_END='___dtors_end = .;' diff --git a/ld/emulparams/news.sh b/ld/emulparams/news.sh new file mode 100644 index 0000000..310ddf9 --- /dev/null +++ b/ld/emulparams/news.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-newsos3" +TEXT_START_ADDR=0 +TARGET_PAGE_SIZE=0x1000 +ARCH=m68k diff --git a/ld/emulparams/ns32knbsd.sh b/ld/emulparams/ns32knbsd.sh new file mode 100644 index 0000000..1c4fdf3 --- /dev/null +++ b/ld/emulparams/ns32knbsd.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=aout +TEXT_START_ADDR=0x1020 +OUTPUT_FORMAT="a.out-ns32k-netbsd" +TARGET_PAGE_SIZE=0x1000 +ARCH=ns32k diff --git a/ld/emulparams/pc532macha.sh b/ld/emulparams/pc532macha.sh new file mode 100644 index 0000000..9c1d079 --- /dev/null +++ b/ld/emulparams/pc532macha.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-pc532-mach" +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR="0x10020" +NONPAGED_TEXT_START_ADDR=0x10000 +ARCH=ns32k diff --git a/ld/emulparams/ppcmacos.sh b/ld/emulparams/ppcmacos.sh new file mode 100644 index 0000000..b6b800c --- /dev/null +++ b/ld/emulparams/ppcmacos.sh @@ -0,0 +1,4 @@ +TEMPLATE_NAME=aix +SCRIPT_NAME=aix +OUTPUT_FORMAT="xcoff-powermac" +ARCH=powerpc diff --git a/ld/emulparams/ppcnw.sh b/ld/emulparams/ppcnw.sh new file mode 100644 index 0000000..c3ead43 --- /dev/null +++ b/ld/emulparams/ppcnw.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=nw +OUTPUT_FORMAT="elf32-powerpc" +TEXT_START_ADDR=0x0400000 +DATA_ADDR=0x10000000 +MAXPAGESIZE=0x40000 +NONPAGED_TEXT_START_ADDR=0x0400000 +ARCH=powerpc diff --git a/ld/emulparams/ppcpe.sh b/ld/emulparams/ppcpe.sh new file mode 100644 index 0000000..655282d --- /dev/null +++ b/ld/emulparams/ppcpe.sh @@ -0,0 +1,4 @@ +ARCH=powerpc +SCRIPT_NAME=ppcpe +OUTPUT_FORMAT="pei-powerpcle" +TEMPLATE_NAME=pe diff --git a/ld/emulparams/riscix.sh b/ld/emulparams/riscix.sh new file mode 100644 index 0000000..e7f6d92 --- /dev/null +++ b/ld/emulparams/riscix.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=riscix +OUTPUT_FORMAT="a.out-riscix" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=0x8000 +ARCH=arm diff --git a/ld/emulparams/sa29200.sh b/ld/emulparams/sa29200.sh new file mode 100644 index 0000000..8b52f92 --- /dev/null +++ b/ld/emulparams/sa29200.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=sa29200 +OUTPUT_FORMAT="coff-a29k-big" +TEXT_START_ADDR=0x40004000 +TARGET_PAGE_SIZE=0x1000 +ARCH=a29k diff --git a/ld/emulparams/sh.sh b/ld/emulparams/sh.sh new file mode 100644 index 0000000..38844fb --- /dev/null +++ b/ld/emulparams/sh.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=sh +OUTPUT_FORMAT="coff-sh" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=sh diff --git a/ld/emulparams/shelf.sh b/ld/emulparams/shelf.sh new file mode 100644 index 0000000..95db587 --- /dev/null +++ b/ld/emulparams/shelf.sh @@ -0,0 +1,17 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-sh" +TEXT_START_ADDR=0x1000 +MAXPAGESIZE=128 +ARCH=sh +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +EMBEDDED=yes + +# These are for compatibility with the COFF toolchain. +ENTRY=start +CTOR_START='___ctors = .;' +CTOR_END='___ctors_end = .;' +DTOR_START='___dtors = .;' +DTOR_END='___dtors_end = .;' +OTHER_RELOCATING_SECTIONS='.stack 0x30000 : { _stack = .; *(.stack) }' diff --git a/ld/emulparams/shl.sh b/ld/emulparams/shl.sh new file mode 100644 index 0000000..360aac8 --- /dev/null +++ b/ld/emulparams/shl.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=sh +OUTPUT_FORMAT="coff-shl" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=sh diff --git a/ld/emulparams/shlelf.sh b/ld/emulparams/shlelf.sh new file mode 100644 index 0000000..bb27f86 --- /dev/null +++ b/ld/emulparams/shlelf.sh @@ -0,0 +1,17 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-shl" +TEXT_START_ADDR=0x1000 +MAXPAGESIZE=128 +ARCH=sh +MACHINE= +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +EMBEDDED=yes + +# These are for compatibility with the COFF toolchain. +ENTRY=start +CTOR_START='___ctors = .;' +CTOR_END='___ctors_end = .;' +DTOR_START='___dtors = .;' +DTOR_END='___dtors_end = .;' +OTHER_RELOCATING_SECTIONS='.stack 0x30000 : { _stack = .; *(.stack) }' diff --git a/ld/emulparams/sparcaout.sh b/ld/emulparams/sparcaout.sh new file mode 100644 index 0000000..429b925 --- /dev/null +++ b/ld/emulparams/sparcaout.sh @@ -0,0 +1,8 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-sunos-big" +BIG_OUTPUT_FORMAT="a.out-sunos-big" +LITTLE_OUTPUT_FORMAT="a.out-sparc-little" +TEXT_START_ADDR=0x2020 +TARGET_PAGE_SIZE=0x2000 +NONPAGED_TEXT_START_ADDR=0x2000 +ARCH=sparc diff --git a/ld/emulparams/sparclinux.sh b/ld/emulparams/sparclinux.sh new file mode 100644 index 0000000..7ccb0bec --- /dev/null +++ b/ld/emulparams/sparclinux.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-sparc-linux" +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR=0x1020 +NONPAGED_TEXT_START_ADDR=0 +ARCH=sparc +TEMPLATE_NAME=linux diff --git a/ld/emulparams/sparclynx.sh b/ld/emulparams/sparclynx.sh new file mode 100644 index 0000000..9aeb30b --- /dev/null +++ b/ld/emulparams/sparclynx.sh @@ -0,0 +1,9 @@ +SCRIPT_NAME=sparclynx +OUTPUT_FORMAT="coff-sparc-lynx" +# This is what LynxOS /lib/init1.o wants. +ENTRY=__main +# following are dubious +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR=0 +NONPAGED_TEXT_START_ADDR=0x1000 +ARCH=sparc diff --git a/ld/emulparams/sparcnbsd.sh b/ld/emulparams/sparcnbsd.sh new file mode 100644 index 0000000..f27daf3 --- /dev/null +++ b/ld/emulparams/sparcnbsd.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=aout +TEXT_START_ADDR=0x1020 +OUTPUT_FORMAT="a.out-sparc-netbsd" +TARGET_PAGE_SIZE=0x1000 +ARCH=sparc diff --git a/ld/emulparams/st2000.sh b/ld/emulparams/st2000.sh new file mode 100644 index 0000000..0498832 --- /dev/null +++ b/ld/emulparams/st2000.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=st2000 +OUTPUT_FORMAT="coff-m68k" +TEXT_START_ADDR=0x0 +TARGET_PAGE_SIZE=128 +ARCH=m68k diff --git a/ld/emulparams/sun3.sh b/ld/emulparams/sun3.sh new file mode 100644 index 0000000..db0f71f --- /dev/null +++ b/ld/emulparams/sun3.sh @@ -0,0 +1,8 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-sunos-big" +TEXT_START_ADDR=0x2020 +TARGET_PAGE_SIZE=0x2000 +SEGMENT_SIZE=0x20000 +NONPAGED_TEXT_START_ADDR=0x2000 +ARCH=m68k +TEMPLATE_NAME=sunos diff --git a/ld/emulparams/sun4.sh b/ld/emulparams/sun4.sh new file mode 100644 index 0000000..bd42775 --- /dev/null +++ b/ld/emulparams/sun4.sh @@ -0,0 +1,8 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-sunos-big" +TEXT_START_ADDR=0x2020 +TARGET_PAGE_SIZE=0x2000 +NONPAGED_TEXT_START_ADDR=0x2000 +ALIGNMENT=8 +ARCH=sparc +TEMPLATE_NAME=sunos diff --git a/ld/emulparams/tic30aout.sh b/ld/emulparams/tic30aout.sh new file mode 100644 index 0000000..2a4c13f --- /dev/null +++ b/ld/emulparams/tic30aout.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=tic30aout +OUTPUT_FORMAT="a.out-tic30" +OUTPUT_ARCH="tms320c30" +TEXT_START_ADDR=0x0 +TARGET_PAGE_SIZE=128 +ARCH=tms320c30 +BIG=1 diff --git a/ld/emulparams/tic30coff.sh b/ld/emulparams/tic30coff.sh new file mode 100644 index 0000000..df77943 --- /dev/null +++ b/ld/emulparams/tic30coff.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=tic30coff +OUTPUT_FORMAT="coff-tic30" +OUTPUT_ARCH="tms320c30" +TEXT_START_ADDR=0x0 +TARGET_PAGE_SIZE=128 +ARCH=tms320c30 +BIG=1 diff --git a/ld/emulparams/tic80coff.sh b/ld/emulparams/tic80coff.sh new file mode 100644 index 0000000..7070323 --- /dev/null +++ b/ld/emulparams/tic80coff.sh @@ -0,0 +1,56 @@ +# This file is sourced by the genscripts.sh script. +# These are shell variables that are used later by either genscripts +# or on of the scripts that it sources. + +# The name of the scripttempl script to use. In this case, genscripts +# uses scripttempl/tic80coff.sc +# +SCRIPT_NAME=tic80coff + +# The name of the emultempl script to use. If set to "template" then +# genscripts.sh will use the script emultempl/template.em. If not set, +# then the default value is "generic". +# +# TEMPLATE_NAME= + +# If this is set to an nonempty string, genscripts.sh will invoke the +# scripttempl script an extra time to create a shared library script. +# +# GENERATE_SHLIB_SCRIPT= + +# The BFD output format to use. The scripttempl script will use it in +# an OUTPUT_FORMAT expression in the linker script. +# +OUTPUT_FORMAT="coff-tic80" + +# This is normally set to indicate the architecture to use, such as +# "sparc". The scripttempl script will normally use it in an OUTPUT_ARCH +# expression in the linker script. +# +ARCH=tic80 + +# Some scripttempl scripts use this to set the entry address in an ENTRY +# expression in the linker script. +# +# ENTRY= + +# The scripttempl script uses this to set the start address of the +# ".text" section. +# +TEXT_START_ADDR=0x2000000 + +# If this is defined, the genscripts.sh script sets TEXT_START_ADDR to +# its value before running the scripttempl script for the -n and -N +# options. +# +# NONPAGED_TEXT_START_ADDR= + +# The genscripts.sh script uses this to set the default value of +# DATA_ALIGNMENT when running the scripttempl script. +# +# SEGMENT_SIZE= + +# If SEGMENT_SIZE is not defined, the genscripts.sh script uses this +# to define it. +# +TARGET_PAGE_SIZE=0x1000 diff --git a/ld/emulparams/v850.sh b/ld/emulparams/v850.sh new file mode 100644 index 0000000..78bfbd3 --- /dev/null +++ b/ld/emulparams/v850.sh @@ -0,0 +1,14 @@ +MACHINE= +SCRIPT_NAME=v850 +OUTPUT_FORMAT="elf32-v850" +TEXT_START_ADDR=0x100000 +ZDATA_START_ADDR=0x160 +ROZDATA_START_ADDR="ALIGN (4)" +SDATA_START_ADDR="ALIGN (4)" +ROSDATA_START_ADDR="ALIGN (4)" +TDATA_START_ADDR="ALIGN (4)" +CALL_TABLE_START_ADDR="ALIGN (4)" +ARCH=v850 +MAXPAGESIZE=256 +ENTRY=_start +EMBEDDED=yes diff --git a/ld/emulparams/vanilla.sh b/ld/emulparams/vanilla.sh new file mode 100644 index 0000000..d8a3b72 --- /dev/null +++ b/ld/emulparams/vanilla.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=vanilla +TEXT_START_ADDR=?? +TARGET_PAGE_SIZE=?? +ARCH=unknown +TEMPLATE_NAME=vanilla diff --git a/ld/emulparams/vax.sh b/ld/emulparams/vax.sh new file mode 100644 index 0000000..9785483 --- /dev/null +++ b/ld/emulparams/vax.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out" +TEXT_START_ADDR=0 +TARGET_PAGE_SIZE=1024 +ARCH=vax diff --git a/ld/emulparams/vsta.sh b/ld/emulparams/vsta.sh new file mode 100644 index 0000000..cc6249b --- /dev/null +++ b/ld/emulparams/vsta.sh @@ -0,0 +1,8 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-i386" +TEXT_START_ADDR=0x1020 +TARGET_PAGE_SIZE=0x1000 +SEGMENT_SIZE=0x400000 +NONPAGED_TEXT_START_ADDR=0x0 +ARCH=i386 + diff --git a/ld/emulparams/w65.sh b/ld/emulparams/w65.sh new file mode 100644 index 0000000..6f02b23 --- /dev/null +++ b/ld/emulparams/w65.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=w65 +OUTPUT_FORMAT="coff-w65" +TEXT_START_ADDR=0x1000 +TARGET_PAGE_SIZE=64 +ARCH=w65 diff --git a/ld/emulparams/z8001.sh b/ld/emulparams/z8001.sh new file mode 100644 index 0000000..63645c3 --- /dev/null +++ b/ld/emulparams/z8001.sh @@ -0,0 +1,7 @@ +SCRIPT_NAME=z8000 +OUTPUT_FORMAT="coff-z8k" +OUTPUT_ARCH="z8001" +TEXT_START_ADDR=0x0 +TARGET_PAGE_SIZE=128 +ARCH=z8k +BIG=1 diff --git a/ld/emulparams/z8002.sh b/ld/emulparams/z8002.sh new file mode 100644 index 0000000..299b5f5 --- /dev/null +++ b/ld/emulparams/z8002.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=z8000 +OUTPUT_FORMAT="coff-z8k" +OUTPUT_ARCH="z8002" +TEXT_START_ADDR=0x0 +TARGET_PAGE_SIZE=128 +ARCH=z8002 diff --git a/ld/emultempl/README b/ld/emultempl/README new file mode 100644 index 0000000..30ec0ab --- /dev/null +++ b/ld/emultempl/README @@ -0,0 +1,3 @@ +The files in this directory are sourced by genscripts.sh, after +setting some variables to substitute in, to produce +C source files that contain jump tables for each emulation. diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em new file mode 100644 index 0000000..c77857f --- /dev/null +++ b/ld/emultempl/aix.em @@ -0,0 +1,1054 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* AIX emulation code for ${EMULATION_NAME} + Copyright (C) 1991, 93, 95, 96, 97, 1998 Free Software Foundation, Inc. + Written by Steve Chamberlain <sac@cygnus.com> + AIX support by Ian Lance Taylor <ian@cygnus.com> + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_${EMULATION_NAME} + +#include "bfd.h" +#include "sysdep.h" +#include "libiberty.h" +#include "getopt.h" +#include "obstack.h" +#include "bfdlink.h" + +#include <ctype.h> + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldctor.h" +#include "ldgram.h" + +static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static int gld${EMULATION_NAME}_parse_args PARAMS ((int, char **)); +static void gld${EMULATION_NAME}_after_open PARAMS ((void)); +static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); +static void gld${EMULATION_NAME}_read_file PARAMS ((const char *, boolean)); +static void gld${EMULATION_NAME}_free PARAMS ((PTR)); +static void gld${EMULATION_NAME}_find_relocs + PARAMS ((lang_statement_union_type *)); +static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *)); +static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); + +/* The file alignment required for each section. */ +static unsigned long file_align; + +/* The maximum size the stack is permitted to grow. This is stored in + the a.out header. */ +static unsigned long maxstack; + +/* The maximum data size. This is stored in the a.out header. */ +static unsigned long maxdata; + +/* Whether to perform garbage collection. */ +static int gc = 1; + +/* The module type to use. */ +static unsigned short modtype = ('1' << 8) | 'L'; + +/* Whether the .text section must be read-only (i.e., no relocs + permitted). */ +static int textro; + +/* Whether to implement Unix like linker semantics. */ +static int unix_ld; + +/* Structure used to hold import file list. */ + +struct filelist +{ + struct filelist *next; + const char *name; +}; + +/* List of import files. */ +static struct filelist *import_files; + +/* List of export symbols read from the export files. */ + +struct export_symbol_list +{ + struct export_symbol_list *next; + const char *name; + boolean syscall; +}; + +static struct export_symbol_list *export_symbols; + +/* This routine is called before anything else is done. */ + +static void +gld${EMULATION_NAME}_before_parse() +{ +#ifndef TARGET_ /* I.e., if not generic. */ + ldfile_output_architecture = bfd_arch_${ARCH}; +#endif /* not TARGET_ */ + config.has_shared = true; +} + +/* Handle AIX specific options. */ + +static int +gld${EMULATION_NAME}_parse_args (argc, argv) + int argc; + char **argv; +{ + int prevoptind = optind; + int prevopterr = opterr; + int indx; + int longind; + int optc; + long val; + char *end; + +#define OPTION_IGNORE (300) +#define OPTION_AUTOIMP (OPTION_IGNORE + 1) +#define OPTION_ERNOTOK (OPTION_AUTOIMP + 1) +#define OPTION_EROK (OPTION_ERNOTOK + 1) +#define OPTION_EXPORT (OPTION_EROK + 1) +#define OPTION_IMPORT (OPTION_EXPORT + 1) +#define OPTION_LOADMAP (OPTION_IMPORT + 1) +#define OPTION_MAXDATA (OPTION_LOADMAP + 1) +#define OPTION_MAXSTACK (OPTION_MAXDATA + 1) +#define OPTION_MODTYPE (OPTION_MAXSTACK + 1) +#define OPTION_NOAUTOIMP (OPTION_MODTYPE + 1) +#define OPTION_NOSTRCMPCT (OPTION_NOAUTOIMP + 1) +#define OPTION_PD (OPTION_NOSTRCMPCT + 1) +#define OPTION_PT (OPTION_PD + 1) +#define OPTION_STRCMPCT (OPTION_PT + 1) +#define OPTION_UNIX (OPTION_STRCMPCT + 1) + + static struct option longopts[] = { + {"basis", no_argument, NULL, OPTION_IGNORE}, + {"bautoimp", no_argument, NULL, OPTION_AUTOIMP}, + {"bcomprld", no_argument, NULL, OPTION_IGNORE}, + {"bcrld", no_argument, NULL, OPTION_IGNORE}, + {"bcror31", no_argument, NULL, OPTION_IGNORE}, + {"bD", required_argument, NULL, OPTION_MAXDATA}, + {"bE", required_argument, NULL, OPTION_EXPORT}, + {"bernotok", no_argument, NULL, OPTION_ERNOTOK}, + {"berok", no_argument, NULL, OPTION_EROK}, + {"berrmsg", no_argument, NULL, OPTION_IGNORE}, + {"bexport", required_argument, NULL, OPTION_EXPORT}, + {"bf", no_argument, NULL, OPTION_ERNOTOK}, + {"bgc", no_argument, &gc, 1}, + {"bh", required_argument, NULL, OPTION_IGNORE}, + {"bhalt", required_argument, NULL, OPTION_IGNORE}, + {"bI", required_argument, NULL, OPTION_IMPORT}, + {"bimport", required_argument, NULL, OPTION_IMPORT}, + {"bl", required_argument, NULL, OPTION_LOADMAP}, + {"bloadmap", required_argument, NULL, OPTION_LOADMAP}, + {"bmaxdata", required_argument, NULL, OPTION_MAXDATA}, + {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK}, + {"bM", required_argument, NULL, OPTION_MODTYPE}, + {"bmodtype", required_argument, NULL, OPTION_MODTYPE}, + {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP}, + {"bnodelcsect", no_argument, NULL, OPTION_IGNORE}, + {"bnoentry", no_argument, NULL, OPTION_IGNORE}, + {"bnogc", no_argument, &gc, 0}, + {"bnso", no_argument, NULL, OPTION_NOAUTOIMP}, + {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT}, + {"bnotextro", no_argument, &textro, 0}, + {"bnro", no_argument, &textro, 0}, + {"bpD", required_argument, NULL, OPTION_PD}, + {"bpT", required_argument, NULL, OPTION_PT}, + {"bro", no_argument, &textro, 1}, + {"bS", required_argument, NULL, OPTION_MAXSTACK}, + {"bso", no_argument, NULL, OPTION_AUTOIMP}, + {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT}, + {"btextro", no_argument, &textro, 1}, + {"static", no_argument, NULL, OPTION_NOAUTOIMP}, + {"unix", no_argument, NULL, OPTION_UNIX}, + {NULL, no_argument, NULL, 0} + }; + + /* Options supported by the AIX linker which we do not support: -f, + -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps, + -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl, + -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl, + -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink, + -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder, + -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk, + -bx, -bX, -bxref. */ + + /* If the current option starts with -b, change the first : to an =. + The AIX linker uses : to separate the option from the argument; + changing it to = lets us treat it as a getopt option. */ + indx = optind; + if (indx == 0) + indx = 1; + if (indx < argc && strncmp (argv[indx], "-b", 2) == 0) + { + char *s; + + for (s = argv[indx]; *s != '\0'; s++) + { + if (*s == ':') + { + *s = '='; + break; + } + } + } + + /* We add s and u so to the short options list so that -s and -u on + the command line do not match -static and -unix. */ + + opterr = 0; + optc = getopt_long_only (argc, argv, "-D:H:KT:zsu", longopts, &longind); + opterr = prevopterr; + + switch (optc) + { + case 's': + case 'u': + default: + optind = prevoptind; + return 0; + + case 0: + /* Long option which just sets a flag. */ + break; + + case 'D': + val = strtol (optarg, &end, 0); + if (*end != '\0') + einfo ("%P: warning: ignoring invalid -D number %s\n", optarg); + else if (val != -1) + lang_section_start (".data", exp_intop (val)); + break; + + case 'H': + val = strtoul (optarg, &end, 0); + if (*end != '\0' + || (val & (val - 1)) != 0) + einfo ("%P: warning: ignoring invalid -H number %s\n", optarg); + else + file_align = val; + break; + + case 'K': + case 'z': + /* FIXME: This should use the page size for the target system. */ + file_align = 4096; + break; + + case 'T': + /* On AIX this is the same as GNU ld -Ttext. When we see -T + number, we assume the AIX option is intended. Otherwise, we + assume the usual GNU ld -T option is intended. We can't just + ignore the AIX option, because gcc passes it to the linker. */ + val = strtoul (optarg, &end, 0); + if (*end != '\0') + { + optind = prevoptind; + return 0; + } + lang_section_start (".text", exp_intop (val)); + break; + + case OPTION_IGNORE: + break; + + case OPTION_AUTOIMP: + link_info.static_link = false; + break; + + case OPTION_ERNOTOK: + force_make_executable = false; + break; + + case OPTION_EROK: + force_make_executable = true; + break; + + case OPTION_EXPORT: + gld${EMULATION_NAME}_read_file (optarg, false); + break; + + case OPTION_IMPORT: + { + struct filelist *n; + struct filelist **flpp; + + n = (struct filelist *) xmalloc (sizeof (struct filelist)); + n->next = NULL; + n->name = optarg; + flpp = &import_files; + while (*flpp != NULL) + flpp = &(*flpp)->next; + *flpp = n; + } + break; + + case OPTION_LOADMAP: + config.map_filename = optarg; + break; + + case OPTION_MAXDATA: + val = strtoul (optarg, &end, 0); + if (*end != '\0') + einfo ("%P: warning: ignoring invalid -bmaxdata number %s\n", + optarg); + else + maxdata = val; + break; + + case OPTION_MAXSTACK: + val = strtoul (optarg, &end, 0); + if (*end != '\0') + einfo ("%P: warning: ignoring invalid -bmaxstack number %s\n", + optarg); + else + maxstack = val; + break; + + case OPTION_MODTYPE: + if (*optarg == 'S') + { + link_info.shared = true; + ++optarg; + } + if (*optarg == '\0' || optarg[1] == '\0') + einfo ("%P: warning: ignoring invalid module type %s\n", optarg); + else + modtype = (*optarg << 8) | optarg[1]; + break; + + case OPTION_NOAUTOIMP: + link_info.static_link = true; + break; + + case OPTION_NOSTRCMPCT: + link_info.traditional_format = true; + break; + + case OPTION_PD: + /* This sets the page that the .data section is supposed to + start on. The offset within the page should still be the + offset within the file, so we need to build an appropriate + expression. */ + val = strtoul (optarg, &end, 0); + if (*end != '\0') + einfo ("%P: warning: ignoring invalid -pD number %s\n", optarg); + else + { + etree_type *t; + + t = exp_binop ('+', + exp_intop (val), + exp_binop ('&', + exp_nameop (NAME, "."), + exp_intop (0xfff))); + t = exp_binop ('&', + exp_binop ('+', t, exp_intop (31)), + exp_intop (~ (bfd_vma) 31)); + lang_section_start (".data", t); + } + break; + + case OPTION_PT: + /* This set the page that the .text section is supposed to start + on. The offset within the page should still be the offset + within the file. */ + val = strtoul (optarg, &end, 0); + if (*end != '\0') + einfo ("%P: warning: ignoring invalid -pT number %s\n", optarg); + else + { + etree_type *t; + + t = exp_binop ('+', + exp_intop (val), + exp_nameop (SIZEOF_HEADERS, NULL)); + t = exp_binop ('&', + exp_binop ('+', t, exp_intop (31)), + exp_intop (~ (bfd_vma) 31)); + lang_section_start (".text", t); + } + break; + + case OPTION_STRCMPCT: + link_info.traditional_format = false; + break; + + case OPTION_UNIX: + unix_ld = true; + break; + } + + return 1; +} + +/* This is called when an input file can not be recognized as a BFD + object or an archive. If the file starts with #!, we must treat it + as an import file. This is for AIX compatibility. */ + +static boolean +gld${EMULATION_NAME}_unrecognized_file (entry) + lang_input_statement_type *entry; +{ + FILE *e; + boolean ret; + + e = fopen (entry->filename, FOPEN_RT); + if (e == NULL) + return false; + + ret = false; + + if (getc (e) == '#' && getc (e) == '!') + { + struct filelist *n; + struct filelist **flpp; + + n = (struct filelist *) xmalloc (sizeof (struct filelist)); + n->next = NULL; + n->name = entry->filename; + flpp = &import_files; + while (*flpp != NULL) + flpp = &(*flpp)->next; + *flpp = n; + + ret = true; + entry->loaded = true; + } + + fclose (e); + + return ret; +} + +/* This is called after the input files have been opened. */ + +static void +gld${EMULATION_NAME}_after_open () +{ + boolean r; + struct set_info *p; + + /* Call ldctor_build_sets, after pretending that this is a + relocateable link. We do this because AIX requires relocation + entries for all references to symbols, even in a final + executable. Of course, we only want to do this if we are + producing an XCOFF output file. */ + r = link_info.relocateable; + if (strstr (bfd_get_target (output_bfd), "xcoff") != NULL) + link_info.relocateable = true; + ldctor_build_sets (); + link_info.relocateable = r; + + /* For each set, record the size, so that the XCOFF backend can + output the correct csect length. */ + for (p = sets; p != (struct set_info *) NULL; p = p->next) + { + bfd_size_type size; + + /* If the symbol is defined, we may have been invoked from + collect, and the sets may already have been built, so we do + not do anything. */ + if (p->h->type == bfd_link_hash_defined + || p->h->type == bfd_link_hash_defweak) + continue; + + if (p->reloc != BFD_RELOC_CTOR) + { + /* Handle this if we need to. */ + abort (); + } + + size = (p->count + 2) * 4; + if (! bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size)) + einfo ("%F%P: bfd_xcoff_link_record_set failed: %E\n"); + } +} + +/* This is called after the sections have been attached to output + sections, but before any sizes or addresses have been set. */ + +static void +gld${EMULATION_NAME}_before_allocation () +{ + struct filelist *fl; + struct export_symbol_list *el; + char *libpath; + asection *special_sections[6]; + int i; + + /* Handle the import and export files, if any. */ + for (fl = import_files; fl != NULL; fl = fl->next) + gld${EMULATION_NAME}_read_file (fl->name, true); + for (el = export_symbols; el != NULL; el = el->next) + { + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (link_info.hash, el->name, false, false, false); + if (h == NULL) + einfo ("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n"); + if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h, el->syscall)) + einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n"); + } + + /* Track down all relocations called for by the linker script (these + are typically constructor/destructor entries created by + CONSTRUCTORS) and let the backend know it will need to create + .loader relocs for them. */ + lang_for_each_statement (gld${EMULATION_NAME}_find_relocs); + + /* We need to build LIBPATH from the -L arguments. If any -rpath + arguments were used, though, we use -rpath instead, as a GNU + extension. */ + if (command_line.rpath != NULL) + libpath = command_line.rpath; + else if (search_head == NULL) + libpath = (char *) ""; + else + { + size_t len; + search_dirs_type *search; + + len = strlen (search_head->name); + libpath = xmalloc (len + 1); + strcpy (libpath, search_head->name); + for (search = search_head->next; search != NULL; search = search->next) + { + size_t nlen; + + nlen = strlen (search->name); + libpath = xrealloc (libpath, len + nlen + 2); + libpath[len] = ':'; + strcpy (libpath + len + 1, search->name); + len += nlen + 1; + } + } + + /* Let the XCOFF backend set up the .loader section. */ + if (! bfd_xcoff_size_dynamic_sections (output_bfd, &link_info, libpath, + entry_symbol, file_align, + maxstack, maxdata, + gc && ! unix_ld ? true : false, + modtype, + textro ? true : false, + unix_ld, + special_sections)) + einfo ("%P%F: failed to set dynamic section sizes: %E\n"); + + /* Look through the special sections, and put them in the right + place in the link ordering. This is especially magic. */ + for (i = 0; i < 6; i++) + { + asection *sec; + lang_output_section_statement_type *os; + lang_statement_union_type **pls; + lang_input_section_type *is; + const char *oname; + boolean start; + + sec = special_sections[i]; + if (sec == NULL) + continue; + + /* Remove this section from the list of the output section. + This assumes we know what the script looks like. */ + is = NULL; + os = lang_output_section_find (sec->output_section->name); + if (os == NULL) + einfo ("%P%F: can't find output section %s\n", + sec->output_section->name); + for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->next) + { + if ((*pls)->header.type == lang_input_section_enum + && (*pls)->input_section.section == sec) + { + is = (lang_input_section_type *) *pls; + *pls = (*pls)->next; + break; + } + if ((*pls)->header.type == lang_wild_statement_enum) + { + lang_statement_union_type **pwls; + + for (pwls = &(*pls)->wild_statement.children.head; + *pwls != NULL; + pwls = &(*pwls)->next) + { + if ((*pwls)->header.type == lang_input_section_enum + && (*pwls)->input_section.section == sec) + { + is = (lang_input_section_type *) *pwls; + *pwls = (*pwls)->next; + break; + } + } + if (is != NULL) + break; + } + } + + if (is == NULL) + einfo ("%P%F: can't find %s in output section\n", + bfd_get_section_name (sec->owner, sec)); + + /* Now figure out where the section should go. */ + switch (i) + { + default: /* to avoid warnings */ + case 0: + /* _text */ + oname = ".text"; + start = true; + break; + case 1: + /* _etext */ + oname = ".text"; + start = false; + break; + case 2: + /* _data */ + oname = ".data"; + start = true; + break; + case 3: + /* _edata */ + oname = ".data"; + start = false; + break; + case 4: + case 5: + /* _end and end */ + oname = ".bss"; + start = false; + break; + } + + os = lang_output_section_find (oname); + + if (start) + { + is->header.next = os->children.head; + os->children.head = (lang_statement_union_type *) is; + } + else + { + is->header.next = NULL; + lang_statement_append (&os->children, + (lang_statement_union_type *) is, + &is->header.next); + } + } +} + +/* Read an import or export file. For an import file, this is called + by the before_allocation emulation routine. For an export file, + this is called by the parse_args emulation routine. */ + +static void +gld${EMULATION_NAME}_read_file (filename, import) + const char *filename; + boolean import; +{ + struct obstack *o; + FILE *f; + int lineno; + int c; + boolean keep; + const char *imppath; + const char *impfile; + const char *impmember; + + o = (struct obstack *) xmalloc (sizeof (struct obstack)); + obstack_specify_allocation (o, 0, 0, xmalloc, gld${EMULATION_NAME}_free); + + f = fopen (filename, FOPEN_RT); + if (f == NULL) + { + bfd_set_error (bfd_error_system_call); + einfo ("%F%s: %E\n", filename); + } + + keep = false; + + imppath = NULL; + impfile = NULL; + impmember = NULL; + + lineno = 0; + while ((c = getc (f)) != EOF) + { + char *s; + char *symname; + boolean syscall; + bfd_vma address; + struct bfd_link_hash_entry *h; + + if (c != '\n') + { + obstack_1grow (o, c); + continue; + } + + obstack_1grow (o, '\0'); + ++lineno; + + s = (char *) obstack_base (o); + while (isspace ((unsigned char) *s)) + ++s; + if (*s == '\0' + || *s == '*' + || (*s == '#' && s[1] == ' ') + || (! import && *s == '#' && s[1] == '!')) + { + obstack_free (o, obstack_base (o)); + continue; + } + + if (*s == '#' && s[1] == '!') + { + s += 2; + while (isspace ((unsigned char) *s)) + ++s; + if (*s == '\0') + { + imppath = NULL; + impfile = NULL; + impmember = NULL; + obstack_free (o, obstack_base (o)); + } + else if (*s == '(') + einfo ("%F%s%d: #! ([member]) is not supported in import files\n", + filename, lineno); + else + { + char cs; + char *file; + + (void) obstack_finish (o); + keep = true; + imppath = s; + file = NULL; + while (! isspace ((unsigned char) *s) && *s != '(' && *s != '\0') + { + if (*s == '/') + file = s + 1; + ++s; + } + if (file != NULL) + { + file[-1] = '\0'; + impfile = file; + if (imppath == file - 1) + imppath = "/"; + } + else + { + impfile = imppath; + imppath = ""; + } + cs = *s; + *s = '\0'; + while (isspace ((unsigned char) cs)) + { + ++s; + cs = *s; + } + if (cs != '(') + { + impmember = ""; + if (cs != '\0') + einfo ("%s:%d: warning: syntax error in import file\n", + filename, lineno); + } + else + { + ++s; + impmember = s; + while (*s != ')' && *s != '\0') + ++s; + if (*s == ')') + *s = '\0'; + else + einfo ("%s:%d: warning: syntax error in import file\n", + filename, lineno); + } + } + + continue; + } + + /* This is a symbol to be imported or exported. */ + symname = s; + syscall = false; + address = (bfd_vma) -1; + + while (! isspace ((unsigned char) *s) && *s != '\0') + ++s; + if (*s != '\0') + { + char *se; + + *s++ = '\0'; + + while (isspace ((unsigned char) *s)) + ++s; + + se = s; + while (! isspace ((unsigned char) *se) && *se != '\0') + ++se; + if (*se != '\0') + { + *se++ = '\0'; + while (isspace ((unsigned char) *se)) + ++se; + if (*se != '\0') + einfo ("%s%d: warning: syntax error in import/export file\n", + filename, lineno); + } + + if (s == se) + { + /* There was no address after all. */ + } + else if (strcasecmp (s, "svc") == 0 + || strcasecmp (s, "syscall") == 0) + syscall = true; + else + { + char *end; + + address = strtoul (s, &end, 0); + if (*end != '\0') + einfo ("%s:%d: warning: syntax error in import/export file\n", + filename, lineno); + } + } + + if (! import) + { + struct export_symbol_list *n; + + ldlang_add_undef (symname); + n = ((struct export_symbol_list *) + xmalloc (sizeof (struct export_symbol_list))); + n->next = export_symbols; + n->name = buystring (symname); + n->syscall = syscall; + export_symbols = n; + } + else + { + h = bfd_link_hash_lookup (link_info.hash, symname, false, false, + true); + if (h == NULL || h->type == bfd_link_hash_new) + { + /* We can just ignore attempts to import an unreferenced + symbol. */ + } + else + { + if (! bfd_xcoff_import_symbol (output_bfd, &link_info, h, + address, imppath, impfile, + impmember)) + einfo ("%X%s:%d: failed to import symbol %s: %E\n", + filename, lineno, symname); + } + } + + obstack_free (o, obstack_base (o)); + } + + if (obstack_object_size (o) > 0) + { + einfo ("%s:%d: warning: ignoring unterminated last line\n", + filename, lineno); + obstack_free (o, obstack_base (o)); + } + + if (! keep) + { + obstack_free (o, NULL); + free (o); + } +} + +/* This routine saves us from worrying about declaring free. */ + +static void +gld${EMULATION_NAME}_free (p) + PTR p; +{ + free (p); +} + +/* This is called by the before_allocation routine via + lang_for_each_statement. It looks for relocations and assignments + to symbols. */ + +static void +gld${EMULATION_NAME}_find_relocs (s) + lang_statement_union_type *s; +{ + if (s->header.type == lang_reloc_statement_enum) + { + lang_reloc_statement_type *rs; + + rs = &s->reloc_statement; + if (rs->name == NULL) + einfo ("%F%P: only relocations against symbols are permitted\n"); + if (! bfd_xcoff_link_count_reloc (output_bfd, &link_info, rs->name)) + einfo ("%F%P: bfd_xcoff_link_count_reloc failed: %E\n"); + } + + if (s->header.type == lang_assignment_statement_enum) + gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); +} + +/* Look through an expression for an assignment statement. */ + +static void +gld${EMULATION_NAME}_find_exp_assignment (exp) + etree_type *exp; +{ + struct bfd_link_hash_entry *h; + + switch (exp->type.node_class) + { + case etree_provide: + h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, + false, false, false); + if (h == NULL) + break; + /* Fall through. */ + case etree_assign: + if (strcmp (exp->assign.dst, ".") != 0) + { + if (! bfd_xcoff_record_link_assignment (output_bfd, &link_info, + exp->assign.dst)) + einfo ("%P%F: failed to record assignment to %s: %E\n", + exp->assign.dst); + } + gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src); + break; + + case etree_binary: + gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs); + gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs); + break; + + case etree_trinary: + gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond); + gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs); + gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs); + break; + + case etree_unary: + gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child); + break; + + default: + break; + } +} + +static char * +gld${EMULATION_NAME}_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc="-f ${srcdir}/emultempl/stringify.sed" + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +EOF +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + gld${EMULATION_NAME}_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gld${EMULATION_NAME}_before_allocation, + gld${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}", + 0, /* finish */ + 0, /* create_output_section_statements */ + 0, /* open_dynamic_archive */ + 0, /* place_orphan */ + 0, /* set_symbols */ + gld${EMULATION_NAME}_parse_args, + gld${EMULATION_NAME}_unrecognized_file +}; +EOF diff --git a/ld/emultempl/armcoff.em b/ld/emultempl/armcoff.em new file mode 100644 index 0000000..9955fda --- /dev/null +++ b/ld/emultempl/armcoff.em @@ -0,0 +1,226 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* emulate the original gld for the given ${EMULATION_NAME} + Copyright (C) 1991, 93, 96, 97, 1998 Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_${EMULATION_NAME} + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "getopt.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" + +#include "ldexp.h" +#include "ldlang.h" + +static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); +static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); +static int gld${EMULATION_NAME}_parse_args PARAMS((int, char **)); +static void gld_${EMULATION_NAME}_list_options PARAMS ((FILE *)); + +/* If true, then interworking stubs which support calls to old, non-interworking + aware ARM code should be generated. */ + +static int support_old_code = 0; + +#define OPTION_SUPPORT_OLD_CODE 300 + +static struct option longopts[] = +{ + {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, + {NULL, no_argument, NULL, 0} +}; + +static void +gld${EMULATION_NAME}_list_options (file) + FILE * file; +{ + fprintf (file, _(" --support-old-code Support interworking with old code\n")); +} + +static int +gld${EMULATION_NAME}_parse_args (argc, argv) + int argc; + char ** argv; +{ + int longind; + int optc; + int prevoptind = optind; + int prevopterr = opterr; + int wanterror; + static int lastoptind = -1; + + if (lastoptind != optind) + opterr = 0; + + wanterror = opterr; + lastoptind = optind; + + optc = getopt_long_only (argc, argv, "-", longopts, & longind); + opterr = prevopterr; + + switch (optc) + { + default: + if (wanterror) + xexit (1); + optind = prevoptind; + return 0; + + case OPTION_SUPPORT_OLD_CODE: + support_old_code = 1; + break; + } + + return 1; +} + +static void +gld${EMULATION_NAME}_before_parse () +{ +#ifndef TARGET_ /* I.e., if not generic. */ + ldfile_set_output_arch ("`echo ${ARCH}`"); +#endif /* not TARGET_ */ +} + +/* This is called after the sections have been attached to output + sections, but before any sizes or addresses have been set. */ + +static void +gld${EMULATION_NAME}_before_allocation () +{ + /* we should be able to set the size of the interworking stub section */ + + /* Here we rummage through the found bfds to collect glue information */ + /* FIXME: should this be based on a command line option? krk@cygnus.com */ + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (! bfd_arm_process_before_allocation + (is->the_bfd, & link_info, support_old_code)) + { + /* xgettext:c-format */ + einfo (_("Errors encountered processing file %s"), is->filename); + } + } + } + + /* We have seen it all. Allocate it, and carry on */ + bfd_arm_allocate_interworking_sections (& link_info); +} + +static void +gld${EMULATION_NAME}_after_open () +{ + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info)) + break; + } +} + +static char * +gld${EMULATION_NAME}_get_script (isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc="-f ${srcdir}/emultempl/stringify.sed" + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +EOF +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + gld${EMULATION_NAME}_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gld${EMULATION_NAME}_before_allocation, + gld${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}", + NULL, /* finish */ + NULL, /* create output section statements */ + NULL, /* open dynamic archive */ + NULL, /* place orphan */ + NULL, /* set_symbols */ + gld${EMULATION_NAME}_parse_args, + NULL, /* unrecognised file */ + gld${EMULATION_NAME}_list_options +}; +EOF diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em new file mode 100644 index 0000000..d9409f2 --- /dev/null +++ b/ld/emultempl/armelf.em @@ -0,0 +1,168 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* emulate the original gld for the given ${EMULATION_NAME} + Copyright (C) 1991, 93, 96, 97, 1998 Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_${EMULATION_NAME} + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "getopt.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" + +#include "ldexp.h" +#include "ldlang.h" + +static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); +static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); + +static void +gld${EMULATION_NAME}_before_parse () +{ +#ifndef TARGET_ /* I.e., if not generic. */ + ldfile_set_output_arch ("`echo ${ARCH}`"); +#endif /* not TARGET_ */ +} + +/* This is called after the sections have been attached to output + sections, but before any sizes or addresses have been set. */ + +static void +gld${EMULATION_NAME}_before_allocation () +{ + /* we should be able to set the size of the interworking stub section */ + + /* Here we rummage through the found bfds to collect glue information */ + /* FIXME: should this be based on a command line option? krk@cygnus.com */ + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (!bfd_elf32_arm_process_before_allocation (is->the_bfd, &link_info)) + { + /* xgettext:c-format */ + einfo (_("Errors encountered processing file %s"), is->filename); + } + } + } + + /* We have seen it all. Allocate it, and carry on */ + bfd_elf32_arm_allocate_interworking_sections (& link_info); +} + +static void +gld${EMULATION_NAME}_after_open () +{ + + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + /* The interworking bfd must be the last one to be processed */ + if (!is->next) + bfd_elf32_arm_get_bfd_for_interworking (is->the_bfd, & link_info); + } +} + +static char * +gld${EMULATION_NAME}_get_script (isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc="-f ${srcdir}/emultempl/stringify.sed" + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +EOF +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + gld${EMULATION_NAME}_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gld${EMULATION_NAME}_before_allocation, + gld${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}", + NULL, /* finish */ + NULL, /* create output section statements */ + NULL, /* open dynamic archive */ + NULL, /* place orphan */ + NULL, /* set_symbols */ + NULL, + NULL, /* unrecognised file */ + NULL +}; +EOF diff --git a/ld/emultempl/armelf_oabi.em b/ld/emultempl/armelf_oabi.em new file mode 100644 index 0000000..c0526e5 --- /dev/null +++ b/ld/emultempl/armelf_oabi.em @@ -0,0 +1,175 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* emulate the original gld for the given ${EMULATION_NAME} + Copyright (C) 1991, 93, 96, 97, 98, 1999 Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_${EMULATION_NAME} + +#define bfd_elf32_arm_allocate_interworking_sections \ + bfd_elf32_arm_oabi_allocate_interworking_sections +#define bfd_elf32_arm_get_bfd_for_interworking \ + bfd_elf32_arm_oabi_get_bfd_for_interworking +#define bfd_elf32_arm_process_before_allocation \ + bfd_elf32_arm_oabi_process_before_allocation + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "getopt.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" + +#include "ldexp.h" +#include "ldlang.h" + +static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); +static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); + +static void +gld${EMULATION_NAME}_before_parse () +{ +#ifndef TARGET_ /* I.e., if not generic. */ + ldfile_set_output_arch ("`echo ${ARCH}`"); +#endif /* not TARGET_ */ +} + +/* This is called after the sections have been attached to output + sections, but before any sizes or addresses have been set. */ + +static void +gld${EMULATION_NAME}_before_allocation () +{ + /* we should be able to set the size of the interworking stub section */ + + /* Here we rummage through the found bfds to collect glue information */ + /* FIXME: should this be based on a command line option? krk@cygnus.com */ + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (!bfd_elf32_arm_process_before_allocation (is->the_bfd, &link_info)) + { + /* xgettext:c-format */ + einfo (_("Errors encountered processing file %s"), is->filename); + } + } + } + + /* We have seen it all. Allocate it, and carry on */ + bfd_elf32_arm_allocate_interworking_sections (& link_info); +} + +static void +gld${EMULATION_NAME}_after_open () +{ + + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + /* The interworking bfd must be the last one to be processed */ + if (!is->next) + bfd_elf32_arm_get_bfd_for_interworking (is->the_bfd, & link_info); + } +} + +static char * +gld${EMULATION_NAME}_get_script (isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc="-f ${srcdir}/emultempl/stringify.sed" + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +EOF +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + gld${EMULATION_NAME}_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gld${EMULATION_NAME}_before_allocation, + gld${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}", + NULL, /* finish */ + NULL, /* create output section statements */ + NULL, /* open dynamic archive */ + NULL, /* place orphan */ + NULL, /* set_symbols */ + NULL, + NULL, /* unrecognised file */ + NULL +}; +EOF diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em new file mode 100644 index 0000000..c2b3ec2 --- /dev/null +++ b/ld/emultempl/beos.em @@ -0,0 +1,837 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is part of GLD, the Gnu Linker. + Copyright 1995, 96, 97, 1998 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* For WINDOWS_NT */ +/* The original file generated returned different default scripts depending + on whether certain switches were set, but these switches pertain to the + Linux system and that particular version of coff. In the NT case, we + only determine if the subsystem is console or windows in order to select + the correct entry point by default. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "getopt.h" +#include "libiberty.h" +#include "ld.h" +#include "ldmain.h" +#include "ldgram.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldemul.h" +#include "ldlex.h" +#include "ldmisc.h" +#include "ldctor.h" +#include "ldfile.h" +#include "coff/internal.h" +#include "../bfd/libcoff.h" + +#define TARGET_IS_${EMULATION_NAME} + +static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void)); +static void gld_${EMULATION_NAME}_after_open PARAMS ((void)); +static void gld_${EMULATION_NAME}_before_parse PARAMS ((void)); +static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void)); +static boolean gld${EMULATION_NAME}_place_orphan + PARAMS ((lang_input_statement_type *, asection *)); +static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *)); +static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **)); + +#if 0 /* argument to qsort so don't prototype */ +static int sort_by_file_name PARAMS ((void *, void *)); +static int sort_by_section_name PARAMS ((void *, void *)); +#endif +static lang_statement_union_type **sort_sections_1 + PARAMS ((lang_statement_union_type **, lang_statement_union_type *, int, + int (*)())); +static void sort_sections PARAMS ((lang_statement_union_type *)); + +static struct internal_extra_pe_aouthdr pe; +static int dll; + +extern const char *output_filename; + +static void +gld_${EMULATION_NAME}_before_parse() +{ + output_filename = "a.exe"; + ldfile_output_architecture = bfd_arch_${ARCH}; +} + +/* PE format extra command line options. */ + +/* Used for setting flags in the PE header. */ +#define OPTION_BASE_FILE (300 + 1) +#define OPTION_DLL (OPTION_BASE_FILE + 1) +#define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1) +#define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1) +#define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1) +#define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1) +#define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1) +#define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1) +#define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1) +#define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1) +#define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1) +#define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1) +#define OPTION_SUBSYSTEM (OPTION_STACK + 1) +#define OPTION_HEAP (OPTION_SUBSYSTEM + 1) + +static struct option longopts[] = { + /* PE options */ + {"base-file", required_argument, NULL, OPTION_BASE_FILE}, + {"dll", no_argument, NULL, OPTION_DLL}, + {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT}, + {"heap", required_argument, NULL, OPTION_HEAP}, + {"image-base", required_argument, NULL, OPTION_IMAGE_BASE}, + {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION}, + {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION}, + {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION}, + {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION}, + {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION}, + {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION}, + {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT}, + {"stack", required_argument, NULL, OPTION_STACK}, + {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM}, + {NULL, no_argument, NULL, 0} + }; + + +/* PE/WIN32; added routines to get the subsystem type, heap and/or stack + parameters which may be input from the command line */ + +typedef struct { + void *ptr; + int size; + int value; + char *symbol; + int inited; +} definfo; + +#define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0} + +static definfo init[] = +{ + /* imagebase must be first */ +#define IMAGEBASEOFF 0 + D(ImageBase,"__image_base__", BEOS_EXE_IMAGE_BASE), +#define DLLOFF 1 + {&dll, sizeof(dll), 0, "__dll__"}, + D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT), + D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT), + D(MajorOperatingSystemVersion,"__major_os_version__", 4), + D(MinorOperatingSystemVersion,"__minor_os_version__", 0), + D(MajorImageVersion,"__major_image_version__", 1), + D(MinorImageVersion,"__minor_image_version__", 0), + D(MajorSubsystemVersion,"__major_subsystem_version__", 4), + D(MinorSubsystemVersion,"__minor_subsystem_version__", 0), + D(Subsystem,"__subsystem__", 3), + D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000), + D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000), + D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000), + D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000), + D(LoaderFlags,"__loader_flags__", 0x0), + { NULL, 0, 0, NULL, 0 } +}; + + +static void +set_pe_name (name, val) + char *name; + long val; +{ + int i; + /* Find the name and set it. */ + for (i = 0; init[i].ptr; i++) + { + if (strcmp (name, init[i].symbol) == 0) + { + init[i].value = val; + init[i].inited = 1; + return; + } + } + abort(); +} + + +static void +set_pe_subsystem () +{ + const char *sver; + int len; + int i; + static const struct + { + const char *name; + const int value; + const char *entry; + } + v[] = + { + { "native", 1, "_NtProcessStartup" }, + { "windows", 2, "_WinMainCRTStartup" }, + { "wwindows", 2, "_wWinMainCRTStartup" }, + { "console", 3, "_mainCRTStartup" }, + { "wconsole", 3, "_wmainCRTStartup" }, +#if 0 + /* The Microsoft linker does not recognize this. */ + { "os2", 5, "" }, +#endif + { "posix", 7, "___PosixProcessStartup"}, + { 0, 0, 0 } + }; + + sver = strchr (optarg, ':'); + if (sver == NULL) + len = strlen (optarg); + else + { + char *end; + + len = sver - optarg; + set_pe_name ("__major_subsystem_version__", + strtoul (sver + 1, &end, 0)); + if (*end == '.') + set_pe_name ("__minor_subsystem_version__", + strtoul (end + 1, &end, 0)); + if (*end != '\0') + einfo ("%P: warning: bad version number in -subsystem option\n"); + } + + for (i = 0; v[i].name; i++) + { + if (strncmp (optarg, v[i].name, len) == 0 + && v[i].name[len] == '\0') + { + set_pe_name ("__subsystem__", v[i].value); + + /* If the subsystem is windows, we use a different entry + point. We also register the entry point as an undefined + symbol. from lang_add_entry() The reason we do + this is so that the user + doesn't have to because they would have to use the -u + switch if they were specifying an entry point other than + _mainCRTStartup. Specifically, if creating a windows + application, entry point _WinMainCRTStartup must be + specified. What I have found for non console + applications (entry not _mainCRTStartup) is that the .obj + that contains mainCRTStartup is brought in since it is + the first encountered in libc.lib and it has other + symbols in it which will be pulled in by the link + process. To avoid this, adding -u with the entry point + name specified forces the correct .obj to be used. We + can avoid making the user do this by always adding the + entry point name as an undefined symbol. */ + lang_add_entry (v[i].entry, 1); + + return; + } + } + einfo ("%P%F: invalid subsystem type %s\n", optarg); +} + + + +static void +set_pe_value (name) + char *name; + +{ + char *end; + set_pe_name (name, strtoul (optarg, &end, 0)); + if (end == optarg) + { + einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg); + } + + optarg = end; +} + +static void +set_pe_stack_heap (resname, comname) + char *resname; + char *comname; +{ + set_pe_value (resname); + if (*optarg == ',') + { + optarg++; + set_pe_value (comname); + } + else if (*optarg) + { + einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg); + } +} + + + +static int +gld_${EMULATION_NAME}_parse_args(argc, argv) + int argc; + char **argv; +{ + int longind; + int optc; + int prevoptind = optind; + int prevopterr = opterr; + int wanterror; + static int lastoptind = -1; + + if (lastoptind != optind) + opterr = 0; + wanterror = opterr; + + lastoptind = optind; + + optc = getopt_long_only (argc, argv, "-", longopts, &longind); + opterr = prevopterr; + + switch (optc) + { + default: + if (wanterror) + xexit (1); + optind = prevoptind; + return 0; + + case OPTION_BASE_FILE: + link_info.base_file = (PTR) fopen (optarg, FOPEN_WB); + if (link_info.base_file == NULL) + { + fprintf (stderr, "%s: Can't open base file %s\n", + program_name, optarg); + xexit (1); + } + break; + + /* PE options */ + case OPTION_HEAP: + set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__"); + break; + case OPTION_STACK: + set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__"); + break; + case OPTION_SUBSYSTEM: + set_pe_subsystem (); + break; + case OPTION_MAJOR_OS_VERSION: + set_pe_value ("__major_os_version__"); + break; + case OPTION_MINOR_OS_VERSION: + set_pe_value ("__minor_os_version__"); + break; + case OPTION_MAJOR_SUBSYSTEM_VERSION: + set_pe_value ("__major_subsystem_version__"); + break; + case OPTION_MINOR_SUBSYSTEM_VERSION: + set_pe_value ("__minor_subsystem_version__"); + break; + case OPTION_MAJOR_IMAGE_VERSION: + set_pe_value ("__major_image_version__"); + break; + case OPTION_MINOR_IMAGE_VERSION: + set_pe_value ("__minor_image_version__"); + break; + case OPTION_FILE_ALIGNMENT: + set_pe_value ("__file_alignment__"); + break; + case OPTION_SECTION_ALIGNMENT: + set_pe_value ("__section_alignment__"); + break; + case OPTION_DLL: + set_pe_name ("__dll__", 1); + break; + case OPTION_IMAGE_BASE: + set_pe_value ("__image_base__"); + break; + } + return 1; +} + +/* Assign values to the special symbols before the linker script is + read. */ + +static void +gld_${EMULATION_NAME}_set_symbols() +{ + /* Run through and invent symbols for all the + names and insert the defaults. */ + int j; + lang_statement_list_type *save; + + if (!init[IMAGEBASEOFF].inited) + { + if (link_info.relocateable) + init[IMAGEBASEOFF].value = 0; + else if (init[DLLOFF].value) + init[IMAGEBASEOFF].value = BEOS_DLL_IMAGE_BASE; + else + init[IMAGEBASEOFF].value = BEOS_EXE_IMAGE_BASE; + } + + /* Don't do any symbol assignments if this is a relocateable link. */ + if (link_info.relocateable) + return; + + /* Glue the assignments into the abs section */ + save = stat_ptr; + + stat_ptr = &(abs_output_section->children); + + for (j = 0; init[j].ptr; j++) + { + long val = init[j].value; + lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val))); + if (init[j].size == sizeof(short)) + *(short *)init[j].ptr = val; + else if (init[j].size == sizeof(int)) + *(int *)init[j].ptr = val; + else if (init[j].size == sizeof(long)) + *(long *)init[j].ptr = val; + /* This might be a long long or other special type. */ + else if (init[j].size == sizeof(bfd_vma)) + *(bfd_vma *)init[j].ptr = val; + else abort(); + } + /* Restore the pointer. */ + stat_ptr = save; + + if (pe.FileAlignment > + pe.SectionAlignment) + { + einfo ("%P: warning, file alignment > section alignment.\n"); + } +} + +static void +gld_${EMULATION_NAME}_after_open() +{ + /* Pass the wacky PE command line options into the output bfd. + FIXME: This should be done via a function, rather than by + including an internal BFD header. */ + if (!coff_data(output_bfd)->pe) + { + einfo ("%F%P: PE operations on non PE file.\n"); + } + + pe_data(output_bfd)->pe_opthdr = pe; + pe_data(output_bfd)->dll = init[DLLOFF].value; + +} + +/* Callback functions for qsort in sort_sections. */ + +static int +sort_by_file_name (a, b) + void *a; + void *b; +{ + lang_statement_union_type **ra = a; + lang_statement_union_type **rb = b; + int i, a_sec, b_sec; + + i = strcmp ((*ra)->input_section.ifile->the_bfd->my_archive->filename, + (*rb)->input_section.ifile->the_bfd->my_archive->filename); + if (i != 0) + return i; + + i = strcmp ((*ra)->input_section.ifile->filename, + (*rb)->input_section.ifile->filename); + if (i != 0) + return i; + /* the tail idata4/5 are the only ones without relocs to an + idata$6 section unless we are importing by ordinal, + so sort them to last to terminate the IAT + and HNT properly. if no reloc this one is import by ordinal + so we have to sort by section contents */ + + if ( ((*ra)->input_section.section->reloc_count + (*rb)->input_section.section->reloc_count) ) + { + i = (((*ra)->input_section.section->reloc_count > + (*rb)->input_section.section->reloc_count) ? -1 : 0); + if ( i != 0) + return i; + + return (((*ra)->input_section.section->reloc_count > + (*rb)->input_section.section->reloc_count) ? 0 : 1); + } + else + { + if ( (strcmp( (*ra)->input_section.section->name, ".idata$6") == 0) ) + return 0; /* don't sort .idata$6 or .idata$7 FIXME dlltool eliminate .idata$7 */ + + if (! bfd_get_section_contents ((*ra)->input_section.ifile->the_bfd, + (*ra)->input_section.section, &a_sec, (file_ptr) 0, (bfd_size_type)sizeof(a_sec))) + einfo ("%F%B: Can't read contents of section .idata: %E\n", + (*ra)->input_section.ifile->the_bfd); + + if (! bfd_get_section_contents ((*rb)->input_section.ifile->the_bfd, + (*rb)->input_section.section, &b_sec, (file_ptr) 0, (bfd_size_type)sizeof(b_sec) )) + einfo ("%F%B: Can't read contents of section .idata: %E\n", + (*rb)->input_section.ifile->the_bfd); + + i = ((a_sec < b_sec) ? -1 : 0); + if ( i != 0) + return i; + return ((a_sec < b_sec) ? 0 : 1); + } +return 0; +} + +static int +sort_by_section_name (a, b) + void *a; + void *b; +{ + lang_statement_union_type **ra = a; + lang_statement_union_type **rb = b; + int i; + i = strcmp ((*ra)->input_section.section->name, + (*rb)->input_section.section->name); +/* this is a hack to make .stab and .stabstr last, so we don't have + to fix strip/objcopy for .reloc sections. + FIXME stripping images with a .rsrc section still needs to be fixed */ + if ( i != 0) + { + if ((strncmp ((*ra)->input_section.section->name, ".stab", 5) == 0) + && (strncmp ((*rb)->input_section.section->name, ".stab", 5) != 0)) + return 1; + return i; + } + return i; +} + +/* Subroutine of sort_sections to a contiguous subset of a list of sections. + NEXT_AFTER is the element after the last one to sort. + The result is a pointer to the last element's "next" pointer. */ + +static lang_statement_union_type ** +sort_sections_1 (startptr, next_after, count, sort_func) + lang_statement_union_type **startptr,*next_after; + int count; + int (*sort_func) (); +{ + lang_statement_union_type **vec; + lang_statement_union_type *p; + int i; + lang_statement_union_type **ret; + + if (count == 0) + return startptr; + + vec = ((lang_statement_union_type **) + xmalloc (count * sizeof (lang_statement_union_type *))); + + for (p = *startptr, i = 0; i < count; i++, p = p->next) + vec[i] = p; + + qsort (vec, count, sizeof (vec[0]), sort_func); + + /* Fill in the next pointers again. */ + *startptr = vec[0]; + for (i = 0; i < count - 1; i++) + vec[i]->header.next = vec[i + 1]; + vec[i]->header.next = next_after; + ret = &vec[i]->header.next; + free (vec); + return ret; +} + +/* Sort the .idata\$foo input sections of archives into filename order. + The reason is so dlltool can arrange to have the pe dll import information + generated correctly - the head of the list goes into dh.o, the tail into + dt.o, and the guts into ds[nnnn].o. Note that this is only needed for the + .idata section. + FIXME: This may no longer be necessary with grouped sections. Instead of + sorting on dh.o, ds[nnnn].o, dt.o, one could, for example, have dh.o use + .idata\$4h, have ds[nnnn].o use .idata\$4s[nnnn], and have dt.o use .idata\$4t. + This would have to be elaborated upon to handle multiple dll's + [assuming such an eloboration is possible of course]. + + We also sort sections in '\$' wild statements. These are created by the + place_orphans routine to implement grouped sections. */ + +static void +sort_sections (s) + lang_statement_union_type *s; +{ + for (; s ; s = s->next) + switch (s->header.type) + { + case lang_output_section_statement_enum: + sort_sections (s->output_section_statement.children.head); + break; + case lang_wild_statement_enum: + { + lang_statement_union_type **p = &s->wild_statement.children.head; + + /* Is this the .idata section? */ + if (s->wild_statement.section_name != NULL + && strncmp (s->wild_statement.section_name, ".idata", 6) == 0) + { + /* Sort the children. We want to sort any objects in + the same archive. In order to handle the case of + including a single archive multiple times, we sort + all the children by archive name and then by object + name. After sorting them, we re-thread the pointer + chain. */ + + while (*p) + { + lang_statement_union_type *start = *p; + if (start->header.type != lang_input_section_enum + || !start->input_section.ifile->the_bfd->my_archive) + p = &(start->header.next); + else + { + lang_statement_union_type *end; + int count; + + for (end = start, count = 0; + end && end->header.type == lang_input_section_enum; + end = end->next) + count++; + + p = sort_sections_1 (p, end, count, sort_by_file_name); + } + } + break; + } + + /* If this is a collection of grouped sections, sort them. + The linker script must explicitly mention "*(.foo\$)" or + "*(.foo\$*)". Don't sort them if \$ is not the last + character (not sure if this is really useful, but it + allows explicitly mentioning some \$ sections and letting + the linker handle the rest). */ + if (s->wild_statement.section_name != NULL) + { + char *q = strchr (s->wild_statement.section_name, '\$'); + + if (q != NULL + && (q[1] == '\0' + || (q[1] == '*' && q[2] == '\0'))) + { + lang_statement_union_type *end; + int count; + + for (end = *p, count = 0; end; end = end->next) + { + if (end->header.type != lang_input_section_enum) + abort (); + count++; + } + (void) sort_sections_1 (p, end, count, sort_by_section_name); + } + break; + } + } + break; + default: + break; + } +} + +static void +gld_${EMULATION_NAME}_before_allocation() +{ + extern lang_statement_list_type *stat_ptr; + +#ifdef TARGET_IS_ppcpe + /* Here we rummage through the found bfds to collect toc information */ + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (!ppc_process_before_allocation(is->the_bfd, &link_info)) + { + einfo("Errors encountered processing file %s\n", is->filename); + } + } + } + + /* We have seen it all. Allocate it, and carry on */ + ppc_allocate_toc_section (&link_info); +#else +#ifdef TARGET_IS_armpe + /* FIXME: we should be able to set the size of the interworking stub + section. + + Here we rummage through the found bfds to collect glue + information. FIXME: should this be based on a command line + option? krk@cygnus.com */ + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (!arm_process_before_allocation (is->the_bfd, & link_info)) + { + einfo ("Errors encountered processing file %s", is->filename); + } + } + } + + /* We have seen it all. Allocate it, and carry on */ + arm_allocate_interworking_sections (& link_info); +#endif /* TARGET_IS_armpe */ +#endif /* TARGET_IS_ppcpe */ + + sort_sections (stat_ptr->head); +} + +/* Place an orphan section. We use this to put sections with a '\$' in them + into the right place. Any section with a '\$' in them (e.g. .text\$foo) + gets mapped to the output section with everything from the '\$' on stripped + (e.g. .text). + See the Microsoft Portable Executable and Common Object File Format + Specification 4.1, section 4.2, Grouped Sections. + + FIXME: This is now handled by the linker script using wildcards, + but I'm leaving this here in case we want to enable it for sections + which are not mentioned in the linker script. */ + +/*ARGSUSED*/ +static boolean +gld${EMULATION_NAME}_place_orphan (file, s) + lang_input_statement_type *file; + asection *s; +{ + const char *secname; + char *output_secname, *ps; + lang_output_section_statement_type *os; + lang_statement_union_type *l; + + if ((s->flags & SEC_ALLOC) == 0) + return false; + + /* Don't process grouped sections unless doing a final link. + If they're marked as COMDAT sections, we don't want .text\$foo to + end up in .text and then have .text disappear because it's marked + link-once-discard. */ + if (link_info.relocateable) + return false; + + secname = bfd_get_section_name (s->owner, s); + + /* Everything from the '\$' on gets deleted so don't allow '\$' as the + first character. */ + if (*secname == '\$') + einfo ("%P%F: section %s has '\$' as first character\n", secname); + if (strchr (secname + 1, '\$') == NULL) + return false; + + /* Look up the output section. The Microsoft specs say sections names in + image files never contain a '\$'. Fortunately, lang_..._lookup creates + the section if it doesn't exist. */ + output_secname = buystring (secname); + ps = strchr (output_secname + 1, '\$'); + *ps = 0; + os = lang_output_section_statement_lookup (output_secname); + + /* Find the '\$' wild statement for this section. We currently require the + linker script to explicitly mention "*(.foo\$)". + FIXME: ppcpe.sc has .CRT\$foo in the .rdata section. According to the + Microsoft docs this isn't correct so it's not (currently) handled. */ + + ps[0] = '\$'; + ps[1] = 0; + for (l = os->children.head; l; l = l->next) + { + if (l->header.type == lang_wild_statement_enum + && strcmp (l->wild_statement.section_name, output_secname) == 0) + break; + } + ps[0] = 0; + if (l == NULL) +#if 1 + einfo ("%P%F: *(%s\$) missing from linker script\n", output_secname); +#else /* FIXME: This block is untried. It exists to convey the intent, + should one decide to not require *(.foo\$) to appear in the linker + script. */ + { + lang_wild_statement_type *new = new_stat (lang_wild_statement, + &os->children); + new->section_name = xmalloc (strlen (output_secname) + 2); + sprintf (new->section_name, "%s\$", output_secname); + new->filename = NULL; + lang_list_init (&new->children); + l = new; + } +#endif + + /* Link the input section in and we're done for now. + The sections still have to be sorted, but that has to wait until + all such sections have been processed by us. The sorting is done by + sort_sections. */ + wild_doit (&l->wild_statement.children, s, os, file); + + return true; +} + +static char * +gld_${EMULATION_NAME}_get_script(isfile) + int *isfile; +EOF +# Scripts compiled in. +# sed commands to quote an ld script as a C string. +sc="-f ${srcdir}/emultempl/stringify.sed" + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +EOF +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c + +cat >>e${EMULATION_NAME}.c <<EOF + + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld_${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + gld_${EMULATION_NAME}_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gld_${EMULATION_NAME}_before_allocation, + gld_${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}", + NULL, /* finish */ + NULL, /* create output section statements */ + NULL, /* open dynamic archive */ + gld${EMULATION_NAME}_place_orphan, + gld_${EMULATION_NAME}_set_symbols, + gld_${EMULATION_NAME}_parse_args +}; +EOF diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em new file mode 100644 index 0000000..0358676 --- /dev/null +++ b/ld/emultempl/elf32.em @@ -0,0 +1,1143 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +# This file is now misnamed, because it supports both 32 bit and 64 bit +# ELF emulations. +test -z "${ELFSIZE}" && ELFSIZE=32 +cat >e${EMULATION_NAME}.c <<EOF +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME} + Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + Written by Steve Chamberlain <sac@cygnus.com> + ELF support by Ian Lance Taylor <ian@cygnus.com> + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_${EMULATION_NAME} + +#include "bfd.h" +#include "sysdep.h" + +#include <ctype.h> + +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldgram.h" + +static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static boolean gld${EMULATION_NAME}_open_dynamic_archive + PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); +static void gld${EMULATION_NAME}_after_open PARAMS ((void)); +static void gld${EMULATION_NAME}_check_needed + PARAMS ((lang_input_statement_type *)); +static void gld${EMULATION_NAME}_stat_needed + PARAMS ((lang_input_statement_type *)); +static boolean gld${EMULATION_NAME}_search_needed + PARAMS ((const char *, const char *, int)); +static boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *, int)); +static void gld${EMULATION_NAME}_vercheck + PARAMS ((lang_input_statement_type *)); +static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); +static void gld${EMULATION_NAME}_find_statement_assignment + PARAMS ((lang_statement_union_type *)); +static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *)); +static boolean gld${EMULATION_NAME}_place_orphan + PARAMS ((lang_input_statement_type *, asection *)); +static void gld${EMULATION_NAME}_place_section + PARAMS ((lang_statement_union_type *)); +static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); + +static void +gld${EMULATION_NAME}_before_parse() +{ + ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`; + config.dynamic_link = ${DYNAMIC_LINK-true}; + config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`; +} + +/* Try to open a dynamic archive. This is where we know that ELF + dynamic libraries have an extension of .so. */ + +static boolean +gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) + const char *arch; + search_dirs_type *search; + lang_input_statement_type *entry; +{ + const char *filename; + char *string; + + if (! entry->is_archive) + return false; + + filename = entry->filename; + + string = (char *) xmalloc (strlen (search->name) + + strlen (filename) + + strlen (arch) + + sizeof "/lib.so"); + + sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); + + if (! ldfile_try_open_bfd (string, entry)) + { + free (string); + return false; + } + + entry->filename = string; + + /* We have found a dynamic object to include in the link. The ELF + backend linker will create a DT_NEEDED entry in the .dynamic + section naming this file. If this file includes a DT_SONAME + entry, it will be used. Otherwise, the ELF linker will just use + the name of the file. For an archive found by searching, like + this one, the DT_NEEDED entry should consist of just the name of + the file, without the path information used to find it. Note + that we only need to do this if we have a dynamic object; an + archive will never be referenced by a DT_NEEDED entry. + + FIXME: This approach--using bfd_elf_set_dt_needed_name--is not + very pretty. I haven't been able to think of anything that is + pretty, though. */ + if (bfd_check_format (entry->the_bfd, bfd_object) + && (entry->the_bfd->flags & DYNAMIC) != 0) + { + char *needed_name; + + ASSERT (entry->is_archive && entry->search_dirs_flag); + needed_name = (char *) xmalloc (strlen (filename) + + strlen (arch) + + sizeof "lib.so"); + sprintf (needed_name, "lib%s%s.so", filename, arch); + bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name); + } + + return true; +} + +EOF +if [ "x${host}" = "x${target}" ] ; then + if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then +cat >>e${EMULATION_NAME}.c <<EOF + +/* For a native linker, check the file /etc/ld.so.conf for directories + in which we may find shared libraries. /etc/ld.so.conf is really + only meaningful on Linux, but we check it on other systems anyhow. */ + +static boolean gld${EMULATION_NAME}_check_ld_so_conf + PARAMS ((const char *, int)); + +static boolean +gld${EMULATION_NAME}_check_ld_so_conf (name, force) + const char *name; + int force; +{ + static boolean initialized; + static char *ld_so_conf; + + if (! initialized) + { + FILE *f; + + f = fopen ("/etc/ld.so.conf", FOPEN_RT); + if (f != NULL) + { + char *b; + size_t len, alloc; + int c; + + len = 0; + alloc = 100; + b = (char *) xmalloc (alloc); + + while ((c = getc (f)) != EOF) + { + if (len + 1 >= alloc) + { + alloc *= 2; + b = (char *) xrealloc (b, alloc); + } + if (c != ':' + && c != ' ' + && c != '\t' + && c != '\n' + && c != ',') + { + b[len] = c; + ++len; + } + else + { + if (len > 0 && b[len - 1] != ':') + { + b[len] = ':'; + ++len; + } + } + } + + if (len > 0 && b[len - 1] == ':') + --len; + + if (len > 0) + b[len] = '\0'; + else + { + free (b); + b = NULL; + } + + fclose (f); + + ld_so_conf = b; + } + + initialized = true; + } + + if (ld_so_conf == NULL) + return false; + + return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force); +} + +EOF + fi +fi +cat >>e${EMULATION_NAME}.c <<EOF + +/* These variables are required to pass information back and forth + between after_open and check_needed and stat_needed and vercheck. */ + +static struct bfd_link_needed_list *global_needed; +static struct stat global_stat; +static boolean global_found; +static struct bfd_link_needed_list *global_vercheck_needed; +static boolean global_vercheck_failed; + +/* This is called after all the input files have been opened. */ + +static void +gld${EMULATION_NAME}_after_open () +{ + struct bfd_link_needed_list *needed, *l; + + /* We only need to worry about this when doing a final link. */ + if (link_info.relocateable || link_info.shared) + return; + + /* Get the list of files which appear in DT_NEEDED entries in + dynamic objects included in the link (often there will be none). + For each such file, we want to track down the corresponding + library, and include the symbol table in the link. This is what + the runtime dynamic linker will do. Tracking the files down here + permits one dynamic object to include another without requiring + special action by the person doing the link. Note that the + needed list can actually grow while we are stepping through this + loop. */ + needed = bfd_elf_get_needed_list (output_bfd, &link_info); + for (l = needed; l != NULL; l = l->next) + { + struct bfd_link_needed_list *ll; + int force; + + /* If we've already seen this file, skip it. */ + for (ll = needed; ll != l; ll = ll->next) + if (strcmp (ll->name, l->name) == 0) + break; + if (ll != l) + continue; + + /* See if this file was included in the link explicitly. */ + global_needed = l; + global_found = false; + lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); + if (global_found) + continue; + + /* We need to find this file and include the symbol table. We + want to search for the file in the same way that the dynamic + linker will search. That means that we want to use + rpath_link, rpath, then the environment variable + LD_LIBRARY_PATH (native only), then the linker script + LIB_SEARCH_DIRS. We do not search using the -L arguments. + + We search twice. The first time, we skip objects which may + introduce version mismatches. The second time, we force + their use. See gld${EMULATION_NAME}_vercheck comment. */ + for (force = 0; force < 2; force++) + { + const char *lib_path; + size_t len; + search_dirs_type *search; + + if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link, + l->name, force)) + break; + if (gld${EMULATION_NAME}_search_needed (command_line.rpath, + l->name, force)) + break; + if (command_line.rpath_link == NULL + && command_line.rpath == NULL) + { + lib_path = (const char *) getenv ("LD_RUN_PATH"); + if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, + force)) + break; + } +EOF +if [ "x${host}" = "x${target}" ] ; then + if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then +cat >>e${EMULATION_NAME}.c <<EOF + lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); + if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force)) + break; +EOF + fi +fi +cat >>e${EMULATION_NAME}.c <<EOF + len = strlen (l->name); + for (search = search_head; search != NULL; search = search->next) + { + char *filename; + + if (search->cmdline) + continue; + filename = (char *) xmalloc (strlen (search->name) + len + 2); + sprintf (filename, "%s/%s", search->name, l->name); + if (gld${EMULATION_NAME}_try_needed (filename, force)) + break; + free (filename); + } + if (search != NULL) + break; +EOF +if [ "x${host}" = "x${target}" ] ; then + if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then +cat >>e${EMULATION_NAME}.c <<EOF + if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force)) + break; +EOF + fi +fi +cat >>e${EMULATION_NAME}.c <<EOF + } + + if (force < 2) + continue; + + einfo ("%P: warning: %s, needed by %B, not found (try using --rpath)\n", + l->name, l->by); + } +} + +/* Search for a needed file in a path. */ + +static boolean +gld${EMULATION_NAME}_search_needed (path, name, force) + const char *path; + const char *name; + int force; +{ + const char *s; + size_t len; + + if (path == NULL || *path == '\0') + return false; + len = strlen (name); + while (1) + { + char *filename, *sset; + + s = strchr (path, ':'); + if (s == NULL) + s = path + strlen (path); + + filename = (char *) xmalloc (s - path + len + 2); + if (s == path) + sset = filename; + else + { + memcpy (filename, path, s - path); + filename[s - path] = '/'; + sset = filename + (s - path) + 1; + } + strcpy (sset, name); + + if (gld${EMULATION_NAME}_try_needed (filename, force)) + return true; + + free (filename); + + if (*s == '\0') + break; + path = s + 1; + } + + return false; +} + +/* This function is called for each possible name for a dynamic object + named by a DT_NEEDED entry. The FORCE parameter indicates whether + to skip the check for a conflicting version. */ + +static boolean +gld${EMULATION_NAME}_try_needed (name, force) + const char *name; + int force; +{ + bfd *abfd; + + abfd = bfd_openr (name, bfd_get_target (output_bfd)); + if (abfd == NULL) + return false; + if (! bfd_check_format (abfd, bfd_object)) + { + (void) bfd_close (abfd); + return false; + } + if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) + { + (void) bfd_close (abfd); + return false; + } + + /* Check whether this object would include any conflicting library + versions. If FORCE is set, then we skip this check; we use this + the second time around, if we couldn't find any compatible + instance of the shared library. */ + + if (! force) + { + struct bfd_link_needed_list *needed; + + if (! bfd_elf_get_bfd_needed_list (abfd, &needed)) + einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd); + + if (needed != NULL) + { + global_vercheck_needed = needed; + global_vercheck_failed = false; + lang_for_each_input_file (gld${EMULATION_NAME}_vercheck); + if (global_vercheck_failed) + { + (void) bfd_close (abfd); + /* Return false to force the caller to move on to try + another file on the search path. */ + return false; + } + + /* But wait! It gets much worse. On Linux, if a shared + library does not use libc at all, we are supposed to skip + it the first time around in case we encounter a shared + library later on with the same name which does use the + version of libc that we want. This is much too horrible + to use on any system other than Linux. */ + +EOF +case ${target} in + *-*-linux-gnu*) + cat >>e${EMULATION_NAME}.c <<EOF + { + struct bfd_link_needed_list *l; + + for (l = needed; l != NULL; l = l->next) + if (strncmp (l->name, "libc.so", 7) == 0) + break; + if (l == NULL) + { + (void) bfd_close (abfd); + return false; + } + } + +EOF + ;; +esac +cat >>e${EMULATION_NAME}.c <<EOF + } + } + + /* We've found a dynamic object matching the DT_NEEDED entry. */ + + /* We have already checked that there is no other input file of the + same name. We must now check again that we are not including the + same file twice. We need to do this because on many systems + libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will + reference libc.so.1. If we have already included libc.so, we + don't want to include libc.so.1 if they are the same file, and we + can only check that using stat. */ + + if (bfd_stat (abfd, &global_stat) != 0) + einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd); + global_found = false; + lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed); + if (global_found) + { + /* Return true to indicate that we found the file, even though + we aren't going to do anything with it. */ + return true; + } + + /* Tell the ELF backend that don't want the output file to have a + DT_NEEDED entry for this file. */ + bfd_elf_set_dt_needed_name (abfd, ""); + + /* Add this file into the symbol table. */ + if (! bfd_link_add_symbols (abfd, &link_info)) + einfo ("%F%B: could not read symbols: %E\n", abfd); + + return true; +} + +/* See if an input file matches a DT_NEEDED entry by name. */ + +static void +gld${EMULATION_NAME}_check_needed (s) + lang_input_statement_type *s; +{ + if (global_found) + return; + + if (s->filename != NULL + && strcmp (s->filename, global_needed->name) == 0) + { + global_found = true; + return; + } + + if (s->the_bfd != NULL) + { + const char *soname; + + soname = bfd_elf_get_dt_soname (s->the_bfd); + if (soname != NULL + && strcmp (soname, global_needed->name) == 0) + { + global_found = true; + return; + } + } + + if (s->search_dirs_flag + && s->filename != NULL + && strchr (global_needed->name, '/') == NULL) + { + const char *f; + + f = strrchr (s->filename, '/'); + if (f != NULL + && strcmp (f + 1, global_needed->name) == 0) + { + global_found = true; + return; + } + } +} + +/* See if an input file matches a DT_NEEDED entry by running stat on + the file. */ + +static void +gld${EMULATION_NAME}_stat_needed (s) + lang_input_statement_type *s; +{ + struct stat st; + const char *suffix; + const char *soname; + const char *f; + + if (global_found) + return; + if (s->the_bfd == NULL) + return; + + if (bfd_stat (s->the_bfd, &st) != 0) + { + einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd); + return; + } + + if (st.st_dev == global_stat.st_dev + && st.st_ino == global_stat.st_ino) + { + global_found = true; + return; + } + + /* We issue a warning if it looks like we are including two + different versions of the same shared library. For example, + there may be a problem if -lc picks up libc.so.6 but some other + shared library has a DT_NEEDED entry of libc.so.5. This is a + hueristic test, and it will only work if the name looks like + NAME.so.VERSION. FIXME: Depending on file names is error-prone. + If we really want to issue warnings about mixing version numbers + of shared libraries, we need to find a better way. */ + + if (strchr (global_needed->name, '/') != NULL) + return; + suffix = strstr (global_needed->name, ".so."); + if (suffix == NULL) + return; + suffix += sizeof ".so." - 1; + + soname = bfd_elf_get_dt_soname (s->the_bfd); + if (soname == NULL) + soname = s->filename; + + f = strrchr (soname, '/'); + if (f != NULL) + ++f; + else + f = soname; + + if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0) + einfo ("%P: warning: %s, needed by %B, may conflict with %s\n", + global_needed->name, global_needed->by, f); +} + +/* On Linux, it's possible to have different versions of the same + shared library linked against different versions of libc. The + dynamic linker somehow tags which libc version to use in + /etc/ld.so.cache, and, based on the libc that it sees in the + executable, chooses which version of the shared library to use. + + We try to do a similar check here by checking whether this shared + library needs any other shared libraries which may conflict with + libraries we have already included in the link. If it does, we + skip it, and try to find another shared library farther on down the + link path. + + This is called via lang_for_each_input_file. + GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object + which we ar checking. This sets GLOBAL_VERCHECK_FAILED if we find + a conflicting version. */ + +static void +gld${EMULATION_NAME}_vercheck (s) + lang_input_statement_type *s; +{ + const char *soname, *f; + struct bfd_link_needed_list *l; + + if (global_vercheck_failed) + return; + if (s->the_bfd == NULL + || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0) + return; + + soname = bfd_elf_get_dt_soname (s->the_bfd); + if (soname == NULL) + soname = bfd_get_filename (s->the_bfd); + + f = strrchr (soname, '/'); + if (f != NULL) + ++f; + else + f = soname; + + for (l = global_vercheck_needed; l != NULL; l = l->next) + { + const char *suffix; + + if (strcmp (f, l->name) == 0) + { + /* Probably can't happen, but it's an easy check. */ + continue; + } + + if (strchr (l->name, '/') != NULL) + continue; + + suffix = strstr (l->name, ".so."); + if (suffix == NULL) + continue; + + suffix += sizeof ".so." - 1; + + if (strncmp (f, l->name, suffix - l->name) == 0) + { + /* Here we know that S is a dynamic object FOO.SO.VER1, and + the object we are considering needs a dynamic object + FOO.SO.VER2, and VER1 and VER2 are different. This + appears to be a version mismatch, so we tell the caller + to try a different version of this library. */ + global_vercheck_failed = true; + return; + } + } +} + +/* This is called after the sections have been attached to output + sections, but before any sizes or addresses have been set. */ + +static void +gld${EMULATION_NAME}_before_allocation () +{ + const char *rpath; + asection *sinterp; + + /* If we are going to make any variable assignments, we need to let + the ELF backend know about them in case the variables are + referred to by dynamic objects. */ + lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment); + + /* Let the ELF backend work out the sizes of any sections required + by dynamic linking. */ + rpath = command_line.rpath; + if (rpath == NULL) + rpath = (const char *) getenv ("LD_RUN_PATH"); + if (! (bfd_elf${ELFSIZE}_size_dynamic_sections + (output_bfd, command_line.soname, rpath, + command_line.export_dynamic, command_line.filter_shlib, + (const char * const *) command_line.auxiliary_filters, + &link_info, &sinterp, lang_elf_version_info))) + einfo ("%P%F: failed to set dynamic section sizes: %E\n"); + + /* Let the user override the dynamic linker we are using. */ + if (command_line.interpreter != NULL + && sinterp != NULL) + { + sinterp->contents = (bfd_byte *) command_line.interpreter; + sinterp->_raw_size = strlen (command_line.interpreter) + 1; + } + + /* Look for any sections named .gnu.warning. As a GNU extensions, + we treat such sections as containing warning messages. We print + out the warning message, and then zero out the section size so + that it does not get copied into the output file. */ + + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + asection *s; + bfd_size_type sz; + char *msg; + boolean ret; + + if (is->just_syms_flag) + continue; + + s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning"); + if (s == NULL) + continue; + + sz = bfd_section_size (is->the_bfd, s); + msg = xmalloc ((size_t) sz + 1); + if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz)) + einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n", + is->the_bfd); + msg[sz] = '\0'; + ret = link_info.callbacks->warning (&link_info, msg, + (const char *) NULL, + is->the_bfd, (asection *) NULL, + (bfd_vma) 0); + ASSERT (ret); + free (msg); + + /* Clobber the section size, so that we don't waste copying the + warning into the output file. */ + s->_raw_size = 0; + } + } +} + +/* This is called by the before_allocation routine via + lang_for_each_statement. It locates any assignment statements, and + tells the ELF backend about them, in case they are assignments to + symbols which are referred to by dynamic objects. */ + +static void +gld${EMULATION_NAME}_find_statement_assignment (s) + lang_statement_union_type *s; +{ + if (s->header.type == lang_assignment_statement_enum) + gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); +} + +/* Look through an expression for an assignment statement. */ + +static void +gld${EMULATION_NAME}_find_exp_assignment (exp) + etree_type *exp; +{ + struct bfd_link_hash_entry *h; + + switch (exp->type.node_class) + { + case etree_provide: + h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, + false, false, false); + if (h == NULL) + break; + + /* We call record_link_assignment even if the symbol is defined. + This is because if it is defined by a dynamic object, we + actually want to use the value defined by the linker script, + not the value from the dynamic object (because we are setting + symbols like etext). If the symbol is defined by a regular + object, then, as it happens, calling record_link_assignment + will do no harm. */ + + /* Fall through. */ + case etree_assign: + if (strcmp (exp->assign.dst, ".") != 0) + { + if (! (bfd_elf${ELFSIZE}_record_link_assignment + (output_bfd, &link_info, exp->assign.dst, + exp->type.node_class == etree_provide ? true : false))) + einfo ("%P%F: failed to record assignment to %s: %E\n", + exp->assign.dst); + } + gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src); + break; + + case etree_binary: + gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs); + gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs); + break; + + case etree_trinary: + gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond); + gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs); + gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs); + break; + + case etree_unary: + gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child); + break; + + default: + break; + } +} + +/* Place an orphan section. We use this to put random SHF_ALLOC + sections in the right segment. */ + +static asection *hold_section; +static lang_output_section_statement_type *hold_use; +static lang_output_section_statement_type *hold_text; +static lang_output_section_statement_type *hold_rodata; +static lang_output_section_statement_type *hold_data; +static lang_output_section_statement_type *hold_bss; +static lang_output_section_statement_type *hold_rel; +static lang_output_section_statement_type *hold_interp; + +/*ARGSUSED*/ +static boolean +gld${EMULATION_NAME}_place_orphan (file, s) + lang_input_statement_type *file; + asection *s; +{ + lang_output_section_statement_type *place; + asection *snew, **pps; + lang_statement_list_type *old; + lang_statement_list_type add; + etree_type *address; + const char *secname, *ps; + const char *outsecname; + lang_output_section_statement_type *os; + + if ((s->flags & SEC_ALLOC) == 0) + return false; + + /* Look through the script to see where to place this section. */ + hold_section = s; + hold_use = NULL; + lang_for_each_statement (gld${EMULATION_NAME}_place_section); + + if (hold_use != NULL) + { + /* We have already placed a section with this name. */ + wild_doit (&hold_use->children, s, hold_use, file); + return true; + } + + secname = bfd_get_section_name (s->owner, s); + + /* If this is a final link, then always put .gnu.warning.SYMBOL + sections into the .text section to get them out of the way. */ + if (! link_info.shared + && ! link_info.relocateable + && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 + && hold_text != NULL) + { + wild_doit (&hold_text->children, s, hold_text, file); + return true; + } + + /* Decide which segment the section should go in based on the + section name and section flags. We put loadable .note sections + right after the .interp section, so that the PT_NOTE segment is + stored right after the program headers where the OS can read it + in the first page. */ + place = NULL; + if (s->flags & SEC_EXCLUDE) + return false; + else if ((s->flags & SEC_LOAD) != 0 + && strncmp (secname, ".note", 4) == 0 + && hold_interp != NULL) + place = hold_interp; + else if ((s->flags & SEC_HAS_CONTENTS) == 0 + && hold_bss != NULL) + place = hold_bss; + else if ((s->flags & SEC_READONLY) == 0 + && hold_data != NULL) + place = hold_data; + else if (strncmp (secname, ".rel", 4) == 0 + && hold_rel != NULL) + place = hold_rel; + else if ((s->flags & SEC_CODE) == 0 + && (s->flags & SEC_READONLY) != 0 + && hold_rodata != NULL) + place = hold_rodata; + else if ((s->flags & SEC_READONLY) != 0 + && hold_text != NULL) + place = hold_text; + if (place == NULL) + return false; + + /* Choose a unique name for the section. This will be needed if the + same section name appears in the input file with different + loadable or allocateable characteristics. */ + outsecname = secname; + if (bfd_get_section_by_name (output_bfd, outsecname) != NULL) + { + unsigned int len; + char *newname; + unsigned int i; + + len = strlen (outsecname); + newname = xmalloc (len + 5); + strcpy (newname, outsecname); + i = 0; + do + { + sprintf (newname + len, "%d", i); + ++i; + } + while (bfd_get_section_by_name (output_bfd, newname) != NULL); + + outsecname = newname; + } + + /* Create the section in the output file, and put it in the right + place. This shuffling is to make the output file look neater. */ + snew = bfd_make_section (output_bfd, outsecname); + if (snew == NULL) + einfo ("%P%F: output format %s cannot represent section called %s\n", + output_bfd->xvec->name, outsecname); + if (place->bfd_section != NULL) + { + for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) + ; + *pps = snew->next; + snew->next = place->bfd_section->next; + place->bfd_section->next = snew; + } + + /* Start building a list of statements for this section. */ + old = stat_ptr; + stat_ptr = &add; + lang_list_init (stat_ptr); + + /* If the name of the section is representable in C, then create + symbols to mark the start and the end of the section. */ + for (ps = outsecname; *ps != '\0'; ps++) + if (! isalnum ((unsigned char) *ps) && *ps != '_') + break; + if (*ps == '\0' && config.build_constructors) + { + char *symname; + + symname = (char *) xmalloc (ps - outsecname + sizeof "__start_"); + sprintf (symname, "__start_%s", outsecname); + lang_add_assignment (exp_assop ('=', symname, + exp_unop (ALIGN_K, + exp_intop ((bfd_vma) 1 + << s->alignment_power)))); + } + + if (! link_info.relocateable) + address = NULL; + else + address = exp_intop ((bfd_vma) 0); + + lang_enter_output_section_statement (outsecname, address, 0, + (bfd_vma) 0, + (etree_type *) NULL, + (etree_type *) NULL, + (etree_type *) NULL); + + os = lang_output_section_statement_lookup (outsecname); + wild_doit (&os->children, s, os, file); + + lang_leave_output_section_statement + ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL); + stat_ptr = &add; + + if (*ps == '\0' && config.build_constructors) + { + char *symname; + + symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_"); + sprintf (symname, "__stop_%s", outsecname); + lang_add_assignment (exp_assop ('=', symname, + exp_nameop (NAME, "."))); + } + + /* Now stick the new statement list right after PLACE. */ + *add.tail = place->header.next; + place->header.next = add.head; + + stat_ptr = old; + + return true; +} + +static void +gld${EMULATION_NAME}_place_section (s) + lang_statement_union_type *s; +{ + lang_output_section_statement_type *os; + + if (s->header.type != lang_output_section_statement_enum) + return; + + os = &s->output_section_statement; + + if (strcmp (os->name, hold_section->name) == 0 + && os->bfd_section != NULL + && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC)) + == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC)))) + hold_use = os; + + if (strcmp (os->name, ".text") == 0) + hold_text = os; + else if (strcmp (os->name, ".rodata") == 0) + hold_rodata = os; + else if (strcmp (os->name, ".data") == 0) + hold_data = os; + else if (strcmp (os->name, ".bss") == 0) + hold_bss = os; + else if (hold_rel == NULL + && os->bfd_section != NULL + && (os->bfd_section->flags & SEC_ALLOC) != 0 + && strncmp (os->name, ".rel", 4) == 0) + hold_rel = os; + else if (strcmp (os->name, ".interp") == 0) + hold_interp = os; +} + +static char * +gld${EMULATION_NAME}_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc='s/["\\]/\\&/g +s/$/\\n\\/ +1s/^/"/ +$s/$/n"/ +' + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; + else if (link_info.relocateable == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; + else if (!config.text_read_only) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; + else if (!config.magic_demand_paged) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; +EOF + +if test -n "$GENERATE_SHLIB_SCRIPT" ; then +cat >>e${EMULATION_NAME}.c <<EOF + else if (link_info.shared) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xs`; +EOF +fi + +cat >>e${EMULATION_NAME}.c <<EOF + else + return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; +} +EOF + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else if (link_info.shared) + return "ldscripts/${EMULATION_NAME}.xs"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + gld${EMULATION_NAME}_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gld${EMULATION_NAME}_before_allocation, + gld${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}", + NULL, + NULL, + gld${EMULATION_NAME}_open_dynamic_archive, + gld${EMULATION_NAME}_place_orphan +}; +EOF diff --git a/ld/emultempl/generic.em b/ld/emultempl/generic.em new file mode 100644 index 0000000..1c0c8eb --- /dev/null +++ b/ld/emultempl/generic.em @@ -0,0 +1,118 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* emulate the original gld for the given ${EMULATION_NAME} + Copyright (C) 1991, 1993 Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_${EMULATION_NAME} + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" + +static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); + +static void +gld${EMULATION_NAME}_before_parse() +{ +#ifndef TARGET_ /* I.e., if not generic. */ + ldfile_set_output_arch ("`echo ${ARCH}`"); +#endif /* not TARGET_ */ +} + +static char * +gld${EMULATION_NAME}_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc="-f ${srcdir}/emultempl/stringify.sed" + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +EOF +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + after_open_default, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + before_allocation_default, + gld${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}" +}; +EOF diff --git a/ld/emultempl/gld960.em b/ld/emultempl/gld960.em new file mode 100644 index 0000000..df998fb --- /dev/null +++ b/ld/emultempl/gld960.em @@ -0,0 +1,176 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* + * emulate the Intels port of gld + */ + + +#include "bfd.h" +#include "sysdep.h" +#include "libiberty.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldmain.h" + +#ifdef GNU960 + +static void +gld960_before_parse() +{ + static char *env_variables[] = { "G960LIB", "G960BASE", 0 }; + char **p; + char *env ; + + for ( p = env_variables; *p; p++ ){ + env = (char *) getenv(*p); + if (env) { + ldfile_add_library_path (concat (env, + "/lib/libbout", + (const char *) NULL), + false); + } + } + ldfile_output_architecture = bfd_arch_i960; +} + +#else /* not GNU960 */ + +static void gld960_before_parse() +{ + char *env ; + env = getenv("G960LIB"); + if (env) { + ldfile_add_library_path(env, false); + } + env = getenv("G960BASE"); + if (env) + ldfile_add_library_path (concat (env, "/lib", (const char *) NULL), false); + ldfile_output_architecture = bfd_arch_i960; +} + +#endif /* GNU960 */ + + +static void +gld960_set_output_arch() +{ + bfd_set_arch_mach(output_bfd, ldfile_output_architecture, bfd_mach_i960_core); +} + +static char * +gld960_choose_target() +{ +#ifdef GNU960 + + output_filename = "b.out"; + return bfd_make_targ_name(BFD_BOUT_FORMAT, 0); + +#else + + char *from_outside = getenv(TARGET_ENVIRON); + output_filename = "b.out"; + + if (from_outside != (char *)NULL) + return from_outside; + + return "b.out.little"; + +#endif +} + +static char * +gld960_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc='s/["\\]/\\&/g +s/$/\\n\\/ +1s/^/"/ +$s/$/n"/ +' + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; + else if (link_info.relocateable == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; + else if (!config.text_read_only) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; + else if (!config.magic_demand_paged) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; + else + return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; +} +EOF + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_gld960_emulation = +{ + gld960_before_parse, + syslib_default, + hll_default, + after_parse_default, + after_open_default, + after_allocation_default, + gld960_set_output_arch, + gld960_choose_target, + before_allocation_default, + gld960_get_script, + "960", + "" +}; +EOF diff --git a/ld/emultempl/gld960c.em b/ld/emultempl/gld960c.em new file mode 100644 index 0000000..20cb5ed --- /dev/null +++ b/ld/emultempl/gld960c.em @@ -0,0 +1,192 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* + * emulate the Intels port of gld + */ + + +#include <ctype.h> +#include "bfd.h" +#include "sysdep.h" +#include "libiberty.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldmain.h" + +#ifdef GNU960 + +static void +gld960_before_parse() +{ + static char *env_variables[] = { "G960LIB", "G960BASE", 0 }; + char **p; + char *env ; + + for ( p = env_variables; *p; p++ ){ + env = (char *) getenv(*p); + if (env) { + ldfile_add_library_path (concat (env, + "/lib/libcoff", + (const char *) NULL), + false); + } + } + ldfile_output_architecture = bfd_arch_i960; +} + +#else /* not GNU960 */ + +static void gld960_before_parse() +{ + char *env ; + env = getenv("G960LIB"); + if (env) { + ldfile_add_library_path(env, false); + } + env = getenv("G960BASE"); + if (env) + ldfile_add_library_path (concat (env, "/lib", (const char *) NULL), + false); + ldfile_output_architecture = bfd_arch_i960; +} + +#endif /* GNU960 */ + + +static void +gld960_set_output_arch() +{ + if (ldfile_output_machine_name != NULL + && *ldfile_output_machine_name != '\0') + { + char *s, *s1; + + s = concat ("i960:", ldfile_output_machine_name, (char *) NULL); + for (s1 = s; *s1 != '\0'; s1++) + if (isupper ((unsigned char) *s1)) + *s1 = tolower ((unsigned char) *s1); + ldfile_set_output_arch (s); + free (s); + } + + set_output_arch_default (); +} + +static char * +gld960_choose_target() +{ +#ifdef GNU960 + + output_filename = "b.out"; + return bfd_make_targ_name(BFD_BOUT_FORMAT, 0); + +#else + + char *from_outside = getenv(TARGET_ENVIRON); + output_filename = "b.out"; + + if (from_outside != (char *)NULL) + return from_outside; + + return "coff-Intel-little"; + +#endif +} + +static char * +gld960_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc='s/["\\]/\\&/g +s/$/\\n\\/ +1s/^/"/ +$s/$/n"/ +' + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; + else if (link_info.relocateable == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; + else if (!config.text_read_only) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; + else if (!config.magic_demand_paged) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; + else + return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; +} +EOF + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_gld960coff_emulation = +{ + gld960_before_parse, + syslib_default, + hll_default, + after_parse_default, + after_open_default, + after_allocation_default, + gld960_set_output_arch, + gld960_choose_target, + before_allocation_default, + gld960_get_script, + "960coff", + "" +}; +EOF diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em new file mode 100644 index 0000000..c0ca113 --- /dev/null +++ b/ld/emultempl/hppaelf.em @@ -0,0 +1,283 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* An emulation for HP PA-RISC ELF linkers. + Copyright (C) 1991, 93, 94, 95, 1997 Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldmisc.h" +#include "ldmain.h" +#include "ldctor.h" + +/* Section in which we build stubs. */ +static asection *stub_sec; +static lang_input_statement_type *stub_file; + + +/* FIXME. This doesn't belong here. */ +extern lang_statement_list_type file_chain; + +/* Perform some emulation specific initialization. For PA ELF we set + up the local label prefix and the output architecture. */ + +static void +hppaelf_before_parse () +{ + ldfile_output_architecture = bfd_arch_hppa; +} + +/* Set the output architecture and machine. */ + +static void +hppaelf_set_output_arch() +{ + unsigned long machine = 0; + + bfd_set_arch_mach (output_bfd, ldfile_output_architecture, machine); +} + +/* This is called before the input files are opened. We create a new + fake input file to hold the stub section. */ + +static void +hppaelf_create_output_section_statements () +{ + stub_file = lang_add_input_file ("linker stubs", + lang_input_file_is_fake_enum, + NULL); + stub_file->the_bfd = bfd_create ("linker stubs", output_bfd); + if (stub_file->the_bfd == NULL + || ! bfd_set_arch_mach (stub_file->the_bfd, + bfd_get_arch (output_bfd), + bfd_get_mach (output_bfd))) + { + einfo ("%X%P: can not create BFD %E\n"); + return; + } + + stub_sec = bfd_make_section_old_way (stub_file->the_bfd, ".text"); + /* Don't set SEC_RELOC until we actually have relocations in this + section. */ + if (stub_sec == NULL + || ! bfd_set_section_flags (stub_file->the_bfd, stub_sec, + (SEC_HAS_CONTENTS + | SEC_ALLOC + | SEC_LOAD + | SEC_CODE + | SEC_IN_MEMORY))) + { + einfo ("%X%P: can not create stub section: %E\n"); + return; + } + + ldlang_add_file (stub_file); +} + +/* Walk all the lang statements splicing out any padding statements from + the list. */ + +static void +hppaelf_delete_padding_statements (s, prev) + lang_statement_union_type *s; + lang_statement_union_type **prev; +{ + lang_statement_union_type *sprev = NULL; + for (; s != NULL; s = s->next) + { + switch (s->header.type) + { + + /* We want recursively walk these sections. */ + case lang_constructors_statement_enum: + hppaelf_delete_padding_statements (constructor_list.head, + &constructor_list.head); + break; + + case lang_output_section_statement_enum: + hppaelf_delete_padding_statements (s->output_section_statement. + children.head, + &s->output_section_statement. + children.head); + break; + + /* Huh? What is a lang_wild_statement? */ + case lang_wild_statement_enum: + hppaelf_delete_padding_statements (s->wild_statement. + children.head, + &s->wild_statement. + children.head); + break; + + /* Here's what we are really looking for. Splice these out of + the list. */ + case lang_padding_statement_enum: + if (sprev) + sprev->header.next = s->header.next; + else + **prev = *s; + break; + + /* We don't care about these cases. */ + case lang_data_statement_enum: + case lang_object_symbols_statement_enum: + case lang_output_statement_enum: + case lang_target_statement_enum: + case lang_input_section_enum: + case lang_input_statement_enum: + case lang_assignment_statement_enum: + case lang_address_statement_enum: + break; + + default: + abort (); + break; + } + sprev = s; + } +} + +/* Final emulation specific call. For the PA we use this opportunity + to build linker stubs. */ + +static void +hppaelf_finish () +{ + /* Call into the BFD backend to do the real work. */ + if (elf32_hppa_size_stubs (stub_file->the_bfd, output_bfd, &link_info) + == false) + { + einfo ("%X%P: can not size stub section: %E\n"); + return; + } + + /* If the size of the stub section is nonzero, then we need + to resize the sections, recompute the assignments, and finally + build the stubs. */ + if (bfd_section_size (stub_file->the_bfd, stub_file->the_bfd->sections) != 0) + { + /* Delete all the padding statements, they're no longer valid. */ + hppaelf_delete_padding_statements (stat_ptr->head, &stat_ptr->head); + + /* Resize the sections. */ + lang_size_sections (stat_ptr->head, abs_output_section, + &stat_ptr->head, 0, (bfd_vma) 0, false); + + /* Redo special stuff. */ + ldemul_after_allocation (); + + /* Do the assignments again. */ + lang_do_assignments (stat_ptr->head, + abs_output_section, + (fill_type) 0, (bfd_vma) 0); + + /* Now build the linker stubs. */ + if (elf32_hppa_build_stubs (stub_file->the_bfd, &link_info) == false) + { + einfo ("%X%P: can not build stubs: %E\n"); + return; + } + } +} + +/* The script itself gets inserted here. */ + +static char * +hppaelf_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc='s/["\\]/\\&/g +s/$/\\n\\/ +1s/^/"/ +$s/$/n"/ +' + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; + else if (link_info.relocateable == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; + else if (!config.text_read_only) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; + else if (!config.magic_demand_paged) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; + else + return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; +} +EOF + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_hppaelf_emulation = +{ + hppaelf_before_parse, + syslib_default, + hll_default, + after_parse_default, + after_open_default, + after_allocation_default, + hppaelf_set_output_arch, + ldemul_default_target, + before_allocation_default, + hppaelf_get_script, + "hppaelf", + "elf32-hppa", + hppaelf_finish, + hppaelf_create_output_section_statements, +}; +EOF diff --git a/ld/emultempl/linux.em b/ld/emultempl/linux.em new file mode 100644 index 0000000..dc0855d --- /dev/null +++ b/ld/emultempl/linux.em @@ -0,0 +1,208 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* Linux a.out emulation code for ${EMULATION_NAME} + Copyright (C) 1991, 93, 94, 95, 96, 1998 Free Software Foundation, Inc. + Written by Steve Chamberlain <sac@cygnus.com> + Linux support by Eric Youngdale <ericy@cais.cais.com> + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_${EMULATION_NAME} + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" + +static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static boolean gld${EMULATION_NAME}_open_dynamic_archive + PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); +static void gld${EMULATION_NAME}_find_address_statement + PARAMS ((lang_statement_union_type *)); +static void gld${EMULATION_NAME}_create_output_section_statements + PARAMS ((void)); +static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); +static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); + +static void +gld${EMULATION_NAME}_before_parse() +{ + ldfile_output_architecture = bfd_arch_${ARCH}; + config.dynamic_link = true; + config.has_shared = true; +} + +/* Try to open a dynamic archive. This is where we know that Linux + dynamic libraries have an extension of .sa. */ + +static boolean +gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) + const char *arch; + search_dirs_type *search; + lang_input_statement_type *entry; +{ + char *string; + + if (! entry->is_archive) + return false; + + string = (char *) xmalloc (strlen (search->name) + + strlen (entry->filename) + + strlen (arch) + + sizeof "/lib.sa"); + + sprintf (string, "%s/lib%s%s.sa", search->name, entry->filename, arch); + + if (! ldfile_try_open_bfd (string, entry)) + { + free (string); + return false; + } + + entry->filename = string; + + return true; +} + +/* This is called by the create_output_section_statements routine via + lang_for_each_statement. It locates any address assignment to + .text, and modifies it to include the size of the headers. This + causes -Ttext to mean the starting address of the header, rather + than the starting address of .text, which is compatible with other + Linux tools. */ + +static void +gld${EMULATION_NAME}_find_address_statement (s) + lang_statement_union_type *s; +{ + if (s->header.type == lang_address_statement_enum + && strcmp (s->address_statement.section_name, ".text") == 0) + { + ASSERT (s->address_statement.address->type.node_class == etree_value); + s->address_statement.address->value.value += 0x20; + } +} + +/* This is called before opening the input BFD's. */ + +static void +gld${EMULATION_NAME}_create_output_section_statements () +{ + lang_for_each_statement (gld${EMULATION_NAME}_find_address_statement); +} + +/* This is called after the sections have been attached to output + sections, but before any sizes or addresses have been set. */ + +static void +gld${EMULATION_NAME}_before_allocation () +{ + if (link_info.relocateable) + return; + + /* Let the backend work out the sizes of any sections required by + dynamic linking. */ + if (! bfd_${EMULATION_NAME}_size_dynamic_sections (output_bfd, &link_info)) + einfo ("%P%F: failed to set dynamic section sizes: %E\n"); +} + +static char * +gld${EMULATION_NAME}_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc='s/["\\]/\\&/g +s/$/\\n\\/ +1s/^/"/ +$s/$/n"/ +' + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; + else if (link_info.relocateable == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; + else if (!config.text_read_only) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; + else if (!config.magic_demand_paged) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; + else + return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; +} +EOF + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + after_open_default, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gld${EMULATION_NAME}_before_allocation, + gld${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}", + NULL, + gld${EMULATION_NAME}_create_output_section_statements, + gld${EMULATION_NAME}_open_dynamic_archive +}; +EOF diff --git a/ld/emultempl/lnk960.em b/ld/emultempl/lnk960.em new file mode 100644 index 0000000..066d46b --- /dev/null +++ b/ld/emultempl/lnk960.em @@ -0,0 +1,327 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* intel coff loader emulation specific stuff + Copyright (C) 1991, 1993 Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "libiberty.h" +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" + +/*#include "archures.h"*/ +#include "ld.h" +#include "ldemul.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldfile.h" +#include "ldmain.h" + +typedef struct lib_list { + char *name; + struct lib_list *next; +} lib_list_type; + +static lib_list_type *hll_list; +static lib_list_type **hll_list_tail = &hll_list; + +static lib_list_type *syslib_list; +static lib_list_type **syslib_list_tail = &syslib_list; + + +static void +append(list, name) + lib_list_type ***list; + char *name; +{ + lib_list_type *element = + (lib_list_type *)(xmalloc(sizeof(lib_list_type))); + + element->name = name; + element->next = (lib_list_type *)NULL; + **list = element; + *list = &element->next; + +} + +static boolean had_hll = false; +static boolean had_hll_name = false; + +static void +lnk960_hll(name) + char *name; +{ + had_hll = true; + if (name != (char *)NULL) { + had_hll_name = true; + append(&hll_list_tail, name); + } +} + +static void +lnk960_syslib(name) + char *name; +{ + append(&syslib_list_tail,name); +} + + +#ifdef GNU960 + +static void +lnk960_before_parse() +{ + static char *env_variables[] = { "G960LIB", "G960BASE", 0 }; + char **p; + char *env ; + + for ( p = env_variables; *p; p++ ){ + env = (char *) getenv(*p); + if (env) { + ldfile_add_library_path(concat(env,"/lib/libcoff",""), false); + } + } + + env= (char *) getenv("I960BASE"); + if ( env ) { + ldfile_add_library_path(concat(env,"/lib",""), false); + } + + ldfile_output_architecture = bfd_arch_i960; + ldfile_output_machine = bfd_mach_i960_core; +} + +#else /* not GNU960 */ + +static void +lnk960_before_parse() +{ + char *name = getenv("I960BASE"); + + if (name == (char *)NULL) { + name = getenv("G960BASE"); + if (name == (char *)NULL) { + einfo("%P%F I960BASE and G960BASE not set\n"); + } + } + + + ldfile_add_library_path(concat(name,"/lib",""), false); + ldfile_output_architecture = bfd_arch_i960; + ldfile_output_machine = bfd_mach_i960_core; +} + +#endif /* GNU960 */ + + +static void +add_on(list, search) + lib_list_type *list; + lang_input_file_enum_type search; +{ + while (list) { + lang_add_input_file(list->name, + search, + (char *)NULL); + list = list->next; + } +} +static void +lnk960_after_parse() +{ + /* If there has been no arch, default to -KB */ + if (ldfile_output_machine_name[0] ==0) { + ldfile_add_arch("KB"); + } + + /* if there has been no hll list then add our own */ + + if(had_hll && !had_hll_name) { + append(&hll_list_tail,"cg"); + if (ldfile_output_machine == bfd_mach_i960_ka_sa || + ldfile_output_machine == bfd_mach_i960_ca) { + { + append(&hll_list_tail,"fpg"); + } + } + } + + add_on(hll_list, lang_input_file_is_l_enum); + add_on(syslib_list, lang_input_file_is_search_file_enum); +} + +static void +lnk960_before_allocation() +{ +} + +static void +lnk960_after_allocation() +{ + if (link_info.relocateable == false) { + lang_abs_symbol_at_end_of(".text","_etext"); + lang_abs_symbol_at_end_of(".data","_edata"); + lang_abs_symbol_at_beginning_of(".bss","_bss_start"); + lang_abs_symbol_at_end_of(".bss","_end"); + } +} + + +static struct + { + unsigned long number; + char *name; + } +machine_table[] = +{ + { bfd_mach_i960_core ,"CORE" }, + { bfd_mach_i960_kb_sb ,"KB" }, + { bfd_mach_i960_kb_sb ,"SB" }, + { bfd_mach_i960_mc ,"MC" }, + { bfd_mach_i960_xa ,"XA" }, + { bfd_mach_i960_ca ,"CA" }, + { bfd_mach_i960_ka_sa ,"KA" }, + { bfd_mach_i960_ka_sa ,"SA" }, + { bfd_mach_i960_jx ,"JX" }, + { bfd_mach_i960_hx ,"HX" }, + + { bfd_mach_i960_core ,"core" }, + { bfd_mach_i960_kb_sb ,"kb" }, + { bfd_mach_i960_kb_sb ,"sb" }, + { bfd_mach_i960_mc ,"mc" }, + { bfd_mach_i960_xa ,"xa" }, + { bfd_mach_i960_ca ,"ca" }, + { bfd_mach_i960_ka_sa ,"ka" }, + { bfd_mach_i960_ka_sa ,"sa" }, + { bfd_mach_i960_jx ,"jx" }, + { bfd_mach_i960_hx ,"hx" }, + + { 0, (char *) NULL } +}; + +static void +lnk960_set_output_arch() +{ + /* Set the output architecture and machine if possible */ + unsigned int i; + ldfile_output_machine = bfd_mach_i960_core; + for (i= 0; machine_table[i].name != (char*)NULL; i++) { + if (strcmp(ldfile_output_machine_name,machine_table[i].name)==0) { + ldfile_output_machine = machine_table[i].number; + break; + } + } + bfd_set_arch_mach(output_bfd, ldfile_output_architecture, ldfile_output_machine); +} + +static char * +lnk960_choose_target() +{ +#ifdef GNU960 + + return bfd_make_targ_name(BFD_COFF_FORMAT, 0); + +#else + + char *from_outside = getenv(TARGET_ENVIRON); + if (from_outside != (char *)NULL) + return from_outside; +#ifdef LNK960_LITTLE + return "coff-Intel-little"; +#else + return "coff-Intel-big"; +#endif +#endif + +} + +static char * +lnk960_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc='s/["\\]/\\&/g +s/$/\\n\\/ +1s/^/"/ +$s/$/n"/ +' + +cat >>e${EMULATION_NAME}.c <<EOF + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; + else if (link_info.relocateable == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; + else if (!config.text_read_only) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; + else if (!config.magic_demand_paged) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; + else + return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; +} +EOF + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_lnk960_emulation = +{ + lnk960_before_parse, + lnk960_syslib, + lnk960_hll, + lnk960_after_parse, + NULL, /* after_open */ + lnk960_after_allocation, + lnk960_set_output_arch, + lnk960_choose_target, + lnk960_before_allocation, + lnk960_get_script, + "lnk960", + "" +}; +EOF diff --git a/ld/emultempl/mipsecoff.em b/ld/emultempl/mipsecoff.em new file mode 100644 index 0000000..d1200c4 --- /dev/null +++ b/ld/emultempl/mipsecoff.em @@ -0,0 +1,229 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* Handle embedded relocs for MIPS. + Copyright 1994 Free Software Foundation, Inc. + Written by Ian Lance Taylor <ian@cygnus.com> based on generic.em. + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_${EMULATION_NAME} + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" + +static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static void gld${EMULATION_NAME}_after_open PARAMS ((void)); +static void check_sections PARAMS ((bfd *, asection *, PTR)); +static void gld${EMULATION_NAME}_after_allocation PARAMS ((void)); +static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); + +static void +gld${EMULATION_NAME}_before_parse() +{ +#ifndef TARGET_ /* I.e., if not generic. */ + ldfile_output_architecture = bfd_arch_${ARCH}; +#endif /* not TARGET_ */ +} + +/* This function is run after all the input files have been opened. + We create a .rel.sdata section for each input file with a non zero + .sdata section. The BFD backend will fill in these sections with + magic numbers which can be used to relocate the data section at run + time. This will only do the right thing if all the input files + have been compiled using -membedded-pic. */ + +static void +gld${EMULATION_NAME}_after_open () +{ + bfd *abfd; + + if (! command_line.embedded_relocs + || link_info.relocateable) + return; + + for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next) + { + asection *datasec; + + datasec = bfd_get_section_by_name (abfd, ".sdata"); + + /* Note that we assume that the reloc_count field has already + been set up. We could call bfd_get_reloc_upper_bound, but + that returns the size of a memory buffer rather than a reloc + count. We do not want to call bfd_canonicalize_reloc, + because although it would always work it would force us to + read in the relocs into BFD canonical form, which would waste + a significant amount of time and memory. */ + if (datasec != NULL && datasec->reloc_count > 0) + { + asection *relsec; + + relsec = bfd_make_section (abfd, ".rel.sdata"); + if (relsec == NULL + || ! bfd_set_section_flags (abfd, relsec, + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY)) + || ! bfd_set_section_alignment (abfd, relsec, 2) + || ! bfd_set_section_size (abfd, relsec, + datasec->reloc_count * 4)) + einfo ("%F%B: can not create .rel.sdata section: %E\n"); + } + + /* Double check that all other data sections are empty, as is + required for embedded PIC code. */ + bfd_map_over_sections (abfd, check_sections, (PTR) datasec); + } +} + +/* Check that of the data sections, only the .sdata section has + relocs. This is called via bfd_map_over_sections. */ + +static void +check_sections (abfd, sec, sdatasec) + bfd *abfd; + asection *sec; + PTR sdatasec; +{ + if ((bfd_get_section_flags (abfd, sec) & SEC_CODE) == 0 + && sec != (asection *) sdatasec + && sec->reloc_count != 0) + einfo ("%P%X: section %s has relocs; can not use --embedded-relocs\n", + abfd, bfd_get_section_name (abfd, sec)); +} + +/* This function is called after the section sizes and offsets have + been set. If we are generating embedded relocs, it calls a special + BFD backend routine to do the work. */ + +static void +gld${EMULATION_NAME}_after_allocation () +{ + bfd *abfd; + + if (! command_line.embedded_relocs + || link_info.relocateable) + return; + + for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next) + { + asection *datasec, *relsec; + char *errmsg; + + datasec = bfd_get_section_by_name (abfd, ".sdata"); + + if (datasec == NULL || datasec->reloc_count == 0) + continue; + + relsec = bfd_get_section_by_name (abfd, ".rel.sdata"); + ASSERT (relsec != NULL); + + if (! bfd_mips_ecoff_create_embedded_relocs (abfd, &link_info, + datasec, relsec, + &errmsg)) + { + if (errmsg == NULL) + einfo ("%B%X: can not create runtime reloc information: %E\n", + abfd); + else + einfo ("%X%B: can not create runtime reloc information: %s\n", + abfd, errmsg); + } + } +} + +static char * +gld${EMULATION_NAME}_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc="-f ${srcdir}/emultempl/stringify.sed" + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +EOF +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + gld${EMULATION_NAME}_after_open, + gld${EMULATION_NAME}_after_allocation, + set_output_arch_default, + ldemul_default_target, + before_allocation_default, + gld${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}" +}; +EOF diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em new file mode 100644 index 0000000..46ebbe9 --- /dev/null +++ b/ld/emultempl/pe.em @@ -0,0 +1,1104 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is part of GLD, the Gnu Linker. + Copyright 1995, 96, 97, 1998 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* For WINDOWS_NT */ +/* The original file generated returned different default scripts depending + on whether certain switches were set, but these switches pertain to the + Linux system and that particular version of coff. In the NT case, we + only determine if the subsystem is console or windows in order to select + the correct entry point by default. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "getopt.h" +#include "libiberty.h" +#include "ld.h" +#include "ldmain.h" +#include "ldgram.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldemul.h" +#include "ldlex.h" +#include "ldmisc.h" +#include "ldctor.h" +#include "ldfile.h" +#include "coff/internal.h" +#include "../bfd/libcoff.h" +#include "deffile.h" + +#define TARGET_IS_${EMULATION_NAME} + +static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void)); +static void gld_${EMULATION_NAME}_after_open PARAMS ((void)); +static void gld_${EMULATION_NAME}_before_parse PARAMS ((void)); +static void gld_${EMULATION_NAME}_after_parse PARAMS ((void)); +static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void)); +static boolean gld_${EMULATION_NAME}_place_orphan + PARAMS ((lang_input_statement_type *, asection *)); +static void gld${EMULATION_NAME}_place_section + PARAMS ((lang_statement_union_type *)); +static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *)); +static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **)); + +static struct internal_extra_pe_aouthdr pe; +static int dll; +static int support_old_code = 0; +extern def_file *pe_def_file; +static lang_assignment_statement_type *image_base_statement = 0; + +static char *pe_out_def_filename = 0; +extern int pe_dll_export_everything; +extern int pe_dll_kill_ats; +extern int pe_dll_stdcall_aliases; +static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable */ +static char *pe_implib_filename = 0; + +extern const char *output_filename; + +static void +gld_${EMULATION_NAME}_before_parse() +{ + output_filename = "a.exe"; + ldfile_output_architecture = bfd_arch_${ARCH}; +#ifdef TARGET_IS_i386pe + config.has_shared = 1; +#endif +} + +/* PE format extra command line options. */ + +/* Used for setting flags in the PE header. */ +#define OPTION_BASE_FILE (300 + 1) +#define OPTION_DLL (OPTION_BASE_FILE + 1) +#define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1) +#define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1) +#define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1) +#define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1) +#define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1) +#define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1) +#define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1) +#define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1) +#define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1) +#define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1) +#define OPTION_SUBSYSTEM (OPTION_STACK + 1) +#define OPTION_HEAP (OPTION_SUBSYSTEM + 1) +#define OPTION_SUPPORT_OLD_CODE (OPTION_HEAP + 1) +#define OPTION_OUT_DEF (OPTION_SUPPORT_OLD_CODE + 1) +#define OPTION_EXPORT_ALL (OPTION_OUT_DEF + 1) +#define OPTION_EXCLUDE_SYMBOLS (OPTION_EXPORT_ALL + 1) +#define OPTION_KILL_ATS (OPTION_EXCLUDE_SYMBOLS + 1) +#define OPTION_STDCALL_ALIASES (OPTION_KILL_ATS + 1) +#define OPTION_ENABLE_STDCALL_FIXUP (OPTION_STDCALL_ALIASES + 1) +#define OPTION_DISABLE_STDCALL_FIXUP (OPTION_ENABLE_STDCALL_FIXUP + 1) +#define OPTION_IMPLIB_FILENAME (OPTION_DISABLE_STDCALL_FIXUP + 1) + +static struct option longopts[] = +{ + /* PE options */ + {"base-file", required_argument, NULL, OPTION_BASE_FILE}, + {"dll", no_argument, NULL, OPTION_DLL}, + {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT}, + {"heap", required_argument, NULL, OPTION_HEAP}, + {"image-base", required_argument, NULL, OPTION_IMAGE_BASE}, + {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION}, + {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION}, + {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION}, + {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION}, + {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION}, + {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION}, + {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT}, + {"stack", required_argument, NULL, OPTION_STACK}, + {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM}, + {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, +#ifdef TARGET_IS_i386pe + /* getopt allows abbreviations, so we do this to stop it from treating -o + as an abbreviation for this option */ + {"output-def", required_argument, NULL, OPTION_OUT_DEF}, + {"output-def", required_argument, NULL, OPTION_OUT_DEF}, + {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL}, + {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS}, + {"kill-at", no_argument, NULL, OPTION_KILL_ATS}, + {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES}, + {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP}, + {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP}, + {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME}, +#endif + {NULL, no_argument, NULL, 0} +}; + + +/* PE/WIN32; added routines to get the subsystem type, heap and/or stack + parameters which may be input from the command line */ + +typedef struct +{ + void *ptr; + int size; + int value; + char *symbol; + int inited; +} definfo; + +#define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0} + +static definfo init[] = +{ + /* imagebase must be first */ +#define IMAGEBASEOFF 0 + D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE), +#define DLLOFF 1 + {&dll, sizeof(dll), 0, "__dll__"}, + D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT), + D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT), + D(MajorOperatingSystemVersion,"__major_os_version__", 4), + D(MinorOperatingSystemVersion,"__minor_os_version__", 0), + D(MajorImageVersion,"__major_image_version__", 1), + D(MinorImageVersion,"__minor_image_version__", 0), + D(MajorSubsystemVersion,"__major_subsystem_version__", 4), + D(MinorSubsystemVersion,"__minor_subsystem_version__", 0), + D(Subsystem,"__subsystem__", 3), + D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000), + D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000), + D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000), + D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000), + D(LoaderFlags,"__loader_flags__", 0x0), + { NULL, 0, 0, NULL, 0 } +}; + +static void +gld_${EMULATION_NAME}_list_options (file) + FILE * file; +{ + fprintf (file, _(" --base_file <basefile> Generate a base file for relocatable DLLs\n")); + fprintf (file, _(" --dll Set image base to the default for DLLs\n")); + fprintf (file, _(" --file-alignment <size> Set file alignment\n")); + fprintf (file, _(" --heap <size> Set initial size of the heap\n")); + fprintf (file, _(" --image-base <address> Set start address of the executable\n")); + fprintf (file, _(" --major-image-version <number> Set version number of the executable\n")); + fprintf (file, _(" --major-os-version <number> Set minimum required OS version\n")); + fprintf (file, _(" --major-subsystem-version <number> Set minimum required OS subsystem version\n")); + fprintf (file, _(" --minor-image-version <number> Set revision number of the executable\n")); + fprintf (file, _(" --minor-os-version <number> Set minimum required OS revision\n")); + fprintf (file, _(" --minor-subsystem-version <number> Set minimum required OS subsystem revision\n")); + fprintf (file, _(" --section-alignment <size> Set section alignment\n")); + fprintf (file, _(" --stack <size> Set size of the initial stack\n")); + fprintf (file, _(" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n")); + fprintf (file, _(" --support-old-code Support interworking with old code\n")); +#ifdef TARGET_IS_i386pe + fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n")); + fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n")); + fprintf (file, _(" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n")); + fprintf (file, _(" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n")); + fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\n")); + fprintf (file, _(" --kill-at Remove @nn from exported symbols\n")); + fprintf (file, _(" --out-implib <file> Generate import library\n")); + fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n")); +#endif +} + +static void +set_pe_name (name, val) + char *name; + long val; +{ + int i; + /* Find the name and set it. */ + for (i = 0; init[i].ptr; i++) + { + if (strcmp (name, init[i].symbol) == 0) + { + init[i].value = val; + init[i].inited = 1; + return; + } + } + abort(); +} + + +static void +set_pe_subsystem () +{ + const char *sver; + int len; + int i; + static const struct + { + const char *name; + const int value; + const char *entry; + } + v[] = + { + { "native", 1, "_NtProcessStartup" }, + { "windows", 2, "_WinMainCRTStartup" }, + { "console", 3, "_mainCRTStartup" }, +#if 0 + /* The Microsoft linker does not recognize this. */ + { "os2", 5, "" }, +#endif + { "posix", 7, "___PosixProcessStartup"}, + { 0, 0, 0 } + }; + + sver = strchr (optarg, ':'); + if (sver == NULL) + len = strlen (optarg); + else + { + char *end; + + len = sver - optarg; + set_pe_name ("__major_subsystem_version__", + strtoul (sver + 1, &end, 0)); + if (*end == '.') + set_pe_name ("__minor_subsystem_version__", + strtoul (end + 1, &end, 0)); + if (*end != '\0') + einfo (_("%P: warning: bad version number in -subsystem option\n")); + } + + for (i = 0; v[i].name; i++) + { + if (strncmp (optarg, v[i].name, len) == 0 + && v[i].name[len] == '\0') + { + set_pe_name ("__subsystem__", v[i].value); + + lang_add_entry (v[i].entry, 1); + + return; + } + } + + einfo (_("%P%F: invalid subsystem type %s\n"), optarg); +} + + + +static void +set_pe_value (name) + char *name; + +{ + char *end; + + set_pe_name (name, strtoul (optarg, &end, 0)); + + if (end == optarg) + einfo (_("%P%F: invalid hex number for PE parameter '%s'\n"), optarg); + + optarg = end; +} + +static void +set_pe_stack_heap (resname, comname) + char *resname; + char *comname; +{ + set_pe_value (resname); + + if (*optarg == ',') + { + optarg++; + set_pe_value (comname); + } + else if (*optarg) + einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg); +} + + + +static int +gld_${EMULATION_NAME}_parse_args(argc, argv) + int argc; + char **argv; +{ + int longind; + int optc; + int prevoptind = optind; + int prevopterr = opterr; + int wanterror; + static int lastoptind = -1; + + if (lastoptind != optind) + opterr = 0; + wanterror = opterr; + + lastoptind = optind; + + optc = getopt_long_only (argc, argv, "-", longopts, &longind); + opterr = prevopterr; + + switch (optc) + { + default: + if (wanterror) + xexit (1); + optind = prevoptind; + return 0; + + case OPTION_BASE_FILE: + link_info.base_file = (PTR) fopen (optarg, FOPEN_WB); + if (link_info.base_file == NULL) + { + /* xgettext:c-format */ + fprintf (stderr, _("%s: Can't open base file %s\n"), + program_name, optarg); + xexit (1); + } + break; + + /* PE options */ + case OPTION_HEAP: + set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__"); + break; + case OPTION_STACK: + set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__"); + break; + case OPTION_SUBSYSTEM: + set_pe_subsystem (); + break; + case OPTION_MAJOR_OS_VERSION: + set_pe_value ("__major_os_version__"); + break; + case OPTION_MINOR_OS_VERSION: + set_pe_value ("__minor_os_version__"); + break; + case OPTION_MAJOR_SUBSYSTEM_VERSION: + set_pe_value ("__major_subsystem_version__"); + break; + case OPTION_MINOR_SUBSYSTEM_VERSION: + set_pe_value ("__minor_subsystem_version__"); + break; + case OPTION_MAJOR_IMAGE_VERSION: + set_pe_value ("__major_image_version__"); + break; + case OPTION_MINOR_IMAGE_VERSION: + set_pe_value ("__minor_image_version__"); + break; + case OPTION_FILE_ALIGNMENT: + set_pe_value ("__file_alignment__"); + break; + case OPTION_SECTION_ALIGNMENT: + set_pe_value ("__section_alignment__"); + break; + case OPTION_DLL: + set_pe_name ("__dll__", 1); + break; + case OPTION_IMAGE_BASE: + set_pe_value ("__image_base__"); + break; + case OPTION_SUPPORT_OLD_CODE: + support_old_code = 1; + break; + case OPTION_OUT_DEF: + pe_out_def_filename = xstrdup (optarg); + break; + case OPTION_EXPORT_ALL: + pe_dll_export_everything = 1; + break; + case OPTION_EXCLUDE_SYMBOLS: +#ifdef TARGET_IS_i386pe + pe_dll_add_excludes (optarg); +#endif + break; + case OPTION_KILL_ATS: + pe_dll_kill_ats = 1; + break; + case OPTION_STDCALL_ALIASES: + pe_dll_stdcall_aliases = 1; + break; + case OPTION_ENABLE_STDCALL_FIXUP: + pe_enable_stdcall_fixup = 1; + break; + case OPTION_DISABLE_STDCALL_FIXUP: + pe_enable_stdcall_fixup = 0; + break; + case OPTION_IMPLIB_FILENAME: + pe_implib_filename = xstrdup (optarg); + break; + } + return 1; +} + +/* Assign values to the special symbols before the linker script is + read. */ + +static void +gld_${EMULATION_NAME}_set_symbols () +{ + /* Run through and invent symbols for all the + names and insert the defaults. */ + int j; + lang_statement_list_type *save; + + if (!init[IMAGEBASEOFF].inited) + { + if (link_info.relocateable) + init[IMAGEBASEOFF].value = 0; + else if (init[DLLOFF].value || link_info.shared) + init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE; + else + init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE; + } + + /* Don't do any symbol assignments if this is a relocateable link. */ + if (link_info.relocateable) + return; + + /* Glue the assignments into the abs section */ + save = stat_ptr; + + stat_ptr = &(abs_output_section->children); + + for (j = 0; init[j].ptr; j++) + { + long val = init[j].value; + lang_assignment_statement_type *rv; + rv = lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val))); + if (init[j].size == sizeof(short)) + *(short *)init[j].ptr = val; + else if (init[j].size == sizeof(int)) + *(int *)init[j].ptr = val; + else if (init[j].size == sizeof(long)) + *(long *)init[j].ptr = val; + /* This might be a long long or other special type. */ + else if (init[j].size == sizeof(bfd_vma)) + *(bfd_vma *)init[j].ptr = val; + else abort(); + if (j == IMAGEBASEOFF) + image_base_statement = rv; + } + /* Restore the pointer. */ + stat_ptr = save; + + if (pe.FileAlignment > + pe.SectionAlignment) + { + einfo (_("%P: warning, file alignment > section alignment.\n")); + } +} + +/* This is called after the linker script and the command line options + have been read. */ + +static void +gld_${EMULATION_NAME}_after_parse () +{ + /* The Windows libraries are designed for the linker to treat the + entry point as an undefined symbol. Otherwise, the .obj that + defines mainCRTStartup is brought in because it is the first + encountered in libc.lib and it has other symbols in it which will + be pulled in by the link process. To avoid this, we act as + though the user specified -u with the entry point symbol. + + This function is called after the linker script and command line + options have been read, so at this point we know the right entry + point. This function is called before the input files are + opened, so registering the symbol as undefined will make a + difference. */ + + if (entry_symbol) + ldlang_add_undef (entry_symbol); +} + +static struct bfd_link_hash_entry *pe_undef_found_sym; + +static boolean +pe_undef_cdecl_match (h, string) + struct bfd_link_hash_entry *h; + PTR string; +{ + int sl = strlen (string); + if (h->type == bfd_link_hash_defined + && strncmp (h->root.string, string, sl) == 0 + && h->root.string[sl] == '@') + { + pe_undef_found_sym = h; + return false; + } + return true; +} + +static void +pe_fixup_stdcalls () +{ + static int gave_warning_message = 0; + struct bfd_link_hash_entry *undef, *sym; + char *at; + for (undef = link_info.hash->undefs; undef; undef=undef->next) + if (undef->type == bfd_link_hash_undefined) + { + at = strchr (undef->root.string, '@'); + if (at) + { + /* The symbol is a stdcall symbol, so let's look for a cdecl + symbol with the same name and resolve to that */ + char *cname = xstrdup (undef->root.string); + at = strchr (cname, '@'); + *at = 0; + sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1); + if (sym && sym->type == bfd_link_hash_defined) + { + undef->type = bfd_link_hash_defined; + undef->u.def.value = sym->u.def.value; + undef->u.def.section = sym->u.def.section; + if (pe_enable_stdcall_fixup == -1) + { + einfo (_("Warning: resolving %s by linking to %s\n"), + undef->root.string, cname); + if (! gave_warning_message) + { + gave_warning_message = 1; + einfo(_("Use --enable-stdcall-fixup to disable these warnings\n")); + einfo(_("Use --disable-stdcall-fixup to disable these fixups\n")); + } + } + } + } + else + { + /* The symbol is a cdecl symbol, so we look for stdcall + symbols - which means scanning the whole symbol table */ + pe_undef_found_sym = 0; + bfd_link_hash_traverse (link_info.hash, pe_undef_cdecl_match, + (PTR) undef->root.string); + sym = pe_undef_found_sym; + if (sym) + { + undef->type = bfd_link_hash_defined; + undef->u.def.value = sym->u.def.value; + undef->u.def.section = sym->u.def.section; + if (pe_enable_stdcall_fixup == -1) + { + einfo (_("Warning: resolving %s by linking to %s\n"), + undef->root.string, sym->root.string); + if (! gave_warning_message) + { + gave_warning_message = 1; + einfo(_("Use --enable-stdcall-fixup to disable these warnings\n")); + einfo(_("Use --disable-stdcall-fixup to disable these fixups\n")); + } + } + } + } + } +} + +static void +gld_${EMULATION_NAME}_after_open () +{ + /* Pass the wacky PE command line options into the output bfd. + FIXME: This should be done via a function, rather than by + including an internal BFD header. */ + + if (!coff_data (output_bfd)->pe) + einfo (_("%F%P: PE operations on non PE file.\n")); + + pe_data (output_bfd)->pe_opthdr = pe; + pe_data (output_bfd)->dll = init[DLLOFF].value; + +#ifdef TARGET_IS_i386pe + if (pe_enable_stdcall_fixup) /* -1=warn or 1=disable */ + pe_fixup_stdcalls (); + + pe_process_import_defs(output_bfd, &link_info); + if (link_info.shared) + pe_dll_build_sections (output_bfd, &link_info); +#endif + +#ifdef TARGET_IS_armpe + { + /* Find a BFD that can hold the interworking stubs. */ + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info)) + break; + } + } +#endif +} + +static void +gld_${EMULATION_NAME}_before_allocation() +{ +#ifdef TARGET_IS_ppcpe + /* Here we rummage through the found bfds to collect toc information */ + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (!ppc_process_before_allocation (is->the_bfd, &link_info)) + { + /* xgettext:c-format */ + einfo (_("Errors encountered processing file %s\n"), is->filename); + } + } + } + + /* We have seen it all. Allocate it, and carry on */ + ppc_allocate_toc_section (&link_info); +#endif /* TARGET_IS_ppcpe */ + +#ifdef TARGET_IS_armpe + /* FIXME: we should be able to set the size of the interworking stub + section. + + Here we rummage through the found bfds to collect glue + information. FIXME: should this be based on a command line + option? krk@cygnus.com */ + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (! bfd_arm_process_before_allocation + (is->the_bfd, & link_info, support_old_code)) + { + /* xgettext:c-format */ + einfo (_("Errors encountered processing file %s for interworking"), + is->filename); + } + } + } + + /* We have seen it all. Allocate it, and carry on */ + bfd_arm_allocate_interworking_sections (& link_info); +#endif /* TARGET_IS_armpe */ +} + + +/* This is called when an input file isn't recognized as a BFD. We + check here for .DEF files and pull them in automatically. */ + +static int +saw_option(char *option) +{ + int i; + for (i=0; init[i].ptr; i++) + if (strcmp (init[i].symbol, option) == 0) + return init[i].inited; + return 0; +} + +static boolean +gld_${EMULATION_NAME}_unrecognized_file(entry) + lang_input_statement_type *entry; +{ +#ifdef TARGET_IS_i386pe + const char *ext = entry->filename + strlen (entry->filename) - 4; + + if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0) + { + if (pe_def_file == 0) + pe_def_file = def_file_empty (); + def_file_parse (entry->filename, pe_def_file); + if (pe_def_file) + { + int i, buflen=0, len; + char *buf; + for (i=0; i<pe_def_file->num_exports; i++) + { + len = strlen(pe_def_file->exports[i].internal_name); + if (buflen < len+2) + buflen = len+2; + } + buf = (char *) xmalloc (buflen); + for (i=0; i<pe_def_file->num_exports; i++) + { + struct bfd_link_hash_entry *h; + sprintf(buf, "_%s", pe_def_file->exports[i].internal_name); + + h = bfd_link_hash_lookup (link_info.hash, buf, true, true, true); + if (h == (struct bfd_link_hash_entry *) NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + if (h->type == bfd_link_hash_new) + { + h->type = bfd_link_hash_undefined; + h->u.undef.abfd = NULL; + bfd_link_add_undef (link_info.hash, h); + } + } + free (buf); + + /* def_file_print (stdout, pe_def_file); */ + if (pe_def_file->is_dll == 1) + link_info.shared = 1; + + if (pe_def_file->base_address != (bfd_vma)(-1)) + { + pe.ImageBase = + pe_data (output_bfd)->pe_opthdr.ImageBase = + init[IMAGEBASEOFF].value = pe_def_file->base_address; + init[IMAGEBASEOFF].inited = 1; + if (image_base_statement) + image_base_statement->exp = + exp_assop ('=', "__image_base__", exp_intop (pe.ImageBase)); + } + +#if 0 + /* Not sure if these *should* be set */ + if (pe_def_file->version_major != -1) + { + pe.MajorImageVersion = pe_def_file->version_major; + pe.MinorImageVersion = pe_def_file->version_minor; + } +#endif + if (pe_def_file->stack_reserve != -1 + && ! saw_option ("__size_of_stack_reserve__")) + { + pe.SizeOfStackReserve = pe_def_file->stack_reserve; + if (pe_def_file->stack_commit != -1) + pe.SizeOfStackCommit = pe_def_file->stack_commit; + } + if (pe_def_file->heap_reserve != -1 + && ! saw_option ("__size_of_heap_reserve__")) + { + pe.SizeOfHeapReserve = pe_def_file->heap_reserve; + if (pe_def_file->heap_commit != -1) + pe.SizeOfHeapCommit = pe_def_file->heap_commit; + } + return true; + } + } +#endif + return false; + +} + +static boolean +gld_${EMULATION_NAME}_recognized_file(entry) + lang_input_statement_type *entry; +{ +#ifdef TARGET_IS_i386pe + if (bfd_get_format (entry->the_bfd) == bfd_object) + { + const char *ext = entry->filename + strlen (entry->filename) - 4; + if (strcmp (ext, ".dll") == 0 || strcmp (ext, ".DLL") == 0) + return pe_implied_import_dll (entry->filename); + } +#endif + return false; +} + +static void +gld_${EMULATION_NAME}_finish () +{ +#ifdef TARGET_IS_i386pe + if (link_info.shared) + { + pe_dll_fill_sections (output_bfd, &link_info); + if (pe_implib_filename) + pe_dll_generate_implib (pe_def_file, pe_implib_filename); + } + if (pe_out_def_filename) + pe_dll_generate_def_file (pe_out_def_filename); +#endif +} + + +/* Place an orphan section. + + We use this to put sections in a reasonable place in the file, and + to ensure that they are aligned as required. + + We handle grouped sections here as well. A section named .foo$nn + goes into the output section .foo. All grouped sections are sorted + by name. + + Grouped sections for the default sections are handled by the + default linker script using wildcards, and are sorted by + sort_sections. */ + +static asection *hold_section; +static char *hold_section_name; +static lang_output_section_statement_type *hold_use; +static lang_output_section_statement_type *hold_text; +static lang_output_section_statement_type *hold_rdata; +static lang_output_section_statement_type *hold_data; +static lang_output_section_statement_type *hold_bss; + +/* Place an orphan section. We use this to put random SHF_ALLOC + sections in the right segment. */ + +/*ARGSUSED*/ +static boolean +gld_${EMULATION_NAME}_place_orphan (file, s) + lang_input_statement_type *file; + asection *s; +{ + const char *secname; + char *dollar; + + if ((s->flags & SEC_ALLOC) == 0) + return false; + + secname = bfd_get_section_name (s->owner, s); + + /* Look through the script to see where to place this section. */ + + hold_section = s; + + hold_section_name = xstrdup (secname); + dollar = strchr (hold_section_name, '$'); + if (dollar != NULL) + *dollar = '\0'; + + hold_use = NULL; + lang_for_each_statement (gld${EMULATION_NAME}_place_section); + + if (hold_use == NULL) + { + lang_output_section_statement_type *place; + char *outsecname; + asection *snew, **pps; + lang_statement_list_type *old; + lang_statement_list_type add; + etree_type *address; + + /* Try to put the new output section in a reasonable place based + on the section name and section flags. */ + place = NULL; + if ((s->flags & SEC_HAS_CONTENTS) == 0 + && hold_bss != NULL) + place = hold_bss; + else if ((s->flags & SEC_READONLY) == 0 + && hold_data != NULL) + place = hold_data; + else if ((s->flags & SEC_CODE) == 0 + && (s->flags & SEC_READONLY) != 0 + && hold_rdata != NULL) + place = hold_rdata; + else if ((s->flags & SEC_READONLY) != 0 + && hold_text != NULL) + place = hold_text; + + /* Choose a unique name for the section. This will be needed if + the same section name appears in the input file with + different loadable or allocateable characteristics. */ + outsecname = xstrdup (hold_section_name); + if (bfd_get_section_by_name (output_bfd, outsecname) != NULL) + { + unsigned int len; + char *newname; + unsigned int i; + + len = strlen (outsecname); + newname = xmalloc (len + 5); + strcpy (newname, outsecname); + i = 0; + do + { + sprintf (newname + len, "%d", i); + ++i; + } + while (bfd_get_section_by_name (output_bfd, newname) != NULL); + + free (outsecname); + outsecname = newname; + } + + /* We don't want to free OUTSECNAME, as it may get attached to + the output section statement. */ + + /* Create the section in the output file, and put it in the + right place. This shuffling is to make the output file look + neater. */ + snew = bfd_make_section (output_bfd, outsecname); + if (snew == NULL) + einfo ("%P%F: output format %s cannot represent section called %s\n", + output_bfd->xvec->name, outsecname); + if (place != NULL && place->bfd_section != NULL) + { + for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) + ; + *pps = snew->next; + snew->next = place->bfd_section->next; + place->bfd_section->next = snew; + } + + /* Start building a list of statements for this section. */ + old = stat_ptr; + stat_ptr = &add; + lang_list_init (stat_ptr); + + if (link_info.relocateable) + address = NULL; + else + { + /* All sections in an executable must be aligned to a page + boundary. */ + address = exp_unop (ALIGN_K, + exp_nameop (NAME, "__section_alignment__")); + } + + lang_enter_output_section_statement (outsecname, address, 0, + (bfd_vma) 0, + (etree_type *) NULL, + (etree_type *) NULL, + (etree_type *) NULL); + + hold_use = lang_output_section_statement_lookup (outsecname); + + lang_leave_output_section_statement + ((bfd_vma) 0, "*default*", + (struct lang_output_section_phdr_list *) NULL); + + /* Now stick the new statement list right after PLACE. */ + if (place != NULL) + { + *add.tail = place->header.next; + place->header.next = add.head; + } + + stat_ptr = old; + } + + if (dollar == NULL) + wild_doit (&hold_use->children, s, hold_use, file); + else + { + lang_statement_union_type **pl; + boolean found_dollar; + lang_statement_list_type list; + + /* The section name has a '$'. Sort it with the other '$' + sections. */ + + found_dollar = false; + for (pl = &hold_use->children.head; *pl != NULL; pl = &(*pl)->next) + { + lang_input_section_type *ls; + const char *lname; + + if ((*pl)->header.type != lang_input_section_enum) + continue; + + ls = &(*pl)->input_section; + + lname = bfd_get_section_name (ls->ifile->the_bfd, ls->section); + if (strchr (lname, '$') == NULL) + { + if (found_dollar) + break; + } + else + { + found_dollar = true; + if (strcmp (secname, lname) < 0) + break; + } + } + + lang_list_init (&list); + wild_doit (&list, s, hold_use, file); + if (list.head != NULL) + { + ASSERT (list.head->next == NULL); + list.head->next = *pl; + *pl = list.head; + } + } + + free (hold_section_name); + + return true; +} + +static void +gld${EMULATION_NAME}_place_section (s) + lang_statement_union_type *s; +{ + lang_output_section_statement_type *os; + + if (s->header.type != lang_output_section_statement_enum) + return; + + os = &s->output_section_statement; + + if (strcmp (os->name, hold_section_name) == 0 + && os->bfd_section != NULL + && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC)) + == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC)))) + hold_use = os; + + if (strcmp (os->name, ".text") == 0) + hold_text = os; + else if (strcmp (os->name, ".rdata") == 0) + hold_rdata = os; + else if (strcmp (os->name, ".data") == 0) + hold_data = os; + else if (strcmp (os->name, ".bss") == 0) + hold_bss = os; +} + +static char * +gld_${EMULATION_NAME}_get_script(isfile) + int *isfile; +EOF +# Scripts compiled in. +# sed commands to quote an ld script as a C string. +sc="-f ${srcdir}/emultempl/stringify.sed" + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +EOF +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c + +cat >>e${EMULATION_NAME}.c <<EOF + + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld_${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + gld_${EMULATION_NAME}_after_parse, + gld_${EMULATION_NAME}_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gld_${EMULATION_NAME}_before_allocation, + gld_${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}", + gld_${EMULATION_NAME}_finish, /* finish */ + NULL, /* create output section statements */ + NULL, /* open dynamic archive */ + gld_${EMULATION_NAME}_place_orphan, + gld_${EMULATION_NAME}_set_symbols, + gld_${EMULATION_NAME}_parse_args, + gld_${EMULATION_NAME}_unrecognized_file, + gld_${EMULATION_NAME}_list_options, + gld_${EMULATION_NAME}_recognized_file +}; +EOF diff --git a/ld/emultempl/stringify.sed b/ld/emultempl/stringify.sed new file mode 100644 index 0000000..a526d3f --- /dev/null +++ b/ld/emultempl/stringify.sed @@ -0,0 +1,4 @@ +s/["\\]/\\&/g +s/$/\\n\\/ +1 s/^/"/ +$ s/$/n"/ diff --git a/ld/emultempl/sunos.em b/ld/emultempl/sunos.em new file mode 100644 index 0000000..8e9599c --- /dev/null +++ b/ld/emultempl/sunos.em @@ -0,0 +1,1037 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* SunOS emulation code for ${EMULATION_NAME} + Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. + Written by Steve Chamberlain <sac@cygnus.com> + SunOS shared library support by Ian Lance Taylor <ian@cygnus.com> + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_${EMULATION_NAME} + +#include <ctype.h> + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libiberty.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" + +#ifdef HAVE_DIRENT_H +# include <dirent.h> +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# ifdef HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# ifdef HAVE_NDIR_H +# include <ndir.h> +# endif +#endif + +static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static void gld${EMULATION_NAME}_set_symbols PARAMS ((void)); +static void gld${EMULATION_NAME}_create_output_section_statements + PARAMS ((void)); +static void gld${EMULATION_NAME}_find_so + PARAMS ((lang_input_statement_type *)); +static char *gld${EMULATION_NAME}_search_dir + PARAMS ((const char *, const char *, boolean *)); +static void gld${EMULATION_NAME}_after_open PARAMS ((void)); +static void gld${EMULATION_NAME}_check_needed + PARAMS ((lang_input_statement_type *)); +static boolean gld${EMULATION_NAME}_search_needed + PARAMS ((const char *, const char *)); +static boolean gld${EMULATION_NAME}_try_needed + PARAMS ((const char *, const char *)); +static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); +static void gld${EMULATION_NAME}_find_assignment + PARAMS ((lang_statement_union_type *)); +static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *)); +static void gld${EMULATION_NAME}_count_need + PARAMS ((lang_input_statement_type *)); +static void gld${EMULATION_NAME}_set_need + PARAMS ((lang_input_statement_type *)); +static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); + +static void +gld${EMULATION_NAME}_before_parse() +{ + ldfile_output_architecture = bfd_arch_${ARCH}; + config.dynamic_link = true; + config.has_shared = true; +} + +/* This is called after the command line arguments have been parsed, + but before the linker script has been read. If this is a native + linker, we add the directories in LD_LIBRARY_PATH to the search + list. */ + +static void +gld${EMULATION_NAME}_set_symbols () +{ +EOF +if [ "x${host}" = "x${target}" ] ; then + if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then +cat >>e${EMULATION_NAME}.c <<EOF + const char *env; + + env = (const char *) getenv ("LD_LIBRARY_PATH"); + if (env != NULL) + { + char *l; + + l = xstrdup (env); + while (1) + { + char *c; + + c = strchr (l, ':'); + if (c != NULL) + *c++ = '\0'; + if (*l != '\0') + ldfile_add_library_path (l, false); + if (c == NULL) + break; + l = c; + } + } +EOF + fi +fi +cat >>e${EMULATION_NAME}.c <<EOF +} + +/* Despite the name, we use this routine to search for dynamic + libraries. On SunOS this requires a directory search. We need to + find the .so file with the highest version number. The user may + restrict the major version by saying, e.g., -lc.1. Also, if we + find a .so file, we need to look for a the same file after + replacing .so with .sa; if it exists, it will be an archive which + provide some initializations for data symbols, and we need to + search it after including the .so file. */ + +static void +gld${EMULATION_NAME}_create_output_section_statements () +{ + lang_for_each_input_file (gld${EMULATION_NAME}_find_so); +} + +/* Search the directory for a .so file for each library search. */ + +static void +gld${EMULATION_NAME}_find_so (inp) + lang_input_statement_type *inp; +{ + search_dirs_type *search; + char *found = NULL; + char *alc; + struct stat st; + + if (! inp->search_dirs_flag + || ! inp->is_archive + || ! inp->dynamic) + return; + + ASSERT (strncmp (inp->local_sym_name, "-l", 2) == 0); + + for (search = search_head; search != NULL; search = search->next) + { + boolean found_static; + + found = gld${EMULATION_NAME}_search_dir (search->name, inp->filename, + &found_static); + if (found != NULL || found_static) + break; + } + + if (found == NULL) + { + /* We did not find a matching .so file. This isn't an error, + since there might still be a matching .a file, which will be + found by the usual search. */ + return; + } + + /* Replace the filename with the one we have found. */ + alc = (char *) xmalloc (strlen (search->name) + strlen (found) + 2); + sprintf (alc, "%s/%s", search->name, found); + inp->filename = alc; + + /* Turn off the search_dirs_flag to prevent ldfile_open_file from + searching for this file again. */ + inp->search_dirs_flag = false; + + free (found); + + /* Now look for the same file name, but with .sa instead of .so. If + found, add it to the list of input files. */ + alc = (char *) xmalloc (strlen (inp->filename) + 1); + strcpy (alc, inp->filename); + strstr (alc + strlen (search->name), ".so")[2] = 'a'; + if (stat (alc, &st) != 0) + free (alc); + else + { + lang_input_statement_type *sa; + + /* Add the .sa file to the statement list just before the .so + file. This is really a hack. */ + sa = ((lang_input_statement_type *) + xmalloc (sizeof (lang_input_statement_type))); + *sa = *inp; + + inp->filename = alc; + inp->local_sym_name = alc; + + inp->header.next = (lang_statement_union_type *) sa; + inp->next_real_file = (lang_statement_union_type *) sa; + } +} + +/* Search a directory for a .so file. */ + +static char * +gld${EMULATION_NAME}_search_dir (dirname, filename, found_static) + const char *dirname; + const char *filename; + boolean *found_static; +{ + int force_maj, force_min; + const char *dot; + unsigned int len; + char *alc; + char *found; + int max_maj, max_min; + DIR *dir; + struct dirent *entry; + unsigned int dirnamelen; + char *full_path; + int statval; + struct stat st; + + *found_static = false; + + force_maj = -1; + force_min = -1; + dot = strchr (filename, '.'); + if (dot == NULL) + { + len = strlen (filename); + alc = NULL; + } + else + { + force_maj = atoi (dot + 1); + + len = dot - filename; + alc = (char *) xmalloc (len + 1); + strncpy (alc, filename, len); + alc[len] = '\0'; + filename = alc; + + dot = strchr (dot + 1, '.'); + if (dot != NULL) + force_min = atoi (dot + 1); + } + + found = NULL; + max_maj = max_min = 0; + + dir = opendir (dirname); + if (dir == NULL) + return NULL; + dirnamelen = strlen (dirname); + + while ((entry = readdir (dir)) != NULL) + { + const char *s; + int found_maj, found_min; + + if (strncmp (entry->d_name, "lib", 3) != 0 + || strncmp (entry->d_name + 3, filename, len) != 0) + continue; + + if (dot == NULL + && strcmp (entry->d_name + 3 + len, ".a") == 0) + { + *found_static = true; + continue; + } + + /* We accept libfoo.so without a version number, even though the + native linker does not. This is more convenient for packages + which just generate .so files for shared libraries, as on ELF + systems. */ + if (strncmp (entry->d_name + 3 + len, ".so", 3) != 0) + continue; + if (entry->d_name[6 + len] == '\0') + ; + else if (entry->d_name[6 + len] == '.' + && isdigit ((unsigned char) entry->d_name[7 + len])) + ; + else + continue; + + for (s = entry->d_name + 6 + len; *s != '\0'; s++) + if (*s != '.' && ! isdigit ((unsigned char) *s)) + break; + if (*s != '\0') + continue; + + /* We've found a .so file. Work out the major and minor + version numbers. */ + found_maj = 0; + found_min = 0; + sscanf (entry->d_name + 3 + len, ".so.%d.%d", + &found_maj, &found_min); + + if ((force_maj != -1 && force_maj != found_maj) + || (force_min != -1 && force_min != found_min)) + continue; + + /* Make sure the file really exists (ignore broken symlinks). */ + full_path = xmalloc (dirnamelen + 1 + strlen (entry->d_name) + 1); + sprintf (full_path, "%s/%s", dirname, entry->d_name); + statval = stat (full_path, &st); + free (full_path); + if (statval != 0) + continue; + + /* We've found a match for the name we are searching for. See + if this is the version we should use. If the major and minor + versions match, we use the last entry in alphabetical order; + I don't know if this is how SunOS distinguishes libc.so.1.8 + from libc.so.1.8.1, but it ought to suffice. */ + if (found == NULL + || (found_maj > max_maj) + || (found_maj == max_maj + && (found_min > max_min + || (found_min == max_min + && strcmp (entry->d_name, found) > 0)))) + { + if (found != NULL) + free (found); + found = (char *) xmalloc (strlen (entry->d_name) + 1); + strcpy (found, entry->d_name); + max_maj = found_maj; + max_min = found_min; + } + } + + closedir (dir); + + if (alc != NULL) + free (alc); + + return found; +} + +/* These variables are required to pass information back and forth + between after_open and check_needed. */ + +static struct bfd_link_needed_list *global_needed; +static boolean global_found; + +/* This is called after all the input files have been opened. */ + +static void +gld${EMULATION_NAME}_after_open () +{ + struct bfd_link_needed_list *needed, *l; + + /* We only need to worry about this when doing a final link. */ + if (link_info.relocateable || link_info.shared) + return; + + /* Get the list of files which appear in ld_need entries in dynamic + objects included in the link. For each such file, we want to + track down the corresponding library, and include the symbol + table in the link. This is what the runtime dynamic linker will + do. Tracking the files down here permits one dynamic object to + include another without requiring special action by the person + doing the link. Note that the needed list can actually grow + while we are stepping through this loop. */ + needed = bfd_sunos_get_needed_list (output_bfd, &link_info); + for (l = needed; l != NULL; l = l->next) + { + struct bfd_link_needed_list *ll; + const char *lname; + search_dirs_type *search; + + lname = l->name; + + /* If we've already seen this file, skip it. */ + for (ll = needed; ll != l; ll = ll->next) + if (strcmp (ll->name, lname) == 0) + break; + if (ll != l) + continue; + + /* See if this file was included in the link explicitly. */ + global_needed = l; + global_found = false; + lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); + if (global_found) + continue; + + if (strncmp (lname, "-l", 2) != 0) + { + bfd *abfd; + + abfd = bfd_openr (lname, bfd_get_target (output_bfd)); + if (abfd != NULL) + { + if (! bfd_check_format (abfd, bfd_object)) + { + (void) bfd_close (abfd); + abfd = NULL; + } + } + if (abfd != NULL) + { + if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) + { + (void) bfd_close (abfd); + abfd = NULL; + } + } + if (abfd != NULL) + { + /* We've found the needed dynamic object. */ + if (! bfd_link_add_symbols (abfd, &link_info)) + einfo ("%F%B: could not read symbols: %E\n", abfd); + } + else + { + einfo ("%P: warning: %s, needed by %B, not found\n", + lname, l->by); + } + + continue; + } + + lname += 2; + + /* We want to search for the file in the same way that the + dynamic linker will search. That means that we want to use + rpath_link, rpath or -L, then the environment variable + LD_LIBRARY_PATH (native only), then (if rpath was used) the + linker script LIB_SEARCH_DIRS. */ + if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link, + lname)) + continue; + if (command_line.rpath != NULL) + { + if (gld${EMULATION_NAME}_search_needed (command_line.rpath, lname)) + continue; + } + else + { + for (search = search_head; search != NULL; search = search->next) + if (gld${EMULATION_NAME}_try_needed (search->name, lname)) + break; + if (search != NULL) + continue; + } +EOF +if [ "x${host}" = "x${target}" ] ; then + if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then +cat >>e${EMULATION_NAME}.c <<EOF + { + const char *lib_path; + + lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); + if (gld${EMULATION_NAME}_search_needed (lib_path, lname)) + continue; + } +EOF + fi +fi +cat >>e${EMULATION_NAME}.c <<EOF + if (command_line.rpath != NULL) + { + for (search = search_head; search != NULL; search = search->next) + { + if (search->cmdline) + continue; + if (gld${EMULATION_NAME}_try_needed (search->name, lname)) + break; + } + if (search != NULL) + continue; + } + + einfo ("%P: warning: %s, needed by %B, not found\n", + l->name, l->by); + } +} + +/* Search for a needed file in a path. */ + +static boolean +gld${EMULATION_NAME}_search_needed (path, name) + const char *path; + const char *name; +{ + const char *s; + + if (path == NULL || *path == '\0') + return false; + while (1) + { + const char *dir; + char *dircopy; + + s = strchr (path, ':'); + if (s == NULL) + { + dircopy = NULL; + dir = path; + } + else + { + dircopy = (char *) xmalloc (s - path + 1); + memcpy (dircopy, path, s - path); + dircopy[s - path] = '\0'; + dir = dircopy; + } + + if (gld${EMULATION_NAME}_try_needed (dir, name)) + return true; + + if (dircopy != NULL) + free (dircopy); + + if (s == NULL) + break; + path = s + 1; + } + + return false; +} + +/* This function is called for each possible directory for a needed + dynamic object. */ + +static boolean +gld${EMULATION_NAME}_try_needed (dir, name) + const char *dir; + const char *name; +{ + char *file; + char *alc; + boolean ignore; + bfd *abfd; + + file = gld${EMULATION_NAME}_search_dir (dir, name, &ignore); + if (file == NULL) + return false; + + alc = (char *) xmalloc (strlen (dir) + strlen (file) + 2); + sprintf (alc, "%s/%s", dir, file); + free (file); + abfd = bfd_openr (alc, bfd_get_target (output_bfd)); + if (abfd == NULL) + return false; + if (! bfd_check_format (abfd, bfd_object)) + { + (void) bfd_close (abfd); + return false; + } + if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) + { + (void) bfd_close (abfd); + return false; + } + + /* We've found the needed dynamic object. */ + + /* Add this file into the symbol table. */ + if (! bfd_link_add_symbols (abfd, &link_info)) + einfo ("%F%B: could not read symbols: %E\n", abfd); + + return true; +} + +/* See if we have already included a needed object in the link. This + does not have to be precise, as it does no harm to include a + dynamic object more than once. */ + +static void +gld${EMULATION_NAME}_check_needed (s) + lang_input_statement_type *s; +{ + if (s->filename == NULL) + return; + if (strncmp (global_needed->name, "-l", 2) != 0) + { + if (strcmp (s->filename, global_needed->name) == 0) + global_found = true; + } + else + { + const char *sname, *lname; + const char *sdot, *ldot; + int lmaj, lmin, smaj, smin; + + lname = global_needed->name + 2; + + sname = strrchr (s->filename, '/'); + if (sname == NULL) + sname = s->filename; + else + ++sname; + + if (strncmp (sname, "lib", 3) != 0) + return; + sname += 3; + + ldot = strchr (lname, '.'); + if (ldot == NULL) + ldot = lname + strlen (lname); + + sdot = strstr (sname, ".so."); + if (sdot == NULL) + return; + + if (sdot - sname != ldot - lname + || strncmp (lname, sname, sdot - sname) != 0) + return; + + lmaj = lmin = -1; + sscanf (ldot, ".%d.%d", &lmaj, &lmin); + smaj = smin = -1; + sscanf (sdot, ".so.%d.%d", &smaj, &smin); + if ((smaj != lmaj && smaj != -1 && lmaj != -1) + || (smin != lmin && smin != -1 && lmin != -1)) + return; + + global_found = true; + } +} + +/* We need to use static variables to pass information around the call + to lang_for_each_statement. Ick. */ + +static const char *find_assign; +static boolean found_assign; + +/* We need to use static variables to pass information around the call + to lang_for_each_input_file. Ick. */ + +static bfd_size_type need_size; +static bfd_size_type need_entries; +static bfd_byte *need_contents; +static bfd_byte *need_pinfo; +static bfd_byte *need_pnames; + +/* The size of one entry in the .need section, not including the file + name. */ + +#define NEED_ENTRY_SIZE (16) + +/* This is called after the sections have been attached to output + sections, but before any sizes or addresses have been set. */ + +static void +gld${EMULATION_NAME}_before_allocation () +{ + struct bfd_link_hash_entry *hdyn = NULL; + asection *sneed; + asection *srules; + asection *sdyn; + + /* The SunOS native linker creates a shared library whenever there + are any undefined symbols in a link, unless -e is used. This is + pretty weird, but we are compatible. */ + if (! link_info.shared && ! link_info.relocateable && ! entry_from_cmdline) + { + struct bfd_link_hash_entry *h; + + for (h = link_info.hash->undefs; h != NULL; h = h->next) + { + if (h->type == bfd_link_hash_undefined + && h->u.undef.abfd != NULL + && (h->u.undef.abfd->flags & DYNAMIC) == 0 + && strcmp (h->root.string, "__DYNAMIC") != 0 + && strcmp (h->root.string, "__GLOBAL_OFFSET_TABLE_") != 0) + { + find_assign = h->root.string; + found_assign = false; + lang_for_each_statement (gld${EMULATION_NAME}_find_assignment); + if (! found_assign) + { + link_info.shared = true; + break; + } + } + } + } + + if (link_info.shared) + { + lang_output_section_statement_type *os; + + /* Set the .text section to start at 0x20, not 0x2020. FIXME: + This is too magical. */ + os = lang_output_section_statement_lookup (".text"); + if (os->addr_tree == NULL) + os->addr_tree = exp_intop (0x20); + } + + /* We need to create a __DYNAMIC symbol. We don't do this in the + linker script because we want to set the value to the start of + the dynamic section if there is one, or to zero if there isn't + one. We need to create the symbol before calling + size_dynamic_sections, although we can't set the value until + afterward. */ + if (! link_info.relocateable) + { + hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", true, false, + false); + if (hdyn == NULL) + einfo ("%P%F: bfd_link_hash_lookup: %E\n"); + if (! bfd_sunos_record_link_assignment (output_bfd, &link_info, + "__DYNAMIC")) + einfo ("%P%F: failed to record assignment to __DYNAMIC: %E\n"); + } + + /* If we are going to make any variable assignments, we need to let + the backend linker know about them in case the variables are + referred to by dynamic objects. */ + lang_for_each_statement (gld${EMULATION_NAME}_find_assignment); + + /* Let the backend linker work out the sizes of any sections + required by dynamic linking. */ + if (! bfd_sunos_size_dynamic_sections (output_bfd, &link_info, &sdyn, + &sneed, &srules)) + einfo ("%P%F: failed to set dynamic section sizes: %E\n"); + + if (sneed != NULL) + { + /* Set up the .need section. See the description of the ld_need + field in include/aout/sun4.h. */ + + need_entries = 0; + need_size = 0; + + lang_for_each_input_file (gld${EMULATION_NAME}_count_need); + + /* We should only have a .need section if we have at least one + dynamic object. */ + ASSERT (need_entries != 0); + + sneed->_raw_size = need_size; + sneed->contents = (bfd_byte *) xmalloc (need_size); + + need_contents = sneed->contents; + need_pinfo = sneed->contents; + need_pnames = sneed->contents + need_entries * 16; + + lang_for_each_input_file (gld${EMULATION_NAME}_set_need); + + ASSERT ((bfd_size_type) (need_pnames - sneed->contents) == need_size); + } + + if (srules != NULL) + { + /* Set up the .rules section. This is just a PATH like string + of the -L arguments given on the command line. We permit the + user to specify the directories using the -rpath command line + option. */ + if (command_line.rpath) + { + srules->_raw_size = strlen (command_line.rpath); + srules->contents = (bfd_byte *) command_line.rpath; + } + else + { + unsigned int size; + search_dirs_type *search; + + size = 0; + for (search = search_head; search != NULL; search = search->next) + if (search->cmdline) + size += strlen (search->name) + 1; + srules->_raw_size = size; + if (size > 0) + { + char *p; + + srules->contents = (bfd_byte *) xmalloc (size); + p = (char *) srules->contents; + *p = '\0'; + for (search = search_head; search != NULL; search = search->next) + { + if (search->cmdline) + { + if (p != (char *) srules->contents) + *p++ = ':'; + strcpy (p, search->name); + p += strlen (p); + } + } + } + } + } + + /* We must assign a value to __DYNAMIC. It should be zero if we are + not doing a dynamic link, or the start of the .dynamic section if + we are doing one. */ + if (! link_info.relocateable) + { + hdyn->type = bfd_link_hash_defined; + hdyn->u.def.value = 0; + if (sdyn != NULL) + hdyn->u.def.section = sdyn; + else + hdyn->u.def.section = bfd_abs_section_ptr; + } +} + +/* This is called by the before_allocation routine via + lang_for_each_statement. It does one of two things: if the + variable find_assign is set, it sets found_assign if it finds an + assignment to that variable; otherwise it tells the backend linker + about all assignment statements, in case they are assignments to + symbols which are referred to by dynamic objects. */ + +static void +gld${EMULATION_NAME}_find_assignment (s) + lang_statement_union_type *s; +{ + if (s->header.type == lang_assignment_statement_enum + && (find_assign == NULL || ! found_assign)) + gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); +} + +/* Look through an expression for an assignment statement. */ + +static void +gld${EMULATION_NAME}_find_exp_assignment (exp) + etree_type *exp; +{ + switch (exp->type.node_class) + { + case etree_assign: + if (find_assign != NULL) + { + if (strcmp (find_assign, exp->assign.dst) == 0) + found_assign = true; + return; + } + + if (strcmp (exp->assign.dst, ".") != 0) + { + if (! bfd_sunos_record_link_assignment (output_bfd, &link_info, + exp->assign.dst)) + einfo ("%P%F: failed to record assignment to %s: %E\n", + exp->assign.dst); + } + gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src); + break; + + case etree_binary: + gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs); + gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs); + break; + + case etree_trinary: + gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond); + gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs); + gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs); + break; + + case etree_unary: + gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child); + break; + + default: + break; + } +} + +/* Work out the size of the .need section, and the number of entries. + The backend will set the ld_need field of the dynamic linking + information to point to the .need section. See include/aout/sun4.h + for more information. */ + +static void +gld${EMULATION_NAME}_count_need (inp) + lang_input_statement_type *inp; +{ + if (inp->the_bfd != NULL + && (inp->the_bfd->flags & DYNAMIC) != 0) + { + ++need_entries; + need_size += NEED_ENTRY_SIZE; + if (! inp->is_archive) + need_size += strlen (inp->filename) + 1; + else + { + ASSERT (inp->local_sym_name[0] == '-' + && inp->local_sym_name[1] == 'l'); + need_size += strlen (inp->local_sym_name + 2) + 1; + } + } +} + +/* Fill in the contents of the .need section. */ + +static void +gld${EMULATION_NAME}_set_need (inp) + lang_input_statement_type *inp; +{ + if (inp->the_bfd != NULL + && (inp->the_bfd->flags & DYNAMIC) != 0) + { + bfd_size_type c; + + /* To really fill in the .need section contents, we need to know + the final file position of the section, but we don't. + Instead, we use offsets, and rely on the BFD backend to + finish the section up correctly. FIXME: Talk about lack of + referential locality. */ + bfd_put_32 (output_bfd, need_pnames - need_contents, need_pinfo); + if (! inp->is_archive) + { + bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 4); + bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 8); + bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 10); + strcpy (need_pnames, inp->filename); + } + else + { + char *verstr; + int maj, min; + + bfd_put_32 (output_bfd, (bfd_vma) 0x80000000, need_pinfo + 4); + maj = 0; + min = 0; + verstr = strstr (inp->filename, ".so."); + if (verstr != NULL) + sscanf (verstr, ".so.%d.%d", &maj, &min); + bfd_put_16 (output_bfd, (bfd_vma) maj, need_pinfo + 8); + bfd_put_16 (output_bfd, (bfd_vma) min, need_pinfo + 10); + strcpy (need_pnames, inp->local_sym_name + 2); + } + + c = (need_pinfo - need_contents) / NEED_ENTRY_SIZE; + if (c + 1 >= need_entries) + bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 12); + else + bfd_put_32 (output_bfd, (bfd_vma) (c + 1) * NEED_ENTRY_SIZE, + need_pinfo + 12); + + need_pinfo += NEED_ENTRY_SIZE; + need_pnames += strlen (need_pnames) + 1; + } +} + +static char * +gld${EMULATION_NAME}_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc='s/["\\]/\\&/g +s/$/\\n\\/ +1s/^/"/ +$s/$/n"/ +' + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; + else if (link_info.relocateable == true) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; + else if (!config.text_read_only) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; + else if (!config.magic_demand_paged) + return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; + else + return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; +} +EOF + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <<EOF +{ + *isfile = 1; + + if (link_info.relocateable == true && config.build_constructors == true) + return "ldscripts/${EMULATION_NAME}.xu"; + else if (link_info.relocateable == true) + return "ldscripts/${EMULATION_NAME}.xr"; + else if (!config.text_read_only) + return "ldscripts/${EMULATION_NAME}.xbn"; + else if (!config.magic_demand_paged) + return "ldscripts/${EMULATION_NAME}.xn"; + else + return "ldscripts/${EMULATION_NAME}.x"; +} +EOF + +fi + +cat >>e${EMULATION_NAME}.c <<EOF + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +{ + gld${EMULATION_NAME}_before_parse, + syslib_default, + hll_default, + after_parse_default, + gld${EMULATION_NAME}_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gld${EMULATION_NAME}_before_allocation, + gld${EMULATION_NAME}_get_script, + "${EMULATION_NAME}", + "${OUTPUT_FORMAT}", + NULL, /* finish */ + gld${EMULATION_NAME}_create_output_section_statements, + NULL, /* open_dynamic_library */ + NULL, /* place_orphan */ + gld${EMULATION_NAME}_set_symbols +}; +EOF diff --git a/ld/emultempl/vanilla.em b/ld/emultempl/vanilla.em new file mode 100644 index 0000000..04e36fb --- /dev/null +++ b/ld/emultempl/vanilla.em @@ -0,0 +1,69 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <<EOF +/* A vanilla emulation with no defaults + Copyright (C) 1991, 1993 Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" + + +#include "ld.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldmain.h" + +static void vanilla_before_parse() +{ +} + +static void +vanilla_set_output_arch() +{ + /* Set the output architecture and machine if possible */ + unsigned long machine = 0; + bfd_set_arch_mach(output_bfd, ldfile_output_architecture, machine); +} + +static char * +vanilla_get_script(isfile) + int *isfile; +{ + *isfile = 0; + return ""; +} + +struct ld_emulation_xfer_struct ld_vanilla_emulation = +{ + vanilla_before_parse, + syslib_default, + hll_default, + after_parse_default, + after_open_default, + after_allocation_default, + vanilla_set_output_arch, + ldemul_default_target, + before_allocation_default, + vanilla_get_script, + "vanilla", + "a.out-sunos-big" +}; +EOF diff --git a/ld/gen-doc.texi b/ld/gen-doc.texi new file mode 100644 index 0000000..3a36727 --- /dev/null +++ b/ld/gen-doc.texi @@ -0,0 +1,13 @@ +@c ------------------------------ CONFIGURATION VARS: +@c 1. Inclusiveness of this manual +@set GENERIC + +@c 2. Specific target machines +@set H8300 +@set I960 + +@c 3. Properties of this configuration +@clear SingleFormat +@set UsesEnvVars +@c ------------------------------ end CONFIGURATION VARS + diff --git a/ld/genscripts.sh b/ld/genscripts.sh new file mode 100755 index 0000000..eea5401 --- /dev/null +++ b/ld/genscripts.sh @@ -0,0 +1,133 @@ +#!/bin/sh +# genscripts.sh - generate the ld-emulation-target specific files +# +# Usage: genscripts.sh srcdir libdir host target target_alias \ +# default_emulation native_lib_dirs this_emulation tool_dir +# +# Sample usage: +# genscripts.sh /djm/ld-devo/devo/ld /usr/local/lib sparc-sun-sunos4.1.3 \ +# sparc-sun-sunos4.1.3 sparc-sun-sunos4.1.3 sun4 "" sun3 sparc-sun-sunos4.1.3 +# produces sun3.x sun3.xbn sun3.xn sun3.xr sun3.xu em_sun3.c + +srcdir=$1 +libdir=$2 +host=$3 +target=$4 +target_alias=$5 +DEFAULT_EMULATION=$6 +NATIVE_LIB_DIRS=$7 +EMULATION_NAME=$8 +tool_lib=`echo ${libdir} | sed -e 's|/lib$||'`/${9-$target_alias}/lib + +# Include the emulation-specific parameters: +. ${srcdir}/emulparams/${EMULATION_NAME}.sh + +if test -d ldscripts; then + true +else + mkdir ldscripts +fi + +# Set the library search path, for libraries named by -lfoo. +# If LIB_PATH is defined (e.g., by Makefile) and non-empty, it is used. +# Otherwise, the default is set here. +# +# The format is the usual list of colon-separated directories. +# To force a logically empty LIB_PATH, do LIBPATH=":". + +if [ "x${LIB_PATH}" = "x" ] ; then + if [ "x${host}" = "x${target}" ] ; then + if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then + # Native. + LIB_PATH=/lib:/usr/lib + if [ -n "${NATIVE_LIB_DIRS}" ]; then + LIB_PATH=${LIB_PATH}:${NATIVE_LIB_DIRS} + fi + if [ "${libdir}" != /usr/lib ]; then + LIB_PATH=${LIB_PATH}:${libdir} + fi + if [ "${libdir}" != /usr/local/lib ] ; then + LIB_PATH=${LIB_PATH}:/usr/local/lib + fi + else + # Native, but not default emulation. + LIB_PATH= + fi + else + # Cross. + LIB_PATH= + fi +fi + +# Always search $(tooldir)/lib, aka /usr/local/TARGET/lib. +LIB_PATH=${LIB_PATH}:${tool_lib} + +LIB_SEARCH_DIRS=`echo ${LIB_PATH} | tr ':' ' ' | sed -e 's/\([^ ][^ ]*\)/SEARCH_DIR(\1);/g'` + +# Generate 5 or 6 script files from a master script template in +# ${srcdir}/scripttempl/${SCRIPT_NAME}.sh. Which one of the 5 or 6 +# script files is actually used depends on command line options given +# to ld. (SCRIPT_NAME was set in the emulparams_file.) +# +# A .x script file is the default script. +# A .xr script is for linking without relocation (-r flag). +# A .xu script is like .xr, but *do* create constructors (-Ur flag). +# A .xn script is for linking with -n flag (mix text and data on same page). +# A .xbn script is for linking with -N flag (mix text and data on same page). +# A .xs script is for generating a shared library with the --shared +# flag; it is only generated if $GENERATE_SHLIB_SCRIPT is set by the +# emulation parameters. + +SEGMENT_SIZE=${SEGMENT_SIZE-${TARGET_PAGE_SIZE}} + +# Determine DATA_ALIGNMENT for the 5 variants, using +# values specified in the emulparams/<emulation>.sh file or default. + +DATA_ALIGNMENT_="${DATA_ALIGNMENT_-${DATA_ALIGNMENT-ALIGN(${SEGMENT_SIZE})}}" +DATA_ALIGNMENT_n="${DATA_ALIGNMENT_n-${DATA_ALIGNMENT_}}" +DATA_ALIGNMENT_N="${DATA_ALIGNMENT_N-${DATA_ALIGNMENT-.}}" +DATA_ALIGNMENT_r="${DATA_ALIGNMENT_r-${DATA_ALIGNMENT-}}" +DATA_ALIGNMENT_u="${DATA_ALIGNMENT_u-${DATA_ALIGNMENT_r}}" + +LD_FLAG=r +DATA_ALIGNMENT=${DATA_ALIGNMENT_r} +DEFAULT_DATA_ALIGNMENT="ALIGN(${SEGMENT_SIZE})" +(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \ + ldscripts/${EMULATION_NAME}.xr + +LD_FLAG=u +DATA_ALIGNMENT=${DATA_ALIGNMENT_u} +CONSTRUCTING=" " +(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \ + ldscripts/${EMULATION_NAME}.xu + +LD_FLAG= +DATA_ALIGNMENT=${DATA_ALIGNMENT_} +RELOCATING=" " +(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \ + ldscripts/${EMULATION_NAME}.x + +LD_FLAG=n +DATA_ALIGNMENT=${DATA_ALIGNMENT_n} +TEXT_START_ADDR=${NONPAGED_TEXT_START_ADDR-${TEXT_START_ADDR}} +(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \ + ldscripts/${EMULATION_NAME}.xn + +LD_FLAG=N +DATA_ALIGNMENT=${DATA_ALIGNMENT_N} +(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \ + ldscripts/${EMULATION_NAME}.xbn + +if test -n "$GENERATE_SHLIB_SCRIPT"; then + LD_FLAG=shared + DATA_ALIGNMENT=${DATA_ALIGNMENT_s-${DATA_ALIGNMENT_}} + CREATE_SHLIB=" " + # Note that TEXT_START_ADDR is set to NONPAGED_TEXT_START_ADDR. + (. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \ + ldscripts/${EMULATION_NAME}.xs +fi + +test "$DEFAULT_EMULATION" = "$EMULATION_NAME" && COMPILE_IN=true + +# Generate e${EMULATION_NAME}.c. +. ${srcdir}/emultempl/${TEMPLATE_NAME-generic}.em diff --git a/ld/h8-doc.texi b/ld/h8-doc.texi new file mode 100644 index 0000000..f3c62a1 --- /dev/null +++ b/ld/h8-doc.texi @@ -0,0 +1,14 @@ +@c ------------------------------ CONFIGURATION VARS: +@c 1. Inclusiveness of this manual +@clear GENERIC + +@c 2. Specific target machines +@set H8300 +@set Hitachi +@clear I960 + +@c 3. Properties of this configuration +@set SingleFormat +@clear UsesEnvVars +@c ------------------------------ end CONFIGURATION VARS + @@ -0,0 +1,1115 @@ +.\" Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation +.\" See section COPYING for conditions for redistribution +.TH ld 1 "17 August 1992" "cygnus support" "GNU Development Tools" +.de BP +.sp +.ti \-.2i +\(** +.. + +.SH NAME +ld \- the GNU linker + +.SH SYNOPSIS +.hy 0 +.na +.TP +.B ld +.RB "[\|" \-o " +.I output\c +\&\|] \c +.I objfile\c +\&.\|.\|. +.br +.RB "[\|" \-A\c +.I architecture\c +\&\|] +.RB "[\|" "\-b\ "\c +.I input-format\c +\&\|] +.RB "[\|" \-Bstatic "\|]" +.RB "[\|" \-Bdynamic "\|]" +.RB "[\|" \-Bsymbolic "\|]" +.RB "[\|" "\-c\ "\c +.I commandfile\c +\&\|] +.RB "[\|" \-\-cref "\|]" +.RB "[\|" \-d | \-dc | \-dp\c +\|] +.br +.RB "[\|" "\-defsym\ "\c +.I symbol\c +\& = \c +.I expression\c +\&\|] +.RB "[\|" \-\-demangle "\|]" +.RB "[\|" \-\-no\-demangle "\|]" +.RB "[\|" "\-e\ "\c +.I entry\c +\&\|] +.RB "[\|" \-embedded\-relocs "\|]" +.RB "[\|" \-E "\|]" +.RB "[\|" \-export\-dynamic "\|]" +.RB "[\|" "\-f\ "\c +.I name\c +\&\|] +.RB "[\|" "\-\-auxiliary\ "\c +.I name\c +\&\|] +.RB "[\|" "\-F\ "\c +.I name\c +\&\|] +.RB "[\|" "\-\-filter\ "\c +.I name\c +\&\|] +.RB "[\|" "\-format\ "\c +.I input-format\c +\&\|] +.RB "[\|" \-g "\|]" +.RB "[\|" \-G +.I size\c +\&\|] +.RB "[\|" "\-h\ "\c +.I name\c +\&\|] +.RB "[\|" "\-soname\ "\c +.I name\c +\&\|] +.RB "[\|" \-\-help "\|]" +.RB "[\|" \-i "\|]" +.RB "[\|" \-l\c +.I ar\c +\&\|] +.RB "[\|" \-L\c +.I searchdir\c +\&\|] +.RB "[\|" \-M "\|]" +.RB "[\|" \-Map +.I mapfile\c +\&\|] +.RB "[\|" \-m +.I emulation\c +\&\|] +.RB "[\|" \-n | \-N "\|]" +.RB "[\|" \-noinhibit-exec "\|]" +.RB "[\|" \-no\-keep\-memory "\|]" +.RB "[\|" \-no\-warn\-mismatch "\|]" +.RB "[\|" \-O\c +.I level\c +\&\|] +.RB "[\|" "\-oformat\ "\c +.I output-format\c +\&\|] +.RB "[\|" "\-R\ "\c +.I filename\c +\&\|] +.RB "[\|" \-relax "\|]" +.RB "[\|" \-r | \-Ur "\|]" +.RB "[\|" "\-rpath\ "\c +.I directory\c +\&\|] +.RB "[\|" "\-rpath\-link\ "\c +.I directory\c +\&\|] +.RB "[\|" \-S "\|]" +.RB "[\|" \-s "\|]" +.RB "[\|" \-shared "\|]" +.RB "[\|" \-sort\-common "\|]" +.RB "[\|" "\-split\-by\-reloc\ "\c +.I count\c +\&\|] +.RB "[\|" \-split\-by\-file "\|]" +.RB "[\|" "\-T\ "\c +.I commandfile\c +\&\|] +.RB "[\|" "\-Ttext\ "\c +.I textorg\c +\&\|] +.RB "[\|" "\-Tdata\ "\c +.I dataorg\c +\&\|] +.RB "[\|" "\-Tbss\ "\c +.I bssorg\c +\&\|] +.RB "[\|" \-t "\|]" +.RB "[\|" "\-u\ "\c +.I sym\c +\&] +.RB "[\|" \-V "\|]" +.RB "[\|" \-v "\|]" +.RB "[\|" \-\-verbose "\|]" +.RB "[\|" \-\-version "\|]" +.RB "[\|" \-warn\-common "\|]" +.RB "[\|" \-warn\-constructors "\|]" +.RB "[\|" \-warn\-multiple\-gp "\|]" +.RB "[\|" \-warn\-once "\|]" +.RB "[\|" \-warn\-section\-align "\|]" +.RB "[\|" \-\-whole\-archive "\|]" +.RB "[\|" \-\-no\-whole\-archive "\|]" +.RB "[\|" "\-\-wrap\ "\c +.I symbol\c +\&\|] +.RB "[\|" \-X "\|]" +.RB "[\|" \-x "\|]" +.ad b +.hy 1 +.SH DESCRIPTION +\c +.B ld\c +\& combines a number of object and archive files, relocates +their data and ties up symbol references. Often the last step in +building a new compiled program to run is a call to \c +.B ld\c +\&. + +\c +.B ld\c +\& accepts Linker Command Language files +to provide explicit and total control over the linking process. +This man page does not describe the command language; see the `\|\c +.B ld\c +\|' entry in `\|\c +.B info\c +\|', or the manual +.I +ld: the GNU linker +\&, for full details on the command language and on other aspects of +the GNU linker. + +This version of \c +.B ld\c +\& uses the general purpose BFD libraries +to operate on object files. This allows \c +.B ld\c +\& to read, combine, and +write object files in many different formats\(em\&for example, COFF or +\c +.B a.out\c +\&. Different formats may be linked together to produce any +available kind of object file. You can use `\|\c +.B objdump \-i\c +\|' to get a list of formats supported on various architectures; see +.BR objdump ( 1 ). + +Aside from its flexibility, the GNU linker is more helpful than other +linkers in providing diagnostic information. Many linkers abandon +execution immediately upon encountering an error; whenever possible, +\c +.B ld\c +\& continues executing, allowing you to identify other errors +(or, in some cases, to get an output file in spite of the error). + +The GNU linker \c +.B ld\c +\& is meant to cover a broad range of situations, +and to be as compatible as possible with other linkers. As a result, +you have many choices to control its behavior through the command line, +and through environment variables. + +.SH OPTIONS +The plethora of command-line options may seem intimidating, but in +actual practice few of them are used in any particular context. +For instance, a frequent use of \c +.B ld\c +\& is to link standard Unix +object files on a standard, supported Unix system. On such a system, to +link a file \c +.B hello.o\c +\&: +.sp +.br +$\ ld\ \-o\ output\ /lib/crt0.o\ hello.o\ \-lc +.br +.sp +This tells \c +.B ld\c +\& to produce a file called \c +.B output\c +\& as the +result of linking the file \c +.B /lib/crt0.o\c +\& with \c +.B hello.o\c +\& and +the library \c +.B libc.a\c +\& which will come from the standard search +directories. + +The command-line options to \c +.B ld\c +\& may be specified in any order, and +may be repeated at will. For the most part, repeating an option with a +different argument will either have no further effect, or override prior +occurrences (those further to the left on the command line) of an +option. + +The exceptions\(em\&which may meaningfully be used more than once\(em\&are +\c +.B \-A\c +\&, \c +.B \-b\c +\& (or its synonym \c +.B \-format\c +\&), \c +.B \-defsym\c +\&, +\c +.B \-L\c +\&, \c +.B \-l\c +\&, \c +.B \-R\c +\&, and \c +.B \-u\c +\&. + +The list of object files to be linked together, shown as \c +.I objfile\c +\&, +may follow, precede, or be mixed in with command-line options; save that +an \c +.I objfile\c +\& argument may not be placed between an option flag and +its argument. + +Usually the linker is invoked with at least one object file, but other +forms of binary input files can also be specified with \c +.B \-l\c +\&, +\c +.B \-R\c +\&, and the script command language. If \c +.I no\c +\& binary input +files at all are specified, the linker does not produce any output, and +issues the message `\|\c +.B No input files\c +\|'. + +Option arguments must either follow the option letter without intervening +whitespace, or be given as separate arguments immediately following the +option that requires them. + +.TP +.BI "-A" "architecture" +In the current release of \c +.B ld\c +\&, this option is useful only for the +Intel 960 family of architectures. In that \c +.B ld\c +\& configuration, the +\c +.I architecture\c +\& argument is one of the two-letter names identifying +members of the 960 family; the option specifies the desired output +target, and warns of any incompatible instructions in the input files. +It also modifies the linker's search strategy for archive libraries, to +support the use of libraries specific to each particular +architecture, by including in the search loop names suffixed with the +string identifying the architecture. + +For example, if your \c +.B ld\c +\& command line included `\|\c +.B \-ACA\c +\|' as +well as `\|\c +.B \-ltry\c +\|', the linker would look (in its built-in search +paths, and in any paths you specify with \c +.B \-L\c +\&) for a library with +the names +.sp +.br +try +.br +libtry.a +.br +tryca +.br +libtryca.a +.br +.sp + +The first two possibilities would be considered in any event; the last +two are due to the use of `\|\c +.B \-ACA\c +\|'. + +Future releases of \c +.B ld\c +\& may support similar functionality for +other architecture families. + +You can meaningfully use \c +.B \-A\c +\& more than once on a command line, if +an architecture family allows combination of target architectures; each +use will add another pair of name variants to search for when \c +.B \-l +specifies a library. + +.TP +.BI "\-b " "input-format" +Specify the binary format for input object files that follow this option +on the command line. You don't usually need to specify this, as +\c +.B ld\c +\& is configured to expect as a default input format the most +usual format on each machine. \c +.I input-format\c +\& is a text string, the +name of a particular format supported by the BFD libraries. +\c +.B \-format \c +.I input-format\c +\&\c +\& has the same effect, as does the script command +.BR TARGET . + +You may want to use this option if you are linking files with an unusual +binary format. You can also use \c +.B \-b\c +\& to switch formats explicitly (when +linking object files of different formats), by including +\c +.B \-b \c +.I input-format\c +\&\c +\& before each group of object files in a +particular format. + +The default format is taken from the environment variable +.B GNUTARGET\c +\&. You can also define the input +format from a script, using the command \c +.B TARGET\c +\&. + +.TP +.B \-Bstatic +Do not link against shared libraries. This is only meaningful on +platforms for which shared libraries are supported. + +.TP +.B \-Bdynamic +Link against dynamic libraries. This is only meaningful on platforms +for which shared libraries are supported. This option is normally the +default on such platforms. + +.TP +.B \-Bsymbolic +When creating a shared library, bind references to global symbols to +the definition within the shared library, if any. Normally, it is +possible for a program linked against a shared library to override the +definition within the shared library. This option is only meaningful +on ELF platforms which support shared libraries. + +.TP +.BI "\-c " "commandfile" +Directs \c +.B ld\c +\& to read link commands from the file +\c +.I commandfile\c +\&. These commands will completely override \c +.B ld\c +\&'s +default link format (rather than adding to it); \c +.I commandfile\c +\& must +specify everything necessary to describe the target format. + + +You may also include a script of link commands directly in the command +line by bracketing it between `\|\c +.B {\c +\|' and `\|\c +.B }\c +\|' characters. + +.TP +.B \-\-cref +Output a cross reference table. If a linker map file is being +generated, the cross reference table is printed to the map file. +Otherwise, it is printed on the standard output. + +.TP +.B \-d +.TP +.B \-dc +.TP +.B \-dp +These three options are equivalent; multiple forms are supported for +compatibility with other linkers. Use any of them to make \c +.B ld +assign space to common symbols even if a relocatable output file is +specified (\c +.B \-r\c +\&). The script command +\c +.B FORCE_COMMON_ALLOCATION\c +\& has the same effect. + +.TP +.BI "-defsym " "symbol" "\fR = \fP" expression +Create a global symbol in the output file, containing the absolute +address given by \c +.I expression\c +\&. You may use this option as many +times as necessary to define multiple symbols in the command line. A +limited form of arithmetic is supported for the \c +.I expression\c +\& in this +context: you may give a hexadecimal constant or the name of an existing +symbol, or use \c +.B +\c +\& and \c +.B \-\c +\& to add or subtract hexadecimal +constants or symbols. If you need more elaborate expressions, consider +using the linker command language from a script. + +.TP +.B \-\-demangle +.TP +.B \-\-no\-demangle +These options control whether to demangle symbol names in error +messages and other output. When the linker is told to demangle, it +tries to present symbol names in a readable fashion: it strips leading +underscores if they are used by the object file format, and converts +C++ mangled symbol names into user readable names. The linker will +demangle by default unless the environment variable +.B COLLECT_NO_DEMANGLE +is set. These options may be used to override the default. + +.TP +.BI "-e " "entry"\c +\& +Use \c +.I entry\c +\& as the explicit symbol for beginning execution of your +program, rather than the default entry point. See the `\|\c +.B ld\c +\|' entry in `\|\c +.B info\c +\|' for a +discussion of defaults and other ways of specifying the +entry point. + +.TP +.B \-embedded\-relocs +This option is only meaningful when linking MIPS embedded PIC code, +generated by the +.B \-membedded\-pic +option to the GNU compiler and assembler. It causes the linker to +create a table which may be used at runtime to relocate any data which +was statically initialized to pointer values. See the code in +testsuite/ld-empic for details. + +.TP +.B \-E +.TP +.B \-export\-dynamic +When creating an ELF file, add all symbols to the dynamic symbol table. +Normally, the dynamic symbol table contains only symbols which are used +by a dynamic object. This option is needed for some uses of +.I dlopen. + +.TP +.BI "-f " "name" +.TP +.BI "--auxiliary " "name" +When creating an ELF shared object, set the internal DT_AUXILIARY field +to the specified name. This tells the dynamic linker that the symbol +table of the shared object should be used as an auxiliary filter on the +symbol table of the shared object +.I name. + +.TP +.BI "-F " "name" +.TP +.BI "--filter " "name" +When creating an ELF shared object, set the internal DT_FILTER field to +the specified name. This tells the dynamic linker that the symbol table +of the shared object should be used as a filter on the symbol table of +the shared object +.I name. + +.TP +.BI "\-format " "input\-format" +Synonym for \c +.B \-b\c +\& \c +.I input\-format\c +\&. + +.TP +.B \-g +Accepted, but ignored; provided for compatibility with other tools. + +.TP +.BI "\-G " "size"\c +Set the maximum size of objects to be optimized using the GP register +to +.I size +under MIPS ECOFF. Ignored for other object file formats. + +.TP +.BI "-h " "name" +.TP +.BI "-soname " "name" +When creating an ELF shared object, set the internal DT_SONAME field to +the specified name. When an executable is linked with a shared object +which has a DT_SONAME field, then when the executable is run the dynamic +linker will attempt to load the shared object specified by the DT_SONAME +field rather than the using the file name given to the linker. + +.TP +.B \-\-help +Print a summary of the command-line options on the standard output and exit. +This option and +.B \-\-version +begin with two dashes instead of one +for compatibility with other GNU programs. The other options start with +only one dash for compatibility with other linkers. + +.TP +.B \-i +Perform an incremental link (same as option \c +.B \-r\c +\&). + +.TP +.BI "\-l" "ar"\c +\& +Add an archive file \c +.I ar\c +\& to the list of files to link. This +option may be used any number of times. \c +.B ld\c +\& will search its +path-list for occurrences of \c +.B lib\c +.I ar\c +\&.a\c +\& for every \c +.I ar +specified. + +.TP +.BI "\-L" "searchdir" +This command adds path \c +.I searchdir\c +\& to the list of paths that +\c +.B ld\c +\& will search for archive libraries. You may use this option +any number of times. + +The default set of paths searched (without being specified with +\c +.B \-L\c +\&) depends on what emulation mode \c +.B ld\c +\& is using, and in +some cases also on how it was configured. The +paths can also be specified in a link script with the \c +.B SEARCH_DIR +command. + +.TP +.B \-M +Print (to the standard output file) a link map\(em\&diagnostic information +about where symbols are mapped by \c +.B ld\c +\&, and information on global +common storage allocation. + +.TP +.BI "\-Map " "mapfile"\c +Print to the file +.I mapfile +a link map\(em\&diagnostic information +about where symbols are mapped by \c +.B ld\c +\&, and information on global +common storage allocation. + +.TP +.BI "\-m " "emulation"\c +Emulate the +.I emulation +linker. You can list the available emulations with the +.I \-\-verbose +or +.I \-V +options. This option overrides the compiled-in default, which is the +system for which you configured +.BR ld . + +.TP +.B \-N +specifies readable and writable \c +.B text\c +\& and \c +.B data\c +\& sections. If +the output format supports Unix style magic numbers, the output is +marked as \c +.B OMAGIC\c +\&. + +When you use the `\|\c +.B \-N\c +\&\|' option, the linker does not page-align the +data segment. + +.TP +.B \-n +sets the text segment to be read only, and \c +.B NMAGIC\c +\& is written +if possible. + +.TP +.B \-noinhibit\-exec +Normally, the linker will not produce an output file if it encounters +errors during the link process. With this flag, you can specify that +you wish the output file retained even after non-fatal errors. + +.TP +.B \-no\-keep\-memory +The linker normally optimizes for speed over memory usage by caching +the symbol tables of input files in memory. This option tells the +linker to instead optimize for memory usage, by rereading the symbol +tables as necessary. This may be required if the linker runs out of +memory space while linking a large executable. + +.TP +.B \-no\-warn\-mismatch +Normally the linker will give an error if you try to link together +input files that are mismatched for some reason, perhaps because they +have been compiled for different processors or for different +endiannesses. This option tells the linker that it should silently +permit such possible errors. This option should only be used with +care, in cases when you have taken some special action that ensures +that the linker errors are inappropriate. + +.TP +.BI "\-o " "output" +.I output\c +\& is a name for the program produced by \c +.B ld\c +\&; if this +option is not specified, the name `\|\c +.B a.out\c +\|' is used by default. The +script command \c +.B OUTPUT\c +\& can also specify the output file name. + +.TP +.BI "\-O" "level" +Generate optimized output files. This might use significantly more +time and therefore probably should be enabled only for generating the +final binary. +\c +.I level\c +\& is supposed to be a numeric value. Any value greater than zero enables +the optimizations. + +.TP +.BI "\-oformat " "output\-format" +Specify the binary format for the output object file. +You don't usually need to specify this, as +\c +.B ld\c +\& is configured to produce as a default output format the most +usual format on each machine. \c +.I output-format\c +\& is a text string, the +name of a particular format supported by the BFD libraries. +The script command +.B OUTPUT_FORMAT +can also specify the output format, but this option overrides it. + +.TP +.BI "\-R " "filename" +Read symbol names and their addresses from \c +.I filename\c +\&, but do not +relocate it or include it in the output. This allows your output file +to refer symbolically to absolute locations of memory defined in other +programs. + +.TP +.B \-relax +An option with machine dependent effects. Currently this option is only +supported on the H8/300. + +On some platforms, use this option to perform global optimizations that +become possible when the linker resolves addressing in your program, such +as relaxing address modes and synthesizing new instructions in the +output object file. + +On platforms where this is not supported, `\|\c +.B \-relax\c +\&\|' is accepted, but has no effect. + +.TP +.B \-r +Generates relocatable output\(em\&i.e., generate an output file that can in +turn serve as input to \c +.B ld\c +\&. This is often called \c +.I partial +linking\c +\&. As a side effect, in environments that support standard Unix +magic numbers, this option also sets the output file's magic number to +\c +.B OMAGIC\c +\&. +If this option is not specified, an absolute file is produced. When +linking C++ programs, this option \c +.I will not\c +\& resolve references to +constructors; \c +.B \-Ur\c +\& is an alternative. + +This option does the same as \c +.B \-i\c +\&. + +.TP +.B \-rpath\ \fIdirectory +Add a directory to the runtime library search path. This is used when +linking an ELF executable with shared objects. All +.B \-rpath +arguments are concatenated and passed to the runtime linker, which uses +them to locate shared objects at runtime. The +.B \-rpath +option is also used when locating shared objects which are needed by +shared objects explicitly included in the link; see the description of +the +.B \-rpath\-link +option. If +.B \-rpath +is not used when linking an ELF executable, the contents of the +environment variable +.B LD_RUN_PATH +will be used if it is defined. + +The +.B \-rpath +option may also be used on SunOS. By default, on SunOS, the linker +will form a runtime search path out of all the +.B \-L +options it is given. If a +.B \-rpath +option is used, the runtime search path will be formed exclusively +using the +.B \-rpath +options, ignoring +the +.B \-L +options. This can be useful when using gcc, which adds many +.B \-L +options which may be on NFS mounted filesystems. + +.TP +.B \-rpath\-link\ \fIdirectory +When using ELF or SunOS, one shared library may require another. This +happens when an +.B ld\ \-shared +link includes a shared library as one of the input files. + +When the linker encounters such a dependency when doing a non-shared, +non-relocateable link, it will automatically try to locate the required +shared library and include it in the link, if it is not included +explicitly. In such a case, the +.B \-rpath\-link +option specifies the first set of directories to search. The +.B \-rpath\-link +option may specify a sequence of directory names either by specifying +a list of names separated by colons, or by appearing multiple times. + +If the required shared library is not found, the linker will issue a +warning and continue with the link. + +.TP +.B \-S +Omits debugger symbol information (but not all symbols) from the output file. + +.TP +.B \-s +Omits all symbol information from the output file. + +.TP +.B \-shared +Create a shared library. This is currently only supported on ELF and +SunOS platforms (on SunOS it is not required, as the linker will +automatically create a shared library when there are undefined symbols +and the +.B \-e +option is not used). + +.TP +.B \-sort\-common +Normally, when +.B ld +places the global common symbols in the appropriate output sections, +it sorts them by size. First come all the one byte symbols, then all +the two bytes, then all the four bytes, and then everything else. +This is to prevent gaps between symbols due to +alignment constraints. This option disables that sorting. + +.TP +.B \-split\-by\-reloc\ \fIcount +Trys to creates extra sections in the output file so that no single +output section in the file contains more than +.I count +relocations. +This is useful when generating huge relocatable for downloading into +certain real time kernels with the COFF object file format; since COFF +cannot represent more than 65535 relocations in a single section. +Note that this will fail to work with object file formats which do not +support arbitrary sections. The linker will not split up individual +input sections for redistribution, so if a single input section +contains more than +.I count +relocations one output section will contain that many relocations. + +.TP +.B \-split\-by\-file +Similar to +.B \-split\-by\-reloc +but creates a new output section for each input file. + +.TP +.BI "\-Tbss " "org"\c +.TP +.BI "\-Tdata " "org"\c +.TP +.BI "\-Ttext " "org"\c +Use \c +.I org\c +\& as the starting address for\(em\&respectively\(em\&the +\c +.B bss\c +\&, \c +.B data\c +\&, or the \c +.B text\c +\& segment of the output file. +\c +.I org\c +\& must be a hexadecimal integer. + +.TP +.BI "\-T " "commandfile" +Equivalent to \c +.B \-c \c +.I commandfile\c +\&\c +\&; supported for compatibility with +other tools. + +.TP +.B \-t +Prints names of input files as \c +.B ld\c +\& processes them. + +.TP +.BI "\-u " "sym" +Forces \c +.I sym\c +\& to be entered in the output file as an undefined symbol. +This may, for example, trigger linking of additional modules from +standard libraries. \c +.B \-u\c +\& may be repeated with different option +arguments to enter additional undefined symbols. + +.TP +.B \-Ur +For anything other than C++ programs, this option is equivalent to +\c +.B \-r\c +\&: it generates relocatable output\(em\&i.e., an output file that can in +turn serve as input to \c +.B ld\c +\&. When linking C++ programs, \c +.B \-Ur +.I will\c +\& resolve references to constructors, unlike \c +.B \-r\c +\&. + +.TP +.B \-\-verbose +Display the version number for \c +.B ld +and list the supported emulations. +Display which input files can and can not be opened. + +.TP +.B \-v, \-V +Display the version number for \c +.B ld\c +\&. +The +.B \-V +option also lists the supported emulations. + +.TP +.B \-\-version +Display the version number for \c +.B ld +and exit. + +.TP +.B \-warn\-common +Warn when a common symbol is combined with another common symbol or with +a symbol definition. Unix linkers allow this somewhat sloppy practice, +but linkers on some other operating systems do not. This option allows +you to find potential problems from combining global symbols. + +.TP +.B \-warn\-constructors +Warn if any global constructors are used. This is only useful for a +few object file formats. For formats like COFF or ELF, the linker can +not detect the use of global constructors. + +.TP +.B \-warn\-multiple\-gp +Warn if the output file requires multiple global-pointer values. This +option is only meaningful for certain processors, such as the Alpha. + +.TP +.B \-warn\-once +Only warn once for each undefined symbol, rather than once per module +which refers to it. + +.TP +.B \-warn\-section\-align +Warn if the address of an output section is changed because of +alignment. Typically, the alignment will be set by an input section. +The address will only be changed if it not explicitly specified; that +is, if the SECTIONS command does not specify a start address for the +section. + +.TP +.B \-\-whole\-archive +For each archive mentioned on the command line after the +.B \-\-whole\-archive +option, include every object file in the archive in the link, rather +than searching the archive for the required object files. This is +normally used to turn an archive file into a shared library, forcing +every object to be included in the resulting shared library. + +.TP +.B \-\-no\-whole\-archive +Turn off the effect of the +.B \-\-whole\-archive +option for archives which appear later on the command line. + +.TP +.BI "--wrap " "symbol" +Use a wrapper function for +.I symbol. +Any undefined reference to +.I symbol +will be resolved to +.BI "__wrap_" "symbol". +Any undefined reference to +.BI "__real_" "symbol" +will be resolved to +.I symbol. + +.TP +.B \-X +Delete all temporary local symbols. For most targets, this is all local +symbols whose names begin with `\|\c +.B L\c +\|'. + +.TP +.B \-x +Delete all local symbols. + +.PP + +.SH ENVIRONMENT +\c +You can change the behavior of +.B ld\c +\& with the environment variable \c +.B GNUTARGET\c +\&. + +\c +.B GNUTARGET\c +\& determines the input-file object format if you don't +use \c +.B \-b\c +\& (or its synonym \c +.B \-format\c +\&). Its value should be one +of the BFD names for an input format. If there is no +\c +.B GNUTARGET\c +\& in the environment, \c +.B ld\c +\& uses the natural format +of the host. If \c +.B GNUTARGET\c +\& is set to \c +.B default\c +\& then BFD attempts to discover the +input format by examining binary input files; this method often +succeeds, but there are potential ambiguities, since there is no method +of ensuring that the magic number used to flag object-file formats is +unique. However, the configuration procedure for BFD on each system +places the conventional format for that system first in the search-list, +so ambiguities are resolved in favor of convention. + +.PP + +.SH "SEE ALSO" + +.BR objdump ( 1 ) +.br +.br +.RB "`\|" ld "\|' and `\|" binutils "\|'" +entries in +.B info\c +.br +.I +ld: the GNU linker\c +, Steve Chamberlain and Roland Pesch; +.I +The GNU Binary Utilities\c +, Roland H. Pesch. + +.SH COPYING +Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. +.PP +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. +.PP +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. +.PP +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. @@ -0,0 +1,226 @@ +/* ld.h -- general linker header file + Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef LD_H +#define LD_H + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#ifdef ENABLE_NLS +# include <libintl.h> +# define _(String) gettext (String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +/* Stubs that do something close enough. */ +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define N_(String) (String) +#endif + +/* Look in this environment name for the linker to pretend to be */ +#define EMULATION_ENVIRON "LDEMULATION" +/* If in there look for the strings: */ + +/* Look in this variable for a target format */ +#define TARGET_ENVIRON "GNUTARGET" + +/* Input sections which are put in a section of this name are actually + discarded. */ +#define DISCARD_SECTION_NAME "/DISCARD/" + +/* A wildcard specification. This is only used in ldgram.y, but it + winds up in ldgram.h, so we need to define it outside. */ + +struct wildcard_spec +{ + const char *name; + const char *exclude_name; + boolean sorted; +}; + +/* Extra information we hold on sections */ +typedef struct user_section_struct +{ + /* Pointer to the section where this data will go */ + struct lang_input_statement_struct *file; +} section_userdata_type; + + +#define get_userdata(x) ((x)->userdata) + +#define BYTE_SIZE (1) +#define SHORT_SIZE (2) +#define LONG_SIZE (4) +#define QUAD_SIZE (8) + +/* ALIGN macro changed to ALIGN_N to avoid */ +/* conflict in /usr/include/machine/machparam.h */ +/* WARNING: If THIS is a 64 bit address and BOUNDARY is a 32 bit int, + you must coerce boundary to the same type as THIS. + ??? Is there a portable way to avoid this. */ +#define ALIGN_N(this, boundary) \ + ((( (this) + ((boundary) -1)) & (~((boundary)-1)))) + +typedef struct +{ + /* 1 => assign space to common symbols even if `relocatable_output'. */ + boolean force_common_definition; + boolean relax; + + /* Name of runtime interpreter to invoke. */ + char *interpreter; + + /* Name to give runtime libary from the -soname argument. */ + char *soname; + + /* Runtime library search path from the -rpath argument. */ + char *rpath; + + /* Link time runtime library search path from the -rpath-link + argument. */ + char *rpath_link; + + /* Big or little endian as set on command line. */ + enum { ENDIAN_UNSET = 0, ENDIAN_BIG, ENDIAN_LITTLE } endian; + + /* If true, export all symbols in the dynamic symbol table of an ELF + executable. */ + boolean export_dynamic; + + /* If true, build MIPS embedded PIC relocation tables in the output + file. */ + boolean embedded_relocs; + + /* If true, force generation of a file with a .exe file. */ + boolean force_exe_suffix; + + /* If true, generate a cross reference report. */ + boolean cref; + + /* If true (which is the default), warn about mismatched input + files. */ + boolean warn_mismatch; + + /* Remove unreferenced sections? */ + boolean gc_sections; + + /* Name of shared object whose symbol table should be filtered with + this shared object. From the --filter option. */ + char *filter_shlib; + + /* Name of shared object for whose symbol table this shared object + is an auxiliary filter. From the --auxiliary option. */ + char **auxiliary_filters; + + /* A version symbol to be applied to the symbol names found in the + .exports sections. */ + char *version_exports_section; + + /* If true (the default) check section addresses, once compute, + fpor overlaps. */ + boolean check_section_addresses; + +} args_type; + +extern args_type command_line; + +typedef int token_code_type; + +typedef struct +{ + bfd_size_type specified_data_size; + boolean magic_demand_paged; + boolean make_executable; + + /* If true, doing a dynamic link. */ + boolean dynamic_link; + + /* If true, -shared is supported. */ + /* ??? A better way to do this is perhaps to define this in the + ld_emulation_xfer_struct since this is really a target dependent + parameter. */ + boolean has_shared; + + /* If true, build constructors. */ + boolean build_constructors; + + /* If true, warn about any constructors. */ + boolean warn_constructors; + + /* If true, warn about merging common symbols with others. */ + boolean warn_common; + + /* If true, only warn once about a particular undefined symbol. */ + boolean warn_once; + + /* If true, warn if multiple global-pointers are needed (Alpha + only). */ + boolean warn_multiple_gp; + + /* If true, warn if the starting address of an output section + changes due to the alignment of an input section. */ + boolean warn_section_align; + + boolean sort_common; + + boolean text_read_only; + + char *map_filename; + FILE *map_file; + + boolean stats; + + int split_by_reloc; + boolean split_by_file; +} ld_config_type; + +extern ld_config_type config; + +typedef enum +{ + lang_first_phase_enum, + lang_allocating_phase_enum, + lang_final_phase_enum +} lang_phase_type; + +extern boolean had_script; +extern boolean force_make_executable; + +/* Non-zero if we are processing a --defsym from the command line. */ +extern int parsing_defsym; + +extern int yyparse PARAMS ((void)); + +extern void add_cref PARAMS ((const char *, bfd *, asection *, bfd_vma)); +extern void output_cref PARAMS ((FILE *)); +extern void check_nocrossrefs PARAMS ((void)); + +#endif diff --git a/ld/ld.texinfo b/ld/ld.texinfo new file mode 100644 index 0000000..027f196 --- /dev/null +++ b/ld/ld.texinfo @@ -0,0 +1,4305 @@ +\input texinfo +@setfilename ld.info +@syncodeindex ky cp +@include configdoc.texi +@c (configdoc.texi is generated by the Makefile) +@include ldver.texi + +@c @smallbook + +@ifinfo +@format +START-INFO-DIR-ENTRY +* Ld: (ld). The GNU linker. +END-INFO-DIR-ENTRY +@end format +@end ifinfo + +@ifinfo +This file documents the @sc{gnu} linker LD version @value{VERSION}. + +Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. + +@ignore +Permission is granted to process this file through Tex and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +@end ifinfo +@iftex +@finalout +@setchapternewpage odd +@settitle Using LD, the GNU linker +@titlepage +@title Using ld +@subtitle The GNU linker +@sp 1 +@subtitle @code{ld} version 2 +@subtitle Version @value{VERSION} +@author Steve Chamberlain +@author Ian Lance Taylor +@author Cygnus Solutions +@page + +@tex +{\parskip=0pt +\hfill Cygnus Solutions\par +\hfill ian\@cygnus.com, doc\@cygnus.com\par +\hfill {\it Using LD, the GNU linker}\par +\hfill Edited by Jeffrey Osier (jeffrey\@cygnus.com)\par +} +\global\parindent=0pt % Steve likes it this way. +@end tex + +@vskip 0pt plus 1filll +Copyright @copyright{} 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. +@end titlepage +@end iftex +@c FIXME: Talk about importance of *order* of args, cmds to linker! + +@ifinfo +@node Top +@top Using ld +This file documents the @sc{gnu} linker ld version @value{VERSION}. + +@menu +* Overview:: Overview +* Invocation:: Invocation +* Scripts:: Linker Scripts +@ifset GENERIC +* Machine Dependent:: Machine Dependent Features +@end ifset +@ifclear GENERIC +@ifset H8300 +* H8/300:: ld and the H8/300 +@end ifset +@ifset Hitachi +* Hitachi:: ld and other Hitachi micros +@end ifset +@ifset I960 +* i960:: ld and the Intel 960 family +@end ifset +@end ifclear +@ifclear SingleFormat +* BFD:: BFD +@end ifclear +@c Following blank line required for remaining bug in makeinfo conds/menus + +* Reporting Bugs:: Reporting Bugs +* MRI:: MRI Compatible Script Files +* Index:: Index +@end menu +@end ifinfo + +@node Overview +@chapter Overview + +@cindex @sc{gnu} linker +@cindex what is this? +@code{ld} combines a number of object and archive files, relocates +their data and ties up symbol references. Usually the last step in +compiling a program is to run @code{ld}. + +@code{ld} accepts Linker Command Language files written in +a superset of AT&T's Link Editor Command Language syntax, +to provide explicit and total control over the linking process. + +@ifclear SingleFormat +This version of @code{ld} uses the general purpose BFD libraries +to operate on object files. This allows @code{ld} to read, combine, and +write object files in many different formats---for example, COFF or +@code{a.out}. Different formats may be linked together to produce any +available kind of object file. @xref{BFD}, for more information. +@end ifclear + +Aside from its flexibility, the @sc{gnu} linker is more helpful than other +linkers in providing diagnostic information. Many linkers abandon +execution immediately upon encountering an error; whenever possible, +@code{ld} continues executing, allowing you to identify other errors +(or, in some cases, to get an output file in spite of the error). + +@node Invocation +@chapter Invocation + +The @sc{gnu} linker @code{ld} is meant to cover a broad range of situations, +and to be as compatible as possible with other linkers. As a result, +you have many choices to control its behavior. + +@ifset UsesEnvVars +@menu +* Options:: Command Line Options +* Environment:: Environment Variables +@end menu + +@node Options +@section Command Line Options +@end ifset + +@cindex command line +@cindex options +The linker supports a plethora of command-line options, but in actual +practice few of them are used in any particular context. +@cindex standard Unix system +For instance, a frequent use of @code{ld} is to link standard Unix +object files on a standard, supported Unix system. On such a system, to +link a file @code{hello.o}: + +@smallexample +ld -o @var{output} /lib/crt0.o hello.o -lc +@end smallexample + +This tells @code{ld} to produce a file called @var{output} as the +result of linking the file @code{/lib/crt0.o} with @code{hello.o} and +the library @code{libc.a}, which will come from the standard search +directories. (See the discussion of the @samp{-l} option below.) + +The command-line options to @code{ld} may be specified in any order, and +may be repeated at will. Repeating most options with a different +argument will either have no further effect, or override prior +occurrences (those further to the left on the command line) of that +option. Options which may be meaningfully specified more than once are +noted in the descriptions below. + +@cindex object files +Non-option arguments are objects files which are to be linked together. +They may follow, precede, or be mixed in with command-line options, +except that an object file argument may not be placed between an option +and its argument. + +Usually the linker is invoked with at least one object file, but you can +specify other forms of binary input files using @samp{-l}, @samp{-R}, +and the script command language. If @emph{no} binary input files at all +are specified, the linker does not produce any output, and issues the +message @samp{No input files}. + +If the linker can not recognize the format of an object file, it will +assume that it is a linker script. A script specified in this way +augments the main linker script used for the link (either the default +linker script or the one specified by using @samp{-T}). This feature +permits the linker to link against a file which appears to be an object +or an archive, but actually merely defines some symbol values, or uses +@code{INPUT} or @code{GROUP} to load other objects. Note that +specifying a script in this way should only be used to augment the main +linker script; if you want to use some command that logically can only +appear once, such as the @code{SECTIONS} or @code{MEMORY} command, you +must replace the default linker script using the @samp{-T} option. +@xref{Scripts}. + +For options whose names are a single letter, +option arguments must either follow the option letter without intervening +whitespace, or be given as separate arguments immediately following the +option that requires them. + +For options whose names are multiple letters, either one dash or two can +precede the option name; for example, @samp{--oformat} and +@samp{--oformat} are equivalent. Arguments to multiple-letter options +must either be separated from the option name by an equals sign, or be +given as separate arguments immediately following the option that +requires them. For example, @samp{--oformat srec} and +@samp{--oformat=srec} are equivalent. Unique abbreviations of the names +of multiple-letter options are accepted. + +@table @code +@kindex -a@var{keyword} +@item -a@var{keyword} +This option is supported for HP/UX compatibility. The @var{keyword} +argument must be one of the strings @samp{archive}, @samp{shared}, or +@samp{default}. @samp{-aarchive} is functionally equivalent to +@samp{-Bstatic}, and the other two keywords are functionally equivalent +to @samp{-Bdynamic}. This option may be used any number of times. + +@ifset I960 +@cindex architectures +@kindex -A@var{arch} +@item -A@var{architecture} +@kindex --architecture=@var{arch} +@itemx --architecture=@var{architecture} +In the current release of @code{ld}, this option is useful only for the +Intel 960 family of architectures. In that @code{ld} configuration, the +@var{architecture} argument identifies the particular architecture in +the 960 family, enabling some safeguards and modifying the +archive-library search path. @xref{i960,,@code{ld} and the Intel 960 +family}, for details. + +Future releases of @code{ld} may support similar functionality for +other architecture families. +@end ifset + +@ifclear SingleFormat +@cindex binary input format +@kindex -b @var{format} +@kindex --format=@var{format} +@cindex input format +@cindex input format +@item -b @var{input-format} +@itemx --format=@var{input-format} +@code{ld} may be configured to support more than one kind of object +file. If your @code{ld} is configured this way, you can use the +@samp{-b} option to specify the binary format for input object files +that follow this option on the command line. Even when @code{ld} is +configured to support alternative object formats, you don't usually need +to specify this, as @code{ld} should be configured to expect as a +default input format the most usual format on each machine. +@var{input-format} is a text string, the name of a particular format +supported by the BFD libraries. (You can list the available binary +formats with @samp{objdump -i}.) +@xref{BFD}. + +You may want to use this option if you are linking files with an unusual +binary format. You can also use @samp{-b} to switch formats explicitly (when +linking object files of different formats), by including +@samp{-b @var{input-format}} before each group of object files in a +particular format. + +The default format is taken from the environment variable +@code{GNUTARGET}. +@ifset UsesEnvVars +@xref{Environment}. +@end ifset +You can also define the input format from a script, using the command +@code{TARGET}; see @ref{Format Commands}. +@end ifclear + +@kindex -c @var{MRI-cmdfile} +@kindex --mri-script=@var{MRI-cmdfile} +@cindex compatibility, MRI +@item -c @var{MRI-commandfile} +@itemx --mri-script=@var{MRI-commandfile} +For compatibility with linkers produced by MRI, @code{ld} accepts script +files written in an alternate, restricted command language, described in +@ref{MRI,,MRI Compatible Script Files}. Introduce MRI script files with +the option @samp{-c}; use the @samp{-T} option to run linker +scripts written in the general-purpose @code{ld} scripting language. +If @var{MRI-cmdfile} does not exist, @code{ld} looks for it in the directories +specified by any @samp{-L} options. + +@cindex common allocation +@kindex -d +@kindex -dc +@kindex -dp +@item -d +@itemx -dc +@itemx -dp +These three options are equivalent; multiple forms are supported for +compatibility with other linkers. They assign space to common symbols +even if a relocatable output file is specified (with @samp{-r}). The +script command @code{FORCE_COMMON_ALLOCATION} has the same effect. +@xref{Miscellaneous Commands}. + +@cindex entry point, from command line +@kindex -e @var{entry} +@kindex --entry=@var{entry} +@item -e @var{entry} +@itemx --entry=@var{entry} +Use @var{entry} as the explicit symbol for beginning execution of your +program, rather than the default entry point. If there is no symbol +named @var{entry}, the linker will try to parse @var{entry} as a number, +and use that as the entry address (the number will be interpreted in +base 10; you may use a leading @samp{0x} for base 16, or a leading +@samp{0} for base 8). @xref{Entry Point}, for a discussion of defaults +and other ways of specifying the entry point. + +@cindex dynamic symbol table +@kindex -E +@kindex --export-dynamic +@item -E +@itemx --export-dynamic +When creating a dynamically linked executable, add all symbols to the +dynamic symbol table. The dynamic symbol table is the set of symbols +which are visible from dynamic objects at run time. + +If you do not use this option, the dynamic symbol table will normally +contain only those symbols which are referenced by some dynamic object +mentioned in the link. + +If you use @code{dlopen} to load a dynamic object which needs to refer +back to the symbols defined by the program, rather than some other +dynamic object, then you will probably need to use this option when +linking the program itself. + +@cindex big-endian objects +@cindex endianness +@kindex -EB +@item -EB +Link big-endian objects. This affects the default output format. + +@cindex little-endian objects +@kindex -EL +@item -EL +Link little-endian objects. This affects the default output format. + +@kindex -f +@kindex --auxiliary +@item -f +@itemx --auxiliary @var{name} +When creating an ELF shared object, set the internal DT_AUXILIARY field +to the specified name. This tells the dynamic linker that the symbol +table of the shared object should be used as an auxiliary filter on the +symbol table of the shared object @var{name}. + +If you later link a program against this filter object, then, when you +run the program, the dynamic linker will see the DT_AUXILIARY field. If +the dynamic linker resolves any symbols from the filter object, it will +first check whether there is a definition in the shared object +@var{name}. If there is one, it will be used instead of the definition +in the filter object. The shared object @var{name} need not exist. +Thus the shared object @var{name} may be used to provide an alternative +implementation of certain functions, perhaps for debugging or for +machine specific performance. + +This option may be specified more than once. The DT_AUXILIARY entries +will be created in the order in which they appear on the command line. + +@kindex -F +@kindex --filter +@item -F @var{name} +@itemx --filter @var{name} +When creating an ELF shared object, set the internal DT_FILTER field to +the specified name. This tells the dynamic linker that the symbol table +of the shared object which is being created should be used as a filter +on the symbol table of the shared object @var{name}. + +If you later link a program against this filter object, then, when you +run the program, the dynamic linker will see the DT_FILTER field. The +dynamic linker will resolve symbols according to the symbol table of the +filter object as usual, but it will actually link to the definitions +found in the shared object @var{name}. Thus the filter object can be +used to select a subset of the symbols provided by the object +@var{name}. + +Some older linkers used the @code{-F} option throughout a compilation +toolchain for specifying object-file format for both input and output +object files. The @sc{gnu} linker uses other mechanisms for this +purpose: the @code{-b}, @code{--format}, @code{--oformat} options, the +@code{TARGET} command in linker scripts, and the @code{GNUTARGET} +environment variable. The @sc{gnu} linker will ignore the @code{-F} +option when not creating an ELF shared object. + +@kindex -g +@item -g +Ignored. Provided for compatibility with other tools. + +@kindex -G +@kindex --gpsize +@cindex object size +@item -G@var{value} +@itemx --gpsize=@var{value} +Set the maximum size of objects to be optimized using the GP register to +@var{size}. This is only meaningful for object file formats such as +MIPS ECOFF which supports putting large and small objects into different +sections. This is ignored for other object file formats. + +@cindex runtime library name +@kindex -h@var{name} +@kindex -soname=@var{name} +@item -h@var{name} +@itemx -soname=@var{name} +When creating an ELF shared object, set the internal DT_SONAME field to +the specified name. When an executable is linked with a shared object +which has a DT_SONAME field, then when the executable is run the dynamic +linker will attempt to load the shared object specified by the DT_SONAME +field rather than the using the file name given to the linker. + +@kindex -i +@cindex incremental link +@item -i +Perform an incremental link (same as option @samp{-r}). + +@cindex archive files, from cmd line +@kindex -l@var{archive} +@kindex --library=@var{archive} +@item -l@var{archive} +@itemx --library=@var{archive} +Add archive file @var{archive} to the list of files to link. This +option may be used any number of times. @code{ld} will search its +path-list for occurrences of @code{lib@var{archive}.a} for every +@var{archive} specified. + +On systems which support shared libraries, @code{ld} may also search for +libraries with extensions other than @code{.a}. Specifically, on ELF +and SunOS systems, @code{ld} will search a directory for a library with +an extension of @code{.so} before searching for one with an extension of +@code{.a}. By convention, a @code{.so} extension indicates a shared +library. + +The linker will search an archive only once, at the location where it is +specified on the command line. If the archive defines a symbol which +was undefined in some object which appeared before the archive on the +command line, the linker will include the appropriate file(s) from the +archive. However, an undefined symbol in an object appearing later on +the command line will not cause the linker to search the archive again. + +See the @code{-(} option for a way to force the linker to search +archives multiple times. + +You may list the same archive multiple times on the command line. + +@ifset GENERIC +This type of archive searching is standard for Unix linkers. However, +if you are using @code{ld} on AIX, note that it is different from the +behaviour of the AIX linker. +@end ifset + +@cindex search directory, from cmd line +@kindex -L@var{dir} +@kindex --library-path=@var{dir} +@item -L@var{searchdir} +@itemx --library-path=@var{searchdir} +Add path @var{searchdir} to the list of paths that @code{ld} will search +for archive libraries and @code{ld} control scripts. You may use this +option any number of times. The directories are searched in the order +in which they are specified on the command line. Directories specified +on the command line are searched before the default directories. All +@code{-L} options apply to all @code{-l} options, regardless of the +order in which the options appear. + +@ifset UsesEnvVars +The default set of paths searched (without being specified with +@samp{-L}) depends on which emulation mode @code{ld} is using, and in +some cases also on how it was configured. @xref{Environment}. +@end ifset + +The paths can also be specified in a link script with the +@code{SEARCH_DIR} command. Directories specified this way are searched +at the point in which the linker script appears in the command line. + +@cindex emulation +@kindex -m @var{emulation} +@item -m@var{emulation} +Emulate the @var{emulation} linker. You can list the available +emulations with the @samp{--verbose} or @samp{-V} options. + +If the @samp{-m} option is not used, the emulation is taken from the +@code{LDEMULATION} environment variable, if that is defined. + +Otherwise, the default emulation depends upon how the linker was +configured. + +@cindex link map +@kindex -M +@kindex --print-map +@item -M +@itemx --print-map +Print a link map to the standard output. A link map provides +information about the link, including the following: + +@itemize @bullet +@item +Where object files and symbols are mapped into memory. +@item +How common symbols are allocated. +@item +All archive members included in the link, with a mention of the symbol +which caused the archive member to be brought in. +@end itemize + +@kindex -n +@cindex read-only text +@cindex NMAGIC +@kindex --nmagic +@item -n +@itemx --nmagic +Set the text segment to be read only, and mark the output as +@code{NMAGIC} if possible. + +@kindex -N +@kindex --omagic +@cindex read/write from cmd line +@cindex OMAGIC +@item -N +@itemx --omagic +Set the text and data sections to be readable and writable. Also, do +not page-align the data segment. If the output format supports Unix +style magic numbers, mark the output as @code{OMAGIC}. + +@kindex -o @var{output} +@kindex --output=@var{output} +@cindex naming the output file +@item -o @var{output} +@itemx --output=@var{output} +Use @var{output} as the name for the program produced by @code{ld}; if this +option is not specified, the name @file{a.out} is used by default. The +script command @code{OUTPUT} can also specify the output file name. + +@kindex -O @var{level} +@cindex generating optimized output +@item -O @var{level} +If @var{level} is a numeric values greater than zero @code{ld} optimizes +the output. This might take significantly longer and therefore probably +should only be enabled for the final binary. + +@cindex partial link +@cindex relocatable output +@kindex -r +@kindex --relocateable +@item -r +@itemx --relocateable +Generate relocatable output---i.e., generate an output file that can in +turn serve as input to @code{ld}. This is often called @dfn{partial +linking}. As a side effect, in environments that support standard Unix +magic numbers, this option also sets the output file's magic number to +@code{OMAGIC}. +@c ; see @code{-N}. +If this option is not specified, an absolute file is produced. When +linking C++ programs, this option @emph{will not} resolve references to +constructors; to do that, use @samp{-Ur}. + +This option does the same thing as @samp{-i}. + +@kindex -R @var{file} +@kindex --just-symbols=@var{file} +@cindex symbol-only input +@item -R @var{filename} +@itemx --just-symbols=@var{filename} +Read symbol names and their addresses from @var{filename}, but do not +relocate it or include it in the output. This allows your output file +to refer symbolically to absolute locations of memory defined in other +programs. You may use this option more than once. + +For compatibility with other ELF linkers, if the @code{-R} option is +followed by a directory name, rather than a file name, it is treated as +the @code{-rpath} option. + +@kindex -s +@kindex --strip-all +@cindex strip all symbols +@item -s +@itemx --strip-all +Omit all symbol information from the output file. + +@kindex -S +@kindex --strip-debug +@cindex strip debugger symbols +@item -S +@itemx --strip-debug +Omit debugger symbol information (but not all symbols) from the output file. + +@kindex -t +@kindex --trace +@cindex input files, displaying +@item -t +@itemx --trace +Print the names of the input files as @code{ld} processes them. + +@kindex -T @var{script} +@kindex --script=@var{script} +@cindex script files +@item -T @var{scriptfile} +@itemx --script=@var{scriptfile} +Use @var{scriptfile} as the linker script. This script replaces +@code{ld}'s default linker script (rather than adding to it), so +@var{commandfile} must specify everything necessary to describe the +output file. You must use this option if you want to use a command +which can only appear once in a linker script, such as the +@code{SECTIONS} or @code{MEMORY} command. @xref{Scripts}. If +@var{scriptfile} does not exist in the current directory, @code{ld} +looks for it in the directories specified by any preceding @samp{-L} +options. Multiple @samp{-T} options accumulate. + +@kindex -u @var{symbol} +@kindex --undefined=@var{symbol} +@cindex undefined symbol +@item -u @var{symbol} +@itemx --undefined=@var{symbol} +Force @var{symbol} to be entered in the output file as an undefined +symbol. Doing this may, for example, trigger linking of additional +modules from standard libraries. @samp{-u} may be repeated with +different option arguments to enter additional undefined symbols. This +option is equivalent to the @code{EXTERN} linker script command. + +@kindex -Ur +@cindex constructors +@item -Ur +For anything other than C++ programs, this option is equivalent to +@samp{-r}: it generates relocatable output---i.e., an output file that can in +turn serve as input to @code{ld}. When linking C++ programs, @samp{-Ur} +@emph{does} resolve references to constructors, unlike @samp{-r}. +It does not work to use @samp{-Ur} on files that were themselves linked +with @samp{-Ur}; once the constructor table has been built, it cannot +be added to. Use @samp{-Ur} only for the last partial link, and +@samp{-r} for the others. + +@kindex -v +@kindex -V +@kindex --version +@cindex version +@item -v +@itemx --version +@itemx -V +Display the version number for @code{ld}. The @code{-V} option also +lists the supported emulations. + +@kindex -x +@kindex --discard-all +@cindex deleting local symbols +@item -x +@itemx --discard-all +Delete all local symbols. + +@kindex -X +@kindex --discard-locals +@cindex local symbols, deleting +@cindex L, deleting symbols beginning +@item -X +@itemx --discard-locals +Delete all temporary local symbols. For most targets, this is all local +symbols whose names begin with @samp{L}. + +@kindex -y @var{symbol} +@kindex --trace-symbol=@var{symbol} +@cindex symbol tracing +@item -y @var{symbol} +@itemx --trace-symbol=@var{symbol} +Print the name of each linked file in which @var{symbol} appears. This +option may be given any number of times. On many systems it is necessary +to prepend an underscore. + +This option is useful when you have an undefined symbol in your link but +don't know where the reference is coming from. + +@kindex -Y @var{path} +@item -Y @var{path} +Add @var{path} to the default library search path. This option exists +for Solaris compatibility. + +@kindex -z @var{keyword} +@item -z @var{keyword} +This option is ignored for Solaris compatibility. + +@kindex -( +@cindex groups of archives +@item -( @var{archives} -) +@itemx --start-group @var{archives} --end-group +The @var{archives} should be a list of archive files. They may be +either explicit file names, or @samp{-l} options. + +The specified archives are searched repeatedly until no new undefined +references are created. Normally, an archive is searched only once in +the order that it is specified on the command line. If a symbol in that +archive is needed to resolve an undefined symbol referred to by an +object in an archive that appears later on the command line, the linker +would not be able to resolve that reference. By grouping the archives, +they all be searched repeatedly until all possible references are +resolved. + +Using this option has a significant performance cost. It is best to use +it only when there are unavoidable circular references between two or +more archives. + +@kindex -assert @var{keyword} +@item -assert @var{keyword} +This option is ignored for SunOS compatibility. + +@kindex -Bdynamic +@kindex -dy +@kindex -call_shared +@item -Bdynamic +@itemx -dy +@itemx -call_shared +Link against dynamic libraries. This is only meaningful on platforms +for which shared libraries are supported. This option is normally the +default on such platforms. The different variants of this option are +for compatibility with various systems. You may use this option +multiple times on the command line: it affects library searching for +@code{-l} options which follow it. + +@kindex -Bstatic +@kindex -dn +@kindex -non_shared +@kindex -static +@item -Bstatic +@itemx -dn +@itemx -non_shared +@itemx -static +Do not link against shared libraries. This is only meaningful on +platforms for which shared libraries are supported. The different +variants of this option are for compatibility with various systems. You +may use this option multiple times on the command line: it affects +library searching for @code{-l} options which follow it. + +@kindex -Bsymbolic +@item -Bsymbolic +When creating a shared library, bind references to global symbols to the +definition within the shared library, if any. Normally, it is possible +for a program linked against a shared library to override the definition +within the shared library. This option is only meaningful on ELF +platforms which support shared libraries. + +@kindex --check-sections +@kindex --no-check-sections +@item --check-sections +@item --no-check-sections +Asks the linker @emph{not} to check section addresses after they have +been assigned to see if there any overlaps. Normally the linker will +perform this check, and if it finds any overlaps it will produce +suitable error messages. The linker does know about, and does make +allowances for sections in overlays. The default behaviour can be +restored by using the command line switch @samp{--check-sections}. + +@cindex cross reference table +@kindex --cref +@item --cref +Output a cross reference table. If a linker map file is being +generated, the cross reference table is printed to the map file. +Otherwise, it is printed on the standard output. + +The format of the table is intentionally simple, so that it may be +easily processed by a script if necessary. The symbols are printed out, +sorted by name. For each symbol, a list of file names is given. If the +symbol is defined, the first file listed is the location of the +definition. The remaining files contain references to the symbol. + +@cindex symbols, from command line +@kindex --defsym @var{symbol}=@var{exp} +@item --defsym @var{symbol}=@var{expression} +Create a global symbol in the output file, containing the absolute +address given by @var{expression}. You may use this option as many +times as necessary to define multiple symbols in the command line. A +limited form of arithmetic is supported for the @var{expression} in this +context: you may give a hexadecimal constant or the name of an existing +symbol, or use @code{+} and @code{-} to add or subtract hexadecimal +constants or symbols. If you need more elaborate expressions, consider +using the linker command language from a script (@pxref{Assignments,, +Assignment: Symbol Definitions}). @emph{Note:} there should be no white +space between @var{symbol}, the equals sign (``@key{=}''), and +@var{expression}. + +@cindex demangling, from command line +@kindex --demangle +@kindex --no-demangle +@item --demangle +@itemx --no-demangle +These options control whether to demangle symbol names in error messages +and other output. When the linker is told to demangle, it tries to +present symbol names in a readable fashion: it strips leading +underscores if they are used by the object file format, and converts C++ +mangled symbol names into user readable names. The linker will demangle +by default unless the environment variable @samp{COLLECT_NO_DEMANGLE} is +set. These options may be used to override the default. + +@cindex dynamic linker, from command line +@kindex --dynamic-linker @var{file} +@item --dynamic-linker @var{file} +Set the name of the dynamic linker. This is only meaningful when +generating dynamically linked ELF executables. The default dynamic +linker is normally correct; don't use this unless you know what you are +doing. + +@cindex MIPS embedded PIC code +@kindex --embedded-relocs +@item --embedded-relocs +This option is only meaningful when linking MIPS embedded PIC code, +generated by the -membedded-pic option to the @sc{gnu} compiler and +assembler. It causes the linker to create a table which may be used at +runtime to relocate any data which was statically initialized to pointer +values. See the code in testsuite/ld-empic for details. + +@kindex --force-exe-suffix +@item --force-exe-suffix +Make sure that an output file has a .exe suffix. + +If a successfully built fully linked output file does not have a +@code{.exe} or @code{.dll} suffix, this option forces the linker to copy +the output file to one of the same name with a @code{.exe} suffix. This +option is useful when using unmodified Unix makefiles on a Microsoft +Windows host, since some versions of Windows won't run an image unless +it ends in a @code{.exe} suffix. + +@kindex --gc-sections +@kindex --no-gc-sections +@cindex garbage collection +@item --no-gc-sections +@itemx --gc-sections +Enable garbage collection of unused input sections. It is ignored on +targets that do not support this option. This option is not compatible +with @samp{-r}, nor should it be used with dynamic linking. The default +behaviour (of not performing this garbage collection) can be restored by +specifying @samp{--no-gc-sections} on the command line. + +@cindex help +@cindex usage +@kindex --help +@item --help +Print a summary of the command-line options on the standard output and exit. + +@kindex -Map +@item -Map @var{mapfile} +Print a link map to the file @var{mapfile}. See the description of the +@samp{-M} option, above. + +@cindex memory usage +@kindex --no-keep-memory +@item --no-keep-memory +@code{ld} normally optimizes for speed over memory usage by caching the +symbol tables of input files in memory. This option tells @code{ld} to +instead optimize for memory usage, by rereading the symbol tables as +necessary. This may be required if @code{ld} runs out of memory space +while linking a large executable. + +@kindex --no-undefined +@item --no-undefined +Normally when creating a non-symbolic shared library, undefined symbols +are allowed and left to be resolved by the runtime loader. This option +disallows such undefined symbols. + +@kindex --no-warn-mismatch +@item --no-warn-mismatch +Normally @code{ld} will give an error if you try to link together input +files that are mismatched for some reason, perhaps because they have +been compiled for different processors or for different endiannesses. +This option tells @code{ld} that it should silently permit such possible +errors. This option should only be used with care, in cases when you +have taken some special action that ensures that the linker errors are +inappropriate. + +@kindex --no-whole-archive +@item --no-whole-archive +Turn off the effect of the @code{--whole-archive} option for subsequent +archive files. + +@cindex output file after errors +@kindex --noinhibit-exec +@item --noinhibit-exec +Retain the executable output file whenever it is still usable. +Normally, the linker will not produce an output file if it encounters +errors during the link process; it exits without writing an output file +when it issues any error whatsoever. + +@ifclear SingleFormat +@kindex --oformat +@item --oformat @var{output-format} +@code{ld} may be configured to support more than one kind of object +file. If your @code{ld} is configured this way, you can use the +@samp{--oformat} option to specify the binary format for the output +object file. Even when @code{ld} is configured to support alternative +object formats, you don't usually need to specify this, as @code{ld} +should be configured to produce as a default output format the most +usual format on each machine. @var{output-format} is a text string, the +name of a particular format supported by the BFD libraries. (You can +list the available binary formats with @samp{objdump -i}.) The script +command @code{OUTPUT_FORMAT} can also specify the output format, but +this option overrides it. @xref{BFD}. +@end ifclear + +@kindex -qmagic +@item -qmagic +This option is ignored for Linux compatibility. + +@kindex -Qy +@item -Qy +This option is ignored for SVR4 compatibility. + +@kindex --relax +@cindex synthesizing linker +@cindex relaxing addressing modes +@item --relax +An option with machine dependent effects. +@ifset GENERIC +This option is only supported on a few targets. +@end ifset +@ifset H8300 +@xref{H8/300,,@code{ld} and the H8/300}. +@end ifset +@ifset I960 +@xref{i960,, @code{ld} and the Intel 960 family}. +@end ifset + + +On some platforms, the @samp{--relax} option performs global +optimizations that become possible when the linker resolves addressing +in the program, such as relaxing address modes and synthesizing new +instructions in the output object file. + +On some platforms these link time global optimizations may make symbolic +debugging of the resulting executable impossible. +@ifset GENERIC +This is known to be +the case for the Matsushita MN10200 and MN10300 family of processors. +@end ifset + +@ifset GENERIC +On platforms where this is not supported, @samp{--relax} is accepted, +but ignored. +@end ifset + +@cindex retaining specified symbols +@cindex stripping all but some symbols +@cindex symbols, retaining selectively +@item --retain-symbols-file @var{filename} +Retain @emph{only} the symbols listed in the file @var{filename}, +discarding all others. @var{filename} is simply a flat file, with one +symbol name per line. This option is especially useful in environments +@ifset GENERIC +(such as VxWorks) +@end ifset +where a large global symbol table is accumulated gradually, to conserve +run-time memory. + +@samp{--retain-symbols-file} does @emph{not} discard undefined symbols, +or symbols needed for relocations. + +You may only specify @samp{--retain-symbols-file} once in the command +line. It overrides @samp{-s} and @samp{-S}. + +@ifset GENERIC +@item -rpath @var{dir} +@cindex runtime library search path +@kindex -rpath +Add a directory to the runtime library search path. This is used when +linking an ELF executable with shared objects. All @code{-rpath} +arguments are concatenated and passed to the runtime linker, which uses +them to locate shared objects at runtime. The @code{-rpath} option is +also used when locating shared objects which are needed by shared +objects explicitly included in the link; see the description of the +@code{-rpath-link} option. If @code{-rpath} is not used when linking an +ELF executable, the contents of the environment variable +@code{LD_RUN_PATH} will be used if it is defined. + +The @code{-rpath} option may also be used on SunOS. By default, on +SunOS, the linker will form a runtime search patch out of all the +@code{-L} options it is given. If a @code{-rpath} option is used, the +runtime search path will be formed exclusively using the @code{-rpath} +options, ignoring the @code{-L} options. This can be useful when using +gcc, which adds many @code{-L} options which may be on NFS mounted +filesystems. + +For compatibility with other ELF linkers, if the @code{-R} option is +followed by a directory name, rather than a file name, it is treated as +the @code{-rpath} option. +@end ifset + +@ifset GENERIC +@cindex link-time runtime library search path +@kindex -rpath-link +@item -rpath-link @var{DIR} +When using ELF or SunOS, one shared library may require another. This +happens when an @code{ld -shared} link includes a shared library as one +of the input files. + +When the linker encounters such a dependency when doing a non-shared, +non-relocatable link, it will automatically try to locate the required +shared library and include it in the link, if it is not included +explicitly. In such a case, the @code{-rpath-link} option +specifies the first set of directories to search. The +@code{-rpath-link} option may specify a sequence of directory names +either by specifying a list of names separated by colons, or by +appearing multiple times. + +The linker uses the following search paths to locate required shared +libraries. +@enumerate +@item +Any directories specified by @code{-rpath-link} options. +@item +Any directories specified by @code{-rpath} options. The difference +between @code{-rpath} and @code{-rpath-link} is that directories +specified by @code{-rpath} options are included in the executable and +used at runtime, whereas the @code{-rpath-link} option is only effective +at link time. +@item +On an ELF system, if the @code{-rpath} and @code{rpath-link} options +were not used, search the contents of the environment variable +@code{LD_RUN_PATH}. +@item +On SunOS, if the @code{-rpath} option was not used, search any +directories specified using @code{-L} options. +@item +For a native linker, the contents of the environment variable +@code{LD_LIBRARY_PATH}. +@item +The default directories, normally @file{/lib} and @file{/usr/lib}. +@item +For a native linker on an ELF system, if the file @file{/etc/ld.so.conf} +exists, the list of directories found in that file. +@end enumerate + +If the required shared library is not found, the linker will issue a +warning and continue with the link. +@end ifset + +@kindex -shared +@kindex -Bshareable +@item -shared +@itemx -Bshareable +@cindex shared libraries +Create a shared library. This is currently only supported on ELF, XCOFF +and SunOS platforms. On SunOS, the linker will automatically create a +shared library if the @code{-e} option is not used and there are +undefined symbols in the link. + +@item --sort-common +@kindex --sort-common +This option tells @code{ld} to sort the common symbols by size when it +places them in the appropriate output sections. First come all the one +byte symbols, then all the two bytes, then all the four bytes, and then +everything else. This is to prevent gaps between symbols due to +alignment constraints. + +@kindex --split-by-file +@item --split-by-file +Similar to @code{--split-by-reloc} but creates a new output section for +each input file. + +@kindex --split-by-reloc +@item --split-by-reloc @var{count} +Trys to creates extra sections in the output file so that no single +output section in the file contains more than @var{count} relocations. +This is useful when generating huge relocatable for downloading into +certain real time kernels with the COFF object file format; since COFF +cannot represent more than 65535 relocations in a single section. Note +that this will fail to work with object file formats which do not +support arbitrary sections. The linker will not split up individual +input sections for redistribution, so if a single input section contains +more than @var{count} relocations one output section will contain that +many relocations. + +@kindex --stats +@item --stats +Compute and display statistics about the operation of the linker, such +as execution time and memory usage. + +@kindex --traditional-format +@cindex traditional format +@item --traditional-format +For some targets, the output of @code{ld} is different in some ways from +the output of some existing linker. This switch requests @code{ld} to +use the traditional format instead. + +@cindex dbx +For example, on SunOS, @code{ld} combines duplicate entries in the +symbol string table. This can reduce the size of an output file with +full debugging information by over 30 percent. Unfortunately, the SunOS +@code{dbx} program can not read the resulting program (@code{gdb} has no +trouble). The @samp{--traditional-format} switch tells @code{ld} to not +combine duplicate entries. + +@kindex -Tbss @var{org} +@kindex -Tdata @var{org} +@kindex -Ttext @var{org} +@cindex segment origins, cmd line +@item -Tbss @var{org} +@itemx -Tdata @var{org} +@itemx -Ttext @var{org} +Use @var{org} as the starting address for---respectively---the +@code{bss}, @code{data}, or the @code{text} segment of the output file. +@var{org} must be a single hexadecimal integer; +for compatibility with other linkers, you may omit the leading +@samp{0x} usually associated with hexadecimal values. + +@kindex --verbose +@cindex verbose +@item --dll-verbose +@item --verbose +Display the version number for @code{ld} and list the linker emulations +supported. Display which input files can and cannot be opened. Display +the linker script if using a default builtin script. + +@kindex --version-script=@var{version-scriptfile} +@cindex version script, symbol versions +@itemx --version-script=@var{version-scriptfile} +Specify the name of a version script to the linker. This is typically +used when creating shared libraries to specify additional information +about the version heirarchy for the library being created. This option +is only meaningful on ELF platforms which support shared libraries. +@xref{VERSION}. + +@kindex --warn-comon +@cindex warnings, on combining symbols +@cindex combining symbols, warnings on +@item --warn-common +Warn when a common symbol is combined with another common symbol or with +a symbol definition. Unix linkers allow this somewhat sloppy practice, +but linkers on some other operating systems do not. This option allows +you to find potential problems from combining global symbols. +Unfortunately, some C libraries use this practice, so you may get some +warnings about symbols in the libraries as well as in your programs. + +There are three kinds of global symbols, illustrated here by C examples: + +@table @samp +@item int i = 1; +A definition, which goes in the initialized data section of the output +file. + +@item extern int i; +An undefined reference, which does not allocate space. +There must be either a definition or a common symbol for the +variable somewhere. + +@item int i; +A common symbol. If there are only (one or more) common symbols for a +variable, it goes in the uninitialized data area of the output file. +The linker merges multiple common symbols for the same variable into a +single symbol. If they are of different sizes, it picks the largest +size. The linker turns a common symbol into a declaration, if there is +a definition of the same variable. +@end table + +The @samp{--warn-common} option can produce five kinds of warnings. +Each warning consists of a pair of lines: the first describes the symbol +just encountered, and the second describes the previous symbol +encountered with the same name. One or both of the two symbols will be +a common symbol. + +@enumerate +@item +Turning a common symbol into a reference, because there is already a +definition for the symbol. +@smallexample +@var{file}(@var{section}): warning: common of `@var{symbol}' + overridden by definition +@var{file}(@var{section}): warning: defined here +@end smallexample + +@item +Turning a common symbol into a reference, because a later definition for +the symbol is encountered. This is the same as the previous case, +except that the symbols are encountered in a different order. +@smallexample +@var{file}(@var{section}): warning: definition of `@var{symbol}' + overriding common +@var{file}(@var{section}): warning: common is here +@end smallexample + +@item +Merging a common symbol with a previous same-sized common symbol. +@smallexample +@var{file}(@var{section}): warning: multiple common + of `@var{symbol}' +@var{file}(@var{section}): warning: previous common is here +@end smallexample + +@item +Merging a common symbol with a previous larger common symbol. +@smallexample +@var{file}(@var{section}): warning: common of `@var{symbol}' + overridden by larger common +@var{file}(@var{section}): warning: larger common is here +@end smallexample + +@item +Merging a common symbol with a previous smaller common symbol. This is +the same as the previous case, except that the symbols are +encountered in a different order. +@smallexample +@var{file}(@var{section}): warning: common of `@var{symbol}' + overriding smaller common +@var{file}(@var{section}): warning: smaller common is here +@end smallexample +@end enumerate + +@kindex --warn-constructors +@item --warn-constructors +Warn if any global constructors are used. This is only useful for a few +object file formats. For formats like COFF or ELF, the linker can not +detect the use of global constructors. + +@kindex --warn-multiple-gp +@item --warn-multiple-gp +Warn if multiple global pointer values are required in the output file. +This is only meaningful for certain processors, such as the Alpha. +Specifically, some processors put large-valued constants in a special +section. A special register (the global pointer) points into the middle +of this section, so that constants can be loaded efficiently via a +base-register relative addressing mode. Since the offset in +base-register relative mode is fixed and relatively small (e.g., 16 +bits), this limits the maximum size of the constant pool. Thus, in +large programs, it is often necessary to use multiple global pointer +values in order to be able to address all possible constants. This +option causes a warning to be issued whenever this case occurs. + +@kindex --warn-once +@cindex warnings, on undefined symbols +@cindex undefined symbols, warnings on +@item --warn-once +Only warn once for each undefined symbol, rather than once per module +which refers to it. + +@kindex --warn-section-align +@cindex warnings, on section alignment +@cindex section alignment, warnings on +@item --warn-section-align +Warn if the address of an output section is changed because of +alignment. Typically, the alignment will be set by an input section. +The address will only be changed if it not explicitly specified; that +is, if the @code{SECTIONS} command does not specify a start address for +the section (@pxref{SECTIONS}). + +@kindex --whole-archive +@cindex including an entire archive +@item --whole-archive +For each archive mentioned on the command line after the +@code{--whole-archive} option, include every object file in the archive +in the link, rather than searching the archive for the required object +files. This is normally used to turn an archive file into a shared +library, forcing every object to be included in the resulting shared +library. This option may be used more than once. + +@kindex --wrap +@item --wrap @var{symbol} +Use a wrapper function for @var{symbol}. Any undefined reference to +@var{symbol} will be resolved to @code{__wrap_@var{symbol}}. Any +undefined reference to @code{__real_@var{symbol}} will be resolved to +@var{symbol}. + +This can be used to provide a wrapper for a system function. The +wrapper function should be called @code{__wrap_@var{symbol}}. If it +wishes to call the system function, it should call +@code{__real_@var{symbol}}. + +Here is a trivial example: + +@smallexample +void * +__wrap_malloc (int c) +@{ + printf ("malloc called with %ld\n", c); + return __real_malloc (c); +@} +@end smallexample + +If you link other code with this file using @code{--wrap malloc}, then +all calls to @code{malloc} will call the function @code{__wrap_malloc} +instead. The call to @code{__real_malloc} in @code{__wrap_malloc} will +call the real @code{malloc} function. + +You may wish to provide a @code{__real_malloc} function as well, so that +links without the @code{--wrap} option will succeed. If you do this, +you should not put the definition of @code{__real_malloc} in the same +file as @code{__wrap_malloc}; if you do, the assembler may resolve the +call before the linker has a chance to wrap it to @code{malloc}. + +@end table + +@subsection Options specific to i386 PE targets + +The i386 PE linker supports the @code{-shared} option, which causes +the output to be a dynamically linked library (DLL) instead of a +normal executable. You should name the output @code{*.dll} when you +use this option. In addition, the linker fully supports the standard +@code{*.def} files, which may be specified on the linker command line +like an object file (in fact, it should precede archives it exports +symbols from, to ensure that they get linked in, just like a normal +object file). + +In addition to the options common to all targets, the i386 PE linker +support additional command line options that are specific to the i386 +PE target. Options that take values may be separated from their +values by either a space or an equals sign. + +@table @code + +@kindex --add-stdcall-alias +@item --add-stdcall-alias +If given, symbols with a stdcall suffix (@@@var{nn}) will be exported +as-is and also with the suffix stripped. + +@kindex --base-file +@item --base-file @var{file} +Use @var{file} as the name of a file in which to save the base +addresses of all the relocations needed for generating DLLs with +@file{dlltool}. + +@kindex --dll +@item --dll +Create a DLL instead of a regular executable. You may also use +@code{-shared} or specify a @code{LIBRARY} in a given @code{.def} +file. + +@kindex --enable-stdcall-fixup +@kindex --disable-stdcall-fixup +@item --enable-stdcall-fixup +@itemx --disable-stdcall-fixup +If the link finds a symbol that it cannot resolve, it will attempt to +do "fuzzy linking" by looking for another defined symbol that differs +only in the format of the symbol name (cdecl vs stdcall) and will +resolve that symbol by linking to the match. For example, the +undefined symbol @code{_foo} might be linked to the function +@code{_foo@@12}, or the undefined symbol @code{_bar@@16} might be linked +to the function @code{_bar}. When the linker does this, it prints a +warning, since it normally should have failed to link, but sometimes +import libraries generated from third-party dlls may need this feature +to be usable. If you specify @code{--enable-stdcall-fixup}, this +feature is fully enabled and warnings are not printed. If you specify +@code{--disable-stdcall-fixup}, this feature is disabled and such +mismatches are considered to be errors. + +@cindex DLLs, creating +@kindex --export-all-symbols +@item --export-all-symbols +If given, all global symbols in the objects used to build a DLL will +be exported by the DLL. Note that this is the default if there +otherwise wouldn't be any exported symbols. When symbols are +explicitly exported via DEF files or implicitly exported via function +attributes, the default is to not export anything else unless this +option is given. Note that the symbols @code{DllMain@@12}, +@code{DllEntryPoint@@0}, and @code{impure_ptr} will not be automatically +exported. + +@kindex --exclude-symbols +@item --exclude-symbols @var{symbol,symbol,...} +Specifies a list of symbols which should not be automatically +exported. The symbol names may be delimited by commas or colons. + +@kindex --file-alignment +@item --file-alignment +Specify the file alignment. Sections in the file will always begin at +file offsets which are multiples of this number. This defaults to +512. + +@cindex heap size +@kindex --heap +@item --heap @var{reserve} +@itemx --heap @var{reserve},@var{commit} +Specify the amount of memory to reserve (and optionally commit) to be +used as heap for this program. The default is 1Mb reserved, 4K +committed. + +@cindex image base +@kindex --image-base +@item --image-base @var{value} +Use @var{value} as the base address of your program or dll. This is +the lowest memory location that will be used when your program or dll +is loaded. To reduce the need to relocate and improve performance of +your dlls, each should have a unique base address and not overlap any +other dlls. The default is 0x400000 for executables, and 0x10000000 +for dlls. + +@kindex --kill-at +@item --kill-at +If given, the stdcall suffixes (@@@var{nn}) will be stripped from +symbols before they are exported. + +@kindex --major-image-version +@item --major-image-version @var{value} +Sets the major number of the "image version". Defaults to 1. + +@kindex --major-os-version +@item --major-os-version @var{value} +Sets the major number of the "os version". Defaults to 4. + +@kindex --major-subsystem-version +@item --major-subsystem-version @var{value} +Sets the major number of the "subsystem version". Defaults to 4. + +@kindex --minor-image-version +@item --minor-image-version @var{value} +Sets the minor number of the "image version". Defaults to 0. + +@kindex --minor-os-version +@item --minor-os-version @var{value} +Sets the minor number of the "os version". Defaults to 0. + +@kindex --minor-subsystem-version +@item --minor-subsystem-version @var{value} +Sets the minor number of the "subsystem version". Defaults to 0. + +@cindex DEF files, creating +@cindex DLLs, creating +@kindex --output-def +@item --output-def @var{file} +The linker will create the file @var{file} which will contain a DEF +file corresponding to the DLL the linker is generating. This DEF file +(which should be called @code{*.def}) may be used to create an import +library with @code{dlltool} or may be used as a reference to +automatically or implicitly exported symbols. + +@kindex --section-alignment +@item --section-alignment +Sets the section alignment. Sections in memory will always begin at +addresses which are a multiple of this number. Defaults to 0x1000. + +@cindex stack size +@kindex --stack +@item --stack @var{reserve} +@itemx --stack @var{reserve},@var{commit} +Specify the amount of memory to reserve (and optionally commit) to be +used as stack for this program. The default is 32Mb reserved, 4K +committed. + +@kindex --subsystem +@item --subsystem @var{which} +@itemx --subsystem @var{which}:@var{major} +@itemx --subsystem @var{which}:@var{major}.@var{minor} +Specifies the subsystem under which your program will execute. The +legal values for @var{which} are @code{native}, @code{windows}, +@code{console}, and @code{posix}. You may optionally set the +subsystem version also. + +@end table + +@ifset UsesEnvVars +@node Environment +@section Environment Variables + +You can change the behavior of @code{ld} with the environment variables +@code{GNUTARGET}, @code{LDEMULATION}, and @code{COLLECT_NO_DEMANGLE}. + +@kindex GNUTARGET +@cindex default input format +@code{GNUTARGET} determines the input-file object format if you don't +use @samp{-b} (or its synonym @samp{--format}). Its value should be one +of the BFD names for an input format (@pxref{BFD}). If there is no +@code{GNUTARGET} in the environment, @code{ld} uses the natural format +of the target. If @code{GNUTARGET} is set to @code{default} then BFD +attempts to discover the input format by examining binary input files; +this method often succeeds, but there are potential ambiguities, since +there is no method of ensuring that the magic number used to specify +object-file formats is unique. However, the configuration procedure for +BFD on each system places the conventional format for that system first +in the search-list, so ambiguities are resolved in favor of convention. + +@kindex LDEMULATION +@cindex default emulation +@cindex emulation, default +@code{LDEMULATION} determines the default emulation if you don't use the +@samp{-m} option. The emulation can affect various aspects of linker +behaviour, particularly the default linker script. You can list the +available emulations with the @samp{--verbose} or @samp{-V} options. If +the @samp{-m} option is not used, and the @code{LDEMULATION} environment +variable is not defined, the default emulation depends upon how the +linker was configured. +@end ifset + +@kindex COLLECT_NO_DEMANGLE +@cindex demangling, default +Normally, the linker will default to demangling symbols. However, if +@code{COLLECT_NO_DEMANGLE} is set in the environment, then it will +default to not demangling symbols. This environment variable is used in +a similar fashion by the @code{gcc} linker wrapper program. The default +may be overridden by the @samp{--demangle} and @samp{--no-demangle} +options. + +@node Scripts +@chapter Linker Scripts + +@cindex scripts +@cindex linker scripts +@cindex command files +Every link is controlled by a @dfn{linker script}. This script is +written in the linker command language. + +The main purpose of the linker script is to describe how the sections in +the input files should be mapped into the output file, and to control +the memory layout of the output file. Most linker scripts do nothing +more than this. However, when necessary, the linker script can also +direct the linker to perform many other operations, using the commands +described below. + +The linker always uses a linker script. If you do not supply one +yourself, the linker will use a default script that is compiled into the +linker executable. You can use the @samp{--verbose} command line option +to display the default linker script. Certain command line options, +such as @samp{-r} or @samp{-N}, will affect the default linker script. + +You may supply your own linker script by using the @samp{-T} command +line option. When you do this, your linker script will replace the +default linker script. + +You may also use linker scripts implicitly by naming them as input files +to the linker, as though they were files to be linked. @xref{Implicit +Linker Scripts}. + +@menu +* Basic Script Concepts:: Basic Linker Script Concepts +* Script Format:: Linker Script Format +* Simple Example:: Simple Linker Script Example +* Simple Commands:: Simple Linker Script Commands +* Assignments:: Assigning Values to Symbols +* SECTIONS:: SECTIONS Command +* MEMORY:: MEMORY Command +* PHDRS:: PHDRS Command +* VERSION:: VERSION Command +* Expressions:: Expressions in Linker Scripts +* Implicit Linker Scripts:: Implicit Linker Scripts +@end menu + +@node Basic Script Concepts +@section Basic Linker Script Concepts +@cindex linker script concepts +We need to define some basic concepts and vocabulary in order to +describe the linker script language. + +The linker combines input files into a single output file. The output +file and each input file are in a special data format known as an +@dfn{object file format}. Each file is called an @dfn{object file}. +The output file is often called an @dfn{executable}, but for our +purposes we will also call it an object file. Each object file has, +among other things, a list of @dfn{sections}. We sometimes refer to a +section in an input file as an @dfn{input section}; similarly, a section +in the output file is an @dfn{output section}. + +Each section in an object file has a name and a size. Most sections +also have an associated block of data, known as the @dfn{section +contents}. A section may be marked as @dfn{loadable}, which mean that +the contents should be loaded into memory when the output file is run. +A section with no contents may be @dfn{allocatable}, which means that an +area in memory should be set aside, but nothing in particular should be +loaded there (in some cases this memory must be zeroed out). A section +which is neither loadable nor allocatable typically contains some sort +of debugging information. + +Every loadable or allocatable output section has two addresses. The +first is the @dfn{VMA}, or virtual memory address. This is the address +the section will have when the output file is run. The second is the +@dfn{LMA}, or load memory address. This is the address at which the +section will be loaded. In most cases the two addresses will be the +same. An example of when they might be different is when a data section +is loaded into ROM, and then copied into RAM when the program starts up +(this technique is often used to initialize global variables in a ROM +based system). In this case the ROM address would be the LMA, and the +RAM address would be the VMA. + +You can see the sections in an object file by using the @code{objdump} +program with the @samp{-h} option. + +Every object file also has a list of @dfn{symbols}, known as the +@dfn{symbol table}. A symbol may be defined or undefined. Each symbol +has a name, and each defined symbol has an address, among other +information. If you compile a C or C++ program into an object file, you +will get a defined symbol for every defined function and global or +static variable. Every undefined function or global variable which is +referenced in the input file will become an undefined symbol. + +You can see the symbols in an object file by using the @code{nm} +program, or by using the @code{objdump} program with the @samp{-t} +option. + +@node Script Format +@section Linker Script Format +@cindex linker script format +Linker scripts are text files. + +You write a linker script as a series of commands. Each command is +either a keyword, possibly followed by arguments, or an assignment to a +symbol. You may separate commands using semicolons. Whitespace is +generally ignored. + +Strings such as file or format names can normally be entered directly. +If the file name contains a character such as a comma which would +otherwise serve to separate file names, you may put the file name in +double quotes. There is no way to use a double quote character in a +file name. + +You may include comments in linker scripts just as in C, delimited by +@samp{/*} and @samp{*/}. As in C, comments are syntactically equivalent +to whitespace. + +@node Simple Example +@section Simple Linker Script Example +@cindex linker script example +@cindex example of linker script +Many linker scripts are fairly simple. + +The simplest possible linker script has just one command: +@samp{SECTIONS}. You use the @samp{SECTIONS} command to describe the +memory layout of the output file. + +The @samp{SECTIONS} command is a powerful command. Here we will +describe a simple use of it. Let's assume your program consists only of +code, initialized data, and uninitialized data. These will be in the +@samp{.text}, @samp{.data}, and @samp{.bss} sections, respectively. +Let's assume further that these are the only sections which appear in +your input files. + +For this example, let's say that the code should be loaded at address +0x10000, and that the data should start at address 0x8000000. Here is a +linker script which will do that: +@smallexample +SECTIONS +@{ + . = 0x10000; + .text : @{ *(.text) @} + . = 0x8000000; + .data : @{ *(.data) @} + .bss : @{ *(.bss) @} +@} +@end smallexample + +You write the @samp{SECTIONS} command as the keyword @samp{SECTIONS}, +followed by a series of symbol assignments and output section +descriptions enclosed in curly braces. + +The first line in the above example sets the special symbol @samp{.}, +which is the location counter. If you do not specify the address of an +output section in some other way (other ways are described later), the +address is set from the current value of the location counter. The +location counter is then incremented by the size of the output section. + +The first line inside the @samp{SECTIONS} command of the above example +sets the value of the special symbol @samp{.}, which is the location +counter. If you do not specify the address of an output section in some +other way (other ways are described later), the address is set from the +current value of the location counter. The location counter is then +incremented by the size of the output section. At the start of the +@samp{SECTIONS} command, the location counter has the value @samp{0}. + +The second line defines an output section, @samp{.text}. The colon is +required syntax which may be ignored for now. Within the curly braces +after the output section name, you list the names of the input sections +which should be placed into this output section. The @samp{*} is a +wildcard which matches any file name. The expression @samp{*(.text)} +means all @samp{.text} input sections in all input files. + +Since the location counter is @samp{0x10000} when the output section +@samp{.text} is defined, the linker will set the address of the +@samp{.text} section in the output file to be @samp{0x10000}. + +The remaining lines define the @samp{.data} and @samp{.bss} sections in +the output file. The linker will place the @samp{.data} output section +at address @samp{0x8000000}. After the linker places the @samp{.data} +output section, the value of the location counter will be +@samp{0x8000000} plus the size of the @samp{.data} output section. The +effect is that the linker will place the @samp{.bss} output section +immediately after the @samp{.data} output section in memory + +The linker will ensure that each output section has the required +alignment, by increasing the location counter if necessary. In this +example, the specified addresses for the @samp{.text} and @samp{.data} +sections will probably satisfy any alignment constraints, but the linker +may have to create a small gap between the @samp{.data} and @samp{.bss} +sections. + +That's it! That's a simple and complete linker script. + +@node Simple Commands +@section Simple Linker Script Commands +@cindex linker script simple commands +In this section we describe the simple linker script commands. + +@menu +* Entry Point:: Setting the entry point +* File Commands:: Commands dealing with files +@ifclear SingleFormat +* Format Commands:: Commands dealing with object file formats +@end ifclear + +* Miscellaneous Commands:: Other linker script commands +@end menu + +@node Entry Point +@subsection Setting the entry point +@kindex ENTRY(@var{symbol}) +@cindex start of execution +@cindex first instruction +@cindex entry point +The first instruction to execute in a program is called the @dfn{entry +point}. You can use the @code{ENTRY} linker script command to set the +entry point. The argument is a symbol name: +@smallexample +ENTRY(@var{symbol}) +@end smallexample + +There are several ways to set the entry point. The linker will set the +entry point by trying each of the following methods in order, and +stopping when one of them succeeds: +@itemize @bullet +@item +the @samp{-e} @var{entry} command-line option; +@item +the @code{ENTRY(@var{symbol})} command in a linker script; +@item +the value of the symbol @code{start}, if defined; +@item +the address of the first byte of the @samp{.text} section, if present; +@item +The address @code{0}. +@end itemize + +@node File Commands +@subsection Commands dealing with files +@cindex linker script file commands +Several linker script commands deal with files. + +@table @code +@item INCLUDE @var{filename} +@kindex INCLUDE @var{filename} +@cindex including a linker script +Include the linker script @var{filename} at this point. The file will +be searched for in the current directory, and in any directory specified +with the @code{-L} option. You can nest calls to @code{INCLUDE} up to +10 levels deep. + +@item INPUT(@var{file}, @var{file}, @dots{}) +@itemx INPUT(@var{file} @var{file} @dots{}) +@kindex INPUT(@var{files}) +@cindex input files in linker scripts +@cindex input object files in linker scripts +@cindex linker script input object files +The @code{INPUT} command directs the linker to include the named files +in the link, as though they were named on the command line. + +For example, if you always want to include @file{subr.o} any time you do +a link, but you can't be bothered to put it on every link command line, +then you can put @samp{INPUT (subr.o)} in your linker script. + +In fact, if you like, you can list all of your input files in the linker +script, and then invoke the linker with nothing but a @samp{-T} option. + +The linker will first try to open the file in the current directory. If +it is not found, the linker will search through the archive library +search path. See the description of @samp{-L} in @ref{Options,,Command +Line Options}. + +If you use @samp{INPUT (-l@var{file})}, @code{ld} will transform the +name to @code{lib@var{file}.a}, as with the command line argument +@samp{-l}. + +When you use the @code{INPUT} command in an implicit linker script, the +files will be included in the link at the point at which the linker +script file is included. This can affect archive searching. + +@item GROUP(@var{file}, @var{file}, @dots{}) +@itemx GROUP(@var{file} @var{file} @dots{}) +@kindex GROUP(@var{files}) +@cindex grouping input files +The @code{GROUP} command is like @code{INPUT}, except that the named +files should all be archives, and they are searched repeatedly until no +new undefined references are created. See the description of @samp{-(} +in @ref{Options,,Command Line Options}. + +@item OUTPUT(@var{filename}) +@kindex OUTPUT(@var{filename}) +@cindex output file name in linker scripot +The @code{OUTPUT} command names the output file. Using +@code{OUTPUT(@var{filename})} in the linker script is exactly like using +@samp{-o @var{filename}} on the command line (@pxref{Options,,Command +Line Options}). If both are used, the command line option takes +precedence. + +You can use the @code{OUTPUT} command to define a default name for the +output file other than the usual default of @file{a.out}. + +@item SEARCH_DIR(@var{path}) +@kindex SEARCH_DIR(@var{path}) +@cindex library search path in linker script +@cindex archive search path in linker script +@cindex search path in linker script +The @code{SEARCH_DIR} command adds @var{path} to the list of paths where +@code{ld} looks for archive libraries. Using +@code{SEARCH_DIR(@var{path})} is exactly like using @samp{-L @var{path}} +on the command line (@pxref{Options,,Command Line Options}). If both +are used, then the linker will search both paths. Paths specified using +the command line option are searched first. + +@item STARTUP(@var{filename}) +@kindex STARTUP(@var{filename}) +@cindex first input file +The @code{STARTUP} command is just like the @code{INPUT} command, except +that @var{filename} will become the first input file to be linked, as +though it were specified first on the command line. This may be useful +when using a system in which the entry point is always the start of the +first file. +@end table + +@ifclear SingleFormat +@node Format Commands +@subsection Commands dealing with object file formats +A couple of linker script commands deal with object file formats. + +@table @code +@item OUTPUT_FORMAT(@var{bfdname}) +@itemx OUTPUT_FORMAT(@var{default}, @var{big}, @var{little}) +@kindex OUTPUT_FORMAT(@var{bfdname}) +@cindex output file format in linker script +The @code{OUTPUT_FORMAT} command names the BFD format to use for the +output file (@pxref{BFD}). Using @code{OUTPUT_FORMAT(@var{bfdname})} is +exactly like using @samp{-oformat @var{bfdname}} on the command line +(@pxref{Options,,Command Line Options}). If both are used, the command +line option takes precedence. + +You can use @code{OUTPUT_FORMAT} with three arguments to use different +formats based on the @samp{-EB} and @samp{-EL} command line options. +This permits the linker script to set the output format based on the +desired endianness. + +If neither @samp{-EB} nor @samp{-EL} are used, then the output format +will be the first argument, @var{default}. If @samp{-EB} is used, the +output format will be the second argument, @var{big}. If @samp{-EL} is +used, the output format will be the third argument, @var{little}. + +For example, the default linker script for the MIPS ELF target uses this +command: +@smallexample +OUTPUT_FORMAT(elf32-bigmips, elf32-bigmips, elf32-littlemips) +@end smallexample +This says that the default format for the output file is +@samp{elf32-bigmips}, but if the user uses the @samp{-EL} command line +option, the output file will be created in the @samp{elf32-littlemips} +format. + +@item TARGET(@var{bfdname}) +@kindex TARGET(@var{bfdname}) +@cindex input file format in linker script +The @code{TARGET} command names the BFD format to use when reading input +files. It affects subsequent @code{INPUT} and @code{GROUP} commands. +This command is like using @samp{-b @var{bfdname}} on the command line +(@pxref{Options,,Command Line Options}). If the @code{TARGET} command +is used but @code{OUTPUT_FORMAT} is not, then the last @code{TARGET} +command is also used to set the format for the output file. @xref{BFD}. +@end table +@end ifclear + +@node Miscellaneous Commands +@subsection Other linker script commands +There are a few other linker scripts commands. + +@table @code +@item ASSERT(@var{exp}, @var{message}) +@kindex ASSERT +@cindex assertion in linker script +Ensure that @var{exp} is non-zero. If it is zero, then exit the linker +with an error code, and print @var{message}. + +@item EXTERN(@var{symbol} @var{symbol} @dots{}) +@kindex EXTERN +@cindex undefined symbol in linker script +Force @var{symbol} to be entered in the output file as an undefined +symbol. Doing this may, for example, trigger linking of additional +modules from standard libraries. You may list several @var{symbol}s for +each @code{EXTERN}, and you may use @code{EXTERN} multiple times. This +command has the same effect as the @samp{-u} command-line option. + +@item FORCE_COMMON_ALLOCATION +@kindex FORCE_COMMON_ALLOCATION +@cindex common allocation in linker script +This command has the same effect as the @samp{-d} command-line option: +to make @code{ld} assign space to common symbols even if a relocatable +output file is specified (@samp{-r}). + +@item NOCROSSREFS(@var{section} @var{section} @dots{}) +@kindex NOCROSSREFS(@var{sections}) +@cindex cross references +This command may be used to tell @code{ld} to issue an error about any +references among certain output sections. + +In certain types of programs, particularly on embedded systems when +using overlays, when one section is loaded into memory, another section +will not be. Any direct references between the two sections would be +errors. For example, it would be an error if code in one section called +a function defined in the other section. + +The @code{NOCROSSREFS} command takes a list of output section names. If +@code{ld} detects any cross references between the sections, it reports +an error and returns a non-zero exit status. Note that the +@code{NOCROSSREFS} command uses output section names, not input section +names. + +@ifclear SingleFormat +@item OUTPUT_ARCH(@var{bfdarch}) +@kindex OUTPUT_ARCH(@var{bfdarch}) +@cindex machine architecture +@cindex architecture +Specify a particular output machine architecture. The argument is one +of the names used by the BFD library (@pxref{BFD}). You can see the +architecture of an object file by using the @code{objdump} program with +the @samp{-f} option. +@end ifclear +@end table + +@node Assignments +@section Assigning Values to Symbols +@cindex assignment in scripts +@cindex symbol definition, scripts +@cindex variables, defining +You may assign a value to a symbol in a linker script. This will define +the symbol as a global symbol. + +@menu +* Simple Assignments:: Simple Assignments +* PROVIDE:: PROVIDE +@end menu + +@node Simple Assignments +@subsection Simple Assignments + +You may assign to a symbol using any of the C assignment operators: + +@table @code +@item @var{symbol} = @var{expression} ; +@itemx @var{symbol} += @var{expression} ; +@itemx @var{symbol} -= @var{expression} ; +@itemx @var{symbol} *= @var{expression} ; +@itemx @var{symbol} /= @var{expression} ; +@itemx @var{symbol} <<= @var{expression} ; +@itemx @var{symbol} >>= @var{expression} ; +@itemx @var{symbol} &= @var{expression} ; +@itemx @var{symbol} |= @var{expression} ; +@end table + +The first case will define @var{symbol} to the value of +@var{expression}. In the other cases, @var{symbol} must already be +defined, and the value will be adjusted accordingly. + +The special symbol name @samp{.} indicates the location counter. You +may only use this within a @code{SECTIONS} command. + +The semicolon after @var{expression} is required. + +Expressions are defined below; see @ref{Expressions}. + +You may write symbol assignments as commands in their own right, or as +statements within a @code{SECTIONS} command, or as part of an output +section description in a @code{SECTIONS} command. + +The section of the symbol will be set from the section of the +expression; for more information, see @ref{Expression Section}. + +Here is an example showing the three different places that symbol +assignments may be used: + +@smallexample +floating_point = 0; +SECTIONS +@{ + .text : + @{ + *(.text) + _etext = .; + @} + _bdata = (. + 3) & ~ 4; + .data : @{ *(.data) @} +@} +@end smallexample +@noindent +In this example, the symbol @samp{floating_point} will be defined as +zero. The symbol @samp{_etext} will be defined as the address following +the last @samp{.text} input section. The symbol @samp{_bdata} will be +defined as the address following the @samp{.text} output section aligned +upward to a 4 byte boundary. + +@node PROVIDE +@subsection PROVIDE +@cindex PROVIDE +In some cases, it is desirable for a linker script to define a symbol +only if it is referenced and is not defined by any object included in +the link. For example, traditional linkers defined the symbol +@samp{etext}. However, ANSI C requires that the user be able to use +@samp{etext} as a function name without encountering an error. The +@code{PROVIDE} keyword may be used to define a symbol, such as +@samp{etext}, only if it is referenced but not defined. The syntax is +@code{PROVIDE(@var{symbol} = @var{expression})}. + +Here is an example of using @code{PROVIDE} to define @samp{etext}: +@smallexample +SECTIONS +@{ + .text : + @{ + *(.text) + _etext = .; + PROVIDE(etext = .); + @} +@} +@end smallexample + +In this example, if the program defines @samp{_etext} (with a leading +underscore), the linker will give a multiple definition error. If, on +the other hand, the program defines @samp{etext} (with no leading +underscore), the linker will silently use the definition in the program. +If the program references @samp{etext} but does not define it, the +linker will use the definition in the linker script. + +@node SECTIONS +@section SECTIONS command +@kindex SECTIONS +The @code{SECTIONS} command tells the linker how to map input sections +into output sections, and how to place the output sections in memory. + +The format of the @code{SECTIONS} command is: +@smallexample +SECTIONS +@{ + @var{sections-command} + @var{sections-command} + @dots{} +@} +@end smallexample + +Each @var{sections-command} may of be one of the following: + +@itemize @bullet +@item +an @code{ENTRY} command (@pxref{Entry Point,,Entry command}) +@item +a symbol assignment (@pxref{Assignments}) +@item +an output section description +@item +an overlay description +@end itemize + +The @code{ENTRY} command and symbol assignments are permitted inside the +@code{SECTIONS} command for convenience in using the location counter in +those commands. This can also make the linker script easier to +understand because you can use those commands at meaningful points in +the layout of the output file. + +Output section descriptions and overlay descriptions are described +below. + +If you do not use a @code{SECTIONS} command in your linker script, the +linker will place each input section into an identically named output +section in the order that the sections are first encountered in the +input files. If all input sections are present in the first file, for +example, the order of sections in the output file will match the order +in the first input file. The first section will be at address zero. + +@menu +* Output Section Description:: Output section description +* Output Section Name:: Output section name +* Output Section Address:: Output section address +* Input Section:: Input section description +* Output Section Data:: Output section data +* Output Section Keywords:: Output section keywords +* Output Section Discarding:: Output section discarding +* Output Section Attributes:: Output section attributes +* Overlay Description:: Overlay description +@end menu + +@node Output Section Description +@subsection Output section description +The full description of an output section looks like this: +@smallexample +@group +@var{section} [@var{address}] [(@var{type})] : [AT(@var{lma})] + @{ + @var{output-section-command} + @var{output-section-command} + @dots{} + @} [>@var{region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}] +@end group +@end smallexample + +Most output sections do not use most of the optional section attributes. + +The whitespace around @var{section} is required, so that the section +name is unambiguous. The colon and the curly braces are also required. +The line breaks and other white space are optional. + +Each @var{output-section-command} may be one of the following: + +@itemize @bullet +@item +a symbol assignment (@pxref{Assignments}) +@item +an input section description (@pxref{Input Section}) +@item +data values to include directly (@pxref{Output Section Data}) +@item +a special output section keyword (@pxref{Output Section Keywords}) +@end itemize + +@node Output Section Name +@subsection Output section name +@cindex name, section +@cindex section name +The name of the output section is @var{section}. @var{section} must +meet the constraints of your output format. In formats which only +support a limited number of sections, such as @code{a.out}, the name +must be one of the names supported by the format (@code{a.out}, for +example, allows only @samp{.text}, @samp{.data} or @samp{.bss}). If the +output format supports any number of sections, but with numbers and not +names (as is the case for Oasys), the name should be supplied as a +quoted numeric string. A section name may consist of any sequence of +characters, but a name which contains any unusual characters such as +commas must be quoted. + +The output section name @samp{/DISCARD/} is special; @ref{Output Section +Discarding}. + +@node Output Section Address +@subsection Output section address +@cindex address, section +@cindex section address +The @var{address} is an expression for the VMA (the virtual memory +address) of the output section. If you do not provide @var{address}, +the linker will set it based on @var{region} if present, or otherwise +based on the current value of the location counter. + +If you provide @var{address}, the address of the output section will be +set to precisely that. If you provide neither @var{address} nor +@var{region}, then the address of the output section will be set to the +current value of the location counter aligned to the alignment +requirements of the output section. The alignment requirement of the +output section is the strictest alignment of any input section contained +within the output section. + +For example, +@smallexample +.text . : @{ *(.text) @} +@end smallexample +@noindent +and +@smallexample +.text : @{ *(.text) @} +@end smallexample +@noindent +are subtly different. The first will set the address of the +@samp{.text} output section to the current value of the location +counter. The second will set it to the current value of the location +counter aligned to the strictest alignment of a @samp{.text} input +section. + +The @var{address} may be an arbitrary expression; @ref{Expressions}. +For example, if you want to align the section on a 0x10 byte boundary, +so that the lowest four bits of the section address are zero, you could +do something like this: +@smallexample +.text ALIGN(0x10) : @{ *(.text) @} +@end smallexample +@noindent +This works because @code{ALIGN} returns the current location counter +aligned upward to the specified value. + +Specifying @var{address} for a section will change the value of the +location counter. + +@node Input Section +@subsection Input section description +@cindex input sections +@cindex mapping input sections to output sections +The most common output section command is an input section description. + +The input section description is the most basic linker script operation. +You use output sections to tell the linker how to lay out your program +in memory. You use input section descriptions to tell the linker how to +map the input files into your memory layout. + +@menu +* Input Section Basics:: Input section basics +* Input Section Wildcards:: Input section wildcard patterns +* Input Section Common:: Input section for common symbols +* Input Section Keep:: Input section and garbage collection +* Input Section Example:: Input section example +@end menu + +@node Input Section Basics +@subsubsection Input section basics +@cindex input section basics +An input section description consists of a file name optionally followed +by a list of section names in parentheses. + +The file name and the section name may be wildcard patterns, which we +describe further below (@pxref{Input Section Wildcards}). + +The most common input section description is to include all input +sections with a particular name in the output section. For example, to +include all input @samp{.text} sections, you would write: +@smallexample +*(.text) +@end smallexample +@noindent +Here the @samp{*} is a wildcard which matches any file name. To exclude a file +from matching the file name wildcard, EXCLUDE_FILE may be used to match all files +except the one specified by EXCLUDE_FILE. For example: +@smallexample +(*(EXCLUDE_FILE (*crtend.o) .ctors)) +@end smallexample +will cause all .ctors sections from all files except crtend.o to be included. + +There are two ways to include more than one section: +@smallexample +*(.text .rdata) +*(.text) *(.rdata) +@end smallexample +@noindent +The difference between these is the order in which the @samp{.text} and +@samp{.rdata} input sections will appear in the output section. In the +first example, they will be intermingled. In the second example, all +@samp{.text} input sections will appear first, followed by all +@samp{.rdata} input sections. + +You can specify a file name to include sections from a particular file. +You would do this if one or more of your files contain special data that +needs to be at a particular location in memory. For example: +@smallexample +data.o(.data) +@end smallexample + +If you use a file name without a list of sections, then all sections in +the input file will be included in the output section. This is not +commonly done, but it may by useful on occasion. For example: +@smallexample +data.o +@end smallexample + +When you use a file name which does not contain any wild card +characters, the linker will first see if you also specified the file +name on the linker command line or in an @code{INPUT} command. If you +did not, the linker will attempt to open the file as an input file, as +though it appeared on the command line. Note that this differs from an +@code{INPUT} command, because the linker will not search for the file in +the archive search path. + +@node Input Section Wildcards +@subsubsection Input section wildcard patterns +@cindex input section wildcards +@cindex wildcard file name patterns +@cindex file name wildcard patterns +@cindex section name wildcard patterns +In an input section description, either the file name or the section +name or both may be wildcard patterns. + +The file name of @samp{*} seen in many examples is a simple wildcard +pattern for the file name. + +The wildcard patterns are like those used by the Unix shell. + +@table @samp +@item * +matches any number of characters +@item ? +matches any single character +@item [@var{chars}] +matches a single instance of any of the @var{chars}; the @samp{-} +character may be used to specify a range of characters, as in +@samp{[a-z]} to match any lower case letter +@item \ +quotes the following character +@end table + +When a file name is matched with a wildcard, the wildcard characters +will not match a @samp{/} character (used to separate directory names on +Unix). A pattern consisting of a single @samp{*} character is an +exception; it will always match any file name, whether it contains a +@samp{/} or not. In a section name, the wildcard characters will match +a @samp{/} character. + +File name wildcard patterns only match files which are explicitly +specified on the command line or in an @code{INPUT} command. The linker +does not search directories to expand wildcards. + +If a file name matches more than one wildcard pattern, or if a file name +appears explicitly and is also matched by a wildcard pattern, the linker +will use the first match in the linker script. For example, this +sequence of input section descriptions is probably in error, because the +@file{data.o} rule will not be used: +@smallexample +.data : @{ *(.data) @} +.data1 : @{ data.o(.data) @} +@end smallexample + +@cindex SORT +Normally, the linker will place files and sections matched by wildcards +in the order in which they are seen during the link. You can change +this by using the @code{SORT} keyword, which appears before a wildcard +pattern in parentheses (e.g., @code{SORT(.text*)}). When the +@code{SORT} keyword is used, the linker will sort the files or sections +into ascending order by name before placing them in the output file. + +If you ever get confused about where input sections are going, use the +@samp{-M} linker option to generate a map file. The map file shows +precisely how input sections are mapped to output sections. + +This example shows how wildcard patterns might be used to partition +files. This linker script directs the linker to place all @samp{.text} +sections in @samp{.text} and all @samp{.bss} sections in @samp{.bss}. +The linker will place the @samp{.data} section from all files beginning +with an upper case character in @samp{.DATA}; for all other files, the +linker will place the @samp{.data} section in @samp{.data}. +@smallexample +@group +SECTIONS @{ + .text : @{ *(.text) @} + .DATA : @{ [A-Z]*(.data) @} + .data : @{ *(.data) @} + .bss : @{ *(.bss) @} +@} +@end group +@end smallexample + +@node Input Section Common +@subsubsection Input section for common symbols +@cindex common symbol placement +@cindex uninitialized data placement +A special notation is needed for common symbols, because in many object +file formats common symbols do not have a particular input section. The +linker treats common symbols as though they are in an input section +named @samp{COMMON}. + +You may use file names with the @samp{COMMON} section just as with any +other input sections. You can use this to place common symbols from a +particular input file in one section while common symbols from other +input files are placed in another section. + +In most cases, common symbols in input files will be placed in the +@samp{.bss} section in the output file. For example: +@smallexample +.bss @{ *(.bss) *(COMMON) @} +@end smallexample + +@cindex scommon section +@cindex small common symbols +Some object file formats have more than one type of common symbol. For +example, the MIPS ELF object file format distinguishes standard common +symbols and small common symbols. In this case, the linker will use a +different special section name for other types of common symbols. In +the case of MIPS ELF, the linker uses @samp{COMMON} for standard common +symbols and @samp{.scommon} for small common symbols. This permits you +to map the different types of common symbols into memory at different +locations. + +@cindex [COMMON] +You will sometimes see @samp{[COMMON]} in old linker scripts. This +notation is now considered obsolete. It is equivalent to +@samp{*(COMMON)}. + +@node Input Section Keep +@subsubsection Input section and garbage collection +@cindex KEEP +@cindex garbage collection +When link-time garbage collection is in use (@samp{--gc-sections}), +it is often useful to mark sections that should not be eliminated. +This is accomplished by surrounding an input section's wildcard entry +with @code{KEEP()}, as in @code{KEEP(*(.init))} or +@code{KEEP(SORT(*)(.ctors))}. + +@node Input Section Example +@subsubsection Input section example +The following example is a complete linker script. It tells the linker +to read all of the sections from file @file{all.o} and place them at the +start of output section @samp{outputa} which starts at location +@samp{0x10000}. All of section @samp{.input1} from file @file{foo.o} +follows immediately, in the same output section. All of section +@samp{.input2} from @file{foo.o} goes into output section +@samp{outputb}, followed by section @samp{.input1} from @file{foo1.o}. +All of the remaining @samp{.input1} and @samp{.input2} sections from any +files are written to output section @samp{outputc}. + +@smallexample +@group +SECTIONS @{ + outputa 0x10000 : + @{ + all.o + foo.o (.input1) + @} + outputb : + @{ + foo.o (.input2) + foo1.o (.input1) + @} + outputc : + @{ + *(.input1) + *(.input2) + @} +@} +@end group +@end smallexample + +@node Output Section Data +@subsection Output section data +@cindex data +@cindex section data +@cindex output section data +@kindex BYTE(@var{expression}) +@kindex SHORT(@var{expression}) +@kindex LONG(@var{expression}) +@kindex QUAD(@var{expression}) +@kindex SQUAD(@var{expression}) +You can include explicit bytes of data in an output section by using +@code{BYTE}, @code{SHORT}, @code{LONG}, @code{QUAD}, or @code{SQUAD} as +an output section command. Each keyword is followed by an expression in +parentheses providing the value to store (@pxref{Expressions}). The +value of the expression is stored at the current value of the location +counter. + +The @code{BYTE}, @code{SHORT}, @code{LONG}, and @code{QUAD} commands +store one, two, four, and eight bytes (respectively). After storing the +bytes, the location counter is incremented by the number of bytes +stored. + +For example, this will store the byte 1 followed by the four byte value +of the symbol @samp{addr}: +@smallexample +BYTE(1) +LONG(addr) +@end smallexample + +When using a 64 bit host or target, @code{QUAD} and @code{SQUAD} are the +same; they both store an 8 byte, or 64 bit, value. When both host and +target are 32 bits, an expression is computed as 32 bits. In this case +@code{QUAD} stores a 32 bit value zero extended to 64 bits, and +@code{SQUAD} stores a 32 bit value sign extended to 64 bits. + +If the object file format of the output file has an explicit endianness, +which is the normal case, the value will be stored in that endianness. +When the object file format does not have an explicit endianness, as is +true of, for example, S-records, the value will be stored in the +endianness of the first input object file. + +@kindex FILL(@var{expression}) +@cindex holes, filling +@cindex unspecified memory +You may use the @code{FILL} command to set the fill pattern for the +current section. It is followed by an expression in parentheses. Any +otherwise unspecified regions of memory within the section (for example, +gaps left due to the required alignment of input sections) are filled +with the two least significant bytes of the expression, repeated as +necessary. A @code{FILL} statement covers memory locations after the +point at which it occurs in the section definition; by including more +than one @code{FILL} statement, you can have different fill patterns in +different parts of an output section. + +This example shows how to fill unspecified regions of memory with the +value @samp{0x9090}: +@smallexample +FILL(0x9090) +@end smallexample + +The @code{FILL} command is similar to the @samp{=@var{fillexp}} output +section attribute (@pxref{Output Section Fill}), but it only affects the +part of the section following the @code{FILL} command, rather than the +entire section. If both are used, the @code{FILL} command takes +precedence. + +@node Output Section Keywords +@subsection Output section keywords +There are a couple of keywords which can appear as output section +commands. + +@table @code +@kindex CREATE_OBJECT_SYMBOLS +@cindex input filename symbols +@cindex filename symbols +@item CREATE_OBJECT_SYMBOLS +The command tells the linker to create a symbol for each input file. +The name of each symbol will be the name of the corresponding input +file. The section of each symbol will be the output section in which +the @code{CREATE_OBJECT_SYMBOLS} command appears. + +This is conventional for the a.out object file format. It is not +normally used for any other object file format. + +@kindex CONSTRUCTORS +@cindex C++ constructors, arranging in link +@cindex constructors, arranging in link +@item CONSTRUCTORS +When linking using the a.out object file format, the linker uses an +unusual set construct to support C++ global constructors and +destructors. When linking object file formats which do not support +arbitrary sections, such as ECOFF and XCOFF, the linker will +automatically recognize C++ global constructors and destructors by name. +For these object file formats, the @code{CONSTRUCTORS} command tells the +linker to place constructor information in the output section where the +@code{CONSTRUCTORS} command appears. The @code{CONSTRUCTORS} command is +ignored for other object file formats. + +The symbol @w{@code{__CTOR_LIST__}} marks the start of the global +constructors, and the symbol @w{@code{__DTOR_LIST}} marks the end. The +first word in the list is the number of entries, followed by the address +of each constructor or destructor, followed by a zero word. The +compiler must arrange to actually run the code. For these object file +formats @sc{gnu} C++ normally calls constructors from a subroutine +@code{__main}; a call to @code{__main} is automatically inserted into +the startup code for @code{main}. @sc{gnu} C++ normally runs +destructors either by using @code{atexit}, or directly from the function +@code{exit}. + +For object file formats such as @code{COFF} or @code{ELF} which support +arbitrary section names, @sc{gnu} C++ will normally arrange to put the +addresses of global constructors and destructors into the @code{.ctors} +and @code{.dtors} sections. Placing the following sequence into your +linker script will build the sort of table which the @sc{gnu} C++ +runtime code expects to see. + +@smallexample + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; +@end smallexample + +If you are using the @sc{gnu} C++ support for initialization priority, +which provides some control over the order in which global constructors +are run, you must sort the constructors at link time to ensure that they +are executed in the correct order. When using the @code{CONSTRUCTORS} +command, use @samp{SORT(CONSTRUCTORS)} instead. When using the +@code{.ctors} and @code{.dtors} sections, use @samp{*(SORT(.ctors))} and +@samp{*(SORT(.dtors))} instead of just @samp{*(.ctors)} and +@samp{*(.dtors)}. + +Normally the compiler and linker will handle these issues automatically, +and you will not need to concern yourself with them. However, you may +need to consider this if you are using C++ and writing your own linker +scripts. + +@end table + +@node Output Section Discarding +@subsection Output section discarding +@cindex discarding sections +@cindex sections, discarding +@cindex removing sections +The linker will not create output section which do not have any +contents. This is for convenience when referring to input sections that +may or may not be present in any of the input files. For example: +@smallexample +.foo @{ *(.foo) @} +@end smallexample +@noindent +will only create a @samp{.foo} section in the output file if there is a +@samp{.foo} section in at least one input file. + +If you use anything other than an input section description as an output +section command, such as a symbol assignment, then the output section +will always be created, even if there are no matching input sections. + +@cindex /DISCARD/ +The special output section name @samp{/DISCARD/} may be used to discard +input sections. Any input sections which are assigned to an output +section named @samp{/DISCARD/} are not included in the output file. + +@node Output Section Attributes +@subsection Output section attributes +@cindex output section attributes +We showed above that the full description of an output section looked +like this: +@smallexample +@group +@var{section} [@var{address}] [(@var{type})] : [AT(@var{lma})] + @{ + @var{output-section-command} + @var{output-section-command} + @dots{} + @} [>@var{region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}] +@end group +@end smallexample +We've already described @var{section}, @var{address}, and +@var{output-section-command}. In this section we will describe the +remaining section attributes. + +@menu +* Output Section Type:: Output section type +* Output Section LMA:: Output section LMA +* Output Section Region:: Output section region +* Output Section Phdr:: Output section phdr +* Output Section Fill:: Output section fill +@end menu + +@node Output Section Type +@subsubsection Output section type +Each output section may have a type. The type is a keyword in +parentheses. The following types are defined: + +@table @code +@item NOLOAD +The section should be marked as not loadable, so that it will not be +loaded into memory when the program is run. +@item DSECT +@itemx COPY +@itemx INFO +@itemx OVERLAY +These type names are supported for backward compatibility, and are +rarely used. They all have the same effect: the section should be +marked as not allocatable, so that no memory is allocated for the +section when the program is run. +@end table + +@kindex NOLOAD +@cindex prevent unnecessary loading +@cindex loading, preventing +The linker normally sets the attributes of an output section based on +the input sections which map into it. You can override this by using +the section type. For example, in the script sample below, the +@samp{ROM} section is addressed at memory location @samp{0} and does not +need to be loaded when the program is run. The contents of the +@samp{ROM} section will appear in the linker output file as usual. +@smallexample +@group +SECTIONS @{ + ROM 0 (NOLOAD) : @{ @dots{} @} + @dots{} +@} +@end group +@end smallexample + +@node Output Section LMA +@subsubsection Output section LMA +@kindex AT(@var{lma}) +@cindex load address +@cindex section load address +Every section has a virtual address (VMA) and a load address (LMA); see +@ref{Basic Script Concepts}. The address expression which may appear in +an output section description sets the VMA (@pxref{Output Section +Address}). + +The linker will normally set the LMA equal to the VMA. You can change +that by using the @code{AT} keyword. The expression @var{lma} that +follows the @code{AT} keyword specifies the load address of the section. + +@cindex ROM initialized data +@cindex initialized data in ROM +This feature is designed to make it easy to build a ROM image. For +example, the following linker script creates three output sections: one +called @samp{.text}, which starts at @code{0x1000}, one called +@samp{.mdata}, which is loaded at the end of the @samp{.text} section +even though its VMA is @code{0x2000}, and one called @samp{.bss} to hold +uninitialized data at address @code{0x3000}. The symbol @code{_data} is +defined with the value @code{0x2000}, which shows that the location +counter holds the VMA value, not the LMA value. + +@smallexample +@group +SECTIONS + @{ + .text 0x1000 : @{ *(.text) _etext = . ; @} + .mdata 0x2000 : + AT ( ADDR (.text) + SIZEOF (.text) ) + @{ _data = . ; *(.data); _edata = . ; @} + .bss 0x3000 : + @{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;@} +@} +@end group +@end smallexample + +The run-time initialization code for use with a program generated with +this linker script would include something like the following, to copy +the initialized data from the ROM image to its runtime address. Notice +how this code takes advantage of the symbols defined by the linker +script. + +@smallexample +@group +extern char _etext, _data, _edata, _bstart, _bend; +char *src = &_etext; +char *dst = &_data; + +/* ROM has data at end of text; copy it. */ +while (dst < &_edata) @{ + *dst++ = *src++; +@} + +/* Zero bss */ +for (dst = &_bstart; dst< &_bend; dst++) + *dst = 0; +@end group +@end smallexample + +@node Output Section Region +@subsubsection Output section region +@kindex >@var{region} +@cindex section, assigning to memory region +@cindex memory regions and sections +You can assign a section to a previously defined region of memory by +using @samp{>@var{region}}. @xref{MEMORY}. + +Here is a simple example: +@smallexample +@group +MEMORY @{ rom : ORIGIN = 0x1000, LENGTH = 0x1000 @} +SECTIONS @{ ROM : @{ *(.text) @} >rom @} +@end group +@end smallexample + +@node Output Section Phdr +@subsubsection Output section phdr +@kindex :@var{phdr} +@cindex section, assigning to program header +@cindex program headers and sections +You can assign a section to a previously defined program segment by +using @samp{:@var{phdr}}. @xref{PHDRS}. If a section is assigned to +one or more segments, then all subsequent allocated sections will be +assigned to those segments as well, unless they use an explicitly +@code{:@var{phdr}} modifier. You can use @code{:NONE} to tell the +linker to not put the section in any segment at all. + +Here is a simple example: +@smallexample +@group +PHDRS @{ text PT_LOAD ; @} +SECTIONS @{ .text : @{ *(.text) @} :text @} +@end group +@end smallexample + +@node Output Section Fill +@subsubsection Output section fill +@kindex =@var{fillexp} +@cindex section fill pattern +@cindex fill pattern, entire section +You can set the fill pattern for an entire section by using +@samp{=@var{fillexp}}. @var{fillexp} is an expression +(@pxref{Expressions}). Any otherwise unspecified regions of memory +within the output section (for example, gaps left due to the required +alignment of input sections) will be filled with the two least +significant bytes of the value, repeated as necessary. + +You can also change the fill value with a @code{FILL} command in the +output section commands; see @ref{Output Section Data}. + +Here is a simple example: +@smallexample +@group +SECTIONS @{ .text : @{ *(.text) @} =0x9090 @} +@end group +@end smallexample + +@node Overlay Description +@subsection Overlay description +@kindex OVERLAY +@cindex overlays +An overlay description provides an easy way to describe sections which +are to be loaded as part of a single memory image but are to be run at +the same memory address. At run time, some sort of overlay manager will +copy the overlaid sections in and out of the runtime memory address as +required, perhaps by simply manipulating addressing bits. This approach +can be useful, for example, when a certain region of memory is faster +than another. + +Overlays are described using the @code{OVERLAY} command. The +@code{OVERLAY} command is used within a @code{SECTIONS} command, like an +output section description. The full syntax of the @code{OVERLAY} +command is as follows: +@smallexample +@group +OVERLAY [@var{start}] : [NOCROSSREFS] [AT ( @var{ldaddr} )] + @{ + @var{secname1} + @{ + @var{output-section-command} + @var{output-section-command} + @dots{} + @} [:@var{phdr}@dots{}] [=@var{fill}] + @var{secname2} + @{ + @var{output-section-command} + @var{output-section-command} + @dots{} + @} [:@var{phdr}@dots{}] [=@var{fill}] + @dots{} + @} [>@var{region}] [:@var{phdr}@dots{}] [=@var{fill}] +@end group +@end smallexample + +Everything is optional except @code{OVERLAY} (a keyword), and each +section must have a name (@var{secname1} and @var{secname2} above). The +section definitions within the @code{OVERLAY} construct are identical to +those within the general @code{SECTIONS} contruct (@pxref{SECTIONS}), +except that no addresses and no memory regions may be defined for +sections within an @code{OVERLAY}. + +The sections are all defined with the same starting address. The load +addresses of the sections are arranged such that they are consecutive in +memory starting at the load address used for the @code{OVERLAY} as a +whole (as with normal section definitions, the load address is optional, +and defaults to the start address; the start address is also optional, +and defaults to the current value of the location counter). + +If the @code{NOCROSSREFS} keyword is used, and there any references +among the sections, the linker will report an error. Since the sections +all run at the same address, it normally does not make sense for one +section to refer directly to another. @xref{Miscellaneous Commands, +NOCROSSREFS}. + +For each section within the @code{OVERLAY}, the linker automatically +defines two symbols. The symbol @code{__load_start_@var{secname}} is +defined as the starting load address of the section. The symbol +@code{__load_stop_@var{secname}} is defined as the final load address of +the section. Any characters within @var{secname} which are not legal +within C identifiers are removed. C (or assembler) code may use these +symbols to move the overlaid sections around as necessary. + +At the end of the overlay, the value of the location counter is set to +the start address of the overlay plus the size of the largest section. + +Here is an example. Remember that this would appear inside a +@code{SECTIONS} construct. +@smallexample +@group + OVERLAY 0x1000 : AT (0x4000) + @{ + .text0 @{ o1/*.o(.text) @} + .text1 @{ o2/*.o(.text) @} + @} +@end group +@end smallexample +@noindent +This will define both @samp{.text0} and @samp{.text1} to start at +address 0x1000. @samp{.text0} will be loaded at address 0x4000, and +@samp{.text1} will be loaded immediately after @samp{.text0}. The +following symbols will be defined: @code{__load_start_text0}, +@code{__load_stop_text0}, @code{__load_start_text1}, +@code{__load_stop_text1}. + +C code to copy overlay @code{.text1} into the overlay area might look +like the following. + +@smallexample +@group + extern char __load_start_text1, __load_stop_text1; + memcpy ((char *) 0x1000, &__load_start_text1, + &__load_stop_text1 - &__load_start_text1); +@end group +@end smallexample + +Note that the @code{OVERLAY} command is just syntactic sugar, since +everything it does can be done using the more basic commands. The above +example could have been written identically as follows. + +@smallexample +@group + .text0 0x1000 : AT (0x4000) @{ o1/*.o(.text) @} + __load_start_text0 = LOADADDR (.text0); + __load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0); + .text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) @{ o2/*.o(.text) @} + __load_start_text1 = LOADADDR (.text1); + __load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1); + . = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1)); +@end group +@end smallexample + +@node MEMORY +@section MEMORY command +@kindex MEMORY +@cindex memory regions +@cindex regions of memory +@cindex allocating memory +@cindex discontinuous memory +The linker's default configuration permits allocation of all available +memory. You can override this by using the @code{MEMORY} command. + +The @code{MEMORY} command describes the location and size of blocks of +memory in the target. You can use it to describe which memory regions +may be used by the linker, and which memory regions it must avoid. You +can then assign sections to particular memory regions. The linker will +set section addresses based on the memory regions, and will warn about +regions that become too full. The linker will not shuffle sections +around to fit into the available regions. + +A linker script may contain at most one use of the @code{MEMORY} +command. However, you can define as many blocks of memory within it as +you wish. The syntax is: +@smallexample +@group +MEMORY + @{ + @var{name} [(@var{attr})] : ORIGIN = @var{origin}, LENGTH = @var{len} + @dots{} + @} +@end group +@end smallexample + +The @var{name} is a name used in the linker script to refer to the +region. The region name has no meaning outside of the linker script. +Region names are stored in a separate name space, and will not conflict +with symbol names, file names, or section names. Each memory region +must have a distinct name. + +@cindex memory region attributes +The @var{attr} string is an optional list of attributes that specify +whether to use a particular memory region for an input section which is +not explicitly mapped in the linker script. As described in +@ref{SECTIONS}, if you do not specify an output section for some input +section, the linker will create an output section with the same name as +the input section. If you define region attributes, the linker will use +them to select the memory region for the output section that it creates. + +The @var{attr} string must consist only of the following characters: +@table @samp +@item R +Read-only section +@item W +Read/write section +@item X +Executable section +@item A +Allocatable section +@item I +Initialized section +@item L +Same as @samp{I} +@item ! +Invert the sense of any of the preceding attributes +@end table + +If a unmapped section matches any of the listed attributes other than +@samp{!}, it will be placed in the memory region. The @samp{!} +attribute reverses this test, so that an unmapped section will be placed +in the memory region only if it does not match any of the listed +attributes. + +@kindex ORIGIN = +@kindex o = +@kindex org = +The @var{origin} is an expression for the start address of the memory +region. The expression must evaluate to a constant before memory +allocation is performed, which means that you may not use any section +relative symbols. The keyword @code{ORIGIN} may be abbreviated to +@code{org} or @code{o} (but not, for example, @code{ORG}). + +@kindex LENGTH = +@kindex len = +@kindex l = +The @var{len} is an expression for the size in bytes of the memory +region. As with the @var{origin} expression, the expression must +evaluate to a constant before memory allocation is performed. The +keyword @code{LENGTH} may be abbreviated to @code{len} or @code{l}. + +In the following example, we specify that there are two memory regions +available for allocation: one starting at @samp{0} for 256 kilobytes, +and the other starting at @samp{0x40000000} for four megabytes. The +linker will place into the @samp{rom} memory region every section which +is not explicitly mapped into a memory region, and is either read-only +or executable. The linker will place other sections which are not +explicitly mapped into a memory region into the @samp{ram} memory +region. + +@smallexample +@group +MEMORY + @{ + rom (rx) : ORIGIN = 0, LENGTH = 256K + ram (!rx) : org = 0x40000000, l = 4M + @} +@end group +@end smallexample + +Once you define a memory region, you can direct the linker to place +specific output sections into that memory region by using the +@samp{>@var{region}} output section attribute. For example, if you have +a memory region named @samp{mem}, you would use @samp{>mem} in the +output section definition. @xref{Output Section Region}. If no address +was specified for the output section, the linker will set the address to +the next available address within the memory region. If the combined +output sections directed to a memory region are too large for the +region, the linker will issue an error message. + +@node PHDRS +@section PHDRS Command +@kindex PHDRS +@cindex program headers +@cindex ELF program headers +@cindex program segments +@cindex segments, ELF +The ELF object file format uses @dfn{program headers}, also knows as +@dfn{segments}. The program headers describe how the program should be +loaded into memory. You can print them out by using the @code{objdump} +program with the @samp{-p} option. + +When you run an ELF program on a native ELF system, the system loader +reads the program headers in order to figure out how to load the +program. This will only work if the program headers are set correctly. +This manual does not describe the details of how the system loader +interprets program headers; for more information, see the ELF ABI. + +The linker will create reasonable program headers by default. However, +in some cases, you may need to specify the program headers more +precisely. You may use the @code{PHDRS} command for this purpose. When +the linker sees the @code{PHDRS} command in the linker script, it will +not create any program headers other than the ones specified. + +The linker only pays attention to the @code{PHDRS} command when +generating an ELF output file. In other cases, the linker will simply +ignore @code{PHDRS}. + +This is the syntax of the @code{PHDRS} command. The words @code{PHDRS}, +@code{FILEHDR}, @code{AT}, and @code{FLAGS} are keywords. + +@smallexample +@group +PHDRS +@{ + @var{name} @var{type} [ FILEHDR ] [ PHDRS ] [ AT ( @var{address} ) ] + [ FLAGS ( @var{flags} ) ] ; +@} +@end group +@end smallexample + +The @var{name} is used only for reference in the @code{SECTIONS} command +of the linker script. It is not put into the output file. Program +header names are stored in a separate name space, and will not conflict +with symbol names, file names, or section names. Each program header +must have a distinct name. + +Certain program header types describe segments of memory which the +system loader will load from the file. In the linker script, you +specify the contents of these segments by placing allocatable output +sections in the segments. You use the @samp{:@var{phdr}} output section +attribute to place a section in a particular segment. @xref{Output +Section Phdr}. + +It is normal to put certain sections in more than one segment. This +merely implies that one segment of memory contains another. You may +repeat @samp{:@var{phdr}}, using it once for each segment which should +contain the section. + +If you place a section in one or more segments using @samp{:@var{phdr}}, +then the linker will place all subsequent allocatable sections which do +not specify @samp{:@var{phdr}} in the same segments. This is for +convenience, since generally a whole set of contiguous sections will be +placed in a single segment. You can use @code{:NONE} to override the +default segment and tell the linker to not put the section in any +segment at all. + +@kindex FILEHDR +@kindex PHDRS +You may use the @code{FILEHDR} and @code{PHDRS} keywords appear after +the program header type to further describe the contents of the segment. +The @code{FILEHDR} keyword means that the segment should include the ELF +file header. The @code{PHDRS} keyword means that the segment should +include the ELF program headers themselves. + +The @var{type} may be one of the following. The numbers indicate the +value of the keyword. + +@table @asis +@item @code{PT_NULL} (0) +Indicates an unused program header. + +@item @code{PT_LOAD} (1) +Indicates that this program header describes a segment to be loaded from +the file. + +@item @code{PT_DYNAMIC} (2) +Indicates a segment where dynamic linking information can be found. + +@item @code{PT_INTERP} (3) +Indicates a segment where the name of the program interpreter may be +found. + +@item @code{PT_NOTE} (4) +Indicates a segment holding note information. + +@item @code{PT_SHLIB} (5) +A reserved program header type, defined but not specified by the ELF +ABI. + +@item @code{PT_PHDR} (6) +Indicates a segment where the program headers may be found. + +@item @var{expression} +An expression giving the numeric type of the program header. This may +be used for types not defined above. +@end table + +You can specify that a segment should be loaded at a particular address +in memory by using an @code{AT} expression. This is identical to the +@code{AT} command used as an output section attribute (@pxref{Output +Section LMA}). The @code{AT} command for a program header overrides the +output section attribute. + +The linker will normally set the segment flags based on the sections +which comprise the segment. You may use the @code{FLAGS} keyword to +explicitly specify the segment flags. The value of @var{flags} must be +an integer. It is used to set the @code{p_flags} field of the program +header. + +Here is an example of @code{PHDRS}. This shows a typical set of program +headers used on a native ELF system. + +@example +@group +PHDRS +@{ + headers PT_PHDR PHDRS ; + interp PT_INTERP ; + text PT_LOAD FILEHDR PHDRS ; + data PT_LOAD ; + dynamic PT_DYNAMIC ; +@} + +SECTIONS +@{ + . = SIZEOF_HEADERS; + .interp : @{ *(.interp) @} :text :interp + .text : @{ *(.text) @} :text + .rodata : @{ *(.rodata) @} /* defaults to :text */ + @dots{} + . = . + 0x1000; /* move to a new page in memory */ + .data : @{ *(.data) @} :data + .dynamic : @{ *(.dynamic) @} :data :dynamic + @dots{} +@} +@end group +@end example + +@node VERSION +@section VERSION Command +@kindex VERSION @{script text@} +@cindex symbol versions +@cindex version script +@cindex versions of symbols +The linker supports symbol versions when using ELF. Symbol versions are +only useful when using shared libraries. The dynamic linker can use +symbol versions to select a specific version of a function when it runs +a program that may have been linked against an earlier version of the +shared library. + +You can include a version script directly in the main linker script, or +you can supply the version script as an implicit linker script. You can +also use the @samp{--version-script} linker option. + +The syntax of the @code{VERSION} command is simply +@smallexample +VERSION @{ version-script-commands @} +@end smallexample + +The format of the version script commands is identical to that used by +Sun's linker in Solaris 2.5. The version script defines a tree of +version nodes. You specify the node names and interdependencies in the +version script. You can specify which symbols are bound to which +version nodes, and you can reduce a specified set of symbols to local +scope so that they are not globally visible outside of the shared +library. + +The easiest way to demonstrate the version script language is with a few +examples. + +@smallexample +VERS_1.1 @{ + global: + foo1; + local: + old*; + original*; + new*; +@}; + +VERS_1.2 @{ + foo2; +@} VERS_1.1; + +VERS_2.0 @{ + bar1; bar2; +@} VERS_1.2; +@end smallexample + +This example version script defines three version nodes. The first +version node defined is @samp{VERS_1.1}; it has no other dependencies. +The script binds the symbol @samp{foo1} to @samp{VERS_1.1}. It reduces +a number of symbols to local scope so that they are not visible outside +of the shared library. + +Next, the version script defines node @samp{VERS_1.2}. This node +depends upon @samp{VERS_1.1}. The script binds the symbol @samp{foo2} +to the version node @samp{VERS_1.2}. + +Finally, the version script defines node @samp{VERS_2.0}. This node +depends upon @samp{VERS_1.2}. The scripts binds the symbols @samp{bar1} +and @samp{bar2} are bound to the version node @samp{VERS_2.0}. + +When the linker finds a symbol defined in a library which is not +specifically bound to a version node, it will effectively bind it to an +unspecified base version of the library. You can bind all otherwise +unspecified symbols to a given version node by using @samp{global: *} +somewhere in the version script. + +The names of the version nodes have no specific meaning other than what +they might suggest to the person reading them. The @samp{2.0} version +could just as well have appeared in between @samp{1.1} and @samp{1.2}. +However, this would be a confusing way to write a version script. + +When you link an application against a shared library that has versioned +symbols, the application itself knows which version of each symbol it +requires, and it also knows which version nodes it needs from each +shared library it is linked against. Thus at runtime, the dynamic +loader can make a quick check to make sure that the libraries you have +linked against do in fact supply all of the version nodes that the +application will need to resolve all of the dynamic symbols. In this +way it is possible for the dynamic linker to know with certainty that +all external symbols that it needs will be resolvable without having to +search for each symbol reference. + +The symbol versioning is in effect a much more sophisticated way of +doing minor version checking that SunOS does. The fundamental problem +that is being addressed here is that typically references to external +functions are bound on an as-needed basis, and are not all bound when +the application starts up. If a shared library is out of date, a +required interface may be missing; when the application tries to use +that interface, it may suddenly and unexpectedly fail. With symbol +versioning, the user will get a warning when they start their program if +the libraries being used with the application are too old. + +There are several GNU extensions to Sun's versioning approach. The +first of these is the ability to bind a symbol to a version node in the +source file where the symbol is defined instead of in the versioning +script. This was done mainly to reduce the burden on the library +maintainer. You can do this by putting something like: +@smallexample +__asm__(".symver original_foo,foo@@VERS_1.1"); +@end smallexample +@noindent +in the C source file. This renames the function @samp{original_foo} to +be an alias for @samp{foo} bound to the version node @samp{VERS_1.1}. +The @samp{local:} directive can be used to prevent the symbol +@samp{original_foo} from being exported. + +The second GNU extension is to allow multiple versions of the same +function to appear in a given shared library. In this way you can make +an incompatible change to an interface without increasing the major +version number of the shared library, while still allowing applications +linked against the old interface to continue to function. + +To do this, you must use multiple @samp{.symver} directives in the +source file. Here is an example: + +@smallexample +__asm__(".symver original_foo,foo@@"); +__asm__(".symver old_foo,foo@@VERS_1.1"); +__asm__(".symver old_foo1,foo@@VERS_1.2"); +__asm__(".symver new_foo,foo@@@@VERS_2.0"); +@end smallexample + +In this example, @samp{foo@@} represents the symbol @samp{foo} bound to the +unspecified base version of the symbol. The source file that contains this +example would define 4 C functions: @samp{original_foo}, @samp{old_foo}, +@samp{old_foo1}, and @samp{new_foo}. + +When you have multiple definitions of a given symbol, there needs to be +some way to specify a default version to which external references to +this symbol will be bound. You can do this with the +@samp{foo@@@@VERS_2.0} type of @samp{.symver} directive. You can only +declare one version of a symbol as the default in this manner; otherwise +you would effectively have multiple definitions of the same symbol. + +If you wish to bind a reference to a specific version of the symbol +within the shared library, you can use the aliases of convenience +(i.e. @samp{old_foo}), or you can use the @samp{.symver} directive to +specifically bind to an external version of the function in question. + +@node Expressions +@section Expressions in Linker Scripts +@cindex expressions +@cindex arithmetic +The syntax for expressions in the linker script language is identical to +that of C expressions. All expressions are evaluated as integers. All +expressions are evaluated in the same size, which is 32 bits if both the +host and target are 32 bits, and is otherwise 64 bits. + +You can use and set symbol values in expressions. + +The linker defines several special purpose builtin functions for use in +expressions. + +@menu +* Constants:: Constants +* Symbols:: Symbol Names +* Location Counter:: The Location Counter +* Operators:: Operators +* Evaluation:: Evaluation +* Expression Section:: The Section of an Expression +* Builtin Functions:: Builtin Functions +@end menu + +@node Constants +@subsection Constants +@cindex integer notation +@cindex constants in linker scripts +All constants are integers. + +As in C, the linker considers an integer beginning with @samp{0} to be +octal, and an integer beginning with @samp{0x} or @samp{0X} to be +hexadecimal. The linker considers other integers to be decimal. + +@cindex scaled integers +@cindex K and M integer suffixes +@cindex M and K integer suffixes +@cindex suffixes for integers +@cindex integer suffixes +In addition, you can use the suffixes @code{K} and @code{M} to scale a +constant by +@c TEXI2ROFF-KILL +@ifinfo +@c END TEXI2ROFF-KILL +@code{1024} or @code{1024*1024} +@c TEXI2ROFF-KILL +@end ifinfo +@tex +${\rm 1024}$ or ${\rm 1024}^2$ +@end tex +@c END TEXI2ROFF-KILL +respectively. For example, the following all refer to the same quantity: +@smallexample + _fourk_1 = 4K; + _fourk_2 = 4096; + _fourk_3 = 0x1000; +@end smallexample + +@node Symbols +@subsection Symbol Names +@cindex symbol names +@cindex names +@cindex quoted symbol names +@kindex " +Unless quoted, symbol names start with a letter, underscore, or period +and may include letters, digits, underscores, periods, and hyphens. +Unquoted symbol names must not conflict with any keywords. You can +specify a symbol which contains odd characters or has the same name as a +keyword by surrounding the symbol name in double quotes: +@smallexample + "SECTION" = 9; + "with a space" = "also with a space" + 10; +@end smallexample + +Since symbols can contain many non-alphabetic characters, it is safest +to delimit symbols with spaces. For example, @samp{A-B} is one symbol, +whereas @samp{A - B} is an expression involving subtraction. + +@node Location Counter +@subsection The Location Counter +@kindex . +@cindex dot +@cindex location counter +@cindex current output location +The special linker variable @dfn{dot} @samp{.} always contains the +current output location counter. Since the @code{.} always refers to a +location in an output section, it may only appear in an expression +within a @code{SECTIONS} command. The @code{.} symbol may appear +anywhere that an ordinary symbol is allowed in an expression. + +@cindex holes +Assigning a value to @code{.} will cause the location counter to be +moved. This may be used to create holes in the output section. The +location counter may never be moved backwards. + +@smallexample +SECTIONS +@{ + output : + @{ + file1(.text) + . = . + 1000; + file2(.text) + . += 1000; + file3(.text) + @} = 0x1234; +@} +@end smallexample +@noindent +In the previous example, the @samp{.text} section from @file{file1} is +located at the beginning of the output section @samp{output}. It is +followed by a 1000 byte gap. Then the @samp{.text} section from +@file{file2} appears, also with a 1000 byte gap following before the +@samp{.text} section from @file{file3}. The notation @samp{= 0x1234} +specifies what data to write in the gaps (@pxref{Output Section Fill}). + +@need 2000 +@node Operators +@subsection Operators +@cindex operators for arithmetic +@cindex arithmetic operators +@cindex precedence in expressions +The linker recognizes the standard C set of arithmetic operators, with +the standard bindings and precedence levels: +@c TEXI2ROFF-KILL +@ifinfo +@c END TEXI2ROFF-KILL +@smallexample +precedence associativity Operators Notes +(highest) +1 left ! - ~ (1) +2 left * / % +3 left + - +4 left >> << +5 left == != > < <= >= +6 left & +7 left | +8 left && +9 left || +10 right ? : +11 right &= += -= *= /= (2) +(lowest) +@end smallexample +Notes: +(1) Prefix operators +(2) @xref{Assignments}. +@c TEXI2ROFF-KILL +@end ifinfo +@tex +\vskip \baselineskip +%"lispnarrowing" is the extra indent used generally for smallexample +\hskip\lispnarrowing\vbox{\offinterlineskip +\hrule +\halign +{\vrule#&\strut\hfil\ #\ \hfil&\vrule#&\strut\hfil\ #\ \hfil&\vrule#&\strut\hfil\ {\tt #}\ \hfil&\vrule#\cr +height2pt&\omit&&\omit&&\omit&\cr +&Precedence&& Associativity &&{\rm Operators}&\cr +height2pt&\omit&&\omit&&\omit&\cr +\noalign{\hrule} +height2pt&\omit&&\omit&&\omit&\cr +&highest&&&&&\cr +% '176 is tilde, '~' in tt font +&1&&left&&\qquad- \char'176\ !\qquad\dag&\cr +&2&&left&&* / \%&\cr +&3&&left&&+ -&\cr +&4&&left&&>> <<&\cr +&5&&left&&== != > < <= >=&\cr +&6&&left&&\&&\cr +&7&&left&&|&\cr +&8&&left&&{\&\&}&\cr +&9&&left&&||&\cr +&10&&right&&? :&\cr +&11&&right&&\qquad\&= += -= *= /=\qquad\ddag&\cr +&lowest&&&&&\cr +height2pt&\omit&&\omit&&\omit&\cr} +\hrule} +@end tex +@iftex +{ +@obeylines@parskip=0pt@parindent=0pt +@dag@quad Prefix operators. +@ddag@quad @xref{Assignments}. +} +@end iftex +@c END TEXI2ROFF-KILL + +@node Evaluation +@subsection Evaluation +@cindex lazy evaluation +@cindex expression evaluation order +The linker evaluates expressions lazily. It only computes the value of +an expression when absolutely necessary. + +The linker needs some information, such as the value of the start +address of the first section, and the origins and lengths of memory +regions, in order to do any linking at all. These values are computed +as soon as possible when the linker reads in the linker script. + +However, other values (such as symbol values) are not known or needed +until after storage allocation. Such values are evaluated later, when +other information (such as the sizes of output sections) is available +for use in the symbol assignment expression. + +The sizes of sections cannot be known until after allocation, so +assignments dependent upon these are not performed until after +allocation. + +Some expressions, such as those depending upon the location counter +@samp{.}, must be evaluated during section allocation. + +If the result of an expression is required, but the value is not +available, then an error results. For example, a script like the +following +@smallexample +@group +SECTIONS + @{ + .text 9+this_isnt_constant : + @{ *(.text) @} + @} +@end group +@end smallexample +@noindent +will cause the error message @samp{non constant expression for initial +address}. + +@node Expression Section +@subsection The Section of an Expression +@cindex expression sections +@cindex absolute expressions +@cindex relative expressions +@cindex absolute and relocatable symbols +@cindex relocatable and absolute symbols +@cindex symbols, relocatable and absolute +When the linker evaluates an expression, the result is either absolute +or relative to some section. A relative expression is expressed as a +fixed offset from the base of a section. + +The position of the expression within the linker script determines +whether it is absolute or relative. An expression which appears within +an output section definition is relative to the base of the output +section. An expression which appears elsewhere will be absolute. + +A symbol set to a relative expression will be relocatable if you request +relocatable output using the @samp{-r} option. That means that a +further link operation may change the value of the symbol. The symbol's +section will be the section of the relative expression. + +A symbol set to an absolute expression will retain the same value +through any further link operation. The symbol will be absolute, and +will not have any particular associated section. + +You can use the builtin function @code{ABSOLUTE} to force an expression +to be absolute when it would otherwise be relative. For example, to +create an absolute symbol set to the address of the end of the output +section @samp{.data}: +@smallexample +SECTIONS + @{ + .data : @{ *(.data) _edata = ABSOLUTE(.); @} + @} +@end smallexample +@noindent +If @samp{ABSOLUTE} were not used, @samp{_edata} would be relative to the +@samp{.data} section. + +@node Builtin Functions +@subsection Builtin Functions +@cindex functions in expressions +The linker script language includes a number of builtin functions for +use in linker script expressions. + +@table @code +@item ABSOLUTE(@var{exp}) +@kindex ABSOLUTE(@var{exp}) +@cindex expression, absolute +Return the absolute (non-relocatable, as opposed to non-negative) value +of the expression @var{exp}. Primarily useful to assign an absolute +value to a symbol within a section definition, where symbol values are +normally section relative. @xref{Expression Section}. + +@item ADDR(@var{section}) +@kindex ADDR(@var{section}) +@cindex section address in expression +Return the absolute address (the VMA) of the named @var{section}. Your +script must previously have defined the location of that section. In +the following example, @code{symbol_1} and @code{symbol_2} are assigned +identical values: +@smallexample +@group +SECTIONS @{ @dots{} + .output1 : + @{ + start_of_output_1 = ABSOLUTE(.); + @dots{} + @} + .output : + @{ + symbol_1 = ADDR(.output1); + symbol_2 = start_of_output_1; + @} +@dots{} @} +@end group +@end smallexample + +@item ALIGN(@var{exp}) +@kindex ALIGN(@var{exp}) +@cindex round up location counter +@cindex align location counter +Return the location counter (@code{.}) aligned to the next @var{exp} +boundary. @var{exp} must be an expression whose value is a power of +two. This is equivalent to +@smallexample +(. + @var{exp} - 1) & ~(@var{exp} - 1) +@end smallexample + +@code{ALIGN} doesn't change the value of the location counter---it just +does arithmetic on it. Here is an example which aligns the output +@code{.data} section to the next @code{0x2000} byte boundary after the +preceding section and sets a variable within the section to the next +@code{0x8000} boundary after the input sections: +@smallexample +@group +SECTIONS @{ @dots{} + .data ALIGN(0x2000): @{ + *(.data) + variable = ALIGN(0x8000); + @} +@dots{} @} +@end group +@end smallexample +@noindent +The first use of @code{ALIGN} in this example specifies the location of +a section because it is used as the optional @var{address} attribute of +a section definition (@pxref{Output Section Address}). The second use +of @code{ALIGN} is used to defines the value of a symbol. + +The builtin function @code{NEXT} is closely related to @code{ALIGN}. + +@item BLOCK(@var{exp}) +@kindex BLOCK(@var{exp}) +This is a synonym for @code{ALIGN}, for compatibility with older linker +scripts. It is most often seen when setting the address of an output +section. + +@item DEFINED(@var{symbol}) +@kindex DEFINED(@var{symbol}) +@cindex symbol defaults +Return 1 if @var{symbol} is in the linker global symbol table and is +defined, otherwise return 0. You can use this function to provide +default values for symbols. For example, the following script fragment +shows how to set a global symbol @samp{begin} to the first location in +the @samp{.text} section---but if a symbol called @samp{begin} already +existed, its value is preserved: + +@smallexample +@group +SECTIONS @{ @dots{} + .text : @{ + begin = DEFINED(begin) ? begin : . ; + @dots{} + @} + @dots{} +@} +@end group +@end smallexample + +@item LOADADDR(@var{section}) +@kindex LOADADDR(@var{section}) +@cindex section load address in expression +Return the absolute LMA of the named @var{section}. This is normally +the same as @code{ADDR}, but it may be different if the @code{AT} +attribute is used in the output section definition (@pxref{Output +Section LMA}). + +@kindex MAX +@item MAX(@var{exp1}, @var{exp2}) +Returns the maximum of @var{exp1} and @var{exp2}. + +@kindex MIN +@item MIN(@var{exp1}, @var{exp2}) +Returns the minimum of @var{exp1} and @var{exp2}. + +@item NEXT(@var{exp}) +@kindex NEXT(@var{exp}) +@cindex unallocated address, next +Return the next unallocated address that is a multiple of @var{exp}. +This function is closely related to @code{ALIGN(@var{exp})}; unless you +use the @code{MEMORY} command to define discontinuous memory for the +output file, the two functions are equivalent. + +@item SIZEOF(@var{section}) +@kindex SIZEOF(@var{section}) +@cindex section size +Return the size in bytes of the named @var{section}, if that section has +been allocated. If the section has not been allocated when this is +evaluated, the linker will report an error. In the following example, +@code{symbol_1} and @code{symbol_2} are assigned identical values: +@smallexample +@group +SECTIONS@{ @dots{} + .output @{ + .start = . ; + @dots{} + .end = . ; + @} + symbol_1 = .end - .start ; + symbol_2 = SIZEOF(.output); +@dots{} @} +@end group +@end smallexample + +@item SIZEOF_HEADERS +@itemx sizeof_headers +@kindex SIZEOF_HEADERS +@cindex header size +Return the size in bytes of the output file's headers. This is +information which appears at the start of the output file. You can use +this number when setting the start address of the first section, if you +choose, to facilitate paging. + +@cindex not enough room for program headers +@cindex program headers, not enough room +When producing an ELF output file, if the linker script uses the +@code{SIZEOF_HEADERS} builtin function, the linker must compute the +number of program headers before it has determined all the section +addresses and sizes. If the linker later discovers that it needs +additional program headers, it will report an error @samp{not enough +room for program headers}. To avoid this error, you must avoid using +the @code{SIZEOF_HEADERS} function, or you must rework your linker +script to avoid forcing the linker to use additional program headers, or +you must define the program headers yourself using the @code{PHDRS} +command (@pxref{PHDRS}). +@end table + +@node Implicit Linker Scripts +@section Implicit Linker Scripts +@cindex implicit linker scripts +If you specify a linker input file which the linker can not recognize as +an object file or an archive file, it will try to read the file as a +linker script. If the file can not be parsed as a linker script, the +linker will report an error. + +An implicit linker script will not replace the default linker script. + +Typically an implicit linker script would contain only symbol +assignments, or the @code{INPUT}, @code{GROUP}, or @code{VERSION} +commands. + +Any input files read because of an implicit linker script will be read +at the position in the command line where the implicit linker script was +read. This can affect archive searching. + +@ifset GENERIC +@node Machine Dependent +@chapter Machine Dependent Features + +@cindex machine dependencies +@code{ld} has additional features on some platforms; the following +sections describe them. Machines where @code{ld} has no additional +functionality are not listed. + +@menu +* H8/300:: @code{ld} and the H8/300 +* i960:: @code{ld} and the Intel 960 family +* ARM:: @code{ld} and the ARM family +@end menu +@end ifset + +@c FIXME! This could use @raisesections/@lowersections, but there seems to be a conflict +@c between those and node-defaulting. +@ifset H8300 +@ifclear GENERIC +@raisesections +@end ifclear + +@node H8/300 +@section @code{ld} and the H8/300 + +@cindex H8/300 support +For the H8/300, @code{ld} can perform these global optimizations when +you specify the @samp{--relax} command-line option. + +@table @emph +@cindex relaxing on H8/300 +@item relaxing address modes +@code{ld} finds all @code{jsr} and @code{jmp} instructions whose +targets are within eight bits, and turns them into eight-bit +program-counter relative @code{bsr} and @code{bra} instructions, +respectively. + +@cindex synthesizing on H8/300 +@item synthesizing instructions +@c FIXME: specifically mov.b, or any mov instructions really? +@code{ld} finds all @code{mov.b} instructions which use the +sixteen-bit absolute address form, but refer to the top +page of memory, and changes them to use the eight-bit address form. +(That is: the linker turns @samp{mov.b @code{@@}@var{aa}:16} into +@samp{mov.b @code{@@}@var{aa}:8} whenever the address @var{aa} is in the +top page of memory). +@end table + +@ifclear GENERIC +@lowersections +@end ifclear +@end ifset + +@ifclear GENERIC +@ifset Hitachi +@c This stuff is pointless to say unless you're especially concerned +@c with Hitachi chips; don't enable it for generic case, please. +@node Hitachi +@chapter @code{ld} and other Hitachi chips + +@code{ld} also supports the H8/300H, the H8/500, and the Hitachi SH. No +special features, commands, or command-line options are required for +these chips. +@end ifset +@end ifclear + +@ifset I960 +@ifclear GENERIC +@raisesections +@end ifclear + +@node i960 +@section @code{ld} and the Intel 960 family + +@cindex i960 support + +You can use the @samp{-A@var{architecture}} command line option to +specify one of the two-letter names identifying members of the 960 +family; the option specifies the desired output target, and warns of any +incompatible instructions in the input files. It also modifies the +linker's search strategy for archive libraries, to support the use of +libraries specific to each particular architecture, by including in the +search loop names suffixed with the string identifying the architecture. + +For example, if your @code{ld} command line included @w{@samp{-ACA}} as +well as @w{@samp{-ltry}}, the linker would look (in its built-in search +paths, and in any paths you specify with @samp{-L}) for a library with +the names + +@smallexample +@group +try +libtry.a +tryca +libtryca.a +@end group +@end smallexample + +@noindent +The first two possibilities would be considered in any event; the last +two are due to the use of @w{@samp{-ACA}}. + +You can meaningfully use @samp{-A} more than once on a command line, since +the 960 architecture family allows combination of target architectures; each +use will add another pair of name variants to search for when @w{@samp{-l}} +specifies a library. + +@cindex @code{--relax} on i960 +@cindex relaxing on i960 +@code{ld} supports the @samp{--relax} option for the i960 family. If +you specify @samp{--relax}, @code{ld} finds all @code{balx} and +@code{calx} instructions whose targets are within 24 bits, and turns +them into 24-bit program-counter relative @code{bal} and @code{cal} +instructions, respectively. @code{ld} also turns @code{cal} +instructions into @code{bal} instructions when it determines that the +target subroutine is a leaf routine (that is, the target subroutine does +not itself call any subroutines). + +@ifclear GENERIC +@lowersections +@end ifclear +@end ifset + +@ifclear GENERIC +@raisesections +@end ifclear + +@node ARM +@section @code{ld}'s support for interworking between ARM and Thumb code + +@cindex ARM interworking support +@cindex --support-old-code +For the ARM, @code{ld} will generate code stubs to allow functions calls +betweem ARM and Thumb code. These stubs only work with code that has +been compiled and assembled with the @samp{-mthumb-interwork} command +line option. If it is necessary to link with old ARM object files or +libraries, which have not been compiled with the -mthumb-interwork +option then the @samp{--support-old-code} command line switch should be +given to the linker. This will make it generate larger stub functions +which will work with non-interworking aware ARM code. Note, however, +the linker does not support generating stubs for function calls to +non-interworking aware Thumb code. + +@ifclear GENERIC +@lowersections +@end ifclear + +@ifclear SingleFormat +@node BFD +@chapter BFD + +@cindex back end +@cindex object file management +@cindex object formats available +@kindex objdump -i +The linker accesses object and archive files using the BFD libraries. +These libraries allow the linker to use the same routines to operate on +object files whatever the object file format. A different object file +format can be supported simply by creating a new BFD back end and adding +it to the library. To conserve runtime memory, however, the linker and +associated tools are usually configured to support only a subset of the +object file formats available. You can use @code{objdump -i} +(@pxref{objdump,,objdump,binutils.info,The GNU Binary Utilities}) to +list all the formats available for your configuration. + +@cindex BFD requirements +@cindex requirements for BFD +As with most implementations, BFD is a compromise between +several conflicting requirements. The major factor influencing +BFD design was efficiency: any time used converting between +formats is time which would not have been spent had BFD not +been involved. This is partly offset by abstraction payback; since +BFD simplifies applications and back ends, more time and care +may be spent optimizing algorithms for a greater speed. + +One minor artifact of the BFD solution which you should bear in +mind is the potential for information loss. There are two places where +useful information can be lost using the BFD mechanism: during +conversion and during output. @xref{BFD information loss}. + +@menu +* BFD outline:: How it works: an outline of BFD +@end menu + +@node BFD outline +@section How it works: an outline of BFD +@cindex opening object files +@include bfdsumm.texi +@end ifclear + +@node Reporting Bugs +@chapter Reporting Bugs +@cindex bugs in @code{ld} +@cindex reporting bugs in @code{ld} + +Your bug reports play an essential role in making @code{ld} reliable. + +Reporting a bug may help you by bringing a solution to your problem, or +it may not. But in any case the principal function of a bug report is +to help the entire community by making the next version of @code{ld} +work better. Bug reports are your contribution to the maintenance of +@code{ld}. + +In order for a bug report to serve its purpose, you must include the +information that enables us to fix the bug. + +@menu +* Bug Criteria:: Have you found a bug? +* Bug Reporting:: How to report bugs +@end menu + +@node Bug Criteria +@section Have you found a bug? +@cindex bug criteria + +If you are not sure whether you have found a bug, here are some guidelines: + +@itemize @bullet +@cindex fatal signal +@cindex linker crash +@cindex crash of linker +@item +If the linker gets a fatal signal, for any input whatever, that is a +@code{ld} bug. Reliable linkers never crash. + +@cindex error on valid input +@item +If @code{ld} produces an error message for valid input, that is a bug. + +@cindex invalid input +@item +If @code{ld} does not produce an error message for invalid input, that +may be a bug. In the general case, the linker can not verify that +object files are correct. + +@item +If you are an experienced user of linkers, your suggestions for +improvement of @code{ld} are welcome in any case. +@end itemize + +@node Bug Reporting +@section How to report bugs +@cindex bug reports +@cindex @code{ld} bugs, reporting + +A number of companies and individuals offer support for @sc{gnu} +products. If you obtained @code{ld} from a support organization, we +recommend you contact that organization first. + +You can find contact information for many support companies and +individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs +distribution. + +Otherwise, send bug reports for @code{ld} to +@samp{bug-gnu-utils@@gnu.org}. + +The fundamental principle of reporting bugs usefully is this: +@strong{report all the facts}. If you are not sure whether to state a +fact or leave it out, state it! + +Often people omit facts because they think they know what causes the +problem and assume that some details do not matter. Thus, you might +assume that the name of a symbol you use in an example does not matter. +Well, probably it does not, but one cannot be sure. Perhaps the bug is +a stray memory reference which happens to fetch from the location where +that name is stored in memory; perhaps, if the name were different, the +contents of that location would fool the linker into doing the right +thing despite the bug. Play it safe and give a specific, complete +example. That is the easiest thing for you to do, and the most helpful. + +Keep in mind that the purpose of a bug report is to enable us to fix the bug if +it is new to us. Therefore, always write your bug reports on the assumption +that the bug has not been reported previously. + +Sometimes people give a few sketchy facts and ask, ``Does this ring a +bell?'' Those bug reports are useless, and we urge everyone to +@emph{refuse to respond to them} except to chide the sender to report +bugs properly. + +To enable us to fix the bug, you should include all these things: + +@itemize @bullet +@item +The version of @code{ld}. @code{ld} announces it if you start it with +the @samp{--version} argument. + +Without this, we will not know whether there is any point in looking for +the bug in the current version of @code{ld}. + +@item +Any patches you may have applied to the @code{ld} source, including any +patches made to the @code{BFD} library. + +@item +The type of machine you are using, and the operating system name and +version number. + +@item +What compiler (and its version) was used to compile @code{ld}---e.g. +``@code{gcc-2.7}''. + +@item +The command arguments you gave the linker to link your example and +observe the bug. To guarantee you will not omit something important, +list them all. A copy of the Makefile (or the output from make) is +sufficient. + +If we were to try to guess the arguments, we would probably guess wrong +and then we might not encounter the bug. + +@item +A complete input file, or set of input files, that will reproduce the +bug. It is generally most helpful to send the actual object files, +uuencoded if necessary to get them through the mail system. Making them +available for anonymous FTP is not as good, but may be the only +reasonable choice for large object files. + +If the source files were assembled using @code{gas} or compiled using +@code{gcc}, then it may be OK to send the source files rather than the +object files. In this case, be sure to say exactly what version of +@code{gas} or @code{gcc} was used to produce the object files. Also say +how @code{gas} or @code{gcc} were configured. + +@item +A description of what behavior you observe that you believe is +incorrect. For example, ``It gets a fatal signal.'' + +Of course, if the bug is that @code{ld} gets a fatal signal, then we +will certainly notice it. But if the bug is incorrect output, we might +not notice unless it is glaringly wrong. You might as well not give us +a chance to make a mistake. + +Even if the problem you experience is a fatal signal, you should still +say so explicitly. Suppose something strange is going on, such as, your +copy of @code{ld} is out of synch, or you have encountered a bug in the +C library on your system. (This has happened!) Your copy might crash +and ours would not. If you told us to expect a crash, then when ours +fails to crash, we would know that the bug was not happening for us. If +you had not told us to expect a crash, then we would not be able to draw +any conclusion from our observations. + +@item +If you wish to suggest changes to the @code{ld} source, send us context +diffs, as generated by @code{diff} with the @samp{-u}, @samp{-c}, or +@samp{-p} option. Always send diffs from the old file to the new file. +If you even discuss something in the @code{ld} source, refer to it by +context, not by line number. + +The line numbers in our development sources will not match those in your +sources. Your line numbers would convey no useful information to us. +@end itemize + +Here are some things that are not necessary: + +@itemize @bullet +@item +A description of the envelope of the bug. + +Often people who encounter a bug spend a lot of time investigating +which changes to the input file will make the bug go away and which +changes will not affect it. + +This is often time consuming and not very useful, because the way we +will find the bug is by running a single example under the debugger +with breakpoints, not by pure deduction from a series of examples. +We recommend that you save your time for something else. + +Of course, if you can find a simpler example to report @emph{instead} +of the original one, that is a convenience for us. Errors in the +output will be easier to spot, running under the debugger will take +less time, and so on. + +However, simplification is not vital; if you do not want to do this, +report the bug anyway and send us the entire test case you used. + +@item +A patch for the bug. + +A patch for the bug does help us if it is a good one. But do not omit +the necessary information, such as the test case, on the assumption that +a patch is all we need. We might see problems with your patch and decide +to fix the problem another way, or we might not understand it at all. + +Sometimes with a program as complicated as @code{ld} it is very hard to +construct an example that will make the program follow a certain path +through the code. If you do not send us the example, we will not be +able to construct one, so we will not be able to verify that the bug is +fixed. + +And if we cannot understand what bug you are trying to fix, or why your +patch should be an improvement, we will not install it. A test case will +help us to understand. + +@item +A guess about what the bug is or what it depends on. + +Such guesses are usually wrong. Even we cannot guess right about such +things without first using the debugger to find the facts. +@end itemize + +@node MRI +@appendix MRI Compatible Script Files +@cindex MRI compatibility +To aid users making the transition to @sc{gnu} @code{ld} from the MRI +linker, @code{ld} can use MRI compatible linker scripts as an +alternative to the more general-purpose linker scripting language +described in @ref{Scripts}. MRI compatible linker scripts have a much +simpler command set than the scripting language otherwise used with +@code{ld}. @sc{gnu} @code{ld} supports the most commonly used MRI +linker commands; these commands are described here. + +In general, MRI scripts aren't of much use with the @code{a.out} object +file format, since it only has three sections and MRI scripts lack some +features to make use of them. + +You can specify a file containing an MRI-compatible script using the +@samp{-c} command-line option. + +Each command in an MRI-compatible script occupies its own line; each +command line starts with the keyword that identifies the command (though +blank lines are also allowed for punctuation). If a line of an +MRI-compatible script begins with an unrecognized keyword, @code{ld} +issues a warning message, but continues processing the script. + +Lines beginning with @samp{*} are comments. + +You can write these commands using all upper-case letters, or all +lower case; for example, @samp{chip} is the same as @samp{CHIP}. +The following list shows only the upper-case form of each command. + +@table @code +@cindex @code{ABSOLUTE} (MRI) +@item ABSOLUTE @var{secname} +@itemx ABSOLUTE @var{secname}, @var{secname}, @dots{} @var{secname} +Normally, @code{ld} includes in the output file all sections from all +the input files. However, in an MRI-compatible script, you can use the +@code{ABSOLUTE} command to restrict the sections that will be present in +your output program. If the @code{ABSOLUTE} command is used at all in a +script, then only the sections named explicitly in @code{ABSOLUTE} +commands will appear in the linker output. You can still use other +input sections (whatever you select on the command line, or using +@code{LOAD}) to resolve addresses in the output file. + +@cindex @code{ALIAS} (MRI) +@item ALIAS @var{out-secname}, @var{in-secname} +Use this command to place the data from input section @var{in-secname} +in a section called @var{out-secname} in the linker output file. + +@var{in-secname} may be an integer. + +@cindex @code{ALIGN} (MRI) +@item ALIGN @var{secname} = @var{expression} +Align the section called @var{secname} to @var{expression}. The +@var{expression} should be a power of two. + +@cindex @code{BASE} (MRI) +@item BASE @var{expression} +Use the value of @var{expression} as the lowest address (other than +absolute addresses) in the output file. + +@cindex @code{CHIP} (MRI) +@item CHIP @var{expression} +@itemx CHIP @var{expression}, @var{expression} +This command does nothing; it is accepted only for compatibility. + +@cindex @code{END} (MRI) +@item END +This command does nothing whatever; it's only accepted for compatibility. + +@cindex @code{FORMAT} (MRI) +@item FORMAT @var{output-format} +Similar to the @code{OUTPUT_FORMAT} command in the more general linker +language, but restricted to one of these output formats: + +@enumerate +@item +S-records, if @var{output-format} is @samp{S} + +@item +IEEE, if @var{output-format} is @samp{IEEE} + +@item +COFF (the @samp{coff-m68k} variant in BFD), if @var{output-format} is +@samp{COFF} +@end enumerate + +@cindex @code{LIST} (MRI) +@item LIST @var{anything}@dots{} +Print (to the standard output file) a link map, as produced by the +@code{ld} command-line option @samp{-M}. + +The keyword @code{LIST} may be followed by anything on the +same line, with no change in its effect. + +@cindex @code{LOAD} (MRI) +@item LOAD @var{filename} +@itemx LOAD @var{filename}, @var{filename}, @dots{} @var{filename} +Include one or more object file @var{filename} in the link; this has the +same effect as specifying @var{filename} directly on the @code{ld} +command line. + +@cindex @code{NAME} (MRI) +@item NAME @var{output-name} +@var{output-name} is the name for the program produced by @code{ld}; the +MRI-compatible command @code{NAME} is equivalent to the command-line +option @samp{-o} or the general script language command @code{OUTPUT}. + +@cindex @code{ORDER} (MRI) +@item ORDER @var{secname}, @var{secname}, @dots{} @var{secname} +@itemx ORDER @var{secname} @var{secname} @var{secname} +Normally, @code{ld} orders the sections in its output file in the +order in which they first appear in the input files. In an MRI-compatible +script, you can override this ordering with the @code{ORDER} command. The +sections you list with @code{ORDER} will appear first in your output +file, in the order specified. + +@cindex @code{PUBLIC} (MRI) +@item PUBLIC @var{name}=@var{expression} +@itemx PUBLIC @var{name},@var{expression} +@itemx PUBLIC @var{name} @var{expression} +Supply a value (@var{expression}) for external symbol +@var{name} used in the linker input files. + +@cindex @code{SECT} (MRI) +@item SECT @var{secname}, @var{expression} +@itemx SECT @var{secname}=@var{expression} +@itemx SECT @var{secname} @var{expression} +You can use any of these three forms of the @code{SECT} command to +specify the start address (@var{expression}) for section @var{secname}. +If you have more than one @code{SECT} statement for the same +@var{secname}, only the @emph{first} sets the start address. +@end table + +@node Index +@unnumbered Index + +@printindex cp + +@tex +% I think something like @colophon should be in texinfo. In the +% meantime: +\long\def\colophon{\hbox to0pt{}\vfill +\centerline{The body of this manual is set in} +\centerline{\fontname\tenrm,} +\centerline{with headings in {\bf\fontname\tenbf}} +\centerline{and examples in {\tt\fontname\tentt}.} +\centerline{{\it\fontname\tenit\/} and} +\centerline{{\sl\fontname\tensl\/}} +\centerline{are used for emphasis.}\vfill} +\page\colophon +% Blame: doc@cygnus.com, 28mar91. +@end tex + + +@contents +@bye + + diff --git a/ld/ldcref.c b/ld/ldcref.c new file mode 100644 index 0000000..96e0d2d --- /dev/null +++ b/ld/ldcref.c @@ -0,0 +1,549 @@ +/* ldcref.c -- output a cross reference table + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ian Lance Taylor <ian@cygnus.com> + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This file holds routines that manage the cross reference table. + The table is used to generate cross reference reports. It is also + used to implement the NOCROSSREFS command in the linker script. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libiberty.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" + +/* We keep an instance of this structure for each reference to a + symbol from a given object. */ + +struct cref_ref +{ + /* The next reference. */ + struct cref_ref *next; + /* The object. */ + bfd *abfd; + /* True if the symbol is defined. */ + unsigned int def : 1; + /* True if the symbol is common. */ + unsigned int common : 1; + /* True if the symbol is undefined. */ + unsigned int undef : 1; +}; + +/* We keep a hash table of symbols. Each entry looks like this. */ + +struct cref_hash_entry +{ + struct bfd_hash_entry root; + /* The demangled name. */ + char *demangled; + /* References to and definitions of this symbol. */ + struct cref_ref *refs; +}; + +/* This is what the hash table looks like. */ + +struct cref_hash_table +{ + struct bfd_hash_table root; +}; + +/* Local functions. */ + +static struct bfd_hash_entry *cref_hash_newfunc + PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); +static boolean cref_fill_array PARAMS ((struct cref_hash_entry *, PTR)); +static int cref_sort_array PARAMS ((const PTR, const PTR)); +static void output_one_cref PARAMS ((FILE *, struct cref_hash_entry *)); +static boolean check_nocrossref PARAMS ((struct cref_hash_entry *, PTR)); +static void check_refs + PARAMS ((struct cref_hash_entry *, struct bfd_link_hash_entry *, + struct lang_nocrossrefs *)); +static void check_reloc_refs PARAMS ((bfd *, asection *, PTR)); + +/* Look up an entry in the cref hash table. */ + +#define cref_hash_lookup(table, string, create, copy) \ + ((struct cref_hash_entry *) \ + bfd_hash_lookup (&(table)->root, (string), (create), (copy))) + +/* Traverse the cref hash table. */ + +#define cref_hash_traverse(table, func, info) \ + (bfd_hash_traverse \ + (&(table)->root, \ + (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ + (info))) + +/* The cref hash table. */ + +static struct cref_hash_table cref_table; + +/* Whether the cref hash table has been initialized. */ + +static boolean cref_initialized; + +/* The number of symbols seen so far. */ + +static size_t cref_symcount; + +/* Create an entry in a cref hash table. */ + +static struct bfd_hash_entry * +cref_hash_newfunc (entry, table, string) + struct bfd_hash_entry *entry; + struct bfd_hash_table *table; + const char *string; +{ + struct cref_hash_entry *ret = (struct cref_hash_entry *) entry; + + /* Allocate the structure if it has not already been allocated by a + subclass. */ + if (ret == NULL) + ret = ((struct cref_hash_entry *) + bfd_hash_allocate (table, sizeof (struct cref_hash_entry))); + if (ret == NULL) + return (struct bfd_hash_entry *) ret; + + /* Call the allocation method of the superclass. */ + ret = ((struct cref_hash_entry *) + bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); + if (ret != NULL) + { + /* Set local fields. */ + ret->demangled = NULL; + ret->refs = NULL; + + /* Keep a count of the number of entries created in the hash + table. */ + ++cref_symcount; + } + + return (struct bfd_hash_entry *) ret; +} + +/* Add a symbol to the cref hash table. This is called for every + symbol that is seen during the link. */ + +/*ARGSUSED*/ +void +add_cref (name, abfd, section, value) + const char *name; + bfd *abfd; + asection *section; + bfd_vma value; +{ + struct cref_hash_entry *h; + struct cref_ref *r; + + if (! cref_initialized) + { + if (! bfd_hash_table_init (&cref_table.root, cref_hash_newfunc)) + einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n")); + cref_initialized = true; + } + + h = cref_hash_lookup (&cref_table, name, true, false); + if (h == NULL) + einfo (_("%X%P: cref_hash_lookup failed: %E\n")); + + for (r = h->refs; r != NULL; r = r->next) + if (r->abfd == abfd) + break; + + if (r == NULL) + { + r = (struct cref_ref *) xmalloc (sizeof *r); + r->next = h->refs; + h->refs = r; + r->abfd = abfd; + r->def = false; + r->common = false; + r->undef = false; + } + + if (bfd_is_und_section (section)) + r->undef = true; + else if (bfd_is_com_section (section)) + r->common = true; + else + r->def = true; +} + +/* Copy the addresses of the hash table entries into an array. This + is called via cref_hash_traverse. We also fill in the demangled + name. */ + +static boolean +cref_fill_array (h, data) + struct cref_hash_entry *h; + PTR data; +{ + struct cref_hash_entry ***pph = (struct cref_hash_entry ***) data; + + ASSERT (h->demangled == NULL); + h->demangled = demangle (h->root.string); + + **pph = h; + + ++*pph; + + return true; +} + +/* Sort an array of cref hash table entries by name. */ + +static int +cref_sort_array (a1, a2) + const PTR a1; + const PTR a2; +{ + const struct cref_hash_entry **p1 = (const struct cref_hash_entry **) a1; + const struct cref_hash_entry **p2 = (const struct cref_hash_entry **) a2; + + return strcmp ((*p1)->demangled, (*p2)->demangled); +} + +/* Write out the cref table. */ + +#define FILECOL (50) + +void +output_cref (fp) + FILE *fp; +{ + int len; + struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end; + const char *msg; + + fprintf (fp, _("\nCross Reference Table\n\n")); + msg = _("Symbol"); + fprintf (fp, msg); + len = strlen (msg); + while (len < FILECOL) + { + putc (' ' , fp); + ++len; + } + fprintf (fp, _("File\n")); + + if (! cref_initialized) + { + fprintf (fp, _("No symbols\n")); + return; + } + + csyms = ((struct cref_hash_entry **) + xmalloc (cref_symcount * sizeof (*csyms))); + + csym_fill = csyms; + cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill); + ASSERT ((size_t) (csym_fill - csyms) == cref_symcount); + + qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array); + + csym_end = csyms + cref_symcount; + for (csym = csyms; csym < csym_end; csym++) + output_one_cref (fp, *csym); +} + +/* Output one entry in the cross reference table. */ + +static void +output_one_cref (fp, h) + FILE *fp; + struct cref_hash_entry *h; +{ + int len; + struct bfd_link_hash_entry *hl; + struct cref_ref *r; + + hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false, + false, true); + if (hl == NULL) + einfo ("%P: symbol `%T' missing from main hash table\n", + h->root.string); + else + { + /* If this symbol is defined in a dynamic object but never + referenced by a normal object, then don't print it. */ + if (hl->type == bfd_link_hash_defined) + { + if (hl->u.def.section->output_section == NULL) + return; + if (hl->u.def.section->owner != NULL + && (hl->u.def.section->owner->flags & DYNAMIC) != 0) + { + for (r = h->refs; r != NULL; r = r->next) + if ((r->abfd->flags & DYNAMIC) == 0) + break; + if (r == NULL) + return; + } + } + } + + fprintf (fp, "%s ", h->demangled); + len = strlen (h->demangled) + 1; + + for (r = h->refs; r != NULL; r = r->next) + { + if (r->def) + { + while (len < FILECOL) + { + putc (' ', fp); + ++len; + } + lfinfo (fp, "%B\n", r->abfd); + len = 0; + } + } + + for (r = h->refs; r != NULL; r = r->next) + { + if (! r->def) + { + while (len < FILECOL) + { + putc (' ', fp); + ++len; + } + lfinfo (fp, "%B\n", r->abfd); + len = 0; + } + } + + ASSERT (len == 0); +} + +/* Check for prohibited cross references. */ + +void +check_nocrossrefs () +{ + if (! cref_initialized) + return; + + cref_hash_traverse (&cref_table, check_nocrossref, (PTR) NULL); +} + +/* Check one symbol to see if it is a prohibited cross reference. */ + +/*ARGSUSED*/ +static boolean +check_nocrossref (h, ignore) + struct cref_hash_entry *h; + PTR ignore; +{ + struct bfd_link_hash_entry *hl; + asection *defsec; + const char *defsecname; + struct lang_nocrossrefs *ncrs; + struct lang_nocrossref *ncr; + + hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false, + false, true); + if (hl == NULL) + { + einfo (_("%P: symbol `%T' missing from main hash table\n"), + h->root.string); + return true; + } + + if (hl->type != bfd_link_hash_defined + && hl->type != bfd_link_hash_defweak) + return true; + + defsec = hl->u.def.section->output_section; + if (defsec == NULL) + return true; + defsecname = bfd_get_section_name (defsec->owner, defsec); + + for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next) + for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next) + if (strcmp (ncr->name, defsecname) == 0) + check_refs (h, hl, ncrs); + + return true; +} + +/* The struct is used to pass information from check_refs to + check_reloc_refs through bfd_map_over_sections. */ + +struct check_refs_info +{ + struct cref_hash_entry *h; + asection *defsec; + struct lang_nocrossrefs *ncrs; + asymbol **asymbols; + boolean same; +}; + +/* This function is called for each symbol defined in a section which + prohibits cross references. We need to look through all references + to this symbol, and ensure that the references are not from + prohibited sections. */ + +static void +check_refs (h, hl, ncrs) + struct cref_hash_entry *h; + struct bfd_link_hash_entry *hl; + struct lang_nocrossrefs *ncrs; +{ + struct cref_ref *ref; + + for (ref = h->refs; ref != NULL; ref = ref->next) + { + lang_input_statement_type *li; + asymbol **asymbols; + struct check_refs_info info; + + /* We need to look through the relocations for this BFD, to see + if any of the relocations which refer to this symbol are from + a prohibited section. Note that we need to do this even for + the BFD in which the symbol is defined, since even a single + BFD might contain a prohibited cross reference; for this + case, we set the SAME field in INFO, which will cause + CHECK_RELOCS_REFS to check for relocations against the + section as well as against the symbol. */ + + li = (lang_input_statement_type *) ref->abfd->usrdata; + if (li != NULL && li->asymbols != NULL) + asymbols = li->asymbols; + else + { + long symsize; + long symbol_count; + + symsize = bfd_get_symtab_upper_bound (ref->abfd); + if (symsize < 0) + einfo (_("%B%F: could not read symbols; %E\n"), ref->abfd); + asymbols = (asymbol **) xmalloc (symsize); + symbol_count = bfd_canonicalize_symtab (ref->abfd, asymbols); + if (symbol_count < 0) + einfo (_("%B%F: could not read symbols: %E\n"), ref->abfd); + if (li != NULL) + { + li->asymbols = asymbols; + li->symbol_count = symbol_count; + } + } + + info.h = h; + info.defsec = hl->u.def.section; + info.ncrs = ncrs; + info.asymbols = asymbols; + if (ref->abfd == hl->u.def.section->owner) + info.same = true; + else + info.same = false; + bfd_map_over_sections (ref->abfd, check_reloc_refs, (PTR) &info); + + if (li == NULL) + free (asymbols); + } +} + +/* This is called via bfd_map_over_sections. INFO->H is a symbol + defined in INFO->DEFSECNAME. If this section maps into any of the + sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we + look through the relocations. If any of the relocations are to + INFO->H, then we report a prohibited cross reference error. */ + +static void +check_reloc_refs (abfd, sec, iarg) + bfd *abfd; + asection *sec; + PTR iarg; +{ + struct check_refs_info *info = (struct check_refs_info *) iarg; + asection *outsec; + const char *outsecname; + asection *outdefsec; + const char *outdefsecname; + struct lang_nocrossref *ncr; + const char *symname; + long relsize; + arelent **relpp; + long relcount; + arelent **p, **pend; + + outsec = sec->output_section; + outsecname = bfd_get_section_name (outsec->owner, outsec); + + outdefsec = info->defsec->output_section; + outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec); + + /* The section where the symbol is defined is permitted. */ + if (strcmp (outsecname, outdefsecname) == 0) + return; + + for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next) + if (strcmp (outsecname, ncr->name) == 0) + break; + + if (ncr == NULL) + return; + + /* This section is one for which cross references are prohibited. + Look through the relocations, and see if any of them are to + INFO->H. */ + + symname = info->h->root.string; + + relsize = bfd_get_reloc_upper_bound (abfd, sec); + if (relsize < 0) + einfo (_("%B%F: could not read relocs: %E\n"), abfd); + if (relsize == 0) + return; + + relpp = (arelent **) xmalloc (relsize); + relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols); + if (relcount < 0) + einfo (_("%B%F: could not read relocs: %E\n"), abfd); + + p = relpp; + pend = p + relcount; + for (; p < pend && *p != NULL; p++) + { + arelent *q = *p; + + if (q->sym_ptr_ptr != NULL + && *q->sym_ptr_ptr != NULL + && (strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0 + || (info->same + && bfd_get_section (*q->sym_ptr_ptr) == info->defsec))) + { + /* We found a reloc for the symbol. The symbol is defined + in OUTSECNAME. This reloc is from a section which is + mapped into a section from which references to OUTSECNAME + are prohibited. We must report an error. */ + einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"), + abfd, sec, q->address, outsecname, + bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname); + } + } + + free (relpp); +} diff --git a/ld/ldctor.c b/ld/ldctor.c new file mode 100644 index 0000000..0a434b8 --- /dev/null +++ b/ld/ldctor.c @@ -0,0 +1,383 @@ +/* ldctor.c -- constructor support routines + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 + Free Software Foundation, Inc. + By Steve Chamberlain <sac@cygnus.com> + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" + +#include <ctype.h> + +#include "ld.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldmisc.h" +#include "ldgram.h" +#include "ldmain.h" +#include "ldctor.h" + +static int ctor_prio PARAMS ((const char *)); +static int ctor_cmp PARAMS ((const PTR, const PTR)); + +/* The list of statements needed to handle constructors. These are + invoked by the command CONSTRUCTORS in the linker script. */ +lang_statement_list_type constructor_list; + +/* Whether the constructors should be sorted. Note that this is + global for the entire link; we assume that there is only a single + CONSTRUCTORS command in the linker script. */ +boolean constructors_sorted; + +/* The sets we have seen. */ +struct set_info *sets; + +/* Add an entry to a set. H is the entry in the linker hash table. + RELOC is the relocation to use for an entry in the set. SECTION + and VALUE are the value to add. This is called during the first + phase of the link, when we are still gathering symbols together. + We just record the information now. The ldctor_find_constructors + function will construct the sets. */ + +void +ldctor_add_set_entry (h, reloc, name, section, value) + struct bfd_link_hash_entry *h; + bfd_reloc_code_real_type reloc; + const char *name; + asection *section; + bfd_vma value; +{ + struct set_info *p; + struct set_element *e; + struct set_element **epp; + + for (p = sets; p != (struct set_info *) NULL; p = p->next) + if (p->h == h) + break; + + if (p == (struct set_info *) NULL) + { + p = (struct set_info *) xmalloc (sizeof (struct set_info)); + p->next = sets; + sets = p; + p->h = h; + p->reloc = reloc; + p->count = 0; + p->elements = NULL; + } + else + { + if (p->reloc != reloc) + { + einfo (_("%P%X: Different relocs used in set %s\n"), h->root.string); + return; + } + + /* Don't permit a set to be constructed from different object + file formats. The same reloc may have different results. We + actually could sometimes handle this, but the case is + unlikely to ever arise. Sometimes constructor symbols are in + unusual sections, such as the absolute section--this appears + to be the case in Linux a.out--and in such cases we just + assume everything is OK. */ + if (p->elements != NULL + && section->owner != NULL + && p->elements->section->owner != NULL + && strcmp (bfd_get_target (section->owner), + bfd_get_target (p->elements->section->owner)) != 0) + { + einfo (_("%P%X: Different object file formats composing set %s\n"), + h->root.string); + return; + } + } + + e = (struct set_element *) xmalloc (sizeof (struct set_element)); + e->next = NULL; + e->name = name; + e->section = section; + e->value = value; + + for (epp = &p->elements; *epp != NULL; epp = &(*epp)->next) + ; + *epp = e; + + ++p->count; +} + +/* Get the priority of a g++ global constructor or destructor from the + symbol name. */ + +static int +ctor_prio (name) + const char *name; +{ + /* The name will look something like _GLOBAL_$I$65535$test02__Fv. + There might be extra leading underscores, and the $ characters + might be something else. The I might be a D. */ + + while (*name == '_') + ++name; + + if (strncmp (name, "GLOBAL_", sizeof "GLOBAL_" - 1) != 0) + return -1; + + name += sizeof "GLOBAL_" - 1; + + if (name[0] != name[2]) + return -1; + if (name[1] != 'I' && name[1] != 'D') + return -1; + if (! isdigit ((unsigned char) name[3])) + return -1; + + return atoi (name + 3); +} + +/* This function is used to sort constructor elements by priority. It + is called via qsort. */ + +static int +ctor_cmp (p1, p2) + const PTR p1; + const PTR p2; +{ + const struct set_element **pe1 = (const struct set_element **) p1; + const struct set_element **pe2 = (const struct set_element **) p2; + const char *n1; + const char *n2; + int prio1; + int prio2; + + n1 = (*pe1)->name; + if (n1 == NULL) + n1 = ""; + n2 = (*pe2)->name; + if (n2 == NULL) + n2 = ""; + + /* We need to sort in reverse order by priority. When two + constructors have the same priority, we should maintain their + current relative position. */ + + prio1 = ctor_prio (n1); + prio2 = ctor_prio (n2); + + /* We sort in reverse order because that is what g++ expects. */ + if (prio1 < prio2) + return 1; + else if (prio1 > prio2) + return -1; + + /* Force a stable sort. */ + + if (pe1 < pe2) + return -1; + else if (pe1 > pe2) + return 1; + else + return 0; +} + +/* This function is called after the first phase of the link and + before the second phase. At this point all set information has + been gathered. We now put the statements to build the sets + themselves into constructor_list. */ + +void +ldctor_build_sets () +{ + static boolean called; + lang_statement_list_type *old; + boolean header_printed; + struct set_info *p; + + /* The emulation code may call us directly, but we only want to do + this once. */ + if (called) + return; + called = true; + + if (constructors_sorted) + { + for (p = sets; p != NULL; p = p->next) + { + int c, i; + struct set_element *e; + struct set_element **array; + + if (p->elements == NULL) + continue; + + c = 0; + for (e = p->elements; e != NULL; e = e->next) + ++c; + + array = (struct set_element **) xmalloc (c * sizeof *array); + + i = 0; + for (e = p->elements; e != NULL; e = e->next) + { + array[i] = e; + ++i; + } + + qsort (array, c, sizeof *array, ctor_cmp); + + e = array[0]; + p->elements = e; + for (i = 0; i < c - 1; i++) + array[i]->next = array[i + 1]; + array[i]->next = NULL; + + free (array); + } + } + + old = stat_ptr; + stat_ptr = &constructor_list; + + lang_list_init (stat_ptr); + + header_printed = false; + for (p = sets; p != (struct set_info *) NULL; p = p->next) + { + struct set_element *e; + reloc_howto_type *howto; + int reloc_size, size; + + /* If the symbol is defined, we may have been invoked from + collect, and the sets may already have been built, so we do + not do anything. */ + if (p->h->type == bfd_link_hash_defined + || p->h->type == bfd_link_hash_defweak) + continue; + + /* For each set we build: + set: + .long number_of_elements + .long element0 + ... + .long elementN + .long 0 + except that we use the right size instead of .long. When + generating relocateable output, we generate relocs instead of + addresses. */ + howto = bfd_reloc_type_lookup (output_bfd, p->reloc); + if (howto == (reloc_howto_type *) NULL) + { + if (link_info.relocateable) + { + einfo (_("%P%X: %s does not support reloc %s for set %s\n"), + bfd_get_target (output_bfd), + bfd_get_reloc_code_name (p->reloc), + p->h->root.string); + continue; + } + + /* If this is not a relocateable link, all we need is the + size, which we can get from the input BFD. */ + if (p->elements->section->owner != NULL) + howto = bfd_reloc_type_lookup (p->elements->section->owner, + p->reloc); + if (howto == NULL) + { + einfo (_("%P%X: %s does not support reloc %s for set %s\n"), + bfd_get_target (p->elements->section->owner), + bfd_get_reloc_code_name (p->reloc), + p->h->root.string); + continue; + } + } + + reloc_size = bfd_get_reloc_size (howto); + switch (reloc_size) + { + case 1: size = BYTE; break; + case 2: size = SHORT; break; + case 4: size = LONG; break; + case 8: + if (howto->complain_on_overflow == complain_overflow_signed) + size = SQUAD; + else + size = QUAD; + break; + default: + einfo (_("%P%X: Unsupported size %d for set %s\n"), + bfd_get_reloc_size (howto), p->h->root.string); + size = LONG; + break; + } + + lang_add_assignment (exp_assop ('=', ".", + exp_unop (ALIGN_K, + exp_intop (reloc_size)))); + lang_add_assignment (exp_assop ('=', p->h->root.string, + exp_nameop (NAME, "."))); + lang_add_data (size, exp_intop ((bfd_vma) p->count)); + + for (e = p->elements; e != (struct set_element *) NULL; e = e->next) + { + if (config.map_file != NULL) + { + int len; + + if (! header_printed) + { + minfo (_("\nSet Symbol\n\n")); + header_printed = true; + } + + minfo ("%s", p->h->root.string); + len = strlen (p->h->root.string); + + if (len >= 19) + { + print_nl (); + len = 0; + } + while (len < 20) + { + print_space (); + ++len; + } + + if (e->name != NULL) + minfo ("%T\n", e->name); + else + minfo ("%G\n", e->section->owner, e->section, e->value); + } + + /* Need SEC_KEEP for --gc-sections */ + if (! bfd_is_abs_section (e->section)) + e->section->flags |= SEC_KEEP; + + if (link_info.relocateable) + lang_add_reloc (p->reloc, howto, e->section, e->name, + exp_intop (e->value)); + else + lang_add_data (size, exp_relop (e->section, e->value)); + } + + lang_add_data (size, exp_intop (0)); + } + + stat_ptr = old; +} diff --git a/ld/ldctor.h b/ld/ldctor.h new file mode 100644 index 0000000..d873f77 --- /dev/null +++ b/ld/ldctor.h @@ -0,0 +1,60 @@ +/* ldctor.h - linker constructor support + Copyright 1991, 92, 93, 94, 95, 1998 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +#ifndef LDCTOR_H +#define LDCTOR_H + +/* List of statements needed to handle constructors */ +extern lang_statement_list_type constructor_list; + +/* Whether the constructors should be sorted. Note that this is + global for the entire link; we assume that there is only a single + CONSTRUCTORS command in the linker script. */ +extern boolean constructors_sorted; + +/* We keep a list of these structures for each set we build. */ + +struct set_info +{ + struct set_info *next; /* Next set. */ + struct bfd_link_hash_entry *h; /* Hash table entry. */ + bfd_reloc_code_real_type reloc; /* Reloc to use for an entry. */ + size_t count; /* Number of elements. */ + struct set_element *elements; /* Elements in set. */ +}; + +struct set_element +{ + struct set_element *next; /* Next element. */ + const char *name; /* Name in set (may be NULL). */ + asection *section; /* Section of value in set. */ + bfd_vma value; /* Value in set. */ +}; + +/* The sets we have seen. */ + +extern struct set_info *sets; + +extern void ldctor_add_set_entry PARAMS ((struct bfd_link_hash_entry *, + bfd_reloc_code_real_type, + const char *, asection *, bfd_vma)); +extern void ldctor_build_sets PARAMS ((void)); + +#endif diff --git a/ld/ldemul.c b/ld/ldemul.c new file mode 100644 index 0000000..eab0432 --- /dev/null +++ b/ld/ldemul.c @@ -0,0 +1,298 @@ +/* ldemul.c -- clearing house for ld emulation states + Copyright (C) 1991, 92, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" + +#include "ld.h" +#include "ldemul.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldfile.h" +#include "ldmain.h" +#include "ldemul-list.h" + +ld_emulation_xfer_type *ld_emulation; + +void +ldemul_hll(name) + char *name; +{ + ld_emulation->hll(name); +} + + +void ldemul_syslib(name) + char *name; +{ + ld_emulation->syslib(name); +} + +void +ldemul_after_parse() +{ + ld_emulation->after_parse(); +} + +void +ldemul_before_parse() +{ + ld_emulation->before_parse(); +} + +void +ldemul_after_open () +{ + ld_emulation->after_open (); +} + +void +ldemul_after_allocation() +{ + ld_emulation->after_allocation(); +} + +void +ldemul_before_allocation() +{ + if (ld_emulation->before_allocation) + ld_emulation->before_allocation(); +} + + +void +ldemul_set_output_arch() +{ + ld_emulation->set_output_arch(); +} + +void +ldemul_finish() +{ + if (ld_emulation->finish) + ld_emulation->finish(); +} + +void +ldemul_set_symbols() +{ + if (ld_emulation->set_symbols) + ld_emulation->set_symbols(); +} + +void +ldemul_create_output_section_statements() +{ + if (ld_emulation->create_output_section_statements) + ld_emulation->create_output_section_statements(); +} + +char * +ldemul_get_script(isfile) + int *isfile; +{ + return ld_emulation->get_script(isfile); +} + +boolean +ldemul_open_dynamic_archive (arch, search, entry) + const char *arch; + search_dirs_type *search; + lang_input_statement_type *entry; +{ + if (ld_emulation->open_dynamic_archive) + return (*ld_emulation->open_dynamic_archive) (arch, search, entry); + return false; +} + +boolean +ldemul_place_orphan (file, s) + lang_input_statement_type *file; + asection *s; +{ + if (ld_emulation->place_orphan) + return (*ld_emulation->place_orphan) (file, s); + return false; +} + +int +ldemul_parse_args (argc, argv) + int argc; + char **argv; +{ + /* Try and use the emulation parser if there is one. */ + if (ld_emulation->parse_args) + { + return ld_emulation->parse_args (argc, argv); + } + return 0; +} + +/* Let the emulation code handle an unrecognized file. */ + +boolean +ldemul_unrecognized_file (entry) + lang_input_statement_type *entry; +{ + if (ld_emulation->unrecognized_file) + return (*ld_emulation->unrecognized_file) (entry); + return false; +} + +/* Let the emulation code handle a recognized file. */ + +boolean +ldemul_recognized_file (entry) + lang_input_statement_type *entry; +{ + if (ld_emulation->recognized_file) + return (*ld_emulation->recognized_file) (entry); + return false; +} + +char * +ldemul_choose_target() +{ + return ld_emulation->choose_target(); +} + +/* The default choose_target function. */ + +char * +ldemul_default_target() +{ + char *from_outside = getenv (TARGET_ENVIRON); + if (from_outside != (char *)NULL) + return from_outside; + return ld_emulation->target_name; +} + +void +after_parse_default() +{ + +} + +void +after_open_default () +{ +} + +void +after_allocation_default() +{ + +} + +void +before_allocation_default() +{ + +} + +void +set_output_arch_default() +{ + /* Set the output architecture and machine if possible */ + bfd_set_arch_mach(output_bfd, + ldfile_output_architecture, ldfile_output_machine); +} + +/*ARGSUSED*/ +void +syslib_default(ignore) + char *ignore; +{ + info_msg (_("%S SYSLIB ignored\n")); +} + +/*ARGSUSED*/ +void +hll_default(ignore) + char *ignore; +{ + info_msg (_("%S HLL ignored\n")); +} + +ld_emulation_xfer_type *ld_emulations[] = { EMULATION_LIST }; + +void +ldemul_choose_mode(target) + char *target; +{ + ld_emulation_xfer_type **eptr = ld_emulations; + /* Ignore "gld" prefix. */ + if (target[0] == 'g' && target[1] == 'l' && target[2] == 'd') + target += 3; + for (; *eptr; eptr++) + { + if (strcmp(target, (*eptr)->emulation_name) == 0) + { + ld_emulation = *eptr; + return; + } + } + einfo (_("%P: unrecognised emulation mode: %s\n"), target); + einfo (_("Supported emulations: ")); + ldemul_list_emulations (stderr); + einfo ("%F\n"); +} + +void +ldemul_list_emulations (f) + FILE *f; +{ + ld_emulation_xfer_type **eptr = ld_emulations; + boolean first = true; + + for (; *eptr; eptr++) + { + if (first) + first = false; + else + fprintf (f, " "); + fprintf (f, "%s", (*eptr)->emulation_name); + } +} + +void +ldemul_list_emulation_options (f) + FILE * f; +{ + ld_emulation_xfer_type ** eptr; + int options_found = 0; + + for (eptr = ld_emulations; * eptr; eptr ++) + { + ld_emulation_xfer_type * emul = * eptr; + + if (emul->list_options) + { + fprintf (f, "%s: \n", emul->emulation_name); + + emul->list_options (f); + + options_found = 1; + } + } + + if (! options_found) + fprintf (f, _(" no emulation specific options.\n")); +} diff --git a/ld/ldemul.h b/ld/ldemul.h new file mode 100644 index 0000000..350de06 --- /dev/null +++ b/ld/ldemul.h @@ -0,0 +1,149 @@ +/* ld-emul.h - Linker emulation header file + Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. */ + +#ifndef LDEMUL_H +#define LDEMUL_H + +#if ANSI_PROTOTYPES +struct lang_input_statement_struct; +struct search_dirs; +#endif + +extern void ldemul_hll PARAMS ((char *)); +extern void ldemul_syslib PARAMS ((char *)); +extern void ldemul_after_parse PARAMS ((void)); +extern void ldemul_before_parse PARAMS ((void)); +extern void ldemul_after_open PARAMS ((void)); +extern void ldemul_after_allocation PARAMS ((void)); +extern void ldemul_before_allocation PARAMS ((void)); +extern void ldemul_set_output_arch PARAMS ((void)); +extern char *ldemul_choose_target PARAMS ((void)); +extern void ldemul_choose_mode PARAMS ((char *)); +extern void ldemul_list_emulations PARAMS ((FILE *)); +extern void ldemul_list_emulation_options PARAMS ((FILE *)); +extern char *ldemul_get_script PARAMS ((int *isfile)); +extern void ldemul_finish PARAMS ((void)); +extern void ldemul_set_symbols PARAMS ((void)); +extern void ldemul_create_output_section_statements PARAMS ((void)); +extern boolean ldemul_place_orphan + PARAMS ((struct lang_input_statement_struct *, asection *)); +extern int ldemul_parse_args PARAMS ((int, char **)); +extern boolean ldemul_unrecognized_file + PARAMS ((struct lang_input_statement_struct *)); +extern boolean ldemul_recognized_file + PARAMS ((struct lang_input_statement_struct *)); +extern boolean ldemul_open_dynamic_archive + PARAMS ((const char *, struct search_dirs *, + struct lang_input_statement_struct *)); +extern char *ldemul_default_target PARAMS ((void)); +extern void after_parse_default PARAMS ((void)); +extern void after_open_default PARAMS ((void)); +extern void after_allocation_default PARAMS ((void)); +extern void before_allocation_default PARAMS ((void)); +extern void set_output_arch_default PARAMS ((void)); +extern void syslib_default PARAMS ((char*)); +extern void hll_default PARAMS ((char*)); + +typedef struct ld_emulation_xfer_struct +{ + /* Run before parsing the command line and script file. + Set the architecture, maybe other things. */ + void (*before_parse) PARAMS ((void)); + + /* Handle the SYSLIB (low level library) script command. */ + void (*syslib) PARAMS ((char *)); + + /* Handle the HLL (high level library) script command. */ + void (*hll) PARAMS ((char *)); + + /* Run after parsing the command line and script file. */ + void (*after_parse) PARAMS ((void)); + + /* Run after opening all input files, and loading the symbols. */ + void (*after_open) PARAMS ((void)); + + /* Run after allocating output sections. */ + void (*after_allocation) PARAMS ( (void)); + + /* Set the output architecture and machine if possible. */ + void (*set_output_arch) PARAMS ((void)); + + /* Decide which target name to use. */ + char * (*choose_target) PARAMS ((void)); + + /* Run before allocating output sections. */ + void (*before_allocation) PARAMS ((void)); + + /* Return the appropriate linker script. */ + char * (*get_script) PARAMS ((int *isfile)); + + /* The name of this emulation. */ + char *emulation_name; + + /* The output format. */ + char *target_name; + + /* Run after assigning values from the script. */ + void (*finish) PARAMS ((void)); + + /* Create any output sections needed by the target. */ + void (*create_output_section_statements) PARAMS ((void)); + + /* Try to open a dynamic library. ARCH is an architecture name, and + is normally the empty string. ENTRY is the lang_input_statement + that should be opened. */ + boolean (*open_dynamic_archive) + PARAMS ((const char *arch, struct search_dirs *, + struct lang_input_statement_struct *entry)); + + /* Place an orphan section. Return true if it was placed, false if + the default action should be taken. This field may be NULL, in + which case the default action will always be taken. */ + boolean (*place_orphan) + PARAMS ((struct lang_input_statement_struct *, asection *)); + + /* Run after assigning parsing with the args, but before + reading the script. Used to initialize symbols used in the script. */ + void (*set_symbols) PARAMS ((void)); + + /* Run to parse args which the base linker doesn't + understand. Return non zero on sucess. */ + int (*parse_args) PARAMS ((int, char **)); + + /* Run to handle files which are not recognized as object files or + archives. Return true if the file was handled. */ + boolean (*unrecognized_file) + PARAMS ((struct lang_input_statement_struct *)); + + /* Run to list the command line options which parse_args handles. */ + void (* list_options) PARAMS ((FILE *)); + + /* Run to specially handle files which *are* recognized as object + files or archives. Return true if the file was handled. */ + boolean (*recognized_file) + PARAMS ((struct lang_input_statement_struct *)); + +} ld_emulation_xfer_type; + +typedef enum +{ + intel_ic960_ld_mode_enum, + default_mode_enum , + intel_gld960_ld_mode_enum +} lang_emulation_mode_enum_type; + +extern ld_emulation_xfer_type *ld_emulations[]; + +#endif diff --git a/ld/ldexp.c b/ld/ldexp.c new file mode 100644 index 0000000..6c9d726 --- /dev/null +++ b/ld/ldexp.c @@ -0,0 +1,985 @@ +/* This module handles expression trees. +Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. +Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com). + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* +This module is in charge of working out the contents of expressions. + +It has to keep track of the relative/absness of a symbol etc. This is +done by keeping all values in a struct (an etree_value_type) which +contains a value, a section to which it is relative and a valid bit. + +*/ + + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldgram.h" +#include "ldlang.h" + +static void exp_print_token PARAMS ((token_code_type code)); +static void make_abs PARAMS ((etree_value_type *ptr)); +static etree_value_type new_abs PARAMS ((bfd_vma value)); +static void check PARAMS ((lang_output_section_statement_type *os, + const char *name, const char *op)); +static etree_value_type new_rel + PARAMS ((bfd_vma value, lang_output_section_statement_type *section)); +static etree_value_type new_rel_from_section + PARAMS ((bfd_vma value, lang_output_section_statement_type *section)); +static etree_value_type fold_binary + PARAMS ((etree_type *tree, + lang_output_section_statement_type *current_section, + lang_phase_type allocation_done, + bfd_vma dot, bfd_vma *dotp)); +static etree_value_type fold_name + PARAMS ((etree_type *tree, + lang_output_section_statement_type *current_section, + lang_phase_type allocation_done, + bfd_vma dot)); +static etree_value_type exp_fold_tree_no_dot + PARAMS ((etree_type *tree, + lang_output_section_statement_type *current_section, + lang_phase_type allocation_done)); + +static void +exp_print_token (code) + token_code_type code; +{ + static CONST struct + { + token_code_type code; + char *name; + } table[] = + { + { INT, "int" }, + { REL, "relocateable" }, + { NAME,"NAME" }, + { PLUSEQ,"+=" }, + { MINUSEQ,"-=" }, + { MULTEQ,"*=" }, + { DIVEQ,"/=" }, + { LSHIFTEQ,"<<=" }, + { RSHIFTEQ,">>=" }, + { ANDEQ,"&=" }, + { OREQ,"|=" }, + { OROR,"||" }, + { ANDAND,"&&" }, + { EQ,"==" }, + { NE,"!=" }, + { LE,"<=" }, + { GE,">=" }, + { LSHIFT,"<<" }, + { RSHIFT,">>=" }, + { ALIGN_K,"ALIGN" }, + { BLOCK,"BLOCK" }, + { SECTIONS,"SECTIONS" }, + { SIZEOF_HEADERS,"SIZEOF_HEADERS" }, + { NEXT,"NEXT" }, + { SIZEOF,"SIZEOF" }, + { ADDR,"ADDR" }, + { LOADADDR,"LOADADDR" }, + { MEMORY,"MEMORY" }, + { DEFINED,"DEFINED" }, + { TARGET_K,"TARGET" }, + { SEARCH_DIR,"SEARCH_DIR" }, + { MAP,"MAP" }, + { QUAD,"QUAD" }, + { SQUAD,"SQUAD" }, + { LONG,"LONG" }, + { SHORT,"SHORT" }, + { BYTE,"BYTE" }, + { ENTRY,"ENTRY" }, + { 0,(char *)NULL } + }; + unsigned int idx; + + for (idx = 0; table[idx].name != (char*)NULL; idx++) { + if (table[idx].code == code) { + fprintf(config.map_file, "%s", table[idx].name); + return; + } + } + /* Not in table, just print it alone */ + fprintf(config.map_file, "%c",code); +} + +static void +make_abs (ptr) + etree_value_type *ptr; +{ + asection *s = ptr->section->bfd_section; + ptr->value += s->vma; + ptr->section = abs_output_section; +} + +static etree_value_type +new_abs (value) + bfd_vma value; +{ + etree_value_type new; + new.valid_p = true; + new.section = abs_output_section; + new.value = value; + return new; +} + +static void +check (os, name, op) + lang_output_section_statement_type *os; + const char *name; + const char *op; +{ + if (os == NULL) + einfo (_("%F%P: %s uses undefined section %s\n"), op, name); + if (! os->processed) + einfo (_("%F%P: %s forward reference of section %s\n"), op, name); +} + +etree_type * +exp_intop (value) + bfd_vma value; +{ + etree_type *new = (etree_type *) stat_alloc(sizeof(new->value)); + new->type.node_code = INT; + new->value.value = value; + new->type.node_class = etree_value; + return new; + +} + +/* Build an expression representing an unnamed relocateable value. */ + +etree_type * +exp_relop (section, value) + asection *section; + bfd_vma value; +{ + etree_type *new = (etree_type *) stat_alloc (sizeof (new->rel)); + new->type.node_code = REL; + new->type.node_class = etree_rel; + new->rel.section = section; + new->rel.value = value; + return new; +} + +static etree_value_type +new_rel (value, section) + bfd_vma value; + lang_output_section_statement_type *section; +{ + etree_value_type new; + new.valid_p = true; + new.value = value; + new.section = section; + return new; +} + +static etree_value_type +new_rel_from_section (value, section) + bfd_vma value; + lang_output_section_statement_type *section; +{ + etree_value_type new; + new.valid_p = true; + new.value = value; + new.section = section; + + new.value -= section->bfd_section->vma; + + return new; +} + +static etree_value_type +fold_binary (tree, current_section, allocation_done, dot, dotp) + etree_type *tree; + lang_output_section_statement_type *current_section; + lang_phase_type allocation_done; + bfd_vma dot; + bfd_vma *dotp; +{ + etree_value_type result; + + result = exp_fold_tree (tree->binary.lhs, current_section, + allocation_done, dot, dotp); + if (result.valid_p) + { + etree_value_type other; + + other = exp_fold_tree (tree->binary.rhs, + current_section, + allocation_done, dot,dotp) ; + if (other.valid_p) + { + /* If the values are from different sections, or this is an + absolute expression, make both the source arguments + absolute. However, adding or subtracting an absolute + value from a relative value is meaningful, and is an + exception. */ + if (current_section != abs_output_section + && (other.section == abs_output_section + || (result.section == abs_output_section + && tree->type.node_code == '+')) + && (tree->type.node_code == '+' + || tree->type.node_code == '-')) + { + etree_value_type hold; + + /* If there is only one absolute term, make sure it is the + second one. */ + if (other.section != abs_output_section) + { + hold = result; + result = other; + other = hold; + } + } + else if (result.section != other.section + || current_section == abs_output_section) + { + make_abs(&result); + make_abs(&other); + } + + switch (tree->type.node_code) + { + case '%': + if (other.value == 0) + einfo (_("%F%S %% by zero\n")); + result.value = ((bfd_signed_vma) result.value + % (bfd_signed_vma) other.value); + break; + + case '/': + if (other.value == 0) + einfo (_("%F%S / by zero\n")); + result.value = ((bfd_signed_vma) result.value + / (bfd_signed_vma) other.value); + break; + +#define BOP(x,y) case x : result.value = result.value y other.value; break; + BOP('+',+); + BOP('*',*); + BOP('-',-); + BOP(LSHIFT,<<); + BOP(RSHIFT,>>); + BOP(EQ,==); + BOP(NE,!=); + BOP('<',<); + BOP('>',>); + BOP(LE,<=); + BOP(GE,>=); + BOP('&',&); + BOP('^',^); + BOP('|',|); + BOP(ANDAND,&&); + BOP(OROR,||); + + case MAX_K: + if (result.value < other.value) + result = other; + break; + + case MIN_K: + if (result.value > other.value) + result = other; + break; + + default: + FAIL(); + } + } + else + { + result.valid_p = false; + } + } + + return result; +} + +etree_value_type +invalid () +{ + etree_value_type new; + new.valid_p = false; + return new; +} + +static etree_value_type +fold_name (tree, current_section, allocation_done, dot) + etree_type *tree; + lang_output_section_statement_type *current_section; + lang_phase_type allocation_done; + bfd_vma dot; +{ + etree_value_type result; + switch (tree->type.node_code) + { + case SIZEOF_HEADERS: + if (allocation_done != lang_first_phase_enum) + { + result = new_abs ((bfd_vma) + bfd_sizeof_headers (output_bfd, + link_info.relocateable)); + } + else + { + result.valid_p = false; + } + break; + case DEFINED: + if (allocation_done == lang_first_phase_enum) + result.valid_p = false; + else + { + struct bfd_link_hash_entry *h; + + h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info, + tree->name.name, + false, false, true); + result.value = (h != (struct bfd_link_hash_entry *) NULL + && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak + || h->type == bfd_link_hash_common)); + result.section = 0; + result.valid_p = true; + } + break; + case NAME: + result.valid_p = false; + if (tree->name.name[0] == '.' && tree->name.name[1] == 0) + { + if (allocation_done != lang_first_phase_enum) + result = new_rel_from_section(dot, current_section); + else + result = invalid(); + } + else if (allocation_done != lang_first_phase_enum) + { + struct bfd_link_hash_entry *h; + + h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info, + tree->name.name, + false, false, true); + if (h != NULL + && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak)) + { + if (bfd_is_abs_section (h->u.def.section)) + result = new_abs (h->u.def.value); + else if (allocation_done == lang_final_phase_enum + || allocation_done == lang_allocating_phase_enum) + { + asection *output_section; + + output_section = h->u.def.section->output_section; + if (output_section == NULL) + einfo (_("%X%S: unresolvable symbol `%s' referenced in expression\n"), + tree->name.name); + else + { + lang_output_section_statement_type *os; + + os = (lang_output_section_statement_lookup + (bfd_get_section_name (output_bfd, + output_section))); + + /* FIXME: Is this correct if this section is + being linked with -R? */ + result = new_rel ((h->u.def.value + + h->u.def.section->output_offset), + os); + } + } + } + else if (allocation_done == lang_final_phase_enum) + einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"), + tree->name.name); + } + break; + + case ADDR: + if (allocation_done != lang_first_phase_enum) + { + lang_output_section_statement_type *os; + + os = lang_output_section_find (tree->name.name); + check (os, tree->name.name, "ADDR"); + result = new_rel (0, os); + } + else + result = invalid (); + break; + + case LOADADDR: + if (allocation_done != lang_first_phase_enum) + { + lang_output_section_statement_type *os; + + os = lang_output_section_find (tree->name.name); + check (os, tree->name.name, "LOADADDR"); + if (os->load_base == NULL) + result = new_rel (0, os); + else + result = exp_fold_tree_no_dot (os->load_base, + abs_output_section, + allocation_done); + } + else + result = invalid (); + break; + + case SIZEOF: + if (allocation_done != lang_first_phase_enum) + { + lang_output_section_statement_type *os; + + os = lang_output_section_find (tree->name.name); + check (os, tree->name.name, "SIZEOF"); + result = new_abs (os->bfd_section->_raw_size); + } + else + result = invalid (); + break; + + default: + FAIL(); + break; + } + + return result; +} +etree_value_type +exp_fold_tree (tree, current_section, allocation_done, dot, dotp) + etree_type *tree; + lang_output_section_statement_type *current_section; + lang_phase_type allocation_done; + bfd_vma dot; + bfd_vma *dotp; +{ + etree_value_type result; + + if (tree == NULL) + { + result.valid_p = false; + return result; + } + + switch (tree->type.node_class) + { + case etree_value: + result = new_rel (tree->value.value, current_section); + break; + + case etree_rel: + if (allocation_done != lang_final_phase_enum) + result.valid_p = false; + else + result = new_rel ((tree->rel.value + + tree->rel.section->output_section->vma + + tree->rel.section->output_offset), + current_section); + break; + + case etree_assert: + result = exp_fold_tree (tree->assert_s.child, + current_section, + allocation_done, dot, dotp); + if (result.valid_p) + { + if (! result.value) + einfo ("%F%P: %s\n", tree->assert_s.message); + return result; + } + break; + + case etree_unary: + result = exp_fold_tree (tree->unary.child, + current_section, + allocation_done, dot, dotp); + if (result.valid_p) + { + switch (tree->type.node_code) + { + case ALIGN_K: + if (allocation_done != lang_first_phase_enum) + result = new_rel_from_section (ALIGN_N (dot, result.value), + current_section); + else + result.valid_p = false; + break; + + case ABSOLUTE: + if (allocation_done != lang_first_phase_enum && result.valid_p) + { + result.value += result.section->bfd_section->vma; + result.section = abs_output_section; + } + else + result.valid_p = false; + break; + + case '~': + make_abs (&result); + result.value = ~result.value; + break; + + case '!': + make_abs (&result); + result.value = !result.value; + break; + + case '-': + make_abs (&result); + result.value = -result.value; + break; + + case NEXT: + /* Return next place aligned to value. */ + if (allocation_done == lang_allocating_phase_enum) + { + make_abs (&result); + result.value = ALIGN_N (dot, result.value); + } + else + result.valid_p = false; + break; + + default: + FAIL (); + break; + } + } + break; + + case etree_trinary: + result = exp_fold_tree (tree->trinary.cond, current_section, + allocation_done, dot, dotp); + if (result.valid_p) + result = exp_fold_tree ((result.value + ? tree->trinary.lhs + : tree->trinary.rhs), + current_section, + allocation_done, dot, dotp); + break; + + case etree_binary: + result = fold_binary (tree, current_section, allocation_done, + dot, dotp); + break; + + case etree_assign: + case etree_provide: + if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) + { + /* Assignment to dot can only be done during allocation */ + if (tree->type.node_class == etree_provide) + einfo (_("%F%S can not PROVIDE assignment to location counter\n")); + if (allocation_done == lang_allocating_phase_enum + || (allocation_done == lang_final_phase_enum + && current_section == abs_output_section)) + { + result = exp_fold_tree (tree->assign.src, + current_section, + lang_allocating_phase_enum, dot, + dotp); + if (! result.valid_p) + einfo (_("%F%S invalid assignment to location counter\n")); + else + { + if (current_section == NULL) + einfo (_("%F%S assignment to location counter invalid outside of SECTION\n")); + else + { + bfd_vma nextdot; + + nextdot = (result.value + + current_section->bfd_section->vma); + if (nextdot < dot + && current_section != abs_output_section) + { + einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"), + dot, nextdot); + } + else + *dotp = nextdot; + } + } + } + } + else + { + result = exp_fold_tree (tree->assign.src, + current_section, allocation_done, + dot, dotp); + if (result.valid_p) + { + boolean create; + struct bfd_link_hash_entry *h; + + if (tree->type.node_class == etree_assign) + create = true; + else + create = false; + h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, + create, false, false); + if (h == (struct bfd_link_hash_entry *) NULL) + { + if (tree->type.node_class == etree_assign) + einfo (_("%P%F:%s: hash creation failed\n"), + tree->assign.dst); + } + else if (tree->type.node_class == etree_provide + && h->type != bfd_link_hash_undefined + && h->type != bfd_link_hash_common) + { + /* Do nothing. The symbol was defined by some + object. */ + } + else + { + /* FIXME: Should we worry if the symbol is already + defined? */ + h->type = bfd_link_hash_defined; + h->u.def.value = result.value; + h->u.def.section = result.section->bfd_section; + } + } + } + break; + + case etree_name: + result = fold_name (tree, current_section, allocation_done, dot); + break; + + default: + FAIL (); + break; + } + + return result; +} + +static etree_value_type +exp_fold_tree_no_dot (tree, current_section, allocation_done) + etree_type *tree; + lang_output_section_statement_type *current_section; + lang_phase_type allocation_done; +{ +return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma) + 0, (bfd_vma *)NULL); +} + +etree_type * +exp_binop (code, lhs, rhs) + int code; + etree_type *lhs; + etree_type *rhs; +{ + etree_type value, *new; + etree_value_type r; + + value.type.node_code = code; + value.binary.lhs = lhs; + value.binary.rhs = rhs; + value.type.node_class = etree_binary; + r = exp_fold_tree_no_dot(&value, + abs_output_section, + lang_first_phase_enum ); + if (r.valid_p) + { + return exp_intop(r.value); + } + new = (etree_type *) stat_alloc (sizeof (new->binary)); + memcpy((char *)new, (char *)&value, sizeof(new->binary)); + return new; +} + +etree_type * +exp_trinop (code, cond, lhs, rhs) + int code; + etree_type *cond; + etree_type *lhs; + etree_type *rhs; +{ + etree_type value, *new; + etree_value_type r; + value.type.node_code = code; + value.trinary.lhs = lhs; + value.trinary.cond = cond; + value.trinary.rhs = rhs; + value.type.node_class = etree_trinary; + r= exp_fold_tree_no_dot(&value, (lang_output_section_statement_type + *)NULL,lang_first_phase_enum); + if (r.valid_p) { + return exp_intop(r.value); + } + new = (etree_type *) stat_alloc (sizeof (new->trinary)); + memcpy((char *)new,(char *) &value, sizeof(new->trinary)); + return new; +} + + +etree_type * +exp_unop (code, child) + int code; + etree_type *child; +{ + etree_type value, *new; + + etree_value_type r; + value.unary.type.node_code = code; + value.unary.child = child; + value.unary.type.node_class = etree_unary; + r = exp_fold_tree_no_dot(&value,abs_output_section, + lang_first_phase_enum); + if (r.valid_p) { + return exp_intop(r.value); + } + new = (etree_type *) stat_alloc (sizeof (new->unary)); + memcpy((char *)new, (char *)&value, sizeof(new->unary)); + return new; +} + + +etree_type * +exp_nameop (code, name) + int code; + CONST char *name; +{ + etree_type value, *new; + etree_value_type r; + value.name.type.node_code = code; + value.name.name = name; + value.name.type.node_class = etree_name; + + + r = exp_fold_tree_no_dot(&value, + (lang_output_section_statement_type *)NULL, + lang_first_phase_enum); + if (r.valid_p) { + return exp_intop(r.value); + } + new = (etree_type *) stat_alloc (sizeof (new->name)); + memcpy((char *)new, (char *)&value, sizeof(new->name)); + return new; + +} + + + + +etree_type * +exp_assop (code, dst, src) + int code; + CONST char *dst; + etree_type *src; +{ + etree_type value, *new; + + value.assign.type.node_code = code; + + + value.assign.src = src; + value.assign.dst = dst; + value.assign.type.node_class = etree_assign; + +#if 0 + if (exp_fold_tree_no_dot(&value, &result)) { + return exp_intop(result); + } +#endif + new = (etree_type*) stat_alloc (sizeof (new->assign)); + memcpy((char *)new, (char *)&value, sizeof(new->assign)); + return new; +} + +/* Handle PROVIDE. */ + +etree_type * +exp_provide (dst, src) + const char *dst; + etree_type *src; +{ + etree_type *n; + + n = (etree_type *) stat_alloc (sizeof (n->assign)); + n->assign.type.node_code = '='; + n->assign.type.node_class = etree_provide; + n->assign.src = src; + n->assign.dst = dst; + return n; +} + +/* Handle ASSERT. */ + +etree_type * +exp_assert (exp, message) + etree_type *exp; + const char *message; +{ + etree_type *n; + + n = (etree_type *) stat_alloc (sizeof (n->assert_s)); + n->assert_s.type.node_code = '!'; + n->assert_s.type.node_class = etree_assert; + n->assert_s.child = exp; + n->assert_s.message = message; + return n; +} + +void +exp_print_tree (tree) + etree_type *tree; +{ + switch (tree->type.node_class) { + case etree_value: + minfo ("0x%v", tree->value.value); + return; + case etree_rel: + if (tree->rel.section->owner != NULL) + minfo ("%B:", tree->rel.section->owner); + minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value); + return; + case etree_assign: +#if 0 + if (tree->assign.dst->sdefs != (asymbol *)NULL){ + fprintf(config.map_file,"%s (%x) ",tree->assign.dst->name, + tree->assign.dst->sdefs->value); + } + else { + fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name); + } +#endif + fprintf(config.map_file,"%s",tree->assign.dst); + exp_print_token(tree->type.node_code); + exp_print_tree(tree->assign.src); + break; + case etree_provide: + fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst); + exp_print_tree (tree->assign.src); + fprintf (config.map_file, ")"); + break; + case etree_binary: + fprintf(config.map_file,"("); + exp_print_tree(tree->binary.lhs); + exp_print_token(tree->type.node_code); + exp_print_tree(tree->binary.rhs); + fprintf(config.map_file,")"); + break; + case etree_trinary: + exp_print_tree(tree->trinary.cond); + fprintf(config.map_file,"?"); + exp_print_tree(tree->trinary.lhs); + fprintf(config.map_file,":"); + exp_print_tree(tree->trinary.rhs); + break; + case etree_unary: + exp_print_token(tree->unary.type.node_code); + if (tree->unary.child) + { + fprintf(config.map_file,"("); + exp_print_tree(tree->unary.child); + fprintf(config.map_file,")"); + } + + break; + + case etree_assert: + fprintf (config.map_file, "ASSERT ("); + exp_print_tree (tree->assert_s.child); + fprintf (config.map_file, ", %s)", tree->assert_s.message); + break; + + case etree_undef: + fprintf(config.map_file,"????????"); + break; + case etree_name: + if (tree->type.node_code == NAME) { + fprintf(config.map_file,"%s", tree->name.name); + } + else { + exp_print_token(tree->type.node_code); + if (tree->name.name) + fprintf(config.map_file,"(%s)", tree->name.name); + } + break; + default: + FAIL(); + break; + } +} + +bfd_vma +exp_get_vma (tree, def, name, allocation_done) + etree_type *tree; + bfd_vma def; + char *name; + lang_phase_type allocation_done; +{ + etree_value_type r; + + if (tree != NULL) + { + r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done); + if (! r.valid_p && name != NULL) + einfo (_("%F%S nonconstant expression for %s\n"), name); + return r.value; + } + else + return def; +} + +int +exp_get_value_int (tree,def,name, allocation_done) + etree_type *tree; + int def; + char *name; + lang_phase_type allocation_done; +{ + return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done); +} + + +bfd_vma +exp_get_abs_int (tree, def, name, allocation_done) + etree_type *tree; + int def; + char *name; + lang_phase_type allocation_done; +{ + etree_value_type res; + res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done); + + if (res.valid_p) + { + res.value += res.section->bfd_section->vma; + } + else { + einfo (_("%F%S non constant expression for %s\n"),name); + } + return res.value; +} diff --git a/ld/ldexp.h b/ld/ldexp.h new file mode 100644 index 0000000..b8e8ddf --- /dev/null +++ b/ld/ldexp.h @@ -0,0 +1,116 @@ +/* ldexp.h - + Copyright 1991, 92, 93, 94, 95, 1998 Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef LDEXP_H +#define LDEXP_H + +/* The result of an expression tree */ +typedef struct +{ + bfd_vma value; + struct lang_output_section_statement_struct *section; + boolean valid_p; +} etree_value_type; + + + +typedef struct +{ + int node_code; + enum { etree_binary, + etree_trinary, + etree_unary, + etree_name, + etree_assign, + etree_provide, + etree_undef, + etree_unspec, + etree_value, + etree_assert, + etree_rel } node_class; +} node_type; + + + +typedef union etree_union +{ + node_type type; + struct { + node_type type; + union etree_union *lhs; + union etree_union *rhs; + } binary; + struct { + node_type type; + union etree_union *cond; + union etree_union *lhs; + union etree_union *rhs; + } trinary; + struct { + node_type type; + CONST char *dst; + union etree_union *src; + } assign; + + struct { + node_type type; + union etree_union *child; + } unary; + struct { + node_type type; + CONST char *name; + } name; + struct { + node_type type; + bfd_vma value; + } value; + struct { + node_type type; + asection *section; + bfd_vma value; + } rel; + struct { + node_type type; + union etree_union *child; + const char *message; + } assert_s; +} etree_type; + + +etree_type *exp_intop PARAMS ((bfd_vma)); +etree_type *exp_relop PARAMS ((asection *, bfd_vma)); +etree_value_type invalid PARAMS ((void)); +etree_value_type exp_fold_tree PARAMS ((etree_type *, struct + lang_output_section_statement_struct *, + lang_phase_type, + bfd_vma, bfd_vma *)); +etree_type *exp_binop PARAMS ((int, etree_type *, etree_type *)); +etree_type *exp_trinop PARAMS ((int,etree_type *, etree_type *, etree_type *)); +etree_type *exp_unop PARAMS ((int, etree_type *)); +etree_type *exp_nameop PARAMS ((int, CONST char *)); +etree_type *exp_assop PARAMS ((int, CONST char *, etree_type *)); +etree_type *exp_provide PARAMS ((const char *, etree_type *)); +etree_type *exp_assert PARAMS ((etree_type *, const char *)); +void exp_print_tree PARAMS ((etree_type *)); +bfd_vma exp_get_vma PARAMS ((etree_type *, bfd_vma, char *, lang_phase_type)); +int exp_get_value_int PARAMS ((etree_type *, int, char *,lang_phase_type)); +bfd_vma exp_get_abs_int PARAMS ((etree_type *, int, char *,lang_phase_type)); + +#endif diff --git a/ld/ldfile.c b/ld/ldfile.c new file mode 100644 index 0000000..1dfa31f --- /dev/null +++ b/ld/ldfile.c @@ -0,0 +1,416 @@ +/* Copyright (C) 1991, 92, 93, 94, 95, 98, 1999 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* + ldfile.c + + look after all the file stuff + + */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "ld.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldfile.h" +#include "ldmain.h" +#include "ldgram.h" +#include "ldlex.h" +#include "ldemul.h" + +#include <ctype.h> + +const char *ldfile_input_filename; +boolean ldfile_assumed_script = false; +const char *ldfile_output_machine_name = ""; +unsigned long ldfile_output_machine; +enum bfd_architecture ldfile_output_architecture; +search_dirs_type *search_head; + +#ifndef MPW +#ifdef VMS +char *slash = ""; +#else +#if defined (_WIN32) && ! defined (__CYGWIN32__) +char *slash = "\\"; +#else +char *slash = "/"; +#endif +#endif +#else /* MPW */ +/* The MPW path char is a colon. */ +char *slash = ":"; +#endif /* MPW */ + +/* LOCAL */ + +static search_dirs_type **search_tail_ptr = &search_head; + +typedef struct search_arch +{ + char *name; + struct search_arch *next; +} search_arch_type; + +static search_arch_type *search_arch_head; +static search_arch_type **search_arch_tail_ptr = &search_arch_head; + +static boolean ldfile_open_file_search + PARAMS ((const char *arch, lang_input_statement_type *, + const char *lib, const char *suffix)); +static FILE *try_open PARAMS ((const char *name, const char *exten)); + +void +ldfile_add_library_path (name, cmdline) + const char *name; + boolean cmdline; +{ + search_dirs_type *new; + + new = (search_dirs_type *) xmalloc (sizeof (search_dirs_type)); + new->next = NULL; + new->name = name; + new->cmdline = cmdline; + *search_tail_ptr = new; + search_tail_ptr = &new->next; +} + +/* Try to open a BFD for a lang_input_statement. */ + +boolean +ldfile_try_open_bfd (attempt, entry) + const char *attempt; + lang_input_statement_type *entry; +{ + entry->the_bfd = bfd_openr (attempt, entry->target); + + if (trace_file_tries) + { + if (entry->the_bfd == NULL) + info_msg (_("attempt to open %s failed\n"), attempt); + else + info_msg (_("attempt to open %s succeeded\n"), attempt); + } + + if (entry->the_bfd != NULL) + return true; + else + { + if (bfd_get_error () == bfd_error_invalid_target) + einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target); + return false; + } +} + +/* Search for and open the file specified by ENTRY. If it is an + archive, use ARCH, LIB and SUFFIX to modify the file name. */ + +static boolean +ldfile_open_file_search (arch, entry, lib, suffix) + const char *arch; + lang_input_statement_type *entry; + const char *lib; + const char *suffix; +{ + search_dirs_type *search; + + /* If this is not an archive, try to open it in the current + directory first. */ + if (! entry->is_archive) + { + if (ldfile_try_open_bfd (entry->filename, entry)) + return true; + } + + for (search = search_head; + search != (search_dirs_type *)NULL; + search = search->next) + { + char *string; + + if (entry->dynamic && ! link_info.relocateable) + { + if (ldemul_open_dynamic_archive (arch, search, entry)) + return true; + } + + string = (char *) xmalloc (strlen (search->name) + + strlen (slash) + + strlen (lib) + + strlen (entry->filename) + + strlen (arch) + + strlen (suffix) + + 1); + + if (entry->is_archive) + sprintf (string, "%s%s%s%s%s%s", search->name, slash, + lib, entry->filename, arch, suffix); + else if (entry->filename[0] == '/' || entry->filename[0] == '.' +#if defined (__MSDOS__) || defined (_WIN32) + || entry->filename[0] == '\\' + || (isalpha (entry->filename[0]) + && entry->filename[1] == ':') +#endif + ) + strcpy (string, entry->filename); + else + sprintf (string, "%s%s%s", search->name, slash, entry->filename); + + if (ldfile_try_open_bfd (string, entry)) + { + entry->filename = string; + return true; + } + + free (string); + } + + return false; +} + +/* Open the input file specified by ENTRY. */ + +void +ldfile_open_file (entry) + lang_input_statement_type *entry; +{ + if (entry->the_bfd != NULL) + return; + + if (! entry->search_dirs_flag) + { + if (ldfile_try_open_bfd (entry->filename, entry)) + return; + if (strcmp (entry->filename, entry->local_sym_name) != 0) + einfo (_("%F%P: cannot open %s for %s: %E\n"), + entry->filename, entry->local_sym_name); + else + einfo(_("%F%P: cannot open %s: %E\n"), entry->local_sym_name); + } + else + { + search_arch_type *arch; + + /* Try to open <filename><suffix> or lib<filename><suffix>.a */ + for (arch = search_arch_head; + arch != (search_arch_type *) NULL; + arch = arch->next) + { + if (ldfile_open_file_search (arch->name, entry, "lib", ".a")) + return; +#ifdef VMS + if (ldfile_open_file_search (arch->name, entry, ":lib", ".a")) + return; +#endif + } + einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name); + } +} + +/* Try to open NAME; if that fails, try NAME with EXTEN appended to it. */ + +static FILE * +try_open (name, exten) + const char *name; + const char *exten; +{ + FILE *result; + char buff[1000]; + + result = fopen (name, "r"); + if (trace_file_tries) + { + if (result == NULL) + info_msg (_("cannot find script file %s\n"), name); + else + info_msg (_("opened script file %s\n"), name); + } + + if (result != NULL) + return result; + + if (*exten) + { + sprintf (buff, "%s%s", name, exten); + result = fopen (buff, "r"); + if (trace_file_tries) + { + if (result == NULL) + info_msg (_("cannot find script file %s\n"), buff); + else + info_msg (_("opened script file %s\n"), buff); + } + } + + return result; +} + +/* Try to open NAME; if that fails, look for it in any directories + specified with -L, without and with EXTEND apppended. */ + +FILE * +ldfile_find_command_file (name, extend) + const char *name; + const char *extend; +{ + search_dirs_type *search; + FILE *result; + char buffer[1000]; + + /* First try raw name */ + result = try_open(name,""); + if (result == (FILE *)NULL) { + /* Try now prefixes */ + for (search = search_head; + search != (search_dirs_type *)NULL; + search = search->next) { + sprintf(buffer,"%s%s%s", search->name, slash, name); + result = try_open(buffer, extend); + if (result)break; + } + } + return result; +} + +void +ldfile_open_command_file (name) + const char *name; +{ + FILE *ldlex_input_stack; + ldlex_input_stack = ldfile_find_command_file(name, ""); + + if (ldlex_input_stack == (FILE *)NULL) { + bfd_set_error (bfd_error_system_call); + einfo(_("%P%F: cannot open linker script file %s: %E\n"),name); + } + lex_push_file(ldlex_input_stack, name); + + ldfile_input_filename = name; + lineno = 1; + had_script = true; +} + + + + + +#ifdef GNU960 +static +char * +gnu960_map_archname( name ) +char *name; +{ + struct tabentry { char *cmd_switch; char *arch; }; + static struct tabentry arch_tab[] = { + "", "", + "KA", "ka", + "KB", "kb", + "KC", "mc", /* Synonym for MC */ + "MC", "mc", + "CA", "ca", + "SA", "ka", /* Functionally equivalent to KA */ + "SB", "kb", /* Functionally equivalent to KB */ + NULL, "" + }; + struct tabentry *tp; + + + for ( tp = arch_tab; tp->cmd_switch != NULL; tp++ ){ + if ( !strcmp(name,tp->cmd_switch) ){ + break; + } + } + + if ( tp->cmd_switch == NULL ){ + einfo(_("%P%F: unknown architecture: %s\n"),name); + } + return tp->arch; +} + + + +void +ldfile_add_arch(name) +char *name; +{ + search_arch_type *new = + (search_arch_type *)xmalloc((bfd_size_type)(sizeof(search_arch_type))); + + + if (*name != '\0') { + if (ldfile_output_machine_name[0] != '\0') { + einfo(_("%P%F: target architecture respecified\n")); + return; + } + ldfile_output_machine_name = name; + } + + new->next = (search_arch_type*)NULL; + new->name = gnu960_map_archname( name ); + *search_arch_tail_ptr = new; + search_arch_tail_ptr = &new->next; + +} + +#else /* not GNU960 */ + + +void +ldfile_add_arch (in_name) + CONST char * in_name; +{ + char *name = buystring(in_name); + search_arch_type *new = + (search_arch_type *) xmalloc (sizeof (search_arch_type)); + + ldfile_output_machine_name = in_name; + + new->name = name; + new->next = (search_arch_type*)NULL; + while (*name) + { + if (isupper ((unsigned char) *name)) + *name = tolower ((unsigned char) *name); + name++; + } + *search_arch_tail_ptr = new; + search_arch_tail_ptr = &new->next; + +} +#endif + +/* Set the output architecture */ +void +ldfile_set_output_arch (string) + CONST char *string; +{ + const bfd_arch_info_type *arch = bfd_scan_arch(string); + + if (arch) { + ldfile_output_architecture = arch->arch; + ldfile_output_machine = arch->mach; + ldfile_output_machine_name = arch->printable_name; + } + else { + einfo(_("%P%F: cannot represent machine `%s'\n"), string); + } +} diff --git a/ld/ldfile.h b/ld/ldfile.h new file mode 100644 index 0000000..f33c9ce --- /dev/null +++ b/ld/ldfile.h @@ -0,0 +1,53 @@ +/* ldfile.h - + Copyright 1991, 1992 Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +extern const char *ldfile_input_filename; +extern boolean ldfile_assumed_script; +extern unsigned long ldfile_output_machine; +extern enum bfd_architecture ldfile_output_architecture; +extern const char *ldfile_output_machine_name; + +/* Structure used to hold the list of directories to search for + libraries. */ + +typedef struct search_dirs +{ + /* Next directory on list. */ + struct search_dirs *next; + /* Name of directory. */ + const char *name; + /* true if this is from the command line. */ + boolean cmdline; +} search_dirs_type; + +extern search_dirs_type *search_head; + +#if ANSI_PROTOTYPES +struct lang_input_statement_struct; +#endif + +extern void ldfile_add_arch PARAMS ((CONST char *)); +extern void ldfile_add_library_path PARAMS ((const char *, boolean cmdline)); +extern void ldfile_open_command_file PARAMS ((const char *name)); +extern void ldfile_open_file PARAMS ((struct lang_input_statement_struct *)); +extern boolean ldfile_try_open_bfd + PARAMS ((const char *, struct lang_input_statement_struct *)); +extern FILE *ldfile_find_command_file + PARAMS ((const char *name, const char *extend)); +extern void ldfile_set_output_arch PARAMS ((CONST char *)); diff --git a/ld/ldgram.y b/ld/ldgram.y new file mode 100644 index 0000000..a1f3ed6 --- /dev/null +++ b/ld/ldgram.y @@ -0,0 +1,1094 @@ +/* A YACC grammer to parse a superset of the AT&T linker scripting languaue. + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 + Free Software Foundation, Inc. + Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com). + +This file is part of GNU ld. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +%{ +/* + + */ + +#define DONTDECLARE_MALLOC + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "ld.h" +#include "ldexp.h" +#include "ldver.h" +#include "ldlang.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldmain.h" +#include "mri.h" +#include "ldctor.h" +#include "ldlex.h" + +#ifndef YYDEBUG +#define YYDEBUG 1 +#endif + +static enum section_type sectype; + +lang_memory_region_type *region; + +struct wildcard_spec current_file; +boolean ldgram_want_filename = true; +boolean had_script = false; +boolean force_make_executable = false; + +boolean ldgram_in_script = false; +boolean ldgram_had_equals = false; +boolean ldgram_had_keep = false; +char *ldgram_vers_current_lang = NULL; + +#define ERROR_NAME_MAX 20 +static char *error_names[ERROR_NAME_MAX]; +static int error_index; +#define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++; +#define POP_ERROR() error_index--; +%} +%union { + bfd_vma integer; + char *name; + const char *cname; + struct wildcard_spec wildcard; + int token; + union etree_union *etree; + struct phdr_info + { + boolean filehdr; + boolean phdrs; + union etree_union *at; + union etree_union *flags; + } phdr; + struct lang_nocrossref *nocrossref; + struct lang_output_section_phdr_list *section_phdr; + struct bfd_elf_version_deps *deflist; + struct bfd_elf_version_expr *versyms; + struct bfd_elf_version_tree *versnode; +} + +%type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val +%type <etree> opt_exp_without_type +%type <integer> fill_opt +%type <name> memspec_opt casesymlist +%type <cname> wildcard_name +%type <wildcard> wildcard_spec +%token <integer> INT +%token <name> NAME LNAME +%type <integer> length +%type <phdr> phdr_qualifiers +%type <nocrossref> nocrossref_list +%type <section_phdr> phdr_opt +%type <integer> opt_nocrossrefs + +%right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ +%right <token> '?' ':' +%left <token> OROR +%left <token> ANDAND +%left <token> '|' +%left <token> '^' +%left <token> '&' +%left <token> EQ NE +%left <token> '<' '>' LE GE +%left <token> LSHIFT RSHIFT + +%left <token> '+' '-' +%left <token> '*' '/' '%' + +%right UNARY +%token END +%left <token> '(' +%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE +%token SECTIONS PHDRS SORT +%token '{' '}' +%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH +%token SIZEOF_HEADERS +%token INCLUDE +%token MEMORY DEFSYMEND +%token NOLOAD DSECT COPY INFO OVERLAY +%token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY +%token <integer> NEXT +%token SIZEOF ADDR LOADADDR MAX_K MIN_K +%token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS +%token ORIGIN FILL +%token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS +%token ALIGNMOD AT PROVIDE +%type <token> assign_op atype +%type <name> filename +%token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K +%token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL +%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START +%token <name> VERS_TAG VERS_IDENTIFIER +%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT +%token KEEP +%token EXCLUDE_FILE +%type <versyms> vers_defns +%type <versnode> vers_tag +%type <deflist> verdep + +%% + +file: + INPUT_SCRIPT script_file + | INPUT_MRI_SCRIPT mri_script_file + | INPUT_VERSION_SCRIPT version_script_file + | INPUT_DEFSYM defsym_expr + ; + + +filename: NAME; + + +defsym_expr: + { ldlex_defsym(); } + NAME '=' exp + { + ldlex_popstate(); + lang_add_assignment(exp_assop($3,$2,$4)); + } + +/* SYNTAX WITHIN AN MRI SCRIPT FILE */ +mri_script_file: + { + ldlex_mri_script (); + PUSH_ERROR (_("MRI style script")); + } + mri_script_lines + { + ldlex_popstate (); + mri_draw_tree (); + POP_ERROR (); + } + ; + +mri_script_lines: + mri_script_lines mri_script_command NEWLINE + | + ; + +mri_script_command: + CHIP exp + | CHIP exp ',' exp + | NAME { + einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1); + } + | LIST { + config.map_filename = "-"; + } + | ORDER ordernamelist + | ENDWORD + | PUBLIC NAME '=' exp + { mri_public($2, $4); } + | PUBLIC NAME ',' exp + { mri_public($2, $4); } + | PUBLIC NAME exp + { mri_public($2, $3); } + | FORMAT NAME + { mri_format($2); } + | SECT NAME ',' exp + { mri_output_section($2, $4);} + | SECT NAME exp + { mri_output_section($2, $3);} + | SECT NAME '=' exp + { mri_output_section($2, $4);} + | ALIGN_K NAME '=' exp + { mri_align($2,$4); } + | ALIGN_K NAME ',' exp + { mri_align($2,$4); } + | ALIGNMOD NAME '=' exp + { mri_alignmod($2,$4); } + | ALIGNMOD NAME ',' exp + { mri_alignmod($2,$4); } + | ABSOLUTE mri_abs_name_list + | LOAD mri_load_name_list + | NAMEWORD NAME + { mri_name($2); } + | ALIAS NAME ',' NAME + { mri_alias($2,$4,0);} + | ALIAS NAME ',' INT + { mri_alias($2,0,(int) $4);} + | BASE exp + { mri_base($2); } + | TRUNCATE INT + { mri_truncate((unsigned int) $2); } + | CASE casesymlist + | EXTERN extern_name_list + | INCLUDE filename + { ldfile_open_command_file ($2); } mri_script_lines END + | START NAME + { lang_add_entry ($2, false); } + | + ; + +ordernamelist: + ordernamelist ',' NAME { mri_order($3); } + | ordernamelist NAME { mri_order($2); } + | + ; + +mri_load_name_list: + NAME + { mri_load($1); } + | mri_load_name_list ',' NAME { mri_load($3); } + ; + +mri_abs_name_list: + NAME + { mri_only_load($1); } + | mri_abs_name_list ',' NAME + { mri_only_load($3); } + ; + +casesymlist: + /* empty */ { $$ = NULL; } + | NAME + | casesymlist ',' NAME + ; + +extern_name_list: + NAME + { ldlang_add_undef ($1); } + | extern_name_list NAME + { ldlang_add_undef ($2); } + | extern_name_list ',' NAME + { ldlang_add_undef ($3); } + ; + +script_file: + { + ldlex_both(); + } + ifile_list + { + ldlex_popstate(); + } + ; + + +ifile_list: + ifile_list ifile_p1 + | + ; + + + +ifile_p1: + memory + | sections + | phdrs + | startup + | high_level_library + | low_level_library + | floating_point_support + | statement_anywhere + | version + | ';' + | TARGET_K '(' NAME ')' + { lang_add_target($3); } + | SEARCH_DIR '(' filename ')' + { ldfile_add_library_path ($3, false); } + | OUTPUT '(' filename ')' + { lang_add_output($3, 1); } + | OUTPUT_FORMAT '(' NAME ')' + { lang_add_output_format ($3, (char *) NULL, + (char *) NULL, 1); } + | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')' + { lang_add_output_format ($3, $5, $7, 1); } + | OUTPUT_ARCH '(' NAME ')' + { ldfile_set_output_arch($3); } + | FORCE_COMMON_ALLOCATION + { command_line.force_common_definition = true ; } + | INPUT '(' input_list ')' + | GROUP + { lang_enter_group (); } + '(' input_list ')' + { lang_leave_group (); } + | MAP '(' filename ')' + { lang_add_map($3); } + | INCLUDE filename + { ldfile_open_command_file($2); } ifile_list END + | NOCROSSREFS '(' nocrossref_list ')' + { + lang_add_nocrossref ($3); + } + | EXTERN '(' extern_name_list ')' + ; + +input_list: + NAME + { lang_add_input_file($1,lang_input_file_is_search_file_enum, + (char *)NULL); } + | input_list ',' NAME + { lang_add_input_file($3,lang_input_file_is_search_file_enum, + (char *)NULL); } + | input_list NAME + { lang_add_input_file($2,lang_input_file_is_search_file_enum, + (char *)NULL); } + | LNAME + { lang_add_input_file($1,lang_input_file_is_l_enum, + (char *)NULL); } + | input_list ',' LNAME + { lang_add_input_file($3,lang_input_file_is_l_enum, + (char *)NULL); } + | input_list LNAME + { lang_add_input_file($2,lang_input_file_is_l_enum, + (char *)NULL); } + ; + +sections: + SECTIONS '{' sec_or_group_p1 '}' + ; + +sec_or_group_p1: + sec_or_group_p1 section + | sec_or_group_p1 statement_anywhere + | + ; + +statement_anywhere: + ENTRY '(' NAME ')' + { lang_add_entry ($3, false); } + | assignment end + ; + +/* The '*' and '?' cases are there because the lexer returns them as + separate tokens rather than as NAME. */ +wildcard_name: + NAME + { + $$ = $1; + } + | '*' + { + $$ = "*"; + } + | '?' + { + $$ = "?"; + } + ; + +wildcard_spec: + wildcard_name + { + $$.name = $1; + $$.sorted = false; + $$.exclude_name = NULL; + } + | EXCLUDE_FILE '(' wildcard_name ')' wildcard_name + { + $$.name = $5; + $$.sorted = false; + $$.exclude_name = $3; + } + | SORT '(' wildcard_name ')' + { + $$.name = $3; + $$.sorted = true; + $$.exclude_name = NULL; + } + | SORT '(' EXCLUDE_FILE '(' wildcard_name ')' wildcard_name ')' + { + $$.name = $7; + $$.sorted = true; + $$.exclude_name = $5; + } + ; + + +file_NAME_list: + wildcard_spec + { + lang_add_wild ($1.name, $1.sorted, + current_file.name, + current_file.sorted, + ldgram_had_keep, $1.exclude_name); + } + | file_NAME_list opt_comma wildcard_spec + { + lang_add_wild ($3.name, $3.sorted, + current_file.name, + current_file.sorted, + ldgram_had_keep, $3.exclude_name); + } + ; + +input_section_spec_no_keep: + NAME + { + lang_add_wild (NULL, false, $1, false, + ldgram_had_keep, NULL); + } + | '[' + { + current_file.name = NULL; + current_file.sorted = false; + } + file_NAME_list ']' + | wildcard_spec + { + current_file = $1; + /* '*' matches any file name. */ + if (strcmp (current_file.name, "*") == 0) + current_file.name = NULL; + } + '(' file_NAME_list ')' + ; + +input_section_spec: + input_section_spec_no_keep + | KEEP '(' + { ldgram_had_keep = true; } + input_section_spec_no_keep ')' + { ldgram_had_keep = false; } + ; + +statement: + assignment end + | CREATE_OBJECT_SYMBOLS + { + lang_add_attribute(lang_object_symbols_statement_enum); + } + | ';' + | CONSTRUCTORS + { + + lang_add_attribute(lang_constructors_statement_enum); + } + | SORT '(' CONSTRUCTORS ')' + { + constructors_sorted = true; + lang_add_attribute (lang_constructors_statement_enum); + } + | input_section_spec + | length '(' mustbe_exp ')' + { + lang_add_data((int) $1,$3); + } + + | FILL '(' mustbe_exp ')' + { + lang_add_fill + (exp_get_value_int($3, + 0, + "fill value", + lang_first_phase_enum)); + } + ; + +statement_list: + statement_list statement + | statement + ; + +statement_list_opt: + /* empty */ + | statement_list + ; + +length: + QUAD + { $$ = $1; } + | SQUAD + { $$ = $1; } + | LONG + { $$ = $1; } + | SHORT + { $$ = $1; } + | BYTE + { $$ = $1; } + ; + +fill_opt: + '=' mustbe_exp + { + $$ = exp_get_value_int($2, + 0, + "fill value", + lang_first_phase_enum); + } + | { $$ = 0; } + ; + + + +assign_op: + PLUSEQ + { $$ = '+'; } + | MINUSEQ + { $$ = '-'; } + | MULTEQ + { $$ = '*'; } + | DIVEQ + { $$ = '/'; } + | LSHIFTEQ + { $$ = LSHIFT; } + | RSHIFTEQ + { $$ = RSHIFT; } + | ANDEQ + { $$ = '&'; } + | OREQ + { $$ = '|'; } + + ; + +end: ';' | ',' + ; + + +assignment: + NAME '=' mustbe_exp + { + lang_add_assignment (exp_assop ($2, $1, $3)); + } + | NAME assign_op mustbe_exp + { + lang_add_assignment (exp_assop ('=', $1, + exp_binop ($2, + exp_nameop (NAME, + $1), + $3))); + } + | PROVIDE '(' NAME '=' mustbe_exp ')' + { + lang_add_assignment (exp_provide ($3, $5)); + } + ; + + +opt_comma: + ',' | ; + + +memory: + MEMORY '{' memory_spec memory_spec_list '}' + ; + +memory_spec_list: + memory_spec_list memory_spec + | memory_spec_list ',' memory_spec + | + ; + + +memory_spec: NAME + { region = lang_memory_region_lookup($1); } + attributes_opt ':' + origin_spec opt_comma length_spec + + ; origin_spec: + ORIGIN '=' mustbe_exp + { region->current = + region->origin = + exp_get_vma($3, 0L,"origin", lang_first_phase_enum); +} + ; + +length_spec: + LENGTH '=' mustbe_exp + { region->length = exp_get_vma($3, + ~((bfd_vma)0), + "length", + lang_first_phase_enum); + } + + +attributes_opt: + '(' NAME ')' + { + lang_set_flags(region, $2); + } + | + + ; + +startup: + STARTUP '(' filename ')' + { lang_startup($3); } + ; + +high_level_library: + HLL '(' high_level_library_NAME_list ')' + | HLL '(' ')' + { ldemul_hll((char *)NULL); } + ; + +high_level_library_NAME_list: + high_level_library_NAME_list opt_comma filename + { ldemul_hll($3); } + | filename + { ldemul_hll($1); } + + ; + +low_level_library: + SYSLIB '(' low_level_library_NAME_list ')' + ; low_level_library_NAME_list: + low_level_library_NAME_list opt_comma filename + { ldemul_syslib($3); } + | + ; + +floating_point_support: + FLOAT + { lang_float(true); } + | NOFLOAT + { lang_float(false); } + ; + +nocrossref_list: + /* empty */ + { + $$ = NULL; + } + | NAME nocrossref_list + { + struct lang_nocrossref *n; + + n = (struct lang_nocrossref *) xmalloc (sizeof *n); + n->name = $1; + n->next = $2; + $$ = n; + } + | NAME ',' nocrossref_list + { + struct lang_nocrossref *n; + + n = (struct lang_nocrossref *) xmalloc (sizeof *n); + n->name = $1; + n->next = $3; + $$ = n; + } + ; + +mustbe_exp: { ldlex_expression(); } + exp + { ldlex_popstate(); $$=$2;} + ; + +exp : + '-' exp %prec UNARY + { $$ = exp_unop('-', $2); } + | '(' exp ')' + { $$ = $2; } + | NEXT '(' exp ')' %prec UNARY + { $$ = exp_unop((int) $1,$3); } + | '!' exp %prec UNARY + { $$ = exp_unop('!', $2); } + | '+' exp %prec UNARY + { $$ = $2; } + | '~' exp %prec UNARY + { $$ = exp_unop('~', $2);} + + | exp '*' exp + { $$ = exp_binop('*', $1, $3); } + | exp '/' exp + { $$ = exp_binop('/', $1, $3); } + | exp '%' exp + { $$ = exp_binop('%', $1, $3); } + | exp '+' exp + { $$ = exp_binop('+', $1, $3); } + | exp '-' exp + { $$ = exp_binop('-' , $1, $3); } + | exp LSHIFT exp + { $$ = exp_binop(LSHIFT , $1, $3); } + | exp RSHIFT exp + { $$ = exp_binop(RSHIFT , $1, $3); } + | exp EQ exp + { $$ = exp_binop(EQ , $1, $3); } + | exp NE exp + { $$ = exp_binop(NE , $1, $3); } + | exp LE exp + { $$ = exp_binop(LE , $1, $3); } + | exp GE exp + { $$ = exp_binop(GE , $1, $3); } + | exp '<' exp + { $$ = exp_binop('<' , $1, $3); } + | exp '>' exp + { $$ = exp_binop('>' , $1, $3); } + | exp '&' exp + { $$ = exp_binop('&' , $1, $3); } + | exp '^' exp + { $$ = exp_binop('^' , $1, $3); } + | exp '|' exp + { $$ = exp_binop('|' , $1, $3); } + | exp '?' exp ':' exp + { $$ = exp_trinop('?' , $1, $3, $5); } + | exp ANDAND exp + { $$ = exp_binop(ANDAND , $1, $3); } + | exp OROR exp + { $$ = exp_binop(OROR , $1, $3); } + | DEFINED '(' NAME ')' + { $$ = exp_nameop(DEFINED, $3); } + | INT + { $$ = exp_intop($1); } + | SIZEOF_HEADERS + { $$ = exp_nameop(SIZEOF_HEADERS,0); } + + | SIZEOF '(' NAME ')' + { $$ = exp_nameop(SIZEOF,$3); } + | ADDR '(' NAME ')' + { $$ = exp_nameop(ADDR,$3); } + | LOADADDR '(' NAME ')' + { $$ = exp_nameop(LOADADDR,$3); } + | ABSOLUTE '(' exp ')' + { $$ = exp_unop(ABSOLUTE, $3); } + | ALIGN_K '(' exp ')' + { $$ = exp_unop(ALIGN_K,$3); } + | BLOCK '(' exp ')' + { $$ = exp_unop(ALIGN_K,$3); } + | NAME + { $$ = exp_nameop(NAME,$1); } + | MAX_K '(' exp ',' exp ')' + { $$ = exp_binop (MAX_K, $3, $5 ); } + | MIN_K '(' exp ',' exp ')' + { $$ = exp_binop (MIN_K, $3, $5 ); } + | ASSERT_K '(' exp ',' NAME ')' + { $$ = exp_assert ($3, $5); } + ; + + +opt_at: + AT '(' exp ')' { $$ = $3; } + | { $$ = 0; } + ; + +section: NAME { ldlex_expression(); } + opt_exp_with_type + opt_at { ldlex_popstate (); ldlex_script (); } + '{' + { + lang_enter_output_section_statement($1, $3, + sectype, + 0, 0, 0, $4); + } + statement_list_opt + '}' { ldlex_popstate (); ldlex_expression (); } + memspec_opt phdr_opt fill_opt + { + ldlex_popstate (); + lang_leave_output_section_statement ($13, $11, $12); + } + opt_comma + | OVERLAY + { ldlex_expression (); } + opt_exp_without_type opt_nocrossrefs opt_at + { ldlex_popstate (); ldlex_script (); } + '{' + { + lang_enter_overlay ($3, $5, (int) $4); + } + overlay_section + '}' + { ldlex_popstate (); ldlex_expression (); } + memspec_opt phdr_opt fill_opt + { + ldlex_popstate (); + lang_leave_overlay ($14, $12, $13); + } + opt_comma + | /* The GROUP case is just enough to support the gcc + svr3.ifile script. It is not intended to be full + support. I'm not even sure what GROUP is supposed + to mean. */ + GROUP { ldlex_expression (); } + opt_exp_with_type + { + ldlex_popstate (); + lang_add_assignment (exp_assop ('=', ".", $3)); + } + '{' sec_or_group_p1 '}' + ; + +type: + NOLOAD { sectype = noload_section; } + | DSECT { sectype = dsect_section; } + | COPY { sectype = copy_section; } + | INFO { sectype = info_section; } + | OVERLAY { sectype = overlay_section; } + ; + +atype: + '(' type ')' + | /* EMPTY */ { sectype = normal_section; } + | '(' ')' { sectype = normal_section; } + ; + +opt_exp_with_type: + exp atype ':' { $$ = $1; } + | atype ':' { $$ = (etree_type *)NULL; } + | /* The BIND cases are to support the gcc svr3.ifile + script. They aren't intended to implement full + support for the BIND keyword. I'm not even sure + what BIND is supposed to mean. */ + BIND '(' exp ')' atype ':' { $$ = $3; } + | BIND '(' exp ')' BLOCK '(' exp ')' atype ':' + { $$ = $3; } + ; + +opt_exp_without_type: + exp ':' { $$ = $1; } + | ':' { $$ = (etree_type *) NULL; } + ; + +opt_nocrossrefs: + /* empty */ + { $$ = 0; } + | NOCROSSREFS + { $$ = 1; } + ; + +memspec_opt: + '>' NAME + { $$ = $2; } + | { $$ = "*default*"; } + ; + +phdr_opt: + /* empty */ + { + $$ = NULL; + } + | phdr_opt ':' NAME + { + struct lang_output_section_phdr_list *n; + + n = ((struct lang_output_section_phdr_list *) + xmalloc (sizeof *n)); + n->name = $3; + n->used = false; + n->next = $1; + $$ = n; + } + ; + +overlay_section: + /* empty */ + | overlay_section + NAME + { + ldlex_script (); + lang_enter_overlay_section ($2); + } + '{' statement_list_opt '}' + { ldlex_popstate (); ldlex_expression (); } + phdr_opt fill_opt + { + ldlex_popstate (); + lang_leave_overlay_section ($9, $8); + } + opt_comma + ; + +phdrs: + PHDRS '{' phdr_list '}' + ; + +phdr_list: + /* empty */ + | phdr_list phdr + ; + +phdr: + NAME { ldlex_expression (); } + phdr_type phdr_qualifiers { ldlex_popstate (); } + ';' + { + lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at, + $4.flags); + } + ; + +phdr_type: + exp + { + $$ = $1; + + if ($1->type.node_class == etree_name + && $1->type.node_code == NAME) + { + const char *s; + unsigned int i; + static const char * const phdr_types[] = + { + "PT_NULL", "PT_LOAD", "PT_DYNAMIC", + "PT_INTERP", "PT_NOTE", "PT_SHLIB", + "PT_PHDR" + }; + + s = $1->name.name; + for (i = 0; + i < sizeof phdr_types / sizeof phdr_types[0]; + i++) + if (strcmp (s, phdr_types[i]) == 0) + { + $$ = exp_intop (i); + break; + } + } + } + ; + +phdr_qualifiers: + /* empty */ + { + memset (&$$, 0, sizeof (struct phdr_info)); + } + | NAME phdr_val phdr_qualifiers + { + $$ = $3; + if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL) + $$.filehdr = true; + else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL) + $$.phdrs = true; + else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL) + $$.flags = $2; + else + einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1); + } + | AT '(' exp ')' phdr_qualifiers + { + $$ = $5; + $$.at = $3; + } + ; + +phdr_val: + /* empty */ + { + $$ = NULL; + } + | '(' exp ')' + { + $$ = $2; + } + ; + +/* This syntax is used within an external version script file. */ + +version_script_file: + { + ldlex_version_file (); + PUSH_ERROR (_("VERSION script")); + } + vers_nodes + { + ldlex_popstate (); + POP_ERROR (); + } + ; + +/* This is used within a normal linker script file. */ + +version: + { + ldlex_version_script (); + } + VERSIONK '{' vers_nodes '}' + { + ldlex_popstate (); + } + ; + +vers_nodes: + vers_node + | vers_nodes vers_node + ; + +vers_node: + VERS_TAG '{' vers_tag '}' ';' + { + lang_register_vers_node ($1, $3, NULL); + } + | VERS_TAG '{' vers_tag '}' verdep ';' + { + lang_register_vers_node ($1, $3, $5); + } + ; + +verdep: + VERS_TAG + { + $$ = lang_add_vers_depend (NULL, $1); + } + | verdep VERS_TAG + { + $$ = lang_add_vers_depend ($1, $2); + } + ; + +vers_tag: + /* empty */ + { + $$ = lang_new_vers_node (NULL, NULL); + } + | vers_defns ';' + { + $$ = lang_new_vers_node ($1, NULL); + } + | GLOBAL ':' vers_defns ';' + { + $$ = lang_new_vers_node ($3, NULL); + } + | LOCAL ':' vers_defns ';' + { + $$ = lang_new_vers_node (NULL, $3); + } + | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';' + { + $$ = lang_new_vers_node ($3, $7); + } + ; + +vers_defns: + VERS_IDENTIFIER + { + $$ = lang_new_vers_regex (NULL, $1, ldgram_vers_current_lang); + } + | vers_defns ';' VERS_IDENTIFIER + { + $$ = lang_new_vers_regex ($1, $3, ldgram_vers_current_lang); + } + | EXTERN NAME '{' + { + $<name>$ = ldgram_vers_current_lang; + ldgram_vers_current_lang = $2; + } + vers_defns '}' + { + ldgram_vers_current_lang = $<name>4; + } + ; + +%% +void +yyerror(arg) + const char *arg; +{ + if (ldfile_assumed_script) + einfo (_("%P:%s: file format not recognized; treating as linker script\n"), + ldfile_input_filename); + if (error_index > 0 && error_index < ERROR_NAME_MAX) + einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]); + else + einfo ("%P%F:%S: %s\n", arg); +} diff --git a/ld/ldint.texinfo b/ld/ldint.texinfo new file mode 100644 index 0000000..58ea788 --- /dev/null +++ b/ld/ldint.texinfo @@ -0,0 +1,564 @@ +\input texinfo +@setfilename ldint.info + +@ifinfo +@format +START-INFO-DIR-ENTRY +* Ld-Internals: (ldint). The GNU linker internals. +END-INFO-DIR-ENTRY +@end format +@end ifinfo + +@ifinfo +This file documents the internals of the GNU linker ld. + +Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. +Contributed by Cygnus Support. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through Tex and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy or distribute modified versions of this +manual under the terms of the GPL (for which purpose this text may be +regarded as a program in the language TeX). +@end ifinfo + +@iftex +@finalout +@setchapternewpage off +@settitle GNU Linker Internals +@titlepage +@title{A guide to the internals of the GNU linker} +@author Per Bothner, Steve Chamberlain, Ian Lance Taylor, DJ Delorie +@author Cygnus Support +@page + +@tex +\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$ +\xdef\manvers{\$Revision$} % For use in headers, footers too +{\parskip=0pt +\hfill Cygnus Support\par +\hfill \manvers\par +\hfill \TeX{}info \texinfoversion\par +} +@end tex + +@vskip 0pt plus 1filll +Copyright @copyright{} 1992, 93, 94, 95, 96, 97, 1998 +Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@end titlepage +@end iftex + +@node Top +@top + +This file documents the internals of the GNU linker @code{ld}. It is a +collection of miscellaneous information with little form at this point. +Mostly, it is a repository into which you can put information about +GNU @code{ld} as you discover it (or as you design changes to @code{ld}). + +@menu +* README:: The README File +* Emulations:: How linker emulations are generated +* Emulation Walkthrough:: A Walkthrough of a Typical Emulation +@end menu + +@node README +@chapter The @file{README} File + +Check the @file{README} file; it often has useful information that does not +appear anywhere else in the directory. + +@node Emulations +@chapter How linker emulations are generated + +Each linker target has an @dfn{emulation}. The emulation includes the +default linker script, and certain emulations also modify certain types +of linker behaviour. + +Emulations are created during the build process by the shell script +@file{genscripts.sh}. + +The @file{genscripts.sh} script starts by reading a file in the +@file{emulparams} directory. This is a shell script which sets various +shell variables used by @file{genscripts.sh} and the other shell scripts +it invokes. + +The @file{genscripts.sh} script will invoke a shell script in the +@file{scripttempl} directory in order to create default linker scripts +written in the linker command language. The @file{scripttempl} script +will be invoked 5 (or, in some cases, 6) times, with different +assignments to shell variables, to create different default scripts. +The choice of script is made based on the command line options. + +After creating the scripts, @file{genscripts.sh} will invoke yet another +shell script, this time in the @file{emultempl} directory. That shell +script will create the emulation source file, which contains C code. +This C code permits the linker emulation to override various linker +behaviours. Most targets use the generic emulation code, which is in +@file{emultempl/generic.em}. + +To summarize, @file{genscripts.sh} reads three shell scripts: an +emulation parameters script in the @file{emulparams} directory, a linker +script generation script in the @file{scripttempl} directory, and an +emulation source file generation script in the @file{emultempl} +directory. + +For example, the Sun 4 linker sets up variables in +@file{emulparams/sun4.sh}, creates linker scripts using +@file{scripttempl/aout.sc}, and creates the emulation code using +@file{emultempl/sunos.em}. + +Note that the linker can support several emulations simultaneously, +depending upon how it is configured. An emulation can be selected with +the @code{-m} option. The @code{-V} option will list all supported +emulations. + +@menu +* emulation parameters:: @file{emulparams} scripts +* linker scripts:: @file{scripttempl} scripts +* linker emulations:: @file{emultempl} scripts +@end menu + +@node emulation parameters +@section @file{emulparams} scripts + +Each target selects a particular file in the @file{emulparams} directory +by setting the shell variable @code{targ_emul} in @file{configure.tgt}. +This shell variable is used by the @file{configure} script to control +building an emulation source file. + +Certain conventions are enforced. Suppose the @code{targ_emul} variable +is set to @var{emul} in @file{configure.tgt}. The name of the emulation +shell script will be @file{emulparams/@var{emul}.sh}. The +@file{Makefile} must have a target named @file{e@var{emul}.c}; this +target must depend upon @file{emulparams/@var{emul}.sh}, as well as the +appropriate scripts in the @file{scripttempl} and @file{emultempl} +directories. The @file{Makefile} target must invoke @code{GENSCRIPTS} +with two arguments: @var{emul}, and the value of the make variable +@code{tdir_@var{emul}}. The value of the latter variable will be set by +the @file{configure} script, and is used to set the default target +directory to search. + +By convention, the @file{emulparams/@var{emul}.sh} shell script should +only set shell variables. It may set shell variables which are to be +interpreted by the @file{scripttempl} and the @file{emultempl} scripts. +Certain shell variables are interpreted directly by the +@file{genscripts.sh} script. + +Here is a list of shell variables interpreted by @file{genscripts.sh}, +as well as some conventional shell variables interpreted by the +@file{scripttempl} and @file{emultempl} scripts. + +@table @code +@item SCRIPT_NAME +This is the name of the @file{scripttempl} script to use. If +@code{SCRIPT_NAME} is set to @var{script}, @file{genscripts.sh} will use +the script @file{scriptteml/@var{script}.sc}. + +@item TEMPLATE_NAME +This is the name of the @file{emultemlp} script to use. If +@code{TEMPLATE_NAME} is set to @var{template}, @file{genscripts.sh} will +use the script @file{emultempl/@var{template}.em}. If this variable is +not set, the default value is @samp{generic}. + +@item GENERATE_SHLIB_SCRIPT +If this is set to a nonempty string, @file{genscripts.sh} will invoke +the @file{scripttempl} script an extra time to create a shared library +script. @ref{linker scripts}. + +@item OUTPUT_FORMAT +This is normally set to indicate the BFD output format use (e.g., +@samp{"a.out-sunos-big"}. The @file{scripttempl} script will normally +use it in an @code{OUTPUT_FORMAT} expression in the linker script. + +@item ARCH +This is normally set to indicate the architecture to use (e.g., +@samp{sparc}). The @file{scripttempl} script will normally use it in an +@code{OUTPUT_ARCH} expression in the linker script. + +@item ENTRY +Some @file{scripttempl} scripts use this to set the entry address, in an +@code{ENTRY} expression in the linker script. + +@item TEXT_START_ADDR +Some @file{scripttempl} scripts use this to set the start address of the +@samp{.text} section. + +@item NONPAGED_TEXT_START_ADDR +If this is defined, the @file{genscripts.sh} script sets +@code{TEXT_START_ADDR} to its value before running the +@file{scripttempl} script for the @code{-n} and @code{-N} options +(@pxref{linker scripts}). + +@item SEGMENT_SIZE +The @file{genscripts.sh} script uses this to set the default value of +@code{DATA_ALIGNMENT} when running the @file{scripttempl} script. + +@item TARGET_PAGE_SIZE +If @code{SEGMENT_SIZE} is not defined, the @file{genscripts.sh} script +uses this to define it. + +@item ALIGNMENT +Some @file{scripttempl} scripts set this to a number to pass to +@code{ALIGN} to set the required alignment for the @code{end} symbol. +@end table + +@node linker scripts +@section @file{scripttempl} scripts + +Each linker target uses a @file{scripttempl} script to generate the +default linker scripts. The name of the @file{scripttempl} script is +set by the @code{SCRIPT_NAME} variable in the @file{emulparams} script. +If @code{SCRIPT_NAME} is set to @var{script}, @code{genscripts.sh} will +invoke @file{scripttempl/@var{script}.sc}. + +The @file{genscripts.sh} script will invoke the @file{scripttempl} +script 5 or 6 times. Each time it will set the shell variable +@code{LD_FLAG} to a different value. When the linker is run, the +options used will direct it to select a particular script. (Script +selection is controlled by the @code{get_script} emulation entry point; +this describes the conventional behaviour). + +The @file{scripttempl} script should just write a linker script, written +in the linker command language, to standard output. If the emulation +name--the name of the @file{emulparams} file without the @file{.sc} +extension--is @var{emul}, then the output will be directed to +@file{ldscripts/@var{emul}.@var{extension}} in the build directory, +where @var{extension} changes each time the @file{scripttempl} script is +invoked. + +Here is the list of values assigned to @code{LD_FLAG}. + +@table @code +@item (empty) +The script generated is used by default (when none of the following +cases apply). The output has an extension of @file{.x}. +@item n +The script generated is used when the linker is invoked with the +@code{-n} option. The output has an extension of @file{.xn}. +@item N +The script generated is used when the linker is invoked with the +@code{-N} option. The output has an extension of @file{.xbn}. +@item r +The script generated is used when the linker is invoked with the +@code{-r} option. The output has an extension of @file{.xr}. +@item u +The script generated is used when the linker is invoked with the +@code{-Ur} option. The output has an extension of @file{.xu}. +@item shared +The @file{scripttempl} script is only invoked with @code{LD_FLAG} set to +this value if @code{GENERATE_SHLIB_SCRIPT} is defined in the +@file{emulparams} file. The @file{emultempl} script must arrange to use +this script at the appropriate time, normally when the linker is invoked +with the @code{-shared} option. The output has an extension of +@file{.xs}. +@end table + +Besides the shell variables set by the @file{emulparams} script, and the +@code{LD_FLAG} variable, the @file{genscripts.sh} script will set +certain variables for each run of the @file{scripttempl} script. + +@table @code +@item RELOCATING +This will be set to a non-empty string when the linker is doing a final +relocation (e.g., all scripts other than @code{-r} and @code{-Ur}). + +@item CONSTRUCTING +This will be set to a non-empty string when the linker is building +global constructor and destructor tables (e.g., all scripts other than +@code{-r}). + +@item DATA_ALIGNMENT +This will be set to an @code{ALIGN} expression when the output should be +page aligned, or to @samp{.} when generating the @code{-N} script. + +@item CREATE_SHLIB +This will be set to a non-empty string when generating a @code{-shared} +script. +@end table + +The conventional way to write a @file{scripttempl} script is to first +set a few shell variables, and then write out a linker script using +@code{cat} with a here document. The linker script will use variable +substitutions, based on the above variables and those set in the +@file{emulparams} script, to control its behaviour. + +When there are parts of the @file{scripttempl} script which should only +be run when doing a final relocation, they should be enclosed within a +variable substitution based on @code{RELOCATING}. For example, on many +targets special symbols such as @code{_end} should be defined when doing +a final link. Naturally, those symbols should not be defined when doing +a relocateable link using @code{-r}. The @file{scripttempl} script +could use a construct like this to define those symbols: +@smallexample + $@{RELOCATING+ _end = .;@} +@end smallexample +This will do the symbol assignment only if the @code{RELOCATING} +variable is defined. + +The basic job of the linker script is to put the sections in the correct +order, and at the correct memory addresses. For some targets, the +linker script may have to do some other operations. + +For example, on most MIPS platforms, the linker is responsible for +defining the special symbol @code{_gp}, used to initialize the +@code{$gp} register. It must be set to the start of the small data +section plus @code{0x8000}. Naturally, it should only be defined when +doing a final relocation. This will typically be done like this: +@smallexample + $@{RELOCATING+ _gp = ALIGN(16) + 0x8000;@} +@end smallexample +This line would appear just before the sections which compose the small +data section (@samp{.sdata}, @samp{.sbss}). All those sections would be +contiguous in memory. + +Many COFF systems build constructor tables in the linker script. The +compiler will arrange to output the address of each global constructor +in a @samp{.ctor} section, and the address of each global destructor in +a @samp{.dtor} section (this is done by defining +@code{ASM_OUTPUT_CONSTRUCTOR} and @code{ASM_OUTPUT_DESTRUCTOR} in the +@code{gcc} configuration files). The @code{gcc} runtime support +routines expect the constructor table to be named @code{__CTOR_LIST__}. +They expect it to be a list of words, with the first word being the +count of the number of entries. There should be a trailing zero word. +(Actually, the count may be -1 if the trailing word is present, and the +trailing word may be omitted if the count is correct, but, as the +@code{gcc} behaviour has changed slightly over the years, it is safest +to provide both). Here is a typical way that might be handled in a +@file{scripttempl} file. +@smallexample + $@{CONSTRUCTING+ __CTOR_LIST__ = .;@} + $@{CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)@} + $@{CONSTRUCTING+ *(.ctors)@} + $@{CONSTRUCTING+ LONG(0)@} + $@{CONSTRUCTING+ __CTOR_END__ = .;@} + $@{CONSTRUCTING+ __DTOR_LIST__ = .;@} + $@{CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)@} + $@{CONSTRUCTING+ *(.dtors)@} + $@{CONSTRUCTING+ LONG(0)@} + $@{CONSTRUCTING+ __DTOR_END__ = .;@} +@end smallexample +The use of @code{CONSTRUCTING} ensures that these linker script commands +will only appear when the linker is supposed to be building the +constructor and destructor tables. This example is written for a target +which uses 4 byte pointers. + +Embedded systems often need to set a stack address. This is normally +best done by using the @code{PROVIDE} construct with a default stack +address. This permits the user to easily override the stack address +using the @code{--defsym} option. Here is an example: +@smallexample + $@{RELOCATING+ PROVIDE (__stack = 0x80000000);@} +@end smallexample +The value of the symbol @code{__stack} would then be used in the startup +code to initialize the stack pointer. + +@node linker emulations +@section @file{emultempl} scripts + +Each linker target uses an @file{emultempl} script to generate the +emulation code. The name of the @file{emultempl} script is set by the +@code{TEMPLATE_NAME} variable in the @file{emulparams} script. If the +@code{TEMPLATE_NAME} variable is not set, the default is +@samp{generic}. If the value of @code{TEMPLATE_NAME} is @var{template}, +@file{genscripts.sh} will use @file{emultempl/@var{template}.em}. + +Most targets use the generic @file{emultempl} script, +@file{emultempl/generic.em}. A different @file{emultempl} script is +only needed if the linker must support unusual actions, such as linking +against shared libraries. + +The @file{emultempl} script is normally written as a simple invocation +of @code{cat} with a here document. The document will use a few +variable substitutions. Typically each function names uses a +substitution involving @code{EMULATION_NAME}, for ease of debugging when +the linker supports multiple emulations. + +Every function and variable in the emitted file should be static. The +only globally visible object must be named +@code{ld_@var{EMULATION_NAME}_emulation}, where @var{EMULATION_NAME} is +the name of the emulation set in @file{configure.tgt} (this is also the +name of the @file{emulparams} file without the @file{.sh} extension). +The @file{genscripts.sh} script will set the shell variable +@code{EMULATION_NAME} before invoking the @file{emultempl} script. + +The @code{ld_@var{EMULATION_NAME}_emulation} variable must be a +@code{struct ld_emulation_xfer_struct}, as defined in @file{ldemul.h}. +It defines a set of function pointers which are invoked by the linker, +as well as strings for the emulation name (normally set from the shell +variable @code{EMULATION_NAME} and the default BFD target name (normally +set from the shell variable @code{OUTPUT_FORMAT} which is normally set +by the @file{emulparams} file). + +The @file{genscripts.sh} script will set the shell variable +@code{COMPILE_IN} when it invokes the @file{emultempl} script for the +default emulation. In this case, the @file{emultempl} script should +include the linker scripts directly, and return them from the +@code{get_scripts} entry point. When the emulation is not the default, +the @code{get_scripts} entry point should just return a file name. See +@file{emultempl/generic.em} for an example of how this is done. + +At some point, the linker emulation entry points should be documented. + +@node Emulation Walkthrough +@chapter A Walkthrough of a Typical Emulation + +This chapter is to help people who are new to the way emulations +interact with the linker, or who are suddenly thrust into the position +of having to work with existing emulations. It will discuss the files +you need to be aware of. It will tell you when the given "hooks" in +the emulation will be called. It will, hopefully, give you enough +information about when and how things happen that you'll be able to +get by. As always, the source is the definitive reference to this. + +The starting point for the linker is in @file{ldmain.c} where +@code{main} is defined. The bulk of the code that's emulation +specific will initially be in @code{emultempl/@var{emulation}.em} but +will end up in @code{e@var{emulation}.c} when the build is done. +Most of the work to select and interface with emulations is in +@code{ldemul.h} and @code{ldemul.c}. Specifically, @code{ldemul.h} +defines the @code{ld_emulation_xfer_struct} structure your emulation +exports. + +Your emulation file exports a symbol +@code{ld_@var{EMULATION_NAME}_emulation}. If your emulation is +selected (it usually is, since usually there's only one), +@code{ldemul.c} sets the variable @var{ld_emulation} to point to it. +@code{ldemul.c} also defines a number of API functions that interface +to your emulation, like @code{ldemul_after_parse} which simply calls +your @code{ld_@var{EMULATION}_emulation.after_parse} function. For +the rest of this section, the functions will be mentioned, but you +should assume the indirect reference to your emulation also. + +We will also skip or gloss over parts of the link process that don't +relate to emulations, like setting up internationalization. + +After initialization, @code{main} selects an emulation by pre-scanning +the command line arguments. It calls @code{ldemul_choose_target} to +choose a target. If you set @code{choose_target} to +@code{ldemul_default_target}, it picks your @code{target_name} by +default. + +@code{main} calls @code{ldemul_before_parse}, then @code{parse_args}. +@code{parse_args} calls @code{ldemul_parse_args} for each arg, which +must update the @code{getopt} globals if it recognizes the argument. +If the emulation doesn't recognize it, then parse_args checks to see +if it recognizes it. + +Now that the emulation has had access to all its command-line options, +@code{main} calls @code{ldemul_set_symbols}. This can be used for any +initialization that may be affected by options. It is also supposed +to set up any variables needed by the emulation script. + +@code{main} now calls @code{ldemul_get_script} to get the emulation +script to use (based on arguments, no doubt, @pxref{Emulations}) and +runs it. While parsing, @code{ldgram.y} may call @code{ldemul_hll} or +@code{ldemul_syslib} to handle the @code{HLL} or @code{SYSLIB} +commands. It may call @code{ldemul_unrecognized_file} if you asked +the linker to link a file it doesn't recognize. It will call +@code{ldemul_recognized_file} for each file it does recognize, in case +the emulation wants to handle some files specially. All the while, +it's loading the files (possibly calling +@code{ldemul_open_dynamic_archive}) and symbols and stuff. After it's +done reading the script, @code{main} calls @code{ldemul_after_parse}. +Use the after-parse hook to set up anything that depends on stuff the +script might have set up, like the entry point. + +@code{main} next calls @code{lang_process} in @code{ldlang.c}. This +appears to be the main core of the linking itself, as far as emulation +hooks are concerned(*). It first opens the output file's BFD, calling +@code{ldemul_set_output_arch}, and calls +@code{ldemul_create_output_section_statements} in case you need to use +other means to find or create object files (i.e. shared libraries +found on a path, or fake stub objects). Despite the name, nobody +creates output sections here. + +(*) In most cases, the BFD library does the bulk of the actual +linking, handling symbol tables, symbol resolution, relocations, and +building the final output file. See the BFD reference for all the +details. Your emulation is usually concerned more with managing +things at the file and section level, like "put this here, add this +section", etc. + +Next, the objects to be linked are opened and BFDs created for them, +and @code{ldemul_after_open} is called. At this point, you have all +the objects and symbols loaded, but none of the data has been placed +yet. + +Next comes the Big Linking Thingy (except for the parts BFD does). +All input sections are mapped to output sections according to the +script. If a section doesn't get mapped by default, +@code{ldemul_place_orphan} will get called to figure out where it goes. +Next it figures out the offsets for each section, calling +@code{ldemul_before_allocation} before and +@code{ldemul_after_allocation} after deciding where each input section +ends up in the output sections. + +The last part of @code{lang_process} is to figure out all the symbols' +values. After assigning final values to the symbols, +@code{ldemul_finish} is called, and after that, any undefined symbols +are turned into fatal errors. + +OK, back to @code{main}, which calls @code{ldwrite} in +@file{ldwrite.c}. @code{ldwrite} calls BFD's final_link, which does +all the relocation fixups and writes the output bfd to disk, and we're +done. + +In summary, + +@itemize @bullet + +@item @code{main()} in @file{ldmain.c} +@item @file{emultempl/@var{EMULATION}.em} has your code +@item @code{ldemul_choose_target} (defaults to your @code{target_name}) +@item @code{ldemul_before_parse} +@item Parse argv, calls @code{ldemul_parse_args} for each +@item @code{ldemul_set_symbols} +@item @code{ldemul_get_script} +@item parse script + +@itemize @bullet +@item may call @code{ldemul_hll} or @code{ldemul_syslib} +@item may call @code{ldemul_open_dynamic_archive} +@end itemize + +@item @code{ldemul_after_parse} +@item @code{lang_process()} in @file{ldlang.c} + +@itemize @bullet +@item create @code{output_bfd} +@item @code{ldemul_set_output_arch} +@item @code{ldemul_create_output_section_statements} +@item read objects, create input bfds - all symbols exist, but have no values +@item may call @code{ldemul_unrecognized_file} +@item will call @code{ldemul_recognized_file} +@item @code{ldemul_after_open} +@item map input sections to output sections +@item may call @code{ldemul_place_orphan} for remaining sections +@item @code{ldemul_before_allocation} +@item gives input sections offsets into output sections, places output sections +@item @code{ldemul_after_allocation} - section addresses valid +@item assigns values to symbols +@item @code{ldemul_finish} - symbol values valid +@end itemize + +@item output bfd is written to disk + +@end itemize + +@contents +@bye diff --git a/ld/ldlang.c b/ld/ldlang.c new file mode 100644 index 0000000..aa5c681 --- /dev/null +++ b/ld/ldlang.c @@ -0,0 +1,4703 @@ +/* Linker command language support. + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libiberty.h" +#include "obstack.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldgram.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldemul.h" +#include "ldlex.h" +#include "ldmisc.h" +#include "ldctor.h" +#include "ldfile.h" +#include "fnmatch.h" +#include "demangle.h" + +#include <ctype.h> + +/* FORWARDS */ +static lang_statement_union_type *new_statement PARAMS ((enum statement_enum, + size_t, + lang_statement_list_type*)); + + +/* LOCALS */ +static struct obstack stat_obstack; + +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free +static CONST char *startup_file; +static lang_statement_list_type input_file_chain; +static boolean placed_commons = false; +static lang_output_section_statement_type *default_common_section; +static boolean map_option_f; +static bfd_vma print_dot; +static lang_input_statement_type *first_file; +static lang_statement_list_type lang_output_section_statement; +static CONST char *current_target; +static CONST char *output_target; +static lang_statement_list_type statement_list; +static struct lang_phdr *lang_phdr_list; + +static void lang_for_each_statement_worker + PARAMS ((void (*func) (lang_statement_union_type *), + lang_statement_union_type *s)); +static lang_input_statement_type *new_afile + PARAMS ((const char *name, lang_input_file_enum_type file_type, + const char *target, boolean add_to_list)); +static void init_os PARAMS ((lang_output_section_statement_type *s)); +static void exp_init_os PARAMS ((etree_type *)); +static void section_already_linked PARAMS ((bfd *, asection *, PTR)); +static boolean wildcardp PARAMS ((const char *)); +static lang_statement_union_type *wild_sort + PARAMS ((lang_wild_statement_type *, lang_input_statement_type *, + asection *)); +static void wild_section PARAMS ((lang_wild_statement_type *ptr, + const char *section, + lang_input_statement_type *file, + lang_output_section_statement_type *output)); +static lang_input_statement_type *lookup_name PARAMS ((const char *name)); +static void load_symbols PARAMS ((lang_input_statement_type *entry, + lang_statement_list_type *)); +static void wild_file PARAMS ((lang_wild_statement_type *, const char *, + lang_input_statement_type *, + lang_output_section_statement_type *)); +static void wild PARAMS ((lang_wild_statement_type *s, + const char *section, const char *file, + const char *target, + lang_output_section_statement_type *output)); +static bfd *open_output PARAMS ((const char *name)); +static void ldlang_open_output PARAMS ((lang_statement_union_type *statement)); +static void open_input_bfds + PARAMS ((lang_statement_union_type *statement, boolean)); +static void lang_reasonable_defaults PARAMS ((void)); +static void lang_place_undefineds PARAMS ((void)); +static void map_input_to_output_sections + PARAMS ((lang_statement_union_type *s, + const char *target, + lang_output_section_statement_type *output_section_statement)); +static void print_output_section_statement + PARAMS ((lang_output_section_statement_type *output_section_statement)); +static void print_assignment + PARAMS ((lang_assignment_statement_type *assignment, + lang_output_section_statement_type *output_section)); +static void print_input_statement PARAMS ((lang_input_statement_type *statm)); +static boolean print_one_symbol PARAMS ((struct bfd_link_hash_entry *, PTR)); +static void print_input_section PARAMS ((lang_input_section_type *in)); +static void print_fill_statement PARAMS ((lang_fill_statement_type *fill)); +static void print_data_statement PARAMS ((lang_data_statement_type *data)); +static void print_address_statement PARAMS ((lang_address_statement_type *)); +static void print_reloc_statement PARAMS ((lang_reloc_statement_type *reloc)); +static void print_padding_statement PARAMS ((lang_padding_statement_type *s)); +static void print_wild_statement + PARAMS ((lang_wild_statement_type *w, + lang_output_section_statement_type *os)); +static void print_group + PARAMS ((lang_group_statement_type *, lang_output_section_statement_type *)); +static void print_statement PARAMS ((lang_statement_union_type *s, + lang_output_section_statement_type *os)); +static void print_statement_list PARAMS ((lang_statement_union_type *s, + lang_output_section_statement_type *os)); +static void print_statements PARAMS ((void)); +static bfd_vma insert_pad PARAMS ((lang_statement_union_type **this_ptr, + fill_type fill, unsigned int power, + asection *output_section_statement, + bfd_vma dot)); +static bfd_vma size_input_section + PARAMS ((lang_statement_union_type **this_ptr, + lang_output_section_statement_type *output_section_statement, + fill_type fill, bfd_vma dot, boolean relax)); +static void lang_finish PARAMS ((void)); +static void ignore_bfd_errors PARAMS ((const char *, ...)); +static void lang_check PARAMS ((void)); +static void lang_common PARAMS ((void)); +static boolean lang_one_common PARAMS ((struct bfd_link_hash_entry *, PTR)); +static void lang_place_orphans PARAMS ((void)); +static int topower PARAMS ((int)); +static void lang_set_startof PARAMS ((void)); +static void reset_memory_regions PARAMS ((void)); +static void lang_record_phdrs PARAMS ((void)); +static void lang_gc_wild_section + PARAMS ((lang_wild_statement_type *, const char *, + lang_input_statement_type *)); +static void lang_gc_wild_file + PARAMS ((lang_wild_statement_type *, const char *, + lang_input_statement_type *)); +static void lang_gc_wild + PARAMS ((lang_wild_statement_type *, const char *, const char *)); +static void lang_gc_sections_1 PARAMS ((lang_statement_union_type *)); +static void lang_gc_sections PARAMS ((void)); +static void lang_do_version_exports_section PARAMS ((void)); +static void lang_check_section_addresses PARAMS ((void)); + + +/* EXPORTS */ +lang_output_section_statement_type *abs_output_section; +lang_statement_list_type *stat_ptr = &statement_list; +lang_statement_list_type file_chain = { 0 }; +const char *entry_symbol = NULL; +boolean entry_from_cmdline; +boolean lang_has_input_file = false; +boolean had_output_filename = false; +boolean lang_float_flag = false; +boolean delete_output_file_on_failure = false; +struct lang_nocrossrefs *nocrossref_list; + +etree_type *base; /* Relocation base - or null */ + + +#if defined(__STDC__) || defined(ALMOST_STDC) +#define cat(a,b) a##b +#else +#define cat(a,b) a/**/b +#endif + +#define new_stat(x,y) (cat(x,_type)*) new_statement(cat(x,_enum), sizeof(cat(x,_type)),y) + +#define outside_section_address(q) ( (q)->output_offset + (q)->output_section->vma) + +#define outside_symbol_address(q) ((q)->value + outside_section_address(q->section)) + +#define SECTION_NAME_MAP_LENGTH (16) + +PTR +stat_alloc (size) + size_t size; +{ + return obstack_alloc (&stat_obstack, size); +} + +/*---------------------------------------------------------------------- + lang_for_each_statement walks the parse tree and calls the provided + function for each node +*/ + +static void +lang_for_each_statement_worker (func, s) + void (*func) PARAMS ((lang_statement_union_type *)); + lang_statement_union_type *s; +{ + for (; s != (lang_statement_union_type *) NULL; s = s->next) + { + func (s); + + switch (s->header.type) + { + case lang_constructors_statement_enum: + lang_for_each_statement_worker (func, constructor_list.head); + break; + case lang_output_section_statement_enum: + lang_for_each_statement_worker + (func, + s->output_section_statement.children.head); + break; + case lang_wild_statement_enum: + lang_for_each_statement_worker + (func, + s->wild_statement.children.head); + break; + case lang_group_statement_enum: + lang_for_each_statement_worker (func, + s->group_statement.children.head); + break; + case lang_data_statement_enum: + case lang_reloc_statement_enum: + case lang_object_symbols_statement_enum: + case lang_output_statement_enum: + case lang_target_statement_enum: + case lang_input_section_enum: + case lang_input_statement_enum: + case lang_assignment_statement_enum: + case lang_padding_statement_enum: + case lang_address_statement_enum: + case lang_fill_statement_enum: + break; + default: + FAIL (); + break; + } + } +} + +void +lang_for_each_statement (func) + void (*func) PARAMS ((lang_statement_union_type *)); +{ + lang_for_each_statement_worker (func, + statement_list.head); +} + +/*----------------------------------------------------------------------*/ +void +lang_list_init (list) + lang_statement_list_type *list; +{ + list->head = (lang_statement_union_type *) NULL; + list->tail = &list->head; +} + +/*---------------------------------------------------------------------- + + build a new statement node for the parse tree + + */ + +static +lang_statement_union_type * +new_statement (type, size, list) + enum statement_enum type; + size_t size; + lang_statement_list_type * list; +{ + lang_statement_union_type *new = (lang_statement_union_type *) + stat_alloc (size); + + new->header.type = type; + new->header.next = (lang_statement_union_type *) NULL; + lang_statement_append (list, new, &new->header.next); + return new; +} + +/* + Build a new input file node for the language. There are several ways + in which we treat an input file, eg, we only look at symbols, or + prefix it with a -l etc. + + We can be supplied with requests for input files more than once; + they may, for example be split over serveral lines like foo.o(.text) + foo.o(.data) etc, so when asked for a file we check that we havn't + got it already so we don't duplicate the bfd. + + */ +static lang_input_statement_type * +new_afile (name, file_type, target, add_to_list) + CONST char *name; + lang_input_file_enum_type file_type; + CONST char *target; + boolean add_to_list; +{ + lang_input_statement_type *p; + + if (add_to_list) + p = new_stat (lang_input_statement, stat_ptr); + else + { + p = ((lang_input_statement_type *) + stat_alloc (sizeof (lang_input_statement_type))); + p->header.next = NULL; + } + + lang_has_input_file = true; + p->target = target; + switch (file_type) + { + case lang_input_file_is_symbols_only_enum: + p->filename = name; + p->is_archive = false; + p->real = true; + p->local_sym_name = name; + p->just_syms_flag = true; + p->search_dirs_flag = false; + break; + case lang_input_file_is_fake_enum: + p->filename = name; + p->is_archive = false; + p->real = false; + p->local_sym_name = name; + p->just_syms_flag = false; + p->search_dirs_flag = false; + break; + case lang_input_file_is_l_enum: + p->is_archive = true; + p->filename = name; + p->real = true; + p->local_sym_name = concat ("-l", name, (const char *) NULL); + p->just_syms_flag = false; + p->search_dirs_flag = true; + break; + case lang_input_file_is_marker_enum: + p->filename = name; + p->is_archive = false; + p->real = false; + p->local_sym_name = name; + p->just_syms_flag = false; + p->search_dirs_flag = true; + break; + case lang_input_file_is_search_file_enum: + p->filename = name; + p->is_archive = false; + p->real = true; + p->local_sym_name = name; + p->just_syms_flag = false; + p->search_dirs_flag = true; + break; + case lang_input_file_is_file_enum: + p->filename = name; + p->is_archive = false; + p->real = true; + p->local_sym_name = name; + p->just_syms_flag = false; + p->search_dirs_flag = false; + break; + default: + FAIL (); + } + p->the_bfd = (bfd *) NULL; + p->asymbols = (asymbol **) NULL; + p->next_real_file = (lang_statement_union_type *) NULL; + p->next = (lang_statement_union_type *) NULL; + p->symbol_count = 0; + p->dynamic = config.dynamic_link; + p->whole_archive = whole_archive; + p->loaded = false; + lang_statement_append (&input_file_chain, + (lang_statement_union_type *) p, + &p->next_real_file); + return p; +} + +lang_input_statement_type * +lang_add_input_file (name, file_type, target) + CONST char *name; + lang_input_file_enum_type file_type; + CONST char *target; +{ + lang_has_input_file = true; + return new_afile (name, file_type, target, true); +} + +/* Build enough state so that the parser can build its tree */ +void +lang_init () +{ + obstack_begin (&stat_obstack, 1000); + + stat_ptr = &statement_list; + + lang_list_init (stat_ptr); + + lang_list_init (&input_file_chain); + lang_list_init (&lang_output_section_statement); + lang_list_init (&file_chain); + first_file = lang_add_input_file ((char *) NULL, + lang_input_file_is_marker_enum, + (char *) NULL); + abs_output_section = lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME); + + abs_output_section->bfd_section = bfd_abs_section_ptr; + +} + +/*---------------------------------------------------------------------- + A region is an area of memory declared with the + MEMORY { name:org=exp, len=exp ... } + syntax. + + We maintain a list of all the regions here + + If no regions are specified in the script, then the default is used + which is created when looked up to be the entire data space +*/ + +static lang_memory_region_type *lang_memory_region_list; +static lang_memory_region_type **lang_memory_region_list_tail = &lang_memory_region_list; + +lang_memory_region_type * +lang_memory_region_lookup (name) + CONST char *CONST name; +{ + lang_memory_region_type *p; + + for (p = lang_memory_region_list; + p != (lang_memory_region_type *) NULL; + p = p->next) + { + if (strcmp (p->name, name) == 0) + { + return p; + } + } + +#if 0 + /* This code used to always use the first region in the list as the + default region. I changed it to instead use a region + encompassing all of memory as the default region. This permits + NOLOAD sections to work reasonably without requiring a region. + People should specify what region they mean, if they really want + a region. */ + if (strcmp (name, "*default*") == 0) + { + if (lang_memory_region_list != (lang_memory_region_type *) NULL) + { + return lang_memory_region_list; + } + } +#endif + + { + lang_memory_region_type *new = + (lang_memory_region_type *) stat_alloc (sizeof (lang_memory_region_type)); + + new->name = buystring (name); + new->next = (lang_memory_region_type *) NULL; + + *lang_memory_region_list_tail = new; + lang_memory_region_list_tail = &new->next; + new->origin = 0; + new->flags = 0; + new->not_flags = 0; + new->length = ~(bfd_size_type)0; + new->current = 0; + new->had_full_message = false; + + return new; + } +} + + +lang_memory_region_type * +lang_memory_default (section) + asection *section; +{ + lang_memory_region_type *p; + + flagword sec_flags = section->flags; + + /* Override SEC_DATA to mean a writable section. */ + if ((sec_flags & (SEC_ALLOC | SEC_READONLY | SEC_CODE)) == SEC_ALLOC) + sec_flags |= SEC_DATA; + + for (p = lang_memory_region_list; + p != (lang_memory_region_type *) NULL; + p = p->next) + { + if ((p->flags & sec_flags) != 0 + && (p->not_flags & sec_flags) == 0) + { + return p; + } + } + return lang_memory_region_lookup ("*default*"); +} + +lang_output_section_statement_type * +lang_output_section_find (name) + CONST char *CONST name; +{ + lang_statement_union_type *u; + lang_output_section_statement_type *lookup; + + for (u = lang_output_section_statement.head; + u != (lang_statement_union_type *) NULL; + u = lookup->next) + { + lookup = &u->output_section_statement; + if (strcmp (name, lookup->name) == 0) + { + return lookup; + } + } + return (lang_output_section_statement_type *) NULL; +} + +lang_output_section_statement_type * +lang_output_section_statement_lookup (name) + CONST char *CONST name; +{ + lang_output_section_statement_type *lookup; + + lookup = lang_output_section_find (name); + if (lookup == (lang_output_section_statement_type *) NULL) + { + + lookup = (lang_output_section_statement_type *) + new_stat (lang_output_section_statement, stat_ptr); + lookup->region = (lang_memory_region_type *) NULL; + lookup->fill = 0; + lookup->block_value = 1; + lookup->name = name; + + lookup->next = (lang_statement_union_type *) NULL; + lookup->bfd_section = (asection *) NULL; + lookup->processed = false; + lookup->sectype = normal_section; + lookup->addr_tree = (etree_type *) NULL; + lang_list_init (&lookup->children); + + lookup->memspec = (CONST char *) NULL; + lookup->flags = 0; + lookup->subsection_alignment = -1; + lookup->section_alignment = -1; + lookup->load_base = (union etree_union *) NULL; + lookup->phdrs = NULL; + + lang_statement_append (&lang_output_section_statement, + (lang_statement_union_type *) lookup, + &lookup->next); + } + return lookup; +} + +static void +lang_map_flags (flag) + flagword flag; +{ + if (flag & SEC_ALLOC) + minfo ("a"); + + if (flag & SEC_CODE) + minfo ("x"); + + if (flag & SEC_READONLY) + minfo ("r"); + + if (flag & SEC_DATA) + minfo ("w"); + + if (flag & SEC_LOAD) + minfo ("l"); +} + +void +lang_map () +{ + lang_memory_region_type *m; + + minfo (_("\nMemory Configuration\n\n")); + fprintf (config.map_file, "%-16s %-18s %-18s %s\n", + _("Name"), _("Origin"), _("Length"), _("Attributes")); + + for (m = lang_memory_region_list; + m != (lang_memory_region_type *) NULL; + m = m->next) + { + char buf[100]; + int len; + + fprintf (config.map_file, "%-16s ", m->name); + + sprintf_vma (buf, m->origin); + minfo ("0x%s ", buf); + len = strlen (buf); + while (len < 16) + { + print_space (); + ++len; + } + + minfo ("0x%V", m->length); + if (m->flags || m->not_flags) + { +#ifndef BFD64 + minfo (" "); +#endif + if (m->flags) + { + print_space (); + lang_map_flags (m->flags); + } + + if (m->not_flags) + { + minfo (" !"); + lang_map_flags (m->not_flags); + } + } + + print_nl (); + } + + fprintf (config.map_file, _("\nLinker script and memory map\n\n")); + + print_statements (); +} + +/* Initialize an output section. */ + +static void +init_os (s) + lang_output_section_statement_type *s; +{ + section_userdata_type *new; + + if (s->bfd_section != NULL) + return; + + if (strcmp (s->name, DISCARD_SECTION_NAME) == 0) + einfo (_("%P%F: Illegal use of `%s' section"), DISCARD_SECTION_NAME); + + new = ((section_userdata_type *) + stat_alloc (sizeof (section_userdata_type))); + + s->bfd_section = bfd_get_section_by_name (output_bfd, s->name); + if (s->bfd_section == (asection *) NULL) + s->bfd_section = bfd_make_section (output_bfd, s->name); + if (s->bfd_section == (asection *) NULL) + { + einfo (_("%P%F: output format %s cannot represent section called %s\n"), + output_bfd->xvec->name, s->name); + } + s->bfd_section->output_section = s->bfd_section; + + /* We initialize an output sections output offset to minus its own */ + /* vma to allow us to output a section through itself */ + s->bfd_section->output_offset = 0; + get_userdata (s->bfd_section) = (PTR) new; + + /* If there is a base address, make sure that any sections it might + mention are initialized. */ + if (s->addr_tree != NULL) + exp_init_os (s->addr_tree); +} + +/* Make sure that all output sections mentioned in an expression are + initialized. */ + +static void +exp_init_os (exp) + etree_type *exp; +{ + switch (exp->type.node_class) + { + case etree_assign: + exp_init_os (exp->assign.src); + break; + + case etree_binary: + exp_init_os (exp->binary.lhs); + exp_init_os (exp->binary.rhs); + break; + + case etree_trinary: + exp_init_os (exp->trinary.cond); + exp_init_os (exp->trinary.lhs); + exp_init_os (exp->trinary.rhs); + break; + + case etree_unary: + exp_init_os (exp->unary.child); + break; + + case etree_name: + switch (exp->type.node_code) + { + case ADDR: + case LOADADDR: + case SIZEOF: + { + lang_output_section_statement_type *os; + + os = lang_output_section_find (exp->name.name); + if (os != NULL && os->bfd_section == NULL) + init_os (os); + } + } + break; + + default: + break; + } +} + +/* Sections marked with the SEC_LINK_ONCE flag should only be linked + once into the output. This routine checks each sections, and + arranges to discard it if a section of the same name has already + been linked. This code assumes that all relevant sections have the + SEC_LINK_ONCE flag set; that is, it does not depend solely upon the + section name. This is called via bfd_map_over_sections. */ + +/*ARGSUSED*/ +static void +section_already_linked (abfd, sec, data) + bfd *abfd; + asection *sec; + PTR data; +{ + lang_input_statement_type *entry = (lang_input_statement_type *) data; + struct sec_link_once + { + struct sec_link_once *next; + asection *sec; + }; + static struct sec_link_once *sec_link_once_list; + flagword flags; + const char *name; + struct sec_link_once *l; + + /* If we are only reading symbols from this object, then we want to + discard all sections. */ + if (entry->just_syms_flag) + { + sec->output_section = bfd_abs_section_ptr; + sec->output_offset = sec->vma; + return; + } + + flags = bfd_get_section_flags (abfd, sec); + + if ((flags & SEC_LINK_ONCE) == 0) + return; + + name = bfd_get_section_name (abfd, sec); + + for (l = sec_link_once_list; l != NULL; l = l->next) + { + if (strcmp (name, bfd_get_section_name (l->sec->owner, l->sec)) == 0) + { + /* The section has already been linked. See if we should + issue a warning. */ + switch (flags & SEC_LINK_DUPLICATES) + { + default: + abort (); + + case SEC_LINK_DUPLICATES_DISCARD: + break; + + case SEC_LINK_DUPLICATES_ONE_ONLY: + einfo (_("%P: %B: warning: ignoring duplicate section `%s'\n"), + abfd, name); + break; + + case SEC_LINK_DUPLICATES_SAME_CONTENTS: + /* FIXME: We should really dig out the contents of both + sections and memcmp them. The COFF/PE spec says that + the Microsoft linker does not implement this + correctly, so I'm not going to bother doing it + either. */ + /* Fall through. */ + case SEC_LINK_DUPLICATES_SAME_SIZE: + if (bfd_section_size (abfd, sec) + != bfd_section_size (l->sec->owner, l->sec)) + einfo (_("%P: %B: warning: duplicate section `%s' has different size\n"), + abfd, name); + break; + } + + /* Set the output_section field so that wild_doit does not + create a lang_input_section structure for this section. */ + sec->output_section = bfd_abs_section_ptr; + + return; + } + } + + /* This is the first section with this name. Record it. */ + + l = (struct sec_link_once *) xmalloc (sizeof *l); + l->sec = sec; + l->next = sec_link_once_list; + sec_link_once_list = l; +} + +/* The wild routines. + + These expand statements like *(.text) and foo.o to a list of + explicit actions, like foo.o(.text), bar.o(.text) and + foo.o(.text, .data). */ + +/* Return true if the PATTERN argument is a wildcard pattern. + Although backslashes are treated specially if a pattern contains + wildcards, we do not consider the mere presence of a backslash to + be enough to cause the the pattern to be treated as a wildcard. + That lets us handle DOS filenames more naturally. */ + +static boolean +wildcardp (pattern) + const char *pattern; +{ + const char *s; + + for (s = pattern; *s != '\0'; ++s) + if (*s == '?' + || *s == '*' + || *s == '[') + return true; + return false; +} + +/* Add SECTION to the output section OUTPUT. Do this by creating a + lang_input_section statement which is placed at PTR. FILE is the + input file which holds SECTION. */ + +void +wild_doit (ptr, section, output, file) + lang_statement_list_type *ptr; + asection *section; + lang_output_section_statement_type *output; + lang_input_statement_type *file; +{ + flagword flags; + boolean discard; + + flags = bfd_get_section_flags (section->owner, section); + + discard = false; + + /* If we are doing a final link, discard sections marked with + SEC_EXCLUDE. */ + if (! link_info.relocateable + && (flags & SEC_EXCLUDE) != 0) + discard = true; + + /* Discard input sections which are assigned to a section named + DISCARD_SECTION_NAME. */ + if (strcmp (output->name, DISCARD_SECTION_NAME) == 0) + discard = true; + + /* Discard debugging sections if we are stripping debugging + information. */ + if ((link_info.strip == strip_debugger || link_info.strip == strip_all) + && (flags & SEC_DEBUGGING) != 0) + discard = true; + + if (discard) + { + if (section->output_section == NULL) + { + /* This prevents future calls from assigning this section. */ + section->output_section = bfd_abs_section_ptr; + } + return; + } + + if (section->output_section == NULL) + { + boolean first; + lang_input_section_type *new; + flagword flags; + + if (output->bfd_section == NULL) + { + init_os (output); + first = true; + } + else + first = false; + + /* Add a section reference to the list */ + new = new_stat (lang_input_section, ptr); + + new->section = section; + new->ifile = file; + section->output_section = output->bfd_section; + + flags = section->flags; + + /* We don't copy the SEC_NEVER_LOAD flag from an input section + to an output section, because we want to be able to include a + SEC_NEVER_LOAD section in the middle of an otherwise loaded + section (I don't know why we want to do this, but we do). + build_link_order in ldwrite.c handles this case by turning + the embedded SEC_NEVER_LOAD section into a fill. */ + + flags &= ~ SEC_NEVER_LOAD; + + /* If final link, don't copy the SEC_LINK_ONCE flags, they've + already been processed. One reason to do this is that on pe + format targets, .text$foo sections go into .text and it's odd + to see .text with SEC_LINK_ONCE set. */ + + if (! link_info.relocateable) + flags &= ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES); + + /* If this is not the first input section, and the SEC_READONLY + flag is not currently set, then don't set it just because the + input section has it set. */ + + if (! first && (section->output_section->flags & SEC_READONLY) == 0) + flags &= ~ SEC_READONLY; + + section->output_section->flags |= flags; + + /* If SEC_READONLY is not set in the input section, then clear + it from the output section. */ + if ((section->flags & SEC_READONLY) == 0) + section->output_section->flags &= ~SEC_READONLY; + + switch (output->sectype) + { + case normal_section: + break; + case dsect_section: + case copy_section: + case info_section: + case overlay_section: + output->bfd_section->flags &= ~SEC_ALLOC; + break; + case noload_section: + output->bfd_section->flags &= ~SEC_LOAD; + output->bfd_section->flags |= SEC_NEVER_LOAD; + break; + } + + if (section->alignment_power > output->bfd_section->alignment_power) + output->bfd_section->alignment_power = section->alignment_power; + + /* If supplied an aligment, then force it. */ + if (output->section_alignment != -1) + output->bfd_section->alignment_power = output->section_alignment; + } +} + +/* Handle wildcard sorting. This returns the lang_input_section which + should follow the one we are going to create for SECTION and FILE, + based on the sorting requirements of WILD. It returns NULL if the + new section should just go at the end of the current list. */ + +static lang_statement_union_type * +wild_sort (wild, file, section) + lang_wild_statement_type *wild; + lang_input_statement_type *file; + asection *section; +{ + const char *section_name; + lang_statement_union_type *l; + + if (! wild->filenames_sorted && ! wild->sections_sorted) + return NULL; + + section_name = bfd_get_section_name (file->the_bfd, section); + for (l = wild->children.head; l != NULL; l = l->next) + { + lang_input_section_type *ls; + + if (l->header.type != lang_input_section_enum) + continue; + ls = &l->input_section; + + /* Sorting by filename takes precedence over sorting by section + name. */ + + if (wild->filenames_sorted) + { + const char *fn, *ln; + boolean fa, la; + int i; + + /* The PE support for the .idata section as generated by + dlltool assumes that files will be sorted by the name of + the archive and then the name of the file within the + archive. */ + + if (file->the_bfd != NULL + && bfd_my_archive (file->the_bfd) != NULL) + { + fn = bfd_get_filename (bfd_my_archive (file->the_bfd)); + fa = true; + } + else + { + fn = file->filename; + fa = false; + } + + if (ls->ifile->the_bfd != NULL + && bfd_my_archive (ls->ifile->the_bfd) != NULL) + { + ln = bfd_get_filename (bfd_my_archive (ls->ifile->the_bfd)); + la = true; + } + else + { + ln = ls->ifile->filename; + la = false; + } + + i = strcmp (fn, ln); + if (i > 0) + continue; + else if (i < 0) + break; + + if (fa || la) + { + if (fa) + fn = file->filename; + if (la) + ln = ls->ifile->filename; + + i = strcmp (fn, ln); + if (i > 0) + continue; + else if (i < 0) + break; + } + } + + /* Here either the files are not sorted by name, or we are + looking at the sections for this file. */ + + if (wild->sections_sorted) + { + if (strcmp (section_name, + bfd_get_section_name (ls->ifile->the_bfd, + ls->section)) + < 0) + break; + } + } + + return l; +} + +/* Expand a wild statement for a particular FILE. SECTION may be + NULL, in which case it is a wild card. */ + +static void +wild_section (ptr, section, file, output) + lang_wild_statement_type *ptr; + const char *section; + lang_input_statement_type *file; + lang_output_section_statement_type *output; +{ + + /* Don't process sections from files which were excluded. */ + if (ptr->exclude_filename != NULL) + { + boolean match; + + if (wildcardp (ptr->exclude_filename)) + match = fnmatch (ptr->exclude_filename, file->filename, 0) == 0 ? true : false; + else + match = strcmp (ptr->exclude_filename, file->filename) == 0 ? true : false; + + if (match) + return; + } + + if (file->just_syms_flag == false) + { + register asection *s; + boolean wildcard; + + if (section == NULL) + wildcard = false; + else + wildcard = wildcardp (section); + + for (s = file->the_bfd->sections; s != NULL; s = s->next) + { + boolean match; + + /* Attach all sections named SECTION. If SECTION is NULL, + then attach all sections. + + Previously, if SECTION was NULL, this code did not call + wild_doit if the SEC_IS_COMMON flag was set for the + section. I did not understand that, and I took it out. + --ian@cygnus.com. */ + + if (section == NULL) + match = true; + else + { + const char *name; + + name = bfd_get_section_name (file->the_bfd, s); + if (wildcard) + match = fnmatch (section, name, 0) == 0 ? true : false; + else + match = strcmp (section, name) == 0 ? true : false; + } + + if (match) + { + lang_statement_union_type *before; + + /* If the wild pattern was marked KEEP, the member sections + should be as well. */ + if (ptr->keep_sections) + s->flags |= SEC_KEEP; + + before = wild_sort (ptr, file, s); + + /* Here BEFORE points to the lang_input_section which + should follow the one we are about to add. If BEFORE + is NULL, then the section should just go at the end + of the current list. */ + + if (before == NULL) + wild_doit (&ptr->children, s, output, file); + else + { + lang_statement_list_type list; + lang_statement_union_type **pp; + + lang_list_init (&list); + wild_doit (&list, s, output, file); + + /* If we are discarding the section, LIST.HEAD will + be NULL. */ + if (list.head != NULL) + { + ASSERT (list.head->next == NULL); + + for (pp = &ptr->children.head; + *pp != before; + pp = &(*pp)->next) + ASSERT (*pp != NULL); + + list.head->next = *pp; + *pp = list.head; + } + } + } + } + } +} + +/* This is passed a file name which must have been seen already and + added to the statement tree. We will see if it has been opened + already and had its symbols read. If not then we'll read it. */ + +static lang_input_statement_type * +lookup_name (name) + const char *name; +{ + lang_input_statement_type *search; + + for (search = (lang_input_statement_type *) input_file_chain.head; + search != (lang_input_statement_type *) NULL; + search = (lang_input_statement_type *) search->next_real_file) + { + if (search->filename == (char *) NULL && name == (char *) NULL) + return search; + if (search->filename != (char *) NULL + && name != (char *) NULL + && strcmp (search->filename, name) == 0) + break; + } + + if (search == (lang_input_statement_type *) NULL) + search = new_afile (name, lang_input_file_is_file_enum, default_target, + false); + + /* If we have already added this file, or this file is not real + (FIXME: can that ever actually happen?) or the name is NULL + (FIXME: can that ever actually happen?) don't add this file. */ + if (search->loaded + || ! search->real + || search->filename == (const char *) NULL) + return search; + + load_symbols (search, (lang_statement_list_type *) NULL); + + return search; +} + +/* Get the symbols for an input file. */ + +static void +load_symbols (entry, place) + lang_input_statement_type *entry; + lang_statement_list_type *place; +{ + char **matching; + + if (entry->loaded) + return; + + ldfile_open_file (entry); + + if (! bfd_check_format (entry->the_bfd, bfd_archive) + && ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching)) + { + bfd_error_type err; + lang_statement_list_type *hold; + + err = bfd_get_error (); + if (err == bfd_error_file_ambiguously_recognized) + { + char **p; + + einfo (_("%B: file not recognized: %E\n"), entry->the_bfd); + einfo (_("%B: matching formats:"), entry->the_bfd); + for (p = matching; *p != NULL; p++) + einfo (" %s", *p); + einfo ("%F\n"); + } + else if (err != bfd_error_file_not_recognized + || place == NULL) + einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd); + + bfd_close (entry->the_bfd); + entry->the_bfd = NULL; + + /* See if the emulation has some special knowledge. */ + + if (ldemul_unrecognized_file (entry)) + return; + + /* Try to interpret the file as a linker script. */ + + ldfile_open_command_file (entry->filename); + + hold = stat_ptr; + stat_ptr = place; + + ldfile_assumed_script = true; + parser_input = input_script; + yyparse (); + ldfile_assumed_script = false; + + stat_ptr = hold; + + return; + } + + if (ldemul_recognized_file (entry)) + return; + + /* We don't call ldlang_add_file for an archive. Instead, the + add_symbols entry point will call ldlang_add_file, via the + add_archive_element callback, for each element of the archive + which is used. */ + switch (bfd_get_format (entry->the_bfd)) + { + default: + break; + + case bfd_object: + ldlang_add_file (entry); + if (trace_files || trace_file_tries) + info_msg ("%I\n", entry); + break; + + case bfd_archive: + if (entry->whole_archive) + { + bfd *member = bfd_openr_next_archived_file (entry->the_bfd, + (bfd *) NULL); + while (member != NULL) + { + if (! bfd_check_format (member, bfd_object)) + einfo (_("%F%B: object %B in archive is not object\n"), + entry->the_bfd, member); + if (! ((*link_info.callbacks->add_archive_element) + (&link_info, member, "--whole-archive"))) + abort (); + if (! bfd_link_add_symbols (member, &link_info)) + einfo (_("%F%B: could not read symbols: %E\n"), member); + member = bfd_openr_next_archived_file (entry->the_bfd, + member); + } + + entry->loaded = true; + + return; + } + } + + if (! bfd_link_add_symbols (entry->the_bfd, &link_info)) + einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd); + + entry->loaded = true; +} + +/* Handle a wild statement for a single file F. */ + +static void +wild_file (s, section, f, output) + lang_wild_statement_type *s; + const char *section; + lang_input_statement_type *f; + lang_output_section_statement_type *output; +{ + if (f->the_bfd == NULL + || ! bfd_check_format (f->the_bfd, bfd_archive)) + wild_section (s, section, f, output); + else + { + bfd *member; + + /* This is an archive file. We must map each member of the + archive separately. */ + member = bfd_openr_next_archived_file (f->the_bfd, (bfd *) NULL); + while (member != NULL) + { + /* When lookup_name is called, it will call the add_symbols + entry point for the archive. For each element of the + archive which is included, BFD will call ldlang_add_file, + which will set the usrdata field of the member to the + lang_input_statement. */ + if (member->usrdata != NULL) + { + wild_section (s, section, + (lang_input_statement_type *) member->usrdata, + output); + } + + member = bfd_openr_next_archived_file (f->the_bfd, member); + } + } +} + +/* Handle a wild statement. SECTION or FILE or both may be NULL, + indicating that it is a wildcard. Separate lang_input_section + statements are created for each part of the expansion; they are + added after the wild statement S. OUTPUT is the output section. */ + +static void +wild (s, section, file, target, output) + lang_wild_statement_type *s; + const char *section; + const char *file; + const char *target; + lang_output_section_statement_type *output; +{ + lang_input_statement_type *f; + + if (file == (char *) NULL) + { + /* Perform the iteration over all files in the list */ + for (f = (lang_input_statement_type *) file_chain.head; + f != (lang_input_statement_type *) NULL; + f = (lang_input_statement_type *) f->next) + { + wild_file (s, section, f, output); + } + } + else if (wildcardp (file)) + { + for (f = (lang_input_statement_type *) file_chain.head; + f != (lang_input_statement_type *) NULL; + f = (lang_input_statement_type *) f->next) + { + if (fnmatch (file, f->filename, FNM_FILE_NAME) == 0) + wild_file (s, section, f, output); + } + } + else + { + /* Perform the iteration over a single file */ + f = lookup_name (file); + wild_file (s, section, f, output); + } + + if (section != (char *) NULL + && strcmp (section, "COMMON") == 0 + && default_common_section == NULL) + { + /* Remember the section that common is going to in case we later + get something which doesn't know where to put it. */ + default_common_section = output; + } +} + +/* Open the output file. */ + +static bfd * +open_output (name) + const char *name; +{ + bfd *output; + + if (output_target == (char *) NULL) + { + if (current_target != (char *) NULL) + output_target = current_target; + else + output_target = default_target; + } + output = bfd_openw (name, output_target); + + if (output == (bfd *) NULL) + { + if (bfd_get_error () == bfd_error_invalid_target) + { + einfo (_("%P%F: target %s not found\n"), output_target); + } + einfo (_("%P%F: cannot open output file %s: %E\n"), name); + } + + delete_output_file_on_failure = true; + + /* output->flags |= D_PAGED;*/ + + if (! bfd_set_format (output, bfd_object)) + einfo (_("%P%F:%s: can not make object file: %E\n"), name); + if (! bfd_set_arch_mach (output, + ldfile_output_architecture, + ldfile_output_machine)) + einfo (_("%P%F:%s: can not set architecture: %E\n"), name); + + link_info.hash = bfd_link_hash_table_create (output); + if (link_info.hash == (struct bfd_link_hash_table *) NULL) + einfo (_("%P%F: can not create link hash table: %E\n")); + + bfd_set_gp_size (output, g_switch_value); + return output; +} + + + + +static void +ldlang_open_output (statement) + lang_statement_union_type * statement; +{ + switch (statement->header.type) + { + case lang_output_statement_enum: + ASSERT (output_bfd == (bfd *) NULL); + output_bfd = open_output (statement->output_statement.name); + ldemul_set_output_arch (); + if (config.magic_demand_paged && !link_info.relocateable) + output_bfd->flags |= D_PAGED; + else + output_bfd->flags &= ~D_PAGED; + if (config.text_read_only) + output_bfd->flags |= WP_TEXT; + else + output_bfd->flags &= ~WP_TEXT; + if (link_info.traditional_format) + output_bfd->flags |= BFD_TRADITIONAL_FORMAT; + else + output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT; + break; + + case lang_target_statement_enum: + current_target = statement->target_statement.target; + break; + default: + break; + } +} + +/* Open all the input files. */ + +static void +open_input_bfds (s, force) + lang_statement_union_type *s; + boolean force; +{ + for (; s != (lang_statement_union_type *) NULL; s = s->next) + { + switch (s->header.type) + { + case lang_constructors_statement_enum: + open_input_bfds (constructor_list.head, force); + break; + case lang_output_section_statement_enum: + open_input_bfds (s->output_section_statement.children.head, force); + break; + case lang_wild_statement_enum: + /* Maybe we should load the file's symbols */ + if (s->wild_statement.filename + && ! wildcardp (s->wild_statement.filename)) + (void) lookup_name (s->wild_statement.filename); + open_input_bfds (s->wild_statement.children.head, force); + break; + case lang_group_statement_enum: + { + struct bfd_link_hash_entry *undefs; + + /* We must continually search the entries in the group + until no new symbols are added to the list of undefined + symbols. */ + + do + { + undefs = link_info.hash->undefs_tail; + open_input_bfds (s->group_statement.children.head, true); + } + while (undefs != link_info.hash->undefs_tail); + } + break; + case lang_target_statement_enum: + current_target = s->target_statement.target; + break; + case lang_input_statement_enum: + if (s->input_statement.real == true) + { + lang_statement_list_type add; + + s->input_statement.target = current_target; + + /* If we are being called from within a group, and this + is an archive which has already been searched, then + force it to be researched. */ + if (force + && s->input_statement.loaded + && bfd_check_format (s->input_statement.the_bfd, + bfd_archive)) + s->input_statement.loaded = false; + + lang_list_init (&add); + + load_symbols (&s->input_statement, &add); + + if (add.head != NULL) + { + *add.tail = s->next; + s->next = add.head; + } + } + break; + default: + break; + } + } +} + +/* If there are [COMMONS] statements, put a wild one into the bss section */ + +static void +lang_reasonable_defaults () +{ +#if 0 + lang_output_section_statement_lookup (".text"); + lang_output_section_statement_lookup (".data"); + + default_common_section = + lang_output_section_statement_lookup (".bss"); + + + if (placed_commons == false) + { + lang_wild_statement_type *new = + new_stat (lang_wild_statement, + &default_common_section->children); + + new->section_name = "COMMON"; + new->filename = (char *) NULL; + lang_list_init (&new->children); + } +#endif + +} + +/* + Add the supplied name to the symbol table as an undefined reference. + Remove items from the chain as we open input bfds + */ +typedef struct ldlang_undef_chain_list +{ + struct ldlang_undef_chain_list *next; + char *name; +} ldlang_undef_chain_list_type; + +static ldlang_undef_chain_list_type *ldlang_undef_chain_list_head; + +void +ldlang_add_undef (name) + CONST char *CONST name; +{ + ldlang_undef_chain_list_type *new = + ((ldlang_undef_chain_list_type *) + stat_alloc (sizeof (ldlang_undef_chain_list_type))); + + new->next = ldlang_undef_chain_list_head; + ldlang_undef_chain_list_head = new; + + new->name = buystring (name); +} + +/* Run through the list of undefineds created above and place them + into the linker hash table as undefined symbols belonging to the + script file. +*/ +static void +lang_place_undefineds () +{ + ldlang_undef_chain_list_type *ptr; + + for (ptr = ldlang_undef_chain_list_head; + ptr != (ldlang_undef_chain_list_type *) NULL; + ptr = ptr->next) + { + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (link_info.hash, ptr->name, true, false, true); + if (h == (struct bfd_link_hash_entry *) NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + if (h->type == bfd_link_hash_new) + { + h->type = bfd_link_hash_undefined; + h->u.undef.abfd = NULL; + bfd_link_add_undef (link_info.hash, h); + } + } +} + +/* Open input files and attatch to output sections */ +static void +map_input_to_output_sections (s, target, output_section_statement) + lang_statement_union_type * s; + CONST char *target; + lang_output_section_statement_type * output_section_statement; +{ + for (; s != (lang_statement_union_type *) NULL; s = s->next) + { + switch (s->header.type) + { + + + case lang_wild_statement_enum: + wild (&s->wild_statement, s->wild_statement.section_name, + s->wild_statement.filename, target, + output_section_statement); + + break; + case lang_constructors_statement_enum: + map_input_to_output_sections (constructor_list.head, + target, + output_section_statement); + break; + case lang_output_section_statement_enum: + map_input_to_output_sections (s->output_section_statement.children.head, + target, + &s->output_section_statement); + break; + case lang_output_statement_enum: + break; + case lang_target_statement_enum: + target = s->target_statement.target; + break; + case lang_group_statement_enum: + map_input_to_output_sections (s->group_statement.children.head, + target, + output_section_statement); + break; + case lang_fill_statement_enum: + case lang_input_section_enum: + case lang_object_symbols_statement_enum: + case lang_data_statement_enum: + case lang_reloc_statement_enum: + case lang_padding_statement_enum: + case lang_input_statement_enum: + if (output_section_statement != NULL + && output_section_statement->bfd_section == NULL) + init_os (output_section_statement); + break; + case lang_assignment_statement_enum: + if (output_section_statement != NULL + && output_section_statement->bfd_section == NULL) + init_os (output_section_statement); + + /* Make sure that any sections mentioned in the assignment + are initialized. */ + exp_init_os (s->assignment_statement.exp); + break; + case lang_afile_asection_pair_statement_enum: + FAIL (); + break; + case lang_address_statement_enum: + /* Mark the specified section with the supplied address */ + { + lang_output_section_statement_type *os = + lang_output_section_statement_lookup + (s->address_statement.section_name); + + if (os->bfd_section == NULL) + init_os (os); + os->addr_tree = s->address_statement.address; + } + break; + } + } +} + +static void +print_output_section_statement (output_section_statement) + lang_output_section_statement_type * output_section_statement; +{ + asection *section = output_section_statement->bfd_section; + int len; + + if (output_section_statement != abs_output_section) + { + minfo ("\n%s", output_section_statement->name); + + if (section != NULL) + { + print_dot = section->vma; + + len = strlen (output_section_statement->name); + if (len >= SECTION_NAME_MAP_LENGTH - 1) + { + print_nl (); + len = 0; + } + while (len < SECTION_NAME_MAP_LENGTH) + { + print_space (); + ++len; + } + + minfo ("0x%V %W", section->vma, section->_raw_size); + + if (output_section_statement->load_base != NULL) + { + bfd_vma addr; + + addr = exp_get_abs_int (output_section_statement->load_base, 0, + "load base", lang_final_phase_enum); + minfo (_(" load address 0x%V"), addr); + } + } + + print_nl (); + } + + print_statement_list (output_section_statement->children.head, + output_section_statement); +} + +static void +print_assignment (assignment, output_section) + lang_assignment_statement_type * assignment; + lang_output_section_statement_type * output_section; +{ + int i; + etree_value_type result; + + for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) + print_space (); + + result = exp_fold_tree (assignment->exp->assign.src, output_section, + lang_final_phase_enum, print_dot, &print_dot); + if (result.valid_p) + minfo ("0x%V", result.value + result.section->bfd_section->vma); + else + { + minfo ("*undef* "); +#ifdef BFD64 + minfo (" "); +#endif + } + + minfo (" "); + + exp_print_tree (assignment->exp); + + print_nl (); +} + +static void +print_input_statement (statm) + lang_input_statement_type * statm; +{ + if (statm->filename != (char *) NULL) + { + fprintf (config.map_file, "LOAD %s\n", statm->filename); + } +} + +/* Print all symbols defined in a particular section. This is called + via bfd_link_hash_traverse. */ + +static boolean +print_one_symbol (hash_entry, ptr) + struct bfd_link_hash_entry *hash_entry; + PTR ptr; +{ + asection *sec = (asection *) ptr; + + if ((hash_entry->type == bfd_link_hash_defined + || hash_entry->type == bfd_link_hash_defweak) + && sec == hash_entry->u.def.section) + { + int i; + + for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) + print_space (); + minfo ("0x%V ", + (hash_entry->u.def.value + + hash_entry->u.def.section->output_offset + + hash_entry->u.def.section->output_section->vma)); + + minfo (" %T\n", hash_entry->root.string); + } + + return true; +} + +/* Print information about an input section to the map file. */ + +static void +print_input_section (in) + lang_input_section_type * in; +{ + asection *i = in->section; + bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size; + + if (size != 0) + { + print_space (); + + minfo ("%s", i->name); + + if (i->output_section != NULL) + { + int len; + + len = 1 + strlen (i->name); + if (len >= SECTION_NAME_MAP_LENGTH - 1) + { + print_nl (); + len = 0; + } + while (len < SECTION_NAME_MAP_LENGTH) + { + print_space (); + ++len; + } + + minfo ("0x%V %W %B\n", + i->output_section->vma + i->output_offset, size, + i->owner); + + if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size) + { + len = SECTION_NAME_MAP_LENGTH + 3; +#ifdef BFD64 + len += 16; +#else + len += 8; +#endif + while (len > 0) + { + print_space (); + --len; + } + + minfo (_("%W (size before relaxing)\n"), i->_raw_size); + } + + bfd_link_hash_traverse (link_info.hash, print_one_symbol, (PTR) i); + + print_dot = i->output_section->vma + i->output_offset + size; + } + } +} + +static void +print_fill_statement (fill) + lang_fill_statement_type * fill; +{ + fprintf (config.map_file, " FILL mask 0x%x\n", fill->fill); +} + +static void +print_data_statement (data) + lang_data_statement_type * data; +{ + int i; + bfd_vma addr; + bfd_size_type size; + const char *name; + + for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) + print_space (); + + addr = data->output_vma; + if (data->output_section != NULL) + addr += data->output_section->vma; + + switch (data->type) + { + default: + abort (); + case BYTE: + size = BYTE_SIZE; + name = "BYTE"; + break; + case SHORT: + size = SHORT_SIZE; + name = "SHORT"; + break; + case LONG: + size = LONG_SIZE; + name = "LONG"; + break; + case QUAD: + size = QUAD_SIZE; + name = "QUAD"; + break; + case SQUAD: + size = QUAD_SIZE; + name = "SQUAD"; + break; + } + + minfo ("0x%V %W %s 0x%v", addr, size, name, data->value); + + if (data->exp->type.node_class != etree_value) + { + print_space (); + exp_print_tree (data->exp); + } + + print_nl (); + + print_dot = addr + size; +} + +/* Print an address statement. These are generated by options like + -Ttext. */ + +static void +print_address_statement (address) + lang_address_statement_type *address; +{ + minfo (_("Address of section %s set to "), address->section_name); + exp_print_tree (address->address); + print_nl (); +} + +/* Print a reloc statement. */ + +static void +print_reloc_statement (reloc) + lang_reloc_statement_type *reloc; +{ + int i; + bfd_vma addr; + bfd_size_type size; + + for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) + print_space (); + + addr = reloc->output_vma; + if (reloc->output_section != NULL) + addr += reloc->output_section->vma; + + size = bfd_get_reloc_size (reloc->howto); + + minfo ("0x%V %W RELOC %s ", addr, size, reloc->howto->name); + + if (reloc->name != NULL) + minfo ("%s+", reloc->name); + else + minfo ("%s+", reloc->section->name); + + exp_print_tree (reloc->addend_exp); + + print_nl (); + + print_dot = addr + size; +} + +static void +print_padding_statement (s) + lang_padding_statement_type *s; +{ + int len; + bfd_vma addr; + + minfo (" *fill*"); + + len = sizeof " *fill*" - 1; + while (len < SECTION_NAME_MAP_LENGTH) + { + print_space (); + ++len; + } + + addr = s->output_offset; + if (s->output_section != NULL) + addr += s->output_section->vma; + minfo ("0x%V %W", addr, s->size); + + if (s->fill != 0) + minfo (" %u", s->fill); + + print_nl (); + + print_dot = addr + s->size; +} + +static void +print_wild_statement (w, os) + lang_wild_statement_type * w; + lang_output_section_statement_type * os; +{ + print_space (); + + if (w->filenames_sorted) + minfo ("SORT("); + if (w->exclude_filename != NULL) + minfo ("EXCLUDE_FILE ( %s )", w->exclude_filename); + if (w->filename != NULL) + minfo ("%s", w->filename); + else + minfo ("*"); + if (w->filenames_sorted) + minfo (")"); + + minfo ("("); + if (w->sections_sorted) + minfo ("SORT("); + if (w->section_name != NULL) + minfo ("%s", w->section_name); + else + minfo ("*"); + if (w->sections_sorted) + minfo (")"); + minfo (")"); + + print_nl (); + + print_statement_list (w->children.head, os); +} + +/* Print a group statement. */ + +static void +print_group (s, os) + lang_group_statement_type *s; + lang_output_section_statement_type *os; +{ + fprintf (config.map_file, "START GROUP\n"); + print_statement_list (s->children.head, os); + fprintf (config.map_file, "END GROUP\n"); +} + +/* Print the list of statements in S. + This can be called for any statement type. */ + +static void +print_statement_list (s, os) + lang_statement_union_type *s; + lang_output_section_statement_type *os; +{ + while (s != NULL) + { + print_statement (s, os); + s = s->next; + } +} + +/* Print the first statement in statement list S. + This can be called for any statement type. */ + +static void +print_statement (s, os) + lang_statement_union_type *s; + lang_output_section_statement_type *os; +{ + switch (s->header.type) + { + default: + fprintf (config.map_file, _("Fail with %d\n"), s->header.type); + FAIL (); + break; + case lang_constructors_statement_enum: + if (constructor_list.head != NULL) + { + if (constructors_sorted) + minfo (" SORT (CONSTRUCTORS)\n"); + else + minfo (" CONSTRUCTORS\n"); + print_statement_list (constructor_list.head, os); + } + break; + case lang_wild_statement_enum: + print_wild_statement (&s->wild_statement, os); + break; + case lang_address_statement_enum: + print_address_statement (&s->address_statement); + break; + case lang_object_symbols_statement_enum: + minfo (" CREATE_OBJECT_SYMBOLS\n"); + break; + case lang_fill_statement_enum: + print_fill_statement (&s->fill_statement); + break; + case lang_data_statement_enum: + print_data_statement (&s->data_statement); + break; + case lang_reloc_statement_enum: + print_reloc_statement (&s->reloc_statement); + break; + case lang_input_section_enum: + print_input_section (&s->input_section); + break; + case lang_padding_statement_enum: + print_padding_statement (&s->padding_statement); + break; + case lang_output_section_statement_enum: + print_output_section_statement (&s->output_section_statement); + break; + case lang_assignment_statement_enum: + print_assignment (&s->assignment_statement, os); + break; + case lang_target_statement_enum: + fprintf (config.map_file, "TARGET(%s)\n", s->target_statement.target); + break; + case lang_output_statement_enum: + minfo ("OUTPUT(%s", s->output_statement.name); + if (output_target != NULL) + minfo (" %s", output_target); + minfo (")\n"); + break; + case lang_input_statement_enum: + print_input_statement (&s->input_statement); + break; + case lang_group_statement_enum: + print_group (&s->group_statement, os); + break; + case lang_afile_asection_pair_statement_enum: + FAIL (); + break; + } +} + +static void +print_statements () +{ + print_statement_list (statement_list.head, abs_output_section); +} + +/* Print the first N statements in statement list S to STDERR. + If N == 0, nothing is printed. + If N < 0, the entire list is printed. + Intended to be called from GDB. */ + +void +dprint_statement (s, n) + lang_statement_union_type * s; + int n; +{ + FILE *map_save = config.map_file; + + config.map_file = stderr; + + if (n < 0) + print_statement_list (s, abs_output_section); + else + { + while (s && --n >= 0) + { + print_statement (s, abs_output_section); + s = s->next; + } + } + + config.map_file = map_save; +} + +static bfd_vma +insert_pad (this_ptr, fill, power, output_section_statement, dot) + lang_statement_union_type ** this_ptr; + fill_type fill; + unsigned int power; + asection * output_section_statement; + bfd_vma dot; +{ + /* Align this section first to the + input sections requirement, then + to the output section's requirement. + If this alignment is > than any seen before, + then record it too. Perform the alignment by + inserting a magic 'padding' statement. + */ + + unsigned int alignment_needed = align_power (dot, power) - dot; + + if (alignment_needed != 0) + { + lang_statement_union_type *new = + ((lang_statement_union_type *) + stat_alloc (sizeof (lang_padding_statement_type))); + + /* Link into existing chain */ + new->header.next = *this_ptr; + *this_ptr = new; + new->header.type = lang_padding_statement_enum; + new->padding_statement.output_section = output_section_statement; + new->padding_statement.output_offset = + dot - output_section_statement->vma; + new->padding_statement.fill = fill; + new->padding_statement.size = alignment_needed; + } + + + /* Remember the most restrictive alignment */ + if (power > output_section_statement->alignment_power) + { + output_section_statement->alignment_power = power; + } + output_section_statement->_raw_size += alignment_needed; + return alignment_needed + dot; + +} + +/* Work out how much this section will move the dot point */ +static bfd_vma +size_input_section (this_ptr, output_section_statement, fill, dot, relax) + lang_statement_union_type ** this_ptr; + lang_output_section_statement_type * output_section_statement; + fill_type fill; + bfd_vma dot; + boolean relax; +{ + lang_input_section_type *is = &((*this_ptr)->input_section); + asection *i = is->section; + + if (is->ifile->just_syms_flag == false) + { + if (output_section_statement->subsection_alignment != -1) + i->alignment_power = + output_section_statement->subsection_alignment; + + dot = insert_pad (this_ptr, fill, i->alignment_power, + output_section_statement->bfd_section, dot); + + /* Remember where in the output section this input section goes */ + + i->output_offset = dot - output_section_statement->bfd_section->vma; + + /* Mark how big the output section must be to contain this now + */ + if (i->_cooked_size != 0) + dot += i->_cooked_size; + else + dot += i->_raw_size; + output_section_statement->bfd_section->_raw_size = dot - output_section_statement->bfd_section->vma; + } + else + { + i->output_offset = i->vma - output_section_statement->bfd_section->vma; + } + + return dot; +} + +/* Check to see if any allocated sections overlap with other allocated + sections. This can happen when the linker script specifically specifies + the output section addresses of the two sections. */ +static void +lang_check_section_addresses () +{ + asection * s; + + /* Scan all sections in the output list. */ + for (s = output_bfd->sections; s != NULL; s = s->next) + /* Ignore sections which are not loaded or which have no contents. */ + if ((bfd_get_section_flags (output_bfd, s) & (SEC_ALLOC | SEC_LOAD)) + && bfd_section_size (output_bfd, s) != 0) + { + asection * os; + + /* Once we reach section 's' stop our seach. This prevents two + warning messages from being produced, one for 'section A overlaps + section B' and one for 'section B overlaps section A'. */ + for (os = output_bfd->sections; os != s; os = os->next) + { + bfd_vma s_start; + bfd_vma s_end; + bfd_vma os_start; + bfd_vma os_end; + + /* Only consider loadable sections with real contents. */ + if (((bfd_get_section_flags (output_bfd, os) + & (SEC_ALLOC | SEC_LOAD)) == 0) + || bfd_section_size (output_bfd, os) == 0) + continue; + + /* We must check the sections' LMA addresses not their + VMA addresses because overlay sections can have + overlapping VMAs but they must have distinct LMAs. */ + s_start = bfd_section_lma (output_bfd, s); + os_start = bfd_section_lma (output_bfd, os); + s_end = s_start + bfd_section_size (output_bfd, s) - 1; + os_end = os_start + bfd_section_size (output_bfd, os) - 1; + + /* Look for an overlap. */ + if ((s_end < os_start) || (s_start > os_end)) + continue; + + einfo ( +_("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"), + s->name, s_start, s_end, os->name, os_start, os_end); + + /* Once we have found one overlap for this section, + stop looking for others. */ + break; + } + } +} + +/* This variable indicates whether bfd_relax_section should be called + again. */ + +static boolean relax_again; + +/* Set the sizes for all the output sections. */ + +bfd_vma +lang_size_sections (s, output_section_statement, prev, fill, dot, relax) + lang_statement_union_type * s; + lang_output_section_statement_type * output_section_statement; + lang_statement_union_type ** prev; + fill_type fill; + bfd_vma dot; + boolean relax; +{ + /* Size up the sections from their constituent parts. */ + for (; s != (lang_statement_union_type *) NULL; s = s->next) + { + switch (s->header.type) + { + case lang_output_section_statement_enum: + { + bfd_vma after; + lang_output_section_statement_type *os = &s->output_section_statement; + + if (os->bfd_section == NULL) + /* This section was never actually created. */ + break; + + /* If this is a COFF shared library section, use the size and + address from the input section. FIXME: This is COFF + specific; it would be cleaner if there were some other way + to do this, but nothing simple comes to mind. */ + if ((os->bfd_section->flags & SEC_COFF_SHARED_LIBRARY) != 0) + { + asection * input; + + if (os->children.head == NULL + || os->children.head->next != NULL + || os->children.head->header.type != lang_input_section_enum) + einfo (_("%P%X: Internal error on COFF shared library section %s\n"), + os->name); + + input = os->children.head->input_section.section; + bfd_set_section_vma (os->bfd_section->owner, + os->bfd_section, + bfd_section_vma (input->owner, input)); + os->bfd_section->_raw_size = input->_raw_size; + break; + } + + if (bfd_is_abs_section (os->bfd_section)) + { + /* No matter what happens, an abs section starts at zero. */ + ASSERT (os->bfd_section->vma == 0); + } + else + { + if (os->addr_tree == (etree_type *) NULL) + { + /* No address specified for this section, get one + from the region specification. */ + if (os->region == (lang_memory_region_type *) NULL + || (((bfd_get_section_flags (output_bfd, os->bfd_section) + & (SEC_ALLOC | SEC_LOAD)) != 0) + && os->region->name[0] == '*' + && strcmp (os->region->name, "*default*") == 0)) + { + os->region = lang_memory_default (os->bfd_section); + } + + /* If a loadable section is using the default memory + region, and some non default memory regions were + defined, issue a warning. */ + if ((bfd_get_section_flags (output_bfd, os->bfd_section) + & (SEC_ALLOC | SEC_LOAD)) != 0 + && ! link_info.relocateable + && strcmp (os->region->name, "*default*") == 0 + && lang_memory_region_list != NULL + && (strcmp (lang_memory_region_list->name, "*default*") != 0 + || lang_memory_region_list->next != NULL)) + einfo (_("%P: warning: no memory region specified for section `%s'\n"), + bfd_get_section_name (output_bfd, os->bfd_section)); + + dot = os->region->current; + + if (os->section_alignment == -1) + { + bfd_vma olddot; + + olddot = dot; + dot = align_power (dot, os->bfd_section->alignment_power); + + if (dot != olddot && config.warn_section_align) + einfo (_("%P: warning: changing start of section %s by %u bytes\n"), + os->name, (unsigned int) (dot - olddot)); + } + } + else + { + etree_value_type r; + + r = exp_fold_tree (os->addr_tree, + abs_output_section, + lang_allocating_phase_enum, + dot, &dot); + if (r.valid_p == false) + { + einfo (_("%F%S: non constant address expression for section %s\n"), + os->name); + } + dot = r.value + r.section->bfd_section->vma; + } + + /* The section starts here. + First, align to what the section needs. */ + + if (os->section_alignment != -1) + dot = align_power (dot, os->section_alignment); + + bfd_set_section_vma (0, os->bfd_section, dot); + + os->bfd_section->output_offset = 0; + } + + (void) lang_size_sections (os->children.head, os, &os->children.head, + os->fill, dot, relax); + + /* Ignore the size of the input sections, use the vma and size to + align against. */ + + after = ALIGN_N (os->bfd_section->vma + + os->bfd_section->_raw_size, + /* The coercion here is important, see ld.h. */ + (bfd_vma) os->block_value); + + if (bfd_is_abs_section (os->bfd_section)) + ASSERT (after == os->bfd_section->vma); + else + os->bfd_section->_raw_size = after - os->bfd_section->vma; + dot = os->bfd_section->vma + os->bfd_section->_raw_size; + os->processed = true; + + /* Update dot in the region ? + We only do this if the section is going to be allocated, + since unallocated sections do not contribute to the region's + overall size in memory. */ + if (os->region != (lang_memory_region_type *) NULL + && (bfd_get_section_flags (output_bfd, os->bfd_section) + & (SEC_ALLOC | SEC_LOAD))) + { + os->region->current = dot; + + /* Make sure this isn't silly. */ + if (os->region->current < os->region->origin + || (os->region->current - os->region->origin + > os->region->length)) + { + if (os->addr_tree != (etree_type *) NULL) + { + einfo (_("%X%P: address 0x%v of %B section %s is not within region %s\n"), + os->region->current, + os->bfd_section->owner, + os->bfd_section->name, + os->region->name); + } + else + { + einfo (_("%X%P: region %s is full (%B section %s)\n"), + os->region->name, + os->bfd_section->owner, + os->bfd_section->name); + } + /* Reset the region pointer. */ + os->region->current = os->region->origin; + } + } + } + break; + + case lang_constructors_statement_enum: + dot = lang_size_sections (constructor_list.head, + output_section_statement, + &s->wild_statement.children.head, + fill, + dot, relax); + break; + + case lang_data_statement_enum: + { + unsigned int size = 0; + + s->data_statement.output_vma = dot - output_section_statement->bfd_section->vma; + s->data_statement.output_section = + output_section_statement->bfd_section; + + switch (s->data_statement.type) + { + case QUAD: + case SQUAD: + size = QUAD_SIZE; + break; + case LONG: + size = LONG_SIZE; + break; + case SHORT: + size = SHORT_SIZE; + break; + case BYTE: + size = BYTE_SIZE; + break; + } + + dot += size; + output_section_statement->bfd_section->_raw_size += size; + /* The output section gets contents, and then we inspect for + any flags set in the input script which override any ALLOC. */ + output_section_statement->bfd_section->flags |= SEC_HAS_CONTENTS; + if (!(output_section_statement->flags & SEC_NEVER_LOAD)) { + output_section_statement->bfd_section->flags |= SEC_ALLOC | SEC_LOAD; + } + } + break; + + case lang_reloc_statement_enum: + { + int size; + + s->reloc_statement.output_vma = + dot - output_section_statement->bfd_section->vma; + s->reloc_statement.output_section = + output_section_statement->bfd_section; + size = bfd_get_reloc_size (s->reloc_statement.howto); + dot += size; + output_section_statement->bfd_section->_raw_size += size; + } + break; + + case lang_wild_statement_enum: + + dot = lang_size_sections (s->wild_statement.children.head, + output_section_statement, + &s->wild_statement.children.head, + + fill, dot, relax); + + break; + + case lang_object_symbols_statement_enum: + link_info.create_object_symbols_section = + output_section_statement->bfd_section; + break; + case lang_output_statement_enum: + case lang_target_statement_enum: + break; + case lang_input_section_enum: + { + asection *i; + + i = (*prev)->input_section.section; + if (! relax) + { + if (i->_cooked_size == 0) + i->_cooked_size = i->_raw_size; + } + else + { + boolean again; + + if (! bfd_relax_section (i->owner, i, &link_info, &again)) + einfo (_("%P%F: can't relax section: %E\n")); + if (again) + relax_again = true; + } + dot = size_input_section (prev, + output_section_statement, + output_section_statement->fill, + dot, relax); + } + break; + case lang_input_statement_enum: + break; + case lang_fill_statement_enum: + s->fill_statement.output_section = output_section_statement->bfd_section; + + fill = s->fill_statement.fill; + break; + case lang_assignment_statement_enum: + { + bfd_vma newdot = dot; + + exp_fold_tree (s->assignment_statement.exp, + output_section_statement, + lang_allocating_phase_enum, + dot, + &newdot); + + if (newdot != dot) + { + /* The assignment changed dot. Insert a pad. */ + if (output_section_statement == abs_output_section) + { + /* If we don't have an output section, then just adjust + the default memory address. */ + lang_memory_region_lookup ("*default*")->current = newdot; + } + else if (!relax) + { + lang_statement_union_type *new = + ((lang_statement_union_type *) + stat_alloc (sizeof (lang_padding_statement_type))); + + /* Link into existing chain. */ + new->header.next = *prev; + *prev = new; + new->header.type = lang_padding_statement_enum; + new->padding_statement.output_section = + output_section_statement->bfd_section; + new->padding_statement.output_offset = + dot - output_section_statement->bfd_section->vma; + new->padding_statement.fill = fill; + new->padding_statement.size = newdot - dot; + output_section_statement->bfd_section->_raw_size += + new->padding_statement.size; + } + + dot = newdot; + } + } + break; + + case lang_padding_statement_enum: + /* If we are relaxing, and this is not the first pass, some + padding statements may have been inserted during previous + passes. We may have to move the padding statement to a new + location if dot has a different value at this point in this + pass than it did at this point in the previous pass. */ + s->padding_statement.output_offset = + dot - output_section_statement->bfd_section->vma; + dot += s->padding_statement.size; + output_section_statement->bfd_section->_raw_size += + s->padding_statement.size; + break; + + case lang_group_statement_enum: + dot = lang_size_sections (s->group_statement.children.head, + output_section_statement, + &s->group_statement.children.head, + fill, dot, relax); + break; + + default: + FAIL (); + break; + + /* This can only get here when relaxing is turned on. */ + + case lang_address_statement_enum: + break; + } + prev = &s->header.next; + } + return dot; +} + +bfd_vma +lang_do_assignments (s, output_section_statement, fill, dot) + lang_statement_union_type * s; + lang_output_section_statement_type * output_section_statement; + fill_type fill; + bfd_vma dot; +{ + for (; s != (lang_statement_union_type *) NULL; s = s->next) + { + switch (s->header.type) + { + case lang_constructors_statement_enum: + dot = lang_do_assignments (constructor_list.head, + output_section_statement, + fill, + dot); + break; + + case lang_output_section_statement_enum: + { + lang_output_section_statement_type *os = + &(s->output_section_statement); + + if (os->bfd_section != NULL) + { + dot = os->bfd_section->vma; + (void) lang_do_assignments (os->children.head, os, + os->fill, dot); + dot = os->bfd_section->vma + os->bfd_section->_raw_size; + } + if (os->load_base) + { + /* If nothing has been placed into the output section then + it won't have a bfd_section. */ + if (os->bfd_section) + { + os->bfd_section->lma + = exp_get_abs_int(os->load_base, 0,"load base", lang_final_phase_enum); + } + } + } + break; + case lang_wild_statement_enum: + + dot = lang_do_assignments (s->wild_statement.children.head, + output_section_statement, + fill, dot); + + break; + + case lang_object_symbols_statement_enum: + case lang_output_statement_enum: + case lang_target_statement_enum: +#if 0 + case lang_common_statement_enum: +#endif + break; + case lang_data_statement_enum: + { + etree_value_type value; + + value = exp_fold_tree (s->data_statement.exp, + abs_output_section, + lang_final_phase_enum, dot, &dot); + s->data_statement.value = value.value; + if (value.valid_p == false) + einfo (_("%F%P: invalid data statement\n")); + } + switch (s->data_statement.type) + { + case QUAD: + case SQUAD: + dot += QUAD_SIZE; + break; + case LONG: + dot += LONG_SIZE; + break; + case SHORT: + dot += SHORT_SIZE; + break; + case BYTE: + dot += BYTE_SIZE; + break; + } + break; + + case lang_reloc_statement_enum: + { + etree_value_type value; + + value = exp_fold_tree (s->reloc_statement.addend_exp, + abs_output_section, + lang_final_phase_enum, dot, &dot); + s->reloc_statement.addend_value = value.value; + if (value.valid_p == false) + einfo (_("%F%P: invalid reloc statement\n")); + } + dot += bfd_get_reloc_size (s->reloc_statement.howto); + break; + + case lang_input_section_enum: + { + asection *in = s->input_section.section; + + if (in->_cooked_size != 0) + dot += in->_cooked_size; + else + dot += in->_raw_size; + } + break; + + case lang_input_statement_enum: + break; + case lang_fill_statement_enum: + fill = s->fill_statement.fill; + break; + case lang_assignment_statement_enum: + { + exp_fold_tree (s->assignment_statement.exp, + output_section_statement, + lang_final_phase_enum, + dot, + &dot); + } + + break; + case lang_padding_statement_enum: + dot += s->padding_statement.size; + break; + + case lang_group_statement_enum: + dot = lang_do_assignments (s->group_statement.children.head, + output_section_statement, + fill, dot); + + break; + + default: + FAIL (); + break; + case lang_address_statement_enum: + break; + } + + } + return dot; +} + +/* Fix any .startof. or .sizeof. symbols. When the assemblers see the + operator .startof. (section_name), it produces an undefined symbol + .startof.section_name. Similarly, when it sees + .sizeof. (section_name), it produces an undefined symbol + .sizeof.section_name. For all the output sections, we look for + such symbols, and set them to the correct value. */ + +static void +lang_set_startof () +{ + asection *s; + + if (link_info.relocateable) + return; + + for (s = output_bfd->sections; s != NULL; s = s->next) + { + const char *secname; + char *buf; + struct bfd_link_hash_entry *h; + + secname = bfd_get_section_name (output_bfd, s); + buf = xmalloc (10 + strlen (secname)); + + sprintf (buf, ".startof.%s", secname); + h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true); + if (h != NULL && h->type == bfd_link_hash_undefined) + { + h->type = bfd_link_hash_defined; + h->u.def.value = bfd_get_section_vma (output_bfd, s); + h->u.def.section = bfd_abs_section_ptr; + } + + sprintf (buf, ".sizeof.%s", secname); + h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true); + if (h != NULL && h->type == bfd_link_hash_undefined) + { + h->type = bfd_link_hash_defined; + if (s->_cooked_size != 0) + h->u.def.value = s->_cooked_size; + else + h->u.def.value = s->_raw_size; + h->u.def.section = bfd_abs_section_ptr; + } + + free (buf); + } +} + +static void +lang_finish () +{ + struct bfd_link_hash_entry *h; + boolean warn; + + if (link_info.relocateable || link_info.shared) + warn = false; + else + warn = true; + + if (entry_symbol == (char *) NULL) + { + /* No entry has been specified. Look for start, but don't warn + if we don't find it. */ + entry_symbol = "start"; + warn = false; + } + + h = bfd_link_hash_lookup (link_info.hash, entry_symbol, false, false, true); + if (h != (struct bfd_link_hash_entry *) NULL + && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak) + && h->u.def.section->output_section != NULL) + { + bfd_vma val; + + val = (h->u.def.value + + bfd_get_section_vma (output_bfd, + h->u.def.section->output_section) + + h->u.def.section->output_offset); + if (! bfd_set_start_address (output_bfd, val)) + einfo (_("%P%F:%s: can't set start address\n"), entry_symbol); + } + else + { + bfd_vma val; + CONST char *send; + + /* We couldn't find the entry symbol. Try parsing it as a + number. */ + val = bfd_scan_vma (entry_symbol, &send, 0); + if (*send == '\0') + { + if (! bfd_set_start_address (output_bfd, val)) + einfo (_("%P%F: can't set start address\n")); + } + else + { + asection *ts; + + /* Can't find the entry symbol, and it's not a number. Use + the first address in the text section. */ + ts = bfd_get_section_by_name (output_bfd, ".text"); + if (ts != (asection *) NULL) + { + if (warn) + einfo (_("%P: warning: cannot find entry symbol %s; defaulting to %V\n"), + entry_symbol, bfd_get_section_vma (output_bfd, ts)); + if (! bfd_set_start_address (output_bfd, + bfd_get_section_vma (output_bfd, + ts))) + einfo (_("%P%F: can't set start address\n")); + } + else + { + if (warn) + einfo (_("%P: warning: cannot find entry symbol %s; not setting start address\n"), + entry_symbol); + } + } + } +} + +/* This is a small function used when we want to ignore errors from + BFD. */ + +static void +#ifdef ANSI_PROTOTYPES +ignore_bfd_errors (const char *s, ...) +#else +ignore_bfd_errors (s) + const char *s; +#endif +{ + /* Don't do anything. */ +} + +/* Check that the architecture of all the input files is compatible + with the output file. Also call the backend to let it do any + other checking that is needed. */ + +static void +lang_check () +{ + lang_statement_union_type *file; + bfd *input_bfd; + CONST bfd_arch_info_type *compatible; + + for (file = file_chain.head; + file != (lang_statement_union_type *) NULL; + file = file->input_statement.next) + { + input_bfd = file->input_statement.the_bfd; + compatible = bfd_arch_get_compatible (input_bfd, + output_bfd); + if (compatible == NULL) + { + if (command_line.warn_mismatch) + einfo (_("%P: warning: %s architecture of input file `%B' is incompatible with %s output\n"), + bfd_printable_name (input_bfd), input_bfd, + bfd_printable_name (output_bfd)); + } + else + { + bfd_error_handler_type pfn = NULL; + + /* If we aren't supposed to warn about mismatched input + files, temporarily set the BFD error handler to a + function which will do nothing. We still want to call + bfd_merge_private_bfd_data, since it may set up + information which is needed in the output file. */ + if (! command_line.warn_mismatch) + pfn = bfd_set_error_handler (ignore_bfd_errors); + if (! bfd_merge_private_bfd_data (input_bfd, output_bfd)) + { + if (command_line.warn_mismatch) + einfo (_("%E%X: failed to merge target specific data of file %B\n"), + input_bfd); + } + if (! command_line.warn_mismatch) + bfd_set_error_handler (pfn); + } + } +} + +/* Look through all the global common symbols and attach them to the + correct section. The -sort-common command line switch may be used + to roughly sort the entries by size. */ + +static void +lang_common () +{ + if (link_info.relocateable + && ! command_line.force_common_definition) + return; + + if (! config.sort_common) + bfd_link_hash_traverse (link_info.hash, lang_one_common, (PTR) NULL); + else + { + int power; + + for (power = 4; power >= 0; power--) + bfd_link_hash_traverse (link_info.hash, lang_one_common, + (PTR) &power); + } +} + +/* Place one common symbol in the correct section. */ + +static boolean +lang_one_common (h, info) + struct bfd_link_hash_entry *h; + PTR info; +{ + unsigned int power_of_two; + bfd_vma size; + asection *section; + + if (h->type != bfd_link_hash_common) + return true; + + size = h->u.c.size; + power_of_two = h->u.c.p->alignment_power; + + if (config.sort_common + && power_of_two < (unsigned int) *(int *) info) + return true; + + section = h->u.c.p->section; + + /* Increase the size of the section. */ + section->_cooked_size = ALIGN_N (section->_cooked_size, + (bfd_size_type) (1 << power_of_two)); + + /* Adjust the alignment if necessary. */ + if (power_of_two > section->alignment_power) + section->alignment_power = power_of_two; + + /* Change the symbol from common to defined. */ + h->type = bfd_link_hash_defined; + h->u.def.section = section; + h->u.def.value = section->_cooked_size; + + /* Increase the size of the section. */ + section->_cooked_size += size; + + /* Make sure the section is allocated in memory, and make sure that + it is no longer a common section. */ + section->flags |= SEC_ALLOC; + section->flags &= ~ SEC_IS_COMMON; + + if (config.map_file != NULL) + { + static boolean header_printed; + int len; + char *name; + char buf[50]; + + if (! header_printed) + { + minfo (_("\nAllocating common symbols\n")); + minfo (_("Common symbol size file\n\n")); + header_printed = true; + } + + name = demangle (h->root.string); + minfo ("%s", name); + len = strlen (name); + free (name); + + if (len >= 19) + { + print_nl (); + len = 0; + } + while (len < 20) + { + print_space (); + ++len; + } + + minfo ("0x"); + if (size <= 0xffffffff) + sprintf (buf, "%lx", (unsigned long) size); + else + sprintf_vma (buf, size); + minfo ("%s", buf); + len = strlen (buf); + + while (len < 16) + { + print_space (); + ++len; + } + + minfo ("%B\n", section->owner); + } + + return true; +} + +/* +run through the input files and ensure that every input +section has somewhere to go. If one is found without +a destination then create an input request and place it +into the statement tree. +*/ + +static void +lang_place_orphans () +{ + lang_input_statement_type *file; + + for (file = (lang_input_statement_type *) file_chain.head; + file != (lang_input_statement_type *) NULL; + file = (lang_input_statement_type *) file->next) + { + asection *s; + + for (s = file->the_bfd->sections; + s != (asection *) NULL; + s = s->next) + { + if (s->output_section == (asection *) NULL) + { + /* This section of the file is not attatched, root + around for a sensible place for it to go */ + + if (file->just_syms_flag) + { + /* We are only retrieving symbol values from this + file. We want the symbols to act as though the + values in the file are absolute. */ + s->output_section = bfd_abs_section_ptr; + s->output_offset = s->vma; + } + else if (strcmp (s->name, "COMMON") == 0) + { + /* This is a lonely common section which must have + come from an archive. We attach to the section + with the wildcard. */ + if (! link_info.relocateable + || command_line.force_common_definition) + { + if (default_common_section == NULL) + { +#if 0 + /* This message happens when using the + svr3.ifile linker script, so I have + disabled it. */ + info_msg (_("%P: no [COMMON] command, defaulting to .bss\n")); +#endif + default_common_section = + lang_output_section_statement_lookup (".bss"); + + } + wild_doit (&default_common_section->children, s, + default_common_section, file); + } + } + else if (ldemul_place_orphan (file, s)) + ; + else + { + lang_output_section_statement_type *os = + lang_output_section_statement_lookup (s->name); + + wild_doit (&os->children, s, os, file); + } + } + } + } +} + + +void +lang_set_flags (ptr, flags) + lang_memory_region_type *ptr; + CONST char *flags; +{ + flagword *ptr_flags = &ptr->flags; + + ptr->flags = ptr->not_flags = 0; + while (*flags) + { + switch (*flags) + { + case '!': + ptr_flags = (ptr_flags == &ptr->flags) ? &ptr->not_flags : &ptr->flags; + break; + + case 'A': case 'a': + *ptr_flags |= SEC_ALLOC; + break; + + case 'R': case 'r': + *ptr_flags |= SEC_READONLY; + break; + + case 'W': case 'w': + *ptr_flags |= SEC_DATA; + break; + + case 'X': case 'x': + *ptr_flags |= SEC_CODE; + break; + + case 'L': case 'l': + case 'I': case 'i': + *ptr_flags |= SEC_LOAD; + break; + + default: + einfo (_("%P%F: invalid syntax in flags\n")); + break; + } + flags++; + } +} + +/* Call a function on each input file. This function will be called + on an archive, but not on the elements. */ + +void +lang_for_each_input_file (func) + void (*func) PARAMS ((lang_input_statement_type *)); +{ + lang_input_statement_type *f; + + for (f = (lang_input_statement_type *) input_file_chain.head; + f != NULL; + f = (lang_input_statement_type *) f->next_real_file) + func (f); +} + +/* Call a function on each file. The function will be called on all + the elements of an archive which are included in the link, but will + not be called on the archive file itself. */ + +void +lang_for_each_file (func) + void (*func) PARAMS ((lang_input_statement_type *)); +{ + lang_input_statement_type *f; + + for (f = (lang_input_statement_type *) file_chain.head; + f != (lang_input_statement_type *) NULL; + f = (lang_input_statement_type *) f->next) + { + func (f); + } +} + +#if 0 + +/* Not used. */ + +void +lang_for_each_input_section (func) + void (*func) PARAMS ((bfd * ab, asection * as)); +{ + lang_input_statement_type *f; + + for (f = (lang_input_statement_type *) file_chain.head; + f != (lang_input_statement_type *) NULL; + f = (lang_input_statement_type *) f->next) + { + asection *s; + + for (s = f->the_bfd->sections; + s != (asection *) NULL; + s = s->next) + { + func (f->the_bfd, s); + } + } +} + +#endif + +void +ldlang_add_file (entry) + lang_input_statement_type * entry; +{ + bfd **pp; + + lang_statement_append (&file_chain, + (lang_statement_union_type *) entry, + &entry->next); + + /* The BFD linker needs to have a list of all input BFDs involved in + a link. */ + ASSERT (entry->the_bfd->link_next == (bfd *) NULL); + ASSERT (entry->the_bfd != output_bfd); + for (pp = &link_info.input_bfds; + *pp != (bfd *) NULL; + pp = &(*pp)->link_next) + ; + *pp = entry->the_bfd; + entry->the_bfd->usrdata = (PTR) entry; + bfd_set_gp_size (entry->the_bfd, g_switch_value); + + /* Look through the sections and check for any which should not be + included in the link. We need to do this now, so that we can + notice when the backend linker tries to report multiple + definition errors for symbols which are in sections we aren't + going to link. FIXME: It might be better to entirely ignore + symbols which are defined in sections which are going to be + discarded. This would require modifying the backend linker for + each backend which might set the SEC_LINK_ONCE flag. If we do + this, we should probably handle SEC_EXCLUDE in the same way. */ + + bfd_map_over_sections (entry->the_bfd, section_already_linked, (PTR) entry); +} + +void +lang_add_output (name, from_script) + CONST char *name; + int from_script; +{ + /* Make -o on command line override OUTPUT in script. */ + if (had_output_filename == false || !from_script) + { + output_filename = name; + had_output_filename = true; + } +} + + +static lang_output_section_statement_type *current_section; + +static int +topower (x) + int x; +{ + unsigned int i = 1; + int l; + + if (x < 0) + return -1; + + for (l = 0; l < 32; l++) + { + if (i >= (unsigned int) x) + return l; + i <<= 1; + } + + return 0; +} + +void +lang_enter_output_section_statement (output_section_statement_name, + address_exp, sectype, block_value, + align, subalign, ebase) + const char *output_section_statement_name; + etree_type * address_exp; + enum section_type sectype; + bfd_vma block_value; + etree_type *align; + etree_type *subalign; + etree_type *ebase; +{ + lang_output_section_statement_type *os; + + current_section = + os = + lang_output_section_statement_lookup (output_section_statement_name); + + + + /* Add this statement to tree */ + /* add_statement(lang_output_section_statement_enum, + output_section_statement);*/ + /* Make next things chain into subchain of this */ + + if (os->addr_tree == + (etree_type *) NULL) + { + os->addr_tree = + address_exp; + } + os->sectype = sectype; + if (sectype != noload_section) + os->flags = SEC_NO_FLAGS; + else + os->flags = SEC_NEVER_LOAD; + os->block_value = block_value ? block_value : 1; + stat_ptr = &os->children; + + os->subsection_alignment = topower( + exp_get_value_int(subalign, -1, + "subsection alignment", + 0)); + os->section_alignment = topower( + exp_get_value_int(align, -1, + "section alignment", 0)); + + os->load_base = ebase; +} + + +void +lang_final () +{ + lang_output_statement_type *new = + new_stat (lang_output_statement, stat_ptr); + + new->name = output_filename; +} + +/* Reset the current counters in the regions */ +static void +reset_memory_regions () +{ + lang_memory_region_type *p = lang_memory_region_list; + + for (p = lang_memory_region_list; + p != (lang_memory_region_type *) NULL; + p = p->next) + { + p->old_length = (bfd_size_type) (p->current - p->origin); + p->current = p->origin; + } +} + +/* ??? At some point this traversal for GC should share code with the + traversal for manipulating the output file. */ + +/* Expand a wild statement for a particular FILE, marking its sections KEEP + as needed. SECTION may be NULL, in which case it is a wild card. */ + +static void +lang_gc_wild_section (ptr, section, file) + lang_wild_statement_type *ptr; + const char *section; + lang_input_statement_type *file; +{ + if (file->just_syms_flag == false) + { + register asection *s; + boolean wildcard; + + if (section == NULL) + wildcard = false; + else + wildcard = wildcardp (section); + + for (s = file->the_bfd->sections; s != NULL; s = s->next) + { + boolean match; + + if (section == NULL) + match = true; + else + { + const char *name; + + name = bfd_get_section_name (file->the_bfd, s); + if (wildcard) + match = fnmatch (section, name, 0) == 0 ? true : false; + else + match = strcmp (section, name) == 0 ? true : false; + } + + if (match) + { + /* If the wild pattern was marked KEEP, the member sections + should be as well. */ + if (ptr->keep_sections) + s->flags |= SEC_KEEP; + } + } + } +} + +/* Handle a wild statement for a single file F. */ + +static void +lang_gc_wild_file (s, section, f) + lang_wild_statement_type *s; + const char *section; + lang_input_statement_type *f; +{ + if (f->the_bfd == NULL + || ! bfd_check_format (f->the_bfd, bfd_archive)) + lang_gc_wild_section (s, section, f); + else + { + bfd *member; + + /* This is an archive file. We must map each member of the + archive separately. */ + member = bfd_openr_next_archived_file (f->the_bfd, (bfd *) NULL); + while (member != NULL) + { + /* When lookup_name is called, it will call the add_symbols + entry point for the archive. For each element of the + archive which is included, BFD will call ldlang_add_file, + which will set the usrdata field of the member to the + lang_input_statement. */ + if (member->usrdata != NULL) + { + lang_gc_wild_section (s, section, + (lang_input_statement_type *) member->usrdata); + } + + member = bfd_openr_next_archived_file (f->the_bfd, member); + } + } +} + +/* Handle a wild statement, marking it against GC. SECTION or FILE or both + may be NULL, indicating that it is a wildcard. */ + +static void +lang_gc_wild (s, section, file) + lang_wild_statement_type *s; + const char *section; + const char *file; +{ + lang_input_statement_type *f; + + if (file == (char *) NULL) + { + /* Perform the iteration over all files in the list */ + for (f = (lang_input_statement_type *) file_chain.head; + f != (lang_input_statement_type *) NULL; + f = (lang_input_statement_type *) f->next) + { + lang_gc_wild_file (s, section, f); + } + } + else if (wildcardp (file)) + { + for (f = (lang_input_statement_type *) file_chain.head; + f != (lang_input_statement_type *) NULL; + f = (lang_input_statement_type *) f->next) + { + if (fnmatch (file, f->filename, FNM_FILE_NAME) == 0) + lang_gc_wild_file (s, section, f); + } + } + else + { + /* Perform the iteration over a single file */ + f = lookup_name (file); + lang_gc_wild_file (s, section, f); + } +} + +/* Iterate over sections marking them against GC. */ + +static void +lang_gc_sections_1 (s) + lang_statement_union_type * s; +{ + for (; s != (lang_statement_union_type *) NULL; s = s->next) + { + switch (s->header.type) + { + case lang_wild_statement_enum: + lang_gc_wild (&s->wild_statement, + s->wild_statement.section_name, + s->wild_statement.filename); + break; + case lang_constructors_statement_enum: + lang_gc_sections_1 (constructor_list.head); + break; + case lang_output_section_statement_enum: + lang_gc_sections_1 (s->output_section_statement.children.head); + break; + case lang_group_statement_enum: + lang_gc_sections_1 (s->group_statement.children.head); + break; + default: + break; + } + } +} + +static void +lang_gc_sections () +{ + struct bfd_link_hash_entry *h; + ldlang_undef_chain_list_type *ulist, fake_list_start; + + /* Keep all sections so marked in the link script. */ + + lang_gc_sections_1 (statement_list.head); + + /* Keep all sections containing symbols undefined on the command-line. + Handle the entry symbol at the same time. */ + + fake_list_start.next = ldlang_undef_chain_list_head; + if (entry_symbol == NULL) + fake_list_start.name = "start"; + else + fake_list_start.name = (char *) entry_symbol; + + for (ulist = &fake_list_start; ulist; ulist = ulist->next) + { + h = bfd_link_hash_lookup (link_info.hash, ulist->name, + false, false, false); + + if (h != (struct bfd_link_hash_entry *) NULL + && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak) + && ! bfd_is_abs_section (h->u.def.section)) + { + h->u.def.section->flags |= SEC_KEEP; + } + } + + bfd_gc_sections (output_bfd, &link_info); +} + +void +lang_process () +{ + lang_reasonable_defaults (); + current_target = default_target; + + lang_for_each_statement (ldlang_open_output); /* Open the output file */ + + ldemul_create_output_section_statements (); + + /* Add to the hash table all undefineds on the command line */ + lang_place_undefineds (); + + /* Create a bfd for each input file */ + current_target = default_target; + open_input_bfds (statement_list.head, false); + + ldemul_after_open (); + + /* Make sure that we're not mixing architectures. We call this + after all the input files have been opened, but before we do any + other processing, so that any operations merge_private_bfd_data + does on the output file will be known during the rest of the + link. */ + lang_check (); + + /* Handle .exports instead of a version script if we're told to do so. */ + if (command_line.version_exports_section) + lang_do_version_exports_section (); + + /* Build all sets based on the information gathered from the input + files. */ + ldctor_build_sets (); + + /* Remove unreferenced sections if asked to. */ + if (command_line.gc_sections) + lang_gc_sections (); + + /* Size up the common data */ + lang_common (); + + /* Run through the contours of the script and attach input sections + to the correct output sections + */ + map_input_to_output_sections (statement_list.head, (char *) NULL, + (lang_output_section_statement_type *) NULL); + + + /* Find any sections not attached explicitly and handle them */ + lang_place_orphans (); + + ldemul_before_allocation (); + + /* We must record the program headers before we try to fix the + section positions, since they will affect SIZEOF_HEADERS. */ + lang_record_phdrs (); + + /* Now run around and relax if we can */ + if (command_line.relax) + { + /* First time round is a trial run to get the 'worst case' + addresses of the objects if there was no relaxing. */ + lang_size_sections (statement_list.head, + abs_output_section, + &(statement_list.head), 0, (bfd_vma) 0, false); + + /* Keep relaxing until bfd_relax_section gives up. */ + do + { + reset_memory_regions (); + + relax_again = false; + + /* Note: pe-dll.c does something like this also. If you find + you need to change this code, you probably need to change + pe-dll.c also. DJ */ + + /* Do all the assignments with our current guesses as to + section sizes. */ + lang_do_assignments (statement_list.head, + abs_output_section, + (fill_type) 0, (bfd_vma) 0); + + /* Perform another relax pass - this time we know where the + globals are, so can make better guess. */ + lang_size_sections (statement_list.head, + abs_output_section, + &(statement_list.head), 0, (bfd_vma) 0, true); + } + while (relax_again); + } + else + { + /* Size up the sections. */ + lang_size_sections (statement_list.head, + abs_output_section, + &(statement_list.head), 0, (bfd_vma) 0, false); + } + + /* See if anything special should be done now we know how big + everything is. */ + ldemul_after_allocation (); + + /* Fix any .startof. or .sizeof. symbols. */ + lang_set_startof (); + + /* Do all the assignments, now that we know the final restingplaces + of all the symbols */ + + lang_do_assignments (statement_list.head, + abs_output_section, + (fill_type) 0, (bfd_vma) 0); + + /* Make sure that the section addresses make sense. */ + if (! link_info.relocateable + && command_line.check_section_addresses) + lang_check_section_addresses (); + + /* Final stuffs */ + + ldemul_finish (); + lang_finish (); +} + +/* EXPORTED TO YACC */ + +void +lang_add_wild (section_name, sections_sorted, filename, filenames_sorted, + keep_sections, exclude_filename) + const char *const section_name; + boolean sections_sorted; + const char *const filename; + boolean filenames_sorted; + boolean keep_sections; + const char *exclude_filename; +{ + lang_wild_statement_type *new = new_stat (lang_wild_statement, + stat_ptr); + + if (section_name != (char *) NULL && strcmp (section_name, "COMMON") == 0) + { + placed_commons = true; + } + if (filename != NULL && ! wildcardp (filename)) + { + lang_has_input_file = true; + } + new->section_name = section_name; + new->sections_sorted = sections_sorted; + new->filename = filename; + new->filenames_sorted = filenames_sorted; + new->keep_sections = keep_sections; + new->exclude_filename = exclude_filename; + lang_list_init (&new->children); +} + +void +lang_section_start (name, address) + CONST char *name; + etree_type * address; +{ + lang_address_statement_type *ad = new_stat (lang_address_statement, stat_ptr); + + ad->section_name = name; + ad->address = address; +} + +/* Set the start symbol to NAME. CMDLINE is nonzero if this is called + because of a -e argument on the command line, or zero if this is + called by ENTRY in a linker script. Command line arguments take + precedence. */ + +void +lang_add_entry (name, cmdline) + CONST char *name; + boolean cmdline; +{ + if (entry_symbol == NULL + || cmdline + || ! entry_from_cmdline) + { + entry_symbol = name; + entry_from_cmdline = cmdline; + } +} + +void +lang_add_target (name) + CONST char *name; +{ + lang_target_statement_type *new = new_stat (lang_target_statement, + stat_ptr); + + new->target = name; + +} + +void +lang_add_map (name) + CONST char *name; +{ + while (*name) + { + switch (*name) + { + case 'F': + map_option_f = true; + break; + } + name++; + } +} + +void +lang_add_fill (exp) + int exp; +{ + lang_fill_statement_type *new = new_stat (lang_fill_statement, + stat_ptr); + + new->fill = exp; +} + +void +lang_add_data (type, exp) + int type; + union etree_union *exp; +{ + + lang_data_statement_type *new = new_stat (lang_data_statement, + stat_ptr); + + new->exp = exp; + new->type = type; + +} + +/* Create a new reloc statement. RELOC is the BFD relocation type to + generate. HOWTO is the corresponding howto structure (we could + look this up, but the caller has already done so). SECTION is the + section to generate a reloc against, or NAME is the name of the + symbol to generate a reloc against. Exactly one of SECTION and + NAME must be NULL. ADDEND is an expression for the addend. */ + +void +lang_add_reloc (reloc, howto, section, name, addend) + bfd_reloc_code_real_type reloc; + reloc_howto_type *howto; + asection *section; + const char *name; + union etree_union *addend; +{ + lang_reloc_statement_type *p = new_stat (lang_reloc_statement, stat_ptr); + + p->reloc = reloc; + p->howto = howto; + p->section = section; + p->name = name; + p->addend_exp = addend; + + p->addend_value = 0; + p->output_section = NULL; + p->output_vma = 0; +} + +lang_assignment_statement_type * +lang_add_assignment (exp) + etree_type * exp; +{ + lang_assignment_statement_type *new = new_stat (lang_assignment_statement, + stat_ptr); + + new->exp = exp; + return new; +} + +void +lang_add_attribute (attribute) + enum statement_enum attribute; +{ + new_statement (attribute, sizeof (lang_statement_union_type), stat_ptr); +} + +void +lang_startup (name) + CONST char *name; +{ + if (startup_file != (char *) NULL) + { + einfo (_("%P%Fmultiple STARTUP files\n")); + } + first_file->filename = name; + first_file->local_sym_name = name; + first_file->real = true; + + startup_file = name; +} + +void +lang_float (maybe) + boolean maybe; +{ + lang_float_flag = maybe; +} + +void +lang_leave_output_section_statement (fill, memspec, phdrs) + bfd_vma fill; + const char *memspec; + struct lang_output_section_phdr_list *phdrs; +{ + current_section->fill = fill; + current_section->region = lang_memory_region_lookup (memspec); + current_section->phdrs = phdrs; + stat_ptr = &statement_list; +} + +/* + Create an absolute symbol with the given name with the value of the + address of first byte of the section named. + + If the symbol already exists, then do nothing. +*/ +void +lang_abs_symbol_at_beginning_of (secname, name) + const char *secname; + const char *name; +{ + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (link_info.hash, name, true, true, true); + if (h == (struct bfd_link_hash_entry *) NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + + if (h->type == bfd_link_hash_new + || h->type == bfd_link_hash_undefined) + { + asection *sec; + + h->type = bfd_link_hash_defined; + + sec = bfd_get_section_by_name (output_bfd, secname); + if (sec == (asection *) NULL) + h->u.def.value = 0; + else + h->u.def.value = bfd_get_section_vma (output_bfd, sec); + + h->u.def.section = bfd_abs_section_ptr; + } +} + +/* + Create an absolute symbol with the given name with the value of the + address of the first byte after the end of the section named. + + If the symbol already exists, then do nothing. +*/ +void +lang_abs_symbol_at_end_of (secname, name) + const char *secname; + const char *name; +{ + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (link_info.hash, name, true, true, true); + if (h == (struct bfd_link_hash_entry *) NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + + if (h->type == bfd_link_hash_new + || h->type == bfd_link_hash_undefined) + { + asection *sec; + + h->type = bfd_link_hash_defined; + + sec = bfd_get_section_by_name (output_bfd, secname); + if (sec == (asection *) NULL) + h->u.def.value = 0; + else + h->u.def.value = (bfd_get_section_vma (output_bfd, sec) + + bfd_section_size (output_bfd, sec)); + + h->u.def.section = bfd_abs_section_ptr; + } +} + +void +lang_statement_append (list, element, field) + lang_statement_list_type * list; + lang_statement_union_type * element; + lang_statement_union_type ** field; +{ + *(list->tail) = element; + list->tail = field; +} + +/* Set the output format type. -oformat overrides scripts. */ + +void +lang_add_output_format (format, big, little, from_script) + const char *format; + const char *big; + const char *little; + int from_script; +{ + if (output_target == NULL || !from_script) + { + if (command_line.endian == ENDIAN_BIG + && big != NULL) + format = big; + else if (command_line.endian == ENDIAN_LITTLE + && little != NULL) + format = little; + + output_target = format; + } +} + +/* Enter a group. This creates a new lang_group_statement, and sets + stat_ptr to build new statements within the group. */ + +void +lang_enter_group () +{ + lang_group_statement_type *g; + + g = new_stat (lang_group_statement, stat_ptr); + lang_list_init (&g->children); + stat_ptr = &g->children; +} + +/* Leave a group. This just resets stat_ptr to start writing to the + regular list of statements again. Note that this will not work if + groups can occur inside anything else which can adjust stat_ptr, + but currently they can't. */ + +void +lang_leave_group () +{ + stat_ptr = &statement_list; +} + +/* Add a new program header. This is called for each entry in a PHDRS + command in a linker script. */ + +void +lang_new_phdr (name, type, filehdr, phdrs, at, flags) + const char *name; + etree_type *type; + boolean filehdr; + boolean phdrs; + etree_type *at; + etree_type *flags; +{ + struct lang_phdr *n, **pp; + + n = (struct lang_phdr *) stat_alloc (sizeof (struct lang_phdr)); + n->next = NULL; + n->name = name; + n->type = exp_get_value_int (type, 0, "program header type", + lang_final_phase_enum); + n->filehdr = filehdr; + n->phdrs = phdrs; + n->at = at; + n->flags = flags; + + for (pp = &lang_phdr_list; *pp != NULL; pp = &(*pp)->next) + ; + *pp = n; +} + +/* Record the program header information in the output BFD. FIXME: We + should not be calling an ELF specific function here. */ + +static void +lang_record_phdrs () +{ + unsigned int alc; + asection **secs; + struct lang_output_section_phdr_list *last; + struct lang_phdr *l; + lang_statement_union_type *u; + + alc = 10; + secs = (asection **) xmalloc (alc * sizeof (asection *)); + last = NULL; + for (l = lang_phdr_list; l != NULL; l = l->next) + { + unsigned int c; + flagword flags; + bfd_vma at; + + c = 0; + for (u = lang_output_section_statement.head; + u != NULL; + u = u->output_section_statement.next) + { + lang_output_section_statement_type *os; + struct lang_output_section_phdr_list *pl; + + os = &u->output_section_statement; + + pl = os->phdrs; + if (pl != NULL) + last = pl; + else + { + if (os->sectype == noload_section + || os->bfd_section == NULL + || (os->bfd_section->flags & SEC_ALLOC) == 0) + continue; + pl = last; + } + + if (os->bfd_section == NULL) + continue; + + for (; pl != NULL; pl = pl->next) + { + if (strcmp (pl->name, l->name) == 0) + { + if (c >= alc) + { + alc *= 2; + secs = ((asection **) + xrealloc (secs, alc * sizeof (asection *))); + } + secs[c] = os->bfd_section; + ++c; + pl->used = true; + } + } + } + + if (l->flags == NULL) + flags = 0; + else + flags = exp_get_vma (l->flags, 0, "phdr flags", + lang_final_phase_enum); + + if (l->at == NULL) + at = 0; + else + at = exp_get_vma (l->at, 0, "phdr load address", + lang_final_phase_enum); + + if (! bfd_record_phdr (output_bfd, l->type, + l->flags == NULL ? false : true, + flags, + l->at == NULL ? false : true, + at, l->filehdr, l->phdrs, c, secs)) + einfo (_("%F%P: bfd_record_phdr failed: %E\n")); + } + + free (secs); + + /* Make sure all the phdr assignments succeeded. */ + for (u = lang_output_section_statement.head; + u != NULL; + u = u->output_section_statement.next) + { + struct lang_output_section_phdr_list *pl; + + if (u->output_section_statement.bfd_section == NULL) + continue; + + for (pl = u->output_section_statement.phdrs; + pl != NULL; + pl = pl->next) + if (! pl->used && strcmp (pl->name, "NONE") != 0) + einfo (_("%X%P: section `%s' assigned to non-existent phdr `%s'\n"), + u->output_section_statement.name, pl->name); + } +} + +/* Record a list of sections which may not be cross referenced. */ + +void +lang_add_nocrossref (l) + struct lang_nocrossref *l; +{ + struct lang_nocrossrefs *n; + + n = (struct lang_nocrossrefs *) xmalloc (sizeof *n); + n->next = nocrossref_list; + n->list = l; + nocrossref_list = n; + + /* Set notice_all so that we get informed about all symbols. */ + link_info.notice_all = true; +} + +/* Overlay handling. We handle overlays with some static variables. */ + +/* The overlay virtual address. */ +static etree_type *overlay_vma; + +/* The overlay load address. */ +static etree_type *overlay_lma; + +/* Whether nocrossrefs is set for this overlay. */ +static int overlay_nocrossrefs; + +/* An expression for the maximum section size seen so far. */ +static etree_type *overlay_max; + +/* A list of all the sections in this overlay. */ + +struct overlay_list +{ + struct overlay_list *next; + lang_output_section_statement_type *os; +}; + +static struct overlay_list *overlay_list; + +/* Start handling an overlay. */ + +void +lang_enter_overlay (vma_expr, lma_expr, nocrossrefs) + etree_type *vma_expr; + etree_type *lma_expr; + int nocrossrefs; +{ + /* The grammar should prevent nested overlays from occurring. */ + ASSERT (overlay_vma == NULL + && overlay_lma == NULL + && overlay_list == NULL + && overlay_max == NULL); + + overlay_vma = vma_expr; + overlay_lma = lma_expr; + overlay_nocrossrefs = nocrossrefs; +} + +/* Start a section in an overlay. We handle this by calling + lang_enter_output_section_statement with the correct VMA and LMA. */ + +void +lang_enter_overlay_section (name) + const char *name; +{ + struct overlay_list *n; + etree_type *size; + + lang_enter_output_section_statement (name, overlay_vma, normal_section, + 0, 0, 0, overlay_lma); + + /* If this is the first section, then base the VMA and LMA of future + sections on this one. This will work correctly even if `.' is + used in the addresses. */ + if (overlay_list == NULL) + { + overlay_vma = exp_nameop (ADDR, name); + overlay_lma = exp_nameop (LOADADDR, name); + } + + /* Remember the section. */ + n = (struct overlay_list *) xmalloc (sizeof *n); + n->os = current_section; + n->next = overlay_list; + overlay_list = n; + + size = exp_nameop (SIZEOF, name); + + /* Adjust the LMA for the next section. */ + overlay_lma = exp_binop ('+', overlay_lma, size); + + /* Arrange to work out the maximum section end address. */ + if (overlay_max == NULL) + overlay_max = size; + else + overlay_max = exp_binop (MAX_K, overlay_max, size); +} + +/* Finish a section in an overlay. There isn't any special to do + here. */ + +void +lang_leave_overlay_section (fill, phdrs) + bfd_vma fill; + struct lang_output_section_phdr_list *phdrs; +{ + const char *name; + char *clean, *s2; + const char *s1; + char *buf; + + name = current_section->name; + + lang_leave_output_section_statement (fill, "*default*", phdrs); + + /* Define the magic symbols. */ + + clean = xmalloc (strlen (name) + 1); + s2 = clean; + for (s1 = name; *s1 != '\0'; s1++) + if (isalnum ((unsigned char) *s1) || *s1 == '_') + *s2++ = *s1; + *s2 = '\0'; + + buf = xmalloc (strlen (clean) + sizeof "__load_start_"); + sprintf (buf, "__load_start_%s", clean); + lang_add_assignment (exp_assop ('=', buf, + exp_nameop (LOADADDR, name))); + + buf = xmalloc (strlen (clean) + sizeof "__load_stop_"); + sprintf (buf, "__load_stop_%s", clean); + lang_add_assignment (exp_assop ('=', buf, + exp_binop ('+', + exp_nameop (LOADADDR, name), + exp_nameop (SIZEOF, name)))); + + free (clean); +} + +/* Finish an overlay. If there are any overlay wide settings, this + looks through all the sections in the overlay and sets them. */ + +void +lang_leave_overlay (fill, memspec, phdrs) + bfd_vma fill; + const char *memspec; + struct lang_output_section_phdr_list *phdrs; +{ + lang_memory_region_type *region; + struct overlay_list *l; + struct lang_nocrossref *nocrossref; + + if (memspec == NULL) + region = NULL; + else + region = lang_memory_region_lookup (memspec); + + nocrossref = NULL; + + l = overlay_list; + while (l != NULL) + { + struct overlay_list *next; + + if (fill != 0 && l->os->fill == 0) + l->os->fill = fill; + if (region != NULL && l->os->region == NULL) + l->os->region = region; + if (phdrs != NULL && l->os->phdrs == NULL) + l->os->phdrs = phdrs; + + if (overlay_nocrossrefs) + { + struct lang_nocrossref *nc; + + nc = (struct lang_nocrossref *) xmalloc (sizeof *nc); + nc->name = l->os->name; + nc->next = nocrossref; + nocrossref = nc; + } + + next = l->next; + free (l); + l = next; + } + + if (nocrossref != NULL) + lang_add_nocrossref (nocrossref); + + /* Update . for the end of the overlay. */ + lang_add_assignment (exp_assop ('=', ".", + exp_binop ('+', overlay_vma, overlay_max))); + + overlay_vma = NULL; + overlay_lma = NULL; + overlay_nocrossrefs = 0; + overlay_list = NULL; + overlay_max = NULL; +} + +/* Version handling. This is only useful for ELF. */ + +/* This global variable holds the version tree that we build. */ + +struct bfd_elf_version_tree *lang_elf_version_info; + +static int +lang_vers_match_lang_c (expr, sym) + struct bfd_elf_version_expr *expr; + const char *sym; +{ + if (expr->pattern[0] == '*' && expr->pattern[1] == '\0') + return 1; + return fnmatch (expr->pattern, sym, 0) == 0; +} + +static int +lang_vers_match_lang_cplusplus (expr, sym) + struct bfd_elf_version_expr *expr; + const char *sym; +{ + char *alt_sym; + int result; + + if (expr->pattern[0] == '*' && expr->pattern[1] == '\0') + return 1; + + alt_sym = cplus_demangle(sym, /* DMGL_NO_TPARAMS */ 0); + if (!alt_sym) + { + /* cplus_demangle (also) returns NULL when it is not a C++ symbol. + Should we early out false in this case? */ + result = fnmatch (expr->pattern, sym, 0) == 0; + } + else + { + result = fnmatch (expr->pattern, alt_sym, 0) == 0; + free (alt_sym); + } + + return result; +} + +static int +lang_vers_match_lang_java (expr, sym) + struct bfd_elf_version_expr *expr; + const char *sym; +{ + char *alt_sym; + int result; + + if (expr->pattern[0] == '*' && expr->pattern[1] == '\0') + return 1; + + alt_sym = cplus_demangle(sym, DMGL_JAVA); + if (!alt_sym) + { + /* cplus_demangle (also) returns NULL when it is not a Java symbol. + Should we early out false in this case? */ + result = fnmatch (expr->pattern, sym, 0) == 0; + } + else + { + result = fnmatch (expr->pattern, alt_sym, 0) == 0; + free (alt_sym); + } + + return result; +} + +/* This is called for each variable name or match expression. */ + +struct bfd_elf_version_expr * +lang_new_vers_regex (orig, new, lang) + struct bfd_elf_version_expr *orig; + const char *new; + const char *lang; +{ + struct bfd_elf_version_expr *ret; + + ret = (struct bfd_elf_version_expr *) xmalloc (sizeof *ret); + ret->next = orig; + ret->pattern = new; + + if (lang == NULL || strcasecmp (lang, "C") == 0) + ret->match = lang_vers_match_lang_c; + else if (strcasecmp (lang, "C++") == 0) + ret->match = lang_vers_match_lang_cplusplus; + else if (strcasecmp (lang, "Java") == 0) + ret->match = lang_vers_match_lang_java; + else + { + einfo (_("%X%P: unknown language `%s' in version information\n"), + lang); + ret->match = lang_vers_match_lang_c; + } + + return ret; +} + +/* This is called for each set of variable names and match + expressions. */ + +struct bfd_elf_version_tree * +lang_new_vers_node (globals, locals) + struct bfd_elf_version_expr *globals; + struct bfd_elf_version_expr *locals; +{ + struct bfd_elf_version_tree *ret; + + ret = (struct bfd_elf_version_tree *) xmalloc (sizeof *ret); + ret->next = NULL; + ret->name = NULL; + ret->vernum = 0; + ret->globals = globals; + ret->locals = locals; + ret->deps = NULL; + ret->name_indx = (unsigned int) -1; + ret->used = 0; + return ret; +} + +/* This static variable keeps track of version indices. */ + +static int version_index; + +/* This is called when we know the name and dependencies of the + version. */ + +void +lang_register_vers_node (name, version, deps) + const char *name; + struct bfd_elf_version_tree *version; + struct bfd_elf_version_deps *deps; +{ + struct bfd_elf_version_tree *t, **pp; + struct bfd_elf_version_expr *e1; + + /* Make sure this node has a unique name. */ + for (t = lang_elf_version_info; t != NULL; t = t->next) + if (strcmp (t->name, name) == 0) + einfo (_("%X%P: duplicate version tag `%s'\n"), name); + + /* Check the global and local match names, and make sure there + aren't any duplicates. */ + + for (e1 = version->globals; e1 != NULL; e1 = e1->next) + { + for (t = lang_elf_version_info; t != NULL; t = t->next) + { + struct bfd_elf_version_expr *e2; + + for (e2 = t->locals; e2 != NULL; e2 = e2->next) + if (strcmp (e1->pattern, e2->pattern) == 0) + einfo (_("%X%P: duplicate expression `%s' in version information\n"), + e1->pattern); + } + } + + for (e1 = version->locals; e1 != NULL; e1 = e1->next) + { + for (t = lang_elf_version_info; t != NULL; t = t->next) + { + struct bfd_elf_version_expr *e2; + + for (e2 = t->globals; e2 != NULL; e2 = e2->next) + if (strcmp (e1->pattern, e2->pattern) == 0) + einfo (_("%X%P: duplicate expression `%s' in version information\n"), + e1->pattern); + } + } + + version->deps = deps; + version->name = name; + ++version_index; + version->vernum = version_index; + + for (pp = &lang_elf_version_info; *pp != NULL; pp = &(*pp)->next) + ; + *pp = version; +} + +/* This is called when we see a version dependency. */ + +struct bfd_elf_version_deps * +lang_add_vers_depend (list, name) + struct bfd_elf_version_deps *list; + const char *name; +{ + struct bfd_elf_version_deps *ret; + struct bfd_elf_version_tree *t; + + ret = (struct bfd_elf_version_deps *) xmalloc (sizeof *ret); + ret->next = list; + + for (t = lang_elf_version_info; t != NULL; t = t->next) + { + if (strcmp (t->name, name) == 0) + { + ret->version_needed = t; + return ret; + } + } + + einfo (_("%X%P: unable to find version dependency `%s'\n"), name); + + return ret; +} + +static void +lang_do_version_exports_section () +{ + struct bfd_elf_version_expr *greg = NULL, *lreg; + + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + asection *sec = bfd_get_section_by_name (is->the_bfd, ".exports"); + char *contents, *p; + bfd_size_type len; + + if (sec == NULL) + continue; + + len = bfd_section_size (is->the_bfd, sec); + contents = xmalloc (len); + if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len)) + einfo (_("%X%P: unable to read .exports section contents"), sec); + + p = contents; + while (p < contents+len) + { + greg = lang_new_vers_regex (greg, p, NULL); + p = strchr (p, '\0') + 1; + } + + /* Do not free the contents, as we used them creating the regex. */ + + /* Do not include this section in the link. */ + bfd_set_section_flags (is->the_bfd, sec, + bfd_get_section_flags (is->the_bfd, sec) | SEC_EXCLUDE); + } + + lreg = lang_new_vers_regex (NULL, "*", NULL); + lang_register_vers_node (command_line.version_exports_section, + lang_new_vers_node (greg, lreg), NULL); +} diff --git a/ld/ldlang.h b/ld/ldlang.h new file mode 100644 index 0000000..7bd7972 --- /dev/null +++ b/ld/ldlang.h @@ -0,0 +1,490 @@ +/* ldlang.h - linker command language support + Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef LDLANG_H +#define LDLANG_H + +typedef enum +{ + lang_input_file_is_l_enum, + lang_input_file_is_symbols_only_enum, + lang_input_file_is_marker_enum, + lang_input_file_is_fake_enum, + lang_input_file_is_search_file_enum, + lang_input_file_is_file_enum +} lang_input_file_enum_type; + +typedef unsigned int fill_type; +typedef struct statement_list +{ + union lang_statement_union *head; + union lang_statement_union **tail; +} lang_statement_list_type; + + +typedef struct memory_region_struct +{ + char *name; + struct memory_region_struct *next; + bfd_vma origin; + bfd_size_type length; + bfd_vma current; + bfd_size_type old_length; + flagword flags; + flagword not_flags; + boolean had_full_message; +} lang_memory_region_type ; + +typedef struct lang_statement_header_struct +{ + union lang_statement_union *next; + enum statement_enum + { + lang_output_section_statement_enum, + lang_assignment_statement_enum, + lang_input_statement_enum, + lang_address_statement_enum, + lang_wild_statement_enum, + lang_input_section_enum, + lang_object_symbols_statement_enum, + lang_fill_statement_enum, + lang_data_statement_enum, + lang_reloc_statement_enum, + lang_target_statement_enum, + lang_output_statement_enum, + lang_padding_statement_enum, + lang_group_statement_enum, + + lang_afile_asection_pair_statement_enum, + lang_constructors_statement_enum + } type; +} lang_statement_header_type; + + +typedef struct +{ + lang_statement_header_type header; + union etree_union *exp; +} lang_assignment_statement_type; + + +typedef struct lang_target_statement_struct +{ + lang_statement_header_type header; + const char *target; +} lang_target_statement_type; + + +typedef struct lang_output_statement_struct +{ + lang_statement_header_type header; + const char *name; +} lang_output_statement_type; + +/* Section types specified in a linker script. */ + +enum section_type +{ + normal_section, + dsect_section, + copy_section, + noload_section, + info_section, + overlay_section +}; + +/* This structure holds a list of program headers describing segments + in which this section should be placed. */ + +struct lang_output_section_phdr_list +{ + struct lang_output_section_phdr_list *next; + const char *name; + boolean used; +}; + +typedef struct lang_output_section_statement_struct +{ + lang_statement_header_type header; + union etree_union *addr_tree; + lang_statement_list_type children; + const char *memspec; + union lang_statement_union *next; + const char *name; + + boolean processed; + + asection *bfd_section; + flagword flags; /* Or together of all input sections */ + enum section_type sectype; + struct memory_region_struct *region; + size_t block_value; + fill_type fill; + + int subsection_alignment; /* alignment of components */ + int section_alignment; /* alignment of start of section */ + + union etree_union *load_base; + + struct lang_output_section_phdr_list *phdrs; +} lang_output_section_statement_type; + + +typedef struct +{ + lang_statement_header_type header; +} lang_common_statement_type; + +typedef struct +{ + lang_statement_header_type header; +} lang_object_symbols_statement_type; + +typedef struct +{ + lang_statement_header_type header; + fill_type fill; + int size; + asection *output_section; +} lang_fill_statement_type; + +typedef struct +{ + lang_statement_header_type header; + unsigned int type; + union etree_union *exp; + bfd_vma value; + asection *output_section; + bfd_vma output_vma; +} lang_data_statement_type; + +/* Generate a reloc in the output file. */ + +typedef struct +{ + lang_statement_header_type header; + + /* Reloc to generate. */ + bfd_reloc_code_real_type reloc; + + /* Reloc howto structure. */ + reloc_howto_type *howto; + + /* Section to generate reloc against. Exactly one of section and + name must be NULL. */ + asection *section; + + /* Name of symbol to generate reloc against. Exactly one of section + and name must be NULL. */ + const char *name; + + /* Expression for addend. */ + union etree_union *addend_exp; + + /* Resolved addend. */ + bfd_vma addend_value; + + /* Output section where reloc should be performed. */ + asection *output_section; + + /* VMA within output section. */ + bfd_vma output_vma; +} lang_reloc_statement_type; + +typedef struct lang_input_statement_struct +{ + lang_statement_header_type header; + /* Name of this file. */ + const char *filename; + /* Name to use for the symbol giving address of text start */ + /* Usually the same as filename, but for a file spec'd with -l + this is the -l switch itself rather than the filename. */ + const char *local_sym_name; + + bfd *the_bfd; + + boolean closed; + file_ptr passive_position; + + /* Symbol table of the file. */ + asymbol **asymbols; + unsigned int symbol_count; + + /* Point to the next file - whatever it is, wanders up and down + archives */ + + union lang_statement_union *next; + /* Point to the next file, but skips archive contents */ + union lang_statement_union *next_real_file; + + boolean is_archive; + + /* 1 means search a set of directories for this file. */ + boolean search_dirs_flag; + + /* 1 means this is base file of incremental load. + Do not load this file's text or data. + Also default text_start to after this file's bss. */ + + boolean just_syms_flag; + + /* Whether to search for this entry as a dynamic archive. */ + boolean dynamic; + + /* Whether to include the entire contents of an archive. */ + boolean whole_archive; + + boolean loaded; + + /* unsigned int globals_in_this_file;*/ + const char *target; + boolean real; +} lang_input_statement_type; + +typedef struct +{ + lang_statement_header_type header; + asection *section; + lang_input_statement_type *ifile; + +} lang_input_section_type; + + +typedef struct +{ + lang_statement_header_type header; + asection *section; + union lang_statement_union *file; +} lang_afile_asection_pair_statement_type; + +typedef struct lang_wild_statement_struct +{ + lang_statement_header_type header; + const char *section_name; + boolean sections_sorted; + const char *filename; + boolean filenames_sorted; + boolean keep_sections; + const char *exclude_filename; + lang_statement_list_type children; +} lang_wild_statement_type; + +typedef struct lang_address_statement_struct +{ + lang_statement_header_type header; + const char *section_name; + union etree_union *address; +} lang_address_statement_type; + +typedef struct +{ + lang_statement_header_type header; + bfd_vma output_offset; + size_t size; + asection *output_section; + fill_type fill; +} lang_padding_statement_type; + +/* A group statement collects a set of libraries together. The + libraries are searched multiple times, until no new undefined + symbols are found. The effect is to search a group of libraries as + though they were a single library. */ + +typedef struct +{ + lang_statement_header_type header; + lang_statement_list_type children; +} lang_group_statement_type; + +typedef union lang_statement_union +{ + lang_statement_header_type header; + union lang_statement_union *next; + lang_wild_statement_type wild_statement; + lang_data_statement_type data_statement; + lang_reloc_statement_type reloc_statement; + lang_address_statement_type address_statement; + lang_output_section_statement_type output_section_statement; + lang_afile_asection_pair_statement_type afile_asection_pair_statement; + lang_assignment_statement_type assignment_statement; + lang_input_statement_type input_statement; + lang_target_statement_type target_statement; + lang_output_statement_type output_statement; + lang_input_section_type input_section; + lang_common_statement_type common_statement; + lang_object_symbols_statement_type object_symbols_statement; + lang_fill_statement_type fill_statement; + lang_padding_statement_type padding_statement; + lang_group_statement_type group_statement; +} lang_statement_union_type; + +/* This structure holds information about a program header, from the + PHDRS command in the linker script. */ + +struct lang_phdr +{ + struct lang_phdr *next; + const char *name; + unsigned long type; + boolean filehdr; + boolean phdrs; + etree_type *at; + etree_type *flags; +}; + +/* This structure is used to hold a list of sections which may not + cross reference each other. */ + +struct lang_nocrossref +{ + struct lang_nocrossref *next; + const char *name; +}; + +/* The list of nocrossref lists. */ + +struct lang_nocrossrefs +{ + struct lang_nocrossrefs *next; + struct lang_nocrossref *list; +}; + +extern struct lang_nocrossrefs *nocrossref_list; + +extern lang_output_section_statement_type *abs_output_section; +extern boolean lang_has_input_file; +extern etree_type *base; +extern lang_statement_list_type *stat_ptr; +extern boolean delete_output_file_on_failure; + +extern const char *entry_symbol; +extern boolean entry_from_cmdline; + +extern void lang_init PARAMS ((void)); +extern struct memory_region_struct *lang_memory_region_lookup + PARAMS ((const char *const)); +extern struct memory_region_struct *lang_memory_region_default + PARAMS ((asection *)); +extern void lang_map PARAMS ((void)); +extern void lang_set_flags PARAMS ((lang_memory_region_type *, const char *)); +extern void lang_add_output PARAMS ((const char *, int from_script)); +extern void lang_enter_output_section_statement + PARAMS ((const char *output_section_statement_name, + etree_type * address_exp, + enum section_type sectype, + bfd_vma block_value, + etree_type *align, + etree_type *subalign, + etree_type *)); +extern void lang_final PARAMS ((void)); +extern void lang_process PARAMS ((void)); +extern void lang_section_start PARAMS ((const char *, union etree_union *)); +extern void lang_add_entry PARAMS ((const char *, boolean)); +extern void lang_add_target PARAMS ((const char *)); +extern void lang_add_wild + PARAMS ((const char *, boolean, const char *, boolean, boolean, const char *)); +extern void lang_add_map PARAMS ((const char *)); +extern void lang_add_fill PARAMS ((int)); +extern lang_assignment_statement_type * lang_add_assignment PARAMS ((union etree_union *)); +extern void lang_add_attribute PARAMS ((enum statement_enum)); +extern void lang_startup PARAMS ((const char *)); +extern void lang_float PARAMS ((enum bfd_boolean)); +extern void lang_leave_output_section_statement + PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *)); +extern void lang_abs_symbol_at_end_of PARAMS ((const char *, const char *)); +extern void lang_abs_symbol_at_beginning_of PARAMS ((const char *, + const char *)); +extern void lang_statement_append PARAMS ((struct statement_list *, + union lang_statement_union *, + union lang_statement_union **)); +extern void lang_for_each_input_file + PARAMS ((void (*dothis) (lang_input_statement_type *))); +extern void lang_for_each_file + PARAMS ((void (*dothis) (lang_input_statement_type *))); +extern bfd_vma lang_do_assignments + PARAMS ((lang_statement_union_type * s, + lang_output_section_statement_type *output_section_statement, + fill_type fill, + bfd_vma dot)); + +#define LANG_FOR_EACH_INPUT_STATEMENT(statement) \ + extern lang_statement_list_type file_chain; \ + lang_input_statement_type *statement; \ + for (statement = (lang_input_statement_type *)file_chain.head;\ + statement != (lang_input_statement_type *)NULL; \ + statement = (lang_input_statement_type *)statement->next)\ + +extern void lang_process PARAMS ((void)); +extern void ldlang_add_file PARAMS ((lang_input_statement_type *)); +extern lang_output_section_statement_type *lang_output_section_find + PARAMS ((const char * const)); +extern lang_input_statement_type *lang_add_input_file + PARAMS ((const char *name, lang_input_file_enum_type file_type, + const char *target)); +extern void lang_add_keepsyms_file PARAMS ((const char *filename)); +extern lang_output_section_statement_type * + lang_output_section_statement_lookup PARAMS ((const char * const name)); +extern void ldlang_add_undef PARAMS ((const char *const name)); +extern void lang_add_output_format PARAMS ((const char *, const char *, + const char *, int from_script)); +extern void lang_list_init PARAMS ((lang_statement_list_type*)); +extern void lang_add_data PARAMS ((int type, union etree_union *)); +extern void lang_add_reloc + PARAMS ((bfd_reloc_code_real_type reloc, reloc_howto_type *howto, + asection *section, const char *name, union etree_union *addend)); +extern void lang_for_each_statement + PARAMS ((void (*func) (lang_statement_union_type *))); +extern PTR stat_alloc PARAMS ((size_t size)); +extern void dprint_statement PARAMS ((lang_statement_union_type *, int)); +extern bfd_vma lang_size_sections + PARAMS ((lang_statement_union_type *s, + lang_output_section_statement_type *output_section_statement, + lang_statement_union_type **prev, fill_type fill, + bfd_vma dot, boolean relax)); +extern void lang_enter_group PARAMS ((void)); +extern void lang_leave_group PARAMS ((void)); +extern void wild_doit + PARAMS ((lang_statement_list_type *ptr, asection *section, + lang_output_section_statement_type *output, + lang_input_statement_type *file)); +extern void lang_new_phdr + PARAMS ((const char *, etree_type *, boolean, boolean, etree_type *, + etree_type *)); +extern void lang_add_nocrossref PARAMS ((struct lang_nocrossref *)); +extern void lang_enter_overlay PARAMS ((etree_type *, etree_type *, int)); +extern void lang_enter_overlay_section PARAMS ((const char *)); +extern void lang_leave_overlay_section + PARAMS ((bfd_vma, struct lang_output_section_phdr_list *)); +extern void lang_leave_overlay + PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *)); + +extern struct bfd_elf_version_tree *lang_elf_version_info; + +extern struct bfd_elf_version_expr *lang_new_vers_regex + PARAMS ((struct bfd_elf_version_expr *, const char *, const char *)); +extern struct bfd_elf_version_tree *lang_new_vers_node + PARAMS ((struct bfd_elf_version_expr *, struct bfd_elf_version_expr *)); +extern struct bfd_elf_version_deps *lang_add_vers_depend + PARAMS ((struct bfd_elf_version_deps *, const char *)); +extern void lang_register_vers_node + PARAMS ((const char *, struct bfd_elf_version_tree *, + struct bfd_elf_version_deps *)); + +#endif diff --git a/ld/ldlex.h b/ld/ldlex.h new file mode 100644 index 0000000..53444ca --- /dev/null +++ b/ld/ldlex.h @@ -0,0 +1,62 @@ +/* ldlex.h - + Copyright 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef LDLEX_H +#define LDLEX_H + +#include <stdio.h> + +/* The initial parser states. */ +typedef enum input_enum { + input_selected, /* We've set the initial state. */ + input_script, + input_mri_script, + input_version_script, + input_defsym +} input_type; + +extern input_type parser_input; + +extern unsigned int lineno; +extern const char *lex_string; + +/* In ldlex.l. */ +extern int yylex PARAMS ((void)); +extern void lex_push_file PARAMS ((FILE *, const char *)); +extern void lex_redirect PARAMS ((const char *)); +extern void ldlex_script PARAMS ((void)); +extern void ldlex_mri_script PARAMS ((void)); +extern void ldlex_version_script PARAMS ((void)); +extern void ldlex_version_file PARAMS ((void)); +extern void ldlex_defsym PARAMS ((void)); +extern void ldlex_expression PARAMS ((void)); +extern void ldlex_both PARAMS ((void)); +extern void ldlex_command PARAMS ((void)); +extern void ldlex_popstate PARAMS ((void)); + +/* In lexsup.c. */ +extern int lex_input PARAMS ((void)); +extern void lex_unput PARAMS ((int)); +#ifndef yywrap +extern int yywrap PARAMS ((void)); +#endif +extern void parse_args PARAMS ((int, char **)); + +#endif diff --git a/ld/ldlex.l b/ld/ldlex.l new file mode 100644 index 0000000..2eef80f --- /dev/null +++ b/ld/ldlex.l @@ -0,0 +1,662 @@ +%{ + +/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* +This was written by steve chamberlain + sac@cygnus.com +*/ + + +#include <ansidecl.h> +#include <stdio.h> +#include <ctype.h> + +#ifdef MPW +/* Prevent enum redefinition problems. */ +#define TRUE_FALSE_ALREADY_DEFINED +#endif /* MPW */ + +#include "bfd.h" +#include "sysdep.h" +#include "ld.h" +#include "ldgram.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldfile.h" +#include "ldlex.h" +#include "ldmain.h" + +/* The type of top-level parser input. + yylex and yyparse (indirectly) both check this. */ +input_type parser_input; + +/* Line number in the current input file. + (FIXME Actually, it doesn't appear to get reset for each file?) */ +unsigned int lineno = 1; + +/* The string we are currently lexing, or NULL if we are reading a + file. */ +const char *lex_string = NULL; + +/* Support for flex reading from more than one input file (stream). + `include_stack' is flex's input state for each open file; + `file_name_stack' is the file names. `lineno_stack' is the current + line numbers. + + If `include_stack_ptr' is 0, we haven't started reading anything yet. + Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid. */ + +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) yy_input(buf, &result, max_size) + +#define MAX_INCLUDE_DEPTH 10 +static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +static const char *file_name_stack[MAX_INCLUDE_DEPTH]; +static unsigned int lineno_stack[MAX_INCLUDE_DEPTH]; +static unsigned int include_stack_ptr = 0; +static int vers_node_nesting = 0; + +static YY_BUFFER_STATE yy_create_string_buffer PARAMS ((const char *string, + size_t size)); +static void yy_input PARAMS ((char *, int *result, int max_size)); + +static void comment PARAMS ((void)); +static void lex_warn_invalid PARAMS ((char *where, char *what)); + +/* STATES + EXPRESSION definitely in an expression + SCRIPT definitely in a script + BOTH either EXPRESSION or SCRIPT + DEFSYMEXP in an argument to -defsym + MRI in an MRI script + VERS_START starting a Sun style mapfile + VERS_SCRIPT a Sun style mapfile + VERS_NODE a node within a Sun style mapfile +*/ +#define RTOKEN(x) { yylval.token = x; return x; } + +/* Some versions of flex want this. */ +#ifndef yywrap +int yywrap () { return 1; } +#endif +%} + +%a 4000 +%o 5000 + +CMDFILENAMECHAR [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\-\~] +CMDFILENAMECHAR1 [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\~] +FILENAMECHAR1 [_a-zA-Z\/\.\\\$\_\~] +SYMBOLCHARN [_a-zA-Z\/\.\\\$\_\~0-9] +FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~] +WILDCHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~\?\*] +WHITE [ \t\n\r]+ + +NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] + +V_TAG [.$_a-zA-Z][._a-zA-Z0-9]* +V_IDENTIFIER [*?.$_a-zA-Z][*?.$_a-zA-Z0-9]* + +%s SCRIPT +%s EXPRESSION +%s BOTH +%s DEFSYMEXP +%s MRI +%s VERS_START +%s VERS_SCRIPT +%s VERS_NODE +%% + + if (parser_input != input_selected) + { + /* The first token of the input determines the initial parser state. */ + input_type t = parser_input; + parser_input = input_selected; + switch (t) + { + case input_script: return INPUT_SCRIPT; break; + case input_mri_script: return INPUT_MRI_SCRIPT; break; + case input_version_script: return INPUT_VERSION_SCRIPT; break; + case input_defsym: return INPUT_DEFSYM; break; + default: abort (); + } + } + +<BOTH,SCRIPT,EXPRESSION>"/*" { comment(); } + + +<DEFSYMEXP>"-" { RTOKEN('-');} +<DEFSYMEXP>"+" { RTOKEN('+');} +<DEFSYMEXP>{FILENAMECHAR1}{SYMBOLCHARN}* { yylval.name = buystring(yytext); return NAME; } +<DEFSYMEXP>"=" { RTOKEN('='); } + +<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ { + yylval.integer = bfd_scan_vma (yytext+1, 0,16); + return INT; + } + +<MRI,EXPRESSION>([0-9A-Fa-f])+(H|h|X|x|B|b|O|o|D|d) { + int ibase ; + switch (yytext[yyleng-1]) { + case 'X': + case 'x': + case 'H': + case 'h': + ibase = 16; + break; + case 'O': + case 'o': + ibase = 8; + break; + case 'B': + case 'b': + ibase = 2; + break; + default: + ibase = 10; + } + yylval.integer = bfd_scan_vma (yytext, 0, + ibase); + return INT; + } +<SCRIPT,DEFSYMEXP,MRI,BOTH,EXPRESSION>((("$"|"0x")([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? { + char *s = yytext; + + if (*s == '$') + ++s; + yylval.integer = bfd_scan_vma (s, 0, 0); + if (yytext[yyleng-1] == 'M' + || yytext[yyleng-1] == 'm') + yylval.integer *= 1024 * 1024; + if (yytext[yyleng-1] == 'K' + || yytext[yyleng-1]=='k') + yylval.integer *= 1024; + return INT; + } +<BOTH,SCRIPT,EXPRESSION,MRI>"]" { RTOKEN(']');} +<BOTH,SCRIPT,EXPRESSION,MRI>"[" { RTOKEN('[');} +<BOTH,SCRIPT,EXPRESSION,MRI>"<<=" { RTOKEN(LSHIFTEQ);} +<BOTH,SCRIPT,EXPRESSION,MRI>">>=" { RTOKEN(RSHIFTEQ);} +<BOTH,SCRIPT,EXPRESSION,MRI>"||" { RTOKEN(OROR);} +<BOTH,SCRIPT,EXPRESSION,MRI>"==" { RTOKEN(EQ);} +<BOTH,SCRIPT,EXPRESSION,MRI>"!=" { RTOKEN(NE);} +<BOTH,SCRIPT,EXPRESSION,MRI>">=" { RTOKEN(GE);} +<BOTH,SCRIPT,EXPRESSION,MRI>"<=" { RTOKEN(LE);} +<BOTH,SCRIPT,EXPRESSION,MRI>"<<" { RTOKEN(LSHIFT);} +<BOTH,SCRIPT,EXPRESSION,MRI>">>" { RTOKEN(RSHIFT);} +<BOTH,SCRIPT,EXPRESSION,MRI>"+=" { RTOKEN(PLUSEQ);} +<BOTH,SCRIPT,EXPRESSION,MRI>"-=" { RTOKEN(MINUSEQ);} +<BOTH,SCRIPT,EXPRESSION,MRI>"*=" { RTOKEN(MULTEQ);} +<BOTH,SCRIPT,EXPRESSION,MRI>"/=" { RTOKEN(DIVEQ);} +<BOTH,SCRIPT,EXPRESSION,MRI>"&=" { RTOKEN(ANDEQ);} +<BOTH,SCRIPT,EXPRESSION,MRI>"|=" { RTOKEN(OREQ);} +<BOTH,SCRIPT,EXPRESSION,MRI>"&&" { RTOKEN(ANDAND);} +<BOTH,SCRIPT,EXPRESSION,MRI>">" { RTOKEN('>');} +<BOTH,SCRIPT,EXPRESSION,MRI>"," { RTOKEN(',');} +<BOTH,SCRIPT,EXPRESSION,MRI>"&" { RTOKEN('&');} +<BOTH,SCRIPT,EXPRESSION,MRI>"|" { RTOKEN('|');} +<BOTH,SCRIPT,EXPRESSION,MRI>"~" { RTOKEN('~');} +<BOTH,SCRIPT,EXPRESSION,MRI>"!" { RTOKEN('!');} +<BOTH,SCRIPT,EXPRESSION,MRI>"?" { RTOKEN('?');} +<BOTH,SCRIPT,EXPRESSION,MRI>"*" { RTOKEN('*');} +<BOTH,SCRIPT,EXPRESSION,MRI>"+" { RTOKEN('+');} +<BOTH,SCRIPT,EXPRESSION,MRI>"-" { RTOKEN('-');} +<BOTH,SCRIPT,EXPRESSION,MRI>"/" { RTOKEN('/');} +<BOTH,SCRIPT,EXPRESSION,MRI>"%" { RTOKEN('%');} +<BOTH,SCRIPT,EXPRESSION,MRI>"<" { RTOKEN('<');} +<BOTH,SCRIPT,EXPRESSION,MRI>"=" { RTOKEN('=');} +<BOTH,SCRIPT,EXPRESSION,MRI>"}" { RTOKEN('}') ; } +<BOTH,SCRIPT,EXPRESSION,MRI>"{" { RTOKEN('{'); } +<BOTH,SCRIPT,EXPRESSION,MRI>")" { RTOKEN(')');} +<BOTH,SCRIPT,EXPRESSION,MRI>"(" { RTOKEN('(');} +<BOTH,SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); } +<BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');} +<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);} +<BOTH,SCRIPT>"ORIGIN" { RTOKEN(ORIGIN);} +<BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);} +<EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);} +<EXPRESSION,BOTH,SCRIPT>"BIND" { RTOKEN(BIND);} +<BOTH,SCRIPT>"LENGTH" { RTOKEN(LENGTH);} +<EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);} +<EXPRESSION,BOTH,SCRIPT>"ADDR" { RTOKEN(ADDR);} +<EXPRESSION,BOTH,SCRIPT>"LOADADDR" { RTOKEN(LOADADDR);} +<EXPRESSION,BOTH>"MAX" { RTOKEN(MAX_K); } +<EXPRESSION,BOTH>"MIN" { RTOKEN(MIN_K); } +<EXPRESSION,BOTH>"ASSERT" { RTOKEN(ASSERT_K); } +<BOTH,SCRIPT>"ENTRY" { RTOKEN(ENTRY);} +<BOTH,SCRIPT,MRI>"EXTERN" { RTOKEN(EXTERN);} +<EXPRESSION,BOTH,SCRIPT>"NEXT" { RTOKEN(NEXT);} +<EXPRESSION,BOTH,SCRIPT>"sizeof_headers" { RTOKEN(SIZEOF_HEADERS);} +<EXPRESSION,BOTH,SCRIPT>"SIZEOF_HEADERS" { RTOKEN(SIZEOF_HEADERS);} +<BOTH,SCRIPT>"MAP" { RTOKEN(MAP);} +<EXPRESSION,BOTH,SCRIPT>"SIZEOF" { RTOKEN(SIZEOF);} +<BOTH,SCRIPT>"TARGET" { RTOKEN(TARGET_K);} +<BOTH,SCRIPT>"SEARCH_DIR" { RTOKEN(SEARCH_DIR);} +<BOTH,SCRIPT>"OUTPUT" { RTOKEN(OUTPUT);} +<BOTH,SCRIPT>"INPUT" { RTOKEN(INPUT);} +<EXPRESSION,BOTH,SCRIPT>"GROUP" { RTOKEN(GROUP);} +<EXPRESSION,BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);} +<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);} +<BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);} +<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);} +<BOTH,SCRIPT>"SECTIONS" { RTOKEN(SECTIONS);} +<BOTH,SCRIPT>"FILL" { RTOKEN(FILL);} +<BOTH,SCRIPT>"STARTUP" { RTOKEN(STARTUP);} +<BOTH,SCRIPT>"OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT);} +<BOTH,SCRIPT>"OUTPUT_ARCH" { RTOKEN( OUTPUT_ARCH);} +<BOTH,SCRIPT>"HLL" { RTOKEN(HLL);} +<BOTH,SCRIPT>"SYSLIB" { RTOKEN(SYSLIB);} +<BOTH,SCRIPT>"FLOAT" { RTOKEN(FLOAT);} +<BOTH,SCRIPT>"QUAD" { RTOKEN( QUAD);} +<BOTH,SCRIPT>"SQUAD" { RTOKEN( SQUAD);} +<BOTH,SCRIPT>"LONG" { RTOKEN( LONG);} +<BOTH,SCRIPT>"SHORT" { RTOKEN( SHORT);} +<BOTH,SCRIPT>"BYTE" { RTOKEN( BYTE);} +<BOTH,SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT);} +<EXPRESSION,BOTH,SCRIPT>"NOCROSSREFS" { RTOKEN(NOCROSSREFS);} +<BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY); } +<BOTH,SCRIPT>"SORT" { RTOKEN(SORT); } +<EXPRESSION,BOTH,SCRIPT>"NOLOAD" { RTOKEN(NOLOAD);} +<EXPRESSION,BOTH,SCRIPT>"DSECT" { RTOKEN(DSECT);} +<EXPRESSION,BOTH,SCRIPT>"COPY" { RTOKEN(COPY);} +<EXPRESSION,BOTH,SCRIPT>"INFO" { RTOKEN(INFO);} +<EXPRESSION,BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY);} +<BOTH,SCRIPT>"o" { RTOKEN(ORIGIN);} +<BOTH,SCRIPT>"org" { RTOKEN(ORIGIN);} +<BOTH,SCRIPT>"l" { RTOKEN( LENGTH);} +<BOTH,SCRIPT>"len" { RTOKEN( LENGTH);} +<BOTH,SCRIPT>"INCLUDE" { RTOKEN(INCLUDE);} +<BOTH,SCRIPT>"PHDRS" { RTOKEN (PHDRS); } +<EXPRESSION,BOTH,SCRIPT>"AT" { RTOKEN(AT);} +<EXPRESSION,BOTH,SCRIPT>"PROVIDE" { RTOKEN(PROVIDE); } +<EXPRESSION,BOTH,SCRIPT>"KEEP" { RTOKEN(KEEP); } +<EXPRESSION,BOTH,SCRIPT>"EXCLUDE_FILE" { RTOKEN(EXCLUDE_FILE); } +<MRI>"#".*\n? { ++ lineno; } +<MRI>"\n" { ++ lineno; RTOKEN(NEWLINE); } +<MRI>"*".* { /* Mri comment line */ } +<MRI>";".* { /* Mri comment line */ } +<MRI>"END" { RTOKEN(ENDWORD); } +<MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);} +<MRI>"ALIGN" { RTOKEN(ALIGN_K);} +<MRI>"CHIP" { RTOKEN(CHIP); } +<MRI>"BASE" { RTOKEN(BASE); } +<MRI>"ALIAS" { RTOKEN(ALIAS); } +<MRI>"TRUNCATE" { RTOKEN(TRUNCATE); } +<MRI>"LOAD" { RTOKEN(LOAD); } +<MRI>"PUBLIC" { RTOKEN(PUBLIC); } +<MRI>"ORDER" { RTOKEN(ORDER); } +<MRI>"NAME" { RTOKEN(NAMEWORD); } +<MRI>"FORMAT" { RTOKEN(FORMAT); } +<MRI>"CASE" { RTOKEN(CASE); } +<MRI>"START" { RTOKEN(START); } +<MRI>"LIST".* { RTOKEN(LIST); /* LIST and ignore to end of line */ } +<MRI>"SECT" { RTOKEN(SECT); } +<EXPRESSION,BOTH,SCRIPT,MRI>"ABSOLUTE" { RTOKEN(ABSOLUTE); } +<MRI>"end" { RTOKEN(ENDWORD); } +<MRI>"alignmod" { RTOKEN(ALIGNMOD);} +<MRI>"align" { RTOKEN(ALIGN_K);} +<MRI>"chip" { RTOKEN(CHIP); } +<MRI>"base" { RTOKEN(BASE); } +<MRI>"alias" { RTOKEN(ALIAS); } +<MRI>"truncate" { RTOKEN(TRUNCATE); } +<MRI>"load" { RTOKEN(LOAD); } +<MRI>"public" { RTOKEN(PUBLIC); } +<MRI>"order" { RTOKEN(ORDER); } +<MRI>"name" { RTOKEN(NAMEWORD); } +<MRI>"format" { RTOKEN(FORMAT); } +<MRI>"case" { RTOKEN(CASE); } +<MRI>"extern" { RTOKEN(EXTERN); } +<MRI>"start" { RTOKEN(START); } +<MRI>"list".* { RTOKEN(LIST); /* LIST and ignore to end of line */ } +<MRI>"sect" { RTOKEN(SECT); } +<EXPRESSION,BOTH,SCRIPT,MRI>"absolute" { RTOKEN(ABSOLUTE); } + +<MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}* { +/* Filename without commas, needed to parse mri stuff */ + yylval.name = buystring(yytext); + return NAME; + } + + +<BOTH,EXPRESSION>{FILENAMECHAR1}{FILENAMECHAR}* { + yylval.name = buystring(yytext); + return NAME; + } +<BOTH,EXPRESSION>"-l"{FILENAMECHAR}+ { + yylval.name = buystring (yytext + 2); + return LNAME; + } +<SCRIPT>{WILDCHAR}* { + /* Annoyingly, this pattern can match comments, and we have + longest match issues to consider. So if the first two + characters are a comment opening, put the input back and + try again. */ + if (yytext[0] == '/' && yytext[1] == '*') + { + yyless(2); + comment (); + } + else + { + yylval.name = buystring(yytext); + return NAME; + } + } + +<EXPRESSION,BOTH,SCRIPT,VERS_NODE>"\""[^\"]*"\"" { + /* No matter the state, quotes + give what's inside */ + yylval.name = buystring(yytext+1); + yylval.name[yyleng-2] = 0; + return NAME; + } +<BOTH,SCRIPT,EXPRESSION>"\n" { lineno++;} +<MRI,BOTH,SCRIPT,EXPRESSION>[ \t\r]+ { } + +<VERS_NODE,VERS_SCRIPT>[:,;] { return *yytext; } + +<VERS_NODE>global { RTOKEN(GLOBAL); } + +<VERS_NODE>local { RTOKEN(LOCAL); } + +<VERS_NODE>extern { RTOKEN(EXTERN); } + +<VERS_NODE>{V_IDENTIFIER} { yylval.name = buystring (yytext); + return VERS_IDENTIFIER; } + +<VERS_SCRIPT>{V_TAG} { yylval.name = buystring (yytext); + return VERS_TAG; } + +<VERS_START>"{" { BEGIN(VERS_SCRIPT); return *yytext; } + +<VERS_SCRIPT>"{" { BEGIN(VERS_NODE); + vers_node_nesting = 0; + return *yytext; + } +<VERS_SCRIPT>"}" { return *yytext; } +<VERS_NODE>"{" { vers_node_nesting++; return *yytext; } +<VERS_NODE>"}" { if (--vers_node_nesting < 0) + BEGIN(VERS_SCRIPT); + return *yytext; + } + +<VERS_START,VERS_NODE,VERS_SCRIPT>[\n] { lineno++; } + +<VERS_START,VERS_NODE,VERS_SCRIPT>#.* { /* Eat up comments */ } + +<VERS_START,VERS_NODE,VERS_SCRIPT>[ \t\r]+ { /* Eat up whitespace */ } + +<<EOF>> { + include_stack_ptr--; + + if (include_stack_ptr == 0) + { + yyterminate(); + } + else + { + yy_switch_to_buffer(include_stack[include_stack_ptr]); + + } + BEGIN(SCRIPT); + ldfile_input_filename = file_name_stack[include_stack_ptr - 1]; + lineno = lineno_stack[include_stack_ptr - 1]; + + return END; +} + +<SCRIPT,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>. lex_warn_invalid(" in script", yytext); +<EXPRESSION,DEFSYMEXP,BOTH>. lex_warn_invalid(" in expression", yytext); + +%% + + +/* Switch flex to reading script file NAME, open on FILE, + saving the current input info on the include stack. */ + +void +lex_push_file (file, name) + FILE *file; + const char *name; +{ + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) + { + einfo("%F:includes nested too deeply\n"); + } + file_name_stack[include_stack_ptr] = name; + lineno_stack[include_stack_ptr] = 1; + include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; + + include_stack_ptr++; + yyin = file; + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + BEGIN (SCRIPT); +} + +/* Return a newly created flex input buffer containing STRING, + which is SIZE bytes long. */ + +static YY_BUFFER_STATE +yy_create_string_buffer (string, size) + CONST char *string; + size_t size; +{ + YY_BUFFER_STATE b; + + /* Calls to m-alloc get turned by sed into xm-alloc. */ + b = (YY_BUFFER_STATE) malloc (sizeof (struct yy_buffer_state)); + b->yy_input_file = 0; + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + we need to put in 2 end-of-buffer characters. */ + b->yy_ch_buf = (char *) malloc ((unsigned) (b->yy_buf_size + 3)); + + b->yy_ch_buf[0] = '\n'; + strcpy (b->yy_ch_buf+1, string); + b->yy_ch_buf[size+1] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR; + b->yy_n_chars = size+1; + b->yy_buf_pos = &b->yy_ch_buf[1]; + + /* flex 2.4.7 changed the interface. FIXME: We should not be using + a flex internal interface in the first place! */ +#ifdef YY_BUFFER_NEW + b->yy_buffer_status = YY_BUFFER_NEW; +#else + b->yy_eof_status = EOF_NOT_SEEN; +#endif + + return b; +} + +/* Switch flex to reading from STRING, saving the current input info + on the include stack. */ + +void +lex_redirect (string) + CONST char *string; +{ + YY_BUFFER_STATE tmp; + + yy_init = 0; + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) + { + einfo("%F: macros nested too deeply\n"); + } + file_name_stack[include_stack_ptr] = "redirect"; + lineno_stack[include_stack_ptr] = 0; + include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; + include_stack_ptr++; + tmp = yy_create_string_buffer (string, strlen (string)); + yy_switch_to_buffer (tmp); + BEGIN (SCRIPT); +} + +/* Functions to switch to a different flex start condition, + saving the current start condition on `state_stack'. */ + +static int state_stack[MAX_INCLUDE_DEPTH * 2]; +static int *state_stack_p = state_stack; + +void +ldlex_script () +{ + *(state_stack_p)++ = yy_start; + BEGIN (SCRIPT); +} + +void +ldlex_mri_script () +{ + *(state_stack_p)++ = yy_start; + BEGIN (MRI); +} + +void +ldlex_version_script () +{ + *(state_stack_p)++ = yy_start; + BEGIN (VERS_START); +} + +void +ldlex_version_file () +{ + *(state_stack_p)++ = yy_start; + BEGIN (VERS_SCRIPT); +} + +void +ldlex_defsym () +{ + *(state_stack_p)++ = yy_start; + BEGIN (DEFSYMEXP); +} + +void +ldlex_expression () +{ + *(state_stack_p)++ = yy_start; + BEGIN (EXPRESSION); +} + +void +ldlex_both () +{ + *(state_stack_p)++ = yy_start; + BEGIN (BOTH); +} + +void +ldlex_popstate () +{ + yy_start = *(--state_stack_p); +} + + +/* Place up to MAX_SIZE characters in BUF and return in *RESULT + either the number of characters read, or 0 to indicate EOF. */ + +static void +yy_input (buf, result, max_size) + char *buf; + int *result; + int max_size; +{ + *result = 0; + if (yy_current_buffer->yy_input_file) + { + if (yyin) + { + *result = read (fileno (yyin), (char *) buf, max_size); + if (*result < 0) + einfo ("%F%P: read in flex scanner failed\n"); + } + } +} + +/* Eat the rest of a C-style comment. */ + +static void +comment () +{ + int c; + + while (1) + { + c = input(); + while (c != '*' && c != EOF) + { + if (c == '\n') + lineno++; + c = input(); + } + + if (c == '*') + { + c = input(); + while (c == '*') + c = input(); + if (c == '/') + break; /* found the end */ + } + + if (c == '\n') + lineno++; + + if (c == EOF) + { + einfo( "%F%P: EOF in comment\n"); + break; + } + } +} + +/* Warn the user about a garbage character WHAT in the input + in context WHERE. */ + +static void +lex_warn_invalid (where, what) + char *where, *what; +{ + char buf[5]; + + /* If we have found an input file whose format we do not recognize, + and we are therefore treating it as a linker script, and we find + an invalid character, then most likely this is a real object file + of some different format. Treat it as such. */ + if (ldfile_assumed_script) + { + bfd_set_error (bfd_error_file_not_recognized); + einfo ("%F%s: file not recognized: %E\n", ldfile_input_filename); + } + + if (! isprint ((unsigned char) *what)) + { + sprintf (buf, "\\%03o", (unsigned int) *what); + what = buf; + } + + einfo ("%P:%S: ignoring invalid character `%s'%s\n", what, where); +} diff --git a/ld/ldmain.c b/ld/ldmain.c new file mode 100644 index 0000000..1e710db --- /dev/null +++ b/ld/ldmain.c @@ -0,0 +1,1300 @@ +/* Main program of GNU linker. + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include <stdio.h> +#include <ctype.h> +#include "libiberty.h" +#include "progress.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldmisc.h" +#include "ldwrite.h" +#include "ldgram.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldemul.h" +#include "ldlex.h" +#include "ldfile.h" +#include "ldctor.h" + +/* Somewhere above, sys/stat.h got included . . . . */ +#if !defined(S_ISDIR) && defined(S_IFDIR) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +#include <string.h> + +#ifdef HAVE_SBRK +#ifdef NEED_DECLARATION_SBRK +extern PTR sbrk (); +#endif +#endif + +static char *get_emulation PARAMS ((int, char **)); +static void set_scripts_dir PARAMS ((void)); + +/* EXPORTS */ + +char *default_target; +const char *output_filename = "a.out"; + +/* Name this program was invoked by. */ +char *program_name; + +/* The file that we're creating */ +bfd *output_bfd = 0; + +/* Set by -G argument, for MIPS ECOFF target. */ +int g_switch_value = 8; + +/* Nonzero means print names of input files as processed. */ +boolean trace_files; + +/* Nonzero means same, but note open failures, too. */ +boolean trace_file_tries; + +/* Nonzero means version number was printed, so exit successfully + instead of complaining if no input files are given. */ +boolean version_printed; + +/* Nonzero means link in every member of an archive. */ +boolean whole_archive; + +/* True if we should demangle symbol names. */ +boolean demangling; + +args_type command_line; + +ld_config_type config; + +static void remove_output PARAMS ((void)); +static boolean check_for_scripts_dir PARAMS ((char *dir)); +static boolean add_archive_element PARAMS ((struct bfd_link_info *, bfd *, + const char *)); +static boolean multiple_definition PARAMS ((struct bfd_link_info *, + const char *, + bfd *, asection *, bfd_vma, + bfd *, asection *, bfd_vma)); +static boolean multiple_common PARAMS ((struct bfd_link_info *, + const char *, bfd *, + enum bfd_link_hash_type, bfd_vma, + bfd *, enum bfd_link_hash_type, + bfd_vma)); +static boolean add_to_set PARAMS ((struct bfd_link_info *, + struct bfd_link_hash_entry *, + bfd_reloc_code_real_type, + bfd *, asection *, bfd_vma)); +static boolean constructor_callback PARAMS ((struct bfd_link_info *, + boolean constructor, + const char *name, + bfd *, asection *, bfd_vma)); +static boolean warning_callback PARAMS ((struct bfd_link_info *, + const char *, const char *, bfd *, + asection *, bfd_vma)); +static void warning_find_reloc PARAMS ((bfd *, asection *, PTR)); +static boolean undefined_symbol PARAMS ((struct bfd_link_info *, + const char *, bfd *, + asection *, bfd_vma)); +static boolean reloc_overflow PARAMS ((struct bfd_link_info *, const char *, + const char *, bfd_vma, + bfd *, asection *, bfd_vma)); +static boolean reloc_dangerous PARAMS ((struct bfd_link_info *, const char *, + bfd *, asection *, bfd_vma)); +static boolean unattached_reloc PARAMS ((struct bfd_link_info *, + const char *, bfd *, asection *, + bfd_vma)); +static boolean notice PARAMS ((struct bfd_link_info *, const char *, + bfd *, asection *, bfd_vma)); + +static struct bfd_link_callbacks link_callbacks = +{ + add_archive_element, + multiple_definition, + multiple_common, + add_to_set, + constructor_callback, + warning_callback, + undefined_symbol, + reloc_overflow, + reloc_dangerous, + unattached_reloc, + notice +}; + +struct bfd_link_info link_info; + +static void +remove_output () +{ + if (output_filename) + { + if (output_bfd && output_bfd->iostream) + fclose((FILE *)(output_bfd->iostream)); + if (delete_output_file_on_failure) + unlink (output_filename); + } +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *emulation; + long start_time = get_run_time (); + +#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) + setlocale (LC_MESSAGES, ""); +#endif + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + program_name = argv[0]; + xmalloc_set_program_name (program_name); + + START_PROGRESS (program_name, 0); + + bfd_init (); + + bfd_set_error_program_name (program_name); + + xatexit (remove_output); + + /* Set the default BFD target based on the configured target. Doing + this permits the linker to be configured for a particular target, + and linked against a shared BFD library which was configured for + a different target. The macro TARGET is defined by Makefile. */ + if (! bfd_set_default_target (TARGET)) + { + einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET); + xexit (1); + } + + /* Initialize the data about options. */ + trace_files = trace_file_tries = version_printed = false; + whole_archive = false; + config.build_constructors = true; + config.dynamic_link = false; + config.has_shared = false; + command_line.force_common_definition = false; + command_line.interpreter = NULL; + command_line.rpath = NULL; + command_line.warn_mismatch = true; + command_line.check_section_addresses = true; + + /* We initialize DEMANGLING based on the environment variable + COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the + output of the linker, unless COLLECT_NO_DEMANGLE is set in the + environment. Acting the same way here lets us provide the same + interface by default. */ + demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL; + + link_info.callbacks = &link_callbacks; + link_info.relocateable = false; + link_info.shared = false; + link_info.symbolic = false; + link_info.static_link = false; + link_info.traditional_format = false; + link_info.optimize = false; + link_info.no_undefined = false; + link_info.strip = strip_none; + link_info.discard = discard_none; + link_info.keep_memory = true; + link_info.input_bfds = NULL; + link_info.create_object_symbols_section = NULL; + link_info.hash = NULL; + link_info.keep_hash = NULL; + link_info.notice_all = false; + link_info.notice_hash = NULL; + link_info.wrap_hash = NULL; + link_info.mpc860c0 = 0; + + ldfile_add_arch (""); + + config.make_executable = true; + force_make_executable = false; + config.magic_demand_paged = true; + config.text_read_only = true; + config.make_executable = true; + + emulation = get_emulation (argc, argv); + ldemul_choose_mode (emulation); + default_target = ldemul_choose_target (); + lang_init (); + ldemul_before_parse (); + lang_has_input_file = false; + parse_args (argc, argv); + + ldemul_set_symbols (); + + if (link_info.relocateable) + { + if (command_line.gc_sections) + einfo ("%P%F: --gc-sections and -r may not be used together\n"); + if (link_info.mpc860c0) + einfo (_("%P%F: -r and --mpc860c0 may not be used together\n")); + else if (command_line.relax) + einfo (_("%P%F: --relax and -r may not be used together\n")); + if (link_info.shared) + einfo (_("%P%F: -r and -shared may not be used together\n")); + } + + /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I + don't see how else this can be handled, since in this case we + must preserve all externally visible symbols. */ + if (link_info.relocateable && link_info.strip == strip_all) + { + link_info.strip = strip_debugger; + if (link_info.discard == discard_none) + link_info.discard = discard_all; + } + + /* This essentially adds another -L directory so this must be done after + the -L's in argv have been processed. */ + set_scripts_dir (); + + if (had_script == false) + { + /* Read the emulation's appropriate default script. */ + int isfile; + char *s = ldemul_get_script (&isfile); + + if (isfile) + ldfile_open_command_file (s); + else + { + if (trace_file_tries) + { + info_msg (_("using internal linker script:\n")); + info_msg ("==================================================\n"); + info_msg (s); + info_msg ("\n==================================================\n"); + } + lex_string = s; + lex_redirect (s); + } + parser_input = input_script; + yyparse (); + lex_string = NULL; + } + + lang_final (); + + if (lang_has_input_file == false) + { + if (version_printed) + xexit (0); + einfo (_("%P%F: no input files\n")); + } + + if (trace_files) + { + info_msg (_("%P: mode %s\n"), emulation); + } + + ldemul_after_parse (); + + + if (config.map_filename) + { + if (strcmp (config.map_filename, "-") == 0) + { + config.map_file = stdout; + } + else + { + config.map_file = fopen (config.map_filename, FOPEN_WT); + if (config.map_file == (FILE *) NULL) + { + bfd_set_error (bfd_error_system_call); + einfo (_("%P%F: cannot open map file %s: %E\n"), + config.map_filename); + } + } + } + + + lang_process (); + + /* Print error messages for any missing symbols, for any warning + symbols, and possibly multiple definitions */ + + + if (config.text_read_only) + { + /* Look for a text section and mark the readonly attribute in it */ + asection *found = bfd_get_section_by_name (output_bfd, ".text"); + + if (found != (asection *) NULL) + { + found->flags |= SEC_READONLY; + } + } + + if (link_info.relocateable) + output_bfd->flags &= ~EXEC_P; + else + output_bfd->flags |= EXEC_P; + + ldwrite (); + + if (config.map_file != NULL) + lang_map (); + if (command_line.cref) + output_cref (config.map_file != NULL ? config.map_file : stdout); + if (nocrossref_list != NULL) + check_nocrossrefs (); + + /* Even if we're producing relocateable output, some non-fatal errors should + be reported in the exit status. (What non-fatal errors, if any, do we + want to ignore for relocateable output?) */ + + if (config.make_executable == false && force_make_executable == false) + { + if (trace_files == true) + { + einfo (_("%P: link errors found, deleting executable `%s'\n"), + output_filename); + } + + /* The file will be removed by remove_output. */ + + xexit (1); + } + else + { + if (! bfd_close (output_bfd)) + einfo (_("%F%B: final close failed: %E\n"), output_bfd); + + /* If the --force-exe-suffix is enabled, and we're making an + executable file and it doesn't end in .exe, copy it to one which does. */ + + if (! link_info.relocateable && command_line.force_exe_suffix) + { + int len = strlen (output_filename); + if (len < 4 + || (strcasecmp (output_filename + len - 4, ".exe") != 0 + && strcasecmp (output_filename + len - 4, ".dll") != 0)) + { + FILE *src; + FILE *dst; + const int bsize = 4096; + char *buf = xmalloc (bsize); + int l; + char *dst_name = xmalloc (len + 5); + strcpy (dst_name, output_filename); + strcat (dst_name, ".exe"); + src = fopen (output_filename, FOPEN_RB); + dst = fopen (dst_name, FOPEN_WB); + + if (!src) + einfo (_("%X%P: unable to open for source of copy `%s'\n"), output_filename); + if (!dst) + einfo (_("%X%P: unable to open for destination of copy `%s'\n"), dst_name); + while ((l = fread (buf, 1, bsize, src)) > 0) + { + int done = fwrite (buf, 1, l, dst); + if (done != l) + { + einfo (_("%P: Error writing file `%s'\n"), dst_name); + } + } + fclose (src); + if (fclose (dst) == EOF) + { + einfo (_("%P: Error closing file `%s'\n"), dst_name); + } + free (dst_name); + free (buf); + } + } + } + + END_PROGRESS (program_name); + + if (config.stats) + { +#ifdef HAVE_SBRK + char *lim = (char *) sbrk (0); +#endif + long run_time = get_run_time () - start_time; + + fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"), + program_name, run_time / 1000000, run_time % 1000000); +#ifdef HAVE_SBRK + fprintf (stderr, _("%s: data size %ld\n"), program_name, + (long) (lim - (char *) &environ)); +#endif + } + + /* Prevent remove_output from doing anything, after a successful link. */ + output_filename = NULL; + + xexit (0); + return 0; +} + +/* We need to find any explicitly given emulation in order to initialize the + state that's needed by the lex&yacc argument parser (parse_args). */ + +static char * +get_emulation (argc, argv) + int argc; + char **argv; +{ + char *emulation; + int i; + + emulation = getenv (EMULATION_ENVIRON); + if (emulation == NULL) + emulation = DEFAULT_EMULATION; + + for (i = 1; i < argc; i++) + { + if (!strncmp (argv[i], "-m", 2)) + { + if (argv[i][2] == '\0') + { + /* -m EMUL */ + if (i < argc - 1) + { + emulation = argv[i + 1]; + i++; + } + else + { + einfo(_("%P%F: missing argument to -m\n")); + } + } + else if (strcmp (argv[i], "-mips1") == 0 + || strcmp (argv[i], "-mips2") == 0 + || strcmp (argv[i], "-mips3") == 0 + || strcmp (argv[i], "-mips4") == 0) + { + /* FIXME: The arguments -mips1, -mips2 and -mips3 are + passed to the linker by some MIPS compilers. They + generally tell the linker to use a slightly different + library path. Perhaps someday these should be + implemented as emulations; until then, we just ignore + the arguments and hope that nobody ever creates + emulations named ips1, ips2 or ips3. */ + } + else if (strcmp (argv[i], "-m486") == 0) + { + /* FIXME: The argument -m486 is passed to the linker on + some Linux systems. Hope that nobody creates an + emulation named 486. */ + } + else + { + /* -mEMUL */ + emulation = &argv[i][2]; + } + } + } + + return emulation; +} + +/* If directory DIR contains an "ldscripts" subdirectory, + add DIR to the library search path and return true, + else return false. */ + +static boolean +check_for_scripts_dir (dir) + char *dir; +{ + size_t dirlen; + char *buf; + struct stat s; + boolean res; + + dirlen = strlen (dir); + /* sizeof counts the terminating NUL. */ + buf = (char *) xmalloc (dirlen + sizeof("/ldscripts")); + sprintf (buf, "%s/ldscripts", dir); + + res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode); + free (buf); + if (res) + ldfile_add_library_path (dir, false); + return res; +} + +/* Set the default directory for finding script files. + Libraries will be searched for here too, but that's ok. + We look for the "ldscripts" directory in: + + SCRIPTDIR (passed from Makefile) + the dir where this program is (for using it from the build tree) + the dir where this program is/../lib (for installing the tool suite elsewhere) */ + +static void +set_scripts_dir () +{ + char *end, *dir; + size_t dirlen; + + if (check_for_scripts_dir (SCRIPTDIR)) + return; /* We've been installed normally. */ + + /* Look for "ldscripts" in the dir where our binary is. */ + end = strrchr (program_name, '/'); + + if (end == NULL) + { + /* Don't look for ldscripts in the current directory. There is + too much potential for confusion. */ + return; + } + + dirlen = end - program_name; + /* Make a copy of program_name in dir. + Leave room for later "/../lib". */ + dir = (char *) xmalloc (dirlen + 8); + strncpy (dir, program_name, dirlen); + dir[dirlen] = '\0'; + + if (check_for_scripts_dir (dir)) + return; /* Don't free dir. */ + + /* Look for "ldscripts" in <the dir where our binary is>/../lib. */ + strcpy (dir + dirlen, "/../lib"); + if (check_for_scripts_dir (dir)) + return; + + free (dir); /* Well, we tried. */ +} + +void +add_ysym (name) + const char *name; +{ + if (link_info.notice_hash == (struct bfd_hash_table *) NULL) + { + link_info.notice_hash = ((struct bfd_hash_table *) + xmalloc (sizeof (struct bfd_hash_table))); + if (! bfd_hash_table_init_n (link_info.notice_hash, + bfd_hash_newfunc, + 61)) + einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); + } + + if (bfd_hash_lookup (link_info.notice_hash, name, true, true) + == (struct bfd_hash_entry *) NULL) + einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); +} + +/* Record a symbol to be wrapped, from the --wrap option. */ + +void +add_wrap (name) + const char *name; +{ + if (link_info.wrap_hash == NULL) + { + link_info.wrap_hash = ((struct bfd_hash_table *) + xmalloc (sizeof (struct bfd_hash_table))); + if (! bfd_hash_table_init_n (link_info.wrap_hash, + bfd_hash_newfunc, + 61)) + einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); + } + if (bfd_hash_lookup (link_info.wrap_hash, name, true, true) == NULL) + einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); +} + +/* Handle the -retain-symbols-file option. */ + +void +add_keepsyms_file (filename) + const char *filename; +{ + FILE *file; + char *buf; + size_t bufsize; + int c; + + if (link_info.strip == strip_some) + einfo (_("%X%P: error: duplicate retain-symbols-file\n")); + + file = fopen (filename, "r"); + if (file == (FILE *) NULL) + { + bfd_set_error (bfd_error_system_call); + einfo ("%X%P: %s: %E\n", filename); + return; + } + + link_info.keep_hash = ((struct bfd_hash_table *) + xmalloc (sizeof (struct bfd_hash_table))); + if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc)) + einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); + + bufsize = 100; + buf = (char *) xmalloc (bufsize); + + c = getc (file); + while (c != EOF) + { + while (isspace (c)) + c = getc (file); + + if (c != EOF) + { + size_t len = 0; + + while (! isspace (c) && c != EOF) + { + buf[len] = c; + ++len; + if (len >= bufsize) + { + bufsize *= 2; + buf = xrealloc (buf, bufsize); + } + c = getc (file); + } + + buf[len] = '\0'; + + if (bfd_hash_lookup (link_info.keep_hash, buf, true, true) + == (struct bfd_hash_entry *) NULL) + einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n")); + } + } + + if (link_info.strip != strip_none) + einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n")); + + link_info.strip = strip_some; +} + +/* Callbacks from the BFD linker routines. */ + +/* This is called when BFD has decided to include an archive member in + a link. */ + +/*ARGSUSED*/ +static boolean +add_archive_element (info, abfd, name) + struct bfd_link_info *info; + bfd *abfd; + const char *name; +{ + lang_input_statement_type *input; + + input = ((lang_input_statement_type *) + xmalloc (sizeof (lang_input_statement_type))); + input->filename = abfd->filename; + input->local_sym_name = abfd->filename; + input->the_bfd = abfd; + input->asymbols = NULL; + input->next = NULL; + input->just_syms_flag = false; + input->loaded = false; + input->search_dirs_flag = false; + + /* FIXME: The following fields are not set: header.next, + header.type, closed, passive_position, symbol_count, + next_real_file, is_archive, target, real. This bit of code is + from the old decode_library_subfile function. I don't know + whether any of those fields matters. */ + + ldlang_add_file (input); + + if (config.map_file != (FILE *) NULL) + { + static boolean header_printed; + struct bfd_link_hash_entry *h; + bfd *from; + int len; + + h = bfd_link_hash_lookup (link_info.hash, name, false, false, true); + + if (h == NULL) + from = NULL; + else + { + switch (h->type) + { + default: + from = NULL; + break; + + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + from = h->u.def.section->owner; + break; + + case bfd_link_hash_undefined: + case bfd_link_hash_undefweak: + from = h->u.undef.abfd; + break; + + case bfd_link_hash_common: + from = h->u.c.p->section->owner; + break; + } + } + + if (! header_printed) + { + char buf[100]; + + sprintf (buf, "%-29s %s\n\n", _("Archive member included"), + _("because of file (symbol)")); + minfo ("%s", buf); + header_printed = true; + } + + if (bfd_my_archive (abfd) == NULL) + { + minfo ("%s", bfd_get_filename (abfd)); + len = strlen (bfd_get_filename (abfd)); + } + else + { + minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)), + bfd_get_filename (abfd)); + len = (strlen (bfd_get_filename (bfd_my_archive (abfd))) + + strlen (bfd_get_filename (abfd)) + + 2); + } + + if (len >= 29) + { + print_nl (); + len = 0; + } + while (len < 30) + { + print_space (); + ++len; + } + + if (from != NULL) + minfo ("%B ", from); + if (h != NULL) + minfo ("(%T)\n", h->root.string); + else + minfo ("(%s)\n", name); + } + + if (trace_files || trace_file_tries) + info_msg ("%I\n", input); + + return true; +} + +/* This is called when BFD has discovered a symbol which is defined + multiple times. */ + +/*ARGSUSED*/ +static boolean +multiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval) + struct bfd_link_info *info; + const char *name; + bfd *obfd; + asection *osec; + bfd_vma oval; + bfd *nbfd; + asection *nsec; + bfd_vma nval; +{ + /* If either section has the output_section field set to + bfd_abs_section_ptr, it means that the section is being + discarded, and this is not really a multiple definition at all. + FIXME: It would be cleaner to somehow ignore symbols defined in + sections which are being discarded. */ + if ((osec->output_section != NULL + && ! bfd_is_abs_section (osec) + && bfd_is_abs_section (osec->output_section)) + || (nsec->output_section != NULL + && ! bfd_is_abs_section (nsec) + && bfd_is_abs_section (nsec->output_section))) + return true; + + einfo (_("%X%C: multiple definition of `%T'\n"), + nbfd, nsec, nval, name); + if (obfd != (bfd *) NULL) + einfo (_("%D: first defined here\n"), obfd, osec, oval); + return true; +} + +/* This is called when there is a definition of a common symbol, or + when a common symbol is found for a symbol that is already defined, + or when two common symbols are found. We only do something if + -warn-common was used. */ + +/*ARGSUSED*/ +static boolean +multiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize) + struct bfd_link_info *info; + const char *name; + bfd *obfd; + enum bfd_link_hash_type otype; + bfd_vma osize; + bfd *nbfd; + enum bfd_link_hash_type ntype; + bfd_vma nsize; +{ + if (! config.warn_common) + return true; + + if (ntype == bfd_link_hash_defined + || ntype == bfd_link_hash_defweak + || ntype == bfd_link_hash_indirect) + { + ASSERT (otype == bfd_link_hash_common); + einfo (_("%B: warning: definition of `%T' overriding common\n"), + nbfd, name); + if (obfd != NULL) + einfo (_("%B: warning: common is here\n"), obfd); + } + else if (otype == bfd_link_hash_defined + || otype == bfd_link_hash_defweak + || otype == bfd_link_hash_indirect) + { + ASSERT (ntype == bfd_link_hash_common); + einfo (_("%B: warning: common of `%T' overridden by definition\n"), + nbfd, name); + if (obfd != NULL) + einfo (_("%B: warning: defined here\n"), obfd); + } + else + { + ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common); + if (osize > nsize) + { + einfo (_("%B: warning: common of `%T' overridden by larger common\n"), + nbfd, name); + if (obfd != NULL) + einfo (_("%B: warning: larger common is here\n"), obfd); + } + else if (nsize > osize) + { + einfo (_("%B: warning: common of `%T' overriding smaller common\n"), + nbfd, name); + if (obfd != NULL) + einfo (_("%B: warning: smaller common is here\n"), obfd); + } + else + { + einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name); + if (obfd != NULL) + einfo (_("%B: warning: previous common is here\n"), obfd); + } + } + + return true; +} + +/* This is called when BFD has discovered a set element. H is the + entry in the linker hash table for the set. SECTION and VALUE + represent a value which should be added to the set. */ + +/*ARGSUSED*/ +static boolean +add_to_set (info, h, reloc, abfd, section, value) + struct bfd_link_info *info; + struct bfd_link_hash_entry *h; + bfd_reloc_code_real_type reloc; + bfd *abfd; + asection *section; + bfd_vma value; +{ + if (config.warn_constructors) + einfo (_("%P: warning: global constructor %s used\n"), + h->root.string); + + if (! config.build_constructors) + return true; + + ldctor_add_set_entry (h, reloc, (const char *) NULL, section, value); + + if (h->type == bfd_link_hash_new) + { + h->type = bfd_link_hash_undefined; + h->u.undef.abfd = abfd; + /* We don't call bfd_link_add_undef to add this to the list of + undefined symbols because we are going to define it + ourselves. */ + } + + return true; +} + +/* This is called when BFD has discovered a constructor. This is only + called for some object file formats--those which do not handle + constructors in some more clever fashion. This is similar to + adding an element to a set, but less general. */ + +static boolean +constructor_callback (info, constructor, name, abfd, section, value) + struct bfd_link_info *info; + boolean constructor; + const char *name; + bfd *abfd; + asection *section; + bfd_vma value; +{ + char *s; + struct bfd_link_hash_entry *h; + char set_name[1 + sizeof "__CTOR_LIST__"]; + + if (config.warn_constructors) + einfo (_("%P: warning: global constructor %s used\n"), name); + + if (! config.build_constructors) + return true; + + /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a + useful error message. */ + if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL + && (link_info.relocateable + || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL)) + einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n")); + + s = set_name; + if (bfd_get_symbol_leading_char (abfd) != '\0') + *s++ = bfd_get_symbol_leading_char (abfd); + if (constructor) + strcpy (s, "__CTOR_LIST__"); + else + strcpy (s, "__DTOR_LIST__"); + + h = bfd_link_hash_lookup (info->hash, set_name, true, true, true); + if (h == (struct bfd_link_hash_entry *) NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + if (h->type == bfd_link_hash_new) + { + h->type = bfd_link_hash_undefined; + h->u.undef.abfd = abfd; + /* We don't call bfd_link_add_undef to add this to the list of + undefined symbols because we are going to define it + ourselves. */ + } + + ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value); + return true; +} + +/* A structure used by warning_callback to pass information through + bfd_map_over_sections. */ + +struct warning_callback_info +{ + boolean found; + const char *warning; + const char *symbol; + asymbol **asymbols; +}; + +/* This is called when there is a reference to a warning symbol. */ + +/*ARGSUSED*/ +static boolean +warning_callback (info, warning, symbol, abfd, section, address) + struct bfd_link_info *info; + const char *warning; + const char *symbol; + bfd *abfd; + asection *section; + bfd_vma address; +{ + /* This is a hack to support warn_multiple_gp. FIXME: This should + have a cleaner interface, but what? */ + if (! config.warn_multiple_gp + && strcmp (warning, "using multiple gp values") == 0) + return true; + + if (section != NULL) + einfo ("%C: %s\n", abfd, section, address, warning); + else if (abfd == NULL) + einfo ("%P: %s\n", warning); + else if (symbol == NULL) + einfo ("%B: %s\n", abfd, warning); + else + { + lang_input_statement_type *entry; + asymbol **asymbols; + struct warning_callback_info info; + + /* Look through the relocs to see if we can find a plausible + address. */ + + entry = (lang_input_statement_type *) abfd->usrdata; + if (entry != NULL && entry->asymbols != NULL) + asymbols = entry->asymbols; + else + { + long symsize; + long symbol_count; + + symsize = bfd_get_symtab_upper_bound (abfd); + if (symsize < 0) + einfo (_("%B%F: could not read symbols: %E\n"), abfd); + asymbols = (asymbol **) xmalloc (symsize); + symbol_count = bfd_canonicalize_symtab (abfd, asymbols); + if (symbol_count < 0) + einfo (_("%B%F: could not read symbols: %E\n"), abfd); + if (entry != NULL) + { + entry->asymbols = asymbols; + entry->symbol_count = symbol_count; + } + } + + info.found = false; + info.warning = warning; + info.symbol = symbol; + info.asymbols = asymbols; + bfd_map_over_sections (abfd, warning_find_reloc, (PTR) &info); + + if (! info.found) + einfo ("%B: %s\n", abfd, warning); + + if (entry == NULL) + free (asymbols); + } + + return true; +} + +/* This is called by warning_callback for each section. It checks the + relocs of the section to see if it can find a reference to the + symbol which triggered the warning. If it can, it uses the reloc + to give an error message with a file and line number. */ + +static void +warning_find_reloc (abfd, sec, iarg) + bfd *abfd; + asection *sec; + PTR iarg; +{ + struct warning_callback_info *info = (struct warning_callback_info *) iarg; + long relsize; + arelent **relpp; + long relcount; + arelent **p, **pend; + + if (info->found) + return; + + relsize = bfd_get_reloc_upper_bound (abfd, sec); + if (relsize < 0) + einfo (_("%B%F: could not read relocs: %E\n"), abfd); + if (relsize == 0) + return; + + relpp = (arelent **) xmalloc (relsize); + relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols); + if (relcount < 0) + einfo (_("%B%F: could not read relocs: %E\n"), abfd); + + p = relpp; + pend = p + relcount; + for (; p < pend && *p != NULL; p++) + { + arelent *q = *p; + + if (q->sym_ptr_ptr != NULL + && *q->sym_ptr_ptr != NULL + && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0) + { + /* We found a reloc for the symbol we are looking for. */ + einfo ("%C: %s\n", abfd, sec, q->address, info->warning); + info->found = true; + break; + } + } + + free (relpp); +} + +/* This is called when an undefined symbol is found. */ + +/*ARGSUSED*/ +static boolean +undefined_symbol (info, name, abfd, section, address) + struct bfd_link_info *info; + const char *name; + bfd *abfd; + asection *section; + bfd_vma address; +{ + static char *error_name; + static unsigned int error_count; + +#define MAX_ERRORS_IN_A_ROW 5 + + if (config.warn_once) + { + static struct bfd_hash_table *hash; + + /* Only warn once about a particular undefined symbol. */ + + if (hash == NULL) + { + hash = ((struct bfd_hash_table *) + xmalloc (sizeof (struct bfd_hash_table))); + if (! bfd_hash_table_init (hash, bfd_hash_newfunc)) + einfo (_("%F%P: bfd_hash_table_init failed: %E\n")); + } + + if (bfd_hash_lookup (hash, name, false, false) != NULL) + return true; + + if (bfd_hash_lookup (hash, name, true, true) == NULL) + einfo (_("%F%P: bfd_hash_lookup failed: %E\n")); + } + + /* We never print more than a reasonable number of errors in a row + for a single symbol. */ + if (error_name != (char *) NULL + && strcmp (name, error_name) == 0) + ++error_count; + else + { + error_count = 0; + if (error_name != (char *) NULL) + free (error_name); + error_name = buystring (name); + } + + if (section != NULL) + { + if (error_count < MAX_ERRORS_IN_A_ROW) + einfo (_("%X%C: undefined reference to `%T'\n"), + abfd, section, address, name); + else if (error_count == MAX_ERRORS_IN_A_ROW) + einfo (_("%D: more undefined references to `%T' follow\n"), + abfd, section, address, name); + } + else + { + if (error_count < MAX_ERRORS_IN_A_ROW) + einfo (_("%X%B: undefined reference to `%T'\n"), + abfd, name); + else if (error_count == MAX_ERRORS_IN_A_ROW) + einfo (_("%B: more undefined references to `%T' follow\n"), + abfd, name); + } + + return true; +} + +/* This is called when a reloc overflows. */ + +/*ARGSUSED*/ +static boolean +reloc_overflow (info, name, reloc_name, addend, abfd, section, address) + struct bfd_link_info *info; + const char *name; + const char *reloc_name; + bfd_vma addend; + bfd *abfd; + asection *section; + bfd_vma address; +{ + if (abfd == (bfd *) NULL) + einfo (_("%P%X: generated")); + else + einfo ("%X%C:", abfd, section, address); + einfo (_(" relocation truncated to fit: %s %T"), reloc_name, name); + if (addend != 0) + einfo ("+%v", addend); + einfo ("\n"); + return true; +} + +/* This is called when a dangerous relocation is made. */ + +/*ARGSUSED*/ +static boolean +reloc_dangerous (info, message, abfd, section, address) + struct bfd_link_info *info; + const char *message; + bfd *abfd; + asection *section; + bfd_vma address; +{ + if (abfd == (bfd *) NULL) + einfo (_("%P%X: generated")); + else + einfo ("%X%C:", abfd, section, address); + einfo (_("dangerous relocation: %s\n"), message); + return true; +} + +/* This is called when a reloc is being generated attached to a symbol + that is not being output. */ + +/*ARGSUSED*/ +static boolean +unattached_reloc (info, name, abfd, section, address) + struct bfd_link_info *info; + const char *name; + bfd *abfd; + asection *section; + bfd_vma address; +{ + if (abfd == (bfd *) NULL) + einfo (_("%P%X: generated")); + else + einfo ("%X%C:", abfd, section, address); + einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name); + return true; +} + +/* This is called if link_info.notice_all is set, or when a symbol in + link_info.notice_hash is found. Symbols are put in notice_hash + using the -y option. */ + +static boolean +notice (info, name, abfd, section, value) + struct bfd_link_info *info; + const char *name; + bfd *abfd; + asection *section; + bfd_vma value; +{ + if (! info->notice_all + || (info->notice_hash != NULL + && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL)) + { + if (bfd_is_und_section (section)) + einfo ("%B: reference to %s\n", abfd, name); + else + einfo ("%B: definition of %s\n", abfd, name); + } + + if (command_line.cref || nocrossref_list != NULL) + add_cref (name, abfd, section, value); + + return true; +} diff --git a/ld/ldmain.h b/ld/ldmain.h new file mode 100644 index 0000000..041bf3d --- /dev/null +++ b/ld/ldmain.h @@ -0,0 +1,40 @@ +/* ldmain.h - + Copyright 1991, 92, 93, 94, 95, 96, 1999 Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef LDMAIN_H +#define LDMAIN_H + +extern char *program_name; +extern bfd *output_bfd; +extern char *default_target; +extern boolean trace_files; +extern boolean trace_file_tries; +extern boolean version_printed; +extern boolean whole_archive; +extern boolean demangling; +extern int g_switch_value; +extern const char *output_filename; +extern struct bfd_link_info link_info; + +extern void add_ysym PARAMS ((const char *)); +extern void add_wrap PARAMS ((const char *)); +extern void add_keepsyms_file PARAMS ((const char *filename)); + +#endif diff --git a/ld/ldmisc.c b/ld/ldmisc.c new file mode 100644 index 0000000..8fab228 --- /dev/null +++ b/ld/ldmisc.c @@ -0,0 +1,538 @@ +/* ldmisc.c + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. + Written by Steve Chamberlain of Cygnus Support. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libiberty.h" +#include "demangle.h" + +#ifdef ANSI_PROTOTYPES +#include <stdarg.h> +#define USE_STDARG 1 +#else +#include <varargs.h> +#define USE_STDARG 0 +#endif + +#include "ld.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldgram.h" +#include "ldlex.h" +#include "ldmain.h" +#include "ldfile.h" + +static void vfinfo PARAMS ((FILE *, const char *, va_list)); + +/* + %% literal % + %F error is fatal + %P print program name + %S print script file and linenumber + %E current bfd error or errno + %I filename from a lang_input_statement_type + %B filename from a bfd + %T symbol name + %X no object output, fail return + %V hex bfd_vma + %v hex bfd_vma, no leading zeros + %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces + %C clever filename:linenumber with function + %D like %C, but no function name + %G like %D, but only function name + %R info about a relent + %s arbitrary string, like printf + %d integer, like printf + %u integer, like printf +*/ + +char * +demangle (string) + const char *string; +{ + char *res; + + if (output_bfd != NULL + && bfd_get_symbol_leading_char (output_bfd) == string[0]) + ++string; + + /* This is a hack for better error reporting on XCOFF, or the MS PE */ + /* format. Xcoff has a single '.', while the NT PE for PPC has '..'. */ + /* So we remove all of them. */ + while(string[0] == '.') + ++string; + + res = cplus_demangle (string, DMGL_ANSI | DMGL_PARAMS); + return res ? res : xstrdup (string); +} + +static void +vfinfo (fp, fmt, arg) + FILE *fp; + const char *fmt; + va_list arg; +{ + boolean fatal = false; + + while (*fmt != '\0') + { + while (*fmt != '%' && *fmt != '\0') + { + putc (*fmt, fp); + fmt++; + } + + if (*fmt == '%') + { + fmt ++; + switch (*fmt++) + { + default: + fprintf (fp,"%%%c", fmt[-1]); + break; + + case '%': + /* literal % */ + putc ('%', fp); + break; + + case 'X': + /* no object output, fail return */ + config.make_executable = false; + break; + + case 'V': + /* hex bfd_vma */ + { + bfd_vma value = va_arg (arg, bfd_vma); + fprintf_vma (fp, value); + } + break; + + case 'v': + /* hex bfd_vma, no leading zeros */ + { + char buf[100]; + char *p = buf; + bfd_vma value = va_arg (arg, bfd_vma); + sprintf_vma (p, value); + while (*p == '0') + p++; + if (!*p) + p--; + fputs (p, fp); + } + break; + + case 'W': + /* hex bfd_vma with 0x with no leading zeroes taking up + 8 spaces. */ + { + char buf[100]; + bfd_vma value; + char *p; + int len; + + value = va_arg (arg, bfd_vma); + sprintf_vma (buf, value); + for (p = buf; *p == '0'; ++p) + ; + if (*p == '\0') + --p; + len = strlen (p); + while (len < 8) + { + putc (' ', fp); + ++len; + } + fprintf (fp, "0x%s", p); + } + break; + + case 'T': + /* Symbol name. */ + { + const char *name = va_arg (arg, const char *); + + if (name == (const char *) NULL || *name == 0) + fprintf (fp, _("no symbol")); + else if (! demangling) + fprintf (fp, "%s", name); + else + { + char *demangled; + + demangled = demangle (name); + fprintf (fp, "%s", demangled); + free (demangled); + } + } + break; + + case 'B': + /* filename from a bfd */ + { + bfd *abfd = va_arg (arg, bfd *); + if (abfd->my_archive) + fprintf (fp, "%s(%s)", abfd->my_archive->filename, + abfd->filename); + else + fprintf (fp, "%s", abfd->filename); + } + break; + + case 'F': + /* error is fatal */ + fatal = true; + break; + + case 'P': + /* print program name */ + fprintf (fp, "%s", program_name); + break; + + case 'E': + /* current bfd error or errno */ + fprintf (fp, bfd_errmsg (bfd_get_error ())); + break; + + case 'I': + /* filename from a lang_input_statement_type */ + { + lang_input_statement_type *i; + + i = va_arg (arg, lang_input_statement_type *); + if (bfd_my_archive (i->the_bfd) != NULL) + fprintf (fp, "(%s)", + bfd_get_filename (bfd_my_archive (i->the_bfd))); + fprintf (fp, "%s", i->local_sym_name); + if (bfd_my_archive (i->the_bfd) == NULL + && strcmp (i->local_sym_name, i->filename) != 0) + fprintf (fp, " (%s)", i->filename); + } + break; + + case 'S': + /* print script file and linenumber */ + if (parsing_defsym) + fprintf (fp, "--defsym %s", lex_string); + else if (ldfile_input_filename != NULL) + fprintf (fp, "%s:%u", ldfile_input_filename, lineno); + else + fprintf (fp, _("built in linker script:%u"), lineno); + break; + + case 'R': + /* Print all that's interesting about a relent */ + { + arelent *relent = va_arg (arg, arelent *); + + lfinfo (fp, "%s+0x%v (type %s)", + (*(relent->sym_ptr_ptr))->name, + relent->addend, + relent->howto->name); + } + break; + + case 'C': + case 'D': + case 'G': + /* Clever filename:linenumber with function name if possible, + or section name as a last resort. The arguments are a BFD, + a section, and an offset. */ + { + static bfd *last_bfd; + static char *last_file = NULL; + static char *last_function = NULL; + bfd *abfd; + asection *section; + bfd_vma offset; + lang_input_statement_type *entry; + asymbol **asymbols; + const char *filename; + const char *functionname; + unsigned int linenumber; + boolean discard_last; + + abfd = va_arg (arg, bfd *); + section = va_arg (arg, asection *); + offset = va_arg (arg, bfd_vma); + + entry = (lang_input_statement_type *) abfd->usrdata; + if (entry != (lang_input_statement_type *) NULL + && entry->asymbols != (asymbol **) NULL) + asymbols = entry->asymbols; + else + { + long symsize; + long symbol_count; + + symsize = bfd_get_symtab_upper_bound (abfd); + if (symsize < 0) + einfo (_("%B%F: could not read symbols\n"), abfd); + asymbols = (asymbol **) xmalloc (symsize); + symbol_count = bfd_canonicalize_symtab (abfd, asymbols); + if (symbol_count < 0) + einfo (_("%B%F: could not read symbols\n"), abfd); + if (entry != (lang_input_statement_type *) NULL) + { + entry->asymbols = asymbols; + entry->symbol_count = symbol_count; + } + } + + discard_last = true; + if (bfd_find_nearest_line (abfd, section, asymbols, offset, + &filename, &functionname, + &linenumber)) + { + if (functionname != NULL && fmt[-1] == 'G') + { + lfinfo (fp, "%B:", abfd); + if (filename != NULL + && strcmp (filename, bfd_get_filename (abfd)) != 0) + fprintf (fp, "%s:", filename); + lfinfo (fp, "%T", functionname); + } + else if (functionname != NULL && fmt[-1] == 'C') + { + if (filename == (char *) NULL) + filename = abfd->filename; + + if (last_bfd == NULL + || last_file == NULL + || last_function == NULL + || last_bfd != abfd + || strcmp (last_file, filename) != 0 + || strcmp (last_function, functionname) != 0) + { + /* We use abfd->filename in this initial line, + in case filename is a .h file or something + similarly unhelpful. */ + lfinfo (fp, _("%B: In function `%T':\n"), + abfd, functionname); + + last_bfd = abfd; + if (last_file != NULL) + free (last_file); + last_file = buystring (filename); + if (last_function != NULL) + free (last_function); + last_function = buystring (functionname); + } + discard_last = false; + if (linenumber != 0) + fprintf (fp, "%s:%u", filename, linenumber); + else + lfinfo (fp, "%s(%s+0x%v)", filename, section->name, + offset); + } + else if (filename == NULL + || strcmp (filename, abfd->filename) == 0) + { + lfinfo (fp, "%B(%s+0x%v)", abfd, section->name, + offset); + if (linenumber != 0) + lfinfo (fp, ":%u", linenumber); + } + else if (linenumber != 0) + lfinfo (fp, "%B:%s:%u", abfd, filename, linenumber); + else + lfinfo (fp, "%B(%s+0x%v):%s", abfd, section->name, + offset, filename); + } + else + lfinfo (fp, "%B(%s+0x%v)", abfd, section->name, offset); + + if (discard_last) + { + last_bfd = NULL; + if (last_file != NULL) + { + free (last_file); + last_file = NULL; + } + if (last_function != NULL) + { + free (last_function); + last_function = NULL; + } + } + } + break; + + case 's': + /* arbitrary string, like printf */ + fprintf (fp, "%s", va_arg (arg, char *)); + break; + + case 'd': + /* integer, like printf */ + fprintf (fp, "%d", va_arg (arg, int)); + break; + + case 'u': + /* unsigned integer, like printf */ + fprintf (fp, "%u", va_arg (arg, unsigned int)); + break; + } + } + } + + if (fatal == true) + xexit(1); +} + +/* Format info message and print on stdout. */ + +/* (You would think this should be called just "info", but then you + would hosed by LynxOS, which defines that name in its libc.) */ + +void +#if USE_STDARG +info_msg (const char *fmt, ...) +#else +info_msg (va_alist) + va_dcl +#endif +{ + va_list arg; + +#if ! USE_STDARG + const char *fmt; + + va_start (arg); + fmt = va_arg (arg, const char *); +#else + va_start (arg, fmt); +#endif + + vfinfo (stdout, fmt, arg); + va_end (arg); +} + +/* ('e' for error.) Format info message and print on stderr. */ + +void +#if USE_STDARG +einfo (const char *fmt, ...) +#else +einfo (va_alist) + va_dcl +#endif +{ + va_list arg; + +#if ! USE_STDARG + const char *fmt; + + va_start (arg); + fmt = va_arg (arg, const char *); +#else + va_start (arg, fmt); +#endif + + vfinfo (stderr, fmt, arg); + va_end (arg); +} + +void +info_assert (file, line) + const char *file; + unsigned int line; +{ + einfo (_("%F%P: internal error %s %d\n"), file, line); +} + +char * +buystring (x) + CONST char *CONST x; +{ + size_t l = strlen(x)+1; + char *r = xmalloc(l); + memcpy(r, x,l); + return r; +} + +/* ('m' for map) Format info message and print on map. */ + +void +#if USE_STDARG +minfo (const char *fmt, ...) +#else +minfo (va_alist) + va_dcl +#endif +{ + va_list arg; + +#if ! USE_STDARG + const char *fmt; + va_start (arg); + fmt = va_arg (arg, const char *); +#else + va_start (arg, fmt); +#endif + + vfinfo (config.map_file, fmt, arg); + va_end (arg); +} + +void +#if USE_STDARG +lfinfo (FILE *file, const char *fmt, ...) +#else +lfinfo (va_alist) + va_dcl +#endif +{ + va_list arg; + +#if ! USE_STDARG + FILE *file; + const char *fmt; + + va_start (arg); + file = va_arg (arg, FILE *); + fmt = va_arg (arg, const char *); +#else + va_start (arg, fmt); +#endif + + vfinfo (file, fmt, arg); + va_end (arg); +} + +/* Functions to print the link map. */ + +void +print_space () +{ + fprintf (config.map_file, " "); +} + +void +print_nl () +{ + fprintf (config.map_file, "\n"); +} diff --git a/ld/ldmisc.h b/ld/ldmisc.h new file mode 100644 index 0000000..f5b3b4f --- /dev/null +++ b/ld/ldmisc.h @@ -0,0 +1,56 @@ +/* ldmisc.h - + Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef LDMISC_H +#define LDMISC_H + +#ifdef ANSI_PROTOTYPES +extern void einfo PARAMS ((const char *, ...)); +extern void minfo PARAMS ((const char *, ...)); +extern void info_msg PARAMS ((const char *, ...)); +extern void lfinfo PARAMS ((FILE *, const char *, ...)); +#else +/* VARARGS*/ +extern void einfo (); +/* VARARGS*/ +extern void minfo (); +/* VARARGS*/ +extern void info_msg (); +/*VARARGS*/ +extern void lfinfo (); +#endif + +extern void info_assert PARAMS ((const char *, unsigned int)); +extern void yyerror PARAMS ((const char *)); +extern PTR xmalloc PARAMS ((size_t)); +extern PTR xrealloc PARAMS ((PTR, size_t)); +extern void xexit PARAMS ((int)); +extern char *buystring PARAMS ((CONST char *CONST)); + +#define ASSERT(x) \ +do { if (!(x)) info_assert(__FILE__,__LINE__); } while (0) + +#define FAIL() \ +do { info_assert(__FILE__,__LINE__); } while (0) + +extern void print_space PARAMS ((void)); +extern void print_nl PARAMS ((void)); +extern char *demangle PARAMS ((const char *)); + +#endif diff --git a/ld/ldver.c b/ld/ldver.c new file mode 100644 index 0000000..5b600a2 --- /dev/null +++ b/ld/ldver.c @@ -0,0 +1,49 @@ +/* ldver.c -- Print linker version. + Copyright (C) 1991, 92, 93, 94, 95, 1996, 1998 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include <stdio.h> +#include "bfd.h" +#include "sysdep.h" + +#include "ld.h" +#include "ldver.h" +#include "ldemul.h" +#include "ldmain.h" + +const char *ld_program_version = VERSION; + +void +ldversion (noisy) + int noisy; +{ + fprintf (stdout, _("GNU ld version %s (with BFD %s)\n"), + ld_program_version, BFD_VERSION); + + if (noisy) + { + ld_emulation_xfer_type **ptr = ld_emulations; + + printf (_(" Supported emulations:\n")); + while (*ptr) + { + printf (" %s\n", (*ptr)->emulation_name); + ptr++; + } + } +} diff --git a/ld/ldver.h b/ld/ldver.h new file mode 100644 index 0000000..697b6bc --- /dev/null +++ b/ld/ldver.h @@ -0,0 +1,22 @@ +/* ldver.h -- Header file for ldver.c. + Copyright (C) 1991, 92, 93, 95, 1996 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +extern const char *ld_program_version; + +void ldversion PARAMS ((int)); diff --git a/ld/ldwrite.c b/ld/ldwrite.c new file mode 100644 index 0000000..b56119a --- /dev/null +++ b/ld/ldwrite.c @@ -0,0 +1,530 @@ +/* ldwrite.c -- write out the linked file + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 + Free Software Foundation, Inc. + Written by Steve Chamberlain sac@cygnus.com + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libiberty.h" + +#include "ld.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldwrite.h" +#include "ldmisc.h" +#include "ldgram.h" +#include "ldmain.h" + +static void build_link_order PARAMS ((lang_statement_union_type *)); +static asection *clone_section PARAMS ((bfd *, asection *, int *)); +static void split_sections PARAMS ((bfd *, struct bfd_link_info *)); + +/* Build link_order structures for the BFD linker. */ + +static void +build_link_order (statement) + lang_statement_union_type *statement; +{ + switch (statement->header.type) + { + case lang_data_statement_enum: + { + asection *output_section; + struct bfd_link_order *link_order; + bfd_vma value; + boolean big_endian = false; + + output_section = statement->data_statement.output_section; + ASSERT (output_section->owner == output_bfd); + + link_order = bfd_new_link_order (output_bfd, output_section); + if (link_order == NULL) + einfo (_("%P%F: bfd_new_link_order failed\n")); + + link_order->type = bfd_data_link_order; + link_order->offset = statement->data_statement.output_vma; + link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE); + + value = statement->data_statement.value; + + /* If the endianness of the output BFD is not known, then we + base the endianness of the data on the first input file. + By convention, the bfd_put routines for an unknown + endianness are big endian, so we must swap here if the + input file is little endian. */ + if (bfd_big_endian (output_bfd)) + big_endian = true; + else if (bfd_little_endian (output_bfd)) + big_endian = false; + else + { + boolean swap; + + swap = false; + if (command_line.endian == ENDIAN_BIG) + big_endian = true; + else if (command_line.endian == ENDIAN_LITTLE) + { + big_endian = false; + swap = true; + } + else if (command_line.endian == ENDIAN_UNSET) + { + big_endian = true; + { + LANG_FOR_EACH_INPUT_STATEMENT (s) + { + if (s->the_bfd != NULL) + { + if (bfd_little_endian (s->the_bfd)) + { + big_endian = false; + swap = true; + } + break; + } + } + } + } + + if (swap) + { + bfd_byte buffer[8]; + + switch (statement->data_statement.type) + { + case QUAD: + case SQUAD: + if (sizeof (bfd_vma) >= QUAD_SIZE) + { + bfd_putl64 (value, buffer); + value = bfd_getb64 (buffer); + break; + } + /* Fall through. */ + case LONG: + bfd_putl32 (value, buffer); + value = bfd_getb32 (buffer); + break; + case SHORT: + bfd_putl16 (value, buffer); + value = bfd_getb16 (buffer); + break; + case BYTE: + break; + default: + abort (); + } + } + } + + ASSERT (output_section->owner == output_bfd); + switch (statement->data_statement.type) + { + case QUAD: + case SQUAD: + if (sizeof (bfd_vma) >= QUAD_SIZE) + bfd_put_64 (output_bfd, value, link_order->u.data.contents); + else + { + bfd_vma high; + + if (statement->data_statement.type == QUAD) + high = 0; + else if ((value & 0x80000000) == 0) + high = 0; + else + high = (bfd_vma) -1; + bfd_put_32 (output_bfd, high, + (link_order->u.data.contents + + (big_endian ? 0 : 4))); + bfd_put_32 (output_bfd, value, + (link_order->u.data.contents + + (big_endian ? 4 : 0))); + } + link_order->size = QUAD_SIZE; + break; + case LONG: + bfd_put_32 (output_bfd, value, link_order->u.data.contents); + link_order->size = LONG_SIZE; + break; + case SHORT: + bfd_put_16 (output_bfd, value, link_order->u.data.contents); + link_order->size = SHORT_SIZE; + break; + case BYTE: + bfd_put_8 (output_bfd, value, link_order->u.data.contents); + link_order->size = BYTE_SIZE; + break; + default: + abort (); + } + } + break; + + case lang_reloc_statement_enum: + { + lang_reloc_statement_type *rs; + asection *output_section; + struct bfd_link_order *link_order; + + rs = &statement->reloc_statement; + + output_section = rs->output_section; + ASSERT (output_section->owner == output_bfd); + + link_order = bfd_new_link_order (output_bfd, output_section); + if (link_order == NULL) + einfo (_("%P%F: bfd_new_link_order failed\n")); + + link_order->offset = rs->output_vma; + link_order->size = bfd_get_reloc_size (rs->howto); + + link_order->u.reloc.p = + ((struct bfd_link_order_reloc *) + xmalloc (sizeof (struct bfd_link_order_reloc))); + + link_order->u.reloc.p->reloc = rs->reloc; + link_order->u.reloc.p->addend = rs->addend_value; + + if (rs->name == NULL) + { + link_order->type = bfd_section_reloc_link_order; + if (rs->section->owner == output_bfd) + link_order->u.reloc.p->u.section = rs->section; + else + { + link_order->u.reloc.p->u.section = rs->section->output_section; + link_order->u.reloc.p->addend += rs->section->output_offset; + } + } + else + { + link_order->type = bfd_symbol_reloc_link_order; + link_order->u.reloc.p->u.name = rs->name; + } + } + break; + + case lang_input_section_enum: + /* Create a new link_order in the output section with this + attached */ + if (statement->input_section.ifile->just_syms_flag == false) + { + asection *i = statement->input_section.section; + asection *output_section = i->output_section; + + ASSERT (output_section->owner == output_bfd); + + if ((output_section->flags & SEC_HAS_CONTENTS) != 0) + { + struct bfd_link_order *link_order; + + link_order = bfd_new_link_order (output_bfd, output_section); + + if (i->flags & SEC_NEVER_LOAD) + { + /* We've got a never load section inside one which + is going to be output, we'll change it into a + fill link_order */ + link_order->type = bfd_fill_link_order; + link_order->u.fill.value = 0; + } + else + { + link_order->type = bfd_indirect_link_order; + link_order->u.indirect.section = i; + ASSERT (i->output_section == output_section); + } + if (i->_cooked_size) + link_order->size = i->_cooked_size; + else + link_order->size = bfd_get_section_size_before_reloc (i); + link_order->offset = i->output_offset; + } + } + break; + + case lang_padding_statement_enum: + /* Make a new link_order with the right filler */ + { + asection *output_section; + struct bfd_link_order *link_order; + + output_section = statement->padding_statement.output_section; + ASSERT (statement->padding_statement.output_section->owner + == output_bfd); + if ((output_section->flags & SEC_HAS_CONTENTS) != 0) + { + link_order = bfd_new_link_order (output_bfd, output_section); + link_order->type = bfd_fill_link_order; + link_order->size = statement->padding_statement.size; + link_order->offset = statement->padding_statement.output_offset; + link_order->u.fill.value = statement->padding_statement.fill; + } + } + break; + + default: + /* All the other ones fall through */ + break; + } +} + +/* Call BFD to write out the linked file. */ + + +/**********************************************************************/ + + +/* Wander around the input sections, make sure that + we'll never try and create an output section with more relocs + than will fit.. Do this by always assuming the worst case, and + creating new output sections with all the right bits */ +#define TESTIT 1 +static asection * +clone_section (abfd, s, count) + bfd *abfd; + asection *s; + int *count; +{ +#define SSIZE 8 + char sname[SSIZE]; /* ?? find the name for this size */ + asection *n; + struct bfd_link_hash_entry *h; + /* Invent a section name - use first five + chars of base section name and a digit suffix */ + do + { + unsigned int i; + char b[6]; + for (i = 0; i < sizeof (b) - 1 && s->name[i]; i++) + b[i] = s->name[i]; + b[i] = 0; + sprintf (sname, "%s%d", b, (*count)++); + } + while (bfd_get_section_by_name (abfd, sname)); + + n = bfd_make_section_anyway (abfd, xstrdup (sname)); + + /* Create a symbol of the same name */ + + h = bfd_link_hash_lookup (link_info.hash, + sname, true, true, false); + h->type = bfd_link_hash_defined; + h->u.def.value = 0; + h->u.def.section = n ; + + + n->flags = s->flags; + n->vma = s->vma; + n->user_set_vma = s->user_set_vma; + n->lma = s->lma; + n->_cooked_size = 0; + n->_raw_size = 0; + n->output_offset = s->output_offset; + n->output_section = n; + n->orelocation = 0; + n->reloc_count = 0; + n->alignment_power = s->alignment_power; + return n; +} + +#if TESTING +static void +ds (s) + asection *s; +{ + struct bfd_link_order *l = s->link_order_head; + printf ("vma %x size %x\n", s->vma, s->_raw_size); + while (l) + { + if (l->type == bfd_indirect_link_order) + { + printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename); + } + else + { + printf (_("%8x something else\n"), l->offset); + } + l = l->next; + } + printf ("\n"); +} +dump (s, a1, a2) + char *s; + asection *a1; + asection *a2; +{ + printf ("%s\n", s); + ds (a1); + ds (a2); +} + +static void +sanity_check (abfd) + bfd *abfd; +{ + asection *s; + for (s = abfd->sections; s; s = s->next) + { + struct bfd_link_order *p; + bfd_vma prev = 0; + for (p = s->link_order_head; p; p = p->next) + { + if (p->offset > 100000) + abort (); + if (p->offset < prev) + abort (); + prev = p->offset; + } + } +} +#else +#define sanity_check(a) +#define dump(a, b, c) +#endif + +static void +split_sections (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + asection *original_sec; + int nsecs = abfd->section_count; + sanity_check (abfd); + /* look through all the original sections */ + for (original_sec = abfd->sections; + original_sec && nsecs; + original_sec = original_sec->next, nsecs--) + { + boolean first = true; + int count = 0; + int lines = 0; + int relocs = 0; + struct bfd_link_order **pp; + bfd_vma vma = original_sec->vma; + bfd_vma shift_offset = 0; + asection *cursor = original_sec; + + /* count up the relocations and line entries to see if + anything would be too big to fit */ + for (pp = &(cursor->link_order_head); *pp; pp = &((*pp)->next)) + { + struct bfd_link_order *p = *pp; + int thislines = 0; + int thisrelocs = 0; + if (p->type == bfd_indirect_link_order) + { + asection *sec; + + sec = p->u.indirect.section; + + if (info->strip == strip_none + || info->strip == strip_some) + thislines = sec->lineno_count; + + if (info->relocateable) + thisrelocs = sec->reloc_count; + + } + else if (info->relocateable + && (p->type == bfd_section_reloc_link_order + || p->type == bfd_symbol_reloc_link_order)) + thisrelocs++; + + if (! first + && (thisrelocs + relocs > config.split_by_reloc + || thislines + lines > config.split_by_reloc + || config.split_by_file)) + { + /* create a new section and put this link order and the + following link orders into it */ + struct bfd_link_order *l = p; + asection *n = clone_section (abfd, cursor, &count); + *pp = NULL; /* Snip off link orders from old section */ + n->link_order_head = l; /* attach to new section */ + pp = &n->link_order_head; + + /* change the size of the original section and + update the vma of the new one */ + + dump ("before snip", cursor, n); + + n->_raw_size = cursor->_raw_size - l->offset; + cursor->_raw_size = l->offset; + + vma += cursor->_raw_size; + n->lma = n->vma = vma; + + shift_offset = l->offset; + + /* run down the chain and change the output section to + the right one, update the offsets too */ + + while (l) + { + l->offset -= shift_offset; + if (l->type == bfd_indirect_link_order) + { + l->u.indirect.section->output_section = n; + l->u.indirect.section->output_offset = l->offset; + } + l = l->next; + } + dump ("after snip", cursor, n); + cursor = n; + relocs = thisrelocs; + lines = thislines; + } + else + { + relocs += thisrelocs; + lines += thislines; + } + + first = false; + } + } + sanity_check (abfd); +} +/**********************************************************************/ +void +ldwrite () +{ + /* Reset error indicator, which can typically something like invalid + format from openning up the .o files */ + bfd_set_error (bfd_error_no_error); + lang_for_each_statement (build_link_order); + + if (config.split_by_reloc || config.split_by_file) + split_sections (output_bfd, &link_info); + if (!bfd_final_link (output_bfd, &link_info)) + { + /* If there was an error recorded, print it out. Otherwise assume + an appropriate error message like unknown symbol was printed + out. */ + + if (bfd_get_error () != bfd_error_no_error) + einfo (_("%F%P: final link failed: %E\n"), output_bfd); + else + xexit(1); + } +} diff --git a/ld/ldwrite.h b/ld/ldwrite.h new file mode 100644 index 0000000..68d8b52 --- /dev/null +++ b/ld/ldwrite.h @@ -0,0 +1,20 @@ +/* ldwrite.h - + Copyright 1991, 1992, 1993 Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +void ldwrite PARAMS ((void)); diff --git a/ld/lexsup.c b/ld/lexsup.c new file mode 100644 index 0000000..7ee5087 --- /dev/null +++ b/ld/lexsup.c @@ -0,0 +1,1140 @@ +/* Parse options for the GNU linker. + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libiberty.h" +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include "getopt.h" +#include "bfdlink.h" +#include "ld.h" +#include "ldmain.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldgram.h" +#include "ldlex.h" +#include "ldfile.h" +#include "ldver.h" +#include "ldemul.h" + +#ifndef PATH_SEPARATOR +#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__)) +#define PATH_SEPARATOR ';' +#else +#define PATH_SEPARATOR ':' +#endif +#endif + +/* Somewhere above, sys/stat.h got included . . . . */ +#if !defined(S_ISDIR) && defined(S_IFDIR) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +/* Omit args to avoid the possibility of clashing with a system header + that might disagree about consts. */ +unsigned long strtoul (); + +static void set_default_dirlist PARAMS ((char *dirlist_ptr)); +static void set_section_start PARAMS ((char *sect, char *valstr)); +static void help PARAMS ((void)); + +/* Non-zero if we are processing a --defsym from the command line. */ +int parsing_defsym = 0; + +/* Codes used for the long options with no short synonyms. 150 isn't + special; it's just an arbitrary non-ASCII char value. */ + +#define OPTION_ASSERT 150 +#define OPTION_CALL_SHARED (OPTION_ASSERT + 1) +#define OPTION_CREF (OPTION_CALL_SHARED + 1) +#define OPTION_DEFSYM (OPTION_CREF + 1) +#define OPTION_DEMANGLE (OPTION_DEFSYM + 1) +#define OPTION_DYNAMIC_LINKER (OPTION_DEMANGLE + 1) +#define OPTION_EB (OPTION_DYNAMIC_LINKER + 1) +#define OPTION_EL (OPTION_EB + 1) +#define OPTION_EMBEDDED_RELOCS (OPTION_EL + 1) +#define OPTION_EXPORT_DYNAMIC (OPTION_EMBEDDED_RELOCS + 1) +#define OPTION_HELP (OPTION_EXPORT_DYNAMIC + 1) +#define OPTION_IGNORE (OPTION_HELP + 1) +#define OPTION_MAP (OPTION_IGNORE + 1) +#define OPTION_NO_DEMANGLE (OPTION_MAP + 1) +#define OPTION_NO_KEEP_MEMORY (OPTION_NO_DEMANGLE + 1) +#define OPTION_NO_WARN_MISMATCH (OPTION_NO_KEEP_MEMORY + 1) +#define OPTION_NOINHIBIT_EXEC (OPTION_NO_WARN_MISMATCH + 1) +#define OPTION_NON_SHARED (OPTION_NOINHIBIT_EXEC + 1) +#define OPTION_NO_WHOLE_ARCHIVE (OPTION_NON_SHARED + 1) +#define OPTION_OFORMAT (OPTION_NO_WHOLE_ARCHIVE + 1) +#define OPTION_RELAX (OPTION_OFORMAT + 1) +#define OPTION_RETAIN_SYMBOLS_FILE (OPTION_RELAX + 1) +#define OPTION_RPATH (OPTION_RETAIN_SYMBOLS_FILE + 1) +#define OPTION_RPATH_LINK (OPTION_RPATH + 1) +#define OPTION_SHARED (OPTION_RPATH_LINK + 1) +#define OPTION_SONAME (OPTION_SHARED + 1) +#define OPTION_SORT_COMMON (OPTION_SONAME + 1) +#define OPTION_STATS (OPTION_SORT_COMMON + 1) +#define OPTION_SYMBOLIC (OPTION_STATS + 1) +#define OPTION_TASK_LINK (OPTION_SYMBOLIC + 1) +#define OPTION_TBSS (OPTION_TASK_LINK + 1) +#define OPTION_TDATA (OPTION_TBSS + 1) +#define OPTION_TTEXT (OPTION_TDATA + 1) +#define OPTION_TRADITIONAL_FORMAT (OPTION_TTEXT + 1) +#define OPTION_UR (OPTION_TRADITIONAL_FORMAT + 1) +#define OPTION_VERBOSE (OPTION_UR + 1) +#define OPTION_VERSION (OPTION_VERBOSE + 1) +#define OPTION_VERSION_SCRIPT (OPTION_VERSION + 1) +#define OPTION_VERSION_EXPORTS_SECTION (OPTION_VERSION_SCRIPT + 1) +#define OPTION_WARN_COMMON (OPTION_VERSION_EXPORTS_SECTION + 1) +#define OPTION_WARN_CONSTRUCTORS (OPTION_WARN_COMMON + 1) +#define OPTION_WARN_MULTIPLE_GP (OPTION_WARN_CONSTRUCTORS + 1) +#define OPTION_WARN_ONCE (OPTION_WARN_MULTIPLE_GP + 1) +#define OPTION_WARN_SECTION_ALIGN (OPTION_WARN_ONCE + 1) +#define OPTION_SPLIT_BY_RELOC (OPTION_WARN_SECTION_ALIGN + 1) +#define OPTION_SPLIT_BY_FILE (OPTION_SPLIT_BY_RELOC + 1) +#define OPTION_WHOLE_ARCHIVE (OPTION_SPLIT_BY_FILE + 1) +#define OPTION_WRAP (OPTION_WHOLE_ARCHIVE + 1) +#define OPTION_FORCE_EXE_SUFFIX (OPTION_WRAP + 1) +#define OPTION_GC_SECTIONS (OPTION_FORCE_EXE_SUFFIX + 1) +#define OPTION_NO_GC_SECTIONS (OPTION_GC_SECTIONS + 1) +#define OPTION_CHECK_SECTIONS (OPTION_NO_GC_SECTIONS + 1) +#define OPTION_NO_CHECK_SECTIONS (OPTION_CHECK_SECTIONS + 1) +#define OPTION_MPC860C0 (OPTION_NO_CHECK_SECTIONS + 1) +#define OPTION_NO_UNDEFINED (OPTION_MPC860C0 + 1) + +/* The long options. This structure is used for both the option + parsing and the help text. */ + +struct ld_option +{ + /* The long option information. */ + struct option opt; + /* The short option with the same meaning ('\0' if none). */ + char shortopt; + /* The name of the argument (NULL if none). */ + const char *arg; + /* The documentation string. If this is NULL, this is a synonym for + the previous option. */ + const char *doc; + enum + { + /* Use one dash before long option name. */ + ONE_DASH, + /* Use two dashes before long option name. */ + TWO_DASHES, + /* Don't mention this option in --help output. */ + NO_HELP + } control; +}; + +static const struct ld_option ld_options[] = +{ + { {NULL, required_argument, NULL, '\0'}, + 'a', N_("KEYWORD"), N_("Shared library control for HP/UX compatibility"), + ONE_DASH }, + { {"architecture", required_argument, NULL, 'A'}, + 'A', N_("ARCH"), N_("Set architecture") , TWO_DASHES }, + { {"format", required_argument, NULL, 'b'}, + 'b', N_("TARGET"), N_("Specify target for following input files"), TWO_DASHES }, + { {"mri-script", required_argument, NULL, 'c'}, + 'c', N_("FILE"), N_("Read MRI format linker script"), TWO_DASHES }, + { {"dc", no_argument, NULL, 'd'}, + 'd', NULL, N_("Force common symbols to be defined"), ONE_DASH }, + { {"dp", no_argument, NULL, 'd'}, + '\0', NULL, NULL, ONE_DASH }, + { {"entry", required_argument, NULL, 'e'}, + 'e', N_("ADDRESS"), N_("Set start address"), TWO_DASHES }, + { {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC}, + 'E', NULL, N_("Export all dynamic symbols"), TWO_DASHES }, + { {"EB", no_argument, NULL, OPTION_EB}, + '\0', NULL, N_("Link big-endian objects"), ONE_DASH }, + { {"EL", no_argument, NULL, OPTION_EL}, + '\0', NULL, N_("Link little-endian objects"), ONE_DASH }, + { {"auxiliary", required_argument, NULL, 'f'}, + 'f', N_("SHLIB"), N_("Auxiliary filter for shared object symbol table"), + TWO_DASHES }, + { {"filter", required_argument, NULL, 'F'}, + 'F', N_("SHLIB"), N_("Filter for shared object symbol table"), TWO_DASHES }, + { {NULL, no_argument, NULL, '\0'}, + 'g', NULL, N_("Ignored"), ONE_DASH }, + { {"gpsize", required_argument, NULL, 'G'}, + 'G', N_("SIZE"), N_("Small data size (if no size, same as --shared)"), + TWO_DASHES }, + { {"soname", required_argument, NULL, OPTION_SONAME}, + 'h', N_("FILENAME"), N_("Set internal name of shared library"), ONE_DASH }, + { {"library", required_argument, NULL, 'l'}, + 'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES }, + { {"library-path", required_argument, NULL, 'L'}, + 'L', N_("DIRECTORY"), N_("Add DIRECTORY to library search path"), TWO_DASHES }, + { {NULL, required_argument, NULL, '\0'}, + 'm', N_("EMULATION"), N_("Set emulation"), ONE_DASH }, + { {"print-map", no_argument, NULL, 'M'}, + 'M', NULL, N_("Print map file on standard output"), TWO_DASHES }, + { {"nmagic", no_argument, NULL, 'n'}, + 'n', NULL, N_("Do not page align data"), TWO_DASHES }, + { {"omagic", no_argument, NULL, 'N'}, + 'N', NULL, N_("Do not page align data, do not make text readonly"), + TWO_DASHES }, + { {"output", required_argument, NULL, 'o'}, + 'o', N_("FILE"), N_("Set output file name"), TWO_DASHES }, + { {NULL, required_argument, NULL, '\0'}, + 'O', NULL, N_("Optimize output file"), ONE_DASH }, + { {"Qy", no_argument, NULL, OPTION_IGNORE}, + '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH }, + { {"relocateable", no_argument, NULL, 'r'}, + 'r', NULL, N_("Generate relocateable output"), TWO_DASHES }, + { {NULL, no_argument, NULL, '\0'}, + 'i', NULL, NULL, ONE_DASH }, + { {"just-symbols", required_argument, NULL, 'R'}, + 'R', N_("FILE"), N_("Just link symbols (if directory, same as --rpath)"), + TWO_DASHES }, + { {"strip-all", no_argument, NULL, 's'}, + 's', NULL, N_("Strip all symbols"), TWO_DASHES }, + { {"strip-debug", no_argument, NULL, 'S'}, + 'S', NULL, N_("Strip debugging symbols"), TWO_DASHES }, + { {"trace", no_argument, NULL, 't'}, + 't', NULL, N_("Trace file opens"), TWO_DASHES }, + { {"script", required_argument, NULL, 'T'}, + 'T', N_("FILE"), N_("Read linker script"), TWO_DASHES }, + { {"undefined", required_argument, NULL, 'u'}, + 'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"), TWO_DASHES }, + { {"Ur", no_argument, NULL, OPTION_UR}, + '\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH }, + { {"version", no_argument, NULL, OPTION_VERSION}, + 'v', NULL, N_("Print version information"), TWO_DASHES }, + { {NULL, no_argument, NULL, '\0'}, + 'V', NULL, N_("Print version and emulation information"), ONE_DASH }, + { {"discard-all", no_argument, NULL, 'x'}, + 'x', NULL, N_("Discard all local symbols"), TWO_DASHES }, + { {"discard-locals", no_argument, NULL, 'X'}, + 'X', NULL, N_("Discard temporary local symbols"), TWO_DASHES }, + { {"trace-symbol", required_argument, NULL, 'y'}, + 'y', N_("SYMBOL"), N_("Trace mentions of SYMBOL"), TWO_DASHES }, + { {NULL, required_argument, NULL, '\0'}, + 'Y', N_("PATH"), N_("Default search path for Solaris compatibility"), ONE_DASH }, + { {NULL, required_argument, NULL, '\0'}, + 'z', N_("KEYWORD"), N_("Ignored for Solaris compatibility"), ONE_DASH }, + { {"start-group", no_argument, NULL, '('}, + '(', NULL, N_("Start a group"), TWO_DASHES }, + { {"end-group", no_argument, NULL, ')'}, + ')', NULL, N_("End a group"), TWO_DASHES }, + { {"assert", required_argument, NULL, OPTION_ASSERT}, + '\0', N_("KEYWORD"), N_("Ignored for SunOS compatibility"), ONE_DASH }, + { {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED}, + '\0', NULL, N_("Link against shared libraries"), ONE_DASH }, + { {"dy", no_argument, NULL, OPTION_CALL_SHARED}, + '\0', NULL, NULL, ONE_DASH }, + { {"call_shared", no_argument, NULL, OPTION_CALL_SHARED}, + '\0', NULL, NULL, ONE_DASH }, + { {"Bstatic", no_argument, NULL, OPTION_NON_SHARED}, + '\0', NULL, N_("Do not link against shared libraries"), ONE_DASH }, + { {"dn", no_argument, NULL, OPTION_NON_SHARED}, + '\0', NULL, NULL, ONE_DASH }, + { {"non_shared", no_argument, NULL, OPTION_NON_SHARED}, + '\0', NULL, NULL, ONE_DASH }, + { {"static", no_argument, NULL, OPTION_NON_SHARED}, + '\0', NULL, NULL, ONE_DASH }, + { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC}, + '\0', NULL, N_("Bind global references locally"), ONE_DASH }, + { {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS}, + '\0', NULL, N_("Check section addresses for overlaps (default)"), TWO_DASHES }, + { {"no-check-sections", no_argument, NULL, OPTION_NO_CHECK_SECTIONS}, + '\0', NULL, N_("Do not check section addresses for overlaps"), + TWO_DASHES }, + { {"cref", no_argument, NULL, OPTION_CREF}, + '\0', NULL, N_("Output cross reference table"), TWO_DASHES }, + { {"defsym", required_argument, NULL, OPTION_DEFSYM}, + '\0', N_("SYMBOL=EXPRESSION"), N_("Define a symbol"), TWO_DASHES }, + { {"demangle", no_argument, NULL, OPTION_DEMANGLE}, + '\0', NULL, N_("Demangle symbol names"), TWO_DASHES }, + { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER}, + '\0', N_("PROGRAM"), N_("Set the dynamic linker to use"), TWO_DASHES }, + { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS}, + '\0', NULL, N_("Generate embedded relocs"), TWO_DASHES}, + { {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX}, + '\0', NULL, N_("Force generation of file with .exe suffix"), TWO_DASHES}, + { {"gc-sections", no_argument, NULL, OPTION_GC_SECTIONS}, + '\0', NULL, N_("Remove unused sections (on some targets)"), + TWO_DASHES }, + { {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS}, + '\0', NULL, N_("Don't remove unused sections (default)"), + TWO_DASHES }, + { {"help", no_argument, NULL, OPTION_HELP}, + '\0', NULL, N_("Print option help"), TWO_DASHES }, + { {"Map", required_argument, NULL, OPTION_MAP}, + '\0', N_("FILE"), N_("Write a map file"), ONE_DASH }, + { {"no-demangle", no_argument, NULL, OPTION_NO_DEMANGLE }, + '\0', NULL, N_("Do not demangle symbol names"), TWO_DASHES }, + { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY}, + '\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES }, + { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED}, + '\0', NULL, N_("Allow no undefined symbols"), TWO_DASHES }, + { {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH}, + '\0', NULL, N_("Don't warn about mismatched input files"), TWO_DASHES}, + { {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE}, + '\0', NULL, N_("Turn off --whole-archive"), TWO_DASHES }, + { {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC}, + '\0', NULL, N_("Create an output file even if errors occur"), TWO_DASHES }, + { {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC}, + '\0', NULL, NULL, NO_HELP }, + { {"oformat", required_argument, NULL, OPTION_OFORMAT}, + '\0', N_("TARGET"), N_("Specify target of output file"), TWO_DASHES }, + { {"qmagic", no_argument, NULL, OPTION_IGNORE}, + '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH }, + { {"relax", no_argument, NULL, OPTION_RELAX}, + '\0', NULL, N_("Relax branches on certain targets"), TWO_DASHES }, + { {"retain-symbols-file", required_argument, NULL, + OPTION_RETAIN_SYMBOLS_FILE}, + '\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES }, + { {"rpath", required_argument, NULL, OPTION_RPATH}, + '\0', N_("PATH"), N_("Set runtime shared library search path"), ONE_DASH }, + { {"rpath-link", required_argument, NULL, OPTION_RPATH_LINK}, + '\0', N_("PATH"), N_("Set link time shared library search path"), ONE_DASH }, + { {"shared", no_argument, NULL, OPTION_SHARED}, + '\0', NULL, N_("Create a shared library"), ONE_DASH }, + { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD. */ + '\0', NULL, NULL, ONE_DASH }, + { {"sort-common", no_argument, NULL, OPTION_SORT_COMMON}, + '\0', NULL, N_("Sort common symbols by size"), TWO_DASHES }, + { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON}, + '\0', NULL, NULL, NO_HELP }, + { {"split-by-file", no_argument, NULL, OPTION_SPLIT_BY_FILE}, + '\0', NULL, N_("Split output sections for each file"), TWO_DASHES }, + { {"split-by-reloc", required_argument, NULL, OPTION_SPLIT_BY_RELOC}, + '\0', N_("COUNT"), N_("Split output sections every COUNT relocs"), TWO_DASHES }, + { {"stats", no_argument, NULL, OPTION_STATS}, + '\0', NULL, N_("Print memory usage statistics"), TWO_DASHES }, + { {"task-link", required_argument, NULL, OPTION_TASK_LINK}, + '\0', N_("SYMBOL"), N_("Do task level linking"), TWO_DASHES }, + { {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT}, + '\0', NULL, N_("Use same format as native linker"), TWO_DASHES }, + { {"Tbss", required_argument, NULL, OPTION_TBSS}, + '\0', N_("ADDRESS"), N_("Set address of .bss section"), ONE_DASH }, + { {"Tdata", required_argument, NULL, OPTION_TDATA}, + '\0', N_("ADDRESS"), N_("Set address of .data section"), ONE_DASH }, + { {"Ttext", required_argument, NULL, OPTION_TTEXT}, + '\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH }, + { {"verbose", no_argument, NULL, OPTION_VERBOSE}, + '\0', NULL, N_("Output lots of information during link"), TWO_DASHES }, + { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux. */ + '\0', NULL, NULL, NO_HELP }, + { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT }, + '\0', N_("FILE"), N_("Read version information script"), TWO_DASHES }, + { {"version-exports-section", required_argument, NULL, + OPTION_VERSION_EXPORTS_SECTION }, + '\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using SYMBOL as the version."), + TWO_DASHES }, + { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON}, + '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES }, + { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS}, + '\0', NULL, N_("Warn if global constructors/destructors are seen"), + TWO_DASHES }, + { {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP}, + '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES }, + { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE}, + '\0', NULL, N_("Warn only once per undefined symbol"), TWO_DASHES }, + { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN}, + '\0', NULL, N_("Warn if start of section changes due to alignment"), + TWO_DASHES }, + { {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE}, + '\0', NULL, N_("Include all objects from following archives"), TWO_DASHES }, + { {"wrap", required_argument, NULL, OPTION_WRAP}, + '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES }, + { {"mpc860c0", optional_argument, NULL, OPTION_MPC860C0}, + '\0', N_("[=WORDS]"), N_("Modify problematic branches in last WORDS (1-10, default 5) words of a page"), TWO_DASHES } +}; + +#define OPTION_COUNT ((int) (sizeof ld_options / sizeof ld_options[0])) + +/* Test "string" for containing a string of digits that form a number +between "min" and "max". The return value is the number or "err". */ +static +int is_num( char *string, int min, int max, int err) +{ + int result = 0; + + for ( ; *string; ++string) + { + if (!isdigit(*string)) + { + result = err; + break; + } + result = result * 10 + (*string - '0'); + } + if (result < min || result > max) + result = err; + + return result; +} + +void +parse_args (argc, argv) + int argc; + char **argv; +{ + int i, is, il; + int ingroup = 0; + char *default_dirlist = NULL; + char shortopts[OPTION_COUNT * 3 + 2]; + struct option longopts[OPTION_COUNT + 1]; + int last_optind; + + /* Starting the short option string with '-' is for programs that + expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. */ + shortopts[0] = '-'; + is = 1; + il = 0; + for (i = 0; i < OPTION_COUNT; i++) + { + if (ld_options[i].shortopt != '\0') + { + shortopts[is] = ld_options[i].shortopt; + ++is; + if (ld_options[i].opt.has_arg == required_argument + || ld_options[i].opt.has_arg == optional_argument) + { + shortopts[is] = ':'; + ++is; + if (ld_options[i].opt.has_arg == optional_argument) + { + shortopts[is] = ':'; + ++is; + } + } + } + if (ld_options[i].opt.name != NULL) + { + longopts[il] = ld_options[i].opt; + ++il; + } + } + shortopts[is] = '\0'; + longopts[il].name = NULL; + + /* The -G option is ambiguous on different platforms. Sometimes it + specifies the largest data size to put into the small data + section. Sometimes it is equivalent to --shared. Unfortunately, + the first form takes an argument, while the second does not. + + We need to permit the --shared form because on some platforms, + such as Solaris, gcc -shared will pass -G to the linker. + + To permit either usage, we look through the argument list. If we + find -G not followed by a number, we change it into --shared. + This will work for most normal cases. */ + for (i = 1; i < argc; i++) + if (strcmp (argv[i], "-G") == 0 + && (i + 1 >= argc + || ! isdigit ((unsigned char) argv[i + 1][0]))) + argv[i] = (char *) "--shared"; + + /* Because we permit long options to start with a single dash, and + we have a --library option, and the -l option is conventionally + used with an immediately following argument, we can have bad + results if somebody tries to use -l with a library whose name + happens to start with "ibrary", as in -li. We avoid problems by + simply turning -l into --library. This means that users will + have to use two dashes in order to use --library, which is OK + since that's how it is documented. + + FIXME: It's possible that this problem can arise for other short + options as well, although the user does always have the recourse + of adding a space between the option and the argument. */ + for (i = 1; i < argc; i++) + { + if (argv[i][0] == '-' + && argv[i][1] == 'l' + && argv[i][2] != '\0') + { + char *n; + + n = (char *) xmalloc (strlen (argv[i]) + 20); + sprintf (n, "--library=%s", argv[i] + 2); + argv[i] = n; + } + } + + last_optind = -1; + while (1) + { + int longind; + int optc; + + /* Using last_optind lets us avoid calling ldemul_parse_args + multiple times on a single option, which would lead to + confusion in the internal static variables maintained by + getopt. This could otherwise happen for an argument like + -nx, in which the -n is parsed as a single option, and we + loop around to pick up the -x. */ + if (optind != last_optind) + { + if (ldemul_parse_args (argc, argv)) + continue; + last_optind = optind; + } + + /* getopt_long_only is like getopt_long, but '-' as well as '--' + can indicate a long option. */ + optc = getopt_long_only (argc, argv, shortopts, longopts, &longind); + + if (optc == -1) + break; + switch (optc) + { + default: + xexit (1); + case 1: /* File name. */ + lang_add_input_file (optarg, lang_input_file_is_file_enum, + (char *) NULL); + break; + + case OPTION_IGNORE: + break; + case 'a': + /* For HP/UX compatibility. Actually -a shared should mean + ``use only shared libraries'' but, then, we don't + currently support shared libraries on HP/UX anyhow. */ + if (strcmp (optarg, "archive") == 0) + config.dynamic_link = false; + else if (strcmp (optarg, "shared") == 0 + || strcmp (optarg, "default") == 0) + config.dynamic_link = true; + else + einfo (_("%P%F: unrecognized -a option `%s'\n"), optarg); + break; + case OPTION_ASSERT: + /* FIXME: We just ignore these, but we should handle them. */ + if (strcmp (optarg, "definitions") == 0) + ; + else if (strcmp (optarg, "nodefinitions") == 0) + ; + else if (strcmp (optarg, "nosymbolic") == 0) + ; + else if (strcmp (optarg, "pure-text") == 0) + ; + else + einfo (_("%P%F: unrecognized -assert option `%s'\n"), optarg); + break; + case 'A': + ldfile_add_arch (optarg); + break; + case 'b': + lang_add_target (optarg); + break; + case 'c': + ldfile_open_command_file (optarg); + parser_input = input_mri_script; + yyparse (); + break; + case OPTION_CALL_SHARED: + config.dynamic_link = true; + break; + case OPTION_NON_SHARED: + config.dynamic_link = false; + break; + case OPTION_CREF: + command_line.cref = true; + link_info.notice_all = true; + break; + case 'd': + command_line.force_common_definition = true; + break; + case OPTION_DEFSYM: + lex_string = optarg; + lex_redirect (optarg); + parser_input = input_defsym; + parsing_defsym = 1; + yyparse (); + parsing_defsym = 0; + lex_string = NULL; + break; + case OPTION_DEMANGLE: + demangling = true; + break; + case OPTION_DYNAMIC_LINKER: + command_line.interpreter = optarg; + break; + case OPTION_EB: + command_line.endian = ENDIAN_BIG; + break; + case OPTION_EL: + command_line.endian = ENDIAN_LITTLE; + break; + case OPTION_EMBEDDED_RELOCS: + command_line.embedded_relocs = true; + break; + case OPTION_EXPORT_DYNAMIC: + case 'E': /* HP/UX compatibility. */ + command_line.export_dynamic = true; + break; + case 'e': + lang_add_entry (optarg, true); + break; + case 'f': + if (command_line.auxiliary_filters == NULL) + { + command_line.auxiliary_filters = + (char **) xmalloc (2 * sizeof (char *)); + command_line.auxiliary_filters[0] = optarg; + command_line.auxiliary_filters[1] = NULL; + } + else + { + int c; + char **p; + + c = 0; + for (p = command_line.auxiliary_filters; *p != NULL; p++) + ++c; + command_line.auxiliary_filters = + (char **) xrealloc (command_line.auxiliary_filters, + (c + 2) * sizeof (char *)); + command_line.auxiliary_filters[c] = optarg; + command_line.auxiliary_filters[c + 1] = NULL; + } + break; + case 'F': + command_line.filter_shlib = optarg; + break; + case OPTION_FORCE_EXE_SUFFIX: + command_line.force_exe_suffix = true; + break; + case 'G': + { + char *end; + g_switch_value = strtoul (optarg, &end, 0); + if (*end) + einfo (_("%P%F: invalid number `%s'\n"), optarg); + } + break; + case 'g': + /* Ignore. */ + break; + case OPTION_GC_SECTIONS: + command_line.gc_sections = true; + break; + case OPTION_HELP: + help (); + xexit (0); + break; + case 'L': + ldfile_add_library_path (optarg, true); + break; + case 'l': + lang_add_input_file (optarg, lang_input_file_is_l_enum, + (char *) NULL); + break; + case 'M': + config.map_filename = "-"; + break; + case 'm': + /* Ignore. Was handled in a pre-parse. */ + break; + case OPTION_MAP: + config.map_filename = optarg; + break; + case 'N': + config.text_read_only = false; + config.magic_demand_paged = false; + config.dynamic_link = false; + break; + case 'n': + config.magic_demand_paged = false; + config.dynamic_link = false; + break; + case OPTION_NO_DEMANGLE: + demangling = false; + break; + case OPTION_NO_GC_SECTIONS: + command_line.gc_sections = false; + break; + case OPTION_NO_KEEP_MEMORY: + link_info.keep_memory = false; + break; + case OPTION_NO_UNDEFINED: + link_info.no_undefined = true; + break; + case OPTION_NO_WARN_MISMATCH: + command_line.warn_mismatch = false; + break; + case OPTION_NOINHIBIT_EXEC: + force_make_executable = true; + break; + case OPTION_NO_WHOLE_ARCHIVE: + whole_archive = false; + break; + case 'O': + /* FIXME "-O<non-digits> <value>" used to set the address of + section <non-digits>. Was this for compatibility with + something, or can we create a new option to do that + (with a syntax similar to -defsym)? + getopt can't handle two args to an option without kludges. */ + + /* Enable optimizations of output files. */ + link_info.optimize = strtoul (optarg, NULL, 0) ? true : false; + break; + case 'o': + lang_add_output (optarg, 0); + break; + case OPTION_OFORMAT: + lang_add_output_format (optarg, (char *) NULL, (char *) NULL, 0); + break; + case 'i': + case 'r': + link_info.relocateable = true; + config.build_constructors = false; + config.magic_demand_paged = false; + config.text_read_only = false; + config.dynamic_link = false; + break; + case 'R': + /* The GNU linker traditionally uses -R to mean to include + only the symbols from a file. The Solaris linker uses -R + to set the path used by the runtime linker to find + libraries. This is the GNU linker -rpath argument. We + try to support both simultaneously by checking the file + named. If it is a directory, rather than a regular file, + we assume -rpath was meant. */ + { + struct stat s; + + if (stat (optarg, &s) >= 0 + && ! S_ISDIR (s.st_mode)) + { + lang_add_input_file (optarg, + lang_input_file_is_symbols_only_enum, + (char *) NULL); + break; + } + } + /* Fall through. */ + case OPTION_RPATH: + if (command_line.rpath == NULL) + command_line.rpath = buystring (optarg); + else + { + size_t rpath_len = strlen (command_line.rpath); + size_t optarg_len = strlen (optarg); + char *buf; + char *cp = command_line.rpath; + + /* First see whether OPTARG is already in the path. */ + do + { + size_t idx = 0; + while (optarg[idx] != '\0' && optarg[idx] == cp[idx]) + ++idx; + if (optarg[idx] == '\0' + && (cp[idx] == '\0' || cp[idx] == ':')) + /* We found it. */ + break; + + /* Not yet found. */ + cp = strchr (cp, ':'); + if (cp != NULL) + ++cp; + } + while (cp != NULL); + + if (cp == NULL) + { + buf = xmalloc (rpath_len + optarg_len + 2); + sprintf (buf, "%s:%s", command_line.rpath, optarg); + free (command_line.rpath); + command_line.rpath = buf; + } + } + break; + case OPTION_RPATH_LINK: + if (command_line.rpath_link == NULL) + command_line.rpath_link = buystring (optarg); + else + { + char *buf; + + buf = xmalloc (strlen (command_line.rpath_link) + + strlen (optarg) + + 2); + sprintf (buf, "%s:%s", command_line.rpath_link, optarg); + free (command_line.rpath_link); + command_line.rpath_link = buf; + } + break; + case OPTION_RELAX: + command_line.relax = true; + break; + case OPTION_RETAIN_SYMBOLS_FILE: + add_keepsyms_file (optarg); + break; + case 'S': + link_info.strip = strip_debugger; + break; + case 's': + link_info.strip = strip_all; + break; + case OPTION_SHARED: + if (config.has_shared) + link_info.shared = true; + else + einfo (_("%P%F: -shared not supported\n")); + break; + case 'h': /* Used on Solaris. */ + case OPTION_SONAME: + command_line.soname = optarg; + break; + case OPTION_SORT_COMMON: + config.sort_common = true; + break; + case OPTION_STATS: + config.stats = true; + break; + case OPTION_SYMBOLIC: + link_info.symbolic = true; + break; + case 't': + trace_files = true; + break; + case 'T': + ldfile_open_command_file (optarg); + parser_input = input_script; + yyparse (); + break; + case OPTION_TBSS: + set_section_start (".bss", optarg); + break; + case OPTION_TDATA: + set_section_start (".data", optarg); + break; + case OPTION_TTEXT: + set_section_start (".text", optarg); + break; + case OPTION_TRADITIONAL_FORMAT: + link_info.traditional_format = true; + break; + case OPTION_TASK_LINK: + link_info.task_link = true; + /* Fall through - do an implied -r option. */ + case OPTION_UR: + link_info.relocateable = true; + config.build_constructors = true; + config.magic_demand_paged = false; + config.text_read_only = false; + config.dynamic_link = false; + break; + case 'u': + ldlang_add_undef (optarg); + break; + case OPTION_VERBOSE: + ldversion (1); + version_printed = true; + trace_file_tries = true; + break; + case 'v': + ldversion (0); + version_printed = true; + break; + case 'V': + ldversion (1); + version_printed = true; + break; + case OPTION_VERSION: + /* This output is intended to follow the GNU standards document. */ + printf ("GNU ld %s\n", ld_program_version); + printf (_("Copyright 1997 Free Software Foundation, Inc.\n")); + printf (_("\ +This program is free software; you may redistribute it under the terms of\n\ +the GNU General Public License. This program has absolutely no warranty.\n")); + { + ld_emulation_xfer_type **ptr = ld_emulations; + + printf (_(" Supported emulations:\n")); + while (*ptr) + { + printf (" %s\n", (*ptr)->emulation_name); + ptr++; + } + } + xexit (0); + break; + case OPTION_VERSION_SCRIPT: + /* This option indicates a small script that only specifies + version information. Read it, but don't assume that + we've seen a linker script. */ + { + boolean hold_had_script; + + hold_had_script = had_script; + ldfile_open_command_file (optarg); + had_script = hold_had_script; + parser_input = input_version_script; + yyparse (); + } + break; + case OPTION_VERSION_EXPORTS_SECTION: + /* This option records a version symbol to be applied to the + symbols listed for export to be found in the object files + .exports sections. */ + command_line.version_exports_section = optarg; + break; + case OPTION_WARN_COMMON: + config.warn_common = true; + break; + case OPTION_WARN_CONSTRUCTORS: + config.warn_constructors = true; + break; + case OPTION_WARN_MULTIPLE_GP: + config.warn_multiple_gp = true; + break; + case OPTION_WARN_ONCE: + config.warn_once = true; + break; + case OPTION_WARN_SECTION_ALIGN: + config.warn_section_align = true; + break; + case OPTION_WHOLE_ARCHIVE: + whole_archive = true; + break; + case OPTION_WRAP: + add_wrap (optarg); + break; + case 'X': + link_info.discard = discard_l; + break; + case 'x': + link_info.discard = discard_all; + break; + case 'Y': + if (strncmp (optarg, "P,", 2) == 0) + optarg += 2; + default_dirlist = xstrdup (optarg); + break; + case 'y': + add_ysym (optarg); + break; + case 'z': + /* We accept and ignore this option for Solaris + compatibility. Actually, on Solaris, optarg is not + ignored. Someday we should handle it correctly. FIXME. */ + break; + case OPTION_SPLIT_BY_RELOC: + config.split_by_reloc = atoi (optarg); + break; + case OPTION_SPLIT_BY_FILE: + config.split_by_file = true; + break; + case OPTION_CHECK_SECTIONS: + command_line.check_section_addresses = true; + break; + case OPTION_NO_CHECK_SECTIONS: + command_line.check_section_addresses = false; + break; + case '(': + if (ingroup) + { + fprintf (stderr, + _("%s: may not nest groups (--help for usage)\n"), + program_name); + xexit (1); + } + lang_enter_group (); + ingroup = 1; + break; + case ')': + if (! ingroup) + { + fprintf (stderr, + _("%s: group ended before it began (--help for usage)\n"), + program_name); + xexit (1); + } + lang_leave_group (); + ingroup = 0; + break; + case OPTION_MPC860C0: + link_info.mpc860c0 = 20; /* default value (in bytes) */ + if (optarg) + { + unsigned words; + + words = is_num (optarg, 1, 10, 0); + if (words == 0) + { + fprintf (stderr, _("Invalid argument to option \"mpc860c0\"\n")); + xexit (1); + } + link_info.mpc860c0 = words * 4; /* convert words to bytes */ + } + command_line.relax = true; + break; + } + } + + if (ingroup) + lang_leave_group (); + + if (default_dirlist != NULL) + set_default_dirlist (default_dirlist); + +} + +/* Add the (colon-separated) elements of DIRLIST_PTR to the + library search path. */ + +static void +set_default_dirlist (dirlist_ptr) + char *dirlist_ptr; +{ + char *p; + + while (1) + { + p = strchr (dirlist_ptr, PATH_SEPARATOR); + if (p != NULL) + *p = '\0'; + if (*dirlist_ptr != '\0') + ldfile_add_library_path (dirlist_ptr, true); + if (p == NULL) + break; + dirlist_ptr = p + 1; + } +} + +static void +set_section_start (sect, valstr) + char *sect, *valstr; +{ + char *end; + unsigned long val = strtoul (valstr, &end, 16); + if (*end) + einfo (_("%P%F: invalid hex number `%s'\n"), valstr); + lang_section_start (sect, exp_intop (val)); +} + +/* Print help messages for the options. */ + +static void +help () +{ + int i; + const char **targets, **pp; + + printf (_("Usage: %s [options] file...\n"), program_name); + + printf (_("Options:\n")); + for (i = 0; i < OPTION_COUNT; i++) + { + if (ld_options[i].doc != NULL) + { + boolean comma; + int len; + int j; + + printf (" "); + + comma = false; + len = 2; + + j = i; + do + { + if (ld_options[j].shortopt != '\0' + && ld_options[j].control != NO_HELP) + { + printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt); + len += (comma ? 2 : 0) + 2; + if (ld_options[j].arg != NULL) + { + if (ld_options[j].opt.has_arg != optional_argument) + { + printf (" "); + ++len; + } + printf ("%s", _(ld_options[j].arg)); + len += strlen (_(ld_options[j].arg)); + } + comma = true; + } + ++j; + } + while (j < OPTION_COUNT && ld_options[j].doc == NULL); + + j = i; + do + { + if (ld_options[j].opt.name != NULL + && ld_options[j].control != NO_HELP) + { + printf ("%s-%s%s", + comma ? ", " : "", + ld_options[j].control == TWO_DASHES ? "-" : "", + ld_options[j].opt.name); + len += ((comma ? 2 : 0) + + 1 + + (ld_options[j].control == TWO_DASHES ? 1 : 0) + + strlen (ld_options[j].opt.name)); + if (ld_options[j].arg != NULL) + { + printf (" %s", _(ld_options[j].arg)); + len += 1 + strlen (_(ld_options[j].arg)); + } + comma = true; + } + ++j; + } + while (j < OPTION_COUNT && ld_options[j].doc == NULL); + + if (len >= 30) + { + printf ("\n"); + len = 0; + } + + for (; len < 30; len++) + putchar (' '); + + printf ("%s\n", _(ld_options[i].doc)); + } + } + + /* xgettext:c-format */ + printf (_("%s: supported targets:"), program_name); + targets = bfd_target_list (); + for (pp = targets; *pp != NULL; pp++) + printf (" %s", *pp); + free (targets); + printf ("\n"); + + /* xgettext:c-format */ + printf (_("%s: supported emulations: "), program_name); + ldemul_list_emulations (stdout); + printf ("\n"); + + /* xgettext:c-format */ + printf (_("%s: emulation specific options:\n"), program_name); + ldemul_list_emulation_options (stdout); + printf ("\n"); + + printf (_("\nReport bugs to bug-gnu-utils@gnu.org\n")); +} diff --git a/ld/mac-ld.r b/ld/mac-ld.r new file mode 100644 index 0000000..b316fc5 --- /dev/null +++ b/ld/mac-ld.r @@ -0,0 +1,42 @@ +/* Resources for GNU LD. */ + +#include "SysTypes.r" + +/* Version resources. */ + +resource 'vers' (1) { + 0, + 0, + 0, + 0, + verUs, + VERSION_STRING, + VERSION_STRING " (C) 1986-95 FSF, Inc." +}; + +resource 'vers' (2, purgeable) { + 0, + 0, + 0, + 0, + verUs, + VERSION_STRING, + "GLD " VERSION_STRING " for MPW" +}; + +#ifdef WANT_CFRG + +#include "CodeFragmentTypes.r" + +resource 'cfrg' (0) { + { + kPowerPC, + kFullLib, + kNoVersionNum, kNoVersionNum, + 0, 0, + kIsApp, kOnDiskFlat, kZeroOffset, kWholeFork, + PROG_NAME + } +}; + +#endif /* WANT_CFRG */ diff --git a/ld/mpw-config.in b/ld/mpw-config.in new file mode 100644 index 0000000..b2542cc --- /dev/null +++ b/ld/mpw-config.in @@ -0,0 +1,52 @@ +# Configuration fragment for LD. + +If "{target_canonical}" =~ /m68k-apple-macos/ + Set emulname m68kcoff + forward-include "{srcdir}"mpw-em68kcoff.c em68kcoff.c + Set emulation_ofiles "{o}"em68kcoff.c.o + +Else If "{target_canonical}" =~ /powerpc-apple-macos/ + Set emulname ppcmacos + forward-include "{srcdir}"mpw-eppcmac.c eppcmacos.c + Set emulation_ofiles "{o}"eppcmacos.c.o + +Else If "{target_canonical}" =~ /i386-\Option-x-go32/ + Set emulname i386go32 + forward-include "{srcdir}"mpw-ei386go32.c ei386go32.c + Set emulation_ofiles "{o}"ei386go32.c.o + +Else If "{target_canonical}" =~ /mips-\Option-x-ecoff/ + Set emulname mipsidt + forward-include "{srcdir}"mpw-idtmips.c emipsidt.c + Set emulation_ofiles "{o}"emipsidt.c.o + +Else If "{target_canonical}" =~ /mips-\Option-x-\Option-x/ + Set emulname elf32ebmip + forward-include "{srcdir}"mpw-elfmips.c eelf32ebmip.c + Set emulation_ofiles "{o}"eelf32ebmip.c.o + +Else If "{target_canonical}" =~ /sh-\Option-x-hms/ + Set emulname sh + forward-include "{srcdir}"mpw-esh.c esh.c + Set emulation_ofiles "{o}"esh.c.o +End If + +Echo '/* This file is automatically generated. DO NOT EDIT! */' > "{o}"ldemul-tmp.h +Echo "extern ld_emulation_xfer_type ld_{emulname}_emulation;" >> "{o}"ldemul-tmp.h +Echo '#define EMULATION_LIST \' >> "{o}"ldemul-tmp.h +Echo " &ld_{emulname}_emulation, \" >> "{o}"ldemul-tmp.h +Echo ' 0' >> "{o}"ldemul-tmp.h + +MoveIfChange "{o}"ldemul-tmp.h "{o}"ldemul-list.h + +Echo '# From mpw-config.in' > "{o}"mk.tmp +Echo "EMUL = " {emulname} >> "{o}"mk.tmp +Echo "EMULATION_OFILES = " {emulation_ofiles} >> "{o}"mk.tmp +Echo 'version = ' `Search 'ld version ' {srcdir}ldver.c | sed -e 's/.*ld version \([^ ]*\).*/\1/'` >> "{o}"mk.tmp +Echo "TDEFINES = " >> "{o}"mk.tmp +Echo '# End from mpw-config.in' >> "{o}"mk.tmp + +Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new +Echo '#include "mpw.h"' >> "{o}"config.new + +MoveIfChange "{o}"config.new "{o}"config.h diff --git a/ld/mpw-elfmips.c b/ld/mpw-elfmips.c new file mode 100644 index 0000000..e8ab056 --- /dev/null +++ b/ld/mpw-elfmips.c @@ -0,0 +1,1439 @@ +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* 32 bit ELF emulation code for elf32ebmip + Copyright (C) 1991, 93, 94, 95, 1996, 1998 Free Software Foundation, Inc. + Written by Steve Chamberlain <sac@cygnus.com> + ELF support by Ian Lance Taylor <ian@cygnus.com> + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_elf32ebmip + +#include "bfd.h" +#include "sysdep.h" + +#include <ctype.h> + +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldgram.h" + +static void gldelf32ebmip_before_parse PARAMS ((void)); +static boolean gldelf32ebmip_open_dynamic_archive + PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); +static void gldelf32ebmip_after_open PARAMS ((void)); +static void gldelf32ebmip_check_needed + PARAMS ((lang_input_statement_type *)); +static void gldelf32ebmip_stat_needed + PARAMS ((lang_input_statement_type *)); +static boolean gldelf32ebmip_search_needed + PARAMS ((const char *, const char *)); +static boolean gldelf32ebmip_try_needed PARAMS ((const char *)); +static void gldelf32ebmip_before_allocation PARAMS ((void)); +static void gldelf32ebmip_find_statement_assignment + PARAMS ((lang_statement_union_type *)); +static void gldelf32ebmip_find_exp_assignment PARAMS ((etree_type *)); +static boolean gldelf32ebmip_place_orphan + PARAMS ((lang_input_statement_type *, asection *)); +static void gldelf32ebmip_place_section + PARAMS ((lang_statement_union_type *)); +static char *gldelf32ebmip_get_script PARAMS ((int *isfile)); + +static void +gldelf32ebmip_before_parse() +{ + ldfile_output_architecture = bfd_arch_mips; + config.dynamic_link = true; +} + +/* Try to open a dynamic archive. This is where we know that ELF + dynamic libraries have an extension of .so. */ + +static boolean +gldelf32ebmip_open_dynamic_archive (arch, search, entry) + const char *arch; + search_dirs_type *search; + lang_input_statement_type *entry; +{ + const char *filename; + char *string; + + if (! entry->is_archive) + return false; + + filename = entry->filename; + + string = (char *) xmalloc (strlen (search->name) + + strlen (filename) + + strlen (arch) + + sizeof "/lib.so"); + + sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); + + if (! ldfile_try_open_bfd (string, entry)) + { + free (string); + return false; + } + + entry->filename = string; + + /* We have found a dynamic object to include in the link. The ELF + backend linker will create a DT_NEEDED entry in the .dynamic + section naming this file. If this file includes a DT_SONAME + entry, it will be used. Otherwise, the ELF linker will just use + the name of the file. For an archive found by searching, like + this one, the DT_NEEDED entry should consist of just the name of + the file, without the path information used to find it. Note + that we only need to do this if we have a dynamic object; an + archive will never be referenced by a DT_NEEDED entry. + + FIXME: This approach--using bfd_elf_set_dt_needed_name--is not + very pretty. I haven't been able to think of anything that is + pretty, though. */ + if (bfd_check_format (entry->the_bfd, bfd_object) + && (entry->the_bfd->flags & DYNAMIC) != 0) + { + char *needed_name; + + ASSERT (entry->is_archive && entry->search_dirs_flag); + needed_name = (char *) xmalloc (strlen (filename) + + strlen (arch) + + sizeof "lib.so"); + sprintf (needed_name, "lib%s%s.so", filename, arch); + bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name); + } + + return true; +} + + +/* These variables are required to pass information back and forth + between after_open and check_needed and stat_needed. */ + +static struct bfd_link_needed_list *global_needed; +static struct stat global_stat; +static boolean global_found; + +/* This is called after all the input files have been opened. */ + +static void +gldelf32ebmip_after_open () +{ + struct bfd_link_needed_list *needed, *l; + + /* We only need to worry about this when doing a final link. */ + if (link_info.relocateable || link_info.shared) + return; + + /* Get the list of files which appear in DT_NEEDED entries in + dynamic objects included in the link (often there will be none). + For each such file, we want to track down the corresponding + library, and include the symbol table in the link. This is what + the runtime dynamic linker will do. Tracking the files down here + permits one dynamic object to include another without requiring + special action by the person doing the link. Note that the + needed list can actually grow while we are stepping through this + loop. */ + needed = bfd_elf_get_needed_list (output_bfd, &link_info); + for (l = needed; l != NULL; l = l->next) + { + struct bfd_link_needed_list *ll; + const char *lib_path; + size_t len; + search_dirs_type *search; + + /* If we've already seen this file, skip it. */ + for (ll = needed; ll != l; ll = ll->next) + if (strcmp (ll->name, l->name) == 0) + break; + if (ll != l) + continue; + + /* See if this file was included in the link explicitly. */ + global_needed = l; + global_found = false; + lang_for_each_input_file (gldelf32ebmip_check_needed); + if (global_found) + continue; + + /* We need to find this file and include the symbol table. We + want to search for the file in the same way that the dynamic + linker will search. That means that we want to use + rpath_link, rpath, then the environment variable + LD_LIBRARY_PATH (native only), then the linker script + LIB_SEARCH_DIRS. We do not search using the -L arguments. */ + if (gldelf32ebmip_search_needed (command_line.rpath_link, + l->name)) + continue; + if (gldelf32ebmip_search_needed (command_line.rpath, l->name)) + continue; + if (command_line.rpath_link == NULL + && command_line.rpath == NULL) + { + lib_path = (const char *) getenv ("LD_RUN_PATH"); + if (gldelf32ebmip_search_needed (lib_path, l->name)) + continue; + } + len = strlen (l->name); + for (search = search_head; search != NULL; search = search->next) + { + char *filename; + + if (search->cmdline) + continue; + filename = (char *) xmalloc (strlen (search->name) + len + 2); + sprintf (filename, "%s/%s", search->name, l->name); + if (gldelf32ebmip_try_needed (filename)) + break; + free (filename); + } + if (search != NULL) + continue; + + einfo (_("%P: warning: %s, needed by %B, not found\n"), + l->name, l->by); + } +} + +/* Search for a needed file in a path. */ + +static boolean +gldelf32ebmip_search_needed (path, name) + const char *path; + const char *name; +{ + const char *s; + size_t len; + + if (path == NULL || *path == '\0') + return false; + len = strlen (name); + while (1) + { + char *filename, *sset; + + s = strchr (path, ':'); + if (s == NULL) + s = path + strlen (path); + + filename = (char *) xmalloc (s - path + len + 2); + if (s == path) + sset = filename; + else + { + memcpy (filename, path, s - path); + filename[s - path] = '/'; + sset = filename + (s - path) + 1; + } + strcpy (sset, name); + + if (gldelf32ebmip_try_needed (filename)) + return true; + + free (filename); + + if (*s == '\0') + break; + path = s + 1; + } + + return false; +} + +/* This function is called for each possible name for a dynamic object + named by a DT_NEEDED entry. */ + +static boolean +gldelf32ebmip_try_needed (name) + const char *name; +{ + bfd *abfd; + + abfd = bfd_openr (name, bfd_get_target (output_bfd)); + if (abfd == NULL) + return false; + if (! bfd_check_format (abfd, bfd_object)) + { + (void) bfd_close (abfd); + return false; + } + if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) + { + (void) bfd_close (abfd); + return false; + } + + /* We've found a dynamic object matching the DT_NEEDED entry. */ + + /* We have already checked that there is no other input file of the + same name. We must now check again that we are not including the + same file twice. We need to do this because on many systems + libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will + reference libc.so.1. If we have already included libc.so, we + don't want to include libc.so.1 if they are the same file, and we + can only check that using stat. */ + + if (bfd_stat (abfd, &global_stat) != 0) + einfo (_("%F%P:%B: bfd_stat failed: %E\n"), abfd); + global_found = false; + lang_for_each_input_file (gldelf32ebmip_stat_needed); + if (global_found) + { + /* Return true to indicate that we found the file, even though + we aren't going to do anything with it. */ + return true; + } + + /* Tell the ELF backend that don't want the output file to have a + DT_NEEDED entry for this file. */ + bfd_elf_set_dt_needed_name (abfd, ""); + + /* Add this file into the symbol table. */ + if (! bfd_link_add_symbols (abfd, &link_info)) + einfo (_("%F%B: could not read symbols: %E\n"), abfd); + + return true; +} + +/* See if an input file matches a DT_NEEDED entry by name. */ + +static void +gldelf32ebmip_check_needed (s) + lang_input_statement_type *s; +{ + if (global_found) + return; + + if (s->filename != NULL + && strcmp (s->filename, global_needed->name) == 0) + { + global_found = true; + return; + } + + if (s->the_bfd != NULL) + { + const char *soname; + + soname = bfd_elf_get_dt_soname (s->the_bfd); + if (soname != NULL + && strcmp (soname, global_needed->name) == 0) + { + global_found = true; + return; + } + } + + if (s->search_dirs_flag + && s->filename != NULL + && strchr (global_needed->name, '/') == NULL) + { + const char *f; + + f = strrchr (s->filename, '/'); + if (f != NULL + && strcmp (f + 1, global_needed->name) == 0) + { + global_found = true; + return; + } + } +} + +/* See if an input file matches a DT_NEEDED entry by running stat on + the file. */ + +static void +gldelf32ebmip_stat_needed (s) + lang_input_statement_type *s; +{ + struct stat st; + const char *suffix; + const char *soname; + const char *f; + + if (global_found) + return; + if (s->the_bfd == NULL) + return; + + if (bfd_stat (s->the_bfd, &st) != 0) + { + einfo (_("%P:%B: bfd_stat failed: %E\n"), s->the_bfd); + return; + } + + if (st.st_dev == global_stat.st_dev + && st.st_ino == global_stat.st_ino) + { + global_found = true; + return; + } + + /* We issue a warning if it looks like we are including two + different versions of the same shared library. For example, + there may be a problem if -lc picks up libc.so.6 but some other + shared library has a DT_NEEDED entry of libc.so.5. This is a + hueristic test, and it will only work if the name looks like + NAME.so.VERSION. FIXME: Depending on file names is error-prone. + If we really want to issue warnings about mixing version numbers + of shared libraries, we need to find a better way. */ + + if (strchr (global_needed->name, '/') != NULL) + return; + suffix = strstr (global_needed->name, ".so."); + if (suffix == NULL) + return; + suffix += sizeof ".so." - 1; + + soname = bfd_elf_get_dt_soname (s->the_bfd); + if (soname == NULL) + soname = s->filename; + + f = strrchr (soname, '/'); + if (f != NULL) + ++f; + else + f = soname; + + if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0) + einfo (_("%P: warning: %s, needed by %B, may conflict with %s\n"), + global_needed->name, global_needed->by, f); +} + +/* This is called after the sections have been attached to output + sections, but before any sizes or addresses have been set. */ + +static void +gldelf32ebmip_before_allocation () +{ + const char *rpath; + asection *sinterp; + + /* If we are going to make any variable assignments, we need to let + the ELF backend know about them in case the variables are + referred to by dynamic objects. */ + lang_for_each_statement (gldelf32ebmip_find_statement_assignment); + + /* Let the ELF backend work out the sizes of any sections required + by dynamic linking. */ + rpath = command_line.rpath; + if (rpath == NULL) + rpath = (const char *) getenv ("LD_RUN_PATH"); + if (! bfd_elf32_size_dynamic_sections (output_bfd, + command_line.soname, + rpath, + command_line.export_dynamic, + &link_info, + &sinterp)) + einfo (_("%P%F: failed to set dynamic section sizes: %E\n")); + + /* Let the user override the dynamic linker we are using. */ + if (command_line.interpreter != NULL + && sinterp != NULL) + { + sinterp->contents = (bfd_byte *) command_line.interpreter; + sinterp->_raw_size = strlen (command_line.interpreter) + 1; + } + + /* Look for any sections named .gnu.warning. As a GNU extensions, + we treat such sections as containing warning messages. We print + out the warning message, and then zero out the section size so + that it does not get copied into the output file. */ + + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + asection *s; + bfd_size_type sz; + char *msg; + boolean ret; + + if (is->just_syms_flag) + continue; + + s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning"); + if (s == NULL) + continue; + + sz = bfd_section_size (is->the_bfd, s); + msg = xmalloc ((size_t) sz + 1); + if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz)) + einfo (_("%F%B: Can't read contents of section .gnu.warning: %E\n"), + is->the_bfd); + msg[sz] = '\0'; + ret = link_info.callbacks->warning (&link_info, msg, + (const char *) NULL, + is->the_bfd, (asection *) NULL, + (bfd_vma) 0); + ASSERT (ret); + free (msg); + + /* Clobber the section size, so that we don't waste copying the + warning into the output file. */ + s->_raw_size = 0; + } + } +} + +/* This is called by the before_allocation routine via + lang_for_each_statement. It locates any assignment statements, and + tells the ELF backend about them, in case they are assignments to + symbols which are referred to by dynamic objects. */ + +static void +gldelf32ebmip_find_statement_assignment (s) + lang_statement_union_type *s; +{ + if (s->header.type == lang_assignment_statement_enum) + gldelf32ebmip_find_exp_assignment (s->assignment_statement.exp); +} + +/* Look through an expression for an assignment statement. */ + +static void +gldelf32ebmip_find_exp_assignment (exp) + etree_type *exp; +{ + struct bfd_link_hash_entry *h; + + switch (exp->type.node_class) + { + case etree_provide: + h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, + false, false, false); + if (h == NULL) + break; + + /* We call record_link_assignment even if the symbol is defined. + This is because if it is defined by a dynamic object, we + actually want to use the value defined by the linker script, + not the value from the dynamic object (because we are setting + symbols like etext). If the symbol is defined by a regular + object, then, as it happens, calling record_link_assignment + will do no harm. */ + + /* Fall through. */ + case etree_assign: + if (strcmp (exp->assign.dst, ".") != 0) + { + if (! (bfd_elf32_record_link_assignment + (output_bfd, &link_info, exp->assign.dst, + exp->type.node_class == etree_provide ? true : false))) + einfo (_("%P%F: failed to record assignment to %s: %E\n"), + exp->assign.dst); + } + gldelf32ebmip_find_exp_assignment (exp->assign.src); + break; + + case etree_binary: + gldelf32ebmip_find_exp_assignment (exp->binary.lhs); + gldelf32ebmip_find_exp_assignment (exp->binary.rhs); + break; + + case etree_trinary: + gldelf32ebmip_find_exp_assignment (exp->trinary.cond); + gldelf32ebmip_find_exp_assignment (exp->trinary.lhs); + gldelf32ebmip_find_exp_assignment (exp->trinary.rhs); + break; + + case etree_unary: + gldelf32ebmip_find_exp_assignment (exp->unary.child); + break; + + default: + break; + } +} + +/* Place an orphan section. We use this to put random SHF_ALLOC + sections in the right segment. */ + +static asection *hold_section; +static lang_output_section_statement_type *hold_use; +static lang_output_section_statement_type *hold_text; +static lang_output_section_statement_type *hold_rodata; +static lang_output_section_statement_type *hold_data; +static lang_output_section_statement_type *hold_bss; +static lang_output_section_statement_type *hold_rel; + +/*ARGSUSED*/ +static boolean +gldelf32ebmip_place_orphan (file, s) + lang_input_statement_type *file; + asection *s; +{ + lang_output_section_statement_type *place; + asection *snew, **pps; + lang_statement_list_type *old; + lang_statement_list_type add; + etree_type *address; + const char *secname, *ps; + lang_output_section_statement_type *os; + + if ((s->flags & SEC_ALLOC) == 0) + return false; + + /* Look through the script to see where to place this section. */ + hold_section = s; + hold_use = NULL; + lang_for_each_statement (gldelf32ebmip_place_section); + + if (hold_use != NULL) + { + /* We have already placed a section with this name. */ + wild_doit (&hold_use->children, s, hold_use, file); + return true; + } + + secname = bfd_get_section_name (s->owner, s); + + /* If this is a final link, then always put .gnu.warning.SYMBOL + sections into the .text section to get them out of the way. */ + if (! link_info.shared + && ! link_info.relocateable + && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 + && hold_text != NULL) + { + wild_doit (&hold_text->children, s, hold_text, file); + return true; + } + + /* Decide which segment the section should go in based on the + section name and section flags. */ + place = NULL; + if ((s->flags & SEC_HAS_CONTENTS) == 0 + && hold_bss != NULL) + place = hold_bss; + else if ((s->flags & SEC_READONLY) == 0 + && hold_data != NULL) + place = hold_data; + else if (strncmp (secname, ".rel", 4) == 0 + && hold_rel != NULL) + place = hold_rel; + else if ((s->flags & SEC_CODE) == 0 + && (s->flags & SEC_READONLY) != 0 + && hold_rodata != NULL) + place = hold_rodata; + else if ((s->flags & SEC_READONLY) != 0 + && hold_text != NULL) + place = hold_text; + if (place == NULL) + return false; + + /* Create the section in the output file, and put it in the right + place. This shuffling is to make the output file look neater. */ + snew = bfd_make_section (output_bfd, secname); + if (snew == NULL) + einfo (_("%P%F: output format %s cannot represent section called %s\n"), + output_bfd->xvec->name, secname); + if (place->bfd_section != NULL) + { + for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) + ; + *pps = snew->next; + snew->next = place->bfd_section->next; + place->bfd_section->next = snew; + } + + /* Start building a list of statements for this section. */ + old = stat_ptr; + stat_ptr = &add; + lang_list_init (stat_ptr); + + /* If the name of the section is representable in C, then create + symbols to mark the start and the end of the section. */ + for (ps = secname; *ps != '\0'; ps++) + if (! isalnum (*ps) && *ps != '_') + break; + if (*ps == '\0' && config.build_constructors) + { + char *symname; + + symname = (char *) xmalloc (ps - secname + sizeof "__start_"); + sprintf (symname, "__start_%s", secname); + lang_add_assignment (exp_assop ('=', symname, + exp_unop (ALIGN_K, + exp_intop ((bfd_vma) 1 + << s->alignment_power)))); + } + + if (! link_info.relocateable) + address = NULL; + else + address = exp_intop ((bfd_vma) 0); + + lang_enter_output_section_statement (secname, address, 0, + (bfd_vma) 0, + (etree_type *) NULL, + (etree_type *) NULL, + (etree_type *) NULL); + + os = lang_output_section_statement_lookup (secname); + wild_doit (&os->children, s, os, file); + + lang_leave_output_section_statement ((bfd_vma) 0, "*default*"); + stat_ptr = &add; + + if (*ps == '\0' && config.build_constructors) + { + char *symname; + + symname = (char *) xmalloc (ps - secname + sizeof "__stop_"); + sprintf (symname, "__stop_%s", secname); + lang_add_assignment (exp_assop ('=', symname, + exp_nameop (NAME, "."))); + } + + /* Now stick the new statement list right after PLACE. */ + *add.tail = place->header.next; + place->header.next = add.head; + + stat_ptr = old; + + return true; +} + +static void +gldelf32ebmip_place_section (s) + lang_statement_union_type *s; +{ + lang_output_section_statement_type *os; + + if (s->header.type != lang_output_section_statement_enum) + return; + + os = &s->output_section_statement; + + if (strcmp (os->name, hold_section->name) == 0) + hold_use = os; + + if (strcmp (os->name, ".text") == 0) + hold_text = os; + else if (strcmp (os->name, ".rodata") == 0) + hold_rodata = os; + else if (strcmp (os->name, ".data") == 0) + hold_data = os; + else if (strcmp (os->name, ".bss") == 0) + hold_bss = os; + else if (hold_rel == NULL + && os->bfd_section != NULL + && strncmp (os->name, ".rel", 4) == 0) + hold_rel = os; +} + +static char * +gldelf32ebmip_get_script(isfile) + int *isfile; +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\ + \"elf32-littlemips\")\n\ +OUTPUT_ARCH(mips)\n\ +ENTRY(_start)\n\ + /* For some reason, the Solaris linker makes bad executables\n\ + if gld -r is used and the intermediate file has sections starting\n\ + at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld\n\ + bug. But for now assigning the zero vmas works. */\n\ +SECTIONS\n\ +{\n\ + /* Read-only sections, merged into text segment: */\n\ + .interp 0 : { *(.interp) }\n\ + .reginfo 0 : { *(.reginfo) }\n\ + .dynamic 0 : { *(.dynamic) }\n\ + .dynstr 0 : { *(.dynstr) }\n\ + .dynsym 0 : { *(.dynsym) }\n\ + .hash 0 : { *(.hash) }\n\ + .rel.text 0 : { *(.rel.text) }\n\ + .rela.text 0 : { *(.rela.text) }\n\ + .rel.data 0 : { *(.rel.data) }\n\ + .rela.data 0 : { *(.rela.data) }\n\ + .rel.rodata 0 : { *(.rel.rodata) }\n\ + .rela.rodata 0 : { *(.rela.rodata) }\n\ + .rel.got 0 : { *(.rel.got) }\n\ + .rela.got 0 : { *(.rela.got) }\n\ + .rel.ctors 0 : { *(.rel.ctors) }\n\ + .rela.ctors 0 : { *(.rela.ctors) }\n\ + .rel.dtors 0 : { *(.rel.dtors) }\n\ + .rela.dtors 0 : { *(.rela.dtors) }\n\ + .rel.init 0 : { *(.rel.init) }\n\ + .rela.init 0 : { *(.rela.init) }\n\ + .rel.fini 0 : { *(.rel.fini) }\n\ + .rela.fini 0 : { *(.rela.fini) }\n\ + .rel.bss 0 : { *(.rel.bss) }\n\ + .rela.bss 0 : { *(.rela.bss) }\n\ + .rel.plt 0 : { *(.rel.plt) }\n\ + .rela.plt 0 : { *(.rela.plt) }\n\ + .rodata 0 : { *(.rodata) }\n\ + .rodata1 0 : { *(.rodata1) }\n\ + .init 0 : { *(.init) } =0\n\ + .text 0 :\n\ + {\n\ + *(.text)\n\ + *(.stub)\n\ + /* .gnu.warning sections are handled specially by elf32.em. */\n\ + *(.gnu.warning)\n\ + } =0\n\ + .fini 0 : { *(.fini) } =0\n\ + /* Adjust the address for the data segment. We want to adjust up to\n\ + the same address within the page on the next page up. It would\n\ + be more correct to do this:\n\ + The current expression does not correctly handle the case of a\n\ + text segment ending precisely at the end of a page; it causes the\n\ + data segment to skip a page. The above expression does not have\n\ + this problem, but it will currently (2/95) cause BFD to allocate\n\ + a single segment, combining both text and data, for this case.\n\ + This will prevent the text segment from being shared among\n\ + multiple executions of the program; I think that is more\n\ + important than losing a page of the virtual address space (note\n\ + that no actual memory is lost; the page which is skipped can not\n\ + be referenced). */\n\ + .data 0 :\n\ + {\n\ + *(.data)\n\ + CONSTRUCTORS\n\ + }\n\ + .data1 0 : { *(.data1) }\n\ + .ctors 0 : { *(.ctors) }\n\ + .dtors 0 : { *(.dtors) }\n\ + .got 0 :\n\ + {\n\ + *(.got.plt) *(.got)\n\ + }\n\ + /* We want the small data sections together, so single-instruction offsets\n\ + can access them all, and initialized data all before uninitialized, so\n\ + we can shorten the on-disk segment size. */\n\ + .sdata 0 : { *(.sdata) }\n\ + .sbss 0 : { *(.sbss) *(.scommon) }\n\ + .bss 0 :\n\ + {\n\ + *(.dynbss)\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ + /* These are needed for ELF backends which have not yet been\n\ + converted to the new style linker. */\n\ + .stab 0 : { *(.stab) }\n\ + .stabstr 0 : { *(.stabstr) }\n\ + /* DWARF debug sections.\n\ + Symbols in the .debug DWARF section are relative to the beginning of the\n\ + section so we begin .debug at 0. It's not clear yet what needs to happen\n\ + for the others. */\n\ + .debug 0 : { *(.debug) }\n\ + .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\ + .debug_aranges 0 : { *(.debug_aranges) }\n\ + .debug_pubnames 0 : { *(.debug_pubnames) }\n\ + .debug_sfnames 0 : { *(.debug_sfnames) }\n\ + .line 0 : { *(.line) }\n\ + /* These must appear regardless of . */\n\ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\ + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\ +}\n\n"; + else if (link_info.relocateable == true) + return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\ + \"elf32-littlemips\")\n\ +OUTPUT_ARCH(mips)\n\ +ENTRY(_start)\n\ + /* For some reason, the Solaris linker makes bad executables\n\ + if gld -r is used and the intermediate file has sections starting\n\ + at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld\n\ + bug. But for now assigning the zero vmas works. */\n\ +SECTIONS\n\ +{\n\ + /* Read-only sections, merged into text segment: */\n\ + .interp 0 : { *(.interp) }\n\ + .reginfo 0 : { *(.reginfo) }\n\ + .dynamic 0 : { *(.dynamic) }\n\ + .dynstr 0 : { *(.dynstr) }\n\ + .dynsym 0 : { *(.dynsym) }\n\ + .hash 0 : { *(.hash) }\n\ + .rel.text 0 : { *(.rel.text) }\n\ + .rela.text 0 : { *(.rela.text) }\n\ + .rel.data 0 : { *(.rel.data) }\n\ + .rela.data 0 : { *(.rela.data) }\n\ + .rel.rodata 0 : { *(.rel.rodata) }\n\ + .rela.rodata 0 : { *(.rela.rodata) }\n\ + .rel.got 0 : { *(.rel.got) }\n\ + .rela.got 0 : { *(.rela.got) }\n\ + .rel.ctors 0 : { *(.rel.ctors) }\n\ + .rela.ctors 0 : { *(.rela.ctors) }\n\ + .rel.dtors 0 : { *(.rel.dtors) }\n\ + .rela.dtors 0 : { *(.rela.dtors) }\n\ + .rel.init 0 : { *(.rel.init) }\n\ + .rela.init 0 : { *(.rela.init) }\n\ + .rel.fini 0 : { *(.rel.fini) }\n\ + .rela.fini 0 : { *(.rela.fini) }\n\ + .rel.bss 0 : { *(.rel.bss) }\n\ + .rela.bss 0 : { *(.rela.bss) }\n\ + .rel.plt 0 : { *(.rel.plt) }\n\ + .rela.plt 0 : { *(.rela.plt) }\n\ + .rodata 0 : { *(.rodata) }\n\ + .rodata1 0 : { *(.rodata1) }\n\ + .init 0 : { *(.init) } =0\n\ + .text 0 :\n\ + {\n\ + *(.text)\n\ + *(.stub)\n\ + /* .gnu.warning sections are handled specially by elf32.em. */\n\ + *(.gnu.warning)\n\ + } =0\n\ + .fini 0 : { *(.fini) } =0\n\ + /* Adjust the address for the data segment. We want to adjust up to\n\ + the same address within the page on the next page up. It would\n\ + be more correct to do this:\n\ + The current expression does not correctly handle the case of a\n\ + text segment ending precisely at the end of a page; it causes the\n\ + data segment to skip a page. The above expression does not have\n\ + this problem, but it will currently (2/95) cause BFD to allocate\n\ + a single segment, combining both text and data, for this case.\n\ + This will prevent the text segment from being shared among\n\ + multiple executions of the program; I think that is more\n\ + important than losing a page of the virtual address space (note\n\ + that no actual memory is lost; the page which is skipped can not\n\ + be referenced). */\n\ + .data 0 :\n\ + {\n\ + *(.data)\n\ + }\n\ + .data1 0 : { *(.data1) }\n\ + .ctors 0 : { *(.ctors) }\n\ + .dtors 0 : { *(.dtors) }\n\ + .got 0 :\n\ + {\n\ + *(.got.plt) *(.got)\n\ + }\n\ + /* We want the small data sections together, so single-instruction offsets\n\ + can access them all, and initialized data all before uninitialized, so\n\ + we can shorten the on-disk segment size. */\n\ + .sdata 0 : { *(.sdata) }\n\ + .sbss 0 : { *(.sbss) *(.scommon) }\n\ + .bss 0 :\n\ + {\n\ + *(.dynbss)\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ + /* These are needed for ELF backends which have not yet been\n\ + converted to the new style linker. */\n\ + .stab 0 : { *(.stab) }\n\ + .stabstr 0 : { *(.stabstr) }\n\ + /* DWARF debug sections.\n\ + Symbols in the .debug DWARF section are relative to the beginning of the\n\ + section so we begin .debug at 0. It's not clear yet what needs to happen\n\ + for the others. */\n\ + .debug 0 : { *(.debug) }\n\ + .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\ + .debug_aranges 0 : { *(.debug_aranges) }\n\ + .debug_pubnames 0 : { *(.debug_pubnames) }\n\ + .debug_sfnames 0 : { *(.debug_sfnames) }\n\ + .line 0 : { *(.line) }\n\ + /* These must appear regardless of . */\n\ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\ + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\ +}\n\n"; + else if (!config.text_read_only) + return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\ + \"elf32-littlemips\")\n\ +OUTPUT_ARCH(mips)\n\ +ENTRY(_start)\n\ + SEARCH_DIR(/usr/local/mips-elf/lib);\n\ +/* Do we need any of these for elf?\n\ + __DYNAMIC = 0; */\n\ +SECTIONS\n\ +{\n\ + /* Read-only sections, merged into text segment: */\n\ + . = 0x0400000;\n\ + .interp : { *(.interp) }\n\ + .reginfo : { *(.reginfo) }\n\ + .dynamic : { *(.dynamic) }\n\ + .dynstr : { *(.dynstr) }\n\ + .dynsym : { *(.dynsym) }\n\ + .hash : { *(.hash) }\n\ + .rel.text : { *(.rel.text) }\n\ + .rela.text : { *(.rela.text) }\n\ + .rel.data : { *(.rel.data) }\n\ + .rela.data : { *(.rela.data) }\n\ + .rel.rodata : { *(.rel.rodata) }\n\ + .rela.rodata : { *(.rela.rodata) }\n\ + .rel.got : { *(.rel.got) }\n\ + .rela.got : { *(.rela.got) }\n\ + .rel.ctors : { *(.rel.ctors) }\n\ + .rela.ctors : { *(.rela.ctors) }\n\ + .rel.dtors : { *(.rel.dtors) }\n\ + .rela.dtors : { *(.rela.dtors) }\n\ + .rel.init : { *(.rel.init) }\n\ + .rela.init : { *(.rela.init) }\n\ + .rel.fini : { *(.rel.fini) }\n\ + .rela.fini : { *(.rela.fini) }\n\ + .rel.bss : { *(.rel.bss) }\n\ + .rela.bss : { *(.rela.bss) }\n\ + .rel.plt : { *(.rel.plt) }\n\ + .rela.plt : { *(.rela.plt) }\n\ + .rodata : { *(.rodata) }\n\ + .rodata1 : { *(.rodata1) }\n\ + .init : { *(.init) } =0\n\ + .text :\n\ + {\n\ + _ftext = . ;\n\ + *(.text)\n\ + *(.stub)\n\ + /* .gnu.warning sections are handled specially by elf32.em. */\n\ + *(.gnu.warning)\n\ + } =0\n\ + _etext = .;\n\ + PROVIDE (etext = .);\n\ + .fini : { *(.fini) } =0\n\ + /* Adjust the address for the data segment. We want to adjust up to\n\ + the same address within the page on the next page up. It would\n\ + be more correct to do this:\n\ + . = .;\n\ + The current expression does not correctly handle the case of a\n\ + text segment ending precisely at the end of a page; it causes the\n\ + data segment to skip a page. The above expression does not have\n\ + this problem, but it will currently (2/95) cause BFD to allocate\n\ + a single segment, combining both text and data, for this case.\n\ + This will prevent the text segment from being shared among\n\ + multiple executions of the program; I think that is more\n\ + important than losing a page of the virtual address space (note\n\ + that no actual memory is lost; the page which is skipped can not\n\ + be referenced). */\n\ + . += . - 0x0400000;\n\ + .data :\n\ + {\n\ + _fdata = . ;\n\ + *(.data)\n\ + CONSTRUCTORS\n\ + }\n\ + .data1 : { *(.data1) }\n\ + .ctors : { *(.ctors) }\n\ + .dtors : { *(.dtors) }\n\ + _gp = ALIGN(16) + 0x7ff0;\n\ + .got :\n\ + {\n\ + *(.got.plt) *(.got)\n\ + }\n\ + /* We want the small data sections together, so single-instruction offsets\n\ + can access them all, and initialized data all before uninitialized, so\n\ + we can shorten the on-disk segment size. */\n\ + .sdata : { *(.sdata) }\n\ + .lit8 : { *(.lit8) }\n\ + .lit4 : { *(.lit4) }\n\ + _edata = .;\n\ + PROVIDE (edata = .);\n\ + __bss_start = .;\n\ + _fbss = .;\n\ + .sbss : { *(.sbss) *(.scommon) }\n\ + .bss :\n\ + {\n\ + *(.dynbss)\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ + _end = . ;\n\ + PROVIDE (end = .);\n\ + /* These are needed for ELF backends which have not yet been\n\ + converted to the new style linker. */\n\ + .stab 0 : { *(.stab) }\n\ + .stabstr 0 : { *(.stabstr) }\n\ + /* DWARF debug sections.\n\ + Symbols in the .debug DWARF section are relative to the beginning of the\n\ + section so we begin .debug at 0. It's not clear yet what needs to happen\n\ + for the others. */\n\ + .debug 0 : { *(.debug) }\n\ + .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\ + .debug_aranges 0 : { *(.debug_aranges) }\n\ + .debug_pubnames 0 : { *(.debug_pubnames) }\n\ + .debug_sfnames 0 : { *(.debug_sfnames) }\n\ + .line 0 : { *(.line) }\n\ + /* These must appear regardless of . */\n\ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\ + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\ +}\n\n"; + else if (!config.magic_demand_paged) + return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\ + \"elf32-littlemips\")\n\ +OUTPUT_ARCH(mips)\n\ +ENTRY(_start)\n\ + SEARCH_DIR(/usr/local/mips-elf/lib);\n\ +/* Do we need any of these for elf?\n\ + __DYNAMIC = 0; */\n\ +SECTIONS\n\ +{\n\ + /* Read-only sections, merged into text segment: */\n\ + . = 0x0400000;\n\ + .interp : { *(.interp) }\n\ + .reginfo : { *(.reginfo) }\n\ + .dynamic : { *(.dynamic) }\n\ + .dynstr : { *(.dynstr) }\n\ + .dynsym : { *(.dynsym) }\n\ + .hash : { *(.hash) }\n\ + .rel.text : { *(.rel.text) }\n\ + .rela.text : { *(.rela.text) }\n\ + .rel.data : { *(.rel.data) }\n\ + .rela.data : { *(.rela.data) }\n\ + .rel.rodata : { *(.rel.rodata) }\n\ + .rela.rodata : { *(.rela.rodata) }\n\ + .rel.got : { *(.rel.got) }\n\ + .rela.got : { *(.rela.got) }\n\ + .rel.ctors : { *(.rel.ctors) }\n\ + .rela.ctors : { *(.rela.ctors) }\n\ + .rel.dtors : { *(.rel.dtors) }\n\ + .rela.dtors : { *(.rela.dtors) }\n\ + .rel.init : { *(.rel.init) }\n\ + .rela.init : { *(.rela.init) }\n\ + .rel.fini : { *(.rel.fini) }\n\ + .rela.fini : { *(.rela.fini) }\n\ + .rel.bss : { *(.rel.bss) }\n\ + .rela.bss : { *(.rela.bss) }\n\ + .rel.plt : { *(.rel.plt) }\n\ + .rela.plt : { *(.rela.plt) }\n\ + .rodata : { *(.rodata) }\n\ + .rodata1 : { *(.rodata1) }\n\ + .init : { *(.init) } =0\n\ + .text :\n\ + {\n\ + _ftext = . ;\n\ + *(.text)\n\ + *(.stub)\n\ + /* .gnu.warning sections are handled specially by elf32.em. */\n\ + *(.gnu.warning)\n\ + } =0\n\ + _etext = .;\n\ + PROVIDE (etext = .);\n\ + .fini : { *(.fini) } =0\n\ + /* Adjust the address for the data segment. We want to adjust up to\n\ + the same address within the page on the next page up. It would\n\ + be more correct to do this:\n\ + . = 0x10000000;\n\ + The current expression does not correctly handle the case of a\n\ + text segment ending precisely at the end of a page; it causes the\n\ + data segment to skip a page. The above expression does not have\n\ + this problem, but it will currently (2/95) cause BFD to allocate\n\ + a single segment, combining both text and data, for this case.\n\ + This will prevent the text segment from being shared among\n\ + multiple executions of the program; I think that is more\n\ + important than losing a page of the virtual address space (note\n\ + that no actual memory is lost; the page which is skipped can not\n\ + be referenced). */\n\ + . += 0x10000000 - 0x0400000;\n\ + .data :\n\ + {\n\ + _fdata = . ;\n\ + *(.data)\n\ + CONSTRUCTORS\n\ + }\n\ + .data1 : { *(.data1) }\n\ + .ctors : { *(.ctors) }\n\ + .dtors : { *(.dtors) }\n\ + _gp = ALIGN(16) + 0x7ff0;\n\ + .got :\n\ + {\n\ + *(.got.plt) *(.got)\n\ + }\n\ + /* We want the small data sections together, so single-instruction offsets\n\ + can access them all, and initialized data all before uninitialized, so\n\ + we can shorten the on-disk segment size. */\n\ + .sdata : { *(.sdata) }\n\ + .lit8 : { *(.lit8) }\n\ + .lit4 : { *(.lit4) }\n\ + _edata = .;\n\ + PROVIDE (edata = .);\n\ + __bss_start = .;\n\ + _fbss = .;\n\ + .sbss : { *(.sbss) *(.scommon) }\n\ + .bss :\n\ + {\n\ + *(.dynbss)\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ + _end = . ;\n\ + PROVIDE (end = .);\n\ + /* These are needed for ELF backends which have not yet been\n\ + converted to the new style linker. */\n\ + .stab 0 : { *(.stab) }\n\ + .stabstr 0 : { *(.stabstr) }\n\ + /* DWARF debug sections.\n\ + Symbols in the .debug DWARF section are relative to the beginning of the\n\ + section so we begin .debug at 0. It's not clear yet what needs to happen\n\ + for the others. */\n\ + .debug 0 : { *(.debug) }\n\ + .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\ + .debug_aranges 0 : { *(.debug_aranges) }\n\ + .debug_pubnames 0 : { *(.debug_pubnames) }\n\ + .debug_sfnames 0 : { *(.debug_sfnames) }\n\ + .line 0 : { *(.line) }\n\ + /* These must appear regardless of . */\n\ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\ + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\ +}\n\n"; + else if (link_info.shared) + return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\ + \"elf32-littlemips\")\n\ +OUTPUT_ARCH(mips)\n\ +ENTRY(_start)\n\ + SEARCH_DIR(/usr/local/mips-elf/lib);\n\ +/* Do we need any of these for elf?\n\ + __DYNAMIC = 0; */\n\ +SECTIONS\n\ +{\n\ + /* Read-only sections, merged into text segment: */\n\ + . = 0x5ffe0000 + SIZEOF_HEADERS;\n\ + .reginfo : { *(.reginfo) }\n\ + .dynamic : { *(.dynamic) }\n\ + .dynstr : { *(.dynstr) }\n\ + .dynsym : { *(.dynsym) }\n\ + .hash : { *(.hash) }\n\ + .rel.text : { *(.rel.text) }\n\ + .rela.text : { *(.rela.text) }\n\ + .rel.data : { *(.rel.data) }\n\ + .rela.data : { *(.rela.data) }\n\ + .rel.rodata : { *(.rel.rodata) }\n\ + .rela.rodata : { *(.rela.rodata) }\n\ + .rel.got : { *(.rel.got) }\n\ + .rela.got : { *(.rela.got) }\n\ + .rel.ctors : { *(.rel.ctors) }\n\ + .rela.ctors : { *(.rela.ctors) }\n\ + .rel.dtors : { *(.rel.dtors) }\n\ + .rela.dtors : { *(.rela.dtors) }\n\ + .rel.init : { *(.rel.init) }\n\ + .rela.init : { *(.rela.init) }\n\ + .rel.fini : { *(.rel.fini) }\n\ + .rela.fini : { *(.rela.fini) }\n\ + .rel.bss : { *(.rel.bss) }\n\ + .rela.bss : { *(.rela.bss) }\n\ + .rel.plt : { *(.rel.plt) }\n\ + .rela.plt : { *(.rela.plt) }\n\ + .rodata : { *(.rodata) }\n\ + .rodata1 : { *(.rodata1) }\n\ + .init : { *(.init) } =0\n\ + .text :\n\ + {\n\ + *(.text)\n\ + *(.stub)\n\ + /* .gnu.warning sections are handled specially by elf32.em. */\n\ + *(.gnu.warning)\n\ + } =0\n\ + .fini : { *(.fini) } =0\n\ + /* Adjust the address for the data segment. We want to adjust up to\n\ + the same address within the page on the next page up. It would\n\ + be more correct to do this:\n\ + . = 0x10000000;\n\ + The current expression does not correctly handle the case of a\n\ + text segment ending precisely at the end of a page; it causes the\n\ + data segment to skip a page. The above expression does not have\n\ + this problem, but it will currently (2/95) cause BFD to allocate\n\ + a single segment, combining both text and data, for this case.\n\ + This will prevent the text segment from being shared among\n\ + multiple executions of the program; I think that is more\n\ + important than losing a page of the virtual address space (note\n\ + that no actual memory is lost; the page which is skipped can not\n\ + be referenced). */\n\ + . += 0x10000;\n\ + .data :\n\ + {\n\ + *(.data)\n\ + CONSTRUCTORS\n\ + }\n\ + .data1 : { *(.data1) }\n\ + .ctors : { *(.ctors) }\n\ + .dtors : { *(.dtors) }\n\ + _gp = ALIGN(16) + 0x7ff0;\n\ + .got :\n\ + {\n\ + *(.got.plt) *(.got)\n\ + }\n\ + /* We want the small data sections together, so single-instruction offsets\n\ + can access them all, and initialized data all before uninitialized, so\n\ + we can shorten the on-disk segment size. */\n\ + .sdata : { *(.sdata) }\n\ + .lit8 : { *(.lit8) }\n\ + .lit4 : { *(.lit4) }\n\ + .sbss : { *(.sbss) *(.scommon) }\n\ + .bss :\n\ + {\n\ + *(.dynbss)\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ + /* These are needed for ELF backends which have not yet been\n\ + converted to the new style linker. */\n\ + .stab 0 : { *(.stab) }\n\ + .stabstr 0 : { *(.stabstr) }\n\ + /* DWARF debug sections.\n\ + Symbols in the .debug DWARF section are relative to the beginning of the\n\ + section so we begin .debug at 0. It's not clear yet what needs to happen\n\ + for the others. */\n\ + .debug 0 : { *(.debug) }\n\ + .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\ + .debug_aranges 0 : { *(.debug_aranges) }\n\ + .debug_pubnames 0 : { *(.debug_pubnames) }\n\ + .debug_sfnames 0 : { *(.debug_sfnames) }\n\ + .line 0 : { *(.line) }\n\ + /* These must appear regardless of . */\n\ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\ + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\ +}\n\n"; + else + return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\ + \"elf32-littlemips\")\n\ +OUTPUT_ARCH(mips)\n\ +ENTRY(_start)\n\ + SEARCH_DIR(/usr/local/mips-elf/lib);\n\ +/* Do we need any of these for elf?\n\ + __DYNAMIC = 0; */\n\ +SECTIONS\n\ +{\n\ + /* Read-only sections, merged into text segment: */\n\ + . = 0x0400000;\n\ + .interp : { *(.interp) }\n\ + .reginfo : { *(.reginfo) }\n\ + .dynamic : { *(.dynamic) }\n\ + .dynstr : { *(.dynstr) }\n\ + .dynsym : { *(.dynsym) }\n\ + .hash : { *(.hash) }\n\ + .rel.text : { *(.rel.text) }\n\ + .rela.text : { *(.rela.text) }\n\ + .rel.data : { *(.rel.data) }\n\ + .rela.data : { *(.rela.data) }\n\ + .rel.rodata : { *(.rel.rodata) }\n\ + .rela.rodata : { *(.rela.rodata) }\n\ + .rel.got : { *(.rel.got) }\n\ + .rela.got : { *(.rela.got) }\n\ + .rel.ctors : { *(.rel.ctors) }\n\ + .rela.ctors : { *(.rela.ctors) }\n\ + .rel.dtors : { *(.rel.dtors) }\n\ + .rela.dtors : { *(.rela.dtors) }\n\ + .rel.init : { *(.rel.init) }\n\ + .rela.init : { *(.rela.init) }\n\ + .rel.fini : { *(.rel.fini) }\n\ + .rela.fini : { *(.rela.fini) }\n\ + .rel.bss : { *(.rel.bss) }\n\ + .rela.bss : { *(.rela.bss) }\n\ + .rel.plt : { *(.rel.plt) }\n\ + .rela.plt : { *(.rela.plt) }\n\ + .rodata : { *(.rodata) }\n\ + .rodata1 : { *(.rodata1) }\n\ + .init : { *(.init) } =0\n\ + .text :\n\ + {\n\ + _ftext = . ;\n\ + *(.text)\n\ + *(.stub)\n\ + /* .gnu.warning sections are handled specially by elf32.em. */\n\ + *(.gnu.warning)\n\ + } =0\n\ + _etext = .;\n\ + PROVIDE (etext = .);\n\ + .fini : { *(.fini) } =0\n\ + /* Adjust the address for the data segment. We want to adjust up to\n\ + the same address within the page on the next page up. It would\n\ + be more correct to do this:\n\ + . = 0x10000000;\n\ + The current expression does not correctly handle the case of a\n\ + text segment ending precisely at the end of a page; it causes the\n\ + data segment to skip a page. The above expression does not have\n\ + this problem, but it will currently (2/95) cause BFD to allocate\n\ + a single segment, combining both text and data, for this case.\n\ + This will prevent the text segment from being shared among\n\ + multiple executions of the program; I think that is more\n\ + important than losing a page of the virtual address space (note\n\ + that no actual memory is lost; the page which is skipped can not\n\ + be referenced). */\n\ + . += 0x10000000 - 0x0400000;\n\ + .data :\n\ + {\n\ + _fdata = . ;\n\ + *(.data)\n\ + CONSTRUCTORS\n\ + }\n\ + .data1 : { *(.data1) }\n\ + .ctors : { *(.ctors) }\n\ + .dtors : { *(.dtors) }\n\ + _gp = ALIGN(16) + 0x7ff0;\n\ + .got :\n\ + {\n\ + *(.got.plt) *(.got)\n\ + }\n\ + /* We want the small data sections together, so single-instruction offsets\n\ + can access them all, and initialized data all before uninitialized, so\n\ + we can shorten the on-disk segment size. */\n\ + .sdata : { *(.sdata) }\n\ + .lit8 : { *(.lit8) }\n\ + .lit4 : { *(.lit4) }\n\ + _edata = .;\n\ + PROVIDE (edata = .);\n\ + __bss_start = .;\n\ + _fbss = .;\n\ + .sbss : { *(.sbss) *(.scommon) }\n\ + .bss :\n\ + {\n\ + *(.dynbss)\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ + _end = . ;\n\ + PROVIDE (end = .);\n\ + /* These are needed for ELF backends which have not yet been\n\ + converted to the new style linker. */\n\ + .stab 0 : { *(.stab) }\n\ + .stabstr 0 : { *(.stabstr) }\n\ + /* DWARF debug sections.\n\ + Symbols in the .debug DWARF section are relative to the beginning of the\n\ + section so we begin .debug at 0. It's not clear yet what needs to happen\n\ + for the others. */\n\ + .debug 0 : { *(.debug) }\n\ + .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\ + .debug_aranges 0 : { *(.debug_aranges) }\n\ + .debug_pubnames 0 : { *(.debug_pubnames) }\n\ + .debug_sfnames 0 : { *(.debug_sfnames) }\n\ + .line 0 : { *(.line) }\n\ + /* These must appear regardless of . */\n\ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\ + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\ +}\n\n"; +} + +struct ld_emulation_xfer_struct ld_elf32ebmip_emulation = +{ + gldelf32ebmip_before_parse, + syslib_default, + hll_default, + after_parse_default, + gldelf32ebmip_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gldelf32ebmip_before_allocation, + gldelf32ebmip_get_script, + "elf32ebmip", + "elf32-bigmips", + NULL, + NULL, + gldelf32ebmip_open_dynamic_archive, + gldelf32ebmip_place_orphan +}; diff --git a/ld/mpw-eppcmac.c b/ld/mpw-eppcmac.c new file mode 100644 index 0000000..ba09a41 --- /dev/null +++ b/ld/mpw-eppcmac.c @@ -0,0 +1,1224 @@ +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* AIX emulation code for ppcmacos + Copyright (C) 1991, 1993, 1995, 1998 Free Software Foundation, Inc. + Written by Steve Chamberlain <sac@cygnus.com> + AIX support by Ian Lance Taylor <ian@cygnus.com> + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_ppcmacos + +#include "bfd.h" +#include "sysdep.h" +#include "libiberty.h" +#include "getopt.h" +#include "bfdlink.h" + +#include <ctype.h> + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldctor.h" +#include "ldgram.h" + +static void gldppcmacos_before_parse PARAMS ((void)); +static int gldppcmacos_parse_args PARAMS ((int, char **)); +static void gldppcmacos_after_open PARAMS ((void)); +static void gldppcmacos_before_allocation PARAMS ((void)); +static void gldppcmacos_read_file PARAMS ((const char *, boolean)); +static void gldppcmacos_free PARAMS ((PTR)); +static void gldppcmacos_find_relocs + PARAMS ((lang_statement_union_type *)); +static void gldppcmacos_find_exp_assignment PARAMS ((etree_type *)); +static char *gldppcmacos_get_script PARAMS ((int *isfile)); + +/* The file alignment required for each section. */ +static unsigned long file_align; + +/* The maximum size the stack is permitted to grow. This is stored in + the a.out header. */ +static unsigned long maxstack; + +/* The maximum data size. This is stored in the a.out header. */ +static unsigned long maxdata; + +/* Whether to perform garbage collection. */ +static int gc = 1; + +/* The module type to use. */ +static unsigned short modtype = ('1' << 8) | 'L'; + +/* Whether the .text section must be read-only (i.e., no relocs + permitted). */ +static int textro; + +/* Whether to implement Unix like linker semantics. */ +static int unix_ld; + +/* Structure used to hold import file list. */ + +struct filelist +{ + struct filelist *next; + const char *name; +}; + +/* List of import files. */ +static struct filelist *import_files; + +/* List of export symbols read from the export files. */ + +struct export_symbol_list +{ + struct export_symbol_list *next; + const char *name; + boolean syscall; +}; + +static struct export_symbol_list *export_symbols; + +/* This routine is called before anything else is done. */ + +static void +gldppcmacos_before_parse() +{ +#ifndef TARGET_ /* I.e., if not generic. */ + ldfile_output_architecture = bfd_arch_powerpc; +#endif /* not TARGET_ */ +} + +/* Handle AIX specific options. */ + +static int +gldppcmacos_parse_args (argc, argv) + int argc; + char **argv; +{ + int prevoptind = optind; + int prevopterr = opterr; + int indx; + int longind; + int optc; + long val; + char *end; + +#define OPTION_IGNORE (300) +#define OPTION_AUTOIMP (OPTION_IGNORE + 1) +#define OPTION_ERNOTOK (OPTION_AUTOIMP + 1) +#define OPTION_EROK (OPTION_ERNOTOK + 1) +#define OPTION_EXPORT (OPTION_EROK + 1) +#define OPTION_IMPORT (OPTION_EXPORT + 1) +#define OPTION_LOADMAP (OPTION_IMPORT + 1) +#define OPTION_MAXDATA (OPTION_LOADMAP + 1) +#define OPTION_MAXSTACK (OPTION_MAXDATA + 1) +#define OPTION_MODTYPE (OPTION_MAXSTACK + 1) +#define OPTION_NOAUTOIMP (OPTION_MODTYPE + 1) +#define OPTION_NOSTRCMPCT (OPTION_NOAUTOIMP + 1) +#define OPTION_PD (OPTION_NOSTRCMPCT + 1) +#define OPTION_PT (OPTION_PD + 1) +#define OPTION_STRCMPCT (OPTION_PT + 1) +#define OPTION_UNIX (OPTION_STRCMPCT + 1) + + static struct option longopts[] = { + {"basis", no_argument, NULL, OPTION_IGNORE}, + {"bautoimp", no_argument, NULL, OPTION_AUTOIMP}, + {"bcomprld", no_argument, NULL, OPTION_IGNORE}, + {"bcrld", no_argument, NULL, OPTION_IGNORE}, + {"bcror31", no_argument, NULL, OPTION_IGNORE}, + {"bD", required_argument, NULL, OPTION_MAXDATA}, + {"bE", required_argument, NULL, OPTION_EXPORT}, + {"bernotok", no_argument, NULL, OPTION_ERNOTOK}, + {"berok", no_argument, NULL, OPTION_EROK}, + {"berrmsg", no_argument, NULL, OPTION_IGNORE}, + {"bexport", required_argument, NULL, OPTION_EXPORT}, + {"bf", no_argument, NULL, OPTION_ERNOTOK}, + {"bgc", no_argument, &gc, 1}, + {"bh", required_argument, NULL, OPTION_IGNORE}, + {"bhalt", required_argument, NULL, OPTION_IGNORE}, + {"bI", required_argument, NULL, OPTION_IMPORT}, + {"bimport", required_argument, NULL, OPTION_IMPORT}, + {"bl", required_argument, NULL, OPTION_LOADMAP}, + {"bloadmap", required_argument, NULL, OPTION_LOADMAP}, + {"bmaxdata", required_argument, NULL, OPTION_MAXDATA}, + {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK}, + {"bM", required_argument, NULL, OPTION_MODTYPE}, + {"bmodtype", required_argument, NULL, OPTION_MODTYPE}, + {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP}, + {"bnodelcsect", no_argument, NULL, OPTION_IGNORE}, + {"bnoentry", no_argument, NULL, OPTION_IGNORE}, + {"bnogc", no_argument, &gc, 0}, + {"bnso", no_argument, NULL, OPTION_NOAUTOIMP}, + {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT}, + {"bnotextro", no_argument, &textro, 0}, + {"bnro", no_argument, &textro, 0}, + {"bpD", required_argument, NULL, OPTION_PD}, + {"bpT", required_argument, NULL, OPTION_PT}, + {"bro", no_argument, &textro, 1}, + {"bS", required_argument, NULL, OPTION_MAXSTACK}, + {"bso", no_argument, NULL, OPTION_AUTOIMP}, + {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT}, + {"btextro", no_argument, &textro, 1}, + {"static", no_argument, NULL, OPTION_NOAUTOIMP}, + {"unix", no_argument, NULL, OPTION_UNIX}, + {NULL, no_argument, NULL, 0} + }; + + /* Options supported by the AIX linker which we do not support: -f, + -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps, + -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl, + -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl, + -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink, + -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder, + -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk, + -bx, -bX, -bxref. */ + + /* If the current option starts with -b, change the first : to an =. + The AIX linker uses : to separate the option from the argument; + changing it to = lets us treat it as a getopt option. */ + indx = optind; + if (indx == 0) + indx = 1; + if (indx < argc && strncmp (argv[indx], "-b", 2) == 0) + { + char *s; + + for (s = argv[indx]; *s != '\0'; s++) + { + if (*s == ':') + { + *s = '='; + break; + } + } + } + + opterr = 0; + optc = getopt_long_only (argc, argv, "-D:H:KT:z", longopts, &longind); + opterr = prevopterr; + + switch (optc) + { + default: + optind = prevoptind; + return 0; + + case 0: + /* Long option which just sets a flag. */ + break; + + case 'D': + val = strtol (optarg, &end, 0); + if (*end != '\0') + einfo (_("%P: warning: ignoring invalid -D number %s\n"), optarg); + else if (val != -1) + lang_section_start (".data", exp_intop (val)); + break; + + case 'H': + val = strtoul (optarg, &end, 0); + if (*end != '\0' + || (val & (val - 1)) != 0) + einfo (_("%P: warning: ignoring invalid -H number %s\n"), optarg); + else + file_align = val; + break; + + case 'K': + case 'z': + /* FIXME: This should use the page size for the target system. */ + file_align = 4096; + break; + + case 'T': + /* On AIX this is the same as GNU ld -Ttext. When we see -T + number, we assume the AIX option is intended. Otherwise, we + assume the usual GNU ld -T option is intended. We can't just + ignore the AIX option, because gcc passes it to the linker. */ + val = strtoul (optarg, &end, 0); + if (*end != '\0') + { + optind = prevoptind; + return 0; + } + lang_section_start (".text", exp_intop (val)); + break; + + case OPTION_IGNORE: + break; + + case OPTION_AUTOIMP: + link_info.static_link = false; + break; + + case OPTION_ERNOTOK: + force_make_executable = false; + break; + + case OPTION_EROK: + force_make_executable = true; + break; + + case OPTION_EXPORT: + gldppcmacos_read_file (optarg, false); + break; + + case OPTION_IMPORT: + { + struct filelist *n; + struct filelist **flpp; + + n = (struct filelist *) xmalloc (sizeof (struct filelist)); + n->next = NULL; + n->name = optarg; + flpp = &import_files; + while (*flpp != NULL) + flpp = &(*flpp)->next; + *flpp = n; + } + break; + + case OPTION_LOADMAP: + config.map_filename = optarg; + break; + + case OPTION_MAXDATA: + val = strtoul (optarg, &end, 0); + if (*end != '\0') + einfo (_("%P: warning: ignoring invalid -bmaxdata number %s\n"), + optarg); + else + maxdata = val; + break; + + case OPTION_MAXSTACK: + val = strtoul (optarg, &end, 0); + if (*end != '\0') + einfo (_("%P: warning: ignoring invalid -bmaxstack number %s\n"), + optarg); + else + maxstack = val; + break; + + case OPTION_MODTYPE: + if (*optarg == 'S') + { + link_info.shared = true; + ++optarg; + } + if (*optarg == '\0' || optarg[1] == '\0') + einfo (_("%P: warning: ignoring invalid module type %s\n"), optarg); + else + modtype = (*optarg << 8) | optarg[1]; + break; + + case OPTION_NOAUTOIMP: + link_info.static_link = true; + break; + + case OPTION_NOSTRCMPCT: + link_info.traditional_format = true; + break; + + case OPTION_PD: + /* This sets the page that the .data section is supposed to + start on. The offset within the page should still be the + offset within the file, so we need to build an appropriate + expression. */ + val = strtoul (optarg, &end, 0); + if (*end != '\0') + einfo (_("%P: warning: ignoring invalid -pD number %s\n"), optarg); + else + { + etree_type *t; + + t = exp_binop ('+', + exp_intop (val), + exp_binop ('&', + exp_nameop (NAME, "."), + exp_intop (0xfff))); + t = exp_binop ('&', + exp_binop ('+', t, exp_intop (7)), + exp_intop (~ (bfd_vma) 7)); + lang_section_start (".data", t); + } + break; + + case OPTION_PT: + /* This set the page that the .text section is supposed to start + on. The offset within the page should still be the offset + within the file. */ + val = strtoul (optarg, &end, 0); + if (*end != '\0') + einfo (_("%P: warning: ignoring invalid -pT number %s\n"), optarg); + else + { + etree_type *t; + + t = exp_binop ('+', + exp_intop (val), + exp_nameop (SIZEOF_HEADERS, NULL)); + t = exp_binop ('&', + exp_binop ('+', t, exp_intop (7)), + exp_intop (~ (bfd_vma) 7)); + lang_section_start (".text", t); + } + break; + + case OPTION_STRCMPCT: + link_info.traditional_format = false; + break; + + case OPTION_UNIX: + unix_ld = true; + break; + } + + return 1; +} + +/* This is called when an input file can not be recognized as a BFD + object or an archive. If the file starts with #!, we must treat it + as an import file. This is for AIX compatibility. */ + +static boolean +gldppcmacos_unrecognized_file (entry) + lang_input_statement_type *entry; +{ + FILE *e; + boolean ret; + + e = fopen (entry->filename, FOPEN_RT); + if (e == NULL) + return false; + + ret = false; + + if (getc (e) == '#' && getc (e) == '!') + { + struct filelist *n; + struct filelist **flpp; + + n = (struct filelist *) xmalloc (sizeof (struct filelist)); + n->next = NULL; + n->name = entry->filename; + flpp = &import_files; + while (*flpp != NULL) + flpp = &(*flpp)->next; + *flpp = n; + + ret = true; + entry->loaded = true; + } + + fclose (e); + + return ret; +} + +/* This is called after the input files have been opened. */ + +static void +gldppcmacos_after_open () +{ + boolean r; + struct set_info *p; + + /* Call ldctor_build_sets, after pretending that this is a + relocateable link. We do this because AIX requires relocation + entries for all references to symbols, even in a final + executable. Of course, we only want to do this if we are + producing an XCOFF output file. */ + r = link_info.relocateable; + if (strstr (bfd_get_target (output_bfd), "xcoff") != NULL) + link_info.relocateable = true; + ldctor_build_sets (); + link_info.relocateable = r; + + /* For each set, record the size, so that the XCOFF backend can + output the correct csect length. */ + for (p = sets; p != (struct set_info *) NULL; p = p->next) + { + bfd_size_type size; + + /* If the symbol is defined, we may have been invoked from + collect, and the sets may already have been built, so we do + not do anything. */ + if (p->h->type == bfd_link_hash_defined + || p->h->type == bfd_link_hash_defweak) + continue; + + if (p->reloc != BFD_RELOC_CTOR) + { + /* Handle this if we need to. */ + abort (); + } + + size = (p->count + 2) * 4; + if (! bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size)) + einfo (_("%F%P: bfd_xcoff_link_record_set failed: %E\n")); + } +} + +/* This is called after the sections have been attached to output + sections, but before any sizes or addresses have been set. */ + +static void +gldppcmacos_before_allocation () +{ + struct filelist *fl; + struct export_symbol_list *el; + char *libpath; + asection *special_sections[6]; + int i; + + /* Handle the import and export files, if any. */ + for (fl = import_files; fl != NULL; fl = fl->next) + gldppcmacos_read_file (fl->name, true); + for (el = export_symbols; el != NULL; el = el->next) + { + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (link_info.hash, el->name, false, false, false); + if (h == NULL) + einfo (_("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n")); + if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h, el->syscall)) + einfo (_("%P%F: bfd_xcoff_export_symbol failed: %E\n")); + } + + /* Track down all relocations called for by the linker script (these + are typically constructor/destructor entries created by + CONSTRUCTORS) and let the backend know it will need to create + .loader relocs for them. */ + lang_for_each_statement (gldppcmacos_find_relocs); + + /* We need to build LIBPATH from the -L arguments. If any -rpath + arguments were used, though, we use -rpath instead, as a GNU + extension. */ + if (command_line.rpath != NULL) + libpath = command_line.rpath; + else if (search_head == NULL) + libpath = (char *) ""; + else + { + size_t len; + search_dirs_type *search; + + len = strlen (search_head->name); + libpath = xmalloc (len + 1); + strcpy (libpath, search_head->name); + for (search = search_head->next; search != NULL; search = search->next) + { + size_t nlen; + + nlen = strlen (search->name); + libpath = xrealloc (libpath, len + nlen + 2); + libpath[len] = ':'; + strcpy (libpath + len + 1, search->name); + len += nlen + 1; + } + } + + /* Let the XCOFF backend set up the .loader section. */ + if (! bfd_xcoff_size_dynamic_sections (output_bfd, &link_info, libpath, + entry_symbol, file_align, + maxstack, maxdata, + gc && ! unix_ld ? true : false, + modtype, + textro ? true : false, + unix_ld, + special_sections)) + einfo (_("%P%F: failed to set dynamic section sizes: %E\n")); + + /* Look through the special sections, and put them in the right + place in the link ordering. This is especially magic. */ + for (i = 0; i < 6; i++) + { + asection *sec; + lang_output_section_statement_type *os; + lang_statement_union_type **pls; + lang_input_section_type *is; + const char *oname; + boolean start; + + sec = special_sections[i]; + if (sec == NULL) + continue; + + /* Remove this section from the list of the output section. + This assumes we know what the script looks like. */ + is = NULL; + os = lang_output_section_find (sec->output_section->name); + if (os == NULL) + einfo (_("%P%F: can't find output section %s\n"), + sec->output_section->name); + for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->next) + { + if ((*pls)->header.type == lang_input_section_enum + && (*pls)->input_section.section == sec) + { + is = (lang_input_section_type *) *pls; + *pls = (*pls)->next; + break; + } + if ((*pls)->header.type == lang_wild_statement_enum) + { + lang_statement_union_type **pwls; + + for (pwls = &(*pls)->wild_statement.children.head; + *pwls != NULL; + pwls = &(*pwls)->next) + { + if ((*pwls)->header.type == lang_input_section_enum + && (*pwls)->input_section.section == sec) + { + is = (lang_input_section_type *) *pwls; + *pwls = (*pwls)->next; + break; + } + } + if (is != NULL) + break; + } + } + + if (is == NULL) + einfo (_("%P%F: can't find %s in output section\n"), + bfd_get_section_name (sec->owner, sec)); + + /* Now figure out where the section should go. */ + switch (i) + { + default: /* to avoid warnings */ + case 0: + /* _text */ + oname = ".text"; + start = true; + break; + case 1: + /* _etext */ + oname = ".text"; + start = false; + break; + case 2: + /* _data */ + oname = ".data"; + start = true; + break; + case 3: + /* _edata */ + oname = ".data"; + start = false; + break; + case 4: + case 5: + /* _end and end */ + oname = ".bss"; + start = false; + break; + } + + os = lang_output_section_find (oname); + + if (start) + { + is->header.next = os->children.head; + os->children.head = (lang_statement_union_type *) is; + } + else + { + is->header.next = NULL; + lang_statement_append (&os->children, + (lang_statement_union_type *) is, + &is->header.next); + } + } +} + +/* Read an import or export file. For an import file, this is called + by the before_allocation emulation routine. For an export file, + this is called by the parse_args emulation routine. */ + +static void +gldppcmacos_read_file (filename, import) + const char *filename; + boolean import; +{ + struct obstack *o; + FILE *f; + int lineno; + int c; + boolean keep; + const char *imppath; + const char *impfile; + const char *impmember; + + o = (struct obstack *) xmalloc (sizeof (struct obstack)); + obstack_specify_allocation (o, 0, 0, xmalloc, gldppcmacos_free); + + f = fopen (filename, FOPEN_RT); + if (f == NULL) + { + bfd_set_error (bfd_error_system_call); + einfo ("%F%s: %E\n", filename); + } + + keep = false; + + imppath = NULL; + impfile = NULL; + impmember = NULL; + + lineno = 0; + while ((c = getc (f)) != EOF) + { + char *s; + char *symname; + boolean syscall; + bfd_vma address; + struct bfd_link_hash_entry *h; + + if (c != '\n') + { + obstack_1grow (o, c); + continue; + } + + obstack_1grow (o, '\0'); + ++lineno; + + s = (char *) obstack_base (o); + while (isspace ((unsigned char) *s)) + ++s; + if (*s == '\0' + || *s == '*' + || (*s == '#' && s[1] == ' ') + || (! import && *s == '#' && s[1] == '!')) + { + obstack_free (o, obstack_base (o)); + continue; + } + + if (*s == '#' && s[1] == '!') + { + s += 2; + while (isspace ((unsigned char) *s)) + ++s; + if (*s == '\0') + { + imppath = NULL; + impfile = NULL; + impmember = NULL; + obstack_free (o, obstack_base (o)); + } + else if (*s == '(') + einfo (_("%F%s%d: #! ([member]) is not supported in import files\n"), + filename, lineno); + else + { + char cs; + char *file; + + (void) obstack_finish (o); + keep = true; + imppath = s; + file = NULL; + while (! isspace ((unsigned char) *s) && *s != '(' && *s != '\0') + { + if (*s == '/') + file = s + 1; + ++s; + } + if (file != NULL) + { + file[-1] = '\0'; + impfile = file; + if (imppath == file - 1) + imppath = "/"; + } + else + { + impfile = imppath; + imppath = ""; + } + cs = *s; + *s = '\0'; + while (isspace ((unsigned char) cs)) + { + ++s; + cs = *s; + } + if (cs != '(') + { + impmember = ""; + if (cs != '\0') + einfo (_("%s:%d: warning: syntax error in import file\n"), + filename, lineno); + } + else + { + ++s; + impmember = s; + while (*s != ')' && *s != '\0') + ++s; + if (*s == ')') + *s = '\0'; + else + einfo (_("%s:%d: warning: syntax error in import file\n"), + filename, lineno); + } + } + + continue; + } + + /* This is a symbol to be imported or exported. */ + symname = s; + syscall = false; + address = (bfd_vma) -1; + + while (! isspace ((unsigned char) *s) && *s != '\0') + ++s; + if (*s != '\0') + { + char *se; + + *s++ = '\0'; + + while (isspace ((unsigned char) *s)) + ++s; + + se = s; + while (! isspace ((unsigned char) *se) && *se != '\0') + ++se; + if (*se != '\0') + { + *se++ = '\0'; + while (isspace ((unsigned char) *se)) + ++se; + if (*se != '\0') + einfo (_("%s%d: warning: syntax error in import/export file\n"), + filename, lineno); + } + + if (strcasecmp (s, "svc") == 0 + || strcasecmp (s, "syscall") == 0) + syscall = true; + else + { + char *end; + + address = strtoul (s, &end, 0); + if (*end != '\0') + einfo (_("%s:%d: warning: syntax error in import/export file\n"), + filename, lineno); + } + } + + if (! import) + { + struct export_symbol_list *n; + + ldlang_add_undef (symname); + n = ((struct export_symbol_list *) + xmalloc (sizeof (struct export_symbol_list))); + n->next = export_symbols; + n->name = buystring (symname); + n->syscall = syscall; + export_symbols = n; + } + else + { + h = bfd_link_hash_lookup (link_info.hash, symname, false, false, + true); + if (h == NULL || h->type == bfd_link_hash_new) + { + /* We can just ignore attempts to import an unreferenced + symbol. */ + } + else + { + if (! bfd_xcoff_import_symbol (output_bfd, &link_info, h, + address, imppath, impfile, + impmember)) + einfo (_("%X%s:%d: failed to import symbol %s: %E\n"), + filename, lineno, symname); + } + } + + obstack_free (o, obstack_base (o)); + } + + if (obstack_object_size (o) > 0) + { + einfo (_("%s:%d: warning: ignoring unterminated last line\n"), + filename, lineno); + obstack_free (o, obstack_base (o)); + } + + if (! keep) + { + obstack_free (o, NULL); + free (o); + } +} + +/* This routine saves us from worrying about declaring free. */ + +static void +gldppcmacos_free (p) + PTR p; +{ + free (p); +} + +/* This is called by the before_allocation routine via + lang_for_each_statement. It looks for relocations and assignments + to symbols. */ + +static void +gldppcmacos_find_relocs (s) + lang_statement_union_type *s; +{ + if (s->header.type == lang_reloc_statement_enum) + { + lang_reloc_statement_type *rs; + + rs = &s->reloc_statement; + if (rs->name == NULL) + einfo (_("%F%P: only relocations against symbols are permitted\n")); + if (! bfd_xcoff_link_count_reloc (output_bfd, &link_info, rs->name)) + einfo (_("%F%P: bfd_xcoff_link_count_reloc failed: %E\n")); + } + + if (s->header.type == lang_assignment_statement_enum) + gldppcmacos_find_exp_assignment (s->assignment_statement.exp); +} + +/* Look through an expression for an assignment statement. */ + +static void +gldppcmacos_find_exp_assignment (exp) + etree_type *exp; +{ + struct bfd_link_hash_entry *h; + + switch (exp->type.node_class) + { + case etree_provide: + h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, + false, false, false); + if (h == NULL) + break; + /* Fall through. */ + case etree_assign: + if (strcmp (exp->assign.dst, ".") != 0) + { + if (! bfd_xcoff_record_link_assignment (output_bfd, &link_info, + exp->assign.dst)) + einfo (_("%P%F: failed to record assignment to %s: %E\n"), + exp->assign.dst); + } + gldppcmacos_find_exp_assignment (exp->assign.src); + break; + + case etree_binary: + gldppcmacos_find_exp_assignment (exp->binary.lhs); + gldppcmacos_find_exp_assignment (exp->binary.rhs); + break; + + case etree_trinary: + gldppcmacos_find_exp_assignment (exp->trinary.cond); + gldppcmacos_find_exp_assignment (exp->trinary.lhs); + gldppcmacos_find_exp_assignment (exp->trinary.rhs); + break; + + case etree_unary: + gldppcmacos_find_exp_assignment (exp->unary.child); + break; + + default: + break; + } +} + +static char * +gldppcmacos_get_script(isfile) + int *isfile; +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +"OUTPUT_FORMAT(\"xcoff-powermac\")\n\ +OUTPUT_ARCH(powerpc)\n\ +ENTRY(__start)\n\ +SECTIONS\n\ +{\n\ + .pad 0 : { *(.pad) }\n\ + .text 0 : {\n\ + *(.text)\n\ + *(.pr)\n\ + *(.ro)\n\ + *(.db)\n\ + *(.gl)\n\ + *(.xo)\n\ + *(.ti)\n\ + *(.tb)\n\ + }\n\ + .data 0 : {\n\ + *(.data)\n\ + *(.rw)\n\ + *(.sv)\n\ + *(.ua)\n\ + . = ALIGN(4);\n\ + CONSTRUCTORS\n\ + *(.ds)\n\ + *(.tc0)\n\ + *(.tc)\n\ + *(.td)\n\ + }\n\ + .bss : {\n\ + *(.bss)\n\ + *(.bs)\n\ + *(.uc)\n\ + *(COMMON)\n\ + }\n\ + .loader 0 : {\n\ + *(.loader)\n\ + }\n\ + .debug 0 : {\n\ + *(.debug)\n\ + }\n\ +}\n\n" + ; else if (link_info.relocateable == true) return +"OUTPUT_FORMAT(\"xcoff-powermac\")\n\ +OUTPUT_ARCH(powerpc)\n\ +ENTRY(__start)\n\ +SECTIONS\n\ +{\n\ + .pad 0 : { *(.pad) }\n\ + .text 0 : {\n\ + *(.text)\n\ + *(.pr)\n\ + *(.ro)\n\ + *(.db)\n\ + *(.gl)\n\ + *(.xo)\n\ + *(.ti)\n\ + *(.tb)\n\ + }\n\ + .data 0 : {\n\ + *(.data)\n\ + *(.rw)\n\ + *(.sv)\n\ + *(.ua)\n\ + . = ALIGN(4);\n\ + *(.ds)\n\ + *(.tc0)\n\ + *(.tc)\n\ + *(.td)\n\ + }\n\ + .bss : {\n\ + *(.bss)\n\ + *(.bs)\n\ + *(.uc)\n\ + *(COMMON)\n\ + }\n\ + .loader 0 : {\n\ + *(.loader)\n\ + }\n\ + .debug 0 : {\n\ + *(.debug)\n\ + }\n\ +}\n\n" + ; else if (!config.text_read_only) return +"OUTPUT_FORMAT(\"xcoff-powermac\")\n\ +OUTPUT_ARCH(powerpc)\n\ + SEARCH_DIR(/usr/local/powerpc-apple-macos/lib);\n\ +ENTRY(__start)\n\ +SECTIONS\n\ +{\n\ + .pad 0 : { *(.pad) }\n\ + .text : {\n\ + PROVIDE (_text = .);\n\ + *(.text)\n\ + *(.pr)\n\ + *(.ro)\n\ + *(.db)\n\ + *(.gl)\n\ + *(.xo)\n\ + *(.ti)\n\ + *(.tb)\n\ + PROVIDE (_etext = .);\n\ + }\n\ + .data 0 : {\n\ + PROVIDE (_data = .);\n\ + *(.data)\n\ + *(.rw)\n\ + *(.sv)\n\ + *(.ua)\n\ + . = ALIGN(4);\n\ + CONSTRUCTORS\n\ + *(.ds)\n\ + *(.tc0)\n\ + *(.tc)\n\ + *(.td)\n\ + PROVIDE (_edata = .);\n\ + }\n\ + .bss : {\n\ + *(.bss)\n\ + *(.bs)\n\ + *(.uc)\n\ + *(COMMON)\n\ + PROVIDE (_end = .);\n\ + PROVIDE (end = .);\n\ + }\n\ + .loader 0 : {\n\ + *(.loader)\n\ + }\n\ + .debug 0 : {\n\ + *(.debug)\n\ + }\n\ +}\n\n" + ; else if (!config.magic_demand_paged) return +"OUTPUT_FORMAT(\"xcoff-powermac\")\n\ +OUTPUT_ARCH(powerpc)\n\ + SEARCH_DIR(/usr/local/powerpc-apple-macos/lib);\n\ +ENTRY(__start)\n\ +SECTIONS\n\ +{\n\ + .pad 0 : { *(.pad) }\n\ + .text : {\n\ + PROVIDE (_text = .);\n\ + *(.text)\n\ + *(.pr)\n\ + *(.ro)\n\ + *(.db)\n\ + *(.gl)\n\ + *(.xo)\n\ + *(.ti)\n\ + *(.tb)\n\ + PROVIDE (_etext = .);\n\ + }\n\ + .data 0 : {\n\ + PROVIDE (_data = .);\n\ + *(.data)\n\ + *(.rw)\n\ + *(.sv)\n\ + *(.ua)\n\ + . = ALIGN(4);\n\ + CONSTRUCTORS\n\ + *(.ds)\n\ + *(.tc0)\n\ + *(.tc)\n\ + *(.td)\n\ + PROVIDE (_edata = .);\n\ + }\n\ + .bss : {\n\ + *(.bss)\n\ + *(.bs)\n\ + *(.uc)\n\ + *(COMMON)\n\ + PROVIDE (_end = .);\n\ + PROVIDE (end = .);\n\ + }\n\ + .loader 0 : {\n\ + *(.loader)\n\ + }\n\ + .debug 0 : {\n\ + *(.debug)\n\ + }\n\ +}\n\n" + ; else return +"OUTPUT_FORMAT(\"xcoff-powermac\")\n\ +OUTPUT_ARCH(powerpc)\n\ + SEARCH_DIR(/usr/local/powerpc-apple-macos/lib);\n\ +ENTRY(__start)\n\ +SECTIONS\n\ +{\n\ + .pad 0 : { *(.pad) }\n\ + .text : {\n\ + PROVIDE (_text = .);\n\ + *(.text)\n\ + *(.pr)\n\ + *(.ro)\n\ + *(.db)\n\ + *(.gl)\n\ + *(.xo)\n\ + *(.ti)\n\ + *(.tb)\n\ + PROVIDE (_etext = .);\n\ + }\n\ + .data 0 : {\n\ + PROVIDE (_data = .);\n\ + *(.data)\n\ + *(.rw)\n\ + *(.sv)\n\ + *(.ua)\n\ + . = ALIGN(4);\n\ + CONSTRUCTORS\n\ + *(.ds)\n\ + *(.tc0)\n\ + *(.tc)\n\ + *(.td)\n\ + PROVIDE (_edata = .);\n\ + }\n\ + .bss : {\n\ + *(.bss)\n\ + *(.bs)\n\ + *(.uc)\n\ + *(COMMON)\n\ + PROVIDE (_end = .);\n\ + PROVIDE (end = .);\n\ + }\n\ + .loader 0 : {\n\ + *(.loader)\n\ + }\n\ + .debug 0 : {\n\ + *(.debug)\n\ + }\n\ +}\n\n" +; } + +struct ld_emulation_xfer_struct ld_ppcmacos_emulation = +{ + gldppcmacos_before_parse, + syslib_default, + hll_default, + after_parse_default, + gldppcmacos_after_open, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + gldppcmacos_before_allocation, + gldppcmacos_get_script, + "ppcmacos", + "xcoff-powermac", + 0, /* finish */ + 0, /* create_output_section_statements */ + 0, /* open_dynamic_archive */ + 0, /* place_orphan */ + 0, /* set_symbols */ + gldppcmacos_parse_args, + gldppcmacos_unrecognized_file +}; diff --git a/ld/mpw-esh.c b/ld/mpw-esh.c new file mode 100644 index 0000000..93bc5f5 --- /dev/null +++ b/ld/mpw-esh.c @@ -0,0 +1,315 @@ +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* emulate the original gld for the given sh + Copyright (C) 1991, 1993 Free Software Foundation, Inc. + Written by Steve Chamberlain steve@cygnus.com + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_sh + +#include "libiberty.h" +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" + +static void gldsh_before_parse PARAMS ((void)); +static char *gldsh_get_script PARAMS ((int *isfile)); + +static void +gldsh_before_parse() +{ +#ifndef TARGET_ /* I.e., if not generic. */ + ldfile_output_architecture = bfd_arch_sh; +#endif /* not TARGET_ */ +} + +static char * +gldsh_get_script(isfile) + int *isfile; +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +concat( +"OUTPUT_FORMAT(\"coff-sh\")\n\ +OUTPUT_ARCH(sh)\n\ +MEMORY\n\ +{\n\ + ram : o = 0x1000, l = 512k\n\ +}\n\ + "," SECTIONS\n\ +{\n\ + "," .text :\n\ + {\n\ + *(.text)\n\ + *(.strings)\n\ + } \n\ + .tors :\n\ + {\n\ + ___ctors = . ;\n\ + *(.ctors)\n\ + ___ctors_end = . ;\n\ + ___dtors = . ;\n\ + *(.dtors)\n\ + ___dtors_end = . ;\n\ + } \n\ + "," .data :\n\ + {\n\ + *(.data)\n\ + } \n\ + "," .bss :\n\ + {\n\ + *(.bss)\n\ + *(COMMON)\n\ + } \n\ + "," .stack :\n\ + {\n\ + *(.stack)\n\ + } \n\ + "," .stab 0 :\n\ + {\n\ + *(.stab)\n\ + }\n\ + "," .stabstr 0 :\n\ + {\n\ + *(.stabstr)\n\ + }\n\ +}\n\n", NULL) + ; else if (link_info.relocateable == true) return +concat ( +"OUTPUT_FORMAT(\"coff-sh\")\n\ +OUTPUT_ARCH(sh)\n\ + "," MEMORY\n\ +{\n\ + ram : o = 0x1000, l = 512k\n\ +}\n\ + "," SECTIONS\n\ +{\n\ + "," .text :\n\ + {\n\ + *(.text)\n\ + *(.strings)\n\ + } \n\ + "," .tors :\n\ + {\n\ + ___ctors = . ;\n\ + *(.ctors)\n\ + ___ctors_end = . ;\n\ + ___dtors = . ;\n\ + *(.dtors)\n\ + ___dtors_end = . ;\n\ + } \n\ + "," .data :\n\ + {\n\ + *(.data)\n\ + } \n\ + "," .bss :\n\ + {\n\ + *(.bss)\n\ + *(COMMON)\n\ + } \n\ + "," .stack :\n\ + {\n\ + *(.stack)\n\ + } \n\ + "," .stab 0 :\n\ + {\n\ + *(.stab)\n\ + }\n\ + "," .stabstr 0 :\n\ + {\n\ + *(.stabstr)\n\ + }\n\ +}\n\n", NULL) + ; else if (!config.text_read_only) return +concat ( +"OUTPUT_FORMAT(\"coff-sh\")\n\ +OUTPUT_ARCH(sh)\n\ +MEMORY\n\ +{\n\ + ram : o = 0x1000, l = 512k\n\ +}\n\ +SECTIONS\n\ +{\n\ + "," .text :\n\ + {\n\ + *(.text)\n\ + *(.strings)\n\ + _etext = . ; \n\ + } > ram\n\ + "," .tors :\n\ + {\n\ + ___ctors = . ;\n\ + *(.ctors)\n\ + ___ctors_end = . ;\n\ + ___dtors = . ;\n\ + *(.dtors)\n\ + ___dtors_end = . ;\n\ + } > ram\n\ + "," .data :\n\ + {\n\ + *(.data)\n\ + _edata = . ; \n\ + } > ram\n\ + "," .bss :\n\ + {\n\ + _bss_start = . ; \n\ + *(.bss)\n\ + *(COMMON)\n\ + _end = . ; \n\ + } > ram\n\ + "," .stack 0x30000 :\n\ + {\n\ + _stack = . ; \n\ + *(.stack)\n\ + } > ram\n\ + "," .stab 0 (NOLOAD) :\n\ + {\n\ + *(.stab)\n\ + }\n\ + "," .stabstr 0 (NOLOAD) :\n\ + {\n\ + *(.stabstr)\n\ + }\n\ +}\n\n", NULL) + ; else if (!config.magic_demand_paged) return +concat ( +"OUTPUT_FORMAT(\"coff-sh\")\n\ +OUTPUT_ARCH(sh)\n\ +MEMORY\n\ +{\n\ + ram : o = 0x1000, l = 512k\n\ +}\n\ +SECTIONS\n\ +{\n\ + "," .text :\n\ + {\n\ + *(.text)\n\ + *(.strings)\n\ + _etext = . ; \n\ + } > ram\n\ + "," .tors :\n\ + {\n\ + ___ctors = . ;\n\ + *(.ctors)\n\ + ___ctors_end = . ;\n\ + ___dtors = . ;\n\ + *(.dtors)\n\ + ___dtors_end = . ;\n\ + } > ram\n\ + "," .data :\n\ + {\n\ + *(.data)\n\ + _edata = . ; \n\ + } > ram\n\ + "," .bss :\n\ + {\n\ + _bss_start = . ; \n\ + *(.bss)\n\ + *(COMMON)\n\ + _end = . ; \n\ + } > ram\n\ + "," .stack 0x30000 :\n\ + {\n\ + _stack = . ; \n\ + *(.stack)\n\ + } > ram\n\ + "," .stab 0 (NOLOAD) :\n\ + {\n\ + *(.stab)\n\ + }\n\ + "," .stabstr 0 (NOLOAD) :\n\ + {\n\ + *(.stabstr)\n\ + }\n\ +}\n\n", NULL) + ; else return +concat ( +"OUTPUT_FORMAT(\"coff-sh\")\n\ +OUTPUT_ARCH(sh)\n\ +MEMORY\n\ +{\n\ + ram : o = 0x1000, l = 512k\n\ +}\n\ +SECTIONS\n\ +{\n\ + "," .text :\n\ + {\n\ + *(.text)\n\ + *(.strings)\n\ + _etext = . ; \n\ + } > ram\n\ + "," .tors :\n\ + {\n\ + ___ctors = . ;\n\ + *(.ctors)\n\ + ___ctors_end = . ;\n\ + ___dtors = . ;\n\ + *(.dtors)\n\ + ___dtors_end = . ;\n\ + } > ram\n\ + "," .data :\n\ + {\n\ + *(.data)\n\ + _edata = . ; \n\ + } > ram\n\ + "," .bss :\n\ + {\n\ + _bss_start = . ; \n\ + *(.bss)\n\ + *(COMMON)\n\ + _end = . ; \n\ + } > ram\n\ + "," .stack 0x30000 :\n\ + {\n\ + _stack = . ; \n\ + *(.stack)\n\ + } > ram\n\ + "," .stab 0 (NOLOAD) :\n\ + {\n\ + *(.stab)\n\ + }\n\ + "," .stabstr 0 (NOLOAD) :\n\ + {\n\ + *(.stabstr)\n\ + }\n\ +}\n\n", NULL) +; } + +struct ld_emulation_xfer_struct ld_sh_emulation = +{ + gldsh_before_parse, + syslib_default, + hll_default, + after_parse_default, + after_open_default, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + before_allocation_default, + gldsh_get_script, + "sh", + "coff-sh" +}; diff --git a/ld/mpw-idtmips.c b/ld/mpw-idtmips.c new file mode 100644 index 0000000..08ddc70 --- /dev/null +++ b/ld/mpw-idtmips.c @@ -0,0 +1,430 @@ +/* This file is is generated by a shell script. DO NOT EDIT! */ + +/* Handle embedded relocs for MIPS. + Copyright 1994 Free Software Foundation, Inc. + Written by Ian Lance Taylor <ian@cygnus.com> based on generic.em. + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define TARGET_IS_mipsidt + +#include "libiberty.h" +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" + +#include "ld.h" +#include "ldmain.h" +#include "ldemul.h" +#include "ldfile.h" +#include "ldmisc.h" + +static void gldmipsidt_before_parse PARAMS ((void)); +static void gldmipsidt_after_open PARAMS ((void)); +static void check_sections PARAMS ((bfd *, asection *, PTR)); +static void gldmipsidt_after_allocation PARAMS ((void)); +static char *gldmipsidt_get_script PARAMS ((int *isfile)); + +static void +gldmipsidt_before_parse() +{ +#ifndef TARGET_ /* I.e., if not generic. */ + ldfile_output_architecture = bfd_arch_mips; +#endif /* not TARGET_ */ +} + +/* This function is run after all the input files have been opened. + We create a .rel.sdata section for each input file with a non zero + .sdata section. The BFD backend will fill in these sections with + magic numbers which can be used to relocate the data section at run + time. This will only do the right thing if all the input files + have been compiled using -membedded-pic. */ + +static void +gldmipsidt_after_open () +{ + bfd *abfd; + + if (! command_line.embedded_relocs + || link_info.relocateable) + return; + + for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next) + { + asection *datasec; + + datasec = bfd_get_section_by_name (abfd, ".sdata"); + + /* Note that we assume that the reloc_count field has already + been set up. We could call bfd_get_reloc_upper_bound, but + that returns the size of a memory buffer rather than a reloc + count. We do not want to call bfd_canonicalize_reloc, + because although it would always work it would force us to + read in the relocs into BFD canonical form, which would waste + a significant amount of time and memory. */ + if (datasec != NULL && datasec->reloc_count > 0) + { + asection *relsec; + + relsec = bfd_make_section (abfd, ".rel.sdata"); + if (relsec == NULL + || ! bfd_set_section_flags (abfd, relsec, + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY)) + || ! bfd_set_section_alignment (abfd, relsec, 2) + || ! bfd_set_section_size (abfd, relsec, + datasec->reloc_count * 4)) + einfo (_("%F%B: can not create .rel.sdata section: %E\n")); + } + + /* Double check that all other data sections are empty, as is + required for embedded PIC code. */ + bfd_map_over_sections (abfd, check_sections, (PTR) datasec); + } +} + +/* Check that of the data sections, only the .sdata section has + relocs. This is called via bfd_map_over_sections. */ + +static void +check_sections (abfd, sec, sdatasec) + bfd *abfd; + asection *sec; + PTR sdatasec; +{ + if ((bfd_get_section_flags (abfd, sec) & SEC_CODE) == 0 + && sec != (asection *) sdatasec + && sec->reloc_count != 0) + einfo (_("%F%X: section %s has relocs; can not use --embedded-relocs\n"), + abfd, bfd_get_section_name (abfd, sec)); +} + +/* This function is called after the section sizes and offsets have + been set. If we are generating embedded relocs, it calls a special + BFD backend routine to do the work. */ + +static void +gldmipsidt_after_allocation () +{ + bfd *abfd; + + if (! command_line.embedded_relocs + || link_info.relocateable) + return; + + for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next) + { + asection *datasec, *relsec; + char *errmsg; + + datasec = bfd_get_section_by_name (abfd, ".sdata"); + + if (datasec == NULL || datasec->reloc_count == 0) + continue; + + relsec = bfd_get_section_by_name (abfd, ".rel.sdata"); + ASSERT (relsec != NULL); + + if (! bfd_mips_ecoff_create_embedded_relocs (abfd, &link_info, + datasec, relsec, + &errmsg)) + { + if (errmsg == NULL) + einfo (_("%B%X: can not create runtime reloc information: %E\n"), + abfd); + else + einfo (_("%X%B: can not create runtime reloc information: %s\n"), + abfd, errmsg); + } + } +} + +static char * +gldmipsidt_get_script(isfile) + int *isfile; +{ + *isfile = 0; + + if (link_info.relocateable == true && config.build_constructors == true) + return +concat( +"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\ + \"ecoff-littlemips\")\n\ + SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\ +ENTRY(start)\n\ +SECTIONS\n\ +{\n\ + .text : {\n\ + ;\n\ + *(.init)\n\ + ;\n\ + *(.text)\n\ + *(.rel.sdata)\n\ + *(.fini)\n\ + ;\n\ + ;\n\ + }\n\ + "," .rdata : {\n\ + *(.rdata)\n\ + }\n\ + .data : {\n\ + *(.data)\n\ + CONSTRUCTORS\n\ + }\n\ + .lit8 : {\n\ + *(.lit8)\n\ + }\n\ + .lit4 : {\n\ + *(.lit4)\n\ + }\n\ + "," .sdata : {\n\ + *(.sdata)\n\ + }\n\ + .sbss : {\n\ + *(.sbss)\n\ + *(.scommon)\n\ + }\n\ + .bss : {\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ +}\n\n", NULL) + ; else if (link_info.relocateable == true) return +"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\ + \"ecoff-littlemips\")\n\ + SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\ +ENTRY(start)\n\ +SECTIONS\n\ +{\n\ + .text : {\n\ + ;\n\ + *(.init)\n\ + ;\n\ + *(.text)\n\ + *(.rel.sdata)\n\ + *(.fini)\n\ + ;\n\ + ;\n\ + }\n\ + .rdata : {\n\ + *(.rdata)\n\ + }\n\ + .data : {\n\ + *(.data)\n\ + }\n\ + .lit8 : {\n\ + *(.lit8)\n\ + }\n\ + .lit4 : {\n\ + *(.lit4)\n\ + }\n\ + .sdata : {\n\ + *(.sdata)\n\ + }\n\ + .sbss : {\n\ + *(.sbss)\n\ + *(.scommon)\n\ + }\n\ + .bss : {\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ +}\n\n" + ; else if (!config.text_read_only) return +concat( +"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\ + \"ecoff-littlemips\")\n\ + SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\ +ENTRY(start)\n\ +SECTIONS\n\ +{\n\ + . = 0xa0012000;\n\ + .text : {\n\ + _ftext = . ;\n\ + *(.init)\n\ + eprol = .;\n\ + *(.text)\n\ + PROVIDE (__runtime_reloc_start = .);\n\ + *(.rel.sdata)\n\ + PROVIDE (__runtime_reloc_stop = .);\n\ + *(.fini)\n\ + etext = .;\n\ + _etext = .;\n\ +"," }\n\ + . = .;\n\ + .rdata : {\n\ + *(.rdata)\n\ + }\n\ + _fdata = ALIGN(16);\n\ + .data : {\n\ + *(.data)\n\ + CONSTRUCTORS\n\ + }\n\ + _gp = ALIGN(16) + 0x8000;\n\ + .lit8 : {\n\ + *(.lit8)\n\ + }\n\ + .lit4 : {\n\ + *(.lit4)\n\ + }\n\ + .sdata : {\n\ + *(.sdata)\n\ + }\n\ +"," edata = .;\n\ + _edata = .;\n\ + _fbss = .;\n\ + .sbss : {\n\ + *(.sbss)\n\ + *(.scommon)\n\ + }\n\ + .bss : {\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ + end = .;\n\ + _end = .;\n\ +}\n\n" +, NULL) + ; else if (!config.magic_demand_paged) return +concat ( +"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\ + \"ecoff-littlemips\")\n\ + SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\ +ENTRY(start)\n\ +SECTIONS\n\ +{\n\ + . = 0xa0012000;\n\ + .text : {\n\ + _ftext = . ;\n\ + *(.init)\n\ + eprol = .;\n\ + *(.text)\n\ + PROVIDE (__runtime_reloc_start = .);\n\ + *(.rel.sdata)\n\ + PROVIDE (__runtime_reloc_stop = .);\n\ + *(.fini)\n\ + etext = .;\n\ + _etext = .;\n\ + "," }\n\ + . = .;\n\ + .rdata : {\n\ + *(.rdata)\n\ + }\n\ + _fdata = ALIGN(16);\n\ + .data : {\n\ + *(.data)\n\ + CONSTRUCTORS\n\ + }\n\ + _gp = ALIGN(16) + 0x8000;\n\ + .lit8 : {\n\ + *(.lit8)\n\ + "," }\n\ + .lit4 : {\n\ + *(.lit4)\n\ + }\n\ + .sdata : {\n\ + *(.sdata)\n\ + }\n\ + edata = .;\n\ + _edata = .;\n\ + _fbss = .;\n\ + .sbss : {\n\ + *(.sbss)\n\ + *(.scommon)\n\ + "," }\n\ + .bss : {\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ + end = .;\n\ + _end = .;\n\ +}\n\n" +, NULL) + ; else return +concat ( +"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\ + \"ecoff-littlemips\")\n\ + SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\ +ENTRY(start)\n\ +SECTIONS\n\ +{\n\ + . = 0xa0012000;\n\ + .text : {\n\ + _ftext = . ;\n\ + *(.init)\n\ + eprol = .;\n\ + *(.text)\n\ + PROVIDE (__runtime_reloc_start = .);\n\ + *(.rel.sdata)\n\ + PROVIDE (__runtime_reloc_stop = .);\n\ + *(.fini)\n\ + etext = .;\n\ + _etext = .;\n\ + "," }\n\ + . = .;\n\ + .rdata : {\n\ + *(.rdata)\n\ + }\n\ + _fdata = ALIGN(16);\n\ + .data : {\n\ + *(.data)\n\ + CONSTRUCTORS\n\ + }\n\ + _gp = ALIGN(16) + 0x8000;\n\ + .lit8 : {\n\ + *(.lit8)\n\ + }\n\ + .lit4 : {\n\ + *(.lit4)\n\ + "," }\n\ + .sdata : {\n\ + *(.sdata)\n\ + }\n\ + edata = .;\n\ + _edata = .;\n\ + _fbss = .;\n\ + .sbss : {\n\ + *(.sbss)\n\ + *(.scommon)\n\ + }\n\ + .bss : {\n\ + *(.bss)\n\ + *(COMMON)\n\ + }\n\ + end = .;\n\ + _end = .;\n\ +}\n\n" +, NULL) +; } + +struct ld_emulation_xfer_struct ld_mipsidt_emulation = +{ + gldmipsidt_before_parse, + syslib_default, + hll_default, + after_parse_default, + gldmipsidt_after_open, + gldmipsidt_after_allocation, + set_output_arch_default, + ldemul_default_target, + before_allocation_default, + gldmipsidt_get_script, + "mipsidt", + "ecoff-bigmips" +}; diff --git a/ld/mpw-make.sed b/ld/mpw-make.sed new file mode 100644 index 0000000..c919708 --- /dev/null +++ b/ld/mpw-make.sed @@ -0,0 +1,95 @@ +# Sed commands to finish translating the ld Makefile.in into MPW syntax. + +/HDEFINES/s/@HDEFINES@// + +/^target_alias = @target_alias@/s/^/#/ + +/^EMUL = @EMUL@/s/^/#/ + +/^EMULATION_OFILES = @EMULATION_OFILES@/s/^/#/ + +# Fixadd to the include paths. +/^INCLUDES = .*$/s/$/ -i "{INCDIR}":mpw: -i ::extra-include:/ +/BFDDIR/s/-i {BFDDIR} /-i "{BFDDIR}": / +/INCDIR/s/-i {INCDIR} /-i "{INCDIR}": / + +# Use byacc instead of bison (for now anyway). +/BISON/s/^BISON =.*$/BISON = byacc/ +#/BISONFLAGS/s/^BISONFLAGS =.*$/BISONFLAGS = / + +# Suppress the suppression of smart makes. +/^\.y\.c/d + +# Hack up ldmain compile. +/^"{o}"ldmain.c.o \\Option-f .* config.status$/,/^$/c\ +"{o}"ldmain.c.o \\Option-f "{s}"ldmain.c\ + {CC} @DASH_C_FLAG@ -d DEFAULT_EMULATION={dq}{EMUL}{dq} -d SCRIPTDIR={dq}{scriptdir}{dq} {ALL_CFLAGS} "{s}"ldmain.c -o "{o}"ldmain.c.o\ + + +# Remove ldemul-list.h build, rely on configure to make one. +/^ldemul-list.h /,/Rename -y "{s}"ldemul-tmp.h /d + +# Fix pathnames to generated files. +/config.h/s/"{s}"config\.h/"{o}"config.h/g +/config.h/s/^config\.h/"{o}"config.h/ + +/y.tab.c/s/"{s}"y\.tab\.c/"{o}"y.tab.c/g +/y.tab.c/s/^y\.tab\.c/"{o}"y.tab.c/ +/y.tab.h/s/"{s}"y\.tab\.h/"{o}"y.tab.h/g +/y.tab.h/s/^y\.tab\.h/"{o}"y.tab.h/ + +/ldgram.c/s/"{s}"ldgram\.c/"{o}"ldgram.c/g +/ldgram.c/s/^ldgram\.c/"{o}"ldgram.c/ + +/ldgram.h/s/"{s}"ldgram\.h/"{o}"ldgram.h/g +/ldgram.h/s/^ldgram\.h/"{o}"ldgram.h/ + +/ldlex.c/s/"{s}"ldlex\.c/"{o}"ldlex.c/g +/ldlex.c/s/^ldlex\.c/"{o}"ldlex.c/ + +/ldlex.c.new/s/"{s}"ldlex\.c\.new/"{o}"ldlex.c.new/g + +/lex.yy.c/s/"{s}"lex\.yy\.c/"{o}"lex.yy.c/g + +/ldemul-list.h/s/"{s}"ldemul-list\.h/"{o}"ldemul-list.h/g +/ldemul-list.h/s/^ldemul-list\.h/"{o}"ldemul-list.h/ + +# Edit pathnames to emulation files. +/"{s}"e.*\.c/s/"{s}"e\([-_a-z0-9]*\)\.c/"{o}"e\1.c/g +/^e.*\.c/s/^e\([-_a-z0-9]*\)\.c/"{o}"e\1.c/ + +# We can't run genscripts, so don't try. +/{GENSCRIPTS}/s/{GENSCRIPTS}/null-command/ + +# Comment out the TDIRS bits. +/^TDIRS@/s/^/#/ + +# Point at the BFD library directly. +/@BFDLIB@/s/@BFDLIB@/::bfd:libbfd.o/ + +# Don't need this. +/@HLDFLAGS@/s/@HLDFLAGS@// + +#/sed.*free/,/> "{o}"ldlex.c.new/c\ +# \ Catenate "{o}"lex.yy.c >"{o}"ldlex.c.new + +# The resource file is called mac-ld.r. +/{LD_PROG}.r/s/{LD_PROG}\.r/mac-ld.r/ + +/^install \\Option-f /,/^$/c\ +install \\Option-f all install-only\ +\ +install-only \\Option-f\ + NewFolderRecursive "{bindir}"\ + Duplicate -y :ld.new "{bindir}"ld\ + + +# Remove dependency rebuilding crud. +/^.dep /,/# .PHONY /d + +# Remove the lintlog action, pipe symbols in column 1 lose. +/^lintlog \\Option-f/,/^$/d + +/^Makefile \\Option-f/,/^$/d +/^"{o}"config.h \\Option-f/,/^$/d +/^config.status \\Option-f/,/^$/d diff --git a/ld/mri.c b/ld/mri.c new file mode 100644 index 0000000..54aaea2 --- /dev/null +++ b/ld/mri.c @@ -0,0 +1,377 @@ +/* mri.c -- handle MRI style linker scripts + Copyright (C) 1991, 92, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +GLD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GLD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GLD; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + + +/* This bit does the tree decoration when MRI style link scripts are parsed */ + +/* + contributed by Steve Chamberlain + sac@cygnus.com + +*/ + +#include "bfd.h" +#include "sysdep.h" +#include "ld.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldmisc.h" +#include "mri.h" +#include "ldgram.h" +#include "libiberty.h" + +struct section_name_struct { + struct section_name_struct *next; + CONST char *name; + CONST char *alias; + etree_type *vma; + etree_type *align; + etree_type *subalign; + int ok_to_load; +} ; + +unsigned int symbol_truncate = 10000; +struct section_name_struct *order; +struct section_name_struct *only_load; +struct section_name_struct *address; +struct section_name_struct *alias; + +struct section_name_struct *alignment; +struct section_name_struct *subalignment; + +static struct section_name_struct **lookup + PARAMS ((const char *name, struct section_name_struct **list)); +static void mri_add_to_list PARAMS ((struct section_name_struct **list, + const char *name, etree_type *vma, + const char *zalias, etree_type *align, + etree_type *subalign)); + +static struct section_name_struct ** +lookup (name, list) + CONST char *name; + struct section_name_struct **list; +{ + + struct section_name_struct **ptr = list; + while (*ptr) + { + if (strcmp(name, (*ptr)->name) == 0) { + /* If this is a match, delete it, we only keep the last instance + of any name */ + *ptr = (*ptr)->next; + } + else { + ptr = &((*ptr)->next); + } + } + + *ptr = (struct section_name_struct *)xmalloc(sizeof(struct section_name_struct)); + return ptr; +} + +static void +mri_add_to_list (list, name, vma, zalias, align, subalign) + struct section_name_struct **list; + CONST char *name; + etree_type *vma; + CONST char *zalias; + etree_type *align; + etree_type *subalign; +{ + struct section_name_struct **ptr = lookup(name,list); + (*ptr)->name = name; + (*ptr)->vma = vma; + (*ptr)->next = (struct section_name_struct *)NULL; + (*ptr)->ok_to_load = 0; + (*ptr)->alias = zalias; + (*ptr)->align = align; + (*ptr)->subalign = subalign; +} + + +void +mri_output_section (name, vma) + CONST char *name; + etree_type *vma; +{ + mri_add_to_list(&address, name, vma, 0,0,0); +} + +/* if any ABSOLUTE <name> are in the script, only load those files +marked thus */ + +void +mri_only_load (name) + CONST char *name; +{ + mri_add_to_list(&only_load, name, 0, 0,0,0); +} + + +void +mri_base (exp) + etree_type *exp; +{ + base = exp; +} + +static int done_tree = 0; + +void +mri_draw_tree () +{ + if (done_tree) return; + + /* We don't bother with memory regions. */ +#if 0 + /* Create the regions */ + { + lang_memory_region_type *r; + r = lang_memory_region_lookup("long"); + r->current = r->origin = exp_get_vma(base, (bfd_vma)0, "origin", + lang_first_phase_enum); + r->length = (bfd_size_type) exp_get_vma(0, (bfd_vma) ~((bfd_size_type)0), + "length", lang_first_phase_enum); + } +#endif + + /* Now build the statements for the ldlang machine */ + + + /* Attatch the addresses of any which have addresses, and add the + ones not mentioned */ + if (address != (struct section_name_struct *)NULL) { + struct section_name_struct *alist; + struct section_name_struct *olist; + if (order == (struct section_name_struct *)NULL) { + order = address; + } + + for (alist = address; + alist != (struct section_name_struct*)NULL; + alist = alist->next) + { + int done = 0; + for (olist = order; + done == 0 && + olist != (struct section_name_struct *)NULL; + olist = olist->next) + { + if (strcmp(alist->name, olist->name) == 0) + { + olist->vma = alist->vma; + done = 1; + } + } + if (!done) { + /* add this onto end of order list */ + mri_add_to_list(&order, alist->name, alist->vma, 0,0,0); + } + + } + + } + + /* If we're only supposed to load a subset of them in, then prune + the list. */ + + if (only_load != (struct section_name_struct *)NULL) + { + struct section_name_struct *ptr1; + struct section_name_struct *ptr2; + if (order == (struct section_name_struct*)NULL) + order = only_load; + + /* See if this name is in the list, if it is then we can load it + */ + for (ptr1 = only_load; ptr1; ptr1 = ptr1->next) + { + for (ptr2= order; ptr2; ptr2=ptr2->next) + { + if (strcmp(ptr2->name, ptr1->name)==0) { + ptr2->ok_to_load = 1; + } + } + } + } + else + { + /* No only load list, so everything is ok to load */ + struct section_name_struct *ptr; + for (ptr = order; ptr; ptr=ptr->next) { + ptr->ok_to_load = 1; + } + } + + + + /* Create the order of sections to load */ + if (order != (struct section_name_struct *)NULL) + { + /* Been told to output the sections in a certain order */ + struct section_name_struct *p = order; + while (p) + { + struct section_name_struct *aptr; + etree_type *align = 0; + etree_type *subalign = 0; + /* See if an alignment has been specified */ + + for (aptr = alignment; aptr; aptr= aptr->next) + { + if (strcmp(aptr->name, p->name)==0) { + align = aptr->align; + } + } + + for (aptr = subalignment; aptr; aptr= aptr->next) + { + if (strcmp(aptr->name, p->name)==0) { + subalign = aptr->subalign; + } + } + + if (base == 0) { + base = p->vma ? p->vma :exp_nameop(NAME, "."); + } + lang_enter_output_section_statement (p->name, base, + p->ok_to_load ? 0 : noload_section, + 1, align, subalign, + (etree_type *) NULL); + base = 0; + lang_add_wild (p->name, false, (char *)NULL, false, false, NULL); + /* If there is an alias for this section, add it too */ + for (aptr = alias; aptr; aptr = aptr->next) { + + if (strcmp(aptr->alias, p->name)== 0) { + lang_add_wild (aptr->name, false, (char *)NULL, false, false, NULL); + } + } + + lang_leave_output_section_statement + (0, "*default*", (struct lang_output_section_phdr_list *) NULL); + + p = p->next; + } + } + + + done_tree = 1; + +} +void +mri_load (name) + CONST char *name; +{ + base = 0; + lang_add_input_file(name, + lang_input_file_is_file_enum, (char *)NULL); + /* lang_leave_output_section_statement(0,"*default*");*/ +} + + +void +mri_order (name) + CONST char *name; +{ + mri_add_to_list(&order, name, 0, 0,0,0); +} + +void +mri_alias (want, is, isn) + CONST char *want; + CONST char *is; + int isn; +{ + if (!is) { + /* Some sections are digits - */ + char buf[20]; + sprintf(buf, "%d", isn); + is = xstrdup (buf); + if (is == NULL) + abort (); + } + mri_add_to_list(&alias, is, 0, want,0,0); + +} + + +void +mri_name (name) + CONST char *name; +{ + lang_add_output(name, 1); + +} + + +void +mri_format (name) + CONST char *name; +{ + if (strcmp(name, "S") == 0) + { + lang_add_output_format("srec", (char *) NULL, (char *) NULL, 1); + } + else if (strcmp(name, "IEEE") == 0) + { + lang_add_output_format("ieee", (char *) NULL, (char *) NULL, 1); + } + else if (strcmp(name, "COFF") == 0) + { + lang_add_output_format("coff-m68k", (char *) NULL, (char *) NULL, 1); + } + else { + einfo(_("%P%F: unknown format type %s\n"), name); + } +} + + +void +mri_public (name, exp) + CONST char *name; + etree_type *exp; +{ + lang_add_assignment(exp_assop('=', name, exp)); +} + +void +mri_align (name, exp) + CONST char *name; + etree_type *exp; +{ + mri_add_to_list(&alignment, name,0,0,exp,0); +} + +void +mri_alignmod (name, exp) + CONST char *name; + etree_type *exp; +{ + mri_add_to_list(&subalignment, name,0,0,0,exp); +} + + +void +mri_truncate (exp) + unsigned int exp; +{ + symbol_truncate = exp; +} diff --git a/ld/mri.h b/ld/mri.h new file mode 100644 index 0000000..dc3f0f3 --- /dev/null +++ b/ld/mri.h @@ -0,0 +1,39 @@ +/* mri.h -- header file for MRI scripting functions + Copyright 1993, 95, 1996 Free Software Foundation, Inc. + +This file is part of GLD, the Gnu Linker. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef MRI_H +#define MRI_H + +extern unsigned int symbol_truncate; + +extern void mri_output_section PARAMS ((const char *name, etree_type *vma)); +extern void mri_only_load PARAMS ((const char *name)); +extern void mri_base PARAMS ((etree_type *exp)); +extern void mri_load PARAMS ((const char *name)); +extern void mri_order PARAMS ((const char *name)); +extern void mri_alias PARAMS ((const char *want, const char *is, int isn)); +extern void mri_name PARAMS ((const char *name)); +extern void mri_format PARAMS ((const char *name)); +extern void mri_public PARAMS ((const char *name, etree_type *exp)); +extern void mri_align PARAMS ((const char *name, etree_type *exp)); +extern void mri_alignmod PARAMS ((const char *name, etree_type *exp)); +extern void mri_truncate PARAMS ((unsigned int exp)); +extern void mri_draw_tree PARAMS ((void)); + +#endif diff --git a/ld/pe-dll.c b/ld/pe-dll.c new file mode 100644 index 0000000..6d7306c --- /dev/null +++ b/ld/pe-dll.c @@ -0,0 +1,1651 @@ +/* Routines to help build PEI-format DLLs (Win32 etc) + Copyright (C) 1998, 1999 Free Software Foundation, Inc. + Written by DJ Delorie <dj@cygnus.com> + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libiberty.h" + +#include <time.h> +#include <ctype.h> + +#include "ld.h" +#include "ldexp.h" +#include "ldlang.h" +#include "ldwrite.h" +#include "ldmisc.h" +#include "ldgram.h" +#include "ldmain.h" +#include "ldemul.h" +#include "coff/internal.h" +#include "../bfd/libcoff.h" +#include "deffile.h" + +/************************************************************************ + + This file turns a regular Windows PE image into a DLL. Because of + the complexity of this operation, it has been broken down into a + number of separate modules which are all called by the main function + at the end of this file. This function is not re-entrant and is + normally only called once, so static variables are used to reduce + the number of parameters and return values required. + + See also: ld/emultempl/pe.em + + ************************************************************************/ + +/* for emultempl/pe.em */ + +def_file *pe_def_file = 0; +int pe_dll_export_everything = 0; +int pe_dll_do_default_excludes = 1; +int pe_dll_kill_ats = 0; +int pe_dll_stdcall_aliases = 0; + +/************************************************************************ + + static variables and types + + ************************************************************************/ + +static bfd_vma image_base; + +static bfd *filler_bfd; +static struct sec *edata_s, *reloc_s; +static unsigned char *edata_d, *reloc_d; +static int edata_sz, reloc_sz; + +/************************************************************************ + + Helper functions for qsort. Relocs must be sorted so that we can write + them out by pages. + + ************************************************************************/ + +static int +reloc_sort (va, vb) + const void *va, *vb; +{ + bfd_vma a = *(bfd_vma *) va; + bfd_vma b = *(bfd_vma *) vb; + return (a > b) - (a < b); +} + +static int +pe_export_sort (va, vb) + const void *va, *vb; +{ + def_file_export *a = (def_file_export *) va; + def_file_export *b = (def_file_export *) vb; + return strcmp (a->name, b->name); +} + +/************************************************************************ + + Read and process the .DEF file + + ************************************************************************/ + +/* These correspond to the entries in pe_def_file->exports[]. I use + exported_symbol_sections[i] to tag whether or not the symbol was + defined, since we can't export symbols we don't have. */ + +static bfd_vma *exported_symbol_offsets; +static struct sec **exported_symbol_sections; + +static int export_table_size; +static int count_exported; +static int count_exported_byname; +static int count_with_ordinals; +static const char *dll_name; +static int min_ordinal, max_ordinal; +static int *exported_symbols; + +typedef struct exclude_list_struct + { + char *string; + struct exclude_list_struct *next; + } +exclude_list_struct; +static struct exclude_list_struct *excludes = 0; + +void +pe_dll_add_excludes (new_excludes) + const char *new_excludes; +{ + char *local_copy; + char *exclude_string; + + local_copy = xstrdup (new_excludes); + + exclude_string = strtok (local_copy, ",:"); + for (; exclude_string; exclude_string = strtok (NULL, ",:")) + { + struct exclude_list_struct *new_exclude; + + new_exclude = ((struct exclude_list_struct *) + xmalloc (sizeof (struct exclude_list_struct))); + new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 1); + strcpy (new_exclude->string, exclude_string); + new_exclude->next = excludes; + excludes = new_exclude; + } + + free (local_copy); +} + +static int +auto_export (d, n) + def_file *d; + const char *n; +{ + int i; + struct exclude_list_struct *ex; + for (i = 0; i < d->num_exports; i++) + if (strcmp (d->exports[i].name, n) == 0) + return 0; + if (pe_dll_do_default_excludes) + { + if (strcmp (n, "DllMain@12") == 0) + return 0; + if (strcmp (n, "DllEntryPoint@0") == 0) + return 0; + if (strcmp (n, "impure_ptr") == 0) + return 0; + } + for (ex = excludes; ex; ex = ex->next) + if (strcmp (n, ex->string) == 0) + return 0; + return 1; +} + +static void +process_def_file (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + int i, j; + struct bfd_link_hash_entry *blhe; + bfd *b; + struct sec *s; + def_file_export *e=0; + + if (!pe_def_file) + pe_def_file = def_file_empty (); + + /* First, run around to all the objects looking for the .drectve + sections, and push those into the def file too */ + + for (b = info->input_bfds; b; b = b->link_next) + { + s = bfd_get_section_by_name (b, ".drectve"); + if (s) + { + int size = bfd_get_section_size_before_reloc (s); + char *buf = xmalloc (size); + bfd_get_section_contents (b, s, buf, 0, size); + def_file_add_directive (pe_def_file, buf, size); + free (buf); + } + } + + /* Now, maybe export everything else the default way */ + + if (pe_dll_export_everything || pe_def_file->num_exports == 0) + { + for (b = info->input_bfds; b; b = b->link_next) + { + asymbol **symbols; + int nsyms, symsize; + + symsize = bfd_get_symtab_upper_bound (b); + symbols = (asymbol **) xmalloc (symsize); + nsyms = bfd_canonicalize_symtab (b, symbols); + + for (j = 0; j < nsyms; j++) + { + if ((symbols[j]->flags & (BSF_FUNCTION | BSF_GLOBAL)) + == (BSF_FUNCTION | BSF_GLOBAL)) + { + const char *sn = symbols[j]->name; + if (*sn == '_') + sn++; + if (auto_export (pe_def_file, sn)) + def_file_add_export (pe_def_file, sn, 0, -1); + } + } + } + } + +#undef NE +#define NE pe_def_file->num_exports + + /* Canonicalize the export list */ + + if (pe_dll_kill_ats) + { + for (i = 0; i < NE; i++) + { + if (strchr (pe_def_file->exports[i].name, '@')) + { + /* This will preserve internal_name, which may have been pointing + to the same memory as name, or might not have */ + char *tmp = xstrdup (pe_def_file->exports[i].name); + *(strchr (tmp, '@')) = 0; + pe_def_file->exports[i].name = tmp; + } + } + } + + if (pe_dll_stdcall_aliases) + { + for (i = 0; i < NE; i++) + { + if (strchr (pe_def_file->exports[i].name, '@')) + { + char *tmp = xstrdup (pe_def_file->exports[i].name); + *(strchr (tmp, '@')) = 0; + if (auto_export (pe_def_file, tmp)) + def_file_add_export (pe_def_file, tmp, + pe_def_file->exports[i].internal_name, -1); + else + free (tmp); + } + } + } + + e = pe_def_file->exports; /* convenience, but watch out for it changing */ + + exported_symbol_offsets = (bfd_vma *) xmalloc (NE * sizeof (bfd_vma)); + exported_symbol_sections = (struct sec **) xmalloc (NE * sizeof (struct sec *)); + + memset (exported_symbol_sections, 0, NE * sizeof (struct sec *)); + max_ordinal = 0; + min_ordinal = 65536; + count_exported = 0; + count_exported_byname = 0; + count_with_ordinals = 0; + + qsort (pe_def_file->exports, NE, sizeof (pe_def_file->exports[0]), pe_export_sort); + for (i = 0, j = 0; i < NE; i++) + { + if (i > 0 && strcmp (e[i].name, e[i - 1].name) == 0) + { + /* This is a duplicate */ + if (e[j - 1].ordinal != -1 + && e[i].ordinal != -1 + && e[j - 1].ordinal != e[i].ordinal) + { + /* xgettext:c-format */ + einfo (_("%XError, duplicate EXPORT with oridinals: %s (%d vs %d)\n"), + e[j - 1].name, e[j - 1].ordinal, e[i].ordinal); + } + else + { + /* xgettext:c-format */ + einfo (_("Warning, duplicate EXPORT: %s\n"), + e[j - 1].name); + } + if (e[i].ordinal) + e[j - 1].ordinal = e[i].ordinal; + e[j - 1].flag_private |= e[i].flag_private; + e[j - 1].flag_constant |= e[i].flag_constant; + e[j - 1].flag_noname |= e[i].flag_noname; + e[j - 1].flag_data |= e[i].flag_data; + } + else + { + if (i != j) + e[j] = e[i]; + j++; + } + } + pe_def_file->num_exports = j; /* == NE */ + + for (i = 0; i < NE; i++) + { + char *name = (char *) xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2); + *name = '_'; + strcpy (name + 1, pe_def_file->exports[i].internal_name); + + blhe = bfd_link_hash_lookup (info->hash, + name, + false, false, true); + + if (blhe && (blhe->type == bfd_link_hash_defined)) + { + count_exported++; + if (!pe_def_file->exports[i].flag_noname) + count_exported_byname++; + exported_symbol_offsets[i] = blhe->u.def.value; + exported_symbol_sections[i] = blhe->u.def.section; + if (pe_def_file->exports[i].ordinal != -1) + { + if (max_ordinal < pe_def_file->exports[i].ordinal) + max_ordinal = pe_def_file->exports[i].ordinal; + if (min_ordinal > pe_def_file->exports[i].ordinal) + min_ordinal = pe_def_file->exports[i].ordinal; + count_with_ordinals++; + } + } + else if (blhe && blhe->type == bfd_link_hash_undefined) + { + /* xgettext:c-format */ + einfo (_("%XCannot export %s: symbol not defined\n"), + pe_def_file->exports[i].internal_name); + } + else if (blhe) + { + /* xgettext:c-format */ + einfo (_("%XCannot export %s: symbol wrong type (%d vs %d)\n"), + pe_def_file->exports[i].internal_name, + blhe->type, bfd_link_hash_defined); + } + else + { + /* xgettext:c-format */ + einfo (_("%XCannot export %s: symbol not found\n"), + pe_def_file->exports[i].internal_name); + } + free (name); + } +} + +/************************************************************************ + + Build the bfd that will contain .edata and .reloc sections + + ************************************************************************/ + +static void +build_filler_bfd () +{ + lang_input_statement_type *filler_file; + filler_file = lang_add_input_file ("dll stuff", + lang_input_file_is_fake_enum, + NULL); + filler_file->the_bfd = filler_bfd = bfd_create ("dll stuff", output_bfd); + if (filler_bfd == NULL + || !bfd_set_arch_mach (filler_bfd, + bfd_get_arch (output_bfd), + bfd_get_mach (output_bfd))) + { + einfo ("%X%P: can not create BFD %E\n"); + return; + } + + edata_s = bfd_make_section_old_way (filler_bfd, ".edata"); + if (edata_s == NULL + || !bfd_set_section_flags (filler_bfd, edata_s, + (SEC_HAS_CONTENTS + | SEC_ALLOC + | SEC_LOAD + | SEC_KEEP + | SEC_IN_MEMORY))) + { + einfo ("%X%P: can not create .edata section: %E\n"); + return; + } + bfd_set_section_size (filler_bfd, edata_s, edata_sz); + + reloc_s = bfd_make_section_old_way (filler_bfd, ".reloc"); + if (reloc_s == NULL + || !bfd_set_section_flags (filler_bfd, reloc_s, + (SEC_HAS_CONTENTS + | SEC_ALLOC + | SEC_LOAD + | SEC_KEEP + | SEC_IN_MEMORY))) + { + einfo ("%X%P: can not create .reloc section: %E\n"); + return; + } + bfd_set_section_size (filler_bfd, reloc_s, 0); + + ldlang_add_file (filler_file); +} + +/************************************************************************ + + Gather all the exported symbols and build the .edata section + + ************************************************************************/ + +static void +generate_edata (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + int i, next_ordinal; + int name_table_size = 0; + const char *dlnp; + + /* First, we need to know how many exported symbols there are, + and what the range of ordinals is. */ + + if (pe_def_file->name) + { + dll_name = pe_def_file->name; + } + else + { + dll_name = abfd->filename; + for (dlnp = dll_name; *dlnp; dlnp++) + { + if (*dlnp == '\\' || *dlnp == '/' || *dlnp == ':') + dll_name = dlnp + 1; + } + } + + if (count_with_ordinals && max_ordinal > count_exported) + { + if (min_ordinal > max_ordinal - count_exported + 1) + min_ordinal = max_ordinal - count_exported + 1; + } + else + { + min_ordinal = 1; + max_ordinal = count_exported; + } + export_table_size = max_ordinal - min_ordinal + 1; + + exported_symbols = (int *) xmalloc (export_table_size * sizeof (int)); + for (i = 0; i < export_table_size; i++) + exported_symbols[i] = -1; + + /* Now we need to assign ordinals to those that don't have them */ + for (i = 0; i < NE; i++) + { + if (exported_symbol_sections[i]) + { + if (pe_def_file->exports[i].ordinal != -1) + { + int ei = pe_def_file->exports[i].ordinal - min_ordinal; + int pi = exported_symbols[ei]; + if (pi != -1) + { + /* xgettext:c-format */ + einfo (_("%XError, oridinal used twice: %d (%s vs %s)\n"), + pe_def_file->exports[i].ordinal, + pe_def_file->exports[i].name, + pe_def_file->exports[pi].name); + } + exported_symbols[ei] = i; + } + name_table_size += strlen (pe_def_file->exports[i].name) + 1; + } + } + + next_ordinal = min_ordinal; + for (i = 0; i < NE; i++) + if (exported_symbol_sections[i]) + if (pe_def_file->exports[i].ordinal == -1) + { + while (exported_symbols[next_ordinal - min_ordinal] != -1) + next_ordinal++; + exported_symbols[next_ordinal - min_ordinal] = i; + pe_def_file->exports[i].ordinal = next_ordinal; + } + + /* OK, now we can allocate some memory */ + + edata_sz = (40 /* directory */ + + 4 * export_table_size /* addresses */ + + 4 * count_exported_byname /* name ptrs */ + + 2 * count_exported_byname /* ordinals */ + + name_table_size + strlen (dll_name) + 1); +} + +static void +fill_edata (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + int i, hint; + unsigned char *edirectory; + unsigned long *eaddresses; + unsigned long *enameptrs; + unsigned short *eordinals; + unsigned char *enamestr; + time_t now; + + time (&now); + + edata_d = (unsigned char *) xmalloc (edata_sz); + + /* Note use of array pointer math here */ + edirectory = edata_d; + eaddresses = (unsigned long *) (edata_d + 40); + enameptrs = eaddresses + export_table_size; + eordinals = (unsigned short *) (enameptrs + count_exported_byname); + enamestr = (char *) (eordinals + count_exported_byname); + +#define ERVA(ptr) (((unsigned char *)(ptr) - edata_d) + edata_s->output_section->vma - image_base) + + memset (edata_d, 0, 40); + bfd_put_32 (abfd, now, edata_d + 4); + if (pe_def_file->version_major != -1) + { + bfd_put_16 (abfd, pe_def_file->version_major, edata_d + 8); + bfd_put_16 (abfd, pe_def_file->version_minor, edata_d + 10); + } + bfd_put_32 (abfd, ERVA (enamestr), edata_d + 12); + strcpy (enamestr, dll_name); + enamestr += strlen (enamestr) + 1; + bfd_put_32 (abfd, min_ordinal, edata_d + 16); + bfd_put_32 (abfd, export_table_size, edata_d + 20); + bfd_put_32 (abfd, count_exported_byname, edata_d + 24); + bfd_put_32 (abfd, ERVA (eaddresses), edata_d + 28); + bfd_put_32 (abfd, ERVA (enameptrs), edata_d + 32); + bfd_put_32 (abfd, ERVA (eordinals), edata_d + 36); + + /* Ok, now for the filling in part */ + hint = 0; + for (i = 0; i < export_table_size; i++) + { + int s = exported_symbols[i]; + if (s != -1) + { + struct sec *ssec = exported_symbol_sections[s]; + unsigned long srva = (exported_symbol_offsets[s] + + ssec->output_section->vma + + ssec->output_offset); + + bfd_put_32 (abfd, srva - image_base, (void *) (eaddresses + i)); + if (!pe_def_file->exports[s].flag_noname) + { + char *ename = pe_def_file->exports[s].name; + bfd_put_32 (abfd, ERVA (enamestr), (void *) enameptrs); + strcpy (enamestr, ename); + enamestr += strlen (enamestr) + 1; + bfd_put_16 (abfd, i, (void *) eordinals); + enameptrs++; + pe_def_file->exports[s].hint = hint++; + } + eordinals++; + } + } +} + +/************************************************************************ + + Gather all the relocations and build the .reloc section + + ************************************************************************/ + +static void +generate_reloc (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + + /* for .reloc stuff */ + bfd_vma *reloc_addresses; + int total_relocs = 0; + int i; + unsigned long sec_page = (unsigned long) (-1); + unsigned long page_ptr, page_count; + int bi; + bfd *b; + struct sec *s; + + total_relocs = 0; + for (b = info->input_bfds; b; b = b->link_next) + for (s = b->sections; s; s = s->next) + total_relocs += s->reloc_count; + + reloc_addresses = (bfd_vma *) xmalloc (total_relocs * sizeof (bfd_vma)); + + total_relocs = 0; + bi = 0; + for (bi = 0, b = info->input_bfds; b; bi++, b = b->link_next) + { + arelent **relocs; + int relsize, nrelocs, i; + + for (s = b->sections; s; s = s->next) + { + unsigned long sec_vma = s->output_section->vma + s->output_offset; + asymbol **symbols; + int nsyms, symsize; + + /* if it's not loaded, we don't need to relocate it this way */ + if (!(s->output_section->flags & SEC_LOAD)) + continue; + + /* I don't know why there would be a reloc for these, but I've + seen it happen - DJ */ + if (s->output_section == &bfd_abs_section) + continue; + + if (s->output_section->vma == 0) + { + /* Huh? Shouldn't happen, but punt if it does */ + einfo ("DJ: zero vma section reloc detected: `%s' #%d f=%d\n", + s->output_section->name, s->output_section->index, + s->output_section->flags); + continue; + } + + symsize = bfd_get_symtab_upper_bound (b); + symbols = (asymbol **) xmalloc (symsize); + nsyms = bfd_canonicalize_symtab (b, symbols); + + relsize = bfd_get_reloc_upper_bound (b, s); + relocs = (arelent **) xmalloc ((size_t) relsize); + nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols); + + for (i = 0; i < nrelocs; i++) + { + if (!relocs[i]->howto->pc_relative + && relocs[i]->howto->type != R_IMAGEBASE) + { + switch (relocs[i]->howto->bitsize) + { + case 32: + reloc_addresses[total_relocs++] = sec_vma + relocs[i]->address; + break; + default: + /* xgettext:c-format */ + einfo (_("%XError: %d-bit reloc in dll\n"), + relocs[i]->howto->bitsize); + break; + } + } + } + free (relocs); + /* Warning: the allocated symbols are remembered in BFD and reused + later, so don't free them! */ + /* free (symbols); */ + } + } + + /* At this point, we have total_relocs relocation addresses in + reloc_addresses, which are all suitable for the .reloc section. + We must now create the new sections. */ + + qsort (reloc_addresses, total_relocs, sizeof (bfd_vma), reloc_sort); + + for (i = 0; i < total_relocs; i++) + { + unsigned long this_page = (reloc_addresses[i] >> 12); + if (this_page != sec_page) + { + reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */ + reloc_sz += 8; + sec_page = this_page; + } + reloc_sz += 2; + } + reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */ + + reloc_d = (unsigned char *) xmalloc (reloc_sz); + + sec_page = (unsigned long) (-1); + reloc_sz = 0; + page_ptr = (unsigned long) (-1); + page_count = 0; + for (i = 0; i < total_relocs; i++) + { + unsigned long rva = reloc_addresses[i] - image_base; + unsigned long this_page = (rva & ~0xfff); + if (this_page != sec_page) + { + while (reloc_sz & 3) + reloc_d[reloc_sz++] = 0; + if (page_ptr != (unsigned long) (-1)) + bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4); + bfd_put_32 (abfd, this_page, reloc_d + reloc_sz); + page_ptr = reloc_sz; + reloc_sz += 8; + sec_page = this_page; + page_count = 0; + } + bfd_put_16 (abfd, (rva & 0xfff) + 0x3000, reloc_d + reloc_sz); + reloc_sz += 2; + page_count++; + } + while (reloc_sz & 3) + reloc_d[reloc_sz++] = 0; + if (page_ptr != (unsigned long) (-1)) + bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4); + while (reloc_sz < reloc_s->_raw_size) + reloc_d[reloc_sz++] = 0; +} + +/************************************************************************ + + Given the exiting def_file structure, print out a .DEF file that + corresponds to it. + + ************************************************************************/ + +static void +quoteput (s, f, needs_quotes) + char *s; + FILE * f; + int needs_quotes; +{ + char *cp; + for (cp = s; *cp; cp++) + if (*cp == '\'' + || *cp == '"' + || *cp == '\\' + || isspace ((unsigned char) *cp) + || *cp == ',' + || *cp == ';') + needs_quotes = 1; + if (needs_quotes) + { + putc ('"', f); + while (*s) + { + if (*s == '"' || *s == '\\') + putc ('\\', f); + putc (*s, f); + s++; + } + putc ('"', f); + } + else + fputs (s, f); +} + +void +pe_dll_generate_def_file (pe_out_def_filename) + char *pe_out_def_filename; +{ + int i; + FILE *out = fopen (pe_out_def_filename, "w"); + if (out == NULL) + { + /* xgettext:c-format */ + einfo (_("%s: Can't open output def file %s\n"), + program_name, pe_out_def_filename); + } + + if (pe_def_file) + { + if (pe_def_file->name) + { + if (pe_def_file->is_dll) + fprintf (out, "LIBRARY "); + else + fprintf (out, "NAME "); + quoteput (pe_def_file->name, out, 1); + if (pe_data (output_bfd)->pe_opthdr.ImageBase) + fprintf (out, " BASE=0x%lx", + (unsigned long) pe_data (output_bfd)->pe_opthdr.ImageBase); + fprintf (out, "\n"); + } + + if (pe_def_file->description) + { + fprintf (out, "DESCRIPTION "); + quoteput (pe_def_file->description, out, 1); + fprintf (out, "\n"); + } + + if (pe_def_file->version_minor != -1) + fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major, + pe_def_file->version_minor); + else if (pe_def_file->version_major != -1) + fprintf (out, "VERSION %d\n", pe_def_file->version_major); + + if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1) + fprintf (out, "\n"); + + if (pe_def_file->stack_commit != -1) + fprintf (out, "STACKSIZE 0x%x,0x%x\n", + pe_def_file->stack_reserve, pe_def_file->stack_commit); + else if (pe_def_file->stack_reserve != -1) + fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve); + if (pe_def_file->heap_commit != -1) + fprintf (out, "HEAPSIZE 0x%x,0x%x\n", + pe_def_file->heap_reserve, pe_def_file->heap_commit); + else if (pe_def_file->heap_reserve != -1) + fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve); + + if (pe_def_file->num_section_defs > 0) + { + fprintf (out, "\nSECTIONS\n\n"); + for (i = 0; i < pe_def_file->num_section_defs; i++) + { + fprintf (out, " "); + quoteput (pe_def_file->section_defs[i].name, out, 0); + if (pe_def_file->section_defs[i].class) + { + fprintf (out, " CLASS "); + quoteput (pe_def_file->section_defs[i].class, out, 0); + } + if (pe_def_file->section_defs[i].flag_read) + fprintf (out, " READ"); + if (pe_def_file->section_defs[i].flag_write) + fprintf (out, " WRITE"); + if (pe_def_file->section_defs[i].flag_execute) + fprintf (out, " EXECUTE"); + if (pe_def_file->section_defs[i].flag_shared) + fprintf (out, " SHARED"); + fprintf (out, "\n"); + } + } + + if (pe_def_file->num_exports > 0) + { + fprintf (out, "\nEXPORTS\n\n"); + for (i = 0; i < pe_def_file->num_exports; i++) + { + def_file_export *e = pe_def_file->exports + i; + fprintf (out, " "); + quoteput (e->name, out, 0); + if (e->internal_name && strcmp (e->internal_name, e->name)) + { + fprintf (out, " = "); + quoteput (e->internal_name, out, 0); + } + if (e->ordinal != -1) + fprintf (out, " @%d", e->ordinal); + if (e->flag_private) + fprintf (out, " PRIVATE"); + if (e->flag_constant) + fprintf (out, " CONSTANT"); + if (e->flag_noname) + fprintf (out, " NONAME"); + if (e->flag_data) + fprintf (out, " DATA"); + + fprintf (out, "\n"); + } + } + + if (pe_def_file->num_imports > 0) + { + fprintf (out, "\nIMPORTS\n\n"); + for (i = 0; i < pe_def_file->num_imports; i++) + { + def_file_import *im = pe_def_file->imports + i; + fprintf (out, " "); + if (im->internal_name + && (!im->name || strcmp (im->internal_name, im->name))) + { + quoteput (im->internal_name, out, 0); + fprintf (out, " = "); + } + quoteput (im->module->name, out, 0); + fprintf (out, "."); + if (im->name) + quoteput (im->name, out, 0); + else + fprintf (out, "%d", im->ordinal); + fprintf (out, "\n"); + } + } + } + else + fprintf (out, _("; no contents available\n")); + + if (fclose (out) == EOF) + { + /* xgettext:c-format */ + einfo (_("%P: Error closing file `%s'\n"), pe_out_def_filename); + } +} + +/************************************************************************ + + Generate the import library + + ************************************************************************/ + +static asymbol **symtab; +static int symptr; +static int tmp_seq; +static const char *dll_filename; +static char *dll_symname; + +#define UNDSEC (asection *) &bfd_und_section + +static asection * +quick_section(abfd, name, flags, align) + bfd *abfd; + const char *name; + int flags; + int align; +{ + asection *sec; + asymbol *sym; + + sec = bfd_make_section_old_way (abfd, name); + bfd_set_section_flags (abfd, sec, flags + | SEC_ALLOC + | SEC_LOAD + | SEC_KEEP + ); + bfd_set_section_alignment (abfd, sec, align); + /* remember to undo this before trying to link internally! */ + sec->output_section = sec; + + sym = bfd_make_empty_symbol (abfd); + symtab[symptr++] = sym; + sym->name = sec->name; + sym->section = sec; + sym->flags = BSF_LOCAL; + sym->value = 0; + + return sec; +} + +static void +quick_symbol (abfd, n1, n2, n3, sec, flags, addr) + bfd *abfd; + char *n1; + char *n2; + char *n3; + asection *sec; + int flags; + int addr; +{ + asymbol *sym; + char *name = (char *) xmalloc (strlen (n1) + strlen (n2) + strlen (n3) + 1); + strcpy (name, n1); + strcat (name, n2); + strcat (name, n3); + sym = bfd_make_empty_symbol (abfd); + sym->name = name; + sym->section = sec; + sym->flags = flags; + sym->value = addr; + symtab[symptr++] = sym; +} + +static arelent *reltab = 0; +static int relcount = 0, relsize = 0; + +static void +quick_reloc (abfd, address, which_howto, symidx) + bfd *abfd; + int address; + int which_howto; + int symidx; +{ + if (relcount >= (relsize-1)) + { + relsize += 10; + if (reltab) + reltab = (arelent *) xrealloc (reltab, relsize * sizeof (arelent)); + else + reltab = (arelent *) xmalloc (relsize * sizeof (arelent)); + } + reltab[relcount].address = address; + reltab[relcount].addend = 0; + reltab[relcount].howto = bfd_reloc_type_lookup (abfd, which_howto); + reltab[relcount].sym_ptr_ptr = symtab + symidx; + relcount++; +} + +static void +save_relocs (asection *sec) +{ + int i; + sec->relocation = reltab; + sec->reloc_count = relcount; + sec->orelocation = (arelent **) xmalloc ((relcount+1) * sizeof (arelent *)); + for (i=0; i<relcount; i++) + sec->orelocation[i] = sec->relocation + i; + sec->orelocation[relcount] = 0; + sec->flags |= SEC_RELOC; + reltab = 0; + relcount = relsize = 0; +} + +/* + * .section .idata$2 + * .global __head_my_dll + * __head_my_dll: + * .rva hname + * .long 0 + * .long 0 + * .rva __my_dll_iname + * .rva fthunk + * + * .section .idata$5 + * .long 0 + * fthunk: + * + * .section .idata$4 + * .long 0 + * hname: + */ + +static bfd * +make_head (parent) + bfd *parent; +{ + asection *id2, *id5, *id4; + unsigned char *d2, *d5, *d4; + char *oname; + bfd *abfd; + + oname = (char *) xmalloc (20); + sprintf (oname, "d%06d.o", tmp_seq); + tmp_seq++; + + abfd = bfd_create (oname, parent); + bfd_find_target ("pe-i386", abfd); + bfd_make_writable (abfd); + + bfd_set_format (abfd, bfd_object); + bfd_set_arch_mach (abfd, bfd_arch_i386, 0); + + symptr = 0; + symtab = (asymbol **) xmalloc (6 * sizeof (asymbol *)); + id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2); + id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2); + id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2); + quick_symbol (abfd, "__head_", dll_symname, "", id2, BSF_GLOBAL, 0); + quick_symbol (abfd, "_", dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0); + + bfd_set_section_size (abfd, id2, 20); + d2 = (unsigned char *) xmalloc (20); + id2->contents = d2; + memset (d2, 0, 20); + d2[0] = d2[16] = 4; /* reloc addend */ + quick_reloc (abfd, 0, BFD_RELOC_RVA, 2); + quick_reloc (abfd, 12, BFD_RELOC_RVA, 4); + quick_reloc (abfd, 16, BFD_RELOC_RVA, 1); + save_relocs (id2); + + bfd_set_section_size (abfd, id5, 4); + d5 = (unsigned char *) xmalloc (4); + id5->contents = d5; + memset (d5, 0, 4); + + bfd_set_section_size (abfd, id4, 4); + d4 = (unsigned char *) xmalloc (4); + id4->contents = d4; + memset (d4, 0, 4); + + bfd_set_symtab (abfd, symtab, symptr); + + bfd_set_section_contents (abfd, id2, d2, 0, 20); + bfd_set_section_contents (abfd, id5, d5, 0, 4); + bfd_set_section_contents (abfd, id4, d4, 0, 4); + + bfd_make_readable (abfd); + return abfd; +} + +/* + * .section .idata$4 + * .long 0 + * .section .idata$5 + * .long 0 + * .section idata$7 + * .global __my_dll_iname + *__my_dll_iname: + * .asciz "my.dll" + */ + +static bfd * +make_tail (parent) + bfd *parent; +{ + asection *id4, *id5, *id7; + unsigned char *d4, *d5, *d7; + int len; + char *oname; + bfd *abfd; + + oname = (char *) xmalloc (20); + sprintf (oname, "d%06d.o", tmp_seq); + tmp_seq++; + + abfd = bfd_create (oname, parent); + bfd_find_target ("pe-i386", abfd); + bfd_make_writable (abfd); + + bfd_set_format (abfd, bfd_object); + bfd_set_arch_mach (abfd, bfd_arch_i386, 0); + + symptr = 0; + symtab = (asymbol **) xmalloc (5 * sizeof (asymbol *)); + id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2); + id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2); + id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2); + quick_symbol (abfd, "_", dll_symname, "_iname", id7, BSF_GLOBAL, 0); + + bfd_set_section_size (abfd, id4, 4); + d4 = (unsigned char *) xmalloc (4); + id4->contents = d4; + memset (d4, 0, 4); + + bfd_set_section_size (abfd, id5, 4); + d5 = (unsigned char *) xmalloc (4); + id5->contents = d5; + memset (d5, 0, 4); + + len = strlen (dll_filename)+1; + if (len & 1) + len ++; + bfd_set_section_size (abfd, id7, len); + d7 = (unsigned char *) xmalloc (len); + id7->contents = d7; + strcpy (d7, dll_filename); + + bfd_set_symtab (abfd, symtab, symptr); + + bfd_set_section_contents (abfd, id4, d4, 0, 4); + bfd_set_section_contents (abfd, id5, d5, 0, 4); + bfd_set_section_contents (abfd, id7, d7, 0, len); + + bfd_make_readable (abfd); + return abfd; +} + +/* + * .text + * .global _function + * .global ___imp_function + * .global __imp__function + *_function: + * jmp *__imp__function: + * + * .section idata$7 + * .long __head_my_dll + * + * .section .idata$5 + *___imp_function: + *__imp__function: + *iat? + * .section .idata$4 + *iat? + * .section .idata$6 + *ID<ordinal>: + * .short <hint> + * .asciz "function" xlate? (add underscore, kill at) + */ + +static unsigned char jmp_ix86_bytes[] = { + 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 +}; + + +static bfd * +make_one (exp, parent) + def_file_export *exp; + bfd *parent; +{ + asection *tx, *id7, *id5, *id4, *id6; + unsigned char *td, *d7, *d5, *d4, *d6; + int len; + char *oname; + bfd *abfd; + + oname = (char *) xmalloc (20); + sprintf (oname, "d%06d.o", tmp_seq); + tmp_seq++; + + abfd = bfd_create (oname, parent); + bfd_find_target ("pe-i386", abfd); + bfd_make_writable (abfd); + + bfd_set_format (abfd, bfd_object); + bfd_set_arch_mach (abfd, bfd_arch_i386, 0); + + symptr = 0; + symtab = (asymbol **) xmalloc (10 * sizeof (asymbol *)); + tx = quick_section (abfd, ".text", SEC_CODE|SEC_HAS_CONTENTS, 2); + id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2); + id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2); + id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2); + id6 = quick_section (abfd, ".idata$6", SEC_HAS_CONTENTS, 2); + quick_symbol (abfd, "_", exp->internal_name, "", tx, BSF_GLOBAL, 0); + quick_symbol (abfd, "__head_", dll_symname, "", UNDSEC, BSF_GLOBAL, 0); + quick_symbol (abfd, "___imp_", exp->internal_name, "", id5, BSF_GLOBAL, 0); + quick_symbol (abfd, "__imp__", exp->internal_name, "", id5, BSF_GLOBAL, 0); + + bfd_set_section_size (abfd, tx, 8); + td = (unsigned char *) xmalloc (8); + tx->contents = td; + memcpy (td, jmp_ix86_bytes, 8); + quick_reloc (abfd, 2, BFD_RELOC_32, 2); + save_relocs (tx); + + bfd_set_section_size (abfd, id7, 4); + d7 = (unsigned char *) xmalloc (4); + id7->contents = d7; + memset (d7, 0, 4); + quick_reloc (abfd, 0, BFD_RELOC_RVA, 6); + save_relocs (id7); + + bfd_set_section_size (abfd, id5, 4); + d5 = (unsigned char *) xmalloc (4); + id5->contents = d5; + memset (d5, 0, 4); + if (exp->flag_noname) + { + d5[0] = exp->ordinal; + d5[1] = exp->ordinal >> 8; + d5[3] = 0x80; + } + else + { + quick_reloc (abfd, 0, BFD_RELOC_RVA, 4); + save_relocs (id5); + } + + bfd_set_section_size (abfd, id4, 4); + d4 = (unsigned char *) xmalloc (4); + id4->contents = d4; + memset (d4, 0, 4); + if (exp->flag_noname) + { + d5[0] = exp->ordinal; + d5[1] = exp->ordinal >> 8; + d5[3] = 0x80; + } + else + { + quick_reloc (abfd, 0, BFD_RELOC_RVA, 4); + save_relocs (id4); + } + + if (exp->flag_noname) + { + len = 0; + bfd_set_section_size (abfd, id6, 0); + } + else + { + len = strlen (exp->name) + 3; + if (len & 1) + len++; + bfd_set_section_size (abfd, id6, len); + d6 = (unsigned char *) xmalloc (len); + id6->contents = d6; + memset (d6, 0, len); + d6[0] = exp->hint & 0xff; + d6[1] = exp->hint >> 8; + strcpy (d6+2, exp->name); + } + + bfd_set_symtab (abfd, symtab, symptr); + + bfd_set_section_contents (abfd, tx, td, 0, 4); + bfd_set_section_contents (abfd, id7, d7, 0, 4); + bfd_set_section_contents (abfd, id5, d5, 0, 4); + bfd_set_section_contents (abfd, id4, d4, 0, 4); + if (!exp->flag_noname) + bfd_set_section_contents (abfd, id6, d6, 0, len); + + bfd_make_readable (abfd); + return abfd; +} + +void +pe_dll_generate_implib (def, impfilename) + def_file *def; + char *impfilename; +{ + int i; + bfd *ar_head; + bfd *ar_tail; + bfd *outarch; + bfd *head = 0; + + dll_filename = def->name; + if (dll_filename == 0) + { + dll_filename = dll_name; + for (i=0; impfilename[i]; i++) + if (impfilename[i] == '/' || impfilename[i] == '\\') + dll_filename = impfilename+1; + } + dll_symname = xstrdup (dll_filename); + for (i=0; dll_symname[i]; i++) + if (!isalnum ((unsigned char) dll_symname[i])) + dll_symname[i] = '_'; + + unlink (impfilename); + + outarch = bfd_openw (impfilename, 0); + + if (!outarch) + { + /* xgettext:c-format */ + einfo (_("%XCan't open .lib file: %s\n"), impfilename); + return; + } + + /* xgettext:c-format */ + einfo (_("Creating library file: %s\n"), impfilename); + + bfd_set_format (outarch, bfd_archive); + outarch->has_armap = 1; + + /* Work out a reasonable size of things to put onto one line. */ + + ar_head = make_head (outarch); + ar_tail = make_tail (outarch); + + if (ar_head == NULL || ar_tail == NULL) + return; + + for (i = 0; i<def->num_exports; i++) + { + /* The import library doesn't know about the internal name */ + char *internal = def->exports[i].internal_name; + bfd *n; + def->exports[i].internal_name = def->exports[i].name; + n = make_one (def->exports+i, outarch); + n->next = head; + head = n; + def->exports[i].internal_name = internal; + } + + /* Now stick them all into the archive */ + + ar_head->next = head; + ar_tail->next = ar_head; + head = ar_tail; + + if (! bfd_set_archive_head (outarch, head)) + einfo ("%Xbfd_set_archive_head: %s\n", bfd_errmsg (bfd_get_error ())); + + if (! bfd_close (outarch)) + einfo ("%Xbfd_close %s: %s\n", impfilename, bfd_errmsg (bfd_get_error ())); + + while (head != NULL) + { + bfd *n = head->next; + bfd_close (head); + head = n; + } +} + +static void +add_bfd_to_link (abfd, name, link_info) + bfd *abfd; + char *name; + struct bfd_link_info *link_info; +{ + lang_input_statement_type *fake_file; + fake_file = lang_add_input_file (name, + lang_input_file_is_fake_enum, + NULL); + fake_file->the_bfd = abfd; + ldlang_add_file (fake_file); + if (!bfd_link_add_symbols (abfd, link_info)) + einfo ("%Xaddsym %s: %s\n", name, bfd_errmsg (bfd_get_error ())); +} + +void +pe_process_import_defs (output_bfd, link_info) + bfd *output_bfd; + struct bfd_link_info *link_info; +{ + def_file_module *module; + + if (!pe_def_file) + return; + + for (module = pe_def_file->modules; module; module = module->next) + { + int i, do_this_dll; + + dll_filename = module->name; + dll_symname = xstrdup (module->name); + for (i=0; dll_symname[i]; i++) + if (!isalnum (dll_symname[i])) + dll_symname[i] = '_'; + + do_this_dll = 0; + + for (i=0; i<pe_def_file->num_imports; i++) + if (pe_def_file->imports[i].module == module) + { + def_file_export exp; + struct bfd_link_hash_entry *blhe; + + /* see if we need this import */ + char *name = (char *) xmalloc (strlen (pe_def_file->imports[i].internal_name) + 2); + sprintf (name, "_%s", pe_def_file->imports[i].internal_name); + blhe = bfd_link_hash_lookup (link_info->hash, name, + false, false, false); + free (name); + if (blhe && blhe->type == bfd_link_hash_undefined) + { + bfd *one; + /* we do */ + if (!do_this_dll) + { + bfd *ar_head = make_head (output_bfd); + add_bfd_to_link (ar_head, ar_head->filename, link_info); + do_this_dll = 1; + } + exp.internal_name = pe_def_file->imports[i].internal_name; + exp.name = pe_def_file->imports[i].name; + exp.ordinal = pe_def_file->imports[i].ordinal; + exp.hint = exp.ordinal >= 0 ? exp.ordinal : 0; + exp.flag_private = 0; + exp.flag_constant = 0; + exp.flag_data = 0; + exp.flag_noname = exp.name ? 0 : 1; + one = make_one (&exp, output_bfd); + add_bfd_to_link (one, one->filename, link_info); + } + } + if (do_this_dll) + { + bfd *ar_tail = make_tail (output_bfd); + add_bfd_to_link (ar_tail, ar_tail->filename, link_info); + } + + free (dll_symname); + } +} + +/************************************************************************ + + We were handed a *.DLL file. Parse it and turn it into a set of + IMPORTS directives in the def file. Return true if the file was + handled, false if not. + + ************************************************************************/ + +static unsigned int +pe_get16 (abfd, where) + bfd *abfd; + int where; +{ + unsigned char b[2]; + bfd_seek (abfd, where, SEEK_SET); + bfd_read (b, 1, 2, abfd); + return b[0] + (b[1]<<8); +} + +static unsigned int +pe_get32 (abfd, where) + bfd *abfd; + int where; +{ + unsigned char b[4]; + bfd_seek (abfd, where, SEEK_SET); + bfd_read (b, 1, 4, abfd); + return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +} + +#if 0 /* This is not currently used. */ + +static unsigned int +pe_as16 (ptr) + void *ptr; +{ + unsigned char *b = ptr; + return b[0] + (b[1]<<8); +} + +#endif + +static unsigned int +pe_as32 (ptr) + void *ptr; +{ + unsigned char *b = ptr; + return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +} + +boolean +pe_implied_import_dll (filename) + char *filename; +{ + bfd *dll; + unsigned long pe_header_offset, opthdr_ofs, num_entries, i; + unsigned long export_rva, export_size, nsections, secptr, expptr; + unsigned char *expdata, *erva; + unsigned long name_rvas, ordinals, nexp, ordbase; + char *dll_name; + + /* No, I can't use bfd here. kernel32.dll puts its export table in + the middle of the .rdata section. */ + + dll = bfd_openr (filename, "pei-i386"); + if (!dll) + { + einfo ("%Xopen %s: %s\n", filename, bfd_errmsg (bfd_get_error ())); + return false; + } + /* PEI dlls seem to be bfd_objects */ + if (!bfd_check_format (dll, bfd_object)) + { + einfo ("%X%s: this doesn't appear to be a DLL\n", filename); + return false; + } + + dll_name = filename; + for (i=0; filename[i]; i++) + if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') + dll_name = filename + i + 1; + + pe_header_offset = pe_get32 (dll, 0x3c); + opthdr_ofs = pe_header_offset + 4 + 20; + num_entries = pe_get32 (dll, opthdr_ofs + 92); + if (num_entries < 1) /* no exports */ + return false; + export_rva = pe_get32 (dll, opthdr_ofs + 96); + export_size = pe_get32 (dll, opthdr_ofs + 100); + nsections = pe_get16 (dll, pe_header_offset + 4 + 2); + secptr = (pe_header_offset + 4 + 20 + + pe_get16 (dll, pe_header_offset + 4 + 16)); + expptr = 0; + for (i=0; i<nsections; i++) + { + char sname[8]; + unsigned long secptr1 = secptr + 40 * i; + unsigned long vaddr = pe_get32 (dll, secptr1 + 12); + unsigned long vsize = pe_get32 (dll, secptr1 + 16); + unsigned long fptr = pe_get32 (dll, secptr1 + 20); + bfd_seek(dll, secptr1, SEEK_SET); + bfd_read(sname, 1, 8, dll); + if (vaddr <= export_rva && vaddr+vsize > export_rva) + { + expptr = fptr + (export_rva - vaddr); + if (export_rva + export_size > vaddr + vsize) + export_size = vsize - (export_rva - vaddr); + break; + } + } + + expdata = (unsigned char *) xmalloc (export_size); + bfd_seek (dll, expptr, SEEK_SET); + bfd_read (expdata, 1, export_size, dll); + erva = expdata - export_rva; + + if (pe_def_file == 0) + pe_def_file = def_file_empty(); + + nexp = pe_as32 (expdata+24); + name_rvas = pe_as32 (expdata+32); + ordinals = pe_as32 (expdata+36); + ordbase = pe_as32 (expdata+16); + for (i=0; i<nexp; i++) + { + unsigned long name_rva = pe_as32 (erva+name_rvas+i*4); + def_file_import *imp; + imp = def_file_add_import (pe_def_file, erva+name_rva, dll_name, + i, 0); + } + + return true; +} + +/************************************************************************ + + These are the main functions, called from the emulation. The first + is called after the bfds are read, so we can guess at how much space + we need. The second is called after everything is placed, so we + can put the right values in place. + + ************************************************************************/ + +void +pe_dll_build_sections (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + process_def_file (abfd, info); + + generate_edata (abfd, info); + build_filler_bfd (); +} + +void +pe_dll_fill_sections (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + image_base = pe_data (abfd)->pe_opthdr.ImageBase; + + generate_reloc (abfd, info); + if (reloc_sz > 0) + { + bfd_set_section_size (filler_bfd, reloc_s, reloc_sz); + + /* Resize the sections. */ + lang_size_sections (stat_ptr->head, abs_output_section, + &stat_ptr->head, 0, (bfd_vma) 0, false); + + /* Redo special stuff. */ + ldemul_after_allocation (); + + /* Do the assignments again. */ + lang_do_assignments (stat_ptr->head, + abs_output_section, + (fill_type) 0, (bfd_vma) 0); + } + + fill_edata (abfd, info); + + pe_data (abfd)->dll = 1; + + edata_s->contents = edata_d; + reloc_s->contents = reloc_d; +} diff --git a/ld/po/Make-in b/ld/po/Make-in new file mode 100644 index 0000000..4291090 --- /dev/null +++ b/ld/po/Make-in @@ -0,0 +1,251 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu> +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale +gnulocaledir = $(prefix)/share/locale +gettextsrcdir = $(prefix)/share/gettext/po +subdir = po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = @MKINSTALLDIRS@ + +CC = @CC@ +GENCAT = @GENCAT@ +GMSGFMT = PATH=../src:$$PATH @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = PATH=../src:$$PATH @XGETTEXT@ +MSGMERGE = PATH=../src:$$PATH msgmerge + +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I.. -I$(top_srcdir)/intl + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +SOURCES = cat-id-tbl.c +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \ +stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES) + +POTFILES = \ + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat + +.c.o: + $(COMPILE) $< + +.po.pox: + $(MAKE) $(PACKAGE).pot + $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && $(GENCAT) $@ $*.msg + + +all: all-@USE_NLS@ + +all-yes: $(CATALOGS) @MAINT@ $(PACKAGE).pot +all-no: + +$(srcdir)/$(PACKAGE).pot: $(POTFILES) + $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ + --add-comments -C --keyword=_ --keyword=N_ \ + --files-from=$(srcdir)/POTFILES.in + rm -f $(srcdir)/$(PACKAGE).pot + mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot + +$(srcdir)/cat-id-tbl.c: stamp-cat-id; @: +$(srcdir)/stamp-cat-id: $(PACKAGE).pot + rm -f cat-id-tbl.tmp + sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \ + | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp + if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \ + rm cat-id-tbl.tmp; \ + else \ + echo cat-id-tbl.c changed; \ + rm -f $(srcdir)/cat-id-tbl.c; \ + mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \ + fi + cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id + + +install: install-exec install-data +install-exec: +install-info: +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + if test -r $(MKINSTALLDIRS); then \ + $(MKINSTALLDIRS) $(datadir); \ + else \ + $(top_srcdir)/mkinstalldirs $(datadir); \ + fi + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + case "$$cat" in \ + *.gmo) destdir=$(gnulocaledir);; \ + *) destdir=$(localedir);; \ + esac; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + dir=$$destdir/$$lang/LC_MESSAGES; \ + if test -r $(MKINSTALLDIRS); then \ + $(MKINSTALLDIRS) $$dir; \ + else \ + $(top_srcdir)/mkinstalldirs $$dir; \ + fi; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + fi; \ + if test -r $$cat.m; then \ + $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + if test -r $(srcdir)/$$cat.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$cat.m \ + $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + true; \ + fi; \ + fi; \ + done + if test "$(PACKAGE)" = "gettext"; then \ + if test -r $(MKINSTALLDIRS); then \ + $(MKINSTALLDIRS) $(gettextsrcdir); \ + else \ + $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ + fi; \ + $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ + $(gettextsrcdir)/Makefile.in.in; \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + done + rm -f $(gettextsrcdir)/po-Makefile.in.in + +check: all + +cat-id-tbl.o: ../intl/libgettext.h + +dvi info tags TAGS ID: + +mostlyclean: + rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f $(GMOFILES) + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: update-po $(DISTFILES) + dists="$(DISTFILES)"; \ + for file in $$dists; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(PACKAGE).pot + PATH=`pwd`/../src:$$PATH; \ + cd $(srcdir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + mv $$lang.po $$lang.old.po; \ + echo "$$lang:"; \ + if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ + rm -f $$lang.old.po; \ + else \ + echo "msgmerge for $$cat failed!"; \ + rm -f $$lang.po; \ + mv $$lang.old.po $$lang.po; \ + fi; \ + done + +POTFILES: POTFILES.in + ( if test 'x$(srcdir)' != 'x.'; then \ + posrcprefix='$(top_srcdir)/'; \ + else \ + posrcprefix="../"; \ + fi; \ + rm -f $@-t $@ \ + && (sed -e '/^#/d' -e '/^[ ]*$$/d' \ + -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ + | sed -e '$$s/\\$$//') > $@-t \ + && chmod a-w $@-t \ + && mv $@-t $@ ) + +POTFILES.in: @MAINT@ ../Makefile + cd .. && $(MAKE) po/POTFILES.in + +Makefile: Make-in ../config.status POTFILES + cd .. \ + && CONFIG_FILES=$(subdir)/Makefile.in:$(subdir)/Make-in \ + CONFIG_HEADERS= $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ld/po/POTFILES.in b/ld/po/POTFILES.in new file mode 100644 index 0000000..468a8a6 --- /dev/null +++ b/ld/po/POTFILES.in @@ -0,0 +1,64 @@ +deffile.h +ld.h +ldcref.c +ldctor.c +ldctor.h +ldemul.c +ldemul.h +ldexp.c +ldexp.h +ldfile.c +ldfile.h +ldlang.c +ldlang.h +ldlex.h +ldmain.c +ldmain.h +ldmisc.c +ldmisc.h +ldver.c +ldver.h +ldwrite.c +ldwrite.h +lexsup.c +mpw-elfmips.c +mpw-eppcmac.c +mpw-esh.c +mpw-idtmips.c +mri.c +mri.h +pe-dll.c +sysdep.h +testsuite/ld-cdtest/cdtest-foo.h +testsuite/ld-elfvers/vers1.c +testsuite/ld-elfvers/vers15.c +testsuite/ld-elfvers/vers16.c +testsuite/ld-elfvers/vers16a.c +testsuite/ld-elfvers/vers2.c +testsuite/ld-elfvers/vers3.c +testsuite/ld-elfvers/vers4.c +testsuite/ld-elfvers/vers5.c +testsuite/ld-elfvers/vers6.c +testsuite/ld-elfvers/vers7.c +testsuite/ld-elfvers/vers7a.c +testsuite/ld-elfvers/vers8.c +testsuite/ld-elfvers/vers9.c +testsuite/ld-empic/relax1.c +testsuite/ld-empic/relax2.c +testsuite/ld-empic/relax3.c +testsuite/ld-empic/relax4.c +testsuite/ld-empic/run.c +testsuite/ld-empic/runtest1.c +testsuite/ld-empic/runtest2.c +testsuite/ld-scripts/cross1.c +testsuite/ld-scripts/cross2.c +testsuite/ld-scripts/cross3.c +testsuite/ld-selective/1.c +testsuite/ld-selective/2.c +testsuite/ld-sh/sh2.c +testsuite/ld-shared/main.c +testsuite/ld-shared/sh1.c +testsuite/ld-shared/sh2.c +testsuite/ld-srec/sr1.c +testsuite/ld-srec/sr2.c +testsuite/ld-undefined/undefined.c diff --git a/ld/po/ld.pot b/ld/po/ld.pot new file mode 100644 index 0000000..faaaeb0 --- /dev/null +++ b/ld/po/ld.pot @@ -0,0 +1,1372 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 1999-02-11 21:00+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" + +#: emultempl/armcoff.em:65 +msgid " --support-old-code Support interworking with old code\n" +msgstr "" + +#: emultempl/armcoff.em:130 +#, c-format +msgid "Errors encountered processing file %s" +msgstr "" + +#: emultempl/pe.em:190 +msgid "" +" --base_file <basefile> Generate a base file for relocatable " +"DLLs\n" +msgstr "" + +#: emultempl/pe.em:191 +msgid "" +" --dll Set image base to the default for DLLs\n" +msgstr "" + +#: emultempl/pe.em:192 +msgid " --file-alignment <size> Set file alignment\n" +msgstr "" + +#: emultempl/pe.em:193 +msgid " --heap <size> Set initial size of the heap\n" +msgstr "" + +#: emultempl/pe.em:194 +msgid "" +" --image-base <address> Set start address of the executable\n" +msgstr "" + +#: emultempl/pe.em:195 +msgid "" +" --major-image-version <number> Set version number of the executable\n" +msgstr "" + +#: emultempl/pe.em:196 +msgid " --major-os-version <number> Set minimum required OS version\n" +msgstr "" + +#: emultempl/pe.em:197 +msgid "" +" --major-subsystem-version <number> Set minimum required OS subsystem " +"version\n" +msgstr "" + +#: emultempl/pe.em:198 +msgid "" +" --minor-image-version <number> Set revision number of the executable\n" +msgstr "" + +#: emultempl/pe.em:199 +msgid " --minor-os-version <number> Set minimum required OS revision\n" +msgstr "" + +#: emultempl/pe.em:200 +msgid "" +" --minor-subsystem-version <number> Set minimum required OS subsystem " +"revision\n" +msgstr "" + +#: emultempl/pe.em:201 +msgid " --section-alignment <size> Set section alignment\n" +msgstr "" + +#: emultempl/pe.em:202 +msgid " --stack <size> Set size of the initial stack\n" +msgstr "" + +#: emultempl/pe.em:203 +msgid "" +" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n" +msgstr "" + +#: emultempl/pe.em:204 +msgid "" +" --support-old-code Support interworking with old code\n" +msgstr "" + +#: emultempl/pe.em:206 +msgid "" +" --add-stdcall-alias Export symbols with and without @nn\n" +msgstr "" + +#: emultempl/pe.em:207 +msgid " --disable-stdcall-fixup Don't link _sym to _sym@nn\n" +msgstr "" + +#: emultempl/pe.em:208 +msgid "" +" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n" +msgstr "" + +#: emultempl/pe.em:209 +msgid "" +" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n" +msgstr "" + +#: emultempl/pe.em:210 +msgid "" +" --export-all-symbols Automatically export all globals to " +"DLL\n" +msgstr "" + +#: emultempl/pe.em:211 +msgid " --kill-at Remove @nn from exported symbols\n" +msgstr "" + +#: emultempl/pe.em:212 +msgid " --out-implib <file> Generate import library\n" +msgstr "" + +#: emultempl/pe.em:213 +msgid "" +" --output-def <file> Generate a .DEF file for the built DLL\n" +msgstr "" + +#: emultempl/pe.em:276 +msgid "%P: warning: bad version number in -subsystem option\n" +msgstr "" + +#: emultempl/pe.em:292 +msgid "%P%F: invalid subsystem type %s\n" +msgstr "" + +#: emultempl/pe.em:307 +msgid "%P%F: invalid hex number for PE parameter '%s'\n" +msgstr "" + +#: emultempl/pe.em:325 +msgid "%P%F: strange hex info for PE parameter '%s'\n" +msgstr "" + +#: emultempl/pe.em:364 +#, c-format +msgid "%s: Can't open base file %s\n" +msgstr "" + +#: emultempl/pe.em:497 +msgid "%P: warning, file alignment > section alignment.\n" +msgstr "" + +#: emultempl/pe.em:567 emultempl/pe.em:593 +#, c-format +msgid "Warning: resolving %s by linking to %s\n" +msgstr "" + +#: emultempl/pe.em:572 emultempl/pe.em:598 +msgid "Use --enable-stdcall-fixup to disable these warnings\n" +msgstr "" + +#: emultempl/pe.em:573 emultempl/pe.em:599 +msgid "Use --disable-stdcall-fixup to disable these fixups\n" +msgstr "" + +#: emultempl/pe.em:615 +msgid "%F%P: PE operations on non PE file.\n" +msgstr "" + +#: emultempl/pe.em:652 +#, c-format +msgid "Errors encountered processing file %s\n" +msgstr "" + +#: emultempl/pe.em:675 +#, c-format +msgid "Errors encountered processing file %s for interworking" +msgstr "" + +#: emultempl/pe.em:730 ldlang.c:1623 ldlang.c:3990 ldlang.c:4024 ldmain.c:978 +msgid "%P%F: bfd_link_hash_lookup failed: %E\n" +msgstr "" + +#: ldcref.c:162 +msgid "%X%P: bfd_hash_table_init of cref table failed: %E\n" +msgstr "" + +#: ldcref.c:168 +msgid "%X%P: cref_hash_lookup failed: %E\n" +msgstr "" + +#: ldcref.c:239 +msgid "" +"\n" +"Cross Reference Table\n" +"\n" +msgstr "" + +#: ldcref.c:240 +msgid "Symbol" +msgstr "" + +#: ldcref.c:248 +msgid "File\n" +msgstr "" + +#: ldcref.c:252 +msgid "No symbols\n" +msgstr "" + +#: ldcref.c:369 +msgid "%P: symbol `%T' missing from main hash table\n" +msgstr "" + +#: ldcref.c:441 +msgid "%B%F: could not read symbols; %E\n" +msgstr "" + +#: ldcref.c:445 ldmain.c:1046 ldmain.c:1050 +msgid "%B%F: could not read symbols: %E\n" +msgstr "" + +#: ldcref.c:517 ldcref.c:524 ldmain.c:1096 ldmain.c:1103 +msgid "%B%F: could not read relocs: %E\n" +msgstr "" + +#. We found a reloc for the symbol. The symbol is defined +#. in OUTSECNAME. This reloc is from a section which is +#. mapped into a section from which references to OUTSECNAME +#. are prohibited. We must report an error. +#: ldcref.c:542 +msgid "%X%C: prohibited cross reference from %s to `%T' in %s\n" +msgstr "" + +#: ldctor.c:89 +msgid "%P%X: Different relocs used in set %s\n" +msgstr "" + +#: ldctor.c:106 +msgid "%P%X: Different object file formats composing set %s\n" +msgstr "" + +#: ldctor.c:288 ldctor.c:302 +msgid "%P%X: %s does not support reloc %s for set %s\n" +msgstr "" + +#: ldctor.c:323 +msgid "%P%X: Unsupported size %d for set %s\n" +msgstr "" + +#: ldctor.c:344 +msgid "" +"\n" +"Set Symbol\n" +"\n" +msgstr "" + +#: ldemul.c:223 +msgid "%S SYSLIB ignored\n" +msgstr "" + +#: ldemul.c:231 +msgid "%S HLL ignored\n" +msgstr "" + +#: ldemul.c:252 +msgid "%P: unrecognised emulation mode: %s\n" +msgstr "" + +#: ldemul.c:253 +msgid "Supported emulations: " +msgstr "" + +#: ldemul.c:297 +msgid " no emulation specific options.\n" +msgstr "" + +#: ldexp.c:156 +msgid "%F%P: %s uses undefined section %s\n" +msgstr "" + +#: ldexp.c:158 +msgid "%F%P: %s forward reference of section %s\n" +msgstr "" + +#: ldexp.c:270 +msgid "%F%S %% by zero\n" +msgstr "" + +#: ldexp.c:277 +msgid "%F%S / by zero\n" +msgstr "" + +#: ldexp.c:400 +msgid "%X%S: unresolvable symbol `%s' referenced in expression\n" +msgstr "" + +#: ldexp.c:419 +msgid "%F%S: undefined symbol `%s' referenced in expression\n" +msgstr "" + +#: ldexp.c:600 +msgid "%F%S can not PROVIDE assignment to location counter\n" +msgstr "" + +#: ldexp.c:610 +msgid "%F%S invalid assignment to location counter\n" +msgstr "" + +#: ldexp.c:614 +msgid "%F%S assignment to location counter invalid outside of SECTION\n" +msgstr "" + +#: ldexp.c:624 +msgid "%F%S cannot move location counter backwards (from %V to %V)\n" +msgstr "" + +#: ldexp.c:652 +msgid "%P%F:%s: hash creation failed\n" +msgstr "" + +#: ldexp.c:949 +msgid "%F%S nonconstant expression for %s\n" +msgstr "" + +#: ldexp.c:982 +msgid "%F%S non constant expression for %s\n" +msgstr "" + +#: ldfile.c:109 +#, c-format +msgid "attempt to open %s failed\n" +msgstr "" + +#: ldfile.c:111 +#, c-format +msgid "attempt to open %s succeeded\n" +msgstr "" + +#: ldfile.c:119 +msgid "%F%P: invalid BFD target `%s'\n" +msgstr "" + +#: ldfile.c:222 +msgid "%F%P: cannot open %s: %E\n" +msgstr "" + +#: ldfile.c:239 ldfile.c:254 +#, c-format +msgid "cannot find script file %s\n" +msgstr "" + +#: ldfile.c:241 ldfile.c:256 +#, c-format +msgid "opened script file %s\n" +msgstr "" + +#: ldfile.c:299 +msgid "%P%F: cannot open linker script file %s: %E\n" +msgstr "" + +#: ldfile.c:340 +msgid "%P%F: unknown architecture: %s\n" +msgstr "" + +#: ldfile.c:357 +msgid "%P%F: target architecture respecified\n" +msgstr "" + +#: ldfile.c:410 +msgid "%P%F: cannot represent machine `%s'\n" +msgstr "" + +#: ldlang.c:590 +msgid "" +"\n" +"Memory Configuration\n" +"\n" +msgstr "" + +#: ldlang.c:592 +msgid "Name" +msgstr "" + +#: ldlang.c:592 +msgid "Origin" +msgstr "" + +#: ldlang.c:592 +msgid "Length" +msgstr "" + +#: ldlang.c:592 +msgid "Attributes" +msgstr "" + +#: ldlang.c:634 +msgid "" +"\n" +"Linker script and memory map\n" +"\n" +msgstr "" + +#: ldlang.c:651 +msgid "%P%F: Illegal use of `%s' section" +msgstr "" + +#: ldlang.c:661 +msgid "%P%F: output format %s cannot represent section called %s\n" +msgstr "" + +#: ldlang.c:782 +msgid "%P: %B: warning: ignoring duplicate section `%s'\n" +msgstr "" + +#: ldlang.c:796 +msgid "%P: %B: warning: duplicate section `%s' has different size\n" +msgstr "" + +#: ldlang.c:1223 +msgid "%B: file not recognized: %E\n" +msgstr "" + +#: ldlang.c:1224 +msgid "%B: matching formats:" +msgstr "" + +#: ldlang.c:1231 +msgid "%F%B: file not recognized: %E\n" +msgstr "" + +#: ldlang.c:1284 +msgid "%F%B: object %B in archive is not object\n" +msgstr "" + +#: ldlang.c:1290 ldlang.c:1302 +msgid "%F%B: could not read symbols: %E\n" +msgstr "" + +#: ldlang.c:1418 +msgid "%P%F: target %s not found\n" +msgstr "" + +#: ldlang.c:1420 +msgid "%P%F: cannot open output file %s: %E\n" +msgstr "" + +#: ldlang.c:1428 +msgid "%P%F:%s: can not make object file: %E\n" +msgstr "" + +#: ldlang.c:1432 +msgid "%P%F:%s: can not set architecture: %E\n" +msgstr "" + +#: ldlang.c:1436 +msgid "%P%F: can not create link hash table: %E\n" +msgstr "" + +#: ldlang.c:1746 +msgid " load address 0x%V" +msgstr "" + +#: ldlang.c:1875 +msgid "%W (size before relaxing)\n" +msgstr "" + +#: ldlang.c:1954 +#, c-format +msgid "Address of section %s set to " +msgstr "" + +#: ldlang.c:2091 +#, c-format +msgid "Fail with %d\n" +msgstr "" + +#: ldlang.c:2320 +msgid "%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n" +msgstr "" + +#: ldlang.c:2372 +msgid "%P%X: Internal error on COFF shared library section %s\n" +msgstr "" + +#: ldlang.c:2413 +msgid "%P: warning: no memory region specified for section `%s'\n" +msgstr "" + +#: ldlang.c:2426 +msgid "%P: warning: changing start of section %s by %u bytes\n" +msgstr "" + +#: ldlang.c:2440 +msgid "%F%S: non constant address expression for section %s\n" +msgstr "" + +#: ldlang.c:2492 +msgid "%X%P: address 0x%v of %B section %s is not within region %s\n" +msgstr "" + +#: ldlang.c:2500 +msgid "%X%P: region %s is full (%B section %s)\n" +msgstr "" + +#: ldlang.c:2602 +msgid "%P%F: can't relax section: %E\n" +msgstr "" + +#: ldlang.c:2763 +msgid "%F%P: invalid data statement\n" +msgstr "" + +#: ldlang.c:2792 +msgid "%F%P: invalid reloc statement\n" +msgstr "" + +#: ldlang.c:2926 +msgid "%P%F:%s: can't set start address\n" +msgstr "" + +#: ldlang.c:2939 ldlang.c:2956 +msgid "%P%F: can't set start address\n" +msgstr "" + +#: ldlang.c:2951 +msgid "%P: warning: cannot find entry symbol %s; defaulting to %V\n" +msgstr "" + +#: ldlang.c:2961 +msgid "%P: warning: cannot find entry symbol %s; not setting start address\n" +msgstr "" + +#: ldlang.c:3003 +msgid "" +"%P: warning: %s architecture of input file `%B' is incompatible with %s " +"output\n" +msgstr "" + +#: ldlang.c:3021 +msgid "%E%X: failed to merge target specific data of file %B\n" +msgstr "" + +#: ldlang.c:3106 +msgid "" +"\n" +"Allocating common symbols\n" +msgstr "" + +#: ldlang.c:3107 +msgid "" +"Common symbol size file\n" +"\n" +msgstr "" + +#. This message happens when using the +#. svr3.ifile linker script, so I have +#. disabled it. +#: ldlang.c:3196 +msgid "%P: no [COMMON] command, defaulting to .bss\n" +msgstr "" + +#: ldlang.c:3259 +msgid "%P%F: invalid syntax in flags\n" +msgstr "" + +#: ldlang.c:3947 +msgid "%P%Fmultiple STARTUP files\n" +msgstr "" + +#: ldlang.c:4209 +msgid "%F%P: bfd_record_phdr failed: %E\n" +msgstr "" + +#: ldlang.c:4228 +msgid "%X%P: section `%s' assigned to non-existent phdr `%s'\n" +msgstr "" + +#: ldlang.c:4497 +msgid "%X%P: duplicate version tag `%s'\n" +msgstr "" + +#: ldlang.c:4510 ldlang.c:4523 +msgid "%X%P: duplicate expression `%s' in version information\n" +msgstr "" + +#: ldlang.c:4560 +msgid "%X%P: unable to find version dependency `%s'\n" +msgstr "" + +#: ldlang.c:4582 +msgid "%X%P: unable to read .exports section contents" +msgstr "" + +#: ldmain.c:188 +msgid "%X%P: can't set BFD default target to `%s': %E\n" +msgstr "" + +#: ldmain.c:245 +msgid "%P%F: --relax and -r may not be used together\n" +msgstr "" + +#: ldmain.c:247 +msgid "%P%F: -r and -shared may not be used together\n" +msgstr "" + +#: ldmain.c:276 +msgid "using internal linker script:\n" +msgstr "" + +#: ldmain.c:295 +msgid "%P%F: no input files\n" +msgstr "" + +#: ldmain.c:300 +msgid "%P: mode %s\n" +msgstr "" + +#: ldmain.c:318 +msgid "%P%F: cannot open map file %s: %E\n" +msgstr "" + +#: ldmain.c:364 +msgid "%P: link errors found, deleting executable `%s'\n" +msgstr "" + +#: ldmain.c:375 +msgid "%F%B: final close failed: %E\n" +msgstr "" + +#: ldmain.c:399 +msgid "%X%P: unable to open for source of copy `%s'\n" +msgstr "" + +#: ldmain.c:401 +msgid "%X%P: unable to open for destination of copy `%s'\n" +msgstr "" + +#: ldmain.c:407 +msgid "%P: Error writing file `%s'\n" +msgstr "" + +#: ldmain.c:413 pe-dll.c:899 +#, c-format +msgid "%P: Error closing file `%s'\n" +msgstr "" + +#: ldmain.c:431 +#, c-format +msgid "%s: total time in link: %ld.%06ld\n" +msgstr "" + +#: ldmain.c:434 +#, c-format +msgid "%s: data size %ld\n" +msgstr "" + +#: ldmain.c:475 +msgid "%P%F: missing argument to -m\n" +msgstr "" + +#: ldmain.c:589 ldmain.c:610 ldmain.c:641 +msgid "%P%F: bfd_hash_table_init failed: %E\n" +msgstr "" + +#: ldmain.c:594 ldmain.c:613 +msgid "%P%F: bfd_hash_lookup failed: %E\n" +msgstr "" + +#: ldmain.c:628 +msgid "%X%P: error: duplicate retain-symbols-file\n" +msgstr "" + +#: ldmain.c:672 +msgid "%P%F: bfd_hash_lookup for insertion failed: %E\n" +msgstr "" + +#: ldmain.c:677 +msgid "%P: `-retain-symbols-file' overrides `-s' and `-S'\n" +msgstr "" + +#: ldmain.c:754 +msgid "Archive member included" +msgstr "" + +#: ldmain.c:755 +msgid "because of file (symbol)" +msgstr "" + +#: ldmain.c:827 +msgid "%X%C: multiple definition of `%T'\n" +msgstr "" + +#: ldmain.c:830 +msgid "%D: first defined here\n" +msgstr "" + +#: ldmain.c:859 +msgid "%B: warning: definition of `%T' overriding common\n" +msgstr "" + +#: ldmain.c:862 +msgid "%B: warning: common is here\n" +msgstr "" + +#: ldmain.c:869 +msgid "%B: warning: common of `%T' overridden by definition\n" +msgstr "" + +#: ldmain.c:872 +msgid "%B: warning: defined here\n" +msgstr "" + +#: ldmain.c:879 +msgid "%B: warning: common of `%T' overridden by larger common\n" +msgstr "" + +#: ldmain.c:882 +msgid "%B: warning: larger common is here\n" +msgstr "" + +#: ldmain.c:886 +msgid "%B: warning: common of `%T' overriding smaller common\n" +msgstr "" + +#: ldmain.c:889 +msgid "%B: warning: smaller common is here\n" +msgstr "" + +#: ldmain.c:893 +msgid "%B: warning: multiple common of `%T'\n" +msgstr "" + +#: ldmain.c:895 +msgid "%B: warning: previous common is here\n" +msgstr "" + +#: ldmain.c:917 ldmain.c:956 +msgid "%P: warning: global constructor %s used\n" +msgstr "" + +#: ldmain.c:966 +msgid "%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n" +msgstr "" + +#: ldmain.c:1152 +msgid "%F%P: bfd_hash_table_init failed: %E\n" +msgstr "" + +#: ldmain.c:1159 +msgid "%F%P: bfd_hash_lookup failed: %E\n" +msgstr "" + +#: ldmain.c:1178 +msgid "%X%C: undefined reference to `%T'\n" +msgstr "" + +#: ldmain.c:1181 +msgid "%D: more undefined references to `%T' follow\n" +msgstr "" + +#: ldmain.c:1187 +msgid "%X%B: undefined reference to `%T'\n" +msgstr "" + +#: ldmain.c:1190 +msgid "%B: more undefined references to `%T' follow\n" +msgstr "" + +#: ldmain.c:1211 ldmain.c:1233 ldmain.c:1253 +msgid "%P%X: generated" +msgstr "" + +#: ldmain.c:1214 +msgid " relocation truncated to fit: %s %T" +msgstr "" + +#: ldmain.c:1236 +#, c-format +msgid "dangerous relocation: %s\n" +msgstr "" + +#: ldmain.c:1256 +msgid " reloc refers to symbol `%T' which is not being output\n" +msgstr "" + +#: ldmisc.c:177 +msgid "no symbol" +msgstr "" + +#: ldmisc.c:239 +#, c-format +msgid "built in linker script:%u" +msgstr "" + +#: ldmisc.c:289 ldmisc.c:293 +msgid "%B%F: could not read symbols\n" +msgstr "" + +#. We use abfd->filename in this initial line, +#. in case filename is a .h file or something +#. similarly unhelpful. +#: ldmisc.c:329 +msgid "%B: In function `%T':\n" +msgstr "" + +#: ldmisc.c:461 +msgid "%F%P: internal error %s %d\n" +msgstr "" + +#: ldver.c:35 +#, c-format +msgid "GNU ld version %s (with BFD %s)\n" +msgstr "" + +#: ldver.c:42 lexsup.c:829 +msgid " Supported emulations:\n" +msgstr "" + +#: ldwrite.c:59 ldwrite.c:195 +msgid "%P%F: bfd_new_link_order failed\n" +msgstr "" + +#: ldwrite.c:365 +#, c-format +msgid "%8x something else\n" +msgstr "" + +#: ldwrite.c:526 +msgid "%F%P: final link failed: %E\n" +msgstr "" + +#: lexsup.c:148 lexsup.c:231 lexsup.c:237 +msgid "KEYWORD" +msgstr "" + +#: lexsup.c:148 +msgid "Shared library control for HP/UX compatibility" +msgstr "" + +#: lexsup.c:151 +msgid "ARCH" +msgstr "" + +#: lexsup.c:151 +msgid "Set architecture" +msgstr "" + +#: lexsup.c:153 lexsup.c:290 +msgid "TARGET" +msgstr "" + +#: lexsup.c:153 +msgid "Specify target for following input files" +msgstr "" + +#: lexsup.c:155 lexsup.c:194 lexsup.c:204 lexsup.c:213 lexsup.c:278 +#: lexsup.c:297 lexsup.c:331 +msgid "FILE" +msgstr "" + +#: lexsup.c:155 +msgid "Read MRI format linker script" +msgstr "" + +#: lexsup.c:157 +msgid "Force common symbols to be defined" +msgstr "" + +#: lexsup.c:161 lexsup.c:321 lexsup.c:323 lexsup.c:325 +msgid "ADDRESS" +msgstr "" + +#: lexsup.c:161 +msgid "Set start address" +msgstr "" + +#: lexsup.c:163 +msgid "Export all dynamic symbols" +msgstr "" + +#: lexsup.c:165 +msgid "Link big-endian objects" +msgstr "" + +#: lexsup.c:167 +msgid "Link little-endian objects" +msgstr "" + +#: lexsup.c:169 lexsup.c:172 +msgid "SHLIB" +msgstr "" + +#: lexsup.c:169 +msgid "Auxiliary filter for shared object symbol table" +msgstr "" + +#: lexsup.c:172 +msgid "Filter for shared object symbol table" +msgstr "" + +#: lexsup.c:174 +msgid "Ignored" +msgstr "" + +#: lexsup.c:176 +msgid "SIZE" +msgstr "" + +#: lexsup.c:176 +msgid "Small data size (if no size, same as --shared)" +msgstr "" + +#: lexsup.c:179 +msgid "FILENAME" +msgstr "" + +#: lexsup.c:179 +msgid "Set internal name of shared library" +msgstr "" + +#: lexsup.c:181 +msgid "LIBNAME" +msgstr "" + +#: lexsup.c:181 +msgid "Search for library LIBNAME" +msgstr "" + +#: lexsup.c:183 +msgid "DIRECTORY" +msgstr "" + +#: lexsup.c:183 +msgid "Add DIRECTORY to library search path" +msgstr "" + +#: lexsup.c:185 +msgid "EMULATION" +msgstr "" + +#: lexsup.c:185 +msgid "Set emulation" +msgstr "" + +#: lexsup.c:187 +msgid "Print map file on standard output" +msgstr "" + +#: lexsup.c:189 +msgid "Do not page align data" +msgstr "" + +#: lexsup.c:191 +msgid "Do not page align data, do not make text readonly" +msgstr "" + +#: lexsup.c:194 +msgid "Set output file name" +msgstr "" + +#: lexsup.c:196 +msgid "Optimize output file" +msgstr "" + +#: lexsup.c:198 +msgid "Ignored for SVR4 compatibility" +msgstr "" + +#: lexsup.c:200 +msgid "Generate relocateable output" +msgstr "" + +#: lexsup.c:204 +msgid "Just link symbols (if directory, same as --rpath)" +msgstr "" + +#: lexsup.c:207 +msgid "Strip all symbols" +msgstr "" + +#: lexsup.c:209 +msgid "Strip debugging symbols" +msgstr "" + +#: lexsup.c:211 +msgid "Trace file opens" +msgstr "" + +#: lexsup.c:213 +msgid "Read linker script" +msgstr "" + +#: lexsup.c:215 lexsup.c:227 lexsup.c:317 lexsup.c:334 lexsup.c:351 +msgid "SYMBOL" +msgstr "" + +#: lexsup.c:215 +msgid "Start with undefined reference to SYMBOL" +msgstr "" + +#: lexsup.c:217 +msgid "Build global constructor/destructor tables" +msgstr "" + +#: lexsup.c:219 +msgid "Print version information" +msgstr "" + +#: lexsup.c:221 +msgid "Print version and emulation information" +msgstr "" + +#: lexsup.c:223 +msgid "Discard all local symbols" +msgstr "" + +#: lexsup.c:225 +msgid "Discard temporary local symbols" +msgstr "" + +#: lexsup.c:227 +msgid "Trace mentions of SYMBOL" +msgstr "" + +#: lexsup.c:229 lexsup.c:299 lexsup.c:301 +msgid "PATH" +msgstr "" + +#: lexsup.c:229 +msgid "Default search path for Solaris compatibility" +msgstr "" + +#: lexsup.c:231 +msgid "Ignored for Solaris compatibility" +msgstr "" + +#: lexsup.c:233 +msgid "Start a group" +msgstr "" + +#: lexsup.c:235 +msgid "End a group" +msgstr "" + +#: lexsup.c:237 +msgid "Ignored for SunOS compatibility" +msgstr "" + +#: lexsup.c:239 +msgid "Link against shared libraries" +msgstr "" + +#: lexsup.c:245 +msgid "Do not link against shared libraries" +msgstr "" + +#: lexsup.c:253 +msgid "Bind global references locally" +msgstr "" + +#: lexsup.c:255 +msgid "Check section addresses for overlaps (default)" +msgstr "" + +#: lexsup.c:257 +msgid "Do not check section addresses for overlaps" +msgstr "" + +#: lexsup.c:260 +msgid "Output cross reference table" +msgstr "" + +#: lexsup.c:262 +msgid "SYMBOL=EXPRESSION" +msgstr "" + +#: lexsup.c:262 +msgid "Define a symbol" +msgstr "" + +#: lexsup.c:264 +msgid "PROGRAM" +msgstr "" + +#: lexsup.c:264 +msgid "Set the dynamic linker to use" +msgstr "" + +#: lexsup.c:266 +msgid "Generate embedded relocs" +msgstr "" + +#: lexsup.c:268 +msgid "Force generation of file with .exe suffix" +msgstr "" + +#: lexsup.c:270 +msgid "Remove unused sections (on some targets)" +msgstr "" + +#: lexsup.c:273 +msgid "Don't remove unused sections (default)" +msgstr "" + +#: lexsup.c:276 +msgid "Print option help" +msgstr "" + +#: lexsup.c:278 +msgid "Write a map file" +msgstr "" + +#: lexsup.c:280 +msgid "Use less memory and more disk I/O" +msgstr "" + +#: lexsup.c:282 +msgid "Don't warn about mismatched input files" +msgstr "" + +#: lexsup.c:284 +msgid "Turn off --whole-archive" +msgstr "" + +#: lexsup.c:286 +msgid "Create an output file even if errors occur" +msgstr "" + +#: lexsup.c:290 +msgid "Specify target of output file" +msgstr "" + +#: lexsup.c:292 +msgid "Ignored for Linux compatibility" +msgstr "" + +#: lexsup.c:294 +msgid "Relax branches on certain targets" +msgstr "" + +#: lexsup.c:297 +msgid "Keep only symbols listed in FILE" +msgstr "" + +#: lexsup.c:299 +msgid "Set runtime shared library search path" +msgstr "" + +#: lexsup.c:301 +msgid "Set link time shared library search path" +msgstr "" + +#: lexsup.c:303 +msgid "Create a shared library" +msgstr "" + +#: lexsup.c:307 +msgid "Sort common symbols by size" +msgstr "" + +#: lexsup.c:311 +msgid "Split output sections for each file" +msgstr "" + +#: lexsup.c:313 +msgid "COUNT" +msgstr "" + +#: lexsup.c:313 +msgid "Split output sections every COUNT relocs" +msgstr "" + +#: lexsup.c:315 +msgid "Print memory usage statistics" +msgstr "" + +#: lexsup.c:317 +msgid "Do task level linking" +msgstr "" + +#: lexsup.c:319 +msgid "Use same format as native linker" +msgstr "" + +#: lexsup.c:321 +msgid "Set address of .bss section" +msgstr "" + +#: lexsup.c:323 +msgid "Set address of .data section" +msgstr "" + +#: lexsup.c:325 +msgid "Set address of .text section" +msgstr "" + +#: lexsup.c:327 +msgid "Output lots of information during link" +msgstr "" + +#: lexsup.c:331 +msgid "Read version information script" +msgstr "" + +#: lexsup.c:334 +msgid "Take export symbols list from .exports, using SYMBOL as the version." +msgstr "" + +#: lexsup.c:337 +msgid "Warn about duplicate common symbols" +msgstr "" + +#: lexsup.c:339 +msgid "Warn if global constructors/destructors are seen" +msgstr "" + +#: lexsup.c:342 +msgid "Warn if the multiple GP values are used" +msgstr "" + +#: lexsup.c:344 +msgid "Warn only once per undefined symbol" +msgstr "" + +#: lexsup.c:346 +msgid "Warn if start of section changes due to alignment" +msgstr "" + +#: lexsup.c:349 +msgid "Include all objects from following archives" +msgstr "" + +#: lexsup.c:351 +msgid "Use wrapper functions for SYMBOL" +msgstr "" + +#: lexsup.c:491 +msgid "%P%F: unrecognized -a option `%s'\n" +msgstr "" + +#: lexsup.c:504 +msgid "%P%F: unrecognized -assert option `%s'\n" +msgstr "" + +#: lexsup.c:592 +msgid "%P%F: invalid number `%s'\n" +msgstr "" + +#: lexsup.c:758 +msgid "%P%F: -shared not supported\n" +msgstr "" + +#: lexsup.c:822 +msgid "Copyright 1997 Free Software Foundation, Inc.\n" +msgstr "" + +#: lexsup.c:823 +msgid "" +"This program is free software; you may redistribute it under the terms of\n" +"the GNU General Public License. This program has absolutely no warranty.\n" +msgstr "" + +#: lexsup.c:914 +#, c-format +msgid "%s: may not nest groups (--help for usage)\n" +msgstr "" + +#: lexsup.c:925 +#, c-format +msgid "%s: group ended before it began (--help for usage)\n" +msgstr "" + +#: lexsup.c:973 +msgid "%P%F: invalid hex number `%s'\n" +msgstr "" + +#: lexsup.c:985 +#, c-format +msgid "Usage: %s [options] file...\n" +msgstr "" + +#: lexsup.c:987 +msgid "Options:\n" +msgstr "" + +#: lexsup.c:1064 +#, c-format +msgid "%s: supported targets:" +msgstr "" + +#: lexsup.c:1072 +#, c-format +msgid "%s: supported emulations: " +msgstr "" + +#: lexsup.c:1077 +#, c-format +msgid "%s: emulation specific options:\n" +msgstr "" + +#: lexsup.c:1081 +msgid "" +"\n" +"Report bugs to bug-gnu-utils@gnu.org\n" +msgstr "" + +#: mri.c:342 +msgid "%P%F: unknown format type %s\n" +msgstr "" + +#: pe-dll.c:294 +#, c-format +msgid "%XError, duplicate EXPORT with oridinals: %s (%d vs %d)\n" +msgstr "" + +#: pe-dll.c:300 +#, c-format +msgid "Warning, duplicate EXPORT: %s\n" +msgstr "" + +#: pe-dll.c:348 +#, c-format +msgid "%XCannot export %s: symbol not defined\n" +msgstr "" + +#: pe-dll.c:354 +#, c-format +msgid "%XCannot export %s: symbol wrong type (%d vs %d)\n" +msgstr "" + +#: pe-dll.c:361 +#, c-format +msgid "%XCannot export %s: symbol not found\n" +msgstr "" + +#: pe-dll.c:482 +#, c-format +msgid "%XError, oridinal used twice: %d (%s vs %s)\n" +msgstr "" + +#: pe-dll.c:664 +#, c-format +msgid "%XError: %d-bit reloc in dll\n" +msgstr "" + +#: pe-dll.c:773 +#, c-format +msgid "%s: Can't open output def file %s\n" +msgstr "" + +#: pe-dll.c:894 +msgid "; no contents available\n" +msgstr "" + +#: pe-dll.c:1326 +#, c-format +msgid "%XCan't open .lib file: %s\n" +msgstr "" + +#: pe-dll.c:1331 +#, c-format +msgid "Creating library file: %s\n" +msgstr "" diff --git a/ld/scripttempl/README b/ld/scripttempl/README new file mode 100644 index 0000000..26ad2e9 --- /dev/null +++ b/ld/scripttempl/README @@ -0,0 +1,4 @@ +The files in this directory are linker script templates. +genscripts.sh sets some shell variables, then sources +EMULATION.sc, to generate EMULATION.{x,xr,xu,xn,xbn} -- the script +files for default, -r, -Ur, -n, -N. diff --git a/ld/scripttempl/a29k.sc b/ld/scripttempl/a29k.sc new file mode 100644 index 0000000..2825b1e --- /dev/null +++ b/ld/scripttempl/a29k.sc @@ -0,0 +1,37 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +SECTIONS +{ + .text : { + *(.text) + ${RELOCATING+ __etext = .}; + ${CONSTRUCTING+ __CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __CTOR_END__ = .;} + ${CONSTRUCTING+ __DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __DTOR_END__ = .;} + *(.lit) + *(.shdata) + } + .shbss SIZEOF(.text) + ADDR(.text) : { + *(.shbss) + } + .data : { + *(.data) + ${RELOCATING+ __edata = .}; + } + .bss SIZEOF(.data) + ADDR(.data) : + { + *(.bss) + *(COMMON) + ${RELOCATING+ __end = ALIGN(0x8)}; + } +} +EOF diff --git a/ld/scripttempl/aix.sc b/ld/scripttempl/aix.sc new file mode 100644 index 0000000..3f4b617 --- /dev/null +++ b/ld/scripttempl/aix.sc @@ -0,0 +1,55 @@ +# AIX linker script. +# AIX always uses shared libraries. The section VMA appears to be +# unimportant. The native linker aligns the sections on boundaries +# specified by the -H option. +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) +${RELOCATING+${LIB_SEARCH_DIRS}} +ENTRY(__start) +SECTIONS +{ + .pad 0 : { *(.pad) } + .text ${RELOCATING-0} : { + ${RELOCATING+PROVIDE (_text = .);} + *(.text) + *(.pr) + *(.ro) + *(.db) + *(.gl) + *(.xo) + *(.ti) + *(.tb) + ${RELOCATING+PROVIDE (_etext = .);} + } + .data 0 : { + ${RELOCATING+PROVIDE (_data = .);} + *(.data) + *(.rw) + *(.sv) + *(.ua) + . = ALIGN(4); + ${CONSTRUCTING+CONSTRUCTORS} + *(.ds) + *(.tc0) + *(.tc) + *(.td) + ${RELOCATING+PROVIDE (_edata = .);} + } + .bss : { + *(.tocbss) + *(.bss) + *(.bs) + *(.uc) + *(COMMON) + ${RELOCATING+PROVIDE (_end = .);} + ${RELOCATING+PROVIDE (end = .);} + } + .loader 0 : { + *(.loader) + } + .debug 0 : { + *(.debug) + } +} +EOF diff --git a/ld/scripttempl/alpha.sc b/ld/scripttempl/alpha.sc new file mode 100644 index 0000000..44a10c4 --- /dev/null +++ b/ld/scripttempl/alpha.sc @@ -0,0 +1,74 @@ +# Linker script for Alpha systems. +# Ian Lance Taylor <ian@cygnus.com>. +# These variables may be overridden by the emulation file. The +# defaults are appropriate for an Alpha running OSF/1. +test -z "$ENTRY" && ENTRY=__start +test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x120000000 + SIZEOF_HEADERS" +if test "x$LD_FLAG" = "xn" -o "x$LD_FLAG" = "xN"; then + DATA_ADDR=. +else + test -z "$DATA_ADDR" && DATA_ADDR=0x140000000 +fi +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + ${RELOCATING+. = ${TEXT_START_ADDR};} + .text : { + ${RELOCATING+ _ftext = . }; + ${RELOCATING+ __istart = . }; + ${RELOCATING+ *(.init) } + ${RELOCATING+ LONG (0x6bfa8001)} + ${RELOCATING+ eprol = .}; + *(.text) + ${RELOCATING+ __fstart = . }; + ${RELOCATING+ *(.fini)} + ${RELOCATING+ LONG (0x6bfa8001)} + ${RELOCATING+ _etext = .}; + } + .rdata : { + *(.rdata) + } + .rconst : { + *(.rconst) + } + .pdata : { + ${RELOCATING+ _fpdata = .;} + *(.pdata) + } + ${RELOCATING+. = ${DATA_ADDR};} + .data : { + ${RELOCATING+ _fdata = .;} + *(.data) + ${CONSTRUCTING+CONSTRUCTORS} + } + .xdata : { + *(.xdata) + } + ${RELOCATING+ _gp = ALIGN (16) + 0x8000;} + .lit8 : { + *(.lit8) + } + .lita : { + *(.lita) + } + .sdata : { + *(.sdata) + } + ${RELOCATING+ _EDATA = .;} + ${RELOCATING+ _FBSS = .;} + .sbss : { + *(.sbss) + *(.scommon) + } + .bss : { + *(.bss) + *(COMMON) + } + ${RELOCATING+ _end = .;} +} +EOF diff --git a/ld/scripttempl/aout.sc b/ld/scripttempl/aout.sc new file mode 100644 index 0000000..80dbb37 --- /dev/null +++ b/ld/scripttempl/aout.sc @@ -0,0 +1,57 @@ +test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${ALIGNMENT}" && ALIGNMENT="4" + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", + "${LITTLE_OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +${STACKZERO+${RELOCATING+${STACKZERO}}} +${SHLIB_PATH+${RELOCATING+${SHLIB_PATH}}} +${RELOCATING+${EXECUTABLE_SYMBOLS}} +${RELOCATING+PROVIDE (__stack = 0);} +SECTIONS +{ + ${RELOCATING+. = ${TEXT_START_ADDR};} + .text : + { + CREATE_OBJECT_SYMBOLS + *(.text) + /* The next six sections are for SunOS dynamic linking. The order + is important. */ + *(.dynrel) + *(.hash) + *(.dynsym) + *(.dynstr) + *(.rules) + *(.need) + ${RELOCATING+_etext = .;} + ${RELOCATING+__etext = .;} + ${PAD_TEXT+${RELOCATING+. = ${DATA_ALIGNMENT};}} + } + ${RELOCATING+. = ${DATA_ALIGNMENT};} + .data : + { + /* The first three sections are for SunOS dynamic linking. */ + *(.dynamic) + *(.got) + *(.plt) + *(.data) + *(.linux-dynamic) /* For Linux dynamic linking. */ + ${CONSTRUCTING+CONSTRUCTORS} + ${RELOCATING+_edata = .;} + ${RELOCATING+__edata = .;} + } + .bss : + { + ${RELOCATING+ __bss_start = .}; + *(.bss) + *(COMMON) + ${RELOCATING+. = ALIGN(${ALIGNMENT});} + ${RELOCATING+_end = . }; + ${RELOCATING+__end = . }; + } +} +EOF diff --git a/ld/scripttempl/armaout.sc b/ld/scripttempl/armaout.sc new file mode 100644 index 0000000..e9276a8 --- /dev/null +++ b/ld/scripttempl/armaout.sc @@ -0,0 +1,35 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +${STACKZERO+${RELOCATING+${STACKZERO}}} +SECTIONS +{ + .text ${RELOCATING+${TEXT_START_ADDR}} : + { + CREATE_OBJECT_SYMBOLS + ${RELOCATING+__stext_ = .;} + *(.text) + ${PAD_TEXT+${RELOCATING+. = ${DATA_ALIGNMENT};}} + ${RELOCATING+_etext = ${DATA_ALIGNMENT};} + ${RELOCATING+__etext = ${DATA_ALIGNMENT};} + } + .data ${RELOCATING+${DATA_ALIGNMENT}} : + { + ${RELOCATING+__sdata_ = .;} + *(.data) + ${CONSTRUCTING+CONSTRUCTORS} + ${RELOCATING+_edata = .;} + ${RELOCATING+__edata = .;} + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR (.data)} : + { + ${RELOCATING+ __bss_start = .}; + *(.bss) + *(COMMON) + ${RELOCATING+_end = ALIGN(4) }; + ${RELOCATING+__end = ALIGN(4) }; + } +} +EOF diff --git a/ld/scripttempl/armcoff.sc b/ld/scripttempl/armcoff.sc new file mode 100644 index 0000000..8e07169 --- /dev/null +++ b/ld/scripttempl/armcoff.sc @@ -0,0 +1,62 @@ +# Linker script for ARM COFF. +# Based on i386coff.sc by Ian Taylor <ian@cygnus.com>. +test -z "$ENTRY" && ENTRY=_start +if test -z "${DATA_ADDR}"; then + if test "$LD_FLAG" = "N" || test "$LD_FLAG" = "n"; then + DATA_ADDR=. + fi +fi +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + /* We start at 0x8000 because gdb assumes it (see FRAME_CHAIN). + This is an artifact of the ARM Demon monitor using the bottom 32k + as workspace (shared with the FP instruction emulator if + present): */ + .text ${RELOCATING+ 0x8000} : { + *(.init) + *(.text) + *(.glue_7t) + *(.glue_7) + *(.rdata) + ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1); *(.ctors); *(.ctor); LONG (0); } + ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); LONG (0); } + *(.fini) + ${RELOCATING+ etext = .;} + } + .data ${RELOCATING+${DATA_ADDR-0x40000 + (. & 0xfffc0fff)}} : { + ${RELOCATING+ __data_start__ = . ;} + *(.data) + ${RELOCATING+ __data_end__ = . ;} + ${RELOCATING+ edata = .;} + ${RELOCATING+ _edata = .;} + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + ${RELOCATING+ __bss_start__ = . ;} + *(.bss) + *(COMMON) + ${RELOCATING+ __bss_end__ = . ;} + } + + ${RELOCATING+ end = .;} + ${RELOCATING+ _end = .;} + ${RELOCATING+ __end__ = .;} + + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/delta68.sc b/ld/scripttempl/delta68.sc new file mode 100644 index 0000000..d996305 --- /dev/null +++ b/ld/scripttempl/delta68.sc @@ -0,0 +1,49 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) +ENTRY(_start) +${RELOCATING+${LIB_SEARCH_DIRS}} + +SECTIONS +{ + .text ${RELOCATING+ 0x2000 + SIZEOF_HEADERS} : + { + ${RELOCATING+ __.text.start = .}; + *(.text) + ${RELOCATING+ etext = .;} + ${RELOCATING+ _etext = .;} + ${RELOCATING+ __.text.end = .}; + ${CONSTRUCTING+ __CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __CTOR_END__ = .;} + ${CONSTRUCTING+ __DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __DTOR_END__ = .;} + } + .data ${RELOCATING+ SIZEOF(.text) + ADDR(.text) + 0x400000} : + { + ${RELOCATING+ __.data.start = .}; + *(.data) + ${RELOCATING+ edata = .}; + ${RELOCATING+ _edata = .}; + ${RELOCATING+ __.data.end = .}; + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + ${RELOCATING+ __.bss.start = .}; + *(.bss) + *(COMMON) + ${RELOCATING+ __.bss.end = .}; + ${RELOCATING+ end = ALIGN(0x8)}; + ${RELOCATING+ _end = ALIGN(0x8)}; + } + .comment ${RELOCATING+ 0} : + { + *(.comment) + } +} +EOF diff --git a/ld/scripttempl/ebmon29k.sc b/ld/scripttempl/ebmon29k.sc new file mode 100644 index 0000000..62050ee --- /dev/null +++ b/ld/scripttempl/ebmon29k.sc @@ -0,0 +1,27 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +ENTRY(start) + +SECTIONS { + .text ${RELOCATING+${TEXT_START_ADDR}} : + { + *(.text); + ${RELOCATING+_etext = .}; + } + data ${RELOCATING+0x80002000} : + { + *(.data); + *(.mstack); + *(.shbss); + *(.rstack); + *(.mstack); + ${CONSTRUCTING+CONSTRUCTORS} + } + .bss . : + { + *(COMMON) + *(.bss); + ${RELOCATING+_end = .}; + } +} +EOF diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc new file mode 100644 index 0000000..e1fea97 --- /dev/null +++ b/ld/scripttempl/elf.sc @@ -0,0 +1,286 @@ +# +# Unusual variables checked by this code: +# NOP - two byte opcode for no-op (defaults to 0) +# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start +# INITIAL_READONLY_SECTIONS - at start of text segment +# OTHER_READONLY_SECTIONS - other than .text .init .rodata ... +# (e.g., .PARISC.milli) +# OTHER_TEXT_SECTIONS - these get put in .text when relocating +# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ... +# (e.g., .PARISC.global) +# OTHER_SECTIONS - at the end +# EXECUTABLE_SYMBOLS - symbols that must be defined for an +# executable (e.g., _DYNAMIC_LINK) +# TEXT_START_SYMBOLS - symbols that appear at the start of the +# .text section. +# DATA_START_SYMBOLS - symbols that appear at the start of the +# .data section. +# OTHER_GOT_SYMBOLS - symbols defined just before .got. +# OTHER_GOT_SECTIONS - sections just after .got and .sdata. +# OTHER_BSS_SYMBOLS - symbols that appear at the start of the +# .bss section besides __bss_start. +# DATA_PLT - .plt should be in data segment, not text segment. +# TEXT_DYNAMIC - .dynamic in text segment, not data segment. +# EMBEDDED - whether this is for an embedded system. +# SHLIB_TEXT_START_ADDR - if set, add to SIZEOF_HEADERS to set +# start address of shared library. +# INPUT_FILES - INPUT command of files to always include +# +# When adding sections, do note that the names of some sections are used +# when specifying the start address of the next. +# + +test -z "$ENTRY" && ENTRY=_start +test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi +test -z "${ELFSIZE}" && ELFSIZE=32 +test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8" +test "$LD_FLAG" = "N" && DATA_ADDR=. +INTERP=".interp ${RELOCATING-0} : { *(.interp) }" +PLT=".plt ${RELOCATING-0} : { *(.plt) }" +DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }" + +CTOR=".ctors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+${CTOR_START}} + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + + KEEP (*crtbegin.o(.ctors)) + + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + ${CONSTRUCTING+${CTOR_END}} + }" + +DTOR=" .dtors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+${DTOR_START}} + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + ${CONSTRUCTING+${DTOR_END}} + }" + +# if this is for an embedded system, don't add SIZEOF_HEADERS. +if [ -z "$EMBEDDED" ]; then + test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR} + SIZEOF_HEADERS" +else + test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}" +fi + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", + "${LITTLE_OUTPUT_FORMAT}") +OUTPUT_ARCH(${OUTPUT_ARCH}) +ENTRY(${ENTRY}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +${RELOCATING+/* Do we need any of these for elf? + __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */} +${RELOCATING+${EXECUTABLE_SYMBOLS}} +${RELOCATING+${INPUT_FILES}} +${RELOCATING- /* For some reason, the Solaris linker makes bad executables + if gld -r is used and the intermediate file has sections starting + at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld + bug. But for now assigning the zero vmas works. */} + +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_BASE_ADDRESS};}} + ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}} + ${CREATE_SHLIB-${INTERP}} + ${INITIAL_READONLY_SECTIONS} + ${TEXT_DYNAMIC+${DYNAMIC}} + .hash ${RELOCATING-0} : { *(.hash) } + .dynsym ${RELOCATING-0} : { *(.dynsym) } + .dynstr ${RELOCATING-0} : { *(.dynstr) } + .gnu.version ${RELOCATING-0} : { *(.gnu.version) } + .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) } + .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) } + .rel.text ${RELOCATING-0} : + { + *(.rel.text) + ${RELOCATING+*(.rel.text.*)} + ${RELOCATING+*(.rel.gnu.linkonce.t*)} + } + .rela.text ${RELOCATING-0} : + { + *(.rela.text) + ${RELOCATING+*(.rela.text.*)} + ${RELOCATING+*(.rela.gnu.linkonce.t*)} + } + .rel.data ${RELOCATING-0} : + { + *(.rel.data) + ${RELOCATING+*(.rel.data.*)} + ${RELOCATING+*(.rel.gnu.linkonce.d*)} + } + .rela.data ${RELOCATING-0} : + { + *(.rela.data) + ${RELOCATING+*(.rela.data.*)} + ${RELOCATING+*(.rela.gnu.linkonce.d*)} + } + .rel.rodata ${RELOCATING-0} : + { + *(.rel.rodata) + ${RELOCATING+*(.rel.rodata.*)} + ${RELOCATING+*(.rel.gnu.linkonce.r*)} + } + .rela.rodata ${RELOCATING-0} : + { + *(.rela.rodata) + ${RELOCATING+*(.rela.rodata.*)} + ${RELOCATING+*(.rela.gnu.linkonce.r*)} + } + .rel.got ${RELOCATING-0} : { *(.rel.got) } + .rela.got ${RELOCATING-0} : { *(.rela.got) } + .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } + .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } + .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } + .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } + .rel.init ${RELOCATING-0} : { *(.rel.init) } + .rela.init ${RELOCATING-0} : { *(.rela.init) } + .rel.fini ${RELOCATING-0} : { *(.rel.fini) } + .rela.fini ${RELOCATING-0} : { *(.rela.fini) } + .rel.bss ${RELOCATING-0} : { *(.rel.bss) } + .rela.bss ${RELOCATING-0} : { *(.rela.bss) } + .rel.plt ${RELOCATING-0} : { *(.rel.plt) } + .rela.plt ${RELOCATING-0} : { *(.rela.plt) } + .init ${RELOCATING-0} : { KEEP (*(.init)) } =${NOP-0} + ${DATA_PLT-${PLT}} + .text ${RELOCATING-0} : + { + ${RELOCATING+${TEXT_START_SYMBOLS}} + *(.text) + ${RELOCATING+*(.text.*)} + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + ${RELOCATING+*(.gnu.linkonce.t*)} + ${RELOCATING+${OTHER_TEXT_SECTIONS}} + } =${NOP-0} + ${RELOCATING+_etext = .;} + ${RELOCATING+PROVIDE (etext = .);} + .fini ${RELOCATING-0} : { KEEP (*(.fini)) } =${NOP-0} + .rodata ${RELOCATING-0} : + { + *(.rodata) + ${RELOCATING+*(.rodata.*)} + ${RELOCATING+*(.gnu.linkonce.r*)} + } + .rodata1 ${RELOCATING-0} : { *(.rodata1) } + ${RELOCATING+${OTHER_READONLY_SECTIONS}} + + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + ${CREATE_SHLIB-${RELOCATING+. = ${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))};}} + ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))};}} + + .data ${RELOCATING-0} : + { + ${RELOCATING+${DATA_START_SYMBOLS}} + *(.data) + ${RELOCATING+*(.data.*)} + ${RELOCATING+*(.gnu.linkonce.d*)} + ${CONSTRUCTING+SORT(CONSTRUCTORS)} + } + .data1 ${RELOCATING-0} : { *(.data1) } + .eh_frame : { *(.eh_frame) } + .gcc_except_table : { *(.gcc_except_table) } + ${RELOCATING+${OTHER_READWRITE_SECTIONS}} + ${RELOCATING+${CTOR}} + ${RELOCATING+${DTOR}} + ${DATA_PLT+${PLT}} + ${RELOCATING+${OTHER_GOT_SYMBOLS}} + .got ${RELOCATING-0} : { *(.got.plt) *(.got) } + ${TEXT_DYNAMIC-${DYNAMIC}} + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata ${RELOCATING-0} : { *(.sdata) *(.sdata.*) } + ${RELOCATING+${OTHER_GOT_SECTIONS}} + ${RELOCATING+_edata = .;} + ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+__bss_start = .;} + ${RELOCATING+${OTHER_BSS_SYMBOLS}} + .sbss ${RELOCATING-0} : { *(.sbss) *(.scommon) } + .bss ${RELOCATING-0} : + { + *(.dynbss) + *(.bss) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + ${RELOCATING+. = ALIGN(${ALIGNMENT});} + } + ${RELOCATING+. = ALIGN(${ALIGNMENT});} + ${RELOCATING+_end = . ;} + ${RELOCATING+${OTHER_BSS_END_SYMBOLS}} + ${RELOCATING+PROVIDE (end = .);} + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + + .comment 0 : { *(.comment) } + + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + ${RELOCATING+${OTHER_RELOCATING_SECTIONS}} + + /* These must appear regardless of ${RELOCATING}. */ + ${OTHER_SECTIONS} +} +EOF diff --git a/ld/scripttempl/elfd10v.sc b/ld/scripttempl/elfd10v.sc new file mode 100644 index 0000000..322eef4 --- /dev/null +++ b/ld/scripttempl/elfd10v.sc @@ -0,0 +1,226 @@ +# +# Unusual variables checked by this code: +# NOP - two byte opcode for no-op (defaults to 0) +# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start +# OTHER_READONLY_SECTIONS - other than .text .init .rodata ... +# (e.g., .PARISC.milli) +# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ... +# (e.g., .PARISC.global) +# OTHER_SECTIONS - at the end +# EXECUTABLE_SYMBOLS - symbols that must be defined for an +# executable (e.g., _DYNAMIC_LINK) +# TEXT_START_SYMBOLS - symbols that appear at the start of the +# .text section. +# DATA_START_SYMBOLS - symbols that appear at the start of the +# .data section. +# OTHER_BSS_SYMBOLS - symbols that appear at the start of the +# .bss section besides __bss_start. +# DATA_PLT - .plt should be in data segment, not text segment. +# EMBEDDED - whether this is for an embedded system. +# +# When adding sections, do note that the names of some sections are used +# when specifying the start address of the next. +# +test -z "$ENTRY" && ENTRY=_start +test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi +test "$LD_FLAG" = "N" && DATA_ADDR=. +INTERP=".interp ${RELOCATING-0} : { *(.interp) }" +PLT=".plt ${RELOCATING-0} : { *(.plt) }" + + +CTOR=".ctors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+${CTOR_START}} + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + + KEEP (*crtbegin.o(.ctors)) + + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + ${CONSTRUCTING+${CTOR_END}} + }" + +DTOR=" .dtors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+${DTOR_START}} + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + ${CONSTRUCTING+${DTOR_END}} + }" + + +# if this is for an embedded system, don't add SIZEOF_HEADERS. +if [ -z "$EMBEDDED" ]; then + test -z "${READONLY_BASE_ADDRESS}" && READONLY_BASE_ADDRESS="${READONLY_START_ADDR} + SIZEOF_HEADERS" +else + test -z "${READONLY_BASE_ADDRESS}" && READONLY_BASE_ADDRESS="${READONLY_START_ADDR}" +fi + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", + "${LITTLE_OUTPUT_FORMAT}") +OUTPUT_ARCH(${OUTPUT_ARCH}) +ENTRY(${ENTRY}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +${RELOCATING+/* Do we need any of these for elf? + __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */} +${RELOCATING+${EXECUTABLE_SYMBOLS}} +${RELOCATING- /* For some reason, the Solaris linker makes bad executables + if gld -r is used and the intermediate file has sections starting + at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld + bug. But for now assigning the zero vmas works. */} +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + ${CREATE_SHLIB-${RELOCATING+. = ${READONLY_BASE_ADDRESS};}} + ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}} + ${CREATE_SHLIB-${INTERP}} + .hash ${RELOCATING-0} : { *(.hash) } + .dynsym ${RELOCATING-0} : { *(.dynsym) } + .dynstr ${RELOCATING-0} : { *(.dynstr) } + .rel.text ${RELOCATING-0} : { *(.rel.text) } + .rela.text ${RELOCATING-0} : { *(.rela.text) } + .rel.data ${RELOCATING-0} : { *(.rel.data) } + .rela.data ${RELOCATING-0} : { *(.rela.data) } + .rel.rodata ${RELOCATING-0} : { *(.rel.rodata) } + .rela.rodata ${RELOCATING-0} : { *(.rela.rodata) } + .rel.got ${RELOCATING-0} : { *(.rel.got) } + .rela.got ${RELOCATING-0} : { *(.rela.got) } + .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } + .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } + .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } + .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } + .rel.init ${RELOCATING-0} : { *(.rel.init) } + .rela.init ${RELOCATING-0} : { *(.rela.init) } + .rel.fini ${RELOCATING-0} : { *(.rel.fini) } + .rela.fini ${RELOCATING-0} : { *(.rela.fini) } + .rel.bss ${RELOCATING-0} : { *(.rel.bss) } + .rela.bss ${RELOCATING-0} : { *(.rela.bss) } + .rel.plt ${RELOCATING-0} : { *(.rel.plt) } + .rela.plt ${RELOCATING-0} : { *(.rela.plt) } + ${DATA_PLT-${PLT}} + .rodata ${RELOCATING-0} : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 ${RELOCATING-0} : { *(.rodata1) } + ${RELOCATING+${OTHER_READONLY_SECTIONS}} + + /* Adjust the address for the data segment. */ + ${RELOCATING+. = ${DATA_ADDR-ALIGN(4);}} + + .data ${RELOCATING-0} : + { + ${RELOCATING+${DATA_START_SYMBOLS}} + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + ${CONSTRUCTING+CONSTRUCTORS} + } + .data1 ${RELOCATING-0} : { *(.data1) } + ${RELOCATING+${OTHER_READWRITE_SECTIONS}} + ${RELOCATING+${CTOR}} + ${RELOCATING+${DTOR}} + .got ${RELOCATING-0} : { *(.got.plt) *(.got) } + .dynamic ${RELOCATING-0} : { *(.dynamic) } + ${DATA_PLT+${PLT}} + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata ${RELOCATING-0} : { *(.sdata) } + ${RELOCATING+_edata = .;} + ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+__bss_start = .;} + ${RELOCATING+${OTHER_BSS_SYMBOLS}} + .sbss ${RELOCATING-0} : { *(.sbss) *(.scommon) } + .bss ${RELOCATING-0} : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + ${RELOCATING+_end = . ;} + ${RELOCATING+PROVIDE (end = .);} + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + + .comment 0 : { *(.comment) } + + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + ${RELOCATING+${OTHER_RELOCATING_SECTIONS}} + + /* These must appear regardless of ${RELOCATING}. */ + ${OTHER_SECTIONS} + + + /* Hmmm, there's got to be a better way. This sets the stack to the + top of the simulator memory (i.e. top of 64K data space). */ + .stack 0x00007FFE : { _stack = .; *(.stack) } + + .text ${RELOCATING+${TEXT_START_ADDR}} : + { + ${RELOCATING+${TEXT_START_SYMBOLS}} + KEEP (*(.init)) + KEEP (*(.fini)) + *(.text) + *(.text.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =${NOP-0} + ${RELOCATING+_etext = .;} + ${RELOCATING+PROVIDE (etext = .);} +} +EOF diff --git a/ld/scripttempl/elfd30v.sc b/ld/scripttempl/elfd30v.sc new file mode 100644 index 0000000..0ff9283 --- /dev/null +++ b/ld/scripttempl/elfd30v.sc @@ -0,0 +1,219 @@ + +CTOR=".ctors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+ __CTOR_LIST__ = .; } + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + + KEEP (*crtbegin.o(.ctors)) + + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + ${CONSTRUCTING+ __CTOR_END__ = .; } + } ${RELOCATING+ > ${DATA_MEMORY}}" + +DTOR=" .dtors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+ __DTOR_LIST__ = .; } + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + ${CONSTRUCTING+ __DTOR_END__ = .; } + } ${RELOCATING+ > ${DATA_MEMORY}}" + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +MEMORY +{ + text ${TEXT_DEF_SECTION} : ORIGIN = ${TEXT_START_ADDR}, LENGTH = ${TEXT_SIZE} + data ${DATA_DEF_SECTION} : ORIGIN = ${DATA_START_ADDR}, LENGTH = ${DATA_SIZE} + emem ${EMEM_DEF_SECTION} : ORIGIN = ${EMEM_START_ADDR}, LENGTH = ${EMEM_SIZE} + eit : ORIGIN = ${EIT_START_ADDR}, LENGTH = ${EIT_SIZE} +} + +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + ${TEXT_DYNAMIC+${DYNAMIC}} + .hash ${RELOCATING-0} : { *(.hash) } + .dynsym ${RELOCATING-0} : { *(.dynsym) } + .dynstr ${RELOCATING-0} : { *(.dynstr) } + .gnu.version ${RELOCATING-0} : { *(.gnu.version) } + .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) } + .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) } + + .rela.text ${RELOCATING-0} : { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rela.data ${RELOCATING-0} : { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rela.rodata ${RELOCATING-0} : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rela.stext ${RELOCATING-0} : { *(.rela.stest) } + .rela.etext ${RELOCATING-0} : { *(.rela.etest) } + .rela.sdata ${RELOCATING-0} : { *(.rela.sdata) } + .rela.edata ${RELOCATING-0} : { *(.rela.edata) } + .rela.eit_v ${RELOCATING-0} : { *(.rela.eit_v) } + .rela.sbss ${RELOCATING-0} : { *(.rela.sbss) } + .rela.ebss ${RELOCATING-0} : { *(.rela.ebss) } + .rela.srodata ${RELOCATING-0} : { *(.rela.srodata) } + .rela.erodata ${RELOCATING-0} : { *(.rela.erodata) } + .rela.got ${RELOCATING-0} : { *(.rela.got) } + .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } + .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } + .rela.init ${RELOCATING-0} : { *(.rela.init) } + .rela.fini ${RELOCATING-0} : { *(.rela.fini) } + .rela.bss ${RELOCATING-0} : { *(.rela.bss) } + .rela.plt ${RELOCATING-0} : { *(.rela.plt) } + + .rel.data ${RELOCATING-0} : { *(.rel.data) *(.rel.gnu.linkonce.d*) } + .rel.rodata ${RELOCATING-0} : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + .rel.stext ${RELOCATING-0} : { *(.rel.stest) } + .rel.etext ${RELOCATING-0} : { *(.rel.etest) } + .rel.sdata ${RELOCATING-0} : { *(.rel.sdata) } + .rel.edata ${RELOCATING-0} : { *(.rel.edata) } + .rel.sbss ${RELOCATING-0} : { *(.rel.sbss) } + .rel.ebss ${RELOCATING-0} : { *(.rel.ebss) } + .rel.eit_v ${RELOCATING-0} : { *(.rel.eit_v) } + .rel.srodata ${RELOCATING-0} : { *(.rel.srodata) } + .rel.erodata ${RELOCATING-0} : { *(.rel.erodata) } + .rel.got ${RELOCATING-0} : { *(.rel.got) } + .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } + .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } + .rel.init ${RELOCATING-0} : { *(.rel.init) } + .rel.fini ${RELOCATING-0} : { *(.rel.fini) } + .rel.bss ${RELOCATING-0} : { *(.rel.bss) } + .rel.plt ${RELOCATING-0} : { *(.rel.plt) } + + .init ${RELOCATING-0} : { *(.init) } =${NOP-0} + ${DATA_PLT-${PLT}} + + /* Internal text space */ + .stext ${RELOCATING-0} : { *(.stext) } ${RELOCATING+ > text} + + /* Internal text space or external memory */ + .text : + { + *(.text) + *(.gnu.linkonce.t*) + *(.init) + *(.fini) + ${RELOCATING+ _etext = . ; } + } ${RELOCATING+ > ${TEXT_MEMORY}} + + /* Internal data space */ + .srodata ${RELOCATING-0} : { *(.srodata) } ${RELOCATING+ > data} + .sdata ${RELOCATING-0} : { *(.sdata) } ${RELOCATING+ > data} + + /* Internal data space or external memory */ + .rodata ${RELOCATING-0} : { *(.rodata) } ${RELOCATING+ > ${DATA_MEMORY}} + + /* C++ exception support. */ + .eh_frame ${RELOCATING-0} : { *(.eh_frame) } ${RELOCATING+ > ${DATA_MEMORY}} + + ${RELOCATING+${CTOR}} + ${RELOCATING+${DTOR}} + + .data ${RELOCATING-0} : + { + *(.data) + *(.gnu.linkonce.d*) + ${CONSTRUCTING+CONSTRUCTORS} + ${RELOCATING+ _edata = . ; } + } ${RELOCATING+ > ${DATA_MEMORY}} + + /* External memory */ + .etext ${RELOCATING-0} : + { + ${RELOCATING+ PROVIDE (__etext_start = .) ; } + *(.etext) + ${RELOCATING+ PROVIDE (__etext_end = .) ; } + } ${RELOCATING+ > emem} + + .erodata ${RELOCATING-0} : { *(.erodata) } ${RELOCATING+ > emem} + .edata ${RELOCATING-0} : { *(.edata) } ${RELOCATING+ > emem} + + .sbss ${RELOCATING-0} : + { + ${RELOCATING+ PROVIDE (__sbss_start = .) ; } + *(.sbss) + ${RELOCATING+ PROVIDE (__sbss_end = .) ; } + } ${RELOCATING+ > data} + + .ebss ${RELOCATING-0} : + { + ${RELOCATING+ PROVIDE (__ebss_start = .) ; } + *(.ebss) + ${RELOCATING+ PROVIDE (__ebss_end = .) ; } + } ${RELOCATING+ > data} + + .bss ${RELOCATING-0} : + { + ${RELOCATING+ PROVIDE (__bss_start = .) ; } + *(.bss) + *(COMMON) + ${RELOCATING+ PROVIDE (__bss_end = .) ; } + ${RELOCATING+ _end = . ; } + } ${RELOCATING+ > ${DATA_MEMORY}} + + .eit_v ${RELOCATING-0} : + { + ${RELOCATING+ PROVIDE (__eit_start = .) ; } + *(.eit_v) + ${RELOCATING+ PROVIDE (__eit_end = .) ; } + } ${RELOCATING+ > eit} + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + + .comment 0 : { *(.comment) } + + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + PROVIDE (__stack = ${STACK_START_ADDR}); +} +EOF + + + + diff --git a/ld/scripttempl/elfppc.sc b/ld/scripttempl/elfppc.sc new file mode 100644 index 0000000..ddab8f8 --- /dev/null +++ b/ld/scripttempl/elfppc.sc @@ -0,0 +1,288 @@ +# +# Unusual variables checked by this code: +# NOP - two byte opcode for no-op (defaults to 0) +# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start +# OTHER_READONLY_SECTIONS - other than .text .init .rodata ... +# (e.g., .PARISC.milli) +# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ... +# (e.g., .PARISC.global) +# OTHER_SECTIONS - at the end +# EXECUTABLE_SYMBOLS - symbols that must be defined for an +# executable (e.g., _DYNAMIC_LINK) +# TEXT_START_SYMBOLS - symbols that appear at the start of the +# .text section. +# DATA_START_SYMBOLS - symbols that appear at the start of the +# .data section. +# OTHER_BSS_SYMBOLS - symbols that appear at the start of the +# .bss section besides __bss_start. +# +# When adding sections, do note that the names of some sections are used +# when specifying the start address of the next. +# +test -z "$ENTRY" && ENTRY=_start +test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test "$LD_FLAG" = "N" && DATA_ADDR=. +SBSS2=".sbss2 ${RELOCATING-0} : { *(.sbss2) }" +SDATA2=".sdata2 ${RELOCATING-0} : { *(.sdata2) }" +INTERP=".interp ${RELOCATING-0} : { *(.interp) }" +PLT=".plt ${RELOCATING-0} : { *(.plt) }" +CTOR=".ctors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+${CTOR_START}} + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + + KEEP (*crtbegin.o(.ctors)) + + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + ${CONSTRUCTING+${CTOR_END}} + }" + +DTOR=" .dtors ${CONSTRUCTING-0} : + { + ${CONSTRUCTING+${DTOR_START}} + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + ${CONSTRUCTING+${DTOR_END}} + }" + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", + "${LITTLE_OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) +ENTRY(${ENTRY}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +${RELOCATING+/* Do we need any of these for elf? + __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */} +${RELOCATING+${EXECUTABLE_SYMBOLS}} +${RELOCATING- /* For some reason, the Solaris linker makes bad executables + if gld -r is used and the intermediate file has sections starting + at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld + bug. But for now assigning the zero vmas works. */} + +${RELOCATING+PROVIDE (__stack = 0);} +${RELOCATING+PROVIDE (___stack = 0);} +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_START_ADDR} + SIZEOF_HEADERS;}} + ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}} + ${CREATE_SHLIB-${INTERP}} + .hash ${RELOCATING-0} : { *(.hash) } + .dynsym ${RELOCATING-0} : { *(.dynsym) } + .dynstr ${RELOCATING-0} : { *(.dynstr) } + .gnu.version ${RELOCATING-0} : { *(.gnu.version) } + .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) } + .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) } + .rela.text ${RELOCATING-0} : + { + *(.rela.text) + ${RELOCATING+*(.rela.text.*)} + ${RELOCATING+*(.rela.gnu.linkonce.t*)} + } + .rela.data ${RELOCATING-0} : + { + *(.rela.data) + ${RELOCATING+*(.rela.data.*)} + ${RELOCATING+*(.rela.gnu.linkonce.d*)} + } + .rela.rodata ${RELOCATING-0} : + { + *(.rela.rodata) + ${RELOCATING+*(.rela.rodata.*)} + ${RELOCATING+*(.rela.gnu.linkonce.r*)} + } + .rela.got ${RELOCATING-0} : { *(.rela.got) } + .rela.got1 ${RELOCATING-0} : { *(.rela.got1) } + .rela.got2 ${RELOCATING-0} : { *(.rela.got2) } + .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } + .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } + .rela.init ${RELOCATING-0} : { *(.rela.init) } + .rela.fini ${RELOCATING-0} : { *(.rela.fini) } + .rela.bss ${RELOCATING-0} : { *(.rela.bss) } + .rela.plt ${RELOCATING-0} : { *(.rela.plt) } + .rela.sdata ${RELOCATING-0} : { *(.rela.sdata) } + .rela.sbss ${RELOCATING-0} : { *(.rela.sbss) } + .rela.sdata2 ${RELOCATING-0} : { *(.rela.sdata2) } + .rela.sbss2 ${RELOCATING-0} : { *(.rela.sbss2) } + .text ${RELOCATING-0} : + { + ${RELOCATING+${TEXT_START_SYMBOLS}} + *(.text) + ${RELOCATING+*(.text.*)} + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + ${RELOCATING+*(.gnu.linkonce.t*)} + } =${NOP-0} + .init ${RELOCATING-0} : { KEEP (*(.init)) } =${NOP-0} + .fini ${RELOCATING-0} : { KEEP (*(.fini)) } =${NOP-0} + .rodata ${RELOCATING-0} : + { + *(.rodata) + ${RELOCATING+*(.rodata.*)} + ${RELOCATING+*(.gnu.linkonce.r*)} + } + .rodata1 ${RELOCATING-0} : { *(.rodata1) } + ${RELOCATING+_etext = .;} + ${RELOCATING+PROVIDE (etext = .);} + ${RELOCATING+PROVIDE (__etext = .);} + ${CREATE_SHLIB-${SDATA2}} + ${CREATE_SHLIB-${SBSS2}} + ${RELOCATING+${OTHER_READONLY_SECTIONS}} + + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + ${RELOCATING+. = ${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (ALIGN(8) & (${MAXPAGESIZE} - 1))};} + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + ${RELOCATING+. = ${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}};} + + .data ${RELOCATING-0} : + { + ${RELOCATING+${DATA_START_SYMBOLS}} + *(.data) + ${RELOCATING+*(.data.*)} + ${RELOCATING+*(.gnu.linkonce.d*)} + ${CONSTRUCTING+CONSTRUCTORS} + } + .data1 ${RELOCATING-0} : { *(.data1) } + ${RELOCATING+${OTHER_READWRITE_SECTIONS}} + + .got1 ${RELOCATING-0} : { *(.got1) } + .dynamic ${RELOCATING-0} : { *(.dynamic) } + + /* Put .ctors and .dtors next to the .got2 section, so that the pointers + get relocated with -mrelocatable. Also put in the .fixup pointers. + The current compiler no longer needs this, but keep it around for 2.7.2 */ + + ${RELOCATING+PROVIDE (_GOT2_START_ = .);} + ${RELOCATING+PROVIDE (__GOT2_START_ = .);} + .got2 ${RELOCATING-0} : { *(.got2) } + + ${RELOCATING+PROVIDE (__CTOR_LIST__ = .);} + ${RELOCATING+PROVIDE (___CTOR_LIST__ = .);} + ${RELOCATING+${CTOR}} + ${RELOCATING+PROVIDE (__CTOR_END__ = .);} + ${RELOCATING+PROVIDE (___CTOR_END__ = .);} + + ${RELOCATING+PROVIDE (__DTOR_LIST__ = .);} + ${RELOCATING+PROVIDE (___DTOR_LIST__ = .);} + ${RELOCATING+${DTOR}} + ${RELOCATING+PROVIDE (__DTOR_END__ = .);} + ${RELOCATING+PROVIDE (___DTOR_END__ = .);} + + ${RELOCATING+PROVIDE (_FIXUP_START_ = .);} + ${RELOCATING+PROVIDE (__FIXUP_START_ = .);} + .fixup ${RELOCATING-0} : { *(.fixup) } + ${RELOCATING+PROVIDE (_FIXUP_END_ = .);} + ${RELOCATING+PROVIDE (__FIXUP_END_ = .);} + ${RELOCATING+PROVIDE (_GOT2_END_ = .);} + ${RELOCATING+PROVIDE (__GOT2_END_ = .);} + + ${RELOCATING+PROVIDE (_GOT_START_ = .);} + ${RELOCATING+PROVIDE (__GOT_START_ = .);} + .got ${RELOCATING-0} : { *(.got) } + .got.plt ${RELOCATING-0} : { *(.got.plt) } + ${CREATE_SHLIB+${SDATA2}} + ${CREATE_SHLIB+${SBSS2}} + ${RELOCATING+PROVIDE (_GOT_END_ = .);} + ${RELOCATING+PROVIDE (__GOT_END_ = .);} + + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata ${RELOCATING-0} : { *(.sdata) } + ${RELOCATING+_edata = .;} + ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+PROVIDE (__edata = .);} + .sbss ${RELOCATING-0} : + { + ${RELOCATING+PROVIDE (__sbss_start = .);} + ${RELOCATING+PROVIDE (___sbss_start = .);} + *(.sbss) + *(.scommon) + *(.dynsbss) + ${RELOCATING+PROVIDE (__sbss_end = .);} + ${RELOCATING+PROVIDE (___sbss_end = .);} + } + ${PLT} + .bss ${RELOCATING-0} : + { + ${RELOCATING+${OTHER_BSS_SYMBOLS}} + ${RELOCATING+PROVIDE (__bss_start = .);} + ${RELOCATING+PROVIDE (___bss_start = .);} + *(.dynbss) + *(.bss) + *(COMMON) + } + ${RELOCATING+_end = . ;} + ${RELOCATING+PROVIDE (end = .);} + ${RELOCATING+PROVIDE (__end = .);} + + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + /* These must appear regardless of ${RELOCATING}. */ + ${OTHER_SECTIONS} +} +EOF diff --git a/ld/scripttempl/go32coff.sc b/ld/scripttempl/go32coff.sc new file mode 100644 index 0000000..40f6076 --- /dev/null +++ b/ld/scripttempl/go32coff.sc @@ -0,0 +1,33 @@ +# Linker script for 386 go32 +# DJ Delorie (dj@ctron.com) + +test -z "$ENTRY" && ENTRY=start +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + .text ${RELOCATING+ 0x1000+SIZEOF_HEADERS} : { + *(.text) + ${RELOCATING+ etext = . ; _etext = .}; + ${RELOCATING+ . = ALIGN(0x200);} + } + .data ${RELOCATING+ ${DATA_ALIGNMENT}} : { + ${RELOCATING+ *(.ctor)} + ${RELOCATING+ *(.dtor)} + *(.data) + ${RELOCATING+ edata = . ; _edata = .}; + ${RELOCATING+ . = ALIGN(0x200);} + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + *(.bss) + *(COMMON) + ${RELOCATING+ end = . ; _end = .}; + ${RELOCATING+ . = ALIGN(0x200);} + } +} +EOF diff --git a/ld/scripttempl/h8300.sc b/ld/scripttempl/h8300.sc new file mode 100644 index 0000000..f2f876e --- /dev/null +++ b/ld/scripttempl/h8300.sc @@ -0,0 +1,69 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) +ENTRY("_start") + +MEMORY +{ + /* 0xc4 is a magic entry. We should have the linker just + skip over it one day... */ + vectors : o = 0x0000, l = 0xc4 + magicvectors : o = 0xc4, l = 0x3c + ram : o = 0x0100, l = 0xfdfc + /* The stack starts at the top of main ram. */ + topram : o = 0xfefc, l = 0x4 + /* At the very to of the address space is the 8-bit area. */ + eight : o = 0xff00, l = 0x100 +} + +SECTIONS +{ +.vectors : { + /* Use something like this to place a specific function's address + into the vector table. + + SHORT(ABSOLUTE(_foobar)) */ + + *(.vectors) + } ${RELOCATING+ > vectors} + +.text : { + *(.rodata) + *(.text) + *(.strings) + ${RELOCATING+ _etext = . ; } + } ${RELOCATING+ > ram} +.tors : { + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; + } ${RELOCATING+ > ram} +.data : { + *(.data) + *(.tiny) + ${RELOCATING+ _edata = . ; } + } ${RELOCATING+ > ram} +.bss : { + ${RELOCATING+ _bss_start = . ;} + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } ${RELOCATING+ >ram} +.stack : { + ${RELOCATING+ _stack = . ; } + *(.stack) + } ${RELOCATING+ > topram} +.eight : { + *(.eight) + } ${RELOCATING+ > eight} +.stab 0 ${RELOCATING+(NOLOAD)} : { + [ .stab ] + } +.stabstr 0 ${RELOCATING+(NOLOAD)} : { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/h8300h.sc b/ld/scripttempl/h8300h.sc new file mode 100644 index 0000000..d1cfd86 --- /dev/null +++ b/ld/scripttempl/h8300h.sc @@ -0,0 +1,76 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(h8300h) +ENTRY("_start") + +/* The memory size is 256KB to coincide with the simulator. + Don't change either without considering the other. */ + +MEMORY +{ + /* 0xc4 is a magic entry. We should have the linker just + skip over it one day... */ + vectors : o = 0x0000, l = 0xc4 + magicvectors : o = 0xc4, l = 0x3c + /* We still only use 256k as the main ram size. */ + ram : o = 0x0100, l = 0x3fefc + /* The stack starts at the top of main ram. */ + topram : o = 0x3fffc, l = 0x4 + /* This holds variables in the "tiny" sections. */ + tiny : o = 0xff8000, l = 0x7f00 + /* At the very top of the address space is the 8-bit area. */ + eight : o = 0xffff00, l = 0x100 +} + +SECTIONS +{ +.vectors : { + /* Use something like this to place a specific function's address + into the vector table. + + LONG(ABSOLUTE(_foobar)) */ + + *(.vectors) + } ${RELOCATING+ > vectors} +.text : { + *(.rodata) + *(.text) + *(.strings) + ${RELOCATING+ _etext = . ; } + } ${RELOCATING+ > ram} +.tors : { + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; + } ${RELOCATING+ > ram} +.data : { + *(.data) + ${RELOCATING+ _edata = . ; } + } ${RELOCATING+ > ram} +.bss : { + ${RELOCATING+ _bss_start = . ;} + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } ${RELOCATING+ >ram} +.stack : { + ${RELOCATING+ _stack = . ; } + *(.stack) + } ${RELOCATING+ > topram} +.tiny : { + *(.tiny) + } ${RELOCATING+ > tiny} +.eight : { + *(.eight) + } ${RELOCATING+ > eight} +.stab 0 ${RELOCATING+(NOLOAD)} : { + [ .stab ] + } +.stabstr 0 ${RELOCATING+(NOLOAD)} : { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/h8300s.sc b/ld/scripttempl/h8300s.sc new file mode 100644 index 0000000..45474fc --- /dev/null +++ b/ld/scripttempl/h8300s.sc @@ -0,0 +1,76 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(h8300s) +ENTRY("_start") + +/* The memory size is 256KB to coincide with the simulator. + Don't change either without considering the other. */ + +MEMORY +{ + /* 0xc4 is a magic entry. We should have the linker just + skip over it one day... */ + vectors : o = 0x0000, l = 0xc4 + magicvectors : o = 0xc4, l = 0x3c + /* We still only use 256k as the main ram size. */ + ram : o = 0x0100, l = 0x3fefc + /* The stack starts at the top of main ram. */ + topram : o = 0x3fffc, l = 0x4 + /* This holds variables in the "tiny" sections. */ + tiny : o = 0xff8000, l = 0x7f00 + /* At the very top of the address space is the 8-bit area. */ + eight : o = 0xffff00, l = 0x100 +} + +SECTIONS +{ +.vectors : { + /* Use something like this to place a specific function's address + into the vector table. + + LONG(ABSOLUTE(_foobar)) */ + + *(.vectors) + } ${RELOCATING+ > vectors} +.text : { + *(.rodata) + *(.text) + *(.strings) + ${RELOCATING+ _etext = . ; } + } ${RELOCATING+ > ram} +.tors : { + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; + } ${RELOCATING+ > ram} +.data : { + *(.data) + ${RELOCATING+ _edata = . ; } + } ${RELOCATING+ > ram} +.bss : { + ${RELOCATING+ _bss_start = . ;} + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } ${RELOCATING+ >ram} +.stack : { + ${RELOCATING+ _stack = . ; } + *(.stack) + } ${RELOCATING+ > topram} +.tiny : { + *(.tiny) + } ${RELOCATING+ > tiny} +.eight : { + *(.eight) + } ${RELOCATING+ > eight} +.stab 0 ${RELOCATING+(NOLOAD)} : { + [ .stab ] + } +.stabstr 0 ${RELOCATING+(NOLOAD)} : { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/h8500.sc b/ld/scripttempl/h8500.sc new file mode 100644 index 0000000..d6a39ee --- /dev/null +++ b/ld/scripttempl/h8500.sc @@ -0,0 +1,62 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +/* Code and data 64k total */ + +SECTIONS +{ +.text ${RELOCATING+ 0x0000 } : + { + *(.text) + + ${RELOCATING+ _etext = . ; } + } + + +.data ${RELOCATING+ . } : + { + *(.data) + ${RELOCATING+ _edata = . ; } + } + +.rdata ${RELOCATING+ . } : + { + *(.rdata); + *(.strings) + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; +} + +.bss ${RELOCATING+ . } : + { + ${RELOCATING+ __start_bss = . ; } + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } + +.stack ${RELOCATING+ 0xfff0} : + { + ${RELOCATING+ _stack = . ; } + *(.stack) + } + + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF + + + + diff --git a/ld/scripttempl/h8500b.sc b/ld/scripttempl/h8500b.sc new file mode 100644 index 0000000..ef5fa2c --- /dev/null +++ b/ld/scripttempl/h8500b.sc @@ -0,0 +1,62 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +/* Code and data, both larger than 64k */ + +SECTIONS +{ +.text ${RELOCATING+ 0x10000} : + { + *(.text) + + ${RELOCATING+ _etext = . ; } + } + + +.data ${RELOCATING+ 0x20000} : + { + *(.data) + ${RELOCATING+ _edata = . ; } + } + +.rdata ${RELOCATING+ 0x30000} : + { + *(.rdata); + *(.strings) + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; +} + +.bss ${RELOCATING+ 0x40000} : + { + ${RELOCATING+ __start_bss = . ; } + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } + +.stack ${RELOCATING+ 0x50000} : + { + ${RELOCATING+ _stack = . ; } + *(.stack) + } + + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF + + + + diff --git a/ld/scripttempl/h8500c.sc b/ld/scripttempl/h8500c.sc new file mode 100644 index 0000000..03880e3 --- /dev/null +++ b/ld/scripttempl/h8500c.sc @@ -0,0 +1,59 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +/* Compact model - code < 64k, data > 64k */ + +SECTIONS +{ +.text 0x10000 : + { + *(.text) + *(.strings) + ${RELOCATING+ _etext = . ; } + } ${RELOCATING+ > ram} + + +.data 0x20000 : + { + *(.data) + ${RELOCATING+ _edata = . ; } + } ${RELOCATING+ > ram} + +.rdata 0x30000 : { + *(.rdata); + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; +} ${RELOCATING+ > ram} + +.bss 0x40000 : + { + ${RELOCATING+ __start_bss = . ; } + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } ${RELOCATING+ >ram} +.stack 0x5fff0 : + { + ${RELOCATING+ _stack = . ; } + *(.stack) + } ${RELOCATING+ > topram} + + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF + + + + diff --git a/ld/scripttempl/h8500m.sc b/ld/scripttempl/h8500m.sc new file mode 100644 index 0000000..040a4a7 --- /dev/null +++ b/ld/scripttempl/h8500m.sc @@ -0,0 +1,61 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +/* Code and data, both larger than 64k */ + +SECTIONS +{ +.text ${RELOCATING+ 0x10000} : + { + *(.text) + ${RELOCATING+ _etext = . ; } + } + + +.data ${RELOCATING+ 0x20000} : + { + *(.data) + ${RELOCATING+ _edata = . ; } + } + +.rdata ${RELOCATING+ . } : + { + *(.rdata); + *(.strings) + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; + } + +.bss ${RELOCATING+ . } : + { + ${RELOCATING+ __start_bss = . ; } + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } + +.stack ${RELOCATING+ 0x2fff0} : + { + ${RELOCATING+ _stack = . ; } + *(.stack) + } + + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF + + + + diff --git a/ld/scripttempl/h8500s.sc b/ld/scripttempl/h8500s.sc new file mode 100644 index 0000000..11615d8 --- /dev/null +++ b/ld/scripttempl/h8500s.sc @@ -0,0 +1,60 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +/* Code and data, both 64k */ + +SECTIONS +{ +.text ${RELOCATING+ 0x10000 } : + { + *(.text) + ${RELOCATING+ _etext = . ; } + } + +.rdata ${RELOCATING+ 0x20000 } : + { + *(.rdata); + *(.strings) + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; + } + +.data ${RELOCATING+ . } : + { + *(.data) + ${RELOCATING+ _edata = . ; } + } + +.bss ${RELOCATING+ .} : + { + ${RELOCATING+ __start_bss = . ; } + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } + +.stack ${RELOCATING+ 0x2fff0} : + { + ${RELOCATING+ _stack = . ; } + *(.stack) + } + + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF + + + + diff --git a/ld/scripttempl/hppaelf.sc b/ld/scripttempl/hppaelf.sc new file mode 100644 index 0000000..941ce08 --- /dev/null +++ b/ld/scripttempl/hppaelf.sc @@ -0,0 +1,38 @@ +DATA_ADDR=0x40000000 +test "$LD_FLAG" = "N" && DATA_ADDR=. +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) +ENTRY("\$START\$") +${RELOCATING+${LIB_SEARCH_DIRS}} +SECTIONS +{ + .text 0x1000 ${RELOCATING++${TEXT_START_ADDR}}: + { + ${RELOCATING+__text_start = .}; + CREATE_OBJECT_SYMBOLS + *(.PARISC.stubs) + *(.text) + ${RELOCATING+etext = .}; + ${RELOCATING+_etext = .}; + } + ${RELOCATING+. = ${DATA_ADDR};} + .data : + { + ${RELOCATING+ . = . + 0x1000 }; + ${RELOCATING+__data_start = .}; + *(.data) + ${CONSTRUCTING+CONSTRUCTORS} + ${RELOCATING+edata = .}; + ${RELOCATING+_edata = .}; + } + ${RELOCATING+. = ${DATA_ADDR} + SIZEOF(.data);} + .bss : + { + *(.bss) + *(COMMON) + ${RELOCATING+end = . }; + ${RELOCATING+_end = . }; + } +} +EOF diff --git a/ld/scripttempl/i386beos.sc b/ld/scripttempl/i386beos.sc new file mode 100644 index 0000000..83ffde1 --- /dev/null +++ b/ld/scripttempl/i386beos.sc @@ -0,0 +1,194 @@ +# Linker script for PE. + +if test -z "${RELOCATEABLE_OUTPUT_FORMAT}"; then + RELOCATEABLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +fi + +# We can't easily and portably get an unquoted $ in a shell +# substitution, so we do this instead. +if test "${RELOCATING}"; then + R_TEXT='*(.text$*)' + R_DATA='*(.data$*)' + R_RDATA='*(.rdata$*)' + R_IDATA=' + *(.idata$2) + *(.idata$3) + /* These zeroes mark the end of the import list. */ + LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); + *(.idata$4) + *(.idata$5) + *(.idata$6) + *(.idata$7)' + R_CRT='*(.CRT$*)' + R_RSRC='*(.rsrc$*)' + R_EXC='*(.exc$*)' +else + R_TEXT= + R_DATA= + R_RDATA= + R_IDATA= + R_CRT= + R_RSRC= + R_EXC= +fi + +cat <<EOF +${RELOCATING+OUTPUT_FORMAT(${OUTPUT_FORMAT})} +${RELOCATING-OUTPUT_FORMAT(${RELOCATEABLE_OUTPUT_FORMAT})} + +${LIB_SEARCH_DIRS} + +ENTRY(__start) +${RELOCATING+header = .;} +${RELOCATING+__fltused = .; /* set up floating pt for MS .obj\'s */} +${RELOCATING+__ldused = .;} +SECTIONS +{ + .text ${RELOCATING+ __image_base__ + __section_alignment__ } : + { + ${RELOCATING+ __text_start__ = . ;} + ${RELOCATING+ *(.init)} + *(.text) + ${R_TEXT} + *(.glue_7t) + *(.glue_7) + ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1); *(.ctors); *(.ctor); LONG (0); } + ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); LONG (0); } + ${RELOCATING+ *(.fini)} + /* ??? Why is .gcc_exc here? */ + ${RELOCATING+ *(.gcc_exc)} + ${RELOCATING+ etext = .;} + ${RELOCATING+ __text_end__ = .;} + *(.gcc_except_table) + } + + /* The Cygwin32 library uses a section to avoid copying certain data + on fork. This used to be named ".data$nocopy". The linker used + to include this between __data_start__ and __data_end__, but that + breaks building the cygwin32 dll. Instead, we name the section + ".data_cygwin_nocopy" and explictly include it after __data_end__. */ + + .data ${RELOCATING+BLOCK(__section_alignment__)} : + { + ${RELOCATING+__data_start__ = . ;} + *(.data) + *(.data2) + ${R_DATA} + ${RELOCATING+__data_end__ = . ;} + ${RELOCATING+*(.data_cygwin_nocopy)} + } + + .bss ${RELOCATING+BLOCK(__section_alignment__)} : + { + ${RELOCATING+__bss_start__ = . ;} + *(.bss) + *(COMMON) + /* link.exe apparently pulls in .obj's because of UNDEF common + symbols, which is not the coff way, but that's MS for you. */ + *(.CRT\$XCA) + *(.CRT\$XCZ) + *(.CRT\$XIA) + *(.CRT\$XIZ) + ${RELOCATING+__bss_end__ = . ;} + } + + .rdata ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.rdata) + ${R_RDATA} + *(.eh_frame) + } + + .edata ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.edata) + } + + /DISCARD/ : + { + *(.debug\$S) + *(.debug\$T) + *(.debug\$F) + *(.drectve) + *(.debug*) + } + + .idata ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* This cannot currently be handled with grouped sections. + See pe.em:sort_sections. */ + ${R_IDATA} + } + .CRT ${RELOCATING+BLOCK(__section_alignment__)} : + { + ${R_CRT} + } + + .endjunk ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* end is deprecated, don't use it */ + ${RELOCATING+ end = .;} + ${RELOCATING+ _end = .;} + ${RELOCATING+ __end__ = .;} + } + + .reloc ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.reloc) + } + + .rsrc ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.rsrc) + ${R_RSRC} + } + + .exc ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.exc) + ${R_EXC} + } + + .stab ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + + .stabstr ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + + /* DWARF 1 */ + .debug 0 ${RELOCATING+(NOLOAD)} : { *(.debug) } + .line 0 ${RELOCATING+(NOLOAD)} : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 ${RELOCATING+(NOLOAD)} : { *(.debug_srcinfo) } + .debug_sfnames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 ${RELOCATING+(NOLOAD)} : { *(.debug_aranges) } + .debug_pubnames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 ${RELOCATING+(NOLOAD)} : { *(.debug_info) } + .debug_abbrev 0 ${RELOCATING+(NOLOAD)} : { *(.debug_abbrev) } + .debug_line 0 ${RELOCATING+(NOLOAD)} : { *(.debug_line) } + .debug_frame 0 ${RELOCATING+(NOLOAD)} : { *(.debug_frame) } + .debug_str 0 ${RELOCATING+(NOLOAD)} : { *(.debug_str) } + .debug_loc 0 ${RELOCATING+(NOLOAD)} : { *(.debug_loc) } + .debug_macinfo 0 ${RELOCATING+(NOLOAD)} : { *(.debug_macinfo) } + + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_weaknames) } + .debug_funcnames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_funcnames) } + .debug_typenames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_typenames) } + .debug_varnames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_varnames) } +} +EOF diff --git a/ld/scripttempl/i386coff.sc b/ld/scripttempl/i386coff.sc new file mode 100644 index 0000000..fbb1b79 --- /dev/null +++ b/ld/scripttempl/i386coff.sc @@ -0,0 +1,43 @@ +# Linker script for 386 COFF. This works on SVR3.2 and SCO Unix 3.2.2. +# Ian Taylor <ian@cygnus.com>. +test -z "$ENTRY" && ENTRY=_start +# These are substituted in as variables in order to get '}' in a shell +# conditional expansion. +INIT='.init : { *(.init) }' +FINI='.fini : { *(.fini) }' +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + .text ${RELOCATING+ SIZEOF_HEADERS} : { + ${RELOCATING+ *(.init)} + *(.text) + ${RELOCATING+ *(.fini)} + ${RELOCATING+ etext = .}; + } + .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : { + *(.data) + ${RELOCATING+ edata = .}; + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + *(.bss) + *(COMMON) + ${RELOCATING+ end = .}; + } + ${RELOCATING- ${INIT}} + ${RELOCATING- ${FINI}} + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/i386go32.sc b/ld/scripttempl/i386go32.sc new file mode 100644 index 0000000..6bd3d09 --- /dev/null +++ b/ld/scripttempl/i386go32.sc @@ -0,0 +1,46 @@ +# Linker script for i386 go32 (DJGPP) + +test -z "$ENTRY" && ENTRY=start +EXE=${CONSTRUCTING+${RELOCATING+-exe}} + +# These are substituted in as variables in order to get '}' in a shell +# conditional expansion. +CTOR='.ctor : { *(.ctor) }' +DTOR='.dtor : { *(.dtor) }' + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}${EXE}") + +ENTRY(${ENTRY}) + +SECTIONS +{ + .text ${RELOCATING+ ${TARGET_PAGE_SIZE}+SIZEOF_HEADERS} : { + *(.text) + *(.const*) + *(.ro*) + ${RELOCATING+etext = . ; _etext = .}; + ${RELOCATING+. = ALIGN(${SEGMENT_SIZE});} + } + .data ${RELOCATING+ ${DATA_ALIGNMENT}} : { + ${RELOCATING+djgpp_first_ctor = . ; + *(.ctor) + djgpp_last_ctor = . ;} + ${RELOCATING+djgpp_first_dtor = . ; + *(.dtor) + djgpp_last_dtor = . ;} + *(.data) + ${RELOCATING+ edata = . ; _edata = .}; + ${RELOCATING+ . = ALIGN(${SEGMENT_SIZE});} + } + ${CONSTRUCTING+${RELOCATING-$CTOR}} + ${CONSTRUCTING+${RELOCATING-$DTOR}} + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + *(.bss) + *(COMMON) + ${RELOCATING+ end = . ; _end = .}; + ${RELOCATING+ . = ALIGN(${SEGMENT_SIZE});} + } +} +EOF diff --git a/ld/scripttempl/i386lynx.sc b/ld/scripttempl/i386lynx.sc new file mode 100644 index 0000000..16b72a4 --- /dev/null +++ b/ld/scripttempl/i386lynx.sc @@ -0,0 +1,46 @@ +test -z "$ENTRY" && ENTRY=_start +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + .text ${RELOCATING+ SIZEOF_HEADERS} : { + *(.init) + *(.text) + ${RELOCATING+ etext = .;} + ${CONSTRUCTING+ __CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __CTOR_END__ = .;} + ${CONSTRUCTING+ __DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __DTOR_END__ = .;} + *(.fini) + ${RELOCATING+ etext = .}; + } + .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : { + *(.data) + ${RELOCATING+ edata = .}; + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + *(.bss) + *(COMMON) + ${RELOCATING+ end = .}; + } + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/i386msdos.sc b/ld/scripttempl/i386msdos.sc new file mode 100644 index 0000000..4d312e7 --- /dev/null +++ b/ld/scripttempl/i386msdos.sc @@ -0,0 +1,38 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +${STACKZERO+${RELOCATING+${STACKZERO}}} +SECTIONS +{ + ${RELOCATING+. = ${TEXT_START_ADDR};} + .text : + { + CREATE_OBJECT_SYMBOLS + *(.text) + ${RELOCATING+etext = .;} + ${RELOCATING+_etext = .;} + ${RELOCATING+__etext = .;} + } + .data : + { + *(.rodata) + *(.data) + ${CONSTRUCTING+CONSTRUCTORS} + ${RELOCATING+edata = .;} + ${RELOCATING+_edata = .;} + ${RELOCATING+__edata = .;} + } + .bss : + { + ${RELOCATING+ _bss_start = .}; + ${RELOCATING+ __bss_start = .}; + *(.bss) + *(COMMON) + ${RELOCATING+end = ALIGN(4) }; + ${RELOCATING+_end = ALIGN(4) }; + ${RELOCATING+__end = ALIGN(4) }; + } +} +EOF diff --git a/ld/scripttempl/i960.sc b/ld/scripttempl/i960.sc new file mode 100644 index 0000000..dc33555 --- /dev/null +++ b/ld/scripttempl/i960.sc @@ -0,0 +1,25 @@ +cat <<EOF +SECTIONS +{ + .text : + { + ${GLD_STYLE+ CREATE_OBJECT_SYMBOLS} + *(.text) + ${RELOCATING+ _etext = .}; + ${CONSTRUCTING+${COFF_CTORS}} + } + .data : + { + *(.data) + ${CONSTRUCTING+CONSTRUCTORS} + ${RELOCATING+ _edata = .}; + } + .bss : + { + ${RELOCATING+ _bss_start = .}; + *(.bss) + *(COMMON) + ${RELOCATING+ _end = .}; + } +} +EOF diff --git a/ld/scripttempl/m68kaux.sc b/ld/scripttempl/m68kaux.sc new file mode 100644 index 0000000..404280e --- /dev/null +++ b/ld/scripttempl/m68kaux.sc @@ -0,0 +1,46 @@ +# Linker script for A/UX. +test -z "$ENTRY" && ENTRY=_start +INIT='.init : { *(.init) }' +FINI='.fini : { *(.fini) }' +CTORS='.ctors : { *(.ctors) }' +DTORS='.dtors : { *(.dtors) }' + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + .text ${RELOCATING+ $TEXT_START_ADDR} : { + ${RELOCATING+ *(.init)} + ${RELOCATING+ *(.fini)} + *(.text) + ${RELOCATING+ . = ALIGN(4);} + ${RELOCATING+ *(.ctors)} + ${RELOCATING+ *(.dtors)} + ${RELOCATING+ etext = .;} + ${RELOCATING+ _etext = .;} + } =0x4E714E71 + .data ${RELOCATING+ $DATA_ALIGNMENT} : { + *(.data) + ${RELOCATING+ edata = .;} + ${RELOCATING+ _edata = .;} + } + .bss : { + *(.bss) + *(COMMON) + ${RELOCATING+ end = .;} + ${RELOCATING+ _end = .;} + } + ${RELOCATING- ${INIT}} + ${RELOCATING- ${FINI}} + ${RELOCATING- ${CTORS}} + ${RELOCATING- ${DTORS}} + + .comment 0 ${RELOCATING+(NOLOAD)} : { [ .comment ] [ .ident ] } + .stab 0 ${RELOCATING+(NOLOAD)} : { [ .stab ] } + .stabstr 0 ${RELOCATING+(NOLOAD)} : { [ .stabstr ] } +} +EOF diff --git a/ld/scripttempl/m68kcoff.sc b/ld/scripttempl/m68kcoff.sc new file mode 100644 index 0000000..f268c6f --- /dev/null +++ b/ld/scripttempl/m68kcoff.sc @@ -0,0 +1,42 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} +PROVIDE (__stack = 0); +SECTIONS +{ + .text ${RELOCATING+ 0x1000000} : { + *(.text) + ${CONSTRUCTING+ . = ALIGN(4);} + ${RELOCATING+ etext = .;} + ${CONSTRUCTING+ __CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __CTOR_END__ = .;} + ${CONSTRUCTING+ __DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __DTOR_END__ = .;} + } + .data : { + *(.data) + ${RELOCATING+ edata = .}; + } + .bss : { + ${RELOCATING+ __bss_start = .}; + *(.bss) + *(COMMON) + ${RELOCATING+ end = ALIGN(0x8)}; + ${RELOCATING+ _end = ALIGN(0x8)}; + } + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/m68klynx.sc b/ld/scripttempl/m68klynx.sc new file mode 100644 index 0000000..81d2245 --- /dev/null +++ b/ld/scripttempl/m68klynx.sc @@ -0,0 +1,46 @@ +test -z "$ENTRY" && ENTRY=_start +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + .text ${RELOCATING+ SIZEOF_HEADERS} : { + *(.init) + *(.text) + ${RELOCATING+ etext = .;} + ${CONSTRUCTING+ ___CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ ___CTOR_END__ = .;} + ${CONSTRUCTING+ ___DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ ___DTOR_END__ = .;} + *(.fini) + ${RELOCATING+ etext = .}; + } + .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : { + *(.data .data2) + ${RELOCATING+ edata = .}; + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + *(.bss) + *(COMMON) + ${RELOCATING+ end = .}; + } + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/m88kbcs.sc b/ld/scripttempl/m88kbcs.sc new file mode 100644 index 0000000..f52b14d --- /dev/null +++ b/ld/scripttempl/m88kbcs.sc @@ -0,0 +1,49 @@ +# These are substituted in as variables in order to get '}' in a shell +# conditional expansion. +INIT='.init : { *(.init) }' +FINI='.fini : { *(.fini) }' +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) +ENTRY(__start) +${RELOCATING+${LIB_SEARCH_DIRS}} + +SECTIONS +{ + .text ${RELOCATING+ (0x20007 + SIZEOF_HEADERS) &~ 7} : + { + ${RELOCATING+ __.text.start = .}; + ${RELOCATING+ __.init.start = .}; + ${RELOCATING+ *(.init)} + ${RELOCATING+ __.init.end = .}; + *(.text) + ${RELOCATING+ __.tdesc_start = .}; + ${RELOCATING+ *(.tdesc)} + ${RELOCATING+ __.text_end = .} ; + ${RELOCATING+ __.initp.start = .}; + ${RELOCATING+ __.initp.end = .}; + ${RELOCATING+ __.fini_start = .}; + ${RELOCATING+ *(.fini) } + ${RELOCATING+ __.fini_end = .}; + ${RELOCATING+_etext = .}; + } + .data ${RELOCATING+ NEXT (0x400000) + ((SIZEOF(.text) + ADDR(.text)) % 0x2000)} : + { + *(.data) + ${RELOCATING+_edata = .}; + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + *(.bss) + *(COMMON) + ${RELOCATING+ _end = .}; + ${RELOCATING+ __end = .}; + } + ${RELOCATING- ${INIT}} + ${RELOCATING- ${FINI}} + .comment 0 ${RELOCATING+(NOLOAD)} : + { + *(.comment) + } +} +EOF diff --git a/ld/scripttempl/mcorepe.sc b/ld/scripttempl/mcorepe.sc new file mode 100644 index 0000000..8111bf2 --- /dev/null +++ b/ld/scripttempl/mcorepe.sc @@ -0,0 +1,156 @@ +# Linker script for PE. + +if test -z "${RELOCATEABLE_OUTPUT_FORMAT}"; then + RELOCATEABLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +fi + +# We can't easily and portably get an unquoted $ in a shell +# substitution, so we do this instead. +# Sorting of the .foo$* sections is required by the definition of +# grouped sections in PE. +# Sorting of the file names in R_IDATA is required by the +# current implementation of dlltool (this could probably be changed to +# use grouped sections instead). +if test "${RELOCATING}"; then + R_TEXT='*(SORT(.text$*))' + R_DATA='*(SORT(.data$*))' + R_RDATA='*(SORT(.rdata$*))' + R_IDATA=' + SORT(*)(.idata$2) + SORT(*)(.idata$3) + /* These zeroes mark the end of the import list. */ + LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); + SORT(*)(.idata$4) + SORT(*)(.idata$5) + SORT(*)(.idata$6) + SORT(*)(.idata$7)' + R_CRT='*(SORT(.CRT$*))' + R_RSRC='*(SORT(.rsrc$*))' +else + R_TEXT= + R_DATA= + R_RDATA= + R_IDATA= + R_CRT= + R_RSRC= +fi + +cat <<EOF +${RELOCATING+OUTPUT_FORMAT(${OUTPUT_FORMAT})} +${RELOCATING-OUTPUT_FORMAT(${RELOCATEABLE_OUTPUT_FORMAT})} + +${LIB_SEARCH_DIRS} + +ENTRY(_mainCRTStartup) + +SECTIONS +{ + .text ${RELOCATING+ __image_base__ + __section_alignment__ } : + { + ${RELOCATING+ *(.init)} + *(.text) + ${R_TEXT} + *(.glue_7t) + *(.glue_7) + ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1); *(.ctors); *(.ctor); LONG (0); } + ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); LONG (0); } + ${RELOCATING+ *(.fini)} + /* ??? Why is .gcc_exc here? */ + ${RELOCATING+ *(.gcc_exc)} + ${RELOCATING+ etext = .;} + *(.gcc_except_table) + } + + /* The Cygwin32 library uses a section to avoid copying certain data + on fork. This used to be named ".data$nocopy". The linker used + to include this between __data_start__ and __data_end__, but that + breaks building the cygwin32 dll. Instead, we name the section + ".data_cygwin_nocopy" and explictly include it after __data_end__. */ + + .data ${RELOCATING+BLOCK(__section_alignment__)} : + { + ${RELOCATING+__data_start__ = . ;} + *(.data) + *(.data2) + ${R_DATA} + ${RELOCATING+__data_end__ = . ;} + ${RELOCATING+*(.data_cygwin_nocopy)} + } + + .bss ${RELOCATING+BLOCK(__section_alignment__)} : + { + ${RELOCATING+__bss_start__ = . ;} + *(.bss) + *(COMMON) + ${RELOCATING+__bss_end__ = . ;} + } + + .rdata ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.rdata) + ${R_RDATA} + *(.eh_frame) + } + + .edata ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.edata) + } + + /DISCARD/ : + { + *(.debug\$S) + *(.debug\$T) + *(.debug\$F) + *(.drectve) + } + + .idata ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* This cannot currently be handled with grouped sections. + See pe.em:sort_sections. */ + ${R_IDATA} + } + .CRT ${RELOCATING+BLOCK(__section_alignment__)} : + { + ${R_CRT} + } + + .endjunk ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* end is deprecated, don't use it */ + ${RELOCATING+ end = .;} + ${RELOCATING+ _end = .;} + ${RELOCATING+ __end__ = .;} + } + + .reloc ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.reloc) + } + + .rsrc ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.rsrc) + ${R_RSRC} + } + + .stab ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + + .stabstr ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } + + .stack 0x80000 : + { + _stack = .; + *(.stack) + } +} +EOF diff --git a/ld/scripttempl/mips.sc b/ld/scripttempl/mips.sc new file mode 100644 index 0000000..d60aeed --- /dev/null +++ b/ld/scripttempl/mips.sc @@ -0,0 +1,72 @@ +# Linker script for MIPS systems. +# Ian Lance Taylor <ian@cygnus.com>. +# These variables may be overridden by the emulation file. The +# defaults are appropriate for a DECstation running Ultrix. +test -z "$ENTRY" && ENTRY=__start + +if [ -z "$EMBEDDED" ]; then + test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x400000 + SIZEOF_HEADERS" +else + test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x400000" +fi +if test "x$LD_FLAG" = "xn" -o "x$LD_FLAG" = "xN"; then + DATA_ADDR=. +else + test -z "$DATA_ADDR" && DATA_ADDR=0x10000000 +fi +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", + "${LITTLE_OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + ${RELOCATING+. = ${TEXT_START_ADDR};} + .text : { + ${RELOCATING+ _ftext = . }; + *(.init) + ${RELOCATING+ eprol = .}; + *(.text) + ${RELOCATING+PROVIDE (__runtime_reloc_start = .);} + *(.rel.sdata) + ${RELOCATING+PROVIDE (__runtime_reloc_stop = .);} + *(.fini) + ${RELOCATING+ etext = .}; + ${RELOCATING+ _etext = .}; + } + ${RELOCATING+. = ${DATA_ADDR};} + .rdata : { + *(.rdata) + } + ${RELOCATING+ _fdata = ALIGN(16);} + .data : { + *(.data) + ${CONSTRUCTING+CONSTRUCTORS} + } + ${RELOCATING+ _gp = ALIGN(16) + 0x8000;} + .lit8 : { + *(.lit8) + } + .lit4 : { + *(.lit4) + } + .sdata : { + *(.sdata) + } + ${RELOCATING+ edata = .;} + ${RELOCATING+ _edata = .;} + ${RELOCATING+ _fbss = .;} + .sbss : { + *(.sbss) + *(.scommon) + } + .bss : { + *(.bss) + *(COMMON) + } + ${RELOCATING+ end = .;} + ${RELOCATING+ _end = .;} +} +EOF diff --git a/ld/scripttempl/mipsbsd.sc b/ld/scripttempl/mipsbsd.sc new file mode 100644 index 0000000..b222b33 --- /dev/null +++ b/ld/scripttempl/mipsbsd.sc @@ -0,0 +1,30 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", + "${LITTLE_OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +SECTIONS +{ + ${RELOCATING+. = ${TEXT_START_ADDR};} + .text : + { + CREATE_OBJECT_SYMBOLS + *(.text) + ${RELOCATING+etext = ${DATA_ALIGNMENT};} + } + ${RELOCATING+. = ${DATA_ALIGNMENT};} + .data : + { + *(.data) + ${CONSTRUCTING+CONSTRUCTORS} + ${RELOCATING+edata = .;} + } + .bss : + { + *(.bss) + *(COMMON) + ${RELOCATING+end = . }; + } +} +EOF diff --git a/ld/scripttempl/nw.sc b/ld/scripttempl/nw.sc new file mode 100644 index 0000000..725522c --- /dev/null +++ b/ld/scripttempl/nw.sc @@ -0,0 +1,131 @@ +# +# Unusual variables checked by this code: +# NOP - two byte opcode for no-op (defaults to 0) +# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start +# OTHER_READONLY_SECTIONS - other than .text .init .ctors .rodata ... +# (e.g., .PARISC.milli) +# OTHER_READWRITE_SECTIONS - other than .data .bss .sdata ... +# (e.g., .PARISC.global) +# OTHER_SECTIONS - at the end +# EXECUTABLE_SYMBOLS - symbols that must be defined for an +# executable (e.g., _DYNAMIC_LINK) +# TEXT_START_SYMBOLS - symbols that appear at the start of the +# .text section. +# DATA_START_SYMBOLS - symbols that appear at the start of the +# .data section. +# OTHER_BSS_SYMBOLS - symbols that appear at the start of the +# .bss section besides __bss_start. +# DATA_PLT - .plt should be in data segment, not text segment. +# +# When adding sections, do note that the names of some sections are used +# when specifying the start address of the next. +# +test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test "$LD_FLAG" = "N" && DATA_ADDR=. +INTERP=".interp ${RELOCATING-0} : { *(.interp) }" +PLT=".plt ${RELOCATING-0} : { *(.plt) }" +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", + "${LITTLE_OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +${RELOCATING+/* Do we need any of these for elf? + __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */} +${RELOCATING+${EXECUTABLE_SYMBOLS}} +${RELOCATING- /* For some reason, the Solaris linker makes bad executables + if gld -r is used and the intermediate file has sections starting + at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld + bug. But for now assigning the zero vmas works. */} +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_START_ADDR} + SIZEOF_HEADERS;}} + ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}} + ${CREATE_SHLIB-${INTERP}} + .hash ${RELOCATING-0} : { *(.hash) } + .dynsym ${RELOCATING-0} : { *(.dynsym) } + .dynstr ${RELOCATING-0} : { *(.dynstr) } + .rel.text ${RELOCATING-0} : { *(.rel.text) } + .rela.text ${RELOCATING-0} : { *(.rela.text) } + .rel.data ${RELOCATING-0} : { *(.rel.data) } + .rela.data ${RELOCATING-0} : { *(.rela.data) } + .rel.rodata ${RELOCATING-0} : { *(.rel.rodata) } + .rela.rodata ${RELOCATING-0} : { *(.rela.rodata) } + .rel.got ${RELOCATING-0} : { *(.rel.got) } + .rela.got ${RELOCATING-0} : { *(.rela.got) } + .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } + .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } + .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } + .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } + .rel.bss ${RELOCATING-0} : { *(.rel.bss) } + .rela.bss ${RELOCATING-0} : { *(.rela.bss) } + .rel.plt ${RELOCATING-0} : { *(.rel.plt) } + .rela.plt ${RELOCATING-0} : { *(.rela.plt) } + .init ${RELOCATING-0} : { *(.init) } =${NOP-0} + ${DATA_PLT-${PLT}} + .text ${RELOCATING-0} : + { + ${RELOCATING+${TEXT_START_SYMBOLS}} + *(.text) + ${CONSTRUCTING+ __CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __CTOR_END__ = .;} + ${CONSTRUCTING+ __DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ __DTOR_END__ = .;} + } + ${RELOCATING+_etext = .;} + ${RELOCATING+PROVIDE (etext = .);} + .fini ${RELOCATING-0} : { *(.fini) } =${NOP-0} + .ctors ${RELOCATING-0} : { *(.ctors) } + .dtors ${RELOCATING-0} : { *(.dtors) } + .rodata ${RELOCATING-0} : { *(.rodata) } + .rodata1 ${RELOCATING-0} : { *(.rodata1) } + ${RELOCATING+${OTHER_READONLY_SECTIONS}} + + /* Read-write section, merged into data segment: */ + ${RELOCATING+. = ${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}};} + .data ${RELOCATING-0} : + { + ${RELOCATING+${DATA_START_SYMBOLS}} + *(.data) + ${CONSTRUCTING+CONSTRUCTORS} + } + .data1 ${RELOCATING-0} : { *(.data1) } + ${RELOCATING+${OTHER_READWRITE_SECTIONS}} + .got ${RELOCATING-0} : { *(.got.plt) *(.got) } + .dynamic ${RELOCATING-0} : { *(.dynamic) } + ${DATA_PLT+${PLT}} + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata ${RELOCATING-0} : { *(.sdata) } + ${RELOCATING+_edata = .;} + ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+__bss_start = .;} + ${RELOCATING+${OTHER_BSS_SYMBOLS}} + .sbss ${RELOCATING-0} : { *(.sbss) *(.scommon) } + .bss ${RELOCATING-0} : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + ${RELOCATING+_end = . ;} + ${RELOCATING+PROVIDE (end = .);} + + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + + /* These must appear regardless of ${RELOCATING}. */ + ${OTHER_SECTIONS} +} +EOF diff --git a/ld/scripttempl/pe.sc b/ld/scripttempl/pe.sc new file mode 100644 index 0000000..7926bfe --- /dev/null +++ b/ld/scripttempl/pe.sc @@ -0,0 +1,151 @@ +# Linker script for PE. + +if test -z "${RELOCATEABLE_OUTPUT_FORMAT}"; then + RELOCATEABLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +fi + +# We can't easily and portably get an unquoted $ in a shell +# substitution, so we do this instead. +# Sorting of the .foo$* sections is required by the definition of +# grouped sections in PE. +# Sorting of the file names in R_IDATA is required by the +# current implementation of dlltool (this could probably be changed to +# use grouped sections instead). +if test "${RELOCATING}"; then + R_TEXT='*(SORT(.text$*))' + R_DATA='*(SORT(.data$*))' + R_RDATA='*(SORT(.rdata$*))' + R_IDATA=' + SORT(*)(.idata$2) + SORT(*)(.idata$3) + /* These zeroes mark the end of the import list. */ + LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); + SORT(*)(.idata$4) + SORT(*)(.idata$5) + SORT(*)(.idata$6) + SORT(*)(.idata$7)' + R_CRT='*(SORT(.CRT$*))' + R_RSRC='*(SORT(.rsrc$*))' +else + R_TEXT= + R_DATA= + R_RDATA= + R_IDATA= + R_CRT= + R_RSRC= +fi + +cat <<EOF +${RELOCATING+OUTPUT_FORMAT(${OUTPUT_FORMAT})} +${RELOCATING-OUTPUT_FORMAT(${RELOCATEABLE_OUTPUT_FORMAT})} + +${LIB_SEARCH_DIRS} + +ENTRY(_mainCRTStartup) + +SECTIONS +{ + .text ${RELOCATING+ __image_base__ + __section_alignment__ } : + { + ${RELOCATING+ *(.init)} + *(.text) + ${R_TEXT} + *(.glue_7t) + *(.glue_7) + ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1); *(.ctors); *(.ctor); LONG (0); } + ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); LONG (0); } + ${RELOCATING+ *(.fini)} + /* ??? Why is .gcc_exc here? */ + ${RELOCATING+ *(.gcc_exc)} + ${RELOCATING+ etext = .;} + *(.gcc_except_table) + } + + /* The Cygwin32 library uses a section to avoid copying certain data + on fork. This used to be named ".data$nocopy". The linker used + to include this between __data_start__ and __data_end__, but that + breaks building the cygwin32 dll. Instead, we name the section + ".data_cygwin_nocopy" and explictly include it after __data_end__. */ + + .data ${RELOCATING+BLOCK(__section_alignment__)} : + { + ${RELOCATING+__data_start__ = . ;} + *(.data) + *(.data2) + ${R_DATA} + ${RELOCATING+__data_end__ = . ;} + ${RELOCATING+*(.data_cygwin_nocopy)} + } + + .bss ${RELOCATING+BLOCK(__section_alignment__)} : + { + ${RELOCATING+__bss_start__ = . ;} + *(.bss) + *(COMMON) + ${RELOCATING+__bss_end__ = . ;} + } + + .rdata ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.rdata) + ${R_RDATA} + *(.eh_frame) + } + + .edata ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.edata) + } + + /DISCARD/ : + { + *(.debug\$S) + *(.debug\$T) + *(.debug\$F) + *(.drectve) + } + + .idata ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* This cannot currently be handled with grouped sections. + See pe.em:sort_sections. */ + ${R_IDATA} + } + .CRT ${RELOCATING+BLOCK(__section_alignment__)} : + { + ${R_CRT} + } + + .endjunk ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* end is deprecated, don't use it */ + ${RELOCATING+ end = .;} + ${RELOCATING+ _end = .;} + ${RELOCATING+ __end__ = .;} + } + + .reloc ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.reloc) + } + + .rsrc ${RELOCATING+BLOCK(__section_alignment__)} : + { + *(.rsrc) + ${R_RSRC} + } + + .stab ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + + .stabstr ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } + +} +EOF diff --git a/ld/scripttempl/ppcpe.sc b/ld/scripttempl/ppcpe.sc new file mode 100644 index 0000000..40fbe33 --- /dev/null +++ b/ld/scripttempl/ppcpe.sc @@ -0,0 +1,198 @@ +# A PE linker script for PowerPC. +# Loosely based on Steve Chamberlain's pe.sc. +# All new mistakes should be credited to Kim Knuttila (krk@cygnus.com) +# +# These are substituted in as variables in order to get '}' in a shell +# conditional expansion. +INIT='.init : { *(.init) }' +FINI='.fini : { *(.fini) }' +cat <<EOF +OUTPUT_FORMAT(${OUTPUT_FORMAT}) +${LIB_SEARCH_DIRS} + +/* Much of this layout was determined by delving into .exe files for + the box generated by other compilers/linkers/etc. This means that + if a particular feature did not happen to appear in one of the + subject files, then it may not be yet supported. +*/ + +/* It's "mainCRTStartup", not "_mainCRTStartup", and it's located in + one of the two .lib files (libc.lib and kernel32.lib) that currently + must be present on the link line. This means that you must use + "-u mainCRTStartup" to make sure it gets included in the link. +*/ + +ENTRY(mainCRTStartup) + +SECTIONS +{ + + /* text - the usual meaning */ + .text ${RELOCATING+ __image_base__ + __section_alignment__ } : + { + ${RELOCATING+ *(.init);} + *(.text) + *(.gcc_except_table) + ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1); *(.ctors); *(.ctor); LONG (0); } + ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); LONG (0); } + ${RELOCATING+ *(.fini);} + ${RELOCATING+ etext = .}; + } + + /* rdata - Read Only Runtime Data + CTR sections: All of the CRT (read only C runtime data) sections + appear at the start of the .rdata (read only runtime data) + section, in the following order. Don't know if it matters or not. + Not all sections are always present either. + .rdata: compiler generated read only data + .xdata: compiler generated exception handling table. (Most docs + seem to suggest that this section is now deprecated infavor + of the ydata section) + .edata: The exported names table. + */ + .rdata BLOCK(__section_alignment__) : + { + *(.CRT\$XCA); + *(.CRT\$XCC); + *(.CRT\$XCZ); + *(.CRT\$XIA); + *(.CRT\$XIC); + *(.CRT\$XIZ); + *(.CRT\$XLA); + *(.CRT\$XLZ); + *(.CRT\$XPA); + *(.CRT\$XPX); + *(.CRT\$XPZ); + *(.CRT\$XTA); + *(.CRT\$XTZ); + *(.rdata); + *(.xdata); + } + + .edata BLOCK(__section_alignment__) : + { + *(.edata); + } + + /* data - initialized data + .ydata: exception handling information. + .data: the usual meaning. + .data2: more of the same. + .bss: For some reason, bss appears to be included in the data + section, as opposed to being given a section of it's own. + COMMON: + */ + .data BLOCK(__section_alignment__) : + { + __data_start__ = . ; + *(.ydata); + *(.data); + *(.data2); + __bss_start__ = . ; + *(.bss) ; + *(COMMON); + __bss_end__ = . ; + ${RELOCATING+ end = .}; + __data_end__ = . ; + } + + /* The exception handling table. A sequence of 5 word entries. Section + address and extent are placed in the DataDirectory. + */ + .pdata BLOCK(__section_alignment__) : + { + *(.pdata) + ; + } + + /* The idata section is chock full of magic bits. + 1. Boundaries around various idata parts are used to initialize + some of the fields of the DataDirectory. In particular, the + magic for 2, 4 and 5 are known to be used. Some compilers + appear to generate magic section symbols for this purpose. + Where we can, we catch such symbols and use our own. This of + course is something less than a perfect strategy. + 2. The table of contents is placed immediately after idata4. + The ".private.toc" sections are generated by the ppc bfd. The + .toc variable is generated by gas, and resolved here. It is + used to initialized function descriptors (and anyone else who + needs the address of the module's toc). The only thing + interesting about it at all? Most ppc instructions using it + have a 16bit displacement field. The convention for addressing + is to initialize the .toc value to 32K past the start of the + actual toc, and subtract 32K from all references, thus using + the entire 64K range. Naturally, the reloc code must agree + on this number or you get pretty stupid results. + */ + .idata BLOCK(__section_alignment__) : + { + __idata2_magic__ = .; + *(.idata\$2); + __idata3_magic__ = .; + *(.idata\$3); + __idata4_magic__ = .; + *(.idata\$4); + . = ALIGN(4); + .toc = . + 32768; + *(.private.toc); + __idata5_magic__ = .; + *(.idata\$5); + __idata6_magic__ = .; + *(.idata\$6); + __idata7_magic__ = .; + *(.idata\$7); + ; + } + + /* reldata -- data that requires relocation + */ + .reldata BLOCK(__section_alignment__) : + { + *(.reldata) + ; + } + + + /* Resources */ + .rsrc BLOCK(__section_alignment__) : + { + *(.rsrc\$01) + *(.rsrc\$02) + ; + } + + .stab BLOCK(__section_alignment__) ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + + .stabstr BLOCK(__section_alignment__) ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } + + /* The .reloc section is currently generated by the dlltool from Steve + Chamberlain in a second pass of linking. Section address and extent + are placed in the DataDirectory. + */ + .reloc BLOCK(__section_alignment__) : + { + *(.reloc) + ; + } + + /* We don't do anything useful with codeview debugger support or the + directive section (yet). Hopefully, we junk them correctly. + */ + /DISCARD/ BLOCK(__section_alignment__) : + { + *(.debug\$S) + *(.debug\$T) + *(.debug\$F) + *(.drectve) + ; + } +} +EOF diff --git a/ld/scripttempl/psos.sc b/ld/scripttempl/psos.sc new file mode 100644 index 0000000..ab8c6c7 --- /dev/null +++ b/ld/scripttempl/psos.sc @@ -0,0 +1,61 @@ +cat <<EOF +OUTPUT_FORMAT(${OUTPUT_FORMAT}) +OUTPUT_ARCH(${ARCH}) +${RELOCATING+${LIB_SEARCH_DIRS}} + +SECTIONS +{ + .text ${RELOCATING:-0} ${RELOCATING+${TEXT_START_ADDR}} : { + ${RELOCATING+ start = DEFINED(_START) ? _START : DEFINED(_start) ? _start : .;} + ${RELOCATING+ PROVIDE(__text = .);} + *(.text); + *(code); + *(const); + *(strings); + *(pSOS); + *(pROBE); + *(pNA); + *(pHILE); + *(pREPC); + *(pRPC); + ${CONSTRUCTING+ ___CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0);} + ${CONSTRUCTING+ ___CTOR_END__ = .;} + ${CONSTRUCTING+ ___DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2);} + ${CONSTRUCTING+ *(.dtors);} + ${CONSTRUCTING+ LONG(0);} + ${CONSTRUCTING+ ___DTOR_END__ = .;} + ${RELOCATING+ PROVIDE(__etext = .);} + ${RELOCATING+ PROVIDE(_etext = .);} + } + .data ${RELOCATING:-0} : ${RELOCATING+ AT(ADDR(.text) + SIZEOF(.text))} { + ${RELOCATING+ PROVIDE(__data = .);} + *(.data); + *(vars); + ${RELOCATING+ PROVIDE(__edata = .);} + ${RELOCATING+ PROVIDE(_edata = .);} + } + .bss ${RELOCATING:-0} : + { + ${RELOCATING+ PROVIDE(__bss = .);} + *(.bss); + *(zerovars); + *(COMMON); + ${RELOCATING+ PROVIDE(__ebss = .);} + ${RELOCATING+ PROVIDE(__end = .);} + ${RELOCATING+ PROVIDE(_end = .);} + ${RELOCATING+ PROVIDE(_FreeMemStart = .);} + } + .stab 0 ${RELOCATING+(NOLOAD)} : + { + *(.stab); + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + *(.stabstr); + } +} +EOF diff --git a/ld/scripttempl/riscix.sc b/ld/scripttempl/riscix.sc new file mode 100644 index 0000000..c801a0c --- /dev/null +++ b/ld/scripttempl/riscix.sc @@ -0,0 +1,35 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +${RELOCATING+__DYNAMIC = 0;} +${STACKZERO+${RELOCATING+${STACKZERO}}} +${SHLIB_PATH+${RELOCATING+${SHLIB_PATH}}} +SECTIONS +{ + .text ${RELOCATING+${TEXT_START_ADDR}}: + { + CREATE_OBJECT_SYMBOLS + *(.text) + ${PAD_TEXT+${RELOCATING+. = ${DATA_ALIGNMENT};}} + ${RELOCATING+_etext = ${DATA_ALIGNMENT};} + ${RELOCATING+__etext = ${DATA_ALIGNMENT};} + } + .data ${RELOCATING+${DATA_ALIGNMENT}} : + { + *(.data) + ${CONSTRUCTING+CONSTRUCTORS} + ${RELOCATING+_edata = .;} + ${RELOCATING+__edata = .;} + } + .bss ${RELOCATING+SIZEOF(.data) + ADDR(.data)} : + { + ${RELOCATING+ __bss_start = .}; + *(.bss) + *(COMMON) + ${RELOCATING+_end = ALIGN(4) }; + ${RELOCATING+__end = ALIGN(4) }; + } +} +EOF diff --git a/ld/scripttempl/sa29200.sc b/ld/scripttempl/sa29200.sc new file mode 100644 index 0000000..a2f267e --- /dev/null +++ b/ld/scripttempl/sa29200.sc @@ -0,0 +1,44 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +ENTRY(start) + +SECTIONS { + .text ${RELOCATING+${TEXT_START_ADDR}} : + { + *(.text); + *(.text1); + *(.text2); + ${RELOCATING+_etext = .}; + } + .lit ALIGN(4) : + { + *(.lit); + ${RELOCATING+_elit = .}; + } + .data ALIGN(4) : + { + *(.data); + *(.data1); + *(.data2); + ${RELOCATING+_edata = .}; + ${CONSTRUCTING+CONSTRUCTORS} + ${CONSTRUCTING+ ___CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ ___CTOR_END__ = .;} + ${CONSTRUCTING+ ___DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ ___DTOR_END__ = .;} + } + + .bss ALIGN(4) : + { + *(COMMON) + *(.bss) + ${RELOCATING+_end = .}; + } +} +EOF diff --git a/ld/scripttempl/sh.sc b/ld/scripttempl/sh.sc new file mode 100644 index 0000000..036dd21 --- /dev/null +++ b/ld/scripttempl/sh.sc @@ -0,0 +1,59 @@ +TORS=".tors : + { + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; + } > ram" + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +MEMORY +{ + ram : o = 0x1000, l = 512k +} + +SECTIONS +{ + .text : + { + *(.text) + *(.strings) + ${RELOCATING+ _etext = . ; } + } ${RELOCATING+ > ram} + ${CONSTRUCTING+${TORS}} + .data : + { + *(.data) + ${RELOCATING+ _edata = . ; } + } ${RELOCATING+ > ram} + .bss : + { + ${RELOCATING+ _bss_start = . ; } + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } ${RELOCATING+ > ram} + .stack ${RELOCATING+ 0x30000 } : + { + ${RELOCATING+ _stack = . ; } + *(.stack) + } ${RELOCATING+ > ram} + .stab 0 ${RELOCATING+(NOLOAD)} : + { + *(.stab) + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + *(.stabstr) + } +} +EOF + + + + diff --git a/ld/scripttempl/sparccoff.sc b/ld/scripttempl/sparccoff.sc new file mode 100644 index 0000000..6bbb7ad --- /dev/null +++ b/ld/scripttempl/sparccoff.sc @@ -0,0 +1,48 @@ +# Linker script for Sparc COFF. +# Based on i386coff.sc by Ian Taylor <ian@cygnus.com>. +test -z "$ENTRY" && ENTRY=_start +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + .text ${RELOCATING+ SIZEOF_HEADERS} : { + *(.init) + *(.text) + ${RELOCATING+ etext = .;} + ${CONSTRUCTING+ ___CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ ___CTOR_END__ = .;} + ${CONSTRUCTING+ ___DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ ___DTOR_END__ = .;} + *(.fini) + ${RELOCATING+ etext = .}; + } + .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : { + *(.data) + ${RELOCATING+ edata = .}; + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + *(.bss) + *(COMMON) + ${RELOCATING+ end = .}; + } + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/sparclynx.sc b/ld/scripttempl/sparclynx.sc new file mode 100644 index 0000000..c2b1e1d --- /dev/null +++ b/ld/scripttempl/sparclynx.sc @@ -0,0 +1,47 @@ +# Linker script for Sparc LynxOS. +test -z "$ENTRY" && ENTRY=_start +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + .text ${RELOCATING+ SIZEOF_HEADERS} : { + *(.init) + *(.text) + ${RELOCATING+ etext = .;} + ${CONSTRUCTING+ ___CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.ctors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ ___CTOR_END__ = .;} + ${CONSTRUCTING+ ___DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ LONG(0)} + ${CONSTRUCTING+ ___DTOR_END__ = .;} + *(.fini) + ${RELOCATING+ etext = .}; + } + .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : { + *(.data) + ${RELOCATING+ edata = .}; + } + .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : + { + *(.bss) + *(COMMON) + ${RELOCATING+ end = .}; + } + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/st2000.sc b/ld/scripttempl/st2000.sc new file mode 100644 index 0000000..7ee132a --- /dev/null +++ b/ld/scripttempl/st2000.sc @@ -0,0 +1,26 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + + +SECTIONS +{ +.text : + { + *(.text) + *(.strings) + _etext = .; + *(.data) + _edata = .; + *(.bss) + *(COMMON) + _end = .; + +} + +} +EOF + + + + diff --git a/ld/scripttempl/tic30aout.sc b/ld/scripttempl/tic30aout.sc new file mode 100644 index 0000000..28baed3 --- /dev/null +++ b/ld/scripttempl/tic30aout.sc @@ -0,0 +1,34 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +${STACKZERO+${RELOCATING+${STACKZERO}}} +${RELOCATING+PROVIDE (__stack = 0);} +SECTIONS +{ + ${RELOCATING+. = ${TEXT_START_ADDR};} + .text : + { + CREATE_OBJECT_SYMBOLS + *(.text) + ${RELOCATING+_etext = .;} + ${RELOCATING+__etext = .;} + ${PAD_TEXT+${RELOCATING+. = ${DATA_ALIGNMENT};}} + } + ${RELOCATING+. = ${DATA_ALIGNMENT};} + .data : + { + *(.data) + ${RELOCATING+_edata = .;} + ${RELOCATING+__edata = .;} + } + .bss : + { + ${RELOCATING+ __bss_start = .}; + *(.bss) + *(COMMON) + ${RELOCATING+_end = ALIGN(4) }; + ${RELOCATING+__end = ALIGN(4) }; + } +} +EOF diff --git a/ld/scripttempl/tic30coff.sc b/ld/scripttempl/tic30coff.sc new file mode 100644 index 0000000..df2d4f7 --- /dev/null +++ b/ld/scripttempl/tic30coff.sc @@ -0,0 +1,58 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH("${OUTPUT_ARCH}") + +MEMORY +{ + rom : ORIGIN = 0x00000300, LENGTH = 16k + ram : ORIGIN = 0x00000300 + 16k, LENGTH = 16k + ramblk0 : ORIGIN = 0x02026000, LENGTH = 0x1000 + ramblk1 : ORIGIN = 0x02027000, LENGTH = 0x1000 +} + +SECTIONS +{ +.vectors 0x00000000 : +{ + *(vectors) +} + +.text : +{ + *(.text) +} > rom + +.const : +{ + *(.const) + __etext = . ; +} > rom + +.mdata : AT( ADDR(.const) + SIZEOF(.const) ) +{ + __data = . ; + *(.data); + __edata = . ; +} > ram + +.bss : +{ + __bss = . ; + *(.bss); + *(COMMON); + __ebss = . ; +} > ram + +.ram0 : +{ + *(ram0) +} > ramblk0 + +.ram1 : +{ + *(ram1) +} > ramblk1 + +} + +EOF diff --git a/ld/scripttempl/tic80coff.sc b/ld/scripttempl/tic80coff.sc new file mode 100644 index 0000000..2b6f653 --- /dev/null +++ b/ld/scripttempl/tic80coff.sc @@ -0,0 +1,74 @@ +# Linker script for TI TMS320C80 (tic80) COFF. +# +# Besides the shell variables set by the emulparams script, and the LD_FLAG +# variable, the genscripts.sh script will set the following variables for each +# time this script is run to generate one of the linker scripts for ldscripts: +# +# RELOCATING: Set to a non-empty string when the linker is going to be doing +# a final relocation. +# +# CONSTRUCTING: Set to a non-empty string when the linker is going to be +# building global constructor and destructor tables. +# +# DATA_ALIGNMENT: Set to an ALIGN expression when the output should be page +# aligned, or to "." when generating the -N script. +# +# CREATE_SHLIB: Set to a non-empty string when generating a script for +# the -shared linker arg. + +test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x80000 + SIZEOF_HEADERS" +test -z "$ENTRY" && ENTRY=__start + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +${LIB_SEARCH_DIRS} + +ENTRY(${ENTRY}) + +SECTIONS +{ + .text ${RELOCATING+ $TEXT_START_ADDR} : { + *(.init) + *(.fini) + *(.text) + } + .const ALIGN(4) : { + *(.const) + } + .ctors ALIGN(4) : { + ${CONSTRUCTING+ . = ALIGN(4);} + ${CONSTRUCTING+ ___CTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG(-1)} + *(.ctors) + ${CONSTRUCTING+ ___CTOR_END__ = .;} + ${CONSTRUCTING+ LONG(0)} + } + .dtors ALIGN(4) : { + ${CONSTRUCTING+ ___DTOR_LIST__ = .;} + ${CONSTRUCTING+ LONG(-1)} + ${CONSTRUCTING+ *(.dtors)} + ${CONSTRUCTING+ ___DTOR_END__ = .;} + ${CONSTRUCTING+ LONG(0)} + } + ${RELOCATING+ etext = .;} + .data : { + *(.data) + ${RELOCATING+ __edata = .}; + } + .bss : { + ${RELOCATING+ __bss_start = .}; + *(.bss) + *(COMMON) + ${RELOCATING+ _end = ALIGN(0x8)}; + ${RELOCATING+ __end = ALIGN(0x8)}; + } + .stab 0 ${RELOCATING+(NOLOAD)} : + { + [ .stab ] + } + .stabstr 0 ${RELOCATING+(NOLOAD)} : + { + [ .stabstr ] + } +} +EOF diff --git a/ld/scripttempl/v850.sc b/ld/scripttempl/v850.sc new file mode 100644 index 0000000..6b2f7e5 --- /dev/null +++ b/ld/scripttempl/v850.sc @@ -0,0 +1,204 @@ +cat << EOF +OUTPUT_FORMAT("elf32-v850", "elf32-v850", + "elf32-v850") +OUTPUT_ARCH(v850) +ENTRY(_start) +SEARCH_DIR(.); +/*/critters/slug/grossman/install/sun4/v850-elf/lib*/ +SECTIONS +{ + /* This saves a little space in the ELF file, since the zda starts + at a higher location that the ELF headers take up. */ + + .zdata ${ZDATA_START_ADDR} : { + *(.zdata) + *(.zbss) + *(reszdata) + *(.zcommon) + } + + /* This is the read only part of the zero data area. + Having it as a seperate section prevents its + attributes from being inherited by the zdata + section. Specifically it prevents the zdata + section from being marked READONLY. */ + + .rozdata ${ROZDATA_START_ADDR} : { + *(.rozdata) + *(romzdata) + *(romzbss) + } + + /* Read-only sections, merged into text segment: */ + . = ${TEXT_START_ADDR}; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { KEEP (*(.init)) } =0 + .plt : { *(.plt) } + + .text : { + *(.text) + ${RELOCATING+*(.text.*)} + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0 + + ${RELOCATING+_etext = .;} + ${RELOCATING+PROVIDE (etext = .);} + + /* This is special code area at the end of the normal text section. + It contains a small lookup table at the start followed by the + code pointed to by entries in the lookup table. */ + + .call_table_data ${CALL_TABLE_START_ADDR} : { + ${RELOCATING+PROVIDE(__ctbp = .);} + *(.call_table_data) + } = 0xff /* fill gaps with 0xff */ + .call_table_text : { + *(.call_table_text) + } + + .fini : { KEEP (*(.fini)) } =0 + .rodata : { *(.rodata) ${RELOCATING+*(.rodata.*)} *(.gnu.linkonce.r*) } + .rodata1 : { *(.rodata1) } + + .data : { + *(.data) + ${RELOCATING+*(.data.*)} + *(.gnu.linkonce.d*) + CONSTRUCTORS + } + .data1 : { *(.data1) } + .ctors : { + ${RELOCATING+___ctors = .;} + KEEP (*(.ctors)) + ${RELOCATING+___ctors_end = .;} + } + + .dtors : { + ${RELOCATING+___dtors = .;} + KEEP (*(.dtors)) + ${RELOCATING+___dtors_end = .;} + } + + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + + .tdata ${TDATA_START_ADDR} : { + ${RELOCATING+PROVIDE (__ep = .);} + *(.tbyte) + *(.tcommon_byte) + *(.tdata) + *(.tbss) + *(.tcommon) + } + + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata ${SDATA_START_ADDR} : { + ${RELOCATING+PROVIDE (__gp = . + 0x8000);} + *(.sdata) + } + + /* See comment about .rozdata. */ + .rosdata ${ROSDATA_START_ADDR} : { + *(.rosdata) + } + + /* We place the .sbss data section AFTER the .rosdata section, so that + it can directly preceed the .bss section. This allows runtime startup + code to initialise all the zero-data sections by simply taking the + value of '_edata' and zeroing until it reaches '_end' */ + .sbss : { + ${RELOCATING+__sbss_start = .;} + *(.sbss) + *(.scommon) + } + + ${RELOCATING+_edata = DEFINED (__sbss_start) ? __sbss_start : . ;} + ${RELOCATING+PROVIDE (edata = _edata);} + + .bss : + { + ${RELOCATING+__bss_start = DEFINED (__sbss_start) ? __sbss_start : . ;} + ${RELOCATING+__real_bss_start = . ;} + *(.dynbss) + *(.bss) + *(COMMON) + } + + ${RELOCATING+_end = . ;} + ${RELOCATING+PROVIDE (end = .);} + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + /* User stack */ + .stack 0x200000 : { + ${RELOCATING+__stack = .;} + *(.stack) + } + /* These must appear regardless of . */ +} +EOF diff --git a/ld/scripttempl/vanilla.sc b/ld/scripttempl/vanilla.sc new file mode 100644 index 0000000..1798480 --- /dev/null +++ b/ld/scripttempl/vanilla.sc @@ -0,0 +1 @@ +# Nothing to do. diff --git a/ld/scripttempl/w65.sc b/ld/scripttempl/w65.sc new file mode 100644 index 0000000..f904495 --- /dev/null +++ b/ld/scripttempl/w65.sc @@ -0,0 +1,58 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH(${ARCH}) + +MEMORY { + ram : o = 0x1000, l = 512k + } + +SECTIONS +{ +.text : + { + *(.text) + *(.strings) + ${RELOCATING+ _etext = . ; } + } ${RELOCATING+ > ram} + + +.tors : { + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; +} ${RELOCATING+ > ram} + +.data : + { + *(.data) + ${RELOCATING+ _edata = . ; } + } ${RELOCATING+ > ram} +.bss : + { + ${RELOCATING+ _bss_start = . ; } + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } ${RELOCATING+ >ram} +.stack ${RELOCATING+ 0x30000 } : + { + ${RELOCATING+ _stack = . ; } + *(.stack) + } ${RELOCATING+ > ram} + .stab . (NOLOAD) : + { + [ .stab ] + } + .stabstr . (NOLOAD) : + { + [ .stabstr ] + } +} +EOF + + + + diff --git a/ld/scripttempl/z8000.sc b/ld/scripttempl/z8000.sc new file mode 100644 index 0000000..2b87930 --- /dev/null +++ b/ld/scripttempl/z8000.sc @@ -0,0 +1,54 @@ +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}") +OUTPUT_ARCH("${OUTPUT_ARCH}") +ENTRY(_start) + +SECTIONS +{ +.text ${BIG+ ${RELOCATING+ 0x0000000}} : { + *(.text) + *(.strings) + *(.rdata) + } + +.ctors ${BIG+ ${RELOCATING+ 0x2000000}} : + { + ${RELOCATING+ ___ctors = . ; } + *(.ctors); + ${RELOCATING+ ___ctors_end = . ; } + ___dtors = . ; + *(.dtors); + ${RELOCATING+ ___dtors_end = . ; } + } + +.data ${BIG+ ${RELOCATING+ 0x3000000}} : { + *(.data) + } + +.bss ${BIG+ ${RELOCATING+ 0x4000000}} : + { + ${RELOCATING+ __start_bss = . ; } + *(.bss); + *(COMMON); + ${RELOCATING+ __end_bss = . ; } + } + +.heap ${BIG+ ${RELOCATING+ 0x5000000}} : { + ${RELOCATING+ __start_heap = . ; } + ${RELOCATING+ . = . + 20k ; } + ${RELOCATING+ __end_heap = . ; } + } + +.stack ${RELOCATING+ 0xf000 } : + { + ${RELOCATING+ _stack = . ; } + *(.stack) + ${RELOCATING+ __stack_top = . ; } + } + +} +EOF + + + + diff --git a/ld/stamp-h.in b/ld/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/ld/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/ld/sysdep.h b/ld/sysdep.h new file mode 100644 index 0000000..2ccc122 --- /dev/null +++ b/ld/sysdep.h @@ -0,0 +1,73 @@ +/* sysdep.h -- handle host dependencies for the GNU linker + Copyright (C) 1995, 96, 1997 Free Software Foundation, Inc. + + This file is part of GLD, the Gnu Linker. + + GLD is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GLD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GLD; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef LD_SYSDEP_H +#define LD_SYSDEP_H + +#include "ansidecl.h" + +#include "config.h" + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef HAVE_STRING_H +#include <string.h> +#else +#ifdef HAVE_STRINGS_H +#include <strings.h> +#else +extern char *strchr (); +extern char *strrchr (); +#endif +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef USE_BINARY_FOPEN +#include "fopen-bin.h" +#else +#include "fopen-same.h" +#endif + +#ifdef NEED_DECLARATION_STRSTR +extern char *strstr (); +#endif + +#ifdef NEED_DECLARATION_FREE +extern void free (); +#endif + +#ifdef NEED_DECLARATION_GETENV +extern char *getenv (); +#endif + +#ifdef NEED_DECLARATION_ENVIRON +extern char **environ; +#endif + +#endif /* ! defined (LD_SYSDEP_H) */ diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog new file mode 100644 index 0000000..6610cbf --- /dev/null +++ b/ld/testsuite/ChangeLog @@ -0,0 +1,731 @@ +1999-03-05 Nick Clifton <nickc@cygnus.com> + + * ld-selective/selective.exp: Do not run tests for COFF or PE + based ports. + +1999-02-17 Nick Clifton <nickc@cygnus.com> + + * ld-undefined/undefined.exp: Add expected failures for StrongARM + targets. + + * ld-srec/srec.exp: Add expected failures for StrongARM targets. + + * ld-selective/selective.exp: Add expected failure for ARM-COFF + targets. + +1999-02-16 Nick Clifton <nickc@cygnus.com> + + * ld-checks/asm.s: Use .long instead of .word. + Replace custom section names with .text, .data and .bss. + * ld-checks/script: Replace custom section names with .text, .data + and .bss. + * ld-checks/checks.exp: Replace custom section names with .text, + .data and .bss. + +1999-02-11 Nick Clifton <nickc@cygnus.com> + + * ld-checks: New directory: Tests for the linker's + --check-sections option. + * ld-checks/checks.exp: New file. + * ld-checks/script: Bogus linker script. + * ld-checks/asm.s: Simple test assembler file. + +Tue Feb 2 19:15:02 1999 Catherine Moore <clm@cygnus.com> + + * ld-selective/selective.exp: Disable test for unsupported + targets. Change tests to check for absence of symbols instead + of address zero. + +Mon Jan 18 03:44:52 1999 Ian Lance Taylor <ian@cygnus.com> + + * config/default.exp (get_link_files): Quote target_triplet and CC + when invoking shell. + (get_target_emul): Likewise. + +1999-01-03 Ken Raeburn <raeburn@cygnus.com> + + * config/default.exp (get_link_files, get_target_emul): New procs; + run shell commands to extract information from configure.host and + configure.tgt in the source tree. + (top level): Use them to get information needed to run tests, if + not otherwise provided. + + * ld-shared/elf-offset.ld: New file. Builds a shared library, but + gives non-zero addresses for memory region. + * ld-shared/shared.exp: Run the non-PIC non-AIX test again using + the new linker script. + +Tue Dec 8 22:56:05 1998 Geoff Keating <geoffk@ozemail.com.au> + + * ld-srec/srec.exp: Delete xfails for PPC Linux targets, + newer glibc lets link succeed. + +Sun Dec 6 12:59:37 1998 H.J. Lu <hjl@gnu.org> + + * ld-elfvers/vers1.c: Add missing return types and values. + * ld-elfvers/vers2.c: Likewise. + * ld-elfvers/vers3.c: Likewise. + * ld-elfvers/vers4.c: Likewise. + * ld-elfvers/vers5.c: Likewise. + * ld-elfvers/vers6.c: Likewise. + * ld-elfvers/vers7.c: Likewise. + * ld-elfvers/vers9.c: Likewise. + * ld-elfvers/vers15.c: Likewise. + +Fri Oct 23 16:28:29 1998 Catherine Moore <clm@cygnus.com> + + * ld-selective: New directory with new files to test + selective linking. + + * lib/ld-lib.exp (ld_nm): Strip leading underscore from $name. + +Sun Oct 4 22:17:05 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld-elfvers/vers16.dsym: Work correctly on a system without + versioned system libraries. + +Mon Sep 28 21:31:12 1998 Richard Henderson <rth@cygnus.com> + + * ld-elfvers/vers.exp: Run tests on alpha-linux. + * ld-elfvers/*.sym, ld-elfvers/*.dsym: Adjust patters to match + Alpha's use of st_other. + +1998-09-27 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * ld-elfvers/vers.exp (vers16, vers16a): New tests. + * ld-elfvers/{vers16.*, vers16a.*}: New files. + +Thu Sep 17 17:18:19 1998 Nick Clifton <nickc@cygnus.com> + + * ld-undefined/undefined.exp: Make undefined line test be an xfail + for arm/thunb elf toolchains. + +Wed Sep 9 14:10:15 1998 Nick Clifton <nickc@cygnus.com> + + * ld-undefined/undefined.exp: change test for elf/dwarf2 targets. + + * ld-srec/srec.exp: Arm-elf now passes this test. + +Wed Aug 19 11:59:19 1998 Nick Clifton <nickc@cygnus.com> + + * ld-srec/srec.exp: Add arm/thumb-elf expected failures. + +Thu Aug 13 12:41:58 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld-bootstrap/bootstrap.exp: Don't run the --static bootstrap + test if we don't have a static libbfd.a. + +Wed Aug 12 15:19:35 1998 Ian Lance Taylor <ian@cygnus.com> + + Based on patch from H.J. Lu <hjl@gnu.org>: + * ld-srec/srec.exp: Add xfails for Alpha ELF targets. + +Mon Aug 10 15:42:20 1998 Richard Henderson <rth@cygnus.com> + + * ld-scripts/weak.t (.text, .data): Focus data to be used. + (/DISCARD/): All the rest. + * ld-scripts/weak1.s, ld-scripts/weak2.s: Put stuff in .data. + +Fri Jul 24 18:37:17 1998 Ian Lance Taylor <ian@cygnus.com> + + * config/default.exp: Create tmpdir/gas subdirectory, add a + symlink to as-new, and set gcc_gas_flag variable. + * lib/ld-lib.exp (default_ld_compile): If the compiler appears to + be gcc, use gcc_gas_flag when compiling. + +Thu Jul 23 12:23:29 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld-elfvers/vers.exp: Just check for i?86 rather than checking + for i386, i486, and i586. + (objdump_versionstuff): If we can't find the line, dump the file. + +Fri Jul 3 00:27:41 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/phdrs.exp: Run test on *-*-eabi*. + * ld-scripts/weak.exp: Likewise. + +Wed Jul 1 10:51:46 1998 Nick Clifton <nickc@cygnus.com> + + * ld-srec/srec.exp: Add xfail for v850. + + * ld-undefined/undefined.exp: arm and thumb PE toolchains now pass + these tests. + +Fri Jun 19 17:12:52 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/weak.exp: New test. + * ld-scripts/weak.t: New file. + * ld-scripts/weak1.s: New file. + * ld-scripts/weak2.s: New file. + +Tue Jun 16 12:40:38 1998 Geoff Keating <geoffk@ozemail.com.au> + + * ld-elfvers/vers.exp: Run tests on powerpc ELF targets. + * ld-shared/shared.exp: Likewise. + * ld-elfvers/vers1.dsym: Allow for .sdata. + * ld-srec/srec.exp: Add setup_xfails for PowerPC Linux. + +Fri May 29 15:02:50 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: Add xfails for powerpc*-*-eabi. + (run_srec_test): On mn10200, define __truncsipsi2_do_d2. + * ld-srec/sr1.c (__main): Change return type to void. + * ld-srec/sr3.cc (__main): Likewise. + (__builtin_delete, __builtin_new): Likewise. + (__get_dynamic_handler_chain): Return 0. + (__get_eh_context): Likewise. + +Thu May 21 15:21:33 1998 Nick Clifton <nickc@cygnus.com> + + * ld-undefined/undefined.exp: Add support for thumb-pe target. + * ld-srec/srec.exp: Add support for arm-pe and thumb-pe targets. + +Mon May 4 17:54:20 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * ld-shared/shared.exp: Remove setup_xfails for m68k-linux. + +Mon May 4 17:12:06 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld-shared/main.c (shlib_overriddencall2): New function. + (main): Call shlib_shlibcall2. + * ld-shared/sh1.c (shlib_shlibcall2): New function. + (shlib_overriddencall2): New function. + * ld-shared/shared.dat: Add output line for new test. + * ld-shared/sun4.dat: Likewise. + + * ld-srec/sr3.cc (__get_eh_context): New function. + +Tue Apr 7 12:50:17 1998 Manfred Hollstein <manfred@s-direktnet.de> + + * ld-cdtest/cdtest-foo.h (class Foo): Declare len to be static to + avoid compiler warning. + * ld-srec/sr3.cc (class Foo): Likewise. + +Tue Feb 10 16:42:40 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/sr3.cc (__get_dynamic_handler_chain): New function. + +Mon Feb 2 14:17:48 1998 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/phdrs.exp: Adjust phdrs_regexp for a 64 bit target. + +Thu Dec 18 11:13:28 1997 Nick Clifton <nickc@cygnus.com> + + * ld-srec/srec.exp: Duplicated Arm patch for Thumb targets. + +Tue Dec 2 09:50:19 1997 Nick Clifton <nickc@cygnus.com> + + * ld-srec/srec.exp: Applied patch from Tony.Thompson@arm.com which + fixes ARM tests. + +Mon Dec 1 16:12:05 1997 Nick Clifton <nickc@cygnus.com> + + * ld-srec/srec.exp: Add expected failures of tests 1 and 2 for ARM + coff targets. + +Wed Nov 12 14:18:31 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-cdtest/cdtest-foo.h (class Foo): Declare len to be int to + avoid compiler warning. + * ld-srec/sr3.cc (class Foo): Likewise. + +Mon Nov 10 14:25:43 1997 Ian Lance Taylor <ian@cygnus.com> + + * lib/ld-lib.exp (default_ld_simple_link): Permit the linker to + have any name when looking for entry symbol warnings. + + * ld-srec/sr3.cc (__eh_pc): Define. + +Mon Oct 20 14:36:39 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/sr3.cc: Add definitions for terminate, __terminate, and + __throw, since the current g++ expects them to be defined. + +Fri Oct 3 12:24:03 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-elfvers/vers.exp (objdump_emptyverstuff): Accept the output + file if the string libc appears in it. + (objdump_versionstuff): Accept unexpected lines in the output + file. Compare lines using string match. + * ld-elfvers/vers6.ver: Permit any value in the vna_other field. + +Tue Aug 12 16:01:22 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/crossref.exp: Correct string quoting. + +Sat Aug 9 00:56:03 1997 Ian Lance Taylor <ian@cygnus.com> + + * config/default.exp: Change ld, as, nm and strip from .new to + -new. Load ld-lib.exp rather than ld.exp. + * ld-bootstrap/bootstrap.exp: Use ld-new rather than ld.new. + * lib/ld-lib.exp: Rename from lib/ld.exp, for the benefit of + DejaGnu changes. + +Thu Jun 26 12:07:03 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-elfvers/vers.exp: Use egrep rather than grep when looking for + an alternation. From Greg Margo <gmargo@dl.com>. + +Wed Jun 25 12:47:22 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * ld-shared/shared.exp: Add setup_xfail for m68k-linux on tests + with non PIC shared libraries. + +Fri Jun 6 17:35:47 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-elfvers/vers6.ver: Update for recent elflink.h patch to + version handling. + +Wed Jun 4 12:06:48 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: Define ___get_dynamic_handler_chain as well. + +Fri May 30 12:21:39 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: Define __get_dynamic_handler_chain when + linking. + +Mon May 12 11:17:55 1997 Ian Lance Taylor <ian@cygnus.com> + + * config/default.exp: Use $base_dir rather than $objdir when + setting ld. From John David Anglin <dave@hiauly1.hia.nrc.ca>. + +Fri Apr 25 09:07:00 1997 Jeffrey A Law (law@cygnus.com) + + * ld-srec/srec.exp: Define various out of line prologue/epilogue + functions for the mn10200 to avoid needing libgcc.a. + +Wed Mar 26 13:56:10 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: Don't expect failures on mips*-*-elf*. + +Mon Mar 17 19:27:13 1997 Ian Lance Taylor <ian@cygnus.com> + + * ld-elfvers/vers.exp: Don't run on SunOS or AIX. + +Wed Mar 12 21:44:19 1997 Eric Youngdale <eric@andante.jic.com> + + * ld-elfvers/vers.exp, *: New tests for symbol versioning. + * config/default.exp: Set ar and strip. + +Fri Feb 7 16:47:02 1997 Bob Manson <manson@charmed.cygnus.com> + + * ld-bootstrap/bootstrap.exp: Use prune_warnings instead of + prune_system_crud. + * ld-cdtest/cdtest.exp: Ditto. + * ld-scripts/crossref.exp: Ditto. + * ld-sh/sh.exp: Ditto. + * ld-shared/shared.exp: Ditto. + * ld-srec/srec.exp: Ditto. + * lib/ld.exp: Ditto. + +Wed Jan 29 00:47:29 1997 Bob Manson <manson@charmed.cygnus.com> + + * ld-cdtest/cdtest.exp: Put a slash between $srcdir/$subdir. + * ld-scripts/script.exp: Ditto. + * ld-sh/sh.exp: Ditto. + * ld-undefined/undefined.exp: Ditto. + * ld-versados/versados.exp: Ditto. + * lib/ld.exp: Ditto. + +Mon Dec 30 17:08:04 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/crossref.exp: Fix quoting for --defsym $global$. + +Tue Oct 1 15:52:31 1996 Ian Lance Taylor <ian@cygnus.com> + + * lib/ld.exp (default_ld_version): Fix for current version + printing. + +Fri Sep 13 15:51:45 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/crossref.exp: Define $global$ for hppa-elf. + +Thu Aug 8 14:29:32 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/cross2.t: Map XCOFF sections to .text or .data. + + * lib/ld.exp: Use verbose -log instead of calling both verbose and + send_log. + +Wed Aug 7 18:00:58 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/phdrs.exp: New test. + * ld-scripts/phdrs.s, ld-scripts/phdrs.t: New files. + +Sun Aug 4 21:58:12 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/crossref.exp: On a29k targets, use --defsym to define + V_SPILL and V_FILL. + +Thu Aug 1 14:10:27 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/crossref.exp: New test. + * ld-scripts/{cross1.c, cross2.c, cross3.c}: New files. + * ld-scripts/{cross1.t, cross2.t}: New files. + +Sat Jun 29 13:40:11 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-sh/sh.exp: Fix debugging messages. + * ld-sh/sh1.s: Use .align 4. + +Wed May 1 16:45:13 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-sh/sh.exp: Use -O when compiling with -mrelax. + +Mon Apr 29 10:33:10 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * ld-shared/shared.exp: Run the shared library tests on + Linux/m68k. + +Fri Apr 5 16:20:55 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-shared/shared.exp: Run the shared library tests on Linux. + +Mon Feb 26 12:45:26 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-shared/shared.exp: Don't use -fpic on MIPS targets. + +Wed Jan 31 15:09:57 1996 Jeffrey A Law (law@cygnus.com) + + * ld-srec/srec.exp: Add xfails for hppa*-*-*elf*. + * ld-undefined/undefined.exp: Likewise. + +Fri Jan 26 18:43:03 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-undefined/undefined.exp: ELF targets should now pass the + undefined line test. + +Thu Jan 25 15:36:13 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-empic/empic.exp: Update for change to MIPS disassembler. + +Mon Jan 15 15:05:53 1996 Ian Lance Taylor <ian@cygnus.com> + + * ld-bootstrap/bootstrap.exp: Expect failure for mips*-*-irix5* + when doing the --static test. + * ld-shared/shared.exp: Run tests on mips*-*-irix5*. + +Fri Dec 29 12:33:09 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-bootstrap/bootstrap.exp: On AIX, don't pass the -bI option + when creating ld-partial.o. + +Tue Dec 26 17:37:23 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: If powerpc*-*-eabi*, use --defsym to define + __eabi. + +Tue Dec 19 18:01:01 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: Add setup_xfails for XCOFF targets. + +Fri Dec 15 16:36:17 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: On a29k targets, use --defsym to define + V_SPILL and V_FILL. + * ld-srec/sr1.c (V_SPILL, V_FILL): Remove definitions. + * ld-srec/sr3.cc: Likewise. + + * ld-srec/srec.exp: Remove i960 COFF setup_xfail. + +Sat Dec 2 01:20:31 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: Don't use [] in setup_xfail expressions. + +Fri Dec 1 13:18:18 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: Add setup_xfails for MIPS ELF targets. + +Wed Nov 29 13:01:10 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: Add setup_xfail for i960 COFF targets. + +Mon Nov 27 14:36:11 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: Add setup_xfail calls for i[345]86-*-aout*. + + * ld-srec/sr1.c (V_SPILL, V_FILL): Define. + * ld-srec/sr3.cc: Likewise. + +Tue Nov 21 16:05:53 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-empic/empic.exp: Update for changes in objdump output. + +Wed Nov 15 17:42:48 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-srec/srec.exp: New tests. + * ld-srec/sr1.c, ld-srec/sr2.c, ld-srec/sr3.cc: New files. + * lib/ld.exp (ld_simple_link): Discard warnings about not being + able to find the entry symbol. + +Tue Nov 14 20:03:54 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-sh/sh2.c (__main): Define. + +Mon Nov 6 14:39:18 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-empic/empic.exp: Accept a . in the address symbol. + + * ld-shared/shared.exp: Run tests on rs6000*-*-aix* and + powerpc*-*-aix*. Add code to create appropriate exports files, + and pass appropriate compilation flags, and test against + appropriate expected output. + * ld-shared/xcoff.dat: New file. + * ld-shared/main.c: Put #ifndef XCOFF_TEST around tests that can + not be linked using XCOFF. Use shlib_shlibvar1 as a sample + function pointer, rather than shlib_mainvar. + * ld-shared/sh1.c: Likewise. + * ld-shared/shared.dat: Update for change from using shlib_mainvar + to using shlib_shlibvar1. + * ld-shared/sun4.dat: Likewise. + +Sat Oct 28 01:54:25 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/script.t: Put .pr in .text, and .rw in .data, for + convenience when testing XCOFF. + +Thu Oct 26 22:53:17 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-bootstrap/bootstrap.exp: On AIX, pass -bI/lib/syscalls.exp + along with --static. + + * ld-scripts/script.s: Make symbols global. + +Fri Oct 20 12:22:16 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-undefined/undefined.exp: Add setup_xfails for arm*-*-pe*. + +Fri Sep 29 11:06:10 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-undefined/undefined.exp: Use -e when invoking the linker, to + prevent the SunOS linker from trying to create a shared library. + +Thu Sep 28 12:37:14 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-shared/shared.exp: Run the tests on sparc*-*-sunos4*. Add + appropriate modifications and setup_xfails. + * ld-shared/sun4.dat: New file. + +Mon Sep 18 14:12:56 1995 Ian Lance Taylor <ian@cygnus.com> + + * lib/ld.exp (default_ld_version): Call prune_system_crud. + (default_ld_relocate, default_ld_link): Likewise. + (default_ld_simple_link, default_ld_compile): Likewise. + (default_ld_assemble, default_ld_nm): Likewise. + +Fri Sep 8 17:15:38 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-cdtest/cdtest.exp: If the compiler does not exist, mark the + tests as untested rather than unresolved. + +Wed Aug 23 10:46:38 1995 Ian Lance Taylor (ian@cygnus.com) + + * ld-sh/sh.exp: Call prune_system_crud on the output of cmp. + +Tue Aug 15 17:35:35 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/script.exp: Split script verification into a proc. + Add simple test of MRI script. + * ld-scripts/scriptm.t: New file. + +Wed Jul 26 11:38:58 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-sh/sh.exp: Mark `SH confirm relaxing' test unresolved when + appropriate. + +Mon Jul 24 15:34:31 1995 Ian Lance Taylor <ian@cygnus.com> + + * config/default.exp: Define objcopy if it is not defined. + * ld-sh/*: New tests for SH relaxing. + + * ld-empic/empic.exp: If $CC does not exist, call untested rather + than unresolved. + +Thu Jul 20 15:09:26 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-undefined/undefined.exp: If $CC does not exist, mark the + tests as untested rather than unresolved. Clear ELF xfails for + mips*, not just mips. + +Tue Jul 18 12:00:41 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-undefined/undefined.exp: Add setup_xfail for sh-*-* for + undefined line test. + +Fri Jul 14 13:07:48 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-undefined/undefined.exp: New test, to check reporting of + undefined symbols. + * ld-undefined/undefined.c: New file. + +Mon Jul 10 11:13:39 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-versados/versados.exp: If a test fails, report it correctly: + don't try to run the next test, and don't report a pass as well as + a fail. + +Mon Jul 3 14:26:37 1995 Steve Chamberlain <sac@slash.cygnus.com> + + * ld/testsuite/versados/(t1,t2).ld: End in newlines. + +Mon May 22 20:19:38 1995 Ken Raeburn <raeburn@cujo.cygnus.com> + + * lib/ld.exp (default_ld_compile): If cc argument is multiple + words, use only the first when trying to verify the availability + of the compiler. + +Mon Feb 6 11:46:49 1995 Ian Lance Taylor <ian@cygnus.com> + + * ld-scripts/defined.t: Mention .data and .bss explicitly. + +Tue Jan 24 14:51:48 1995 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ld-bootstrap/bootstrap.exp: If not in the ld build directory, + call untested for each test, rather than ignoring it. If one test + fails, go on to the next one instead of returning. + * ld-cdtest/cdtest.exp: If compilations fail, mark tests as + unresolved. + * ld-empic/empic.exp: Likewise. Also, always pass the same test + name to pass or fail. + * ld-shared/shared.exp: Likewise. Also, always run all tests. + * ld-scripts/defined.exp: If as or nm fail, mark test as + unresolved. Always pass the same test name to pass or fail. + * ld-scripts/script.exp: Likewise. + * ld-scripts/sizeof.exp: Likewise. + +Wed Jan 11 11:48:31 1995 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ld-scripts/sizeof.exp: New test, based on bug report from + anders.blomdell@control.lth.se. + * ld-scripts/sizeof.s: New file. + * ld-scripts/sizeof.t: New file. + +Wed Jan 4 18:56:27 1995 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * lib/ld.exp: Use [which $ld] rather than [file exists $ld] to see + if the linker exists. + +Wed Dec 14 16:39:03 1994 Ken Raeburn <raeburn@cujo.cygnus.com> + + * lib/ld.exp (prune_system_crud): Define if not already defined, + in case the user isn't using the newest DejaGnu version that we + haven't released to the net yet. + +Fri Dec 2 14:17:02 1994 Ian Lance Taylor <ian@rtl.cygnus.com> + + * config/default.exp: Define objdump if it is not defined. + * ld-empic/*: New tests to test -membedded-pic code. + +Mon Nov 28 11:24:36 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ld-bootstrap/bootstrap.exp: Pass cmp output through + prune_system_crud. + * ld-cdtest/cdtest.exp: Pass diff output through + prune_system_crud. + * ld-shared/shared.exp: Likewise. + + * config/default.exp: Remove unused and useless proc ld_load. + +Sun Oct 30 13:02:34 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * lib/ld.exp (default_ld_compile): Remove the output file before + compiling. + + * ld-shared/shared.exp: Move common test code into a procedure. + Add tests for compiling the non shared code PIC. + * ld-shared/main.c (main): Call main_called, and print the result. + * ld-shared/shared.dat: Adjust accordingly. + +Thu Oct 27 17:30:12 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * ld-shared: New directory, with new files to test generating ELF + shared libraries. + + * lib/ld.exp (default_ld_compile): If the compilation worked, but + no object file was created, check to see if the compiler foolishly + ignored the -o switch when compiling, and move the resulting + object if it did. + +Thu Sep 29 12:36:51 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * VMS does not permits `.' in directory names. Renamed + ld.bootstrap to ld-bootstrap, ld.cdtest to ld-cdtest, and + ld.scripts to ld-scripts. + +Wed Sep 28 12:18:54 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * config/default.exp: Set variables as and nm. Create tmpdir if + it does not already exist. + * ld.bootstrap/bootstrap.exp: Don't create tmpdir here. + * ld.cdtest/cdtest.exp: Likewise. + * ld.scripts/defined.exp: Likewise. Also, don't set as and nm + here. Change perror for no variables found to fail. + * ld.scripts/script.exp: New test. + * ld.scripts/script.t, ld.scripts/script.s: New files. + +Tue Sep 27 14:59:51 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) + + * ld.scripts: New directory. + * ld.scripts/defined.exp, ld.scripts/defined.s: New files. + * ld.scripts/defined.t: New file. + * lib/ld.exp (default_ld_simple_link): New function. + (default_ld_assemble, default_ld_nm): New functions. + * config/default.exp: Rename from unix-ld.exp. + (ld_simple_link, ld_assemble, ld_nm): New functions. + + * config/unix-ld.exp: Set ld using findfile. + * lib/ld.exp (default_ld_relocate): Return a value. Change format + of log messages. + (default_ld_compile): Likewise. + (default_ld_link): Likewise. Also, don't include $BFDLIB and + $LIBIBERTY in link. + * ld.bootstrap/bootstrap.exp: Rewrite. + * ld.cdtest/cdtest.exp: Rewrite. + * ld.cdtest/cdtest-foo.cc: Update from top level ld directory. + * ld.cdtest/cdtest-foo.h: Likewise. + * ld.cdtest/cdtest-main.cc: Likewise. + +Fri May 27 09:35:04 1994 Ken Raeburn (raeburn@cygnus.com) + + * ld.cdtest/cdtest.exp: Don't look for $result before it's + defined. + +Tue May 17 15:06:49 1994 Bill Cox (bill@rtl.cygnus.com) + + * ld.bootstrap/bootstrap.exp, lib/ld.exp: Replace error proc + calls with perror calls. + +Wed May 11 16:47:46 1994 Ken Raeburn (raeburn@rtl.cygnus.com) + + * ld.cdtest/cdtest-bar.cc: Renamed from cdtest-func.cc. + * ld.cdtest/cdtest.exp: Adjusted. + +Fri Jan 28 13:25:41 1994 Ken Raeburn (raeburn@cujo.cygnus.com) + + * lib/ld.exp (simple_diff): Indicate failure if files have + different numbers of lines. Don't muck with $differences to avoid + indicating a pass, just return. + + * testsuite/ld.cdtest/{cdtest-foo.h,cdtest-foo.cc,cdtest-main.cc}: + Fix test case to be valid ANSI C++. Don't require use of header + files, so "../gcc/xgcc -B../gcc/" can be used for CXX. + * testsuite/ld.cdtest/cdtest.exp: Combine "rm" lines. Add some + commentary on things that are still broken with this test case. + +Fri Sep 10 09:58:23 1993 Jeffrey Wheat (cassidy@cygnus.com) + + * testsuite/ld.cdtest/cdtest.exp: Added CXXFLAGS to compile stage. + +Thu Aug 12 16:05:37 1993 Jeffrey Wheat (cassidy@cygnus.com) + + * testsuite/lib/ld.exp: add compiler and linker support + * testsuite/config/unix-ld.exp: add compiler and linker support + * testsuite/ld.bootstrap/bootstrap.exp: fixed to do partial links + * testsuite/ld.cdtest/cdtest.exp: constructor/destructor testscase + +Wed Aug 4 21:00:18 1993 Jeffrey Wheat (cassidy@cygnus.com) + + * testsuite/lib/ld.exp: new file + * testsuite/config/unix-ld.exp: new file + * testsuite/ld.bootstrap/bootstrap.exp: new file diff --git a/ld/testsuite/config/default.exp b/ld/testsuite/config/default.exp new file mode 100644 index 0000000..0a0fdea --- /dev/null +++ b/ld/testsuite/config/default.exp @@ -0,0 +1,171 @@ +# Basic expect script for LD Regression Tests +# Copyright (C) 1993, 94, 95, 97, 98, 1999 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Jeffrey Wheat (cassidy@cygnus.com) +# + +if ![info exists ld] then { + set ld [findfile $base_dir/ld-new $base_dir/ld-new [transform ld]] +} + +if ![info exists as] then { + set as [findfile $base_dir/../gas/as-new $base_dir/../gas/as-new [transform as]] +} + +if ![info exists nm] then { + set nm [findfile $base_dir/../binutils/nm-new $base_dir/../binutils/nm-new [transform nm]] +} + +if ![info exists objdump] then { + set objdump [findfile $base_dir/../binutils/objdump] +} + +if ![info exists objcopy] then { + set objcopy [findfile $base_dir/../binutils/objcopy] +} + +if ![info exists ar] then { + set ar [findfile $base_dir/../binutils/ar] +} + +if ![info exists strip] then { + set strip [findfile $base_dir/../binutils/strip-new $base_dir/../binutils/strip-new [transform strip]] +} + +if {![file isdirectory tmpdir]} then { + catch "exec mkdir tmpdir" status +} + +# Make a symlink from tmpdir/as to the assembler in the build tree, so +# that we can use a -B option to gcc to force it to use the newly +# built assembler. +if {![file isdirectory tmpdir/gas]} then { + catch "exec mkdir tmpdir/gas" status + catch "exec ln -s ../../../gas/as-new tmpdir/gas/as" status +} +set gcc_gas_flag "-B[pwd]/tmpdir/gas/" + +# load the utility procedures +load_lib ld-lib.exp + +proc get_link_files {varname} { + global $varname + global target_triplet + global srcdir + global CC + if ![info exists $varname] { + set status [catch "exec sh -c \"host='$target_triplet' && CC='$CC' && . $srcdir/../configure.host && eval echo \\$$varname\"" result] + if $status { error "Error getting native link files: $result" } + set $varname $result + } +} + +proc get_target_emul {} { + global target_triplet + global srcdir + set status [catch "exec sh -c \"targ='$target_triplet' && . $srcdir/../configure.tgt && echo \\\$targ_emul\"" result] + if $status { error "Error getting emulation name: $result" } + return $result +} + +if [isnative] { + foreach x {HOSTING_CRT0 HOSTING_LIBS} { + get_link_files $x + } +} else { + foreach x {HOSTING_CRT0 HOSTING_LIBS} { set $x "" } +} +if ![info exists HOSTING_EMU] { set HOSTING_EMU "-m [get_target_emul]" } + +# +# ld_version -- extract and print the version number of ld compiler (GCC) +# +proc ld_version {} { + global ld + default_ld_version $ld +} + +# +# ld_exit -- just a stub for ld +# +proc ld_exit {} { +} + +# +# ld_start +# relink the linker +# +proc ld_start { ld target } { + # +} + +# +# ld_relocate +# link an object using relocation +# +proc ld_relocate { ld target objects } { + default_ld_relocate $ld $target $objects +} + +# +# ld_link +# link a program using ld +# +proc ld_link { ld target objects } { + default_ld_link $ld $target $objects +} + +# +# ld_simple_link +# link a program using ld, without including any libraries +# +proc ld_simple_link { ld target objects } { + default_ld_simple_link $ld $target $objects +} + +# +# ld_compile +# compile an object using $cc +# +proc ld_compile { cc source object } { + default_ld_compile $cc $source $object +} + +# +# ld_assemble +# assemble a file +# +proc ld_assemble { as source object } { + default_ld_assemble $as $source $object +} + +# +# ld_nm +# run nm on a file +# +proc ld_nm { nm object } { + default_ld_nm $nm $object +} + +# +# ld_exec +# execute ithe target +# +proc ld_exec { target output } { + default_ld_exec $target $output +} + diff --git a/ld/testsuite/ld-bootstrap/bootstrap.exp b/ld/testsuite/ld-bootstrap/bootstrap.exp new file mode 100644 index 0000000..0e4b820 --- /dev/null +++ b/ld/testsuite/ld-bootstrap/bootstrap.exp @@ -0,0 +1,103 @@ +# Expect script for LD Bootstrap Tests +# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Jeffrey Wheat (cassidy@cygnus.com) +# Rewritten by Ian Lance Taylor (ian@cygnus.com) +# + +# Make sure that ld can bootstrap itself. + +# This test can only be run if ld generates native executables. +if ![isnative] { + return +} + +# Bootstrap ld. First link the object files together using -r, in +# order to test -r. Then link the result into an executable, ld1, to +# really test -r. Use ld1 to link a fresh ld, ld2. Use ld2 to link a +# new ld, ld3. ld2 and ld3 should be identical. + +foreach flags {"" "--static" "--traditional-format" "--no-keep-memory"} { + if {"$flags" != ""} { + set testname "bootstrap with $flags" + } else { + set testname "bootstrap" + } + + # This test can only be run if we have the ld build directory, + # since we need the object files. + if {$ld != "$objdir/ld-new"} { + untested $testname + continue + } + + # If we only have a shared libbfd, we probably can't run the + # --static test. + if { $flags == "--static" && ! [string match "*libbfd.a*" $BFDLIB] } then { + untested $testname + continue + } + + if ![ld_relocate $ld tmpdir/ld-partial.o "$flags $OFILES"] { + fail $testname + continue + } + + # On AIX, you need to specify an import list when using --static. + # You only want the import list when creating the final + # executable. + if [istarget "*-*-aix*"] { + if {"$flags" == "--static"} { + set flags "--static -bI:/lib/syscalls.exp" + } + } + + # On Irix 5, linking with --static only works if all the files are + # compiled using -non_shared. + if {"$flags" == "--static"} { + setup_xfail "mips*-*-irix5*" + } + + if ![ld_link $ld tmpdir/ld1 "$flags tmpdir/ld-partial.o $BFDLIB $LIBIBERTY"] { + fail $testname + continue + } + + if ![ld_link tmpdir/ld1 tmpdir/ld2 "$flags $OFILES $BFDLIB $LIBIBERTY"] { + fail $testname + continue + } + + if ![ld_link tmpdir/ld2 tmpdir/ld3 "$flags $OFILES $BFDLIB $LIBIBERTY"] { + fail $testname + continue + } + + send_log "cmp tmpdir/ld2 tmpdir/ld3\n" + verbose "cmp tmpdir/ld2 tmpdir/ld3" + catch "exec cmp tmpdir/ld2 tmpdir/ld3" exec_output + set exec_output [prune_warnings $exec_output] + + if [string match "" $exec_output] then { + pass $testname + } else { + send_log "$exec_output\n" + verbose "$exec_output" 1 + + fail $testname + } +} diff --git a/ld/testsuite/ld-cdtest/cdtest-bar.cc b/ld/testsuite/ld-cdtest/cdtest-bar.cc new file mode 100644 index 0000000..79000e3 --- /dev/null +++ b/ld/testsuite/ld-cdtest/cdtest-bar.cc @@ -0,0 +1,17 @@ +// test program for Class Foo + +#include "cdtest-foo.h" + +static Foo static_foo( "static_foo"); + +Foo f() +{ + Foo x; + return x; +} + +void g() +{ + Foo other_foo1 = Foo( "other_foo1"), other_foo2 = Foo( "other_foo2"); + other_foo2 = other_foo1; +} diff --git a/ld/testsuite/ld-cdtest/cdtest-foo.cc b/ld/testsuite/ld-cdtest/cdtest-foo.cc new file mode 100644 index 0000000..615e33c --- /dev/null +++ b/ld/testsuite/ld-cdtest/cdtest-foo.cc @@ -0,0 +1,89 @@ +// Class Foo +#pragma implementation + + +// We don't use header files, since we only want to see, whether the +// compiler is installed properly. +// +#if (__GNUG__ == 2) +typedef __SIZE_TYPE__ size_t; +#else +typedef unsigned int size_t; +#endif + +extern "C" { + char *strncpy (char* dest, const char* dest, size_t len); + int printf (const char*, ...); +}; + +#include "cdtest-foo.h" + +int Foo::foos = 0; + +void Foo::init_foo () +{ + printf ("BROKENLY calling Foo::init_foo from __init_start; size_of(Foo) = %d\n", sizeof(Foo)); + foos = FOOLISH_NUMBER; +} + + +Foo::Foo () +{ + i = ++foos; + strncpy (message, "default-foo", len); +#ifdef WITH_ADDR + printf ("Constructing Foo(%d) \"default-foo\" at %08x\n", i, this); +#else + printf ("Constructing Foo(%d) \"default-foo\"\n", i); +#endif +} + +Foo::Foo (char* msg) +{ + i = ++foos; + strncpy( message, msg, len); +#ifdef WITH_ADDR + printf ( "Constructing Foo(%d) \"%s\" at %08x\n", i, message, this); +#else + printf ( "Constructing Foo(%d) \"%s\"\n", i, message); +#endif +} + + +Foo::Foo (const Foo& foo) +{ + i = ++foos; +#ifdef WITH_ADDR + printf ("Initializing Foo(%d) \"%s\" at %08x with Foo(%d) %08x\n", + i, foo.message, this, foo.i, &foo); +#else + printf ("Initializing Foo(%d) \"%s\" with Foo(%d)\n",i, foo.message, foo.i); +#endif + for ( int k = 0; k < FOO_MSG_LEN; k++) message[k] = foo.message[k]; +} + + +Foo& Foo::operator= (const Foo& foo) +{ +#ifdef WITH_ADDR + printf ("Copying Foo(%d) \"%s\" at %08x to Foo(%d) %08x\n", + foo.i, foo.message, &foo, i, this); +#else + printf ("Copying Foo(%d) \"%s\" to Foo(%d)\n", foo.i, foo.message, i); +#endif + for ( int k = 0; k < FOO_MSG_LEN; k++) message[k] = foo.message[k]; + return *this; +} + + +Foo::~Foo () +{ + foos--; +#ifdef WITH_ADDR + printf ("Destructing Foo(%d) \"%s\" at %08x (remaining foos: %d)\n", + i, message, this, foos); +#else + printf ("Destructing Foo(%d) \"%s\" (remaining foos: %d)\n", + i, message, foos); +#endif +} diff --git a/ld/testsuite/ld-cdtest/cdtest-foo.h b/ld/testsuite/ld-cdtest/cdtest-foo.h new file mode 100644 index 0000000..0afe52a --- /dev/null +++ b/ld/testsuite/ld-cdtest/cdtest-foo.h @@ -0,0 +1,24 @@ +// Class Foo + +#pragma interface + +#define FOOLISH_NUMBER -4711 + +#ifndef FOO_MSG_LEN +#define FOO_MSG_LEN 80 +#endif + +class Foo { + static int foos; + int i; + static const int len = FOO_MSG_LEN; + char message[len]; +public: + static void init_foo (); + static int nb_foos() { return foos; } + Foo(); + Foo( char* message); + Foo(const Foo&); + Foo & operator= (const Foo&); + ~Foo (); +}; diff --git a/ld/testsuite/ld-cdtest/cdtest-main.cc b/ld/testsuite/ld-cdtest/cdtest-main.cc new file mode 100644 index 0000000..4b99b5c --- /dev/null +++ b/ld/testsuite/ld-cdtest/cdtest-main.cc @@ -0,0 +1,40 @@ +// main program for Class Foo + +extern "C" { +// Some <assert.h> implementations (e.g. SUNOS 4.1) are broken, +// in that they require <stdio.h>. But, if gcc/g++ is installed +// correctly, you should get gcc's assert.h. +// If the compile fails, it means the wrong include files are in use! +#include <assert.h> +}; +#include "cdtest-foo.h" + +extern "C" void __init_start(); + +extern Foo f(void); +extern void g(void); + +/* This function should *not* be called by the environment. There is + no way in C++ to ``run something after the initializers but before main()''. + The library that depends on this (NIHCL) is broken. -- John Gilmore + We leave this here to test that future changes to the compiler + do not re-introduce this losing ``feature''. */ +void +__init_start() +{ + Foo::init_foo(); +} + +static Foo static_foo( "static_foo"); + +main() +{ + assert (Foo::nb_foos() == 2); + Foo automatic_foo( "automatic_foo"); + Foo bla_foo = f(); + assert (Foo::nb_foos() == 4); + g(); + assert (Foo::nb_foos() == 4); + // `automatic_foo' and `bla_foo' are destructed here +} + diff --git a/ld/testsuite/ld-cdtest/cdtest.dat b/ld/testsuite/ld-cdtest/cdtest.dat new file mode 100644 index 0000000..39be0db --- /dev/null +++ b/ld/testsuite/ld-cdtest/cdtest.dat @@ -0,0 +1,15 @@ +Constructing Foo(1) "static_foo" +Constructing Foo(2) "static_foo" +Constructing Foo(3) "automatic_foo" +Constructing Foo(4) "default-foo" +Initializing Foo(5) "default-foo" with Foo(4) +Destructing Foo(4) "default-foo" (remaining foos: 4) +Constructing Foo(5) "other_foo1" +Constructing Foo(6) "other_foo2" +Copying Foo(5) "other_foo1" to Foo(6) +Destructing Foo(6) "other_foo1" (remaining foos: 5) +Destructing Foo(5) "other_foo1" (remaining foos: 4) +Destructing Foo(5) "default-foo" (remaining foos: 3) +Destructing Foo(3) "automatic_foo" (remaining foos: 2) +Destructing Foo(2) "static_foo" (remaining foos: 1) +Destructing Foo(1) "static_foo" (remaining foos: 0) diff --git a/ld/testsuite/ld-cdtest/cdtest.exp b/ld/testsuite/ld-cdtest/cdtest.exp new file mode 100644 index 0000000..ccbe35e --- /dev/null +++ b/ld/testsuite/ld-cdtest/cdtest.exp @@ -0,0 +1,100 @@ +# Expect script for LD cdtest Tests +# Copyright (C) 1993,1994,1995, 1997 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Jeffrey Wheat (cassidy@cygnus.com) +# Rewritten by Ian Lance Taylor (ian@cygnus.com) +# + +# Make sure that constructors are handled correctly. + +set test1 "cdtest" +set test2 "cdtest with -Ur" + +# This test requires running the executable generated by ld. +if ![isnative] { + return +} + +if { [which $CXX] == 0 } { + untested $test1 + untested $test2 + return +} + +if { ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir/$subdir/cdtest-foo.cc tmpdir/cdtest-foo.o] + || ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir/$subdir/cdtest-bar.cc tmpdir/cdtest-bar.o] + || ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir/$subdir/cdtest-main.cc tmpdir/cdtest-main.o] } { + unresolved $test1 + unresolved $test2 + return +} + +if ![ld_link $ld tmpdir/cdtest {tmpdir/cdtest-foo.o tmpdir/cdtest-bar.o tmpdir/cdtest-main.o}] { + fail $test1 +} else { + send_log "tmpdir/cdtest >tmpdir/cdtest.out\n" + verbose "tmpdir/cdtest >tmpdir/cdtest.out" + catch "exec tmpdir/cdtest >tmpdir/cdtest.out" exec_output + if ![string match "" $exec_output] then { + send_log "$exec_output\n" + verbose "$exec_output" 1 + fail $test1 + } else { + send_log "diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat\n" + verbose "diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat" + catch "exec diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat" exec_output + set exec_output [prune_warnings $exec_output] + + if [string match "" $exec_output] then { + pass $test1 + } else { + send_log "$exec_output\n" + verbose "$exec_output" 1 + fail $test1 + } + } +} + +if ![ld_relocate $ld tmpdir/cdtest.o {-Ur tmpdir/cdtest-foo.o tmpdir/cdtest-bar.o tmpdir/cdtest-main.o}] { + fail $test2 +} else { + if ![ld_link $ld tmpdir/cdtest tmpdir/cdtest.o] { + fail $test2 + } else { + send_log "tmpdir/cdtest >tmpdir/cdtest.out\n" + verbose "tmpdir/cdtest >tmpdir/cdtest.out" + catch "exec tmpdir/cdtest >tmpdir/cdtest.out" exec_output + if ![string match "" $exec_output] then { + send_log "$exec_output\n" + verbose "$exec_output" 1 + fail $test2 + } else { + send_log "diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat\n" + verbose "diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat" + catch "exec diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat" exec_output + set exec_output [prune_warnings $exec_output] + + if [string match "" $exec_output] then { + pass $test2 + } else { + send_log "$exec_output\n" + verbose "$exec_output" 1 + fail $test2 + } + } + } +} diff --git a/ld/testsuite/ld-checks/asm.s b/ld/testsuite/ld-checks/asm.s new file mode 100644 index 0000000..e4e0c33 --- /dev/null +++ b/ld/testsuite/ld-checks/asm.s @@ -0,0 +1,14 @@ +.text + .global foo +foo: + .long 0x12345678 + +.data + .global bar +bar: + .long 0x87654321 + + .lcomm 0x12 + + +
\ No newline at end of file diff --git a/ld/testsuite/ld-checks/checks.exp b/ld/testsuite/ld-checks/checks.exp new file mode 100644 index 0000000..af3ef7d --- /dev/null +++ b/ld/testsuite/ld-checks/checks.exp @@ -0,0 +1,72 @@ +# Expect script for LD section checks tests +# Copyright (C) 1999 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Nick Clifton (nickc@cygnus.com) + +proc section_check {} { + global ld_flags + global as + global ld + global srcdir + global subdir + + set test "check sections" + + set ldflags "--check-sections" + + if { ![ld_assemble $as $srcdir/$subdir/asm.s tmpdir/asm.o]} { + unresolved $test + return + } + + if ![ld_simple_link $ld tmpdir/asm.x "$ldflags tmpdir/asm.o"] { + fail "$test : using default linker script" + } else { + pass $test + } + + # Change the linker flags so that our "buggy" linker + # script is used. + set ldflags "--check-sections -T $srcdir/$subdir/script -e foo" + + # Perform the equivalent of invoking ld_simple_link + # except that we need to massage the output futher. + + catch "exec $ld -o tmpdir/asm.x $ldflags tmpdir/asm.o" exec_output + set exec_output [prune_warnings $exec_output] + + # Make sure that we got some output from the linker + if [string match "" $exec_output] then { + fail "$test - error message expected but not found" + } + + # Now remove our expected error message + regsub -all ".*: section .data .* overlaps section .text .*" $exec_output "" exec_output + + # And check to see if anything else, (unexpected) was left + if [string match "" $exec_output] then { + pass $test + } else { + verbose -log "Unexpected linker message(s): $exec_output" + + fail "$test - using erroneous linker script" + } +} + +section_check + + diff --git a/ld/testsuite/ld-checks/script b/ld/testsuite/ld-checks/script new file mode 100644 index 0000000..44c6a08 --- /dev/null +++ b/ld/testsuite/ld-checks/script @@ -0,0 +1,6 @@ +SECTIONS { + .text 0x100 : { *(.text) } + .data 0x100 : AT (0x100) { *(.data) } + .bss 0x100 : AT (0x4000) { *(.bss) } +} + diff --git a/ld/testsuite/ld-elfvers/vers.exp b/ld/testsuite/ld-elfvers/vers.exp new file mode 100644 index 0000000..5dfaa93 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers.exp @@ -0,0 +1,808 @@ +# Expect script for ld-version tests +# Copyright (C) 1997, 1998 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Eric Youngdale (eric@andante.jic.com) + +# + +# This test can only be run if ld generates native executables. +if ![isnative] then {return} + +# This test can only be run on a couple of ELF platforms. +# Square bracket expressions seem to confuse istarget. +# This is similar to the test that is used in ld-shared, BTW. +if { ![istarget i?86-*-sysv4*] \ + && ![istarget i?86-*-unixware] \ + && ![istarget i?86-*-elf*] \ + && ![istarget i?86-*-linux*] \ + && ![istarget m68k-*-linux*] \ + && ![istarget mips*-*-irix5*] \ + && ![istarget powerpc-*-elf*] \ + && ![istarget powerpc-*-linux*] \ + && ![istarget powerpc-*-sysv4*] \ + && ![istarget sparc*-*-elf] \ + && ![istarget sparc*-*-solaris2*] + && ![istarget alpha*-*-linux*] } { + return +} + +if { [istarget i?86-*-linuxaout*] \ + || [istarget i?86-*-linuxoldld*] \ + || [istarget m68k-*-linuxaout*] } { + return +} + +if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { + return +} + +set diff diff +set tmpdir tmpdir +set VOBJDUMP_FLAGS --private-headers +set DOBJDUMP_FLAGS --dynamic-syms +set SOBJDUMP_FLAGS --syms +set shared --shared +set script --version-script + +proc test_ar { test lib object expect } { + global ar + global nm + global tmpdir + global srcdir + global subdir + global diff + + verbose -log "$ar -cr $tmpdir/$lib $tmpdir/$object" + catch "exec $ar -cr $tmpdir/$lib $tmpdir/$object" exec_output + set exec_output [prune_warnings $exec_output] + if ![string match "" $exec_output] { + verbose -log "$exec_output" + unresolved "$test" + return + } + + verbose -log "$nm --print-armap $tmpdir/$lib | grep \" in \" | egrep \"VERS\\|bar\\|foo\" | sort > $tmpdir/nm.out" + + catch "exec $nm --print-armap $tmpdir/$lib | grep \\\ in\\\ | egrep VERS\\\|bar\\\|foo | sort > $tmpdir/nm.out" exec_output + if [string match "" $exec_output] then { + catch "exec $diff -q $tmpdir/nm.out $srcdir/$subdir/$expect" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + pass $test + return + } else { + verbose -log "$exec_output" + fail "$test" + return + } + } else { + verbose -log "$exec_output" + fail "$test" + } +} + +# +# objdump_emptysymstuff +# Check non-dynamic symbols and make sure there are none with '@'. +# +proc objdump_emptysymstuff { objdump object } { + global SOBJDUMP_FLAGS + global version_output + global diff + + if ![info exists SOBJDUMP_FLAGS] { set SOBJDUMP_FLAGS "" } + + verbose -log "$objdump $SOBJDUMP_FLAGS $object | sed -n /\@/p" + + catch "exec $objdump $SOBJDUMP_FLAGS $object | sed -n /\@/p" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { +# We shouldn't get anything here. + return 1 + } else { +# it is not normal to come here - we have no output to compare. + verbose -log "$exec_output" + verbose -log "objdump_emptysymstuff: did not expect any output from objdump" + return 0 + } + +} + +# +# objdump_emptydynsymstuff +# Check dynamic symbols and make sure there are none with '@'. +# +proc objdump_emptydynsymstuff { objdump object } { + global DOBJDUMP_FLAGS + global version_output + global diff + + if ![info exists VOBJDUMP_FLAGS] { set VOBJDUMP_FLAGS "" } + + verbose -log "$objdump $DOBJDUMP_FLAGS $object | sed -n /VERS/p\\\;/show/p" + + catch "exec $objdump $DOBJDUMP_FLAGS $object | sed -n /VERS/p\\\;/show/p" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { +# We shouldn't get anything here. + return 1 + } else { if [string match "*objdump: *: not a dynamic object" $exec_output] then { + return 1 + } else { +# it is not normal to come here - we have no output to compare. + verbose -log "$exec_output" + verbose -log "objdump_emptydynsymstuff: did not expect any output from objdump" + return 0 + } } +} + +# +# objdump_emptyverstuff +# Make sure there is no version information +# +proc objdump_emptyverstuff { objdump object } { + global VOBJDUMP_FLAGS + global version_output + global diff + global tmpdir + + if {[which $objdump] == 0} then { + perror "$objdump does not exist" + return 0 + } + + if ![info exists VOBJDUMP_FLAGS] { set VOBJDUMP_FLAGS "" } + + verbose -log "$objdump $VOBJDUMP_FLAGS $object | sed -n /Version/,\\\$p > $tmpdir/objdump.out" + + catch "exec $objdump $VOBJDUMP_FLAGS $object | sed -n /Version/,\\\$p" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { +# it is normal to fail here - we have no output to compare. + return 1 + } else { if { [string match "*libc*" $exec_output] } then { +# this probably means that there is version information in libc, so we +# can't really perform this test. + return 1 + } else { + verbose -log "$exec_output" + verbose -log "objdump_emptyverstuff: did not expect any output from objdump" + return 0 + } } + +} + +# +# objdump_symstuff +# Dump non-dynamic symbol stuff and make sure that it is sane. +# +proc objdump_symstuff { objdump object expectfile } { + global SOBJDUMP_FLAGS + global version_output + global diff + global tmpdir + + if ![info exists SOBJDUMP_FLAGS] { set SOBJDUMP_FLAGS "" } + + verbose -log "$objdump $SOBJDUMP_FLAGS $object | grep \@ | sort > $tmpdir/objdump.out" + + catch "exec $objdump $SOBJDUMP_FLAGS $object | grep \@ | sort > $tmpdir/objdump.out" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + +# Now do a line-by-line comparison to effectively diff the darned things +# The stuff coming from the expectfile is actually a regex, so we can +# skip over the actual addresses and so forth. This is currently very +# simpleminded - it expects a one-to-one correspondence in terms of line +# numbers. + + if [file exists $expectfile] then { + set file_a [open $expectfile r] + } else { + perror "$expectfile doesn't exist" + return 0 + } + + if [file exists $tmpdir/objdump.out] then { + set file_b [open $tmpdir/objdump.out r] + } else { + perror "$tmpdir/objdump.out doesn't exist" + return 0 + } + + verbose "# Diff'ing: $expectfile $tmpdir/objdump.out" 2 + + set eof -1 + set differences 0 + + while { [gets $file_a line] != $eof } { + if [regexp "^#.*$" $line] then { + continue + } else { + lappend list_a $line + } + } + close $file_a + + while { [gets $file_b line] != $eof } { + if [regexp "^#.*$" $line] then { + continue + } else { + lappend list_b $line + } + } + close $file_b + + for { set i 0 } { $i < [llength $list_a] } { incr i } { + set line_a [lindex $list_a $i] + set line_b [lindex $list_b $i] + + + verbose "\t$expectfile: $i: $line_a" 3 + verbose "\t/tmp/objdump.out: $i: $line_b" 3 + if [regexp $line_a $line_b] then { + continue + } else { + verbose -log "\t$expectfile: $i: $line_a" + verbose -log "\t$tmpdir/objdump.out: $i: $line_b" + + return 0 + } + } + + if { [llength $list_a] != [llength $list_b] } { + verbose -log "Line count" + return 0 + } + + if $differences<1 then { + return 1 + } + + return 0 + } else { + verbose -log "$exec_output" + return 0 + } + +} + +# +# objdump_dymsymstuff +# Dump dynamic symbol stuff and make sure that it is sane. +# +proc objdump_dynsymstuff { objdump object expectfile } { + global DOBJDUMP_FLAGS + global version_output + global diff + global tmpdir + + if ![info exists DOBJDUMP_FLAGS] { set DOBJDUMP_FLAGS "" } + + verbose -log "$objdump $DOBJDUMP_FLAGS $object | sed -n /VERS/p\\\;/show/p | sort | uniq > $tmpdir/objdump.out" + + catch "exec $objdump $DOBJDUMP_FLAGS $object | sed -n /VERS/p\\\;/show/p | sort | uniq > $tmpdir/objdump.out" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + +# Now do a line-by-line comparison to effectively diff the darned things +# The stuff coming from the expectfile is actually a regex, so we can +# skip over the actual addresses and so forth. This is currently very +# simpleminded - it expects a one-to-one correspondence in terms of line +# numbers. + + if [file exists $expectfile] then { + set file_a [open $expectfile r] + } else { + warning "$expectfile doesn't exist" + return 0 + } + + if [file exists $tmpdir/objdump.out] then { + set file_b [open $tmpdir/objdump.out r] + } else { + fail "$tmpdir/objdump.out doesn't exist" + return 0 + } + + verbose "# Diff'ing: $expectfile $tmpdir/objdump.out" 2 + + set eof -1 + set differences 0 + + while { [gets $file_a line] != $eof } { + if [regexp "^#.*$" $line] then { + continue + } else { + lappend list_a $line + } + } + close $file_a + + while { [gets $file_b line] != $eof } { + if [regexp "^#.*$" $line] then { + continue + } else { + lappend list_b $line + } + } + close $file_b + + for { set i 0 } { $i < [llength $list_b] } { incr i } { + set line_b [lindex $list_b $i] + +# The tests are rigged so that we should never export a symbol with the +# word 'hide' in it. Thus we just search for it, and bail if we find it. + if [regexp "hide" $line_b] then { + verbose -log "\t$tmpdir/objdump.out: $i: $line_b" + + return 0 + } + + verbose "\t$expectfile: $i: $line_b" 3 + + # We can't assume that the sort is consistent across + # systems, so we must check each regexp. When we find a + # regexp, we null it out, so we don't match it twice. + for { set j 0 } { $j < [llength $list_a] } { incr j } { + set line_a [lindex $list_a $j] + + if [regexp $line_a $line_b] then { + lreplace $list_a $j $j "CAN NOT MATCH" + break + } + } + + if { $j >= [llength $list_a] } { + verbose -log "\t$tmpdir/objdump.out: $i: $line_b" + + return 0 + } + } + + if { [llength $list_a] != [llength $list_b] } { + verbose -log "Line count" + return 0 + } + + if $differences<1 then { + return 1 + } + + return 0 + } else { + verbose -log "$exec_output" + return 0 + } + +} + +# +# objdump_versionstuff +# Dump version definitions/references and make sure that it is sane. +# +proc objdump_versionstuff { objdump object expectfile } { + global VOBJDUMP_FLAGS + global version_output + global diff + global tmpdir + + if {[which $objdump] == 0} then { + perror "$objdump does not exist" + return 0 + } + + if ![info exists VOBJDUMP_FLAGS] { set VOBJDUMP_FLAGS "" } + + verbose -log "$objdump $VOBJDUMP_FLAGS $object | sed -n /Version/,\\\$p > $tmpdir/objdump.out" + + catch "exec $objdump $VOBJDUMP_FLAGS $object | sed -n /Version/,\\\$p > $tmpdir/objdump.out" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + + # It's OK if there are extra lines in the actual output; they + # may come from version information in libc. We require that + # every line in EXPECTFILE appear in the output in order. + + set f1 [open $tmpdir/objdump.out r] + set f2 [open $expectfile r] + gets $f2 l2 + while { [gets $f1 l1] != -1 } { + if { [string match $l2 $l1] } then { + if { [gets $f2 l2] == -1 } then { + close $f1 + close $f2 + return 1 + } + } + } + + # We reached the end of the output without seeing the line we + # expected. This is a test failure. + + close $f1 + close $f2 + + verbose -log "Did not find \"$l2\"" + set f1 [open $tmpdir/objdump.out r] + while { [gets $f1 l1] != -1 } { + verbose -log $l1 + } + + verbose -log "$exec_output" + return 0 + } else { + verbose -log "$exec_output" + return 0 + } +} + +proc build_vers_lib { test source libname other mapfile verexp versymexp symexp } { + global ld + global srcdir + global subdir + global exec_output + global host_triplet + global tmpdir + global as + global objdump + global CC + global CFLAGS + global shared + global script + + if ![ld_compile "$CC -S $CFLAGS" $srcdir/$subdir/$source $tmpdir/$libname.s] { + unresolved "$test" + return + } + + if ![ld_assemble $as $tmpdir/$libname.s $tmpdir/$libname.o ] { + unresolved "$test" + return + } + + if [string match "" $other] then { + set other_lib "" + } else { + set other_lib $tmpdir/$other + } + + if [string match "" $mapfile] then { + set script_arg "" + } else { + set script_arg "$script $srcdir/$subdir/$mapfile" + } + + if {![ld_simple_link $ld $tmpdir/$libname.so "$shared $tmpdir/$libname.o $other_lib $script_arg"]} { + fail "$test" + return + } + + if {![objdump_versionstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$verexp ]} { + fail "$test" + return + } + + if {![objdump_dynsymstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$versymexp ]} { + fail "$test" + return + } + + if [string match "" $symexp] then { + if {![objdump_emptysymstuff $objdump $tmpdir/$libname.o ]} { + fail "$test" + return + } + } else { + if {![objdump_symstuff $objdump $tmpdir/$libname.o $srcdir/$subdir/$symexp ]} { + fail "$test" + return + } + } + + pass $test + +} + +proc test_ldfail { test flag source execname other mapfile whyfail } { + global ld + global srcdir + global subdir + global exec_output + global host_triplet + global tmpdir + global as + global objdump + global CC + global CFLAGS + global script + + if [string match "" $other] then { + set other_lib "" + } else { + set other_lib $tmpdir/$other + } + + if ![ld_compile "$CC -S $flag $CFLAGS" $srcdir/$subdir/$source $tmpdir/$execname.s] { + unresolved "$test" + return + } + + if ![ld_assemble $as $tmpdir/$execname.s $tmpdir/$execname.o ] { + unresolved "$test" + return + } + + verbose -log "This link should fail because of $whyfail" + + if [string match "" $mapfile] then { + set script_arg "" + } else { + set script_arg "$script $srcdir/$subdir/$mapfile" + } + + if {![ld_link $ld $tmpdir/$execname "$tmpdir/$execname.o $other_lib $script_arg"]} { + pass "$test" + return + } + fail "$test" +} + +proc test_asfail { test flag source execname whyfail } { + global srcdir + global subdir + global tmpdir + global as + global CC + global CFLAGS + + if ![ld_compile "$CC -S $flag $CFLAGS" $srcdir/$subdir/$source $tmpdir/$execname.s] { + unresolved "$test" + return + } + + verbose -log "This assemble should fail because of $whyfail" + catch "exec $as -o $tmpdir/$execname.o $tmpdir/$execname.s" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + fail "$test" + return + } + verbose -log "$exec_output" + pass "$test" +} + +proc test_strip_vers_lib { test srclib libname verexp versymexp } { + global strip + global srcdir + global subdir + global exec_output + global host_triplet + global tmpdir + global objdump + + verbose -log "cp $tmpdir/$srclib $tmpdir/$libname.so" + exec cp $tmpdir/$srclib $tmpdir/$libname.so + + verbose -log "$strip $tmpdir/$libname.so" + catch "exec $strip $tmpdir/$libname.so" exec_output + if [string match "" $exec_output] then { + +# If strip went OK, then run the usual tests on the thing to make sure that +# it is sane. + if {![objdump_versionstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$verexp ]} { + fail "$test" + return + } + + if {![objdump_dynsymstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$versymexp ]} { + fail "$test" + return + } + + } else { + verbose -log "$exec_output" + fail "$test" + return + } + pass $test +} + + +proc build_exec { test source execname flags solibname verexp versymexp symexp } { + global ld + global srcdir + global subdir + global exec_output + global host_triplet + global tmpdir + global as + global objdump + global CC + global CFLAGS + + set shared --shared + set script --version-script + if ![ld_compile "$CC -S $CFLAGS" $srcdir/$subdir/$source $tmpdir/$execname.s] { + unresolved "$test" + return + } + + if ![ld_assemble $as $tmpdir/$execname.s $tmpdir/$execname.o ] { + unresolved "$test" + return + } + + if [string match "" $solibname] then { + set solibname_lib "" + } else { + set solibname_lib $tmpdir/$solibname + } + + if {![ld_link $ld $tmpdir/$execname "$flags $tmpdir/$execname.o $solibname_lib"]} { + fail "$test" + return + } + + if [string match "" $verexp] then { +# +# Make sure we get nothing back. +# + if {![objdump_emptyverstuff $objdump $tmpdir/$execname ]} { + fail "$test" + return + } + } else { + if {![objdump_versionstuff $objdump $tmpdir/$execname $srcdir/$subdir/$verexp ]} { + fail "$test" + return + } + } + + if [string match "" $versymexp] then { + if {![objdump_emptydynsymstuff $objdump $tmpdir/$execname ]} { + fail "$test" + return + } + } else { + if {![objdump_dynsymstuff $objdump $tmpdir/$execname $srcdir/$subdir/$versymexp ]} { + fail "$test" + return + } + } + + if [string match "" $symexp] then { + if {![objdump_emptysymstuff $objdump $tmpdir/$execname.o ]} { + fail "$test" + return + } + } else { + if {![objdump_symstuff $objdump $tmpdir/$execname.o $srcdir/$subdir/$symexp ]} { + fail "$test" + return + } + } + + pass $test +} + + +# +# Basic test - build a library with versioned symbols. +# +build_vers_lib "vers1" vers1.c vers1 "" vers1.map vers1.ver vers1.dsym vers1.sym + + +# +# Test #2 - build a library, and link it against the library we built in step +# 1. +# +build_vers_lib "vers2" vers2.c vers2 vers1.so vers2.map vers2.ver vers2.dsym "" + +# +# Test #3 - build an executable, and link it against vers1.so. +# +build_exec "vers3" vers3.c vers3 "" vers1.so vers3.ver vers3.dsym "" + +# +# Test #4 - Make sure a version implicitly defined in an executable +# causes a version node to be created. Verify this both with and without +# --export-dynamic. +# + +# This test fails on MIPS. On the MIPS we must put foo in the dynamic +# symbol table, which the test does not expect. +setup_xfail "mips*-*-*" +build_exec "vers4" vers4.c vers4 "" "" "" "" vers4.sym + +build_exec "vers4a" vers4.c vers4a "-export-dynamic" "" vers4a.ver vers4a.dsym vers4a.sym + + +# +# Try multiple definitions foo@BAR and foo@@BAR and make sure the linker +# complains. +# +test_ldfail "vers5" "" vers5.c vers5 "" "" "multiple definition of foo@VERS_1.2" + +# +# +# Now build a test that should reference a bunch of versioned symbols. +# All of them should be correctly referenced. +# +build_exec "vers6" vers6.c vers6 "" vers1.so vers6.ver vers6.dsym vers6.sym + +# +# Another test to verify that something made local via 'local' is truly not +# accessible. +# +build_vers_lib "vers7a" vers7a.c vers7a "" vers7.map vers7a.ver vers7a.dsym vers7a.sym + +test_ldfail "vers7" "" vers7.c vers7 vers7a.so "" "undefined reference to hide_a" + + +# +# This test is designed to verify that we can pass a linker script on the +# command line as if it were a normal .o file. +# +catch "exec cp $srcdir/$subdir/vers8.map $tmpdir/" ignore_output +build_vers_lib "vers8" vers1.c vers8 vers8.map "" vers8.ver vers1.dsym vers1.sym + +# +# This test tries to make sure that version references to versioned symbols +# don't collide with default definitions with the same symbol. +# +build_exec "vers9" vers9.c vers9 "-export-dynamic" "" vers9.ver vers9.dsym vers9.sym + + +# +# Try and use a non-existant version node. The linker should fail with +# an error message. +# +test_ldfail "vers10" "-DDO_TEST10" vers1.c vers10 "" "vers1.map --shared" "invalid version" + +# +# Try and some things the assembler should complain about. +# +test_asfail "vers11" "-DDO_TEST11" vers1.c vers11 "no @ in symver" + +test_asfail "vers12" "-DDO_TEST12" vers1.c vers12 "extern version definition" + +# +# Put a shared library in an archive library, and make sure the global +# archive symbol table is sane. +# +test_ar "ar with versioned solib" vers13.a vers1.so vers13.asym + +# +# Strip a shared library, and make sure we didn't screw something up in there. +# +test_strip_vers_lib "vers14" vers1.so vers14 vers1.ver vers1.dsym + + +# +# Build another test with some versioned symbols. Here we are going to +# try and override something from the library, and we shouldn't get +# any errors. +# +build_exec "vers15" vers15.c vers15 "" vers1.so vers15.ver vers15.dsym vers15.sym + +# +# Test that when we override a versioned symbol from the library this +# symbol appears in the dynamic symbol table of the executable. +# +build_vers_lib "vers16a" vers16a.c vers16a "" vers16.map vers16a.ver vers16a.dsym "" +build_exec "vers16" vers16.c vers16 "" vers16a.so "" vers16.dsym "" diff --git a/ld/testsuite/ld-elfvers/vers1.c b/ld/testsuite/ld-elfvers/vers1.c new file mode 100644 index 0000000..1d41fd9 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers1.c @@ -0,0 +1,98 @@ +/* + * Basic test of versioning. The idea with this is that we define + * a bunch of definitions of the same symbol, and we can theoretically + * then link applications against varying sets of these. + */ +const char * show_bar1 = "asdf"; +const char * show_bar2 = "asdf"; + +int +bar() +{ + return 3; +} + +/* + * The 'hide' prefix is something so that we can automatically search the + * symbol table and verify that none of these symbols were actually exported. + */ +int +hide_original_foo() +{ + return 1+bar(); + +} + +int +hide_old_foo() +{ + return 10+bar(); + +} + +int +hide_old_foo1() +{ + return 100+bar(); + +} + +int +hide_new_foo() +{ + return 1000+bar(); + +} + +__asm__(".symver hide_original_foo,show_foo@"); +__asm__(".symver hide_old_foo,show_foo@VERS_1.1"); +__asm__(".symver hide_old_foo1,show_foo@VERS_1.2"); +__asm__(".symver hide_new_foo,show_foo@@VERS_2.0"); + + + +#ifdef DO_TEST10 +/* In test 10, we try and define a non-existant version node. The linker + * should catch this and complain. */ +int +hide_new_bogus_foo() +{ + return 1000+bar(); + +} +__asm__(".symver hide_new_bogus_foo,show_foo@VERS_2.2"); +#endif + + + + +#ifdef DO_TEST11 +/* + * This test is designed to catch a couple of syntactic errors. The assembler + * should complain about both of the directives below. + */ +int +xyzzz() +{ + new2_foo(); + bar33(); +} + +__asm__(".symver new2_foo,fooVERS_2.0"); +__asm__(".symver bar33,bar@@VERS_2.0"); +#endif + +#ifdef DO_TEST12 +/* + * This test is designed to catch a couple of syntactic errors. The assembler + * should complain about both of the directives below. + */ +int +xyzzz() +{ + new2_foo(); + bar33(); +} + +__asm__(".symver bar33,bar@@VERS_2.0"); +#endif diff --git a/ld/testsuite/ld-elfvers/vers1.dsym b/ld/testsuite/ld-elfvers/vers1.dsym new file mode 100644 index 0000000..834434b --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers1.dsym @@ -0,0 +1,9 @@ +[0]* g DO \*ABS\* [0]* VERS_1.1 VERS_1.1 +[0]* g DO \*ABS\* [0]* VERS_1.2 VERS_1.2 +[0]* g DO \*ABS\* [0]* VERS_2.0 VERS_2.0 +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(Base\) (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.1\) (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.2\) (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* g DO (.s?data|\*ABS\*) [0-9a-f]* VERS_2.0 show_bar1 +[0-9a-f]* g DO (.s?data|\*ABS\*) [0-9a-f]* VERS_2.0 show_bar2 diff --git a/ld/testsuite/ld-elfvers/vers1.map b/ld/testsuite/ld-elfvers/vers1.map new file mode 100644 index 0000000..8fc37bc --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers1.map @@ -0,0 +1,16 @@ +VERS_1.1 { + global: + foo1; + local: + hide_old*; + hide_original*; + hide_new*; +}; + +VERS_1.2 { + foo2; +} VERS_1.1; + +VERS_2.0 { + show_bar1; show_bar2; +} VERS_1.2; diff --git a/ld/testsuite/ld-elfvers/vers1.sym b/ld/testsuite/ld-elfvers/vers1.sym new file mode 100644 index 0000000..70ff855 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers1.sym @@ -0,0 +1,4 @@ +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@ +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@VERS_1.1 +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@VERS_1.2 +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@@VERS_2.0 diff --git a/ld/testsuite/ld-elfvers/vers1.ver b/ld/testsuite/ld-elfvers/vers1.ver new file mode 100644 index 0000000..3e7312b --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers1.ver @@ -0,0 +1,8 @@ +Version definitions: +1 0x01 0x0a26881f tmpdir/vers1.so +2 0x00 0x0a7927b1 VERS_1.1 +3 0x00 0x0a7927b2 VERS_1.2 + VERS_1.1 +4 0x00 0x0a7922b0 VERS_2.0 + VERS_1.2 + diff --git a/ld/testsuite/ld-elfvers/vers13.asym b/ld/testsuite/ld-elfvers/vers13.asym new file mode 100644 index 0000000..d446144 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers13.asym @@ -0,0 +1,10 @@ +VERS_1.1 in vers1.so +VERS_1.2 in vers1.so +VERS_2.0 in vers1.so +bar in vers1.so +show_bar1 in vers1.so +show_bar2 in vers1.so +show_foo@ in vers1.so +show_foo@@VERS_2.0 in vers1.so +show_foo@VERS_1.1 in vers1.so +show_foo@VERS_1.2 in vers1.so diff --git a/ld/testsuite/ld-elfvers/vers15.c b/ld/testsuite/ld-elfvers/vers15.c new file mode 100644 index 0000000..d32be3f --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers15.c @@ -0,0 +1,35 @@ +/* + * Testcase to make sure that if we externally reference a versioned symbol + * that we always get the right one. + */ + +int +foo_1() +{ + return 1034; +} + +int +foo_2() +{ + return 1343; +} + +int +foo_3() +{ + return 1334; +} + +int +main() +{ + printf("Expect 4, get %d\n", foo_1()); + printf("Expect 13, get %d\n", foo_2()); + printf("Expect 103, get %d\n", foo_3()); + return 0; +} + +__asm__(".symver foo_1,show_foo@"); +__asm__(".symver foo_2,show_foo@VERS_1.1"); +__asm__(".symver foo_3,show_foo@@VERS_1.2"); diff --git a/ld/testsuite/ld-elfvers/vers15.dsym b/ld/testsuite/ld-elfvers/vers15.dsym new file mode 100644 index 0000000..1f5e15c --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers15.dsym @@ -0,0 +1,5 @@ +[0]* g DO \*ABS\* [0]* VERS_1.1 VERS_1.1 +[0]* g DO \*ABS\* [0]* VERS_1.2 VERS_1.2 +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(Base\) (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.1\) (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_1.2 (0x[0-9a-f][0-9a-f] )?show_foo diff --git a/ld/testsuite/ld-elfvers/vers15.sym b/ld/testsuite/ld-elfvers/vers15.sym new file mode 100644 index 0000000..87bab62 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers15.sym @@ -0,0 +1,3 @@ +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@ +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@VERS_1.1 +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@@VERS_1.2 diff --git a/ld/testsuite/ld-elfvers/vers15.ver b/ld/testsuite/ld-elfvers/vers15.ver new file mode 100644 index 0000000..3d2ec58 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers15.ver @@ -0,0 +1,5 @@ +Version definitions: +1 0x01 0x0d8a2605 tmpdir/vers15 +2 0x00 0x0a7927b2 VERS_1.2 +3 0x00 0x0a7927b1 VERS_1.1 + diff --git a/ld/testsuite/ld-elfvers/vers16.c b/ld/testsuite/ld-elfvers/vers16.c new file mode 100644 index 0000000..6668bc6 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers16.c @@ -0,0 +1,10 @@ +int show_bar () +{ + return 0; +} +extern int show_foo (); + +int main () +{ + return show_foo (); +} diff --git a/ld/testsuite/ld-elfvers/vers16.dsym b/ld/testsuite/ld-elfvers/vers16.dsym new file mode 100644 index 0000000..6c424c3 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers16.dsym @@ -0,0 +1,2 @@ +[0-9a-f]* g DF (\.text|\*ABS\*) [0-9a-f]*( Base )? (0x[0-9a-f][0-9a-f] )?show_bar +[0-9a-f]* DF \*UND\* [0-9a-f]*( )? (0x[0-9a-f][0-9a-f] )?show_foo diff --git a/ld/testsuite/ld-elfvers/vers16.map b/ld/testsuite/ld-elfvers/vers16.map new file mode 100644 index 0000000..766332f --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers16.map @@ -0,0 +1,3 @@ +VERS_1.1 { + global: show_bar; +}; diff --git a/ld/testsuite/ld-elfvers/vers16a.c b/ld/testsuite/ld-elfvers/vers16a.c new file mode 100644 index 0000000..153b1fd --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers16a.c @@ -0,0 +1,8 @@ +int show_bar () +{ + return 1; +} +int show_foo () +{ + return show_bar (); +} diff --git a/ld/testsuite/ld-elfvers/vers16a.dsym b/ld/testsuite/ld-elfvers/vers16a.dsym new file mode 100644 index 0000000..058df47 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers16a.dsym @@ -0,0 +1,3 @@ +[0-9a-f]* g DO (\.text|\*ABS\*) [0-9a-f]* VERS_1\.1 VERS_1\.1 +[0-9a-f]* g DF (\.text|\*ABS\*) [0-9a-f]* VERS_1\.1 (0x[0-9a-f][0-9a-f] )?show_bar +[0-9a-f]* g DF (\.text|\*ABS\*) [0-9a-f]* Base (0x[0-9a-f][0-9a-f] )?show_foo diff --git a/ld/testsuite/ld-elfvers/vers16a.ver b/ld/testsuite/ld-elfvers/vers16a.ver new file mode 100644 index 0000000..bccf1df --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers16a.ver @@ -0,0 +1,3 @@ +Version definitions: +1 0x01 0x0601cfbf tmpdir/vers16a.so +2 0x00 0x0a7927b1 VERS_1.1 diff --git a/ld/testsuite/ld-elfvers/vers2.c b/ld/testsuite/ld-elfvers/vers2.c new file mode 100644 index 0000000..d6a537e --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers2.c @@ -0,0 +1,10 @@ +/* + * Test function. This is built into a shared library, and references a + * versioned symbol foo that is in test.so. + */ + +void +show_xyzzy() +{ + printf("%d", show_foo()); +} diff --git a/ld/testsuite/ld-elfvers/vers2.dsym b/ld/testsuite/ld-elfvers/vers2.dsym new file mode 100644 index 0000000..99985c2 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers2.dsym @@ -0,0 +1,3 @@ +[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo +[0]* g DO \*ABS\* [0]* VERS_XXX_1.1 VERS_XXX_1.1 +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_XXX_1.1 (0x[0-9a-f][0-9a-f] )?show_xyzzy diff --git a/ld/testsuite/ld-elfvers/vers2.map b/ld/testsuite/ld-elfvers/vers2.map new file mode 100644 index 0000000..cd57d7e --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers2.map @@ -0,0 +1,4 @@ + +VERS_XXX_1.1 { + show_xyzzy; +}; diff --git a/ld/testsuite/ld-elfvers/vers2.ver b/ld/testsuite/ld-elfvers/vers2.ver new file mode 100644 index 0000000..b526343 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers2.ver @@ -0,0 +1,8 @@ +Version definitions: +1 0x01 0x0a26181f tmpdir/vers2.so +2 0x00 0x08785b51 VERS_XXX_1.1 + +Version References: + required from tmpdir/vers1.so: + 0x0a7922b0 0x00 03 VERS_2.0 + diff --git a/ld/testsuite/ld-elfvers/vers3.c b/ld/testsuite/ld-elfvers/vers3.c new file mode 100644 index 0000000..b006d77 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers3.c @@ -0,0 +1,10 @@ +/* + * Main program for test1, test2. + */ + +int +main() +{ + printf("%d\n", show_foo()); + return 0; +} diff --git a/ld/testsuite/ld-elfvers/vers3.dsym b/ld/testsuite/ld-elfvers/vers3.dsym new file mode 100644 index 0000000..c9c2642 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers3.dsym @@ -0,0 +1 @@ +[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo diff --git a/ld/testsuite/ld-elfvers/vers3.ver b/ld/testsuite/ld-elfvers/vers3.ver new file mode 100644 index 0000000..aa230ee --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers3.ver @@ -0,0 +1,4 @@ +Version References: + required from tmpdir/vers1.so: + 0x0a7922b0 0x00 02 VERS_2.0 + diff --git a/ld/testsuite/ld-elfvers/vers4.c b/ld/testsuite/ld-elfvers/vers4.c new file mode 100644 index 0000000..15497ca --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers4.c @@ -0,0 +1,27 @@ +/* + * Testcase to make sure that a versioned symbol definition in an + * application correctly defines the version node, if and only if + * the actual symbol is exported. This is built both with and without + * -export-dynamic. + */ +int +bar() +{ + return 3; +} + +int +new_foo() +{ + return 1000+bar(); + +} + +__asm__(".symver new_foo,foo@@VERS_2.0"); + +int +main() +{ + printf("%d\n", foo()); + return 0; +} diff --git a/ld/testsuite/ld-elfvers/vers4.sym b/ld/testsuite/ld-elfvers/vers4.sym new file mode 100644 index 0000000..7449446 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers4.sym @@ -0,0 +1 @@ +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@@VERS_2.0 diff --git a/ld/testsuite/ld-elfvers/vers4a.dsym b/ld/testsuite/ld-elfvers/vers4a.dsym new file mode 100644 index 0000000..f7f9fda --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers4a.dsym @@ -0,0 +1,2 @@ +[0]* g DO \*ABS\* [0]* VERS_2.0 VERS_2.0 +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?foo diff --git a/ld/testsuite/ld-elfvers/vers4a.sym b/ld/testsuite/ld-elfvers/vers4a.sym new file mode 100644 index 0000000..7449446 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers4a.sym @@ -0,0 +1 @@ +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@@VERS_2.0 diff --git a/ld/testsuite/ld-elfvers/vers4a.ver b/ld/testsuite/ld-elfvers/vers4a.ver new file mode 100644 index 0000000..876cedc --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers4a.ver @@ -0,0 +1,4 @@ +Version definitions: +1 0x01 0x0d8a26e1 tmpdir/vers4a +2 0x00 0x0a7922b0 VERS_2.0 + diff --git a/ld/testsuite/ld-elfvers/vers5.c b/ld/testsuite/ld-elfvers/vers5.c new file mode 100644 index 0000000..cc6ea40 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers5.c @@ -0,0 +1,51 @@ +/* + * Testcase to verify that foo@BAR and foo@@BAR are correctly detected + * as a multiply defined symbol. + */ +const char * bar1 = "asdf"; +const char * bar2 = "asdf"; + +int +bar() +{ + return 3; +} + +int +original_foo() +{ + return 1+bar(); + +} + +int +old_foo() +{ + return 10+bar(); + +} + +int +old_foo1() +{ + return 100+bar(); + +} + +int +new_foo() +{ + return 1000+bar(); + +} + +__asm__(".symver original_foo,foo@"); +__asm__(".symver old_foo,foo@VERS_1.1"); +__asm__(".symver old_foo1,foo@VERS_1.2"); +__asm__(".symver new_foo,foo@@VERS_1.2"); + +int +main () +{ + return 0; +} diff --git a/ld/testsuite/ld-elfvers/vers6.c b/ld/testsuite/ld-elfvers/vers6.c new file mode 100644 index 0000000..b5868bf --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers6.c @@ -0,0 +1,19 @@ +/* + * Testcase to make sure that if we externally reference a versioned symbol + * that we always get the right one. + */ + +int +main() +{ + printf("Expect 4, get %d\n", foo_1()); + printf("Expect 13, get %d\n", foo_2()); + printf("Expect 103, get %d\n", foo_3()); + printf("Expect 1003, get %d\n", foo_4()); + return 0; +} + +__asm__(".symver foo_1,show_foo@"); +__asm__(".symver foo_2,show_foo@VERS_1.1"); +__asm__(".symver foo_3,show_foo@VERS_1.2"); +__asm__(".symver foo_4,show_foo@VERS_2.0"); diff --git a/ld/testsuite/ld-elfvers/vers6.dsym b/ld/testsuite/ld-elfvers/vers6.dsym new file mode 100644 index 0000000..7e851d4 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers6.dsym @@ -0,0 +1,4 @@ +[0-9a-f]* DF \*UND\* [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_1.2 (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_1.1 (0x[0-9a-f][0-9a-f] )?show_foo diff --git a/ld/testsuite/ld-elfvers/vers6.sym b/ld/testsuite/ld-elfvers/vers6.sym new file mode 100644 index 0000000..d7b5cc7 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers6.sym @@ -0,0 +1,4 @@ +[0]* *F? *\*UND\* [0]* show_foo@ +[0]* *F? *\*UND\* [0]* show_foo@VERS_1.1 +[0]* *F? *\*UND\* [0]* show_foo@VERS_1.2 +[0]* *F? *\*UND\* [0]* show_foo@VERS_2.0 diff --git a/ld/testsuite/ld-elfvers/vers6.ver b/ld/testsuite/ld-elfvers/vers6.ver new file mode 100644 index 0000000..48a2b46 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers6.ver @@ -0,0 +1,6 @@ +Version References: + required from tmpdir/vers1.so: + 0x0a7927b1 0x00 ?? VERS_1.1 + 0x0a7927b2 0x00 ?? VERS_1.2 + 0x0a7922b0 0x00 ?? VERS_2.0 + diff --git a/ld/testsuite/ld-elfvers/vers7.c b/ld/testsuite/ld-elfvers/vers7.c new file mode 100644 index 0000000..d25b7e0 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers7.c @@ -0,0 +1,11 @@ +/* + * Test program that goes with test7.so + */ + + +int +main() +{ + return hide_a(1) + show_b(1); + return 0; +} diff --git a/ld/testsuite/ld-elfvers/vers7.map b/ld/testsuite/ld-elfvers/vers7.map new file mode 100644 index 0000000..65fd501 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers7.map @@ -0,0 +1,6 @@ +VERS_1 { + global: + show_b ; + local: + hide_a; +}; diff --git a/ld/testsuite/ld-elfvers/vers7a.c b/ld/testsuite/ld-elfvers/vers7a.c new file mode 100644 index 0000000..7bee8c7 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers7a.c @@ -0,0 +1,18 @@ +/* + * Test supplied by Ulrich. Verify that we can correctly force 'a' + * to local scope. + */ +int +__a_internal (int e) +{ + return e + 10; +} + +int +__b_internal (int e) +{ + return e + 42; +} + +asm (".symver __a_internal,hide_a@@VERS_1"); +asm (".symver __b_internal,show_b@@VERS_1"); diff --git a/ld/testsuite/ld-elfvers/vers7a.dsym b/ld/testsuite/ld-elfvers/vers7a.dsym new file mode 100644 index 0000000..06696c7 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers7a.dsym @@ -0,0 +1,2 @@ +[0]* g DO \*ABS\* [0]* VERS_1 VERS_1 +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_1 (0x[0-9a-f][0-9a-f] )?show_b diff --git a/ld/testsuite/ld-elfvers/vers7a.sym b/ld/testsuite/ld-elfvers/vers7a.sym new file mode 100644 index 0000000..b99bd61 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers7a.sym @@ -0,0 +1,2 @@ +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?hide_a@@VERS_1 +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_b@@VERS_1 diff --git a/ld/testsuite/ld-elfvers/vers7a.ver b/ld/testsuite/ld-elfvers/vers7a.ver new file mode 100644 index 0000000..37ef8a8 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers7a.ver @@ -0,0 +1,4 @@ +Version definitions: +1 0x01 0x0269fd3f tmpdir/vers7a.so +2 0x00 0x05aa7921 VERS_1 + diff --git a/ld/testsuite/ld-elfvers/vers8.c b/ld/testsuite/ld-elfvers/vers8.c new file mode 100644 index 0000000..a14586c --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers8.c @@ -0,0 +1,5 @@ +int +main() +{ + return a(1) + b(1); +} diff --git a/ld/testsuite/ld-elfvers/vers8.map b/ld/testsuite/ld-elfvers/vers8.map new file mode 100644 index 0000000..2635955 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers8.map @@ -0,0 +1,18 @@ +VERSION { + VERS_1.1 { + global: + foo1; + local: + hide_old*; + hide_original*; + hide_new*; + }; + + VERS_1.2 { + foo2; + } VERS_1.1; + + VERS_2.0 { + show_bar1; show_bar2; + } VERS_1.2; +} diff --git a/ld/testsuite/ld-elfvers/vers8.ver b/ld/testsuite/ld-elfvers/vers8.ver new file mode 100644 index 0000000..ef59023 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers8.ver @@ -0,0 +1,8 @@ +Version definitions: +1 0x01 0x0a26f81f tmpdir/vers8.so +2 0x00 0x0a7927b1 VERS_1.1 +3 0x00 0x0a7927b2 VERS_1.2 + VERS_1.1 +4 0x00 0x0a7922b0 VERS_2.0 + VERS_1.2 + diff --git a/ld/testsuite/ld-elfvers/vers9.c b/ld/testsuite/ld-elfvers/vers9.c new file mode 100644 index 0000000..432fddb --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers9.c @@ -0,0 +1,45 @@ +/* + * Testcase to verify that reference to foo@BAR and a definition of foo@@BAR + * are not treated as a multiple def. + */ +const char * bar1 = "asdf"; +const char * bar2 = "asdf"; + +int +bar() +{ + return 3; +} + +int +original_foo() +{ + return 1+bar(); + +} + +int +old_foo() +{ + return 10+bar(); + +} + +int +new_foo() +{ + return 1000+bar(); + +} + +int +main() +{ + old_foo1(); + return 0; +} + +__asm__(".symver original_foo,foo@"); +__asm__(".symver old_foo,foo@VERS_1.1"); +__asm__(".symver old_foo1,foo@VERS_1.2"); +__asm__(".symver new_foo,foo@@VERS_1.2"); diff --git a/ld/testsuite/ld-elfvers/vers9.dsym b/ld/testsuite/ld-elfvers/vers9.dsym new file mode 100644 index 0000000..9793002 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers9.dsym @@ -0,0 +1,4 @@ +[0]* g DO \*ABS\* [0]* VERS_1.1 VERS_1.1 +[0]* g DO \*ABS\* [0]* VERS_1.2 VERS_1.2 +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.1\) (0x[0-9a-f][0-9a-f] )?foo +[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_1.2 (0x[0-9a-f][0-9a-f] )?foo diff --git a/ld/testsuite/ld-elfvers/vers9.sym b/ld/testsuite/ld-elfvers/vers9.sym new file mode 100644 index 0000000..8231516 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers9.sym @@ -0,0 +1,4 @@ +[0]* *F? *\*UND\* [0]* foo@VERS_1.2 +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@ +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@VERS_1.1 +[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@@VERS_1.2 diff --git a/ld/testsuite/ld-elfvers/vers9.ver b/ld/testsuite/ld-elfvers/vers9.ver new file mode 100644 index 0000000..673ba72 --- /dev/null +++ b/ld/testsuite/ld-elfvers/vers9.ver @@ -0,0 +1,5 @@ +Version definitions: +1 0x01 0x04d8a269 tmpdir/vers9 +2 0x00 0x0a7927b1 VERS_1.1 +3 0x00 0x0a7927b2 VERS_1.2 + diff --git a/ld/testsuite/ld-empic/empic.exp b/ld/testsuite/ld-empic/empic.exp new file mode 100644 index 0000000..2d528be --- /dev/null +++ b/ld/testsuite/ld-empic/empic.exp @@ -0,0 +1,263 @@ +# Expect script for ld-empic tests +# Copyright (C) 1994,1995, 1996, 1997 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Ian Lance Taylor (ian@cygnus.com) +# + +# Test the handling of MIPS embedded PIC code. This test essentially +# tests the compiler and assembler as well as the linker, since MIPS +# embedded PIC is a GNU enhancement to standard MIPS tools. + +# Embedded PIC is only supported for MIPS ECOFF targets. +if ![istarget mips*-*-ecoff*] { + return +} + +set testname relax + +if { [which $CC] == 0 } { + untested $testname + return +} + +# Test that relaxation works correctly. This testsuite was composed +# (by experimentation) to force the linker to relax twice--that is, +# the first relaxation pass will force another call to be out of +# range, requiring a second relaxation pass. +if { ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/relax1.c tmpdir/relax1.o] + || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/relax2.c tmpdir/relax2.o] + || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/relax3.c tmpdir/relax3.o] + || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/relax4.c tmpdir/relax4.o] } { + unresolved $testname + return +} + +if ![ld_simple_link $ld tmpdir/relax "--relax -T $srcdir/$subdir/relax.t tmpdir/relax1.o tmpdir/relax2.o tmpdir/relax3.o tmpdir/relax4.o"] { + fail $testname +} else { + # Check that the relaxation produced the correct result. Check + # each bal instruction. Some will go directly to the start of a + # function, which is OK. Some will form part of the five + # instruction expanded call sequence, in which case we compute the + # real destination and make sure it is the start of a function. + # Some bal instructions are used to locate the start of the + # function in order to do position independent addressing into the + # text section, in which case we just check that it correctly + # computes the start of the function. + + # Get the symbol table. + if ![ld_nm $nm tmpdir/relax] { + unresolved $testname + return + } + + # Get a disassembly. + send_log "$objdump -d tmpdir/relax >tmpdir/relax.dis\n" + verbose "$objdump -d tmpdir/relax >tmpdir/relax.dis" + catch "exec $objdump -d tmpdir/relax >tmpdir/relax.dis" exec_output + if ![string match "" $exec_output] { + send_log "$exec_output\n" + verbose $exec_output + unresolved $testname + return + } + + set balcnt 0 + set file [open tmpdir/relax.dis r] + while { [gets $file line] != -1 } { + verbose "$line" 2 + + if ![string match "*bal*" $line] { + continue + } + + verbose "$line" + + incr balcnt + + if ![regexp "^(\[0-9a-fA-F\]+) (<\[a-z+0-9A-Z.\]+>)? bal (\[0-9a-fA-F\]+)" $line whole addr label dest] { + perror "unrecognized format for $line" + unresolved $testname + return + } + + if "0x$addr + 8 != 0x$dest" { + # This is a straight function call. All function calls in + # this example are to either foo or bar. + if "0x$dest != $nm_output(foo) && 0x$dest != $nm_output(bar)" { + send_log "fail 1\n" + send_log "$line\n" + fail $testname + return + } + } else { + # Pick up the next line. If it is sll, this is a switch + # prologue, and there is not much we can do to test it. + # Otherwise, it should be lui, and the next instruction + # should be an addiu, followed by an addu to $31. + if { [gets $file l] == -1 } { + send_log "fail 2\n" + send_log "$line\n" + fail $testname + return + } + verbose $l + + if [string match "*sll*" $l] { + continue + } + if ![regexp "lui (\[\$a-z0-9\]+),(\[0-9a-fA-Fx\]+)" $l whole reg upper] { + send_log "fail 3\n" + send_log "$line\n" + send_log "$l\n" + fail $testname + return + } + + if { [gets $file l] == -1 } { + send_log "fail 4\n" + send_log "$line\n" + fail $testname + return + } + verbose "$l" + if ![regexp "addiu \\$reg,\\$reg,(\[-0-9\]+)" $l whole lower] { + send_log "fail 5\n" + send_log "$line\n" + send_log "$l\n" + send_log "addiu \\$reg,\\$reg,(\[-0-9\]+)\n" + fail $testname + return + } + + if { [gets $file l] == -1 } { + send_log "fail 6\n" + send_log "$line\n" + fail $testname + return + } + verbose "$l" + if ![regexp "addu \\$reg,\\$reg,\\\$ra" $l] { + send_log "fail 7\n" + send_log "$line\n" + send_log "$l\n" + fail $testname + return + } + + # The next line will be jalr in the case of an expanded + # call. Otherwise, the code is getting the start of the + # function, and the next line can be anything. + + if { [gets $file l] == -1 } { + send_log "fail 8\n" + send_log "$line\n" + fail $testname + return + } + verbose "$l" + if [string match "*jalr*" $l] { + set dest [expr 0x$addr + 8 + ($upper << 16) + $lower] + if { $dest != $nm_output(foo) && $dest != $nm_output(bar) } { + send_log "fail 9\n" + send_log "$line\n" + fail $testname + return + } + } else { + set dest [expr ($upper << 16) + $lower] + if ![regexp "<(\[.a-z\]+)\\+(\[0-9a-fA-F\]+)>" $label whole base offset] { + send_log "fail 10\n" + send_log "$line\n" + fail $testname + return + } + set offset 0x$offset + if { $base == ".foo" } { + set offset [expr $offset - ($nm_output(foo) - 0x30)] + } + if { $offset + 8 != - $dest } { + send_log "fail 11\n" + send_log "$line\n" + fail $testname + return + } + } + } + } + + close $file + + if {$balcnt < 10} { + send_log "fail 12\n" + fail $testname + } else { + verbose "$balcnt bal instructions" + pass $testname + } +} + +# We now test actually running embedded MIPS PIC code. This can only +# be done on a MIPS host with the same endianness as our target. +if [istarget mipsel-*-*] { + if ![ishost mips*-*-ultrix*] { + return + } +} else { + if ![ishost mips*-*-irix*] { + return + } +} + +set testname "run embedded PIC code" + +# Compile the program which will run the test. This code must be +# compiled for the host, not the target. +send_log "$CC_FOR_HOST $CFLAGS_FOR_HOST -o tmpdir/run $srcdir/$subdir/run.c\n" +verbose "$CC_FOR_HOST $CFLAGS_FOR_HOST -o tmpdir/run $srcdir/$subdir/run.c" +catch "exec $CC_FOR_HOST $CFLAGS_FOR_HOST -o tmpdir/run $srcdir/$subdir/run.c" exec_output +if ![string match "" $exec_output] { + send_log "$exec_output\n" + verbose "$exec_output" + unresolved $testname + return +} + +# Compile and link the test. +if { ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/runtesti.s tmpdir/runtesti.o] + || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/runtest1.c tmpdir/runtest1.o] + || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/runtest2.c tmpdir/runtest2.o] } { + unresolved $testname + return +} +if ![ld_simple_link $ld tmpdir/runtest "--embedded-relocs tmpdir/runtesti.o tmpdir/runtest1.o tmpdir/runtest2.o"] { + fail $testname +} else { + # Now run the test. + send_log "tmpdir/run tmpdir/runtest\n" + verbose "tmpdir/run tmpdir/runtest" + catch "exec tmpdir/run tmpdir/runtest" exec_output + if [string match "*ran and returned 0*" $exec_output] { + send_log "$exec_output\n" + verbose "$exec_output" + pass $testname + } else { + send_log "$exec_output\n" + verbose "$exec_output" + fail $testname + } +} diff --git a/ld/testsuite/ld-empic/relax.t b/ld/testsuite/ld-empic/relax.t new file mode 100644 index 0000000..8c18b69 --- /dev/null +++ b/ld/testsuite/ld-empic/relax.t @@ -0,0 +1,49 @@ +OUTPUT_FORMAT("ecoff-bigmips") +SECTIONS +{ + .foo 0x30 : { + tmpdir/relax3.o(.text) + tmpdir/relax1.o(.text) + } + .text 0x20000 : { + _ftext = . ; + *(.init) + eprol = .; + tmpdir/relax4.o(.text) + *(.text) + *(.fini) + etext = .; + _etext = .; + } + .rdata . : { + *(.rdata) + } + _fdata = .; + .data . : { + *(.data) + CONSTRUCTORS + } + _gp = . + 0x8000; + .lit8 . : { + *(.lit8) + } + .lit4 . : { + *(.lit4) + } + .sdata . : { + *(.sdata) + } + edata = .; + _edata = .; + _fbss = .; + .sbss . : { + *(.sbss) + *(.scommon) + } + .bss . : { + *(.bss) + *(COMMON) + } + end = .; + _end = .; +} diff --git a/ld/testsuite/ld-empic/relax1.c b/ld/testsuite/ld-empic/relax1.c new file mode 100644 index 0000000..20ec39e --- /dev/null +++ b/ld/testsuite/ld-empic/relax1.c @@ -0,0 +1,22 @@ +/* First source file in relaxation test. */ + +extern int bar (); +static int foo2 (); + +int foo (int i) +{ + switch (i) + { + case 0: bar (0); break; + case 1: bar (1); break; + case 2: bar (2); break; + case 3: bar (3); break; + case 4: bar (foo2); break; + case 5: bar (bar); break; + } + while (1) + if (i) + return bar (); +} + +static int foo2 () { } diff --git a/ld/testsuite/ld-empic/relax2.c b/ld/testsuite/ld-empic/relax2.c new file mode 100644 index 0000000..58854a0 --- /dev/null +++ b/ld/testsuite/ld-empic/relax2.c @@ -0,0 +1,19 @@ +/* Second source file in relaxation test. */ + +int bar2 () +{ + int i; + + for (i = 0; i < 100; i++) + foo (); + return foo () + foo () + foo () + foo (); +} + +int bar (int i) +{ + while (1) + if (i) + return foo (); + else + return foo (); +} diff --git a/ld/testsuite/ld-empic/relax3.c b/ld/testsuite/ld-empic/relax3.c new file mode 100644 index 0000000..1aaa532 --- /dev/null +++ b/ld/testsuite/ld-empic/relax3.c @@ -0,0 +1,3 @@ +/* Third source file in relaxation test. */ + +int quux () { return 0; } diff --git a/ld/testsuite/ld-empic/relax4.c b/ld/testsuite/ld-empic/relax4.c new file mode 100644 index 0000000..21cfb05 --- /dev/null +++ b/ld/testsuite/ld-empic/relax4.c @@ -0,0 +1,3 @@ +/* Fourth source file in relaxation test. */ + +int xyzzy () { return 0; } diff --git a/ld/testsuite/ld-empic/run.c b/ld/testsuite/ld-empic/run.c new file mode 100644 index 0000000..9a0377e --- /dev/null +++ b/ld/testsuite/ld-empic/run.c @@ -0,0 +1,160 @@ +/* Load and run a MIPS position independent ECOFF file. + Written by Ian Lance Taylor <ian@cygnus.com> + Public domain. */ + +/* This program will load an ECOFF file into memory and execute it. + The file must have been compiled using the GNU -membedded-pic + switch to produce position independent code. This will only work + if this program is run on a MIPS system with the same endianness as + the ECOFF file. The ECOFF file must be complete. System calls may + not work correctly. + + There are further restrictions on the file (they could be removed + by doing some additional programming). The file must be aligned + such that it does not require any gaps introduced in the data + segment; the GNU linker produces such files by default. However, + the file must not assume that the text or data segment is aligned + on a page boundary. The start address must be at the start of the + text segment. + + The ECOFF file is run by calling it as though it were a function. + The address of the data segment is passed as the only argument. + The file is expected to return an integer value, which will be + printed. */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> + +/* Structures used in ECOFF files. We assume that a short is two + bytes and an int is four bytes. This is not much of an assumption, + since we already assume that we are running on a MIPS host with the + same endianness as the file we are examining. */ + +struct ecoff_filehdr { + unsigned short f_magic; /* magic number */ + unsigned short f_nscns; /* number of sections */ + unsigned int f_timdat; /* time & date stamp */ + unsigned int f_symptr; /* file pointer to symtab */ + unsigned int f_nsyms; /* number of symtab entries */ + unsigned short f_opthdr; /* sizeof(optional hdr) */ + unsigned short f_flags; /* flags */ +}; + +struct ecoff_aouthdr +{ + unsigned short magic; /* type of file */ + unsigned short vstamp; /* version stamp */ + unsigned int tsize; /* text size in bytes, padded to FW bdry*/ + unsigned int dsize; /* initialized data " " */ + unsigned int bsize; /* uninitialized data " " */ + unsigned int entry; /* entry pt. */ + unsigned int text_start; /* base of text used for this file */ + unsigned int data_start; /* base of data used for this file */ + unsigned int bss_start; /* base of bss used for this file */ + unsigned int gprmask; /* ?? */ + unsigned int cprmask[4]; /* ?? */ + unsigned int gp_value; /* value for gp register */ +}; + +#define ECOFF_SCNHDR_SIZE (40) + +static void +die (s) + char *s; +{ + perror (s); + exit (1); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + FILE *f; + struct stat s; + char *z; + struct ecoff_filehdr *fh; + struct ecoff_aouthdr *ah; + unsigned int toff; + char *t, *d; + int (*pfn) (); + int ret; + + if (argc != 2) + { + fprintf (stderr, "Usage: %s file\n", argv[0]); + exit (1); + } + + f = fopen (argv[1], "r"); + if (f == NULL) + die (argv[1]); + + if (stat (argv[1], &s) < 0) + die ("stat"); + + z = (char *) malloc (s.st_size); + if (z == NULL) + die ("malloc"); + + if (fread (z, 1, s.st_size, f) != s.st_size) + die ("fread"); + + /* We need to figure out the start of the text segment, which is the + location we are going to call, and the start of the data segment, + which we are going to pass as an argument. We also need the size + and start address of the bss segment. This information is all in + the ECOFF a.out header. */ + + fh = (struct ecoff_filehdr *) z; + if (fh->f_opthdr != sizeof (struct ecoff_aouthdr)) + { + fprintf (stderr, "%s: unexpected opthdr size: is %u, want %u\n", + argv[1], (unsigned int) fh->f_opthdr, + (unsigned int) sizeof (struct ecoff_aouthdr)); + exit (1); + } + + ah = (struct ecoff_aouthdr *) (z + sizeof (struct ecoff_filehdr)); + if (ah->magic != 0413) + { + fprintf (stderr, "%s: bad aouthdr magic number 0%o (want 0413)\n", + argv[1], (unsigned int) ah->magic); + exit (1); + } + + /* We should clear the bss segment at this point. This is the + ah->bsize bytes starting at ah->bss_start, To do this correctly, + we would have to make sure our memory block is large enough. It + so happens that our test case does not have any additional pages + for the bss segment--it is contained within the data segment. + So, we don't bother. */ + if (ah->bsize != 0) + { + fprintf (stderr, + "%s: bss segment is %u bytes; non-zero sizes not supported\n", + argv[1], ah->bsize); + exit (1); + } + + /* The text section starts just after all the headers, rounded to a + 16 byte boundary. */ + toff = (sizeof (struct ecoff_filehdr) + sizeof (struct ecoff_aouthdr) + + fh->f_nscns * ECOFF_SCNHDR_SIZE); + toff += 15; + toff &=~ 15; + t = z + toff; + + /* The tsize field gives us the start of the data segment. */ + d = z + ah->tsize; + + /* Call the code as a function. */ + pfn = (int (*) ()) t; + ret = (*pfn) (d); + + printf ("%s ran and returned %d\n", argv[1], ret); + + exit (0); +} diff --git a/ld/testsuite/ld-empic/runtest1.c b/ld/testsuite/ld-empic/runtest1.c new file mode 100644 index 0000000..f9ab6eb --- /dev/null +++ b/ld/testsuite/ld-empic/runtest1.c @@ -0,0 +1,117 @@ +/* First C source file for actual execution test. */ + +/* The main point of this test is to make sure that the code and data + are truly position independent. We statically initialize several + global variables, and make sure that they are correctly adjusted at + runtime. */ + +int i = 1; +int j = 0; +extern int k; +int l; +char small_buf[] = "aaaa"; +char *small_pointer = small_buf; +char big_buf[] = "aaaaaaaaaaaaaaaa"; +char *big_pointer = big_buf; + +extern int bar (); +int (*pbar) () = bar; + +static int +foo2 (arg) + int arg; +{ + l = arg; + return i + j; +} + +int (*pfoo2) () = foo2; + +int +chkstr (z, c) + char *z; + int c; +{ + /* Switch statements need extra effort to be position independent, + so we run one here, even though most of the cases will never be + taken. */ + switch (c) + { + case 1: + case 2: + case 3: + return i - 1; + case 4: + break; + case 5: + case 6: + case 7: + case 8: + case 9: + return i * j; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + return j; + case 16: + break; + default: + return 0; + } + + while (c-- != 0) + if (*z++ != 'a') + return 0; + + return *z == '\0'; +} + +/* This function is called by the assembler startup routine. It tries + to test that everything was correctly initialized. It returns 0 on + success, something else on failure. */ + +int +foo () +{ + if (i != 1) + return 1; + if (j != 0) + return 2; + if (! chkstr (small_buf, 4)) + return 3; + if (! chkstr (small_pointer, 4)) + return 4; + if (! chkstr (big_buf, 16)) + return 5; + if (! chkstr (big_pointer, 16)) + return 6; + + if (l != 0) + return 7; + if (foo2 (1) != 1) + return 8; + if (l != 1) + return 9; + if ((*pfoo2) (2) != 1) + return 10; + if (l != 2) + return 11; + + if (bar (1) != 0) + return 12; + if (bar (-1) != 1) + return 13; + if ((*pbar) (0xa5a5a5a5) != -1) + return 14; + if (k != 0xa5a5a5a5) + return 15; + if ((*pbar) (0) != 0xa5a5a5a5) + return 16; + if (k != 0) + return 17; + + return 0; +} diff --git a/ld/testsuite/ld-empic/runtest2.c b/ld/testsuite/ld-empic/runtest2.c new file mode 100644 index 0000000..000525f --- /dev/null +++ b/ld/testsuite/ld-empic/runtest2.c @@ -0,0 +1,26 @@ +/* Second C source file for actual execution test. */ + +int k; +extern int i; +extern int j; +extern char small_buf[]; +extern char *small_pointer; + +extern int chkstr (); + +int +bar (n) + int n; +{ + int r; + + if (i != 1 + || j != 0 + || ! chkstr (small_buf, 4) + || ! chkstr (small_pointer, 4)) + return k + 1; + + r = k; + k = n; + return r; +} diff --git a/ld/testsuite/ld-empic/runtesti.s b/ld/testsuite/ld-empic/runtesti.s new file mode 100644 index 0000000..efa1953 --- /dev/null +++ b/ld/testsuite/ld-empic/runtesti.s @@ -0,0 +1,94 @@ +# Assembler initialization code for actual execution test. + +# This code becomes the start of the execution test program. It is +# responsible for initializing the static data, invoking the C code, +# and returning the result. It is called as though it were a C +# function with an argument of the address of the data segment. + +# We need to know the value of _ftext and _fdata at link time, but we +# have no way to actually get that at runtime. This is because when +# this code is compiled with -membedded-pic, the la instruction will +# be turned into an addiu $gp instruction. We work around this by +# storing the information in words in the .data section. We then load +# the values of these words *before* doing the runtime relocation. + .sdata +text_start: + .word _ftext +data_start: + .word _fdata + + .globl start + .text +start: + # Grab some space on the stack, just as though we were a real + # function. + addiu $sp,$sp,-8 + sw $31,0($sp) + + # Save the $gp register, and set it up for our data section. + sw $gp,4($sp) + + addu $gp,$4,0x8000 # macro + + # The start of the data segment is in $4. + + # Get the address of start into $5 in a position independent + # fashion. + .set noreorder + $LF1 = . + 8 + bal $LF1 + la $5,start-$LF1 # macro + .set reorder + addu $5,$5,$31 + + # Now get the address of _ftext into $6. + la $6,_ftext-start # macro + addu $6,$6,$5 + + # Get the value of _ftext used to link into $7. + lw $7,text_start # macro + + # Get the value of _fdata used to link into $8. + lw $8,data_start # macro + + # Get the address of __runtime_reloc_start into $9. + la $9,__runtime_reloc_start-start # macro + addu $9,$9,$5 + + # Get the address of __runtime_reloc_stop into $10. + la $10,__runtime_reloc_stop-start # macro + addu $10,$10,$5 + + # The words between $9 and $10 are the runtime initialization + # instructions. Step through and relocate them. First set + # $11 and $12 to the values to add to text and data sections, + # respectively. + subu $11,$6,$7 + subu $12,$4,$8 + +1: + bge $9,$10,3f # macro + lw $13,0($9) + and $14,$13,0xfffffffe # macro + move $15,$11 + beq $13,$14,2f + move $15,$12 +2: + addu $14,$14,$4 + lw $24,0($14) + addu $24,$24,$15 + sw $24,0($14) + addiu $9,$9,4 + b 1b +3: + + # Now the statically initialized data has been relocated + # correctly, and we can call the C code which does the actual + # testing. + bal foo + + # We return the value returned by the C code. + lw $31,0($sp) + lw $gp,4($sp) + addu $sp,$sp,8 + j $31 diff --git a/ld/testsuite/ld-scripts/cross1.c b/ld/testsuite/ld-scripts/cross1.c new file mode 100644 index 0000000..5678945 --- /dev/null +++ b/ld/testsuite/ld-scripts/cross1.c @@ -0,0 +1,6 @@ +extern int foo (); +int +func () +{ + return foo (); +} diff --git a/ld/testsuite/ld-scripts/cross1.t b/ld/testsuite/ld-scripts/cross1.t new file mode 100644 index 0000000..e1948c9 --- /dev/null +++ b/ld/testsuite/ld-scripts/cross1.t @@ -0,0 +1,6 @@ +NOCROSSREFS ( .text .data ) +SECTIONS +{ + .text : { tmpdir/cross1.o } + .data : { tmpdir/cross2.o } +} diff --git a/ld/testsuite/ld-scripts/cross2.c b/ld/testsuite/ld-scripts/cross2.c new file mode 100644 index 0000000..4143177 --- /dev/null +++ b/ld/testsuite/ld-scripts/cross2.c @@ -0,0 +1,5 @@ +int +foo () +{ + return 1; +} diff --git a/ld/testsuite/ld-scripts/cross2.t b/ld/testsuite/ld-scripts/cross2.t new file mode 100644 index 0000000..cf046f6 --- /dev/null +++ b/ld/testsuite/ld-scripts/cross2.t @@ -0,0 +1,6 @@ +NOCROSSREFS ( .text .data ) +SECTIONS +{ + .text : { *(.text) *(.pr) } + .data : { *(.data) *(.sdata) *(.rw) *(.tc0) *(.tc) } +} diff --git a/ld/testsuite/ld-scripts/cross3.c b/ld/testsuite/ld-scripts/cross3.c new file mode 100644 index 0000000..1848c32 --- /dev/null +++ b/ld/testsuite/ld-scripts/cross3.c @@ -0,0 +1,7 @@ +int i = 4; + +int +foo () +{ + return i; +} diff --git a/ld/testsuite/ld-scripts/crossref.exp b/ld/testsuite/ld-scripts/crossref.exp new file mode 100644 index 0000000..fee9759 --- /dev/null +++ b/ld/testsuite/ld-scripts/crossref.exp @@ -0,0 +1,77 @@ +# Test NOCROSSREFS in a linker script. +# By Ian Lance Taylor, Cygnus Support. + +set test1 "NOCROSSREFS 1" +set test2 "NOCROSSREFS 2" + +if { [which $CC] == 0 } { + untested $test1 + untested $test2 + return +} + +if { ![ld_compile $CC "$srcdir/$subdir/cross1.c" tmpdir/cross1.o] \ + || ![ld_compile $CC "$srcdir/$subdir/cross2.c" tmpdir/cross2.o] } { + unresolved $test1 + unresolved $test2 + return +} + +set flags "" + +# The a29k compiled code calls V_SPILL and V_FILL. Since we don't +# need to run this code, but we don't have definitions for those +# functions, we just define them out. +if [istarget a29k*-*-*] { + set flags "$flags --defsym V_SPILL=0 --defsym V_FILL=0" +} + +# hppa-elf needs a definition for $global$. +if [istarget hppa*-*-*] { + set flags "$flags --defsym '\$global\$'=0" +} + +verbose -log "$ld $flags -o tmpdir/cross1 -T $srcdir/$subdir/cross1.t tmpdir/cross1.o tmpdir/cross2.o" + +catch "exec $ld $flags -o tmpdir/cross1 -T $srcdir/$subdir/cross1.t tmpdir/cross1.o tmpdir/cross2.o" exec_output + +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output + +if [string match "" $exec_output] then { + fail $test1 +} else { + verbose -log "$exec_output" + if [regexp "prohibited cross reference from .* to `foo' in" $exec_output] { + pass $test1 + } else { + fail $test1 + } +} + +# Check cross references within a single object. + +if { ![ld_compile $CC "$srcdir/$subdir/cross3.c" tmpdir/cross3.o] } { + unresolved $test2 + return +} + +verbose -log "$ld $flags -o tmpdir/cross2 -T $srcdir/$subdir/cross2.t tmpdir/cross3.o" + +catch "exec $ld $flags -o tmpdir/cross2 -T $srcdir/$subdir/cross2.t tmpdir/cross3.o" exec_output + +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output + +if [string match "" $exec_output] then { + fail $test2 +} else { + verbose -log "$exec_output" + if [regexp "prohibited cross reference from .* to `.*' in" $exec_output] { + pass $test2 + } else { + fail $test2 + } +} diff --git a/ld/testsuite/ld-scripts/defined.exp b/ld/testsuite/ld-scripts/defined.exp new file mode 100644 index 0000000..6da26bc --- /dev/null +++ b/ld/testsuite/ld-scripts/defined.exp @@ -0,0 +1,39 @@ +# Test DEFINED in a linker script. +# By Ian Lance Taylor, Cygnus Support. + +set testname "DEFINED" +set prms_id 5699 + +if ![ld_assemble $as $srcdir/$subdir/defined.s tmpdir/def.o] { + unresolved $testname + return +} + +if ![ld_simple_link $ld tmpdir/def "-T $srcdir/$subdir/defined.t tmpdir/def.o"] { + fail $testname +} else { + if ![ld_nm $nm tmpdir/def] { + unresolved $testname + } else { + if {![info exists nm_output(value1)] \ + || ![info exists nm_output(value2)]} { + send_log "bad output from nm\n" + verbose "bad output from nm" + fail $testname + } else { + if {$nm_output(value1) != 1} { + send_log "value1 == $nm_output(value1)\n" + verbose "value1 == $nm_output(value1)" + fail $testname + } else { + if {$nm_output(value2) != 2} { + send_log "value2 == $nm_output(value2)\n" + verbose "value2 == $nm_output(value2)" + fail $testname + } else { + pass $testname + } + } + } + } +} diff --git a/ld/testsuite/ld-scripts/defined.s b/ld/testsuite/ld-scripts/defined.s new file mode 100644 index 0000000..a364bbb --- /dev/null +++ b/ld/testsuite/ld-scripts/defined.s @@ -0,0 +1,2 @@ + .globl defined + defined = 1 diff --git a/ld/testsuite/ld-scripts/defined.t b/ld/testsuite/ld-scripts/defined.t new file mode 100644 index 0000000..c1ef1b6 --- /dev/null +++ b/ld/testsuite/ld-scripts/defined.t @@ -0,0 +1,7 @@ +SECTIONS { + .text : { *(.text) } + .data : { *(.data) } + .bss : { *(.bss) *(COMMON) } +} +value1 = DEFINED (defined) ? 1 : 2; +value2 = DEFINED (undefined) ? 1 : 2; diff --git a/ld/testsuite/ld-scripts/phdrs.exp b/ld/testsuite/ld-scripts/phdrs.exp new file mode 100644 index 0000000..34ee00f --- /dev/null +++ b/ld/testsuite/ld-scripts/phdrs.exp @@ -0,0 +1,57 @@ +# Test PHDRS in a linker script. +# By Ian Lance Taylor, Cygnus Support. + +# PHDRS is only meaningful for ELF. +if { ![istarget *-*-sysv4*] \ + && ![istarget *-*-unixware*] \ + && ![istarget *-*-elf*] \ + && ![istarget *-*-eabi*] \ + && ![istarget *-*-linux*] \ + && ![istarget *-*-irix5*] \ + && ![istarget *-*-irix6*] \ + && ![istarget *-*-solaris2*] } { + return +} + +if { [istarget *-*-linuxaout*] \ + || [istarget *-*-linuxoldld*] } { + return +} + +# This is a very simplistic test. + +set testname "PHDRS" + +if ![ld_assemble $as $srcdir/$subdir/phdrs.s tmpdir/phdrs.o] { + unresolved $testname + return +} + +set phdrs_regexp \ +".*Program Header:.*PHDR *off *0x00*34 *vaddr *0x00*80034 *paddr *0x00*80034.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* flags r--.*LOAD *off *0x00* *vaddr *0x00*80000 *paddr *0x00*80000.*filesz *0x00*\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags r-x.*LOAD *off *0x0\[0-9a-f\]* *vaddr *0x00*80*\[0-9a-f\]* *paddr *0x00*80*\[0-9a-f\]*.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags *rw-.*" + +# On a 64 bit ELF format, we need different numbers. +if { [istarget alpha*-*-*] } then { + set phdrs_regexp \ +".*Program Header:.*PHDR *off *0x00*40 *vaddr *0x00*80040 *paddr *0x00*80040.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* flags r--.*LOAD *off *0x00* *vaddr *0x00*80000 *paddr *0x00*80000.*filesz *0x00*\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags r-x.*LOAD *off *0x0\[0-9a-f\]* *vaddr *0x00*80*\[0-9a-f\]* *paddr *0x00*80*\[0-9a-f\]*.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags *rw-.*" +} + +if ![ld_simple_link $ld tmpdir/phdrs "-T $srcdir/$subdir/phdrs.t tmpdir/phdrs.o"] { + fail $testname +} else { + if {[which $objdump] == 0} { + unresolved $testname + return + } + + verbose -log "$objdump --private tmpdir/phdrs" + catch "exec $objdump --private tmpdir/phdrs" exec_output + set exec_output [prune_warnings $exec_output] + verbose -log $exec_output + + if [regexp $phdrs_regexp $exec_output] { + pass $testname + } else { + fail $testname + } +} diff --git a/ld/testsuite/ld-scripts/phdrs.s b/ld/testsuite/ld-scripts/phdrs.s new file mode 100644 index 0000000..ec1f0d1 --- /dev/null +++ b/ld/testsuite/ld-scripts/phdrs.s @@ -0,0 +1,8 @@ + .text + + .long 1 + + .data + + .long 2 + diff --git a/ld/testsuite/ld-scripts/phdrs.t b/ld/testsuite/ld-scripts/phdrs.t new file mode 100644 index 0000000..8f710e2 --- /dev/null +++ b/ld/testsuite/ld-scripts/phdrs.t @@ -0,0 +1,14 @@ +PHDRS +{ + header PT_PHDR PHDRS ; + text PT_LOAD FILEHDR PHDRS ; + data PT_LOAD ; +} + +SECTIONS +{ + . = 0x80000 + SIZEOF_HEADERS; + .text : { *(.text) } :text + .data : { *(.data) } :data + /DISCARD/ : { *(.reginfo) } +} diff --git a/ld/testsuite/ld-scripts/script.exp b/ld/testsuite/ld-scripts/script.exp new file mode 100644 index 0000000..fe0a041 --- /dev/null +++ b/ld/testsuite/ld-scripts/script.exp @@ -0,0 +1,64 @@ +# Test basic linker script functionality +# By Ian Lance Taylor, Cygnus Support + +set testname "script" + +if ![ld_assemble $as $srcdir/$subdir/script.s tmpdir/script.o] { + unresolved $testname + return +} + +proc check_script { } { + global nm + global testname + global nm_output + + if ![ld_nm $nm tmpdir/script] { + unresolved $testname + } else { + if {![info exists nm_output(text_start)] \ + || ![info exists nm_output(text_end)] \ + || ![info exists nm_output(data_start)] \ + || ![info exists nm_output(data_end)]} { + send_log "bad output from nm\n" + verbose "bad output from nm" + fail $testname + } else { + if {$nm_output(text_start) != 0x100} { + send_log "text_start == $nm_output(text_start)\n" + verbose "text_start == $nm_output(text_start)" + fail $testname + } else { if {$nm_output(text_end) < 0x104 \ + || $nm_output(text_end) > 0x110} { + send_log "text_end == $nm_output(text_end)\n" + verbose "text_end == $nm_output(text_end)" + fail $testname + } else { if {$nm_output(data_start) != 0x1000} { + send_log "data_start == $nm_output(data_start)\n" + verbose "data_start == $nm_output(data_start)" + fail $testname + } else { if {$nm_output(data_end) < 0x1004 \ + || $nm_output(data_end) > 0x1010} { + send_log "data_end == $nm_output(data_end)\n" + verbose "data_end == $nm_output(data_end)" + fail $testname + } else { + pass $testname + } } } } + } + } +} + +if ![ld_simple_link $ld tmpdir/script "-T $srcdir/$subdir/script.t tmpdir/script.o"] { + fail $testname +} else { + check_script +} + +set testname "MRI script" + +if ![ld_simple_link $ld tmpdir/script "-c $srcdir/$subdir/scriptm.t"] { + fail $testname +} else { + check_script +} diff --git a/ld/testsuite/ld-scripts/script.s b/ld/testsuite/ld-scripts/script.s new file mode 100644 index 0000000..d7b65b0 --- /dev/null +++ b/ld/testsuite/ld-scripts/script.s @@ -0,0 +1,8 @@ + .text + .globl text_symbol +text_symbol: + .long 1 + .data + .globl data_symbol +data_symbol: + .long 2 diff --git a/ld/testsuite/ld-scripts/script.t b/ld/testsuite/ld-scripts/script.t new file mode 100644 index 0000000..ee7a48a --- /dev/null +++ b/ld/testsuite/ld-scripts/script.t @@ -0,0 +1,16 @@ +SECTIONS +{ + .text 0x100 : { + text_start = .; + *(.text) + *(.pr) + text_end = .; + } + . = 0x1000; + .data : { + data_start = .; + *(.data) + *(.rw) + data_end = .; + } +} diff --git a/ld/testsuite/ld-scripts/scriptm.t b/ld/testsuite/ld-scripts/scriptm.t new file mode 100644 index 0000000..57ccae1 --- /dev/null +++ b/ld/testsuite/ld-scripts/scriptm.t @@ -0,0 +1,10 @@ +* MRI script +sect .text = $100 ; .text start address +sect .data = 1000h ; .data start address +public text_start = $100 +public text_end = # continuation line + text_start + 4 +public data_start = 1000h +public data_end = data_start + 4 + +load tmpdir/script.o diff --git a/ld/testsuite/ld-scripts/sizeof.exp b/ld/testsuite/ld-scripts/sizeof.exp new file mode 100644 index 0000000..3bdefd4 --- /dev/null +++ b/ld/testsuite/ld-scripts/sizeof.exp @@ -0,0 +1,55 @@ +# Test SIZEOF in a linker script. +# By Ian Lance Taylor, Cygnus Support +# Based on a bug report from anders.blomdell@control.lth.se. + +set testname "SIZEOF" + +if ![ld_assemble $as $srcdir/$subdir/sizeof.s tmpdir/sizeof.o] { + unresolved $testname + return +} + +if ![ld_simple_link $ld tmpdir/sizeof "-T $srcdir/$subdir/sizeof.t tmpdir/sizeof.o"] { + fail $testname + return +} + +if ![ld_nm $nm tmpdir/sizeof] { + unresolved $testname + return +} + +if {![info exists nm_output(text_start)] \ + || ![info exists nm_output(text_end)] \ + || ![info exists nm_output(data_start)] \ + || ![info exists nm_output(data_end)] \ + || ![info exists nm_output(sizeof_text)] \ + || ![info exists nm_output(sizeof_data)]} { + send_log "bad output from nm\n" + verbose "bad output from nm" + fail $testname + return +} + +if {$nm_output(text_end) - $nm_output(text_start) != $nm_output(sizeof_text)} { + send_log "text_end - text_start != sizeof_text\n" + verbose "text_end - text_start != sizeof_text" + fail $testname + return +} + +if {$nm_output(data_end) - $nm_output(data_start) != $nm_output(sizeof_data)} { + send_log "data_end - data_start != sizeof_data\n" + verbose "data_end - data_start != sizeof_data" + fail $testname + return +} + +if {$nm_output(sizeof_text) != $nm_output(sizeof_data)} { + send_log "sizeof_text != sizeof_data\n" + verbose "sizeof_text != sizeof_data" + fail $testname + return +} + +pass $testname diff --git a/ld/testsuite/ld-scripts/sizeof.s b/ld/testsuite/ld-scripts/sizeof.s new file mode 100644 index 0000000..e221ca3 --- /dev/null +++ b/ld/testsuite/ld-scripts/sizeof.s @@ -0,0 +1 @@ + .space 16 diff --git a/ld/testsuite/ld-scripts/sizeof.t b/ld/testsuite/ld-scripts/sizeof.t new file mode 100644 index 0000000..6244a37 --- /dev/null +++ b/ld/testsuite/ld-scripts/sizeof.t @@ -0,0 +1,17 @@ +SECTIONS { + .text : + { + text_start = .; + tmpdir/sizeof.o + text_end = .; + } + .data : + { + data_start = .; + . = . + SIZEOF(.text); + data_end = .; + } +} + +sizeof_text = SIZEOF(.text); +sizeof_data = SIZEOF(.data); diff --git a/ld/testsuite/ld-scripts/weak.exp b/ld/testsuite/ld-scripts/weak.exp new file mode 100644 index 0000000..f69db57 --- /dev/null +++ b/ld/testsuite/ld-scripts/weak.exp @@ -0,0 +1,57 @@ +# Test weak symbols. +# By Ian Lance Taylor, Cygnus Solutions. + +set testname "weak symbols" + +# This test only works for ELF targets. It ought to work for some +# a.out targets, but it doesn't. + +if { ![istarget *-*-sysv4*] \ + && ![istarget *-*-unixware*] \ + && ![istarget *-*-elf*] \ + && ![istarget *-*-eabi*] \ + && ![istarget *-*-linux*] \ + && ![istarget *-*-irix5*] \ + && ![istarget *-*-irix6*] \ + && ![istarget *-*-solaris2*] } then { + return +} + +if { [istarget *-*-linuxaout*] \ + || [istarget *-*-linuxoldld*] } { + return +} + +if {! [ld_assemble $as $srcdir/$subdir/weak1.s tmpdir/weak1.o] + || ! [ld_assemble $as $srcdir/$subdir/weak2.s tmpdir/weak2.o]} then { + # It's OK if .weak doesn't work on this target. + unresolved $testname + return +} + +set weak_regexp_big \ +".*Contents of section .text:.*1000 00001008 0000200c 12121212 34343434.*Contents of section .data:.*2000 00001008 0000200c 56565656 78787878.*" + +set weak_regexp_little \ +".*Contents of section .text:.*1000 08100000 0c200000 12121212 34343434.*Contents of section .data:.*2000 08100000 0c200000 56565656 78787878.*" + +if {! [ld_simple_link $ld tmpdir/weak "-T $srcdir/$subdir/weak.t tmpdir/weak1.o tmpdir/weak2.o"] } then { + fail $testname +} else { + if {[which $objdump] == 0} then { + unresolved $testname + return + } + + verbose -log "$objdump -s tmpdir/weak" + catch "exec $objdump -s tmpdir/weak" exec_output + set exec_output [prune_warnings $exec_output] + verbose -log $exec_output + + if {[regexp $weak_regexp_big $exec_output] \ + || [regexp $weak_regexp_little $exec_output] } then { + pass $testname + } else { + fail $testname + } +} diff --git a/ld/testsuite/ld-scripts/weak.t b/ld/testsuite/ld-scripts/weak.t new file mode 100644 index 0000000..6cd013e --- /dev/null +++ b/ld/testsuite/ld-scripts/weak.t @@ -0,0 +1,12 @@ +SECTIONS +{ + .text 0x1000 : { + tmpdir/weak1.o(.data) + } + .data 0x2000 : { + tmpdir/weak2.o(.data) + } + /DISCARD/ : { + *(*) + } +} diff --git a/ld/testsuite/ld-scripts/weak1.s b/ld/testsuite/ld-scripts/weak1.s new file mode 100644 index 0000000..046fbe1 --- /dev/null +++ b/ld/testsuite/ld-scripts/weak1.s @@ -0,0 +1,11 @@ +.data + .global foo1 + .global sym1 + .weak sym2 +foo1: + .long sym1 + .long sym2 +sym1: + .long 0x12121212 +sym2: + .long 0x34343434 diff --git a/ld/testsuite/ld-scripts/weak2.s b/ld/testsuite/ld-scripts/weak2.s new file mode 100644 index 0000000..04edff5 --- /dev/null +++ b/ld/testsuite/ld-scripts/weak2.s @@ -0,0 +1,11 @@ +.data + .global foo2 + .weak sym1 + .global sym2 +foo2: + .long sym1 + .long sym2 +sym1: + .long 0x56565656 +sym2: + .long 0x78787878 diff --git a/ld/testsuite/ld-selective/1.c b/ld/testsuite/ld-selective/1.c new file mode 100644 index 0000000..1202367 --- /dev/null +++ b/ld/testsuite/ld-selective/1.c @@ -0,0 +1,12 @@ +/* _start should be the only thing left after GC. */ + +void _start() __asm__("_start"); +void _start() +{ +} + +void dropme1() +{ +} + +int dropme2[102] = { 0 }; diff --git a/ld/testsuite/ld-selective/2.c b/ld/testsuite/ld-selective/2.c new file mode 100644 index 0000000..7295887 --- /dev/null +++ b/ld/testsuite/ld-selective/2.c @@ -0,0 +1,19 @@ +/* Normally we should loose foo and keep _start and _init. + With -u foo, we should keep that as well. */ + +void _start() __asm__("_start"); +void _start() +{ +} + +void __attribute__((section(".init"))) +_init() +{ +} + +int foo() __asm__("foo"); +int foo() +{ + static int x = 1; + return x++; +} diff --git a/ld/testsuite/ld-selective/3.cc b/ld/testsuite/ld-selective/3.cc new file mode 100644 index 0000000..852bc5d --- /dev/null +++ b/ld/testsuite/ld-selective/3.cc @@ -0,0 +1,33 @@ +struct A +{ + virtual void foo(); + virtual void bar(); +}; + +void A::foo() { } // keep +void A::bar() { } // loose + +struct B : public A +{ + virtual void foo(); +}; + +void B::foo() { } // keep + +void _start() __asm__("_start"); // keep + +A a; // keep +B b; +A *getme() { return &a; } // keep + +void _start() +{ + getme()->foo(); +} + +// In addition, keep A's virtual table. + +// We'll wind up keeping `b' and thus B's virtual table because +// `a' and `b' are both referenced from the constructor function. + +extern "C" void __main() { } diff --git a/ld/testsuite/ld-selective/4.cc b/ld/testsuite/ld-selective/4.cc new file mode 100644 index 0000000..9df26ac --- /dev/null +++ b/ld/testsuite/ld-selective/4.cc @@ -0,0 +1,28 @@ +struct A +{ + virtual void foo(); + virtual void bar(); +}; + +void A::foo() { } // loose +void A::bar() { } // keep + +struct B : public A +{ + virtual void foo(); +}; + +void B::foo() { } // loose + +void _start() __asm__("_start"); // keep + +A a; // keep +B b; +A *getme() { return &a; } // keep + +void _start() +{ + getme()->bar(); +} + +extern "C" void __main() { } diff --git a/ld/testsuite/ld-selective/5.cc b/ld/testsuite/ld-selective/5.cc new file mode 100644 index 0000000..5179d91 --- /dev/null +++ b/ld/testsuite/ld-selective/5.cc @@ -0,0 +1,32 @@ +// This test currently fails because the C++ front end emits `A' as +// the base class called rather than `B' as it ought. At least it +// is erroring on the safe side... + +struct A +{ + virtual void foo(); + virtual void bar(); +}; + +void A::foo() { } // loose +void A::bar() { } // loose + +struct B : public A +{ + virtual void foo(); +}; + +void B::foo() { } // keep + +void _start() __asm__("_start"); // keep + +A a; +B b; // keep +B *getme() { return &b; } // keep + +void _start() +{ + getme()->foo(); +} + +extern "C" void __main() { } diff --git a/ld/testsuite/ld-selective/selective.exp b/ld/testsuite/ld-selective/selective.exp new file mode 100644 index 0000000..e6a9d97 --- /dev/null +++ b/ld/testsuite/ld-selective/selective.exp @@ -0,0 +1,208 @@ +# Expect script for LD selective linking tests +# Copyright (C) 1998, 1999 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Catherine Moore (clm@cygnus.com) +# Make sure that constructors are handled correctly. + + +# COFF based ports do not support selective linking +if {[istarget "*-*-coff" "*-*-pe"]} { + return +} + +set test1 "selective1" +set test2 "selective2" +set test3 "selective3" +set test4 "selective4" +set test5 "selective5" +set test6 "selective6" + +set cflags "-w -O2 -ffunction-sections -fdata-sections" +set cxxflags "-fvtable-gc -fno-exceptions -fno-rtti" +set ldflags "--gc-sections -Bstatic" + +if { [which $CXX] == 0 } { + untested $test1 + untested $test2 + untested $test3 + untested $test4 + untested $test5 + untested $test6 + return +} + +if { ![ld_compile "$CC $cflags" $srcdir/$subdir/1.c tmpdir/1.o]} { + unresolved $test1 + return +} + +if ![ld_simple_link $ld tmpdir/1.x "$ldflags tmpdir/1.o"] { + fail $test1 +} else { + if ![ld_nm $nm tmpdir/1.x] { + unresolved $test1 + } else { + if {[info exists nm_output(dropme1)]} { + send_log "dropme1 == $nm_output(dropme1)\n" + verbose "dropme1 == $nm_output(dropme1)" + fail $test1 + } else { + if {[info exists nm_output(dropme2)]} { + send_log "dropme2 == $nm_output(dropme2)\n" + verbose "dropme2 == $nm_output(dropme2)" + fail $test1 + } else { + pass $test1 + } + } + } + } + +if { ![ld_compile "$CC $cflags" $srcdir/$subdir/2.c tmpdir/2.o]} { + unresolved $test2 + return +} + +if ![ld_simple_link $ld tmpdir/2.x "$ldflags tmpdir/2.o"] { + fail $test2 +} else { + if ![ld_nm $nm tmpdir/2.x] { + unresolved $test2 + } else { + if {[info exists nm_output(foo)] } { + send_log "foo == $nm_output(foo)\n" + verbose "foo== $nm_output(foo)" + fail $test2 + } else { + pass $test2 + } + } + } + +if { ![ld_compile "$CC $cflags" $srcdir/$subdir/2.c tmpdir/2.o]} { + unresolved $test3 + return +} + +if ![ld_simple_link $ld tmpdir/2.x "$ldflags -u foo tmpdir/2.o"] { + fail $test3 +} else { + if ![ld_nm $nm tmpdir/2.x] { + unresolved $test3 + } else { + if {![info exists nm_output(foo)] } { + send_log "bad output from nm\n" + verbose "bad output from nm" + fail $test3 + } else { + if {$nm_output(foo) == 0} { + send_log "foo == $nm_output(foo)\n" + verbose "foo== $nm_output(foo)" + fail $test3 + } else { + pass $test3 + } + } + } +} + +setup_xfail "v850*-*-elf" + +if { ![ld_compile "$CC $cflags $cxxflags" $srcdir/$subdir/3.cc tmpdir/3.o]} { + unresolved $test4 + return +} + +setup_xfail "v850*-*-elf" + +if ![ld_simple_link $ld tmpdir/3.x "$ldflags tmpdir/3.o"] { + fail $test4 +} else { + if ![ld_nm $nm tmpdir/3.x] { + unresolved $test4 + } else { + if {[info exists nm_output(foo__1B)]} { + send_log "foo__1B == $nm_output(foo__1B)\n" + verbose "foo__1B == $nm_output(foo__1B)" + fail $test4 + } else { + if {[ info exists nm_output(bar__1A)]} { + send_log "bar__1A== $nm_output(_bar__1A)\n" + verbose "bar__1A == $nm_output(_bar__1A)" + fail $test4 + } else { + pass $test4 + } + } + } +} + +if { ![ld_compile "$CC $cflags $cxxflags" $srcdir/$subdir/4.cc tmpdir/4.o]} { + unresolved $test5 + return +} + +if ![ld_simple_link $ld tmpdir/4.x "$ldflags tmpdir/4.o"] { + fail $test5 +} else { + if ![ld_nm $nm tmpdir/4.x] { + unresolved $test5 + } else { + if {[info exists nm_output(foo__1B)]} { + send_log "foo__1B == $nm_output(foo__1B)\n" + verbose "foo__1B == $nm_output(foo__1B)" + fail $test5 + } else { + if {[info exists nm_output(foo__1A)]} { + send_log "foo__1A== $nm_output(foo__1A)\n" + verbose "foo__1A == $nm_output(foo__1A)" + fail $test5 + } else { + pass $test5 + } + } + } +} + +setup_xfail "v850*-*-elf" + +if { ![ld_compile "$CC $cflags $cxxflags" $srcdir/$subdir/5.cc tmpdir/5.o]} { + unresolved $test6 + return +} + +if ![ld_simple_link $ld tmpdir/5.x "$ldflags tmpdir/5.o"] { + fail $test6 +} else { + if ![ld_nm $nm tmpdir/5.x] { + unresolved $test6 + } else { + if {[info exists nm_output(foo__1B)] } { + send_log "foo__1B == $nm_output(foo__1B)\n" + verbose "foo__1B == $nm_output(foo__1B)" + fail $test6 + } else { + if { [info exists nm_output(foo__1A)]} { + send_log "foo__1A== $nm_output(foo__1A)\n" + verbose "foo__1A == $nm_output(foo__1A)" + fail $test6 + } else { + pass $test6 + } + } + } +} diff --git a/ld/testsuite/ld-sh/sh.exp b/ld/testsuite/ld-sh/sh.exp new file mode 100644 index 0000000..c646d26 --- /dev/null +++ b/ld/testsuite/ld-sh/sh.exp @@ -0,0 +1,143 @@ +# Expect script for ld-sh tests +# Copyright (C) 1995, 1996, 1997 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Ian Lance Taylor (ian@cygnus.com) +# + +# Test SH relaxing. This tests the compiler and assembler as well as +# the linker. + +if ![istarget sh*-*-*] { + return +} + +set testsimple "SH simple relaxing" + +if ![ld_assemble $as "-relax $srcdir/$subdir/sh1.s" tmpdir/sh1.o] { + unresolved $testsimple +} else { if ![ld_simple_link $ld tmpdir/sh1 "-relax tmpdir/sh1.o"] { + fail $testsimple +} else { + if ![ld_nm $nm tmpdir/sh1] { + unresolved $testsimple + } else { + if {![info exists nm_output(bar)] \ + || ![info exists nm_output(foo)]} { + send_log "bad output from nm\n" + verbose "bad output from nm" + fail $testsimple + } else { + if {$nm_output(bar) != $nm_output(foo) + 4} { + send_log "foo == $nm_output(foo)\n" + verbose "foo == $nm_output(foo)" + send_log "bar == $nm_output(bar)\n" + verbose "bar == $nm_output(bar)" + fail $testsimple + } else { + pass $testsimple + } + } + } +} } + +set testsrec "SH relaxing to S-records" + +if ![ld_simple_link $ld tmpdir/sh1.s1 "-relax -oformat srec tmpdir/sh1.o"] { + fail $testsrec +} else { + # The file name is embedded in the S-records, so create both + # files with the same name. + catch "exec rm -f tmpdir/sh1.s2" exec_output + send_log "mv tmpdir/sh1.s1 tmpdir/sh1.s2\n" + verbose "mv tmpdir/sh1.s1 tmpdir/sh1.s2" + catch "exec mv tmpdir/sh1.s1 tmpdir/sh1.s2" exec_output + if ![string match "" $exec_output] { + send_log "$exec_output\n" + verbose "$exec_output" + unresolved $testsrec + } else { + send_log "$objcopy -O srec tmpdir/sh1 tmpdir/sh1.s1" + verbose "$objcopy -O srec tmpdir/sh1 tmpdir/sh1.s1" + catch "exec $objcopy -O srec tmpdir/sh1 tmpdir/sh1.s1" exec_output + if ![string match "" $exec_output] { + send_log "$exec_output\n" + verbose "$exec_output" + unresolved $testsrec + } else { + send_log "cmp tmpdir/sh1.s1 tmpdir/sh1.s2\n" + verbose "cmp tmpdir/sh1.s1 tmpdir/sh1.s2" + catch "exec cmp tmpdir/sh1.s1 tmpdir/sh1.s2" exec_output + set exec_output [prune_warnings $exec_output] + if ![string match "" $exec_output] { + send_log "$exec_output\n" + verbose "$exec_output" + fail $testsrec + } else { + pass $testsrec + } + } + } +} + +set testlink "SH relaxing" +set testjsr "SH confirm relaxing" +set testrun "SH relaxing execution" + +if { [which $CC] == 0 } { + untested $testlink + untested $testjsr + untested $testrun + return +} + +if {![ld_assemble $as "-relax $srcdir/$subdir/start.s" tmpdir/start.o] \ + || ![ld_compile $CC "-O -mrelax $srcdir/$subdir/sh2.c" tmpdir/sh2.o]} { + unresolved $testlink + unresolved $testjsr + unresolved $testrun + return +} + +if ![ld_simple_link $ld tmpdir/sh2 "-relax tmpdir/start.o tmpdir/sh2.o"] { + fail $testlink + unresolved $testjsr + unresolved $testrun + return +} + +pass $testlink + +send_log "$objdump -d tmpdir/sh2\n" +verbose "$objdump -d tmpdir/sh2" +catch "exec $objdump -d tmpdir/sh2" exec_output +if [string match "*jsr*" $exec_output] { + fail $testjsr +} else { + pass $testjsr +} + +if { ![info exists SIM] || [which $SIM] == 0 } { + untested $testrun + return +} + +set status [catch "exec $SIM tmpdir/sh2" exec_output] +if { $status == 0 } { + pass $testrun +} else { + fail $testrun +} diff --git a/ld/testsuite/ld-sh/sh1.s b/ld/testsuite/ld-sh/sh1.s new file mode 100644 index 0000000..d18e439 --- /dev/null +++ b/ld/testsuite/ld-sh/sh1.s @@ -0,0 +1,13 @@ + .text +foo: +L1: + mov.l L2,r0 + .uses L1 + jsr @r0 + rts + .align 2 +L2: + .long bar +bar: + rts + .align 4 diff --git a/ld/testsuite/ld-sh/sh2.c b/ld/testsuite/ld-sh/sh2.c new file mode 100644 index 0000000..527fe88 --- /dev/null +++ b/ld/testsuite/ld-sh/sh2.c @@ -0,0 +1,120 @@ +int global; + +extern void trap (int, int); +static void quit (int); +static int foo (int); + +int +main () +{ + if (foo (0) != 0 || global != 0) + quit (1); + if (foo (1) != 1 || global != 1) + quit (1); + if (foo (2) != 2 || global != 2) + quit (1); + if (foo (3) != 3 || global != 3) + quit (1); + if (foo (4) != 4 || global != 4) + quit (1); + if (foo (5) != 5 || global != 5) + quit (1); + if (foo (6) != 6 || global != 6) + quit (1); + if (foo (7) != 7 || global != 7) + quit (1); + if (foo (8) != 8 || global != 8) + quit (1); + quit (0); +} + +void +__main () +{ +} + +static void +quit (int status) +{ + trap (1, status); +} + +int +bar (int i) +{ + global = i; + return i; +} + +int +bar0 (int i) +{ + global = 0; + return i; +} + +int +bar1 (int i) +{ + global = 1; + return i; +} + +int +bar2 (int i) +{ + global = 2; + return i; +} + +int +bar3 (int i) +{ + global = 3; + return i; +} + +int +bar4 (int i) +{ + global = 4; + return i; +} + +int +bar5 (int i) +{ + global = 5; + return i; +} + +int +bar6 (int i) +{ + global = 6; + return i; +} + +int +bar7 (int i) +{ + global = 7; + return i; +} + +int +foo (int i) +{ + switch (i) + { + case 0: bar0 (0); return 0; + case 1: bar1 (1); return 1; + case 2: bar2 (2); return 2; + case 3: bar3 (3); return 3; + case 4: bar4 (4); return 4; + case 5: bar5 (5); return 5; + case 6: bar6 (6); return 6; + case 7: bar7 (7); return 7; + default: return bar (i); + } +} diff --git a/ld/testsuite/ld-sh/start.s b/ld/testsuite/ld-sh/start.s new file mode 100644 index 0000000..2af4c79 --- /dev/null +++ b/ld/testsuite/ld-sh/start.s @@ -0,0 +1,27 @@ + .section .text + .global start +start: + + mov.l stack_k,r15 + + ! call the mainline +L1: + mov.l main_k,r0 + .uses L1 + jsr @r0 + nop + + .align 2 +stack_k: + .long _stack +main_k: + .long _main + + .global _trap +_trap: + trapa #3 + rts + nop + + .section .stack +_stack: .long 0xdeaddead diff --git a/ld/testsuite/ld-shared/elf-offset.ld b/ld/testsuite/ld-shared/elf-offset.ld new file mode 100644 index 0000000..dfe4293 --- /dev/null +++ b/ld/testsuite/ld-shared/elf-offset.ld @@ -0,0 +1,168 @@ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x100000; + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.text : + { + *(.rel.text) + *(.rel.text.*) + *(.rel.gnu.linkonce.t*) + } + .rela.text : + { + *(.rela.text) + *(.rela.text.*) + *(.rela.gnu.linkonce.t*) + } + .rel.data : + { + *(.rel.data) + *(.rel.data.*) + *(.rel.gnu.linkonce.d*) + } + .rela.data : + { + *(.rela.data) + *(.rela.data.*) + *(.rela.gnu.linkonce.d*) + } + .rel.rodata : + { + *(.rel.rodata) + *(.rel.rodata.*) + *(.rel.gnu.linkonce.r*) + } + .rela.rodata : + { + *(.rela.rodata) + *(.rela.rodata.*) + *(.rela.gnu.linkonce.r*) + } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { KEEP (*(.init)) } + .plt : { *(.plt) } + .text : + { + *(.text) + *(.text.*) + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } + _etext = .; + PROVIDE (etext = .); + .fini : { KEEP (*(.fini)) } =0x9090 + .rodata : + { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r*) + } + .rodata1 : { *(.rodata1) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(0x1000) + (. & (0x1000 - 1)); + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + .ctors : + { + /* gcc uses crtbegin.o to find the start of the constructors, so + we make sure it is first. Because this is a wildcard, it + doesn't matter if the user does not actually link against + crtbegin.o; the linker won't look for a file to match a + wildcard. The wildcard also means that it doesn't matter which + directory crtbegin.o is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) *(.sdata.*) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} diff --git a/ld/testsuite/ld-shared/main.c b/ld/testsuite/ld-shared/main.c new file mode 100644 index 0000000..4fcfdaa --- /dev/null +++ b/ld/testsuite/ld-shared/main.c @@ -0,0 +1,81 @@ +/* This is the main program for the shared library test. */ + +#include <stdio.h> + +int mainvar = 1; +int overriddenvar = 2; +extern int shlibvar1; + +extern int shlib_mainvar (); +extern int shlib_overriddenvar (); +extern int shlib_shlibvar1 (); +extern int shlib_shlibvar2 (); +extern int shlib_shlibcall (); +extern int shlib_maincall (); +extern int shlib_checkfunptr1 (); +extern int shlib_checkfunptr2 (); +extern int (*shlib_getfunptr1 ()) (); +extern int (*shlib_getfunptr2 ()) (); +extern int shlib_check (); + +/* This function is called by the shared library. */ + +int +main_called () +{ + return 6; +} + +/* This function overrides a function in the shared library. */ + +int +shlib_overriddencall2 () +{ + return 8; +} + +int +main () +{ + int (*p) (); + + printf ("mainvar == %d\n", mainvar); + printf ("overriddenvar == %d\n", overriddenvar); + printf ("shlibvar1 == %d\n", shlibvar1); +#ifndef XCOFF_TEST + printf ("shlib_mainvar () == %d\n", shlib_mainvar ()); + printf ("shlib_overriddenvar () == %d\n", shlib_overriddenvar ()); +#endif + printf ("shlib_shlibvar1 () == %d\n", shlib_shlibvar1 ()); + printf ("shlib_shlibvar2 () == %d\n", shlib_shlibvar2 ()); + printf ("shlib_shlibcall () == %d\n", shlib_shlibcall ()); +#ifndef XCOFF_TEST + printf ("shlib_shlibcall2 () == %d\n", shlib_shlibcall2 ()); + printf ("shlib_maincall () == %d\n", shlib_maincall ()); +#endif + printf ("main_called () == %d\n", main_called ()); + printf ("shlib_checkfunptr1 (shlib_shlibvar1) == %d\n", + shlib_checkfunptr1 (shlib_shlibvar1)); +#ifndef XCOFF_TEST + printf ("shlib_checkfunptr2 (main_called) == %d\n", + shlib_checkfunptr2 (main_called)); +#endif + p = shlib_getfunptr1 (); + printf ("shlib_getfunptr1 () "); + if (p == shlib_shlibvar1) + printf ("=="); + else + printf ("!="); + printf (" shlib_shlibvar1\n"); +#ifndef XCOFF_TEST + p = shlib_getfunptr2 (); + printf ("shlib_getfunptr2 () "); + if (p == main_called) + printf ("=="); + else + printf ("!="); + printf (" main_called\n"); +#endif + printf ("shlib_check () == %d\n", shlib_check ()); + return 0; +} diff --git a/ld/testsuite/ld-shared/sh1.c b/ld/testsuite/ld-shared/sh1.c new file mode 100644 index 0000000..e31e06a --- /dev/null +++ b/ld/testsuite/ld-shared/sh1.c @@ -0,0 +1,166 @@ +/* This is part of the shared library ld test. This file becomes part + of a shared library. */ + +/* This variable is supplied by the main program. */ +#ifndef XCOFF_TEST +extern int mainvar; +#endif + +/* This variable is defined in the shared library, and overridden by + the main program. */ +#ifndef XCOFF_TEST +int overriddenvar = -1; +#endif + +/* This variable is defined in the shared library. */ +int shlibvar1 = 3; + +/* This variable is defined by another object in the shared library. */ +extern int shlibvar2; + +/* These functions return the values of the above variables as seen in + the shared library. */ + +#ifndef XCOFF_TEST +int +shlib_mainvar () +{ + return mainvar; +} +#endif + +#ifndef XCOFF_TEST +int +shlib_overriddenvar () +{ + return overriddenvar; +} +#endif + +int +shlib_shlibvar1 () +{ + return shlibvar1; +} + +int +shlib_shlibvar2 () +{ + return shlibvar2; +} + +/* This function calls a function defined by another object in the + shared library. */ + +extern int shlib_shlibcalled (); + +int +shlib_shlibcall () +{ + return shlib_shlibcalled (); +} + +#ifndef XCOFF_TEST +/* This function calls a function defined in this object in the shared + library. The main program will override the called function. */ + +extern int shlib_overiddencall2 (); + +int +shlib_shlibcall2 () +{ + return shlib_overriddencall2 (); +} + +int +shlib_overriddencall2 () +{ + return 7; +} +#endif + +/* This function calls a function defined by the main program. */ + +#ifndef XCOFF_TEST +extern int main_called (); + +int +shlib_maincall () +{ + return main_called (); +} +#endif + +/* This function is passed a function pointer to shlib_mainvar. It + confirms that the pointer compares equally. */ + +int +shlib_checkfunptr1 (p) + int (*p) (); +{ + return p == shlib_shlibvar1; +} + +/* This function is passed a function pointer to main_called. It + confirms that the pointer compares equally. */ + +#ifndef XCOFF_TEST +int +shlib_checkfunptr2 (p) + int (*p) (); +{ + return p == main_called; +} +#endif + +/* This function returns a pointer to shlib_mainvar. */ + +int +(*shlib_getfunptr1 ()) () +{ + return shlib_shlibvar1; +} + +/* This function returns a pointer to main_called. */ + +#ifndef XCOFF_TEST +int +(*shlib_getfunptr2 ()) () +{ + return main_called; +} +#endif + +/* This function makes sure that constant data and local functions + work. */ + +#ifndef __STDC__ +#define const +#endif + +static int i = 6; +static const char *str = "Hello, world\n"; + +int +shlib_check () +{ + const char *s1, *s2; + + if (i != 6) + return 0; + + /* To isolate the test, don't rely on any external functions, such + as strcmp. */ + s1 = "Hello, world\n"; + s2 = str; + while (*s1 != '\0') + if (*s1++ != *s2++) + return 0; + if (*s2 != '\0') + return 0; + + if (shlib_shlibvar1 () != 3) + return 0; + + return 1; +} diff --git a/ld/testsuite/ld-shared/sh2.c b/ld/testsuite/ld-shared/sh2.c new file mode 100644 index 0000000..013a4e0 --- /dev/null +++ b/ld/testsuite/ld-shared/sh2.c @@ -0,0 +1,14 @@ +/* This is part of the shared library ld test. This file becomes part + of a shared library. */ + +/* This variable is defined here, and referenced by another file in + the shared library. */ +int shlibvar2 = 4; + +/* This function is called by another file in the shared library. */ + +int +shlib_shlibcalled () +{ + return 5; +} diff --git a/ld/testsuite/ld-shared/shared.dat b/ld/testsuite/ld-shared/shared.dat new file mode 100644 index 0000000..40ee37f --- /dev/null +++ b/ld/testsuite/ld-shared/shared.dat @@ -0,0 +1,16 @@ +mainvar == 1 +overriddenvar == 2 +shlibvar1 == 3 +shlib_mainvar () == 1 +shlib_overriddenvar () == 2 +shlib_shlibvar1 () == 3 +shlib_shlibvar2 () == 4 +shlib_shlibcall () == 5 +shlib_shlibcall2 () == 8 +shlib_maincall () == 6 +main_called () == 6 +shlib_checkfunptr1 (shlib_shlibvar1) == 1 +shlib_checkfunptr2 (main_called) == 1 +shlib_getfunptr1 () == shlib_shlibvar1 +shlib_getfunptr2 () == main_called +shlib_check () == 1 diff --git a/ld/testsuite/ld-shared/shared.exp b/ld/testsuite/ld-shared/shared.exp new file mode 100644 index 0000000..8939c3d --- /dev/null +++ b/ld/testsuite/ld-shared/shared.exp @@ -0,0 +1,264 @@ +# Expect script for ld-shared tests +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Ian Lance Taylor (ian@cygnus.com) +# + +# Make sure that ld can generate ELF shared libraries. +# Note that linking against ELF shared libraries is tested by the +# bootstrap test. + +# This test can only be run if ld generates native executables. +if ![isnative] then {return} + +# This test can only be run on a couple of ELF platforms. +# Square bracket expressions seem to confuse istarget. +if { ![istarget i386-*-sysv4*] \ + && ![istarget i486-*-sysv4*] \ + && ![istarget i586-*-sysv4*] \ + && ![istarget i386-*-unixware] \ + && ![istarget i486-*-unixware] \ + && ![istarget i586-*-unixware] \ + && ![istarget i386-*-elf*] \ + && ![istarget i486-*-elf*] \ + && ![istarget i586-*-elf*] \ + && ![istarget i386-*-linux*] \ + && ![istarget i486-*-linux*] \ + && ![istarget i586-*-linux*] \ + && ![istarget m68k-*-linux*] \ + && ![istarget mips*-*-irix5*] \ + && ![istarget powerpc-*-elf*] \ + && ![istarget powerpc-*-linux*] \ + && ![istarget powerpc-*-sysv4*] \ + && ![istarget sparc*-*-elf] \ + && ![istarget sparc*-*-solaris2*] \ + && ![istarget sparc*-*-sunos4*] \ + && ![istarget rs6000*-*-aix*] \ + && ![istarget powerpc*-*-aix*] } { + return +} + +if { [istarget i386-*-linuxaout*] \ + || [istarget i486-*-linuxaout*] \ + || [istarget i586-*-linuxaout*] \ + || [istarget i386-*-linuxoldld*] \ + || [istarget i486-*-linuxoldld*] \ + || [istarget i586-*-linuxoldld*] \ + || [istarget m68k-*-linuxaout*] } { + return +} + +set tmpdir tmpdir +set SHCFLAG "" + +if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { + + # AIX shared libraries do not seem to support useful features, + # like overriding the shared library function or letting the + # shared library refer to objects defined in the main program. We + # avoid testing those features. + set SHCFLAG "-DXCOFF_TEST" + + # The AIX 3.2.5 loader appears to randomly fail when loading + # shared libraries from NSF mounted partitions, so we avoid any + # potential problems by using a local directory. + catch {exec /bin/sh -c "echo $$"} pid + set tmpdir /usr/tmp/ld.$pid + catch "exec mkdir $tmpdir" exec_status + + # On AIX, we need to explicitly export the symbols the shared + # library is going to provide, and need. + set file [open $tmpdir/xcoff.exp w] + puts $file shlibvar1 + puts $file shlibvar2 + puts $file shlib_shlibvar1 + puts $file shlib_shlibvar2 + puts $file shlib_shlibcall + puts $file shlib_shlibcalled + puts $file shlib_checkfunptr1 + puts $file shlib_getfunptr1 + puts $file shlib_check + close $file +} + +# The test procedure. +proc shared_test { progname testname main sh1 sh2 dat args } { + global ld + global srcdir + global subdir + global exec_output + global host_triplet + global tmpdir + + if [llength $args] { set shldflags [lindex $args 0] } else { set shldflags "" } + + # Build the shared library. + # On AIX, we need to use an export file. + set shared -shared + if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { + set shared "-bM:SRE -bE:$tmpdir/xcoff.exp" + } + if {![ld_simple_link $ld $tmpdir/$progname.so "$shared $shldflags $tmpdir/$sh1 $tmpdir/$sh2"]} { + fail "$testname" + return + } + + # Link against the shared library. Use -rpath so that the + # dynamic linker can locate the shared library at runtime. + # On AIX, we must include /lib in -rpath, as otherwise the loader + # can not find -lc. + set rpath $tmpdir + if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { + set rpath /lib:$tmpdir + } + if ![ld_link $ld $tmpdir/$progname "-rpath $rpath $tmpdir/$main $tmpdir/$progname.so"] { + fail "$testname" + return + } + + # Run the resulting program + send_log "$tmpdir/$progname >$tmpdir/$progname.out\n" + verbose "$tmpdir/$progname >$tmpdir/$progname.out" + catch "exec $tmpdir/$progname >$tmpdir/$progname.out" exec_output + if ![string match "" $exec_output] then { + send_log "$exec_output\n" + verbose "$exec_output" + fail "$testname" + return + } + + send_log "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat\n" + verbose "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat" + catch "exec diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat" exec_output + set exec_output [prune_warnings $exec_output] + + if {![string match "" $exec_output]} then { + send_log "$exec_output\n" + verbose "$exec_output" + fail "$testname" + return + } + + pass "$testname" +} + +if [istarget mips*-*-*] { + set picflag "" +} else { + # Unfortunately, the gcc argument is -fpic and the cc argument is + # -KPIC. We have to try both. + set picflag "-fpic" + send_log "$CC $picflag\n" + verbose "$CC $picflag" + catch "exec $CC $picflag" exec_output + send_log "$exec_output\n" + verbose "--" "$exec_output" + if { [string match "*illegal option*" $exec_output] \ + || [string match "*option ignored*" $exec_output] \ + || [string match "*unrecognized option*" $exec_output] \ + || [string match "*passed to ld*" $exec_output] } { + if [istarget *-*-sunos4*] { + set picflag "-pic" + } else { + set picflag "-KPIC" + } + } +} +verbose "Using $picflag to compile PIC code" + +# Compile the main program. +if ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/main.c $tmpdir/mainnp.o] { + unresolved "shared (non PIC)" + unresolved "shared" +} else { + # The shared library is composed of two files. First compile them + # without using -fpic. That should work on an ELF system, + # although it will be less efficient because the dynamic linker + # will need to do more relocation work. However, note that not + # using -fpic will cause some of the tests to return different + # results. + if { ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/sh1.c $tmpdir/sh1np.o] + || ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/sh2.c $tmpdir/sh2np.o] } { + unresolved "shared (non PIC)" + } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { + shared_test shnp "shared (nonPIC)" mainnp.o sh1np.o sh2np.o xcoff + } else { + # SunOS non PIC shared libraries don't permit some cases of + # overriding. + setup_xfail "*-*-sunos4*" + shared_test shnp "shared (non PIC)" mainnp.o sh1np.o sh2np.o shared + + # Test ELF shared library relocations with a non-zero load + # address for the library. Near as I can tell, the R_*_RELATIVE + # relocations for various targets are broken in the case where + # the load address is not zero (which is the default). + setup_xfail "*-*-sunos4*" + shared_test shnp "shared (non PIC, load offset)" \ + mainnp.o sh1np.o sh2np.o shared \ + "-T $srcdir/$subdir/elf-offset.ld" + } } + + # Now compile the code using -fpic. + + if { ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/sh1.c $tmpdir/sh1p.o] + || ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/sh2.c $tmpdir/sh2p.o] } { + unresolved "shared" + } else { + # SunOS can not compare function pointers correctly + if [istarget "*-*-sunos4*"] { + shared_test shp "shared" mainnp.o sh1p.o sh2p.o sun4 + } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { + shared_test shp "shared" mainnp.o sh1p.o sh2p.o xcoff + } else { + shared_test shp "shared" mainnp.o sh1p.o sh2p.o shared + } } + } +} + +# Now do the same tests again, but this time compile main.c PIC. +if ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/main.c $tmpdir/mainp.o] { + unresolved "shared (PIC main, non PIC so)" + unresolved "shared (PIC main)" +} else { + if { [file exists $tmpdir/sh1np.o ] && [ file exists $tmpdir/sh2np.o ] } { + if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { + shared_test shmpnp "shared (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o xcoff + } else { + # SunOS non PIC shared libraries don't permit some cases of + # overriding. + setup_xfail "*-*-sunos4*" + shared_test shmpnp "shared (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o shared + } + } else { + unresolved "shared (PIC main, non PIC so)" + } + + if { [file exists $tmpdir/sh1p.o ] && [ file exists $tmpdir/sh2p.o ] } { + if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { + shared_test shmpp "shared (PIC main)" mainp.o sh1p.o sh2p.o xcoff + } else { + shared_test shmpp "shared (PIC main)" mainp.o sh1p.o sh2p.o shared + } + } else { + unresolved "shared (PIC main)" + } +} + +if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { + # Remove the temporary directory. + catch "exec rm -rf $tmpdir" exec_status +} diff --git a/ld/testsuite/ld-shared/sun4.dat b/ld/testsuite/ld-shared/sun4.dat new file mode 100644 index 0000000..be0d87d --- /dev/null +++ b/ld/testsuite/ld-shared/sun4.dat @@ -0,0 +1,16 @@ +mainvar == 1 +overriddenvar == 2 +shlibvar1 == 3 +shlib_mainvar () == 1 +shlib_overriddenvar () == 2 +shlib_shlibvar1 () == 3 +shlib_shlibvar2 () == 4 +shlib_shlibcall () == 5 +shlib_shlibcall2 () == 8 +shlib_maincall () == 6 +main_called () == 6 +shlib_checkfunptr1 (shlib_shlibvar1) == 0 +shlib_checkfunptr2 (main_called) == 1 +shlib_getfunptr1 () != shlib_shlibvar1 +shlib_getfunptr2 () == main_called +shlib_check () == 1 diff --git a/ld/testsuite/ld-shared/xcoff.dat b/ld/testsuite/ld-shared/xcoff.dat new file mode 100644 index 0000000..a409d96 --- /dev/null +++ b/ld/testsuite/ld-shared/xcoff.dat @@ -0,0 +1,10 @@ +mainvar == 1 +overriddenvar == 2 +shlibvar1 == 3 +shlib_shlibvar1 () == 3 +shlib_shlibvar2 () == 4 +shlib_shlibcall () == 5 +main_called () == 6 +shlib_checkfunptr1 (shlib_shlibvar1) == 1 +shlib_getfunptr1 () == shlib_shlibvar1 +shlib_check () == 1 diff --git a/ld/testsuite/ld-srec/sr1.c b/ld/testsuite/ld-srec/sr1.c new file mode 100644 index 0000000..d7de977 --- /dev/null +++ b/ld/testsuite/ld-srec/sr1.c @@ -0,0 +1,25 @@ +/* This file is compiled and linked into the S-record format. */ + +extern int e1; +extern int e2; +int i; +int j = 1; +static int k; +static int l = 1; +static char ab[] = "This is a string constant"; + +extern int fn1 (); +extern int fn2 (); + +int +main () +{ + fn1 (ab); + fn2 ("static string constant"); + return e1 + e2 + i + j + k + l; +} + +void +__main () +{ +} diff --git a/ld/testsuite/ld-srec/sr2.c b/ld/testsuite/ld-srec/sr2.c new file mode 100644 index 0000000..5736cfa --- /dev/null +++ b/ld/testsuite/ld-srec/sr2.c @@ -0,0 +1,18 @@ +/* This file is compiled and linked into the S-record format. */ + +int e1; +int e2 = 1; + +int +fn1 (s) + char *s; +{ + return s[e1]; +} + +int +fn2 (s) + char *s; +{ + return s[e2]; +} diff --git a/ld/testsuite/ld-srec/sr3.cc b/ld/testsuite/ld-srec/sr3.cc new file mode 100644 index 0000000..8717c26 --- /dev/null +++ b/ld/testsuite/ld-srec/sr3.cc @@ -0,0 +1,113 @@ +// This file is compiled and linked into the S-record format. + +#define FOO_MSG_LEN 80 + +class Foo { + static int foos; + int i; + static const int len = FOO_MSG_LEN; + char message[len]; +public: + static void init_foo (); + static int nb_foos() { return foos; } + Foo(); + Foo( char* message); + Foo(const Foo&); + Foo & operator= (const Foo&); + ~Foo (); +}; + +static Foo static_foo( "static_foo"); + +int +main () +{ + Foo automatic_foo( "automatic_foo"); + return 0; +} + +void +terminate(void) +{ + /* This recursive call prevents a compiler warning that the noreturn + function terminate actually does return. */ + terminate (); +} + +extern "C" { +void +__main () +{ +} + +void +__builtin_delete () +{ +} + +void +__builtin_new () +{ +} + +void +__throw () +{ +} + +void +__terminate () +{ +} + +void *__eh_pc; + +void *** +__get_dynamic_handler_chain () +{ + return 0; +} + +void * +__get_eh_context () +{ + return 0; +} + +} + +int Foo::foos = 0; + +void Foo::init_foo () +{ + foos = 80; +} + +Foo::Foo () +{ + i = ++foos; +} + +Foo::Foo (char* msg) +{ + i = ++foos; +} + +Foo::Foo (const Foo& foo) +{ + i = ++foos; + for (int k = 0; k < FOO_MSG_LEN; k++) + message[k] = foo.message[k]; +} + +Foo& Foo::operator= (const Foo& foo) +{ + for (int k = 0; k < FOO_MSG_LEN; k++) + message[k] = foo.message[k]; + return *this; +} + +Foo::~Foo () +{ + foos--; +} diff --git a/ld/testsuite/ld-srec/srec.exp b/ld/testsuite/ld-srec/srec.exp new file mode 100644 index 0000000..63a70ab --- /dev/null +++ b/ld/testsuite/ld-srec/srec.exp @@ -0,0 +1,374 @@ +# Test linking directly to S-records. +# By Ian Lance Taylor, Cygnus Support. +# Public domain. + +# Get the offset from an S-record line to the start of the data. + +proc srec_off { l } { + if [string match "S1*" $l] { + return 8 + } else { if [string match "S2*" $l] { + return 10 + } else { if [string match "S3*" $l] { + return 12 + } else { + return -1 + } } } +} + +# See if an S-record line contains only zero data. + +proc srec_zero { l } { + if [string match "S\[0789\]*" $l] { + return 1 + } + + # Strip the address and checksum. + if [string match "S\[123\]*" $l] { + set l [string range $l [srec_off $l] [expr [string length $l] - 3]] + } else { + return 0 + } + + # The rest must be zero. + return [string match "" [string trim $l "0"]] +} + +# Get the address of an S-record line. + +proc srec_addr { l } { + if [string match "S\[123\]*" $l] { + set addr [string range $l 4 [expr [srec_off $l] - 1]] + } else { + return -1 + } + + return "0x$addr" +} + +# Get the number of data bytes in an S-record line. + +proc srec_len { l } { + if ![string match "S\[123\]*" $l] { + return 0 + } + + return [expr "0x[string range $l 2 3]" - ([srec_off $l] - 4) / 2 - 1] +} + +# Extract bytes from an S-record line. + +proc srec_extract { l start len } { + set off [srec_off $l] + set rlen [srec_len $l] + set stop [expr $start + $len] + if { $stop > $rlen } { + set stop [expr $rlen] + } + set start [expr $start * 2 + $off] + set stop [expr $stop * 2 + $off - 1] + return [string range $l $start $stop] +} + +# See if a range of bytes in an S-record line is all zeroes. + +proc srec_zero_range { l start len } { + return [string match "" [string trim [srec_extract $l $start $len] "0"]] +} + +# Trim an S-record line such that the specified number of bytes remain +# at the end. + +proc srec_trim { l leave } { + set off [srec_off $l] + set addr [srec_addr $l] + set len [srec_len $l] + + if { $leave >= $len } { + return $l + } + + set s1 [string range $l 0 1] + set s2 [format "%02x" [expr ($off - 4) / 2 + $leave + 1]] + set s3 [format "%0[expr $off - 4]x" [expr $addr + $len - $leave]] + set s4 [string range $l [expr [string length $l] - ($leave * 2) - 2] end] + set s "${s1}${s2}${s3}${s4}" + + verbose "srec_trim { '$l' $leave } returning '$s'" 2 + + return $s +} + +# Report failure when comparing S-record lines + +proc srec_compare_fail { which l1 l2 } { + send_log "comparison failure $which:\n$l1\n$l2\n" + verbose "comparison failure $which:\n$l1\n$l2" +} + +# Compare S-record files. We don't want to fuss about things like +# extra zeroes. Note that BFD always sorts S-records by address. + +proc srec_compare { f1 f2 } { + set e1 [gets $f1 l1] + set e2 [gets $f2 l2] + + while { $e1 != -1 } { + set l1 [string trimright $l1 "\r\n"] + set l2 [string trimright $l2 "\r\n"] + if { $e2 == -1 } { + # If l1 contains data, it must be zero. + if ![srec_zero $l1] { + send_log "data after EOF: $l1\n" + verbose "data after EOF: $l1" + return 0 + } + } else { if { [string compare $l1 $l2] == 0 } { + set e1 [gets $f1 l1] + set e2 [gets $f2 l2] + } else { if { [srec_zero $l1] } { + set e1 [gets $f1 l1] + } else { if { [srec_zero $l2] } { + set e2 [gets $f2 l2] + } else { + # The strings are not the same, and neither is all zeroes. + set a1 [srec_addr $l1] + set n1 [srec_len $l1] + set a2 [srec_addr $l2] + set n2 [srec_len $l2] + + if { $a1 < $a2 && ![srec_zero_range $l1 0 [expr $a2 - $a1]] } { + verbose "$a1 $a2 [srec_extract $l1 0 [expr $a2 - $a1]]" 2 + srec_compare_fail 1 $l1 $l2 + return 0 + } + if { $a2 < $a1 && ![srec_zero_range $l2 0 [expr $a1 - $a2]] } { + srec_compare_fail 2 $l1 $l2 + return 0 + } + + # Here we know that any initial data in both lines is + # zero. Now make sure that any overlapping data matches. + if { $a1 < $a2 } { + set os1 [expr $a2 - $a1] + set os2 0 + } else { + set os1 0 + set os2 [expr $a1 - $a2] + } + if { $a1 + $n1 < $a2 + $n2 } { + set ol [expr $n1 - $os1] + } else { + set ol [expr $n2 - $os2] + } + + set x1 [srec_extract $l1 $os1 $ol] + set x2 [srec_extract $l2 $os2 $ol] + if { [string compare $x1 $x2] != 0 } { + verbose "$os1 $ol $x1" 2 + verbose "$os2 $ol $x2" 2 + srec_compare_fail 3 $l1 $l2 + return 0 + } + + # These strings match. Trim the data from the larger + # string, read a new copy of the smaller string, and + # continue. + if { $a1 + $n1 < $a2 + $n2 } { + set l2 [srec_trim $l2 [expr ($a2 + $n2) - ($a1 + $n1)]] + set e1 [gets $f1 l1] + } else { if { $a1 + $n1 > $a2 + $n2 } { + set l1 [srec_trim $l1 [expr ($a1 + $n1) - ($a2 + $n2)]] + set e2 [gets $f2 l2] + } else { + set e1 [gets $f1 l1] + set e2 [gets $f2 l2] + } } + } } } } + } + + # We've reached the end of the first file. The remainder of the + # second file must contain only zeroes. + while { $e2 != -1 } { + set l2 [string trimright $l2 "\r\n"] + if ![srec_zero $l2] { + send_log "data after EOF: $l2\n" + verbose "data after EOF: $l2" + return 0 + } + set e2 [gets $f2 l2] + } + + return 1 +} + +# Link twice, objcopy, and compare + +proc run_srec_test { test objs } { + global ld + global objcopy + global sizeof_headers + global host_triplet + + set flags "" + + # If the linker script uses SIZEOF_HEADERS, use a -Ttext argument + # to force both the normal link and the S-record link to be put in + # the same place. We don't always use -Ttext because it interacts + # poorly with a.out. + + if { $sizeof_headers } { + set flags "$flags -Ttext 0x1000" + } + + # The a29k compiled code calls V_SPILL and V_FILL. Since we don't + # need to run this code, but we don't have definitions for those + # functions, we just define them out. + if [istarget a29k*-*-*] { + set flags "$flags --defsym V_SPILL=0 --defsym V_FILL=0" + } + + # ARM targets call __gccmain + if [istarget arm-*-*] { + set flags "$flags --defsym ___gccmain=0" + } + + if [istarget strongarm-*-*] { + set flags "$flags --defsym __gccmain=0" + } + + # Thumb targets call __gccmain + if [istarget thumb-*-*] { + set flags "$flags --defsym ___gccmain=0" + } + + # PowerPC EABI code calls __eabi. + if [istarget powerpc*-*-eabi*] { + set flags "$flags --defsym __eabi=0" + } + + # mn10200 code calls __truncsipsi2_d0_d2. + if {[istarget mn10200*-*-*]} then { + set flags "$flags --defsym __truncsipsi2_d0_d2=0" + } + + # V850 targets need libgcc.a + if [istarget v850*-*-elf] { + set objs "$objs -L ../gcc -lgcc" + } + + if { ![ld_simple_link $ld tmpdir/sr1 "$flags $objs"] \ + || ![ld_simple_link $ld tmpdir/sr2.sr "$flags -oformat srec $objs"] } { + setup_xfail "hppa*-*-*elf*" + fail $test + return + } + + send_log "$objcopy -O srec tmpdir/sr1 tmpdir/sr1.sr\n" + verbose "$objcopy -O srec tmpdir/sr1 tmpdir/sr1.sr" + catch "exec $objcopy -O srec tmpdir/sr1 tmpdir/sr1.sr" exec_output + set exec_output [prune_warnings $exec_output] + if ![string match "" $exec_output] { + send_log "$exec_output\n" + verbose "$exec_output" + unresolved $test + return + } + + set f1 [open tmpdir/sr1.sr r] + set f2 [open tmpdir/sr2.sr r] + if [srec_compare $f1 $f2] { + pass $test + } else { + fail $test + } + close $f1 + close $f2 +} + +set test1 "S-records" +set test2 "S-records with constructors" + +# See whether the default linker script uses SIZEOF_HEADERS. +catch "exec $ld --verbose" exec_output +set sizeof_headers [string match "*SIZEOF_HEADERS*" $exec_output] + +# First test linking a C program. We don't require any libraries. We +# link it normally, and objcopy to the S-record format, and then link +# directly to the S-record format, and require that the two files +# contain the same data. + +if { [which $CC] == 0 } { + untested $test1 + untested $test2 + return +} + +if { ![ld_compile $CC $srcdir/$subdir/sr1.c tmpdir/sr1.o] \ + || ![ld_compile $CC $srcdir/$subdir/sr2.c tmpdir/sr2.o] } { + unresolved $test1 + unresolved $test2 + return +} + +# The i386-aout target is confused: the linker does not put the +# sections where objdump finds them. I don't know which is wrong. +setup_xfail "i*86-*-aout*" + +# These tests fail on the native MIPS ELF targets because the GP value +# in the .reginfo section is not updated when the S-record version is +# written out. The mips-elf target itself does not use a .reginfo section. +setup_xfail "mips*-*-irix5*" "mips*-*-irix6*" + +# The S-record linker doesn't do the magic TOC handling that XCOFF +# linkers do. +setup_xfail "*-*-aix*" "*-*-xcoff*" + +# The S-record linker doesn't build ARM/Thumb stubs. +setup_xfail "arm-*-coff" +setup_xfail "strongarm-*-*" +setup_xfail "arm-*-pe*" +# setup_xfail "arm-*elf*" +setup_xfail "thumb-*-coff*" +setup_xfail "thumb-*-pe*" +setup_xfail "thumb-*-elf*" + +# The S-record linker doesn't build special EABI sections. +setup_xfail "powerpc*-*-eabi*" + +# The S-record linker doesn't include the .{zda} sections. +setup_xfail "v850*-*-elf" + +# The S-record linker doesn't handle Alpha Elf relaxation. +setup_xfail "alpha*-*-elf*" "alpha*-*-linux-gnu*" "alpha*-*-gnu*" +setup_xfail "alpha*-*-netbsd*" + +run_srec_test $test1 "tmpdir/sr1.o tmpdir/sr2.o" + +# Now try linking a C++ program with global constructors and +# destructors. Note that since we are not linking against any +# libraries, this program won't actually work or anything. + +if { [which $CXX] == 0 } { + untested $test2 + return +} + +if ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir/$subdir/sr3.cc tmpdir/sr3.o] { + unresolved $test2 + return +} + +# See above. +setup_xfail "i*86-*-aout*" +setup_xfail "mips*-*-irix5*" "mips*-*-irix6*" +setup_xfail "*-*-aix*" "*-*-xcoff*" +setup_xfail "arm-*-*" +setup_xfail "strongarm-*-*" +setup_xfail "thumb-*-*" +setup_xfail "powerpc*-*-eabi*" +setup_xfail "v850*-*-elf" +setup_xfail "alpha*-*-elf*" "alpha*-*-linux-gnu*" "alpha*-*-gnu*" +setup_xfail "alpha*-*-netbsd*" + +run_srec_test $test2 "tmpdir/sr3.o" diff --git a/ld/testsuite/ld-undefined/undefined.c b/ld/testsuite/ld-undefined/undefined.c new file mode 100644 index 0000000..ef2aec6 --- /dev/null +++ b/ld/testsuite/ld-undefined/undefined.c @@ -0,0 +1,10 @@ +/* This file is used to test the linker's reporting of undefined + symbols. */ + +extern int this_function_is_not_defined (); + +int +function () +{ + return this_function_is_not_defined (); +} diff --git a/ld/testsuite/ld-undefined/undefined.exp b/ld/testsuite/ld-undefined/undefined.exp new file mode 100644 index 0000000..29b3bdd --- /dev/null +++ b/ld/testsuite/ld-undefined/undefined.exp @@ -0,0 +1,126 @@ +# Test that the linker reports undefined symbol errors correctly. +# By Ian Lance Taylor, Cygnus Support +# +# Copyright (C) 1995, 1996, 1997 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set testund "undefined" +set testfn "undefined function" +set testline "undefined line" + +if { [which $CC] == 0 } { + verbose "Could not find C compiler!" 1 + untested $testund + untested $testfn + untested $testline + return +} + +if ![ld_compile "$CC -g" $srcdir/$subdir/undefined.c tmpdir/undefined.o] { + verbose "Unable to compile test file!" 1 + unresolved $testund + unresolved $testfn + unresolved $testline + return +} + +catch "exec rm -f tmpdir/undefined" exec_output + +# Using -e start prevents the SunOS linker from trying to build a +# shared library. +send_log "$ld -e start -o tmpdir/undefined tmpdir/undefined.o\n" +verbose "$ld -e start -o tmpdir/undefined tmpdir/undefined.o" + +catch "exec $ld -e start -o tmpdir/undefined tmpdir/undefined.o" exec_output +send_log "$exec_output\n" +verbose "$exec_output" + +proc checkund { string testname } { + global exec_output + + if [string match "*$string*" $exec_output] { + pass $testname + } else { + fail $testname + } +} + +set mu "undefined reference to `this_function_is_not_defined'" +checkund $mu $testund + +# ARM PE defaults to using stabs debugging, which we can't handle for +# a COFF file. +#setup_xfail "arm*-*-pe*" +#setup_xfail "thumb*-*-pe*" + +# Just doesn't work for PA ELF. No clue why. +setup_xfail "hppa*-*-*elf*" + +set mf "tmpdir/undefined.o: In function `function':" +checkund $mf $testfn + +# COFF SH gets this test wrong--it reports line 10, because although +# the jump is at line 9, the function address, and the reloc, is +# stored at the end of the function. +setup_xfail "sh-*-*" + +# ARM PE defaults to using stabs debugging, which we can't handle for +# a COFF file. +#setup_xfail "arm*-*-pe*" +#setup_xfail "thumb*-*-pe*" + +# Just doesn't work for PA ELF. No clue why. +setup_xfail "hppa*-*-*elf*" + +set ml "undefined.c:9: undefined reference to `this_function_is_not_defined'" +# With targets that use elf/dwarf2, such as the arm-elf and thumb-elf +# toolchains, the code in bfd/elf.c:_bfd_elf_find_nearest_line() is called +# in order to locate the file name/line number where the undefined +# reference occurs. Unfortunately this tries to use the dwarf2 debug +# information held in the .debug_info section. This section contains a series +# of comp_unit structures, each of which has a low/high address range +# representing the span of memory locations covered by that structure. The +# structures also index into other structures held in the .debug_line section +# and together they can translate memory locations back into file/function/line +# number addresses in the source code. Since the information about the memory +# region covered by a comp_unit is only determined at link time, the low/high +# addresses in the .debug_info section and the line addresses in the .debug_line +# section are computed by generating relocs against known symbols in the object +# code. +# +# When the undefined reference is detected, the relocs in the dwarf2 +# debug sections have not yet been resolved, so the low/high addresses and the +# line number address are all set at zero. Thus when _bfd_elf_find_nearest_line() +# calls _bfd_dwarf2_find_nearest_line() no comp_unit can be found which +# actually covers the address where the reference occured, and so +# _bfd_elf_find_nearest_line() fails. +# +# The upshot of all of this, is that the error message reported by the +# linker, instead of having a source file name & line number as in: +# +# undefined.c:9: undefined reference to `this_function_is_not_defined' +# +# has an object file & section address instead: +# +# undefined.0(.text+0xc): undefined reference to `this_function_is_not_defined' +# +# hence the xfails below. + +setup_xfail arm-*-elf +setup_xfail strongarm-*-elf +setup_xfail thumb-*-elf + +checkund $ml $testline diff --git a/ld/testsuite/ld-versados/t1-1.ro b/ld/testsuite/ld-versados/t1-1.ro Binary files differnew file mode 100644 index 0000000..1d70d80 --- /dev/null +++ b/ld/testsuite/ld-versados/t1-1.ro diff --git a/ld/testsuite/ld-versados/t1-2.ro b/ld/testsuite/ld-versados/t1-2.ro Binary files differnew file mode 100644 index 0000000..8d4dc59 --- /dev/null +++ b/ld/testsuite/ld-versados/t1-2.ro diff --git a/ld/testsuite/ld-versados/t1.ld b/ld/testsuite/ld-versados/t1.ld new file mode 100644 index 0000000..1a5c4e3 --- /dev/null +++ b/ld/testsuite/ld-versados/t1.ld @@ -0,0 +1,281 @@ +OUTPUT_FORMAT("srec") +SECTIONS +{ + + +.text 0 : { *("9") *("10") *("11") *("12") *("13") *("14") *("15") + *("7") *("8") *("0") *("1") *("2") *("3") *("4") } +.bss (NOLOAD) : { *("5") *("6") } + +.PAFI =0x00000050 ; +.PCHIO =0x000000D0 ; +.PCLO =0x00000054 ; +.PCVBSV =0x0000000E ; +.PCVTSU =0x00000012 ; +.PCVTSV =0x00000016 ; +.PCVTSVL =0x0000001A ; +.PCVTUS =0x0000001E ; +.PDIS =0x00000022 ; +.PDISL =0x00000026 ; +.PDVJ =0x0000002A ; +.PEIO =0x000000CC ; +.PEOF =0x00000058 ; +.PEOL =0x0000005C ; +.PEQUS =0x0000002E ; +.PEQUV =0x00000032 ; +.PEQUVL =0x00000036 ; +.PEQUW =0x000000DE ; +.PGCM =0x00000064 ; +.PGEQS =0x0000003A ; +.PGEQV =0x0000003E ; +.PGEQVL =0x00000042 ; +.PGET =0x00000060 ; +.PGRTS =0x00000046 ; +.PGRTV =0x0000004A ; +.PGRTVL =0x0000004E ; +.PIACT =0x0000006C ; +.PIFD =0x00000068 ; +.PINDS =0x00000052 ; +.PINDV =0x00000056 ; +.PINDVL =0x0000005A ; +.PINDW =0x000000D6 ; +.PLDCS =0x0000005E ; +.PLDCV =0x00000062 ; +.PLEQS =0x00000066 ; +.PLEQV =0x0000006A ; +.PLEQVL =0x0000006E ; +.PLESS =0x00000072 ; +.PLESV =0x00000076 ; +.PLESVL =0x0000007A ; +.PLODS =0x0000007E ; +.PLODV =0x00000082 ; +.PLODVL =0x00000086 ; +.PMODJ =0x0000008A ; +.PMOV =0x000000E2 ; +.PMPJ =0x0000008E ; +.PNEQS =0x00000092 ; +.PNEQV =0x00000096 ; +.PNEQVL =0x0000009A ; +.PNEQW =0x000000DA ; +.PPAGE =0x000000D4 ; +.PPEE =0x00000070 ; +.PPUT =0x00000074 ; +.PRDB =0x00000078 ; +.PRDC =0x0000007C ; +.PRDH =0x00000080 ; +.PRDI =0x00000084 ; +.PRDJ =0x00000088 ; +.PRDRS =0x000000C8 ; +.PRDS =0x0000008C ; +.PRDV =0x00000090 ; +.PRLN =0x00000094 ; +.PRRAN =0x00000098 ; +.PRST =0x0000009C ; +.PRWT =0x000000A0 ; +.PSCON =0x0000009E ; +.PSCOP =0x000000A2 ; +.PSDEL =0x000000A6 ; +.PSINS =0x000000AA ; +.PSLEN =0x000000AE ; +.PSPOS =0x000000B2 ; +.PSTCV =0x000000B6 ; +.PSTCVL =0x000000BA ; +.PSTOS =0x000000BE ; +.PSTOV =0x000000C2 ; +.PSTOVL =0x000000C6 ; +.PSTRS =0x000000CA ; +.PSTRV =0x000000CE ; +.PSTRVL =0x000000D2 ; +.PWLN =0x000000A4 ; +.PWRAN =0x000000A8 ; +.PWRB =0x000000AC ; +.PWRC =0x000000B0 ; +.PWRH =0x000000B4 ; +.PWRI =0x000000B8 ; +.PWRJ =0x000000BC ; +.PWRS =0x000000C0 ; +.PWRV =0x000000C4 ; + +/* +.PAFI=0x = 0x00; +.PCHIO =0x 0x000000; +.PCLO =0x 64 ; +.PC; +.PCVTSU =0x 0x000000; +.PCVTSV =0x 0x000000; +.PCVTSVL =0x 0x000000; +.PCVTUS =0x 158 ; +.P; +.PDISL =0x 0x000000; +.PDVJ =0x 0x000000; +.PEIO =0x 0x000000; +.PEOF =0x 0x000000; +.PEOL =0x 0x000000; +.PEQUS =0x 0x000000; +.PEQUV =0x 0x000000; +.PEQUVL =0x 0x000000; +.PEQUW =0x 0x000000; +.PGCM =0x 0x000000; +.PGEQS =0x 0x000000; +.PGEQV =0x 0x000000; +.PGEQVL =0x 0x000000; +.PGET =0x 0x000000; +.PGRTS =0x 0x000000; +.PGRTV =0x 0x000000; +.PGRTVL =0x 0x000000; +.PIACT =0x 0x000000; +.PIFD =0x 126 ; +.P; +.PINDV =0x 0x000000; +.PINDVL =0x 0x000000; +.PINDW =0x 0x000000; +.PLDCS =0x 0x000000; +.PLDCV =0x 0x000000; +.PLEQS =0x 0x000000; +.PLEQV =0x 0x000000; +.PLEQVL =0x 0x000000; +.PLESS =0x 0x000000; +.PLESV =0x 0x000000; +.PLESVL =0x 0x000000; +.PLODS =0x 0x000000; +.PLODV =0x 0x000000; +.PLODVL =0x 0x000000; +.PMODJ =0x 0x000000; +.PMOV =0x 0x000000; +.PMPJ =0x 0x000000; +.PNEQS =0x 0x000000; +.PNEQV =0x 0x000000; +.PNEQVL =0x 0x000000; +.PNEQW =0x 0x000000; +.PPAGE =0x 0x000000; +.PPEE =0x 0x000000; +.PPUT =0x 0x000000; +.PRDB =0x 0x000000; +.PRDC =0x 0x000000; +.PRDH =0x 0x000000; +.PRDI =0x 0x000000; +.PRDJ =0x 0x000000; +.PRDRS =0x 0x000000; +.PRDS =0x 0x000000; +.PRDV =0x 0x000000; +.PRLN =0x 0x000000; +.PRRAN =0x 0x000000; +.PRST =0x 0x000000; +.PRWT =0x 0x000000; +.PSCON =0x 0x000000; +.PSCOP =0x 0x000000; +.PSDEL =0x 0x000000; +.PSINS =0x 0x000000; +.PSLEN =0x 0x000000; +.PSPOS =0x 0x000000; +.PSTCV =0x 0x000000; +.PSTCVL =0x 0x000000; +.PSTOS =0x 0x000000; +.PSTOV =0x 0x000000; +.PSTOVL =0x 0x000000; +.PSTRS =0x 0x000000; +.PSTRV =0x 0x000000; +.PSTRVL =0x 0x000000; +.PWLN =0x 0x000000; +.PWRAN =0x 0x000000; +.PWRB =0x 0x000000; +.PWRC =0x 0x000000; +.PWRH =0x 0x000000; +.PWRI =0x 0x000000; +.PWRJ =0x 0x000000; +.PWRS =0x 0x000000; +.PWRV =0x 0x000000; + +*/ +/* +.P=0x = 0; +.PCHIO =0x 0xfeedfa; +.PCLO =0x 0xfeedfa; +.PCVBSV =0x 0xfeedfa; +.PCVTSU =0x 0xfeedfa; +.PCVTSV =0x 0xfeedfa; +.PCVTSVL =0x 0xfeedfa; +.PCVTUS =0x 0xfeedfa; +.PDIS =0x 0xfeedfa; +.PDISL =0x 0xfeedfa; +.PDVJ =0x 0xfeedfa; +.PEIO =0x 0xfeedfa; +.PEOF =0x 0xfeedfa; +.PEOL =0x 0xfeedfa; +.PEQUS =0x 0xfeedfa; +.PEQUV =0x 0xfeedfa; +.PEQUVL =0x 0xfeedfa; +.PEQUW =0x 0xfeedfa; +.PGCM =0x 0xfeedfa; +.PGEQS =0x 0xfeedfa; +.PGEQV =0x 0xfeedfa; +.PGEQVL =0x 0xfeedfa; +.PGET =0x 0xfeedfa; +.PGRTS =0x 0xfeedfa; +.PGRTV =0x 0xfeedfa; +.PGRTVL =0x 0xfeedfa; +.PIACT =0x 0xfeedfa; +.PIFD =0x 0xfeedfa; +.PINDS =0x 0xfeedfa; +.PINDV =0x 0xfeedfa; +.PINDVL =0x 0xfeedfa; +.PINDW =0x 0xfeedfa; +.PLDCS =0x 0xfeedfa; +.PLDCV =0x 0xfeedfa; +.PLEQS =0x 0xfeedfa; +.PLEQV =0x 0xfeedfa; +.PLEQVL =0x 0xfeedfa; +.PLESS =0x 0xfeedfa; +.PLESV =0x 0xfeedfa; +.PLESVL =0x 0xfeedfa; +.PLODS =0x 0xfeedfa; +.PLODV =0x 0xfeedfa; +.PLODVL =0x 0xfeedfa; +.PMODJ =0x 0xfeedfa; +.PMOV =0x 0xfeedfa; +.PMPJ =0x 0xfeedfa; +.PNEQS =0x 0xfeedfa; +.PNEQV =0x 0xfeedfa; +.PNEQVL = 0xfeedface; +.PNEQW = 0xfeedface; +.PPAGE = 0xfeedface; +.PPEE = 0xfeedface; +.PPUT = 0xfeedface; +.PRDB = 0xfeedface; +.PRDC = 0xfeedface; +.PRDH = 0xfeedface; +.PRDI = 0xfeedface; +.PRDJ = 0xfeedface; +.PRDRS = 0xfeedface; +.PRDS = 0xfeedface; +.PRDV = 0xfeedface; +.PRLN = 0xfeedface; +.PRRAN = 0xfeedface; +.PRST = 0xfeedface; +.PRWT = 0xfeedface; +.PSCON = 0xfeedface; +.PSCOP = 0xfeedface; +.PSDEL = 0xfeedface; +.PSINS = 0xfeedface; +.PSLEN = 0xfeedface; +.PSPOS = 0xfeedface; +.PSTCV = 0xfeedface; +.PSTCVL = 0xfeedface; +.PSTOS = 0xfeedface; +.PSTOV = 0xfeedface; +.PSTOVL = 0xfeedface; +.PSTRS = 0xfeedface; +.PSTRV = 0xfeedface; +.PSTRVL = 0xfeedface; +.PWLN = 0xfeedface; +.PWRAN = 0xfeedface; +.PWRB = 0xfeedface; +.PWRC = 0xfeedface; +.PWRH = 0xfeedface; +.PWRI = 0xfeedface; +.PWRJ = 0xfeedface; +.PWRS = 0xfeedface; +.PWRV = 0xfeedface; +*/ + +} diff --git a/ld/testsuite/ld-versados/t1.ook b/ld/testsuite/ld-versados/t1.ook new file mode 100644 index 0000000..3984b94 --- /dev/null +++ b/ld/testsuite/ld-versados/t1.ook @@ -0,0 +1,133 @@ +S00C000074312E6F75742E6F6BC0
+S118000000000A205341464553544F52452041202020202052BE
+S118001531332E33202020202020205231332E32202020202077
+S118002A202000B5E86600B5E9B11DA15B9900001F0000000A50
+S118003F640000003E0000005C00A800BA00F000040001000251
+S1180054000000000000000000000006004031CF52544C4942D0
+S1180069434F4E0004E5EC52544C4942434F4E0004E5ED5254F0
+S118007E4C4942434F4E004031D252544C4942434F4E00000A08
+S11800937D52544C49425354520010A4A852544C494246494CAD
+S11800A8000200B5E86D0000016000B5E873000002540002006A
+S11800BDB5E937534146455052494E5420000006000200080079
+S11800D20000034200B5E86E494E4954534146455354000002C9
+S11800E71800000E00000009020030000000004E56FFD8BA8FDB
+S11800FC63062E4E6100001641FA003243EEFFD8702612D85149
+S1180111C8FFFC4E5E4E752B57FFF22F3C0000000A6000000259
+S11801263B6F0002FFF62F2D00382F2D00344E4C4E4A434F50E7
+S118013B5952494748542054656C65666F6E204142204C204D6B
+S1180150204572696373736F6E2C2031393933004E56FFFCBAB5
+S11801658F63042E4E61AC202E000C06800000000C4E7656807C
+S118017A4E760280FFFFFFFC4AD56604610000B02D40FFFC200B
+S118018F6C003A2208242C003694814E7604820000000C4E76D2
+S11801A44AD566046100008EB0826E0C0CAE00000001000C6CEB
+S11801B900000C207C0000000061000060206C003A200866046C
+S11801CE610000762208D2AEFFFC68046100005C2081216E0043
+S11801E3100004216E000C0008220806810000000C68046100C2
+S11801F800402D4100142950003A206C003A24086604610000BC
+S118020D3A429042A8000442A800084E5E225F285F508F4EE922
+S118022200022B5FFFF24E5ED1DF285F2F082B48FFF2D0D04EDA
+S1180237D02B57FFF22F3C0000000E6000FEE22B57FFF22F3CD4
+S118024C000000106000FED44E56FFFCBA8F63062E4E6100FE2B
+S1180261B82D6C0032FFFC600000122B5FFFF24FEEFFFC42AEF1
+S1180276FFFC600000824AAEFFFC6700007A206EFFFC200866A7
+S118028B00000461B622280004B2AE001067000062220802810B
+S11802A0000000034A8166402208226C003A2409B2826E3426B6
+S11802B510280806840000000C68046100FF76B6846D2026101B
+S11802CA280896844E7604830000000C4E764AD566046100FFCD
+S11802DF5AB6A800086C0000046182206EFFFC20086604610077
+S11802F4FF522D50FFFC60804AAEFFFC6700002C206EFFFC2019
+S11803090866046100FF38226E000C22A80008220806810000B2
+S118031E000C68046100FF142D4100146000000C206E000C4210
+S11803339042AE00144E5E205F285F508F4ED04FEDFF00707F44
+S1180348204F425851C8FFFC486DFF081F3C00043F3C00019F49
+S118035DFC0000000C224F45FA04FE22DA22DA22DA266C00281F
+S11803722F0C286C002C4EAB0068486DFFB8486DFFB42F0C20E7
+S11803876C0000286C00044E909FFC000000522F2DFFC62F0C32
+S118039C206C0008286C000C4E907052266C00204EAB001E416A
+S11803B1FA04BE266C00204EAB007E266C00204EAB009E41EDD7
+S11803C6FFBA266C00204EAB007E266C00204EAB009E1F3C0098
+S11803DB283F3C0001266C00204EAB009E9FFC00000052302DD2
+S11803F0FFCA48C02F002F0C206C0008286C000C4E90705226BF
+S11804056C00204EAB001E266C00204EAB009E41FA045E266CC3
+S118041A00204EAB007E266C00204EAB009E41EDFF9E70162672
+S118042F6C00204EAB00CA600000162B5FFFF24FEDFF002B7C92
+S118044400000001FFB4600003E4486DFF089FFC0000005220DB
+S11804594F43EDFF9E3019725092406F024241D04130C06F0A23
+S118046E5340E24030D951C8FFFC9FFC00000052224F45FA0303
+S1180483F632DA266C00282F0C286C002C4EAB0050FFAA486D02
+S1180498FF08266C00282F0C286C002C4EAB00A0FF9642ADFF73
+S11804AD002B6C0032FF04487A03C43F3CFFFF486DFF08266C1A
+S11804C200282F0C286C002C4EAB00C0FF70486DFF08266C0088
+S11804D7282F0C286C002C4EAB00A4FF5C600000782B5FFFF29E
+S11804EC4FEDFF00487A03BA3F3CFFFF486DFF08266C00282F1F
+S11805010C286C002C4EAB00C0FF349FFC00000052206DFF04AC
+S118051620082F002F0C206C0010286C00144E902F0F3F3CFF60
+S118052BFF486DFF08266C00282F0C286C002C4EAB00C0FF008F
+S1180540DFFC00000052486DFF08266C00282F0C286C002C4EB6
+S1180555AB00A4FEE6600001F0206DFF042008660261804A902E
+S118056A6700016A22100281000000034A81664A2210242C00F1
+S118057F3604820000000C68046100FCAEB2826E3422102408F0
+S118059406820000000C68046100FC9AB2826D202210240892A6
+S11805A9824E7604810000000C4E764AD566046100FC7EB2A8E0
+S11805BE00086C0000066100FF22206DFF04200866046100FFA6
+S11805D31622280008D2ADFF0068046100FC582B41FF009FFC02
+S11805E80000005224082F022F0C206C0010286C00144E902FBF
+S11805FD0F3F3C000C486DFF08266C00282F0C286C002C4EABE5
+S118061200C0FE2ADFFC00000052206DFF04200866046100FE39
+S1180627C22F2800043F3C000C486DFF08266C00282F0C286CD1
+S118063C002C4EAB00BCFDFC206DFF04200866046100FE9A2F81
+S11806512800083F3C000C486DFF08266C00282F0C286C002C68
+S11806664EAB00BCFDD49FFC00000052206DFF04200866046185
+S118067B00FE6C22102F012F0C206C0010286C00144E902F0FFF
+S11806903F3C000C486DFF08266C00282F0C286C002C4EAB0060
+S11806A5C0FD98DFFC00000052486DFF08266C00282F0C286C75
+S11806BA002C4EAB00A4FD7E206DFF04200866046100FE1C2B1B
+S11806CF50FF046000FE8A206C003AB1EDFF046700006C487ADB
+S11806E401E83F3CFFFF486DFF08266C00282F0C286C002C4EDC
+S11806F9AB00C0FD429FFC00000052206DFF0420082F002F0C2F
+S118070E206C0010286C00144E902F0F3F3CFFFF486DFF082617
+S11807236C00282F0C286C002C4EAB00C0FD0EDFFC000000523D
+S1180738486DFF08266C00282F0C286C002C4EAB00A4FCF44862
+S118074D7A01983F3CFFFF486DFF08266C00282F0C286C002C96
+S11807624EAB00C0FCD8486DFF08266C00282F0C286C002C4E32
+S1180777AB00A4FCC4487A016A3F3CFFFF486DFF08266C00283E
+S118078C2F0C286C002C4EAB00C0FCA8486DFF08266C00282F57
+S11807A10C286C002C4EAB00A4FC94206DFF0420080680000008
+S11807B600184E76222C003692804E760281FFFFFFFC4AD566F3
+S11807CB046100FA6A2F013F3C000C486DFF08266C00282F0CE4
+S11807E0286C002C4EAB00BCFC562F2DFF003F3C000C486DFFA3
+S11807F508266C00282F0C286C002C4EAB00BCFC3A486DFF0887
+S118080A266C00282F0C286C002C4EAB00A4FC26486DFF081F86
+S118081F3C0001266C00282F0C286C002C4EAB0054486DFFB815
+S1180834486DFFB42F0C206C0018286C001C4E90486DFF0842D8
+S118084927266C00282F0C286C002C4EAB005442A72F2D0038F0
+S118085E2F2D00344E4A000A4631202020202020202000023A9C
+S11808733A0002293A0000003020202020204164647265737337
+S1180888202020204964656E746974792020202020202020533A
+S118089D697A6520202020202020204E657874001D496E7661B0
+S11808B26C6964207365676D656E74207374617274696E672035
+S11808C761743A202000185365676D656E74206C69737420637F
+S11808DC6F727275707465643A2000000018202020417661693B
+S11808F16C61626C652020202020202020557365644FEDFFF230
+S11809069FFC0000000A6100015641EC003020DF20DF30DF20F1
+S118091B2C003256804E760280FFFFFFFC4AD566046100F90A63
+S1180930294000322940003A6000003E2B5FFFF24FEDFFF2200A
+S11809452C003256804E760280FFFFFFFC4AD566046100F8E064
+S118095A2940003A206C003A220866046100F8DE429042A80094
+S118096F0442A800086000009E4A2C00306700001A206C003A8E
+S11809842008660261B2429042A8000442A800086000007E2007
+S11809996C003A20086602619A4A906700006E221002810000B0
+S11809AE00034A81664A2210242C003604820000000C6804619B
+S11809C300F874B2826E342210240806820000000C680461001A
+S11809D8F860B2826D202210240892824E7604810000000C4ED8
+S11809ED764AD566046100F844B2A800086C0000066100FF3CE5
+S1180A02206C003A200866046100FF302950003A608442A72F44
+S1180A172D00382F2D00344E4A4E560000518F42A71F3C000E63
+S1180A2C4267487A0012426742272F3C00B5E86E4E49000E50B7
+S1180A418F4E5E205F285F4EE80002207C0000000060042B5F99
+S1180A56FFF24E5ED1DF285F2F08D0D04ED043FA0004D3FC00AE
+S1180A6B02704E2F49000A43FA0004D3FC000000402F49000662
+S1180A8041FA0004D1FCFFFFF57A202800566600002222099201
+S1180A95882141005642812448D25AB5C96DFA4441D368005AAE
+S1110AAA1F7C000100044E75422F00044E759F
+S9030000FC
diff --git a/ld/testsuite/ld-versados/t2-1.ro b/ld/testsuite/ld-versados/t2-1.ro Binary files differnew file mode 100644 index 0000000..633a7cc --- /dev/null +++ b/ld/testsuite/ld-versados/t2-1.ro diff --git a/ld/testsuite/ld-versados/t2-2.ro b/ld/testsuite/ld-versados/t2-2.ro Binary files differnew file mode 100644 index 0000000..704a79d --- /dev/null +++ b/ld/testsuite/ld-versados/t2-2.ro diff --git a/ld/testsuite/ld-versados/t2-3.ro b/ld/testsuite/ld-versados/t2-3.ro Binary files differnew file mode 100644 index 0000000..d959342 --- /dev/null +++ b/ld/testsuite/ld-versados/t2-3.ro diff --git a/ld/testsuite/ld-versados/t2.ld b/ld/testsuite/ld-versados/t2.ld new file mode 100644 index 0000000..5e1e413 --- /dev/null +++ b/ld/testsuite/ld-versados/t2.ld @@ -0,0 +1,281 @@ +OUTPUT_FORMAT("srec") +SECTIONS +{ + + +.text 0 : { *("9") *("10") *("11") *("12") *("13") *("14") *("15") + *("7") *("8") *("0") *("1") *("2") *("3") *("4") } +.bss : { *("5") *("6") } + +.PAFI =0x00000050 ; +.PCHIO =0x000000D0 ; +.PCLO =0x00000054 ; +.PCVBSV =0x0000000E ; +.PCVTSU =0x00000012 ; +.PCVTSV =0x00000016 ; +.PCVTSVL =0x0000001A ; +.PCVTUS =0x0000001E ; +.PDIS =0x00000022 ; +.PDISL =0x00000026 ; +.PDVJ =0x0000002A ; +.PEIO =0x000000CC ; +.PEOF =0x00000058 ; +.PEOL =0x0000005C ; +.PEQUS =0x0000002E ; +.PEQUV =0x00000032 ; +.PEQUVL =0x00000036 ; +.PEQUW =0x000000DE ; +.PGCM =0x00000064 ; +.PGEQS =0x0000003A ; +.PGEQV =0x0000003E ; +.PGEQVL =0x00000042 ; +.PGET =0x00000060 ; +.PGRTS =0x00000046 ; +.PGRTV =0x0000004A ; +.PGRTVL =0x0000004E ; +.PIACT =0x0000006C ; +.PIFD =0x00000068 ; +.PINDS =0x00000052 ; +.PINDV =0x00000056 ; +.PINDVL =0x0000005A ; +.PINDW =0x000000D6 ; +.PLDCS =0x0000005E ; +.PLDCV =0x00000062 ; +.PLEQS =0x00000066 ; +.PLEQV =0x0000006A ; +.PLEQVL =0x0000006E ; +.PLESS =0x00000072 ; +.PLESV =0x00000076 ; +.PLESVL =0x0000007A ; +.PLODS =0x0000007E ; +.PLODV =0x00000082 ; +.PLODVL =0x00000086 ; +.PMODJ =0x0000008A ; +.PMOV =0x000000E2 ; +.PMPJ =0x0000008E ; +.PNEQS =0x00000092 ; +.PNEQV =0x00000096 ; +.PNEQVL =0x0000009A ; +.PNEQW =0x000000DA ; +.PPAGE =0x000000D4 ; +.PPEE =0x00000070 ; +.PPUT =0x00000074 ; +.PRDB =0x00000078 ; +.PRDC =0x0000007C ; +.PRDH =0x00000080 ; +.PRDI =0x00000084 ; +.PRDJ =0x00000088 ; +.PRDRS =0x000000C8 ; +.PRDS =0x0000008C ; +.PRDV =0x00000090 ; +.PRLN =0x00000094 ; +.PRRAN =0x00000098 ; +.PRST =0x0000009C ; +.PRWT =0x000000A0 ; +.PSCON =0x0000009E ; +.PSCOP =0x000000A2 ; +.PSDEL =0x000000A6 ; +.PSINS =0x000000AA ; +.PSLEN =0x000000AE ; +.PSPOS =0x000000B2 ; +.PSTCV =0x000000B6 ; +.PSTCVL =0x000000BA ; +.PSTOS =0x000000BE ; +.PSTOV =0x000000C2 ; +.PSTOVL =0x000000C6 ; +.PSTRS =0x000000CA ; +.PSTRV =0x000000CE ; +.PSTRVL =0x000000D2 ; +.PWLN =0x000000A4 ; +.PWRAN =0x000000A8 ; +.PWRB =0x000000AC ; +.PWRC =0x000000B0 ; +.PWRH =0x000000B4 ; +.PWRI =0x000000B8 ; +.PWRJ =0x000000BC ; +.PWRS =0x000000C0 ; +.PWRV =0x000000C4 ; + +/* +.PAFI=0x = 0x00; +.PCHIO =0x 0x000000; +.PCLO =0x 64 ; +.PC; +.PCVTSU =0x 0x000000; +.PCVTSV =0x 0x000000; +.PCVTSVL =0x 0x000000; +.PCVTUS =0x 158 ; +.P; +.PDISL =0x 0x000000; +.PDVJ =0x 0x000000; +.PEIO =0x 0x000000; +.PEOF =0x 0x000000; +.PEOL =0x 0x000000; +.PEQUS =0x 0x000000; +.PEQUV =0x 0x000000; +.PEQUVL =0x 0x000000; +.PEQUW =0x 0x000000; +.PGCM =0x 0x000000; +.PGEQS =0x 0x000000; +.PGEQV =0x 0x000000; +.PGEQVL =0x 0x000000; +.PGET =0x 0x000000; +.PGRTS =0x 0x000000; +.PGRTV =0x 0x000000; +.PGRTVL =0x 0x000000; +.PIACT =0x 0x000000; +.PIFD =0x 126 ; +.P; +.PINDV =0x 0x000000; +.PINDVL =0x 0x000000; +.PINDW =0x 0x000000; +.PLDCS =0x 0x000000; +.PLDCV =0x 0x000000; +.PLEQS =0x 0x000000; +.PLEQV =0x 0x000000; +.PLEQVL =0x 0x000000; +.PLESS =0x 0x000000; +.PLESV =0x 0x000000; +.PLESVL =0x 0x000000; +.PLODS =0x 0x000000; +.PLODV =0x 0x000000; +.PLODVL =0x 0x000000; +.PMODJ =0x 0x000000; +.PMOV =0x 0x000000; +.PMPJ =0x 0x000000; +.PNEQS =0x 0x000000; +.PNEQV =0x 0x000000; +.PNEQVL =0x 0x000000; +.PNEQW =0x 0x000000; +.PPAGE =0x 0x000000; +.PPEE =0x 0x000000; +.PPUT =0x 0x000000; +.PRDB =0x 0x000000; +.PRDC =0x 0x000000; +.PRDH =0x 0x000000; +.PRDI =0x 0x000000; +.PRDJ =0x 0x000000; +.PRDRS =0x 0x000000; +.PRDS =0x 0x000000; +.PRDV =0x 0x000000; +.PRLN =0x 0x000000; +.PRRAN =0x 0x000000; +.PRST =0x 0x000000; +.PRWT =0x 0x000000; +.PSCON =0x 0x000000; +.PSCOP =0x 0x000000; +.PSDEL =0x 0x000000; +.PSINS =0x 0x000000; +.PSLEN =0x 0x000000; +.PSPOS =0x 0x000000; +.PSTCV =0x 0x000000; +.PSTCVL =0x 0x000000; +.PSTOS =0x 0x000000; +.PSTOV =0x 0x000000; +.PSTOVL =0x 0x000000; +.PSTRS =0x 0x000000; +.PSTRV =0x 0x000000; +.PSTRVL =0x 0x000000; +.PWLN =0x 0x000000; +.PWRAN =0x 0x000000; +.PWRB =0x 0x000000; +.PWRC =0x 0x000000; +.PWRH =0x 0x000000; +.PWRI =0x 0x000000; +.PWRJ =0x 0x000000; +.PWRS =0x 0x000000; +.PWRV =0x 0x000000; + +*/ +/* +.P=0x = 0; +.PCHIO =0x 0xfeedfa; +.PCLO =0x 0xfeedfa; +.PCVBSV =0x 0xfeedfa; +.PCVTSU =0x 0xfeedfa; +.PCVTSV =0x 0xfeedfa; +.PCVTSVL =0x 0xfeedfa; +.PCVTUS =0x 0xfeedfa; +.PDIS =0x 0xfeedfa; +.PDISL =0x 0xfeedfa; +.PDVJ =0x 0xfeedfa; +.PEIO =0x 0xfeedfa; +.PEOF =0x 0xfeedfa; +.PEOL =0x 0xfeedfa; +.PEQUS =0x 0xfeedfa; +.PEQUV =0x 0xfeedfa; +.PEQUVL =0x 0xfeedfa; +.PEQUW =0x 0xfeedfa; +.PGCM =0x 0xfeedfa; +.PGEQS =0x 0xfeedfa; +.PGEQV =0x 0xfeedfa; +.PGEQVL =0x 0xfeedfa; +.PGET =0x 0xfeedfa; +.PGRTS =0x 0xfeedfa; +.PGRTV =0x 0xfeedfa; +.PGRTVL =0x 0xfeedfa; +.PIACT =0x 0xfeedfa; +.PIFD =0x 0xfeedfa; +.PINDS =0x 0xfeedfa; +.PINDV =0x 0xfeedfa; +.PINDVL =0x 0xfeedfa; +.PINDW =0x 0xfeedfa; +.PLDCS =0x 0xfeedfa; +.PLDCV =0x 0xfeedfa; +.PLEQS =0x 0xfeedfa; +.PLEQV =0x 0xfeedfa; +.PLEQVL =0x 0xfeedfa; +.PLESS =0x 0xfeedfa; +.PLESV =0x 0xfeedfa; +.PLESVL =0x 0xfeedfa; +.PLODS =0x 0xfeedfa; +.PLODV =0x 0xfeedfa; +.PLODVL =0x 0xfeedfa; +.PMODJ =0x 0xfeedfa; +.PMOV =0x 0xfeedfa; +.PMPJ =0x 0xfeedfa; +.PNEQS =0x 0xfeedfa; +.PNEQV =0x 0xfeedfa; +.PNEQVL = 0xfeedface; +.PNEQW = 0xfeedface; +.PPAGE = 0xfeedface; +.PPEE = 0xfeedface; +.PPUT = 0xfeedface; +.PRDB = 0xfeedface; +.PRDC = 0xfeedface; +.PRDH = 0xfeedface; +.PRDI = 0xfeedface; +.PRDJ = 0xfeedface; +.PRDRS = 0xfeedface; +.PRDS = 0xfeedface; +.PRDV = 0xfeedface; +.PRLN = 0xfeedface; +.PRRAN = 0xfeedface; +.PRST = 0xfeedface; +.PRWT = 0xfeedface; +.PSCON = 0xfeedface; +.PSCOP = 0xfeedface; +.PSDEL = 0xfeedface; +.PSINS = 0xfeedface; +.PSLEN = 0xfeedface; +.PSPOS = 0xfeedface; +.PSTCV = 0xfeedface; +.PSTCVL = 0xfeedface; +.PSTOS = 0xfeedface; +.PSTOV = 0xfeedface; +.PSTOVL = 0xfeedface; +.PSTRS = 0xfeedface; +.PSTRV = 0xfeedface; +.PSTRVL = 0xfeedface; +.PWLN = 0xfeedface; +.PWRAN = 0xfeedface; +.PWRB = 0xfeedface; +.PWRC = 0xfeedface; +.PWRH = 0xfeedface; +.PWRI = 0xfeedface; +.PWRJ = 0xfeedface; +.PWRS = 0xfeedface; +.PWRV = 0xfeedface; +*/ + +} diff --git a/ld/testsuite/ld-versados/t2.ook b/ld/testsuite/ld-versados/t2.ook new file mode 100644 index 0000000..03f24a5 --- /dev/null +++ b/ld/testsuite/ld-versados/t2.ook @@ -0,0 +1,99 @@ +S0120000696E6974746573745F6570632E7372CF
+S118000000000000494E495454455354202050413035202052AB
+S118001531332E33202020202020205231332E32202020202077
+S118002A202000934B5B00B5E6C11B089DD600005400000005F9
+S118003F5A00000048005C00A60000010A0126000400010002CB
+S1180054009000000000000000000002004020200000494F5F8A
+S11800695245534552564152544C4942434F4E0040484501003B
+S118007E505F414C4C202020202052544C4942434F4E010000E3
+S118009300009C01000000000000085345504152415445000852
+S11800A80008004031CF52544C4942434F4E0004E5EC52544CD3
+S11800BD4942434F4E00B5E86D5341464553544F5200004F28D7
+S11800D253595354454D494D00B5E8735341464553544F520023
+S11800E74031D252544C4942434F4E00000A7D52544C49425309
+S11800FC54520010A4A852544C494246494C000100B5E6C049EC
+S11801114E495454455354202000000616020008000000023210
+S11801260048000000004E56FFF0BA8F63062E4E610000BC4159
+S118013BFA00F443EEFFF032D82D7C00000001FFFC206E000858
+S118015020086604610000BA222EFFFC53814A816C046100002E
+S11801659E2248D3E9FFFC41F01800B3C863EE4A1066000006E7
+S118017A6000006241EEFFF0266C00384EAB007E206E00082095
+S118018F0866046100007C222EFFFC53814A816C0461000060ED
+S11801A42248D3E9FFFC41F01800B3C863EE1F103F3C0001263B
+S11801B96C00384EAB009E41EEFFF0700C266C00384EAB00CACB
+S11801CE52AEFFFC0CAE0000000AFFFC6F00FF7041EEFFF0431F
+S11801E3EE000C22D822D822D84E5E205F588F4ED02B57FFF278
+S11801F82F3C0000000A6000001E2B57FFF22F3C0000000F60AE
+S118020D0000102B57FFF22F3C00000010600000023B6F0002CC
+S1180222FFF62F2D00382F2D00344E4C4E4A00004FEDFEEA2034
+S11802373C0000008A204F425851C8FFFC486DFEEA1F3C0004CF
+S118024C3F3C00019FFC0000000C224F45FA02D422DA22DA22D6
+S1180261DA266C00402F0C286C00444EAB0068486DFFB8486D43
+S1180276FFB42F0C206C0008286C000C4E909FFC000000522F53
+S118028B2DFFC62F0C206C0010286C00144E907052266C00387F
+S11802A04EAB001E41FA0294266C00384EAB007E266C00384E04
+S11802B5AB009E41EDFFBA266C00384EAB007E266C00384EABFC
+S11802CA009E1F3C00283F3C0001266C00384EAB009E9FFC0082
+S11802DF000052302DFFCA48C02F002F0C206C0010286C0014D8
+S11802F44E907052266C00384EAB001E266C00384EAB009E41CE
+S1180309FA0234266C00384EAB007E266C00384EAB009E41EDDB
+S118031EFF807016266C00384EAB00CA9FFC0000000E61000228
+S11803332841EDFF9E20DF20DF20DF30DF4A2DFF9E6700003AFD
+S1180348598F2F2DFFA02F2DFFA82F0C206C0018286C001C4ED9
+S118035D9001B82B5FFF9A2F2DFF9A2F2DFFA42F2DFFA82F0CE9
+S1180372206C0020286C00244E9060000034598F2F2DFFA04871
+S11803876DFFA82F0C206C0028286C002C4E902B5FFF962F2D41
+S118039CFFA42F2DFF962F2DFFA82F0C206C0020286C00244EC4
+S11803B190486DFEEA9FFC00000052204F43EDFF8030197250F0
+S11803C692406F024241D04130C06F0A5340E24030D951C8FF08
+S11803DBFC9FFC00000052224F45FA015C32DA266C00402F0CFA
+S11803F0286C00444EAB0050012C486DFEEA266C00402F0C28D4
+S11804056C00444EAB00A00118487A01343F3CFFFF486DFEEA6F
+S118041A266C00402F0C286C00444EAB00C000FC486DFEEA266C
+S118042F6C00402F0C286C00444EAB00A400E842ADFFB02B7C2B
+S118044400000001FFAC598F2F2DFFAC6100017E2B5FFFB02BC0
+S118045940FFB02F2DFFAC3F3C000A486DFEEA266C00402F0C65
+S118046E286C00444EAB00BC00AE9FFC0000000C2F2DFFB06127
+S118048300FCA82F0F3F3C000A486DFEEA266C00402F0C286CBB
+S118049800444EAB00C00086DFFC0000000C486DFEEA266C00B2
+S11804AD402F0C286C00444EAB00A4006C52ADFFAC0CAD000077
+S11804C2000AFFAC6F82486DFEEA1F3C0001266C00402F0C284D
+S11804D76C00444EAB0054486DFFB8486DFFB42F0C206C003044
+S11804EC286C00344E90486DFEEA4227266C00402F0C286C00AA
+S1180501444EAB005442A72F2D00382F2D00344E4A2B57FFF238
+S11805162F3C0000000C6000FD002B57FFF22F3C000000646056
+S118052B00FCF2000A4631202020202020202000023A3A0002D0
+S1180540293A000000142020202020204361736520202020521D
+S11805556573756C7441FA0004D1FCFFFFFAA02028003C43FAFB
+S118056A0004D3FC000001D645FA0004D5FC0000025E260A58D2
+S118057F8AD0885580222800566600002E2408265AD5B0B8008F
+S1180594B5C06DF6220992882141005642812648D25BB7C96D2E
+S11805A9FA4441D368005A123C00016000000442411F4100048B
+S11805BE2F68003400062F49000A96892F43000E4E754E56FFCC
+S11805D3F0202E000847FA0004D7FC000001A6220B41FA00049E
+S11805E8D1FC000001B62D58FFF02D58FFF42D58FFF82D50FF92
+S11805FDFC53807408B4806500012C41FA0004D1FC0000000EBA
+S1180612D080303008004EFB00020012002200320042004800DC
+S118062758006C00A000DC41FA0004D1FC0000011820106000C5
+S118063C010247FA0004D7FC0000010C200B600000F241FA00C5
+S118065104D1FC000001102010600000E22001600000DC47FA9E
+S11806660004D7FC00000120200B600000CC43FA0004D3FC001C
+S118067B0000FA41E9000C2010600000B8242EFFF447FA000464
+S1180690D7FC000000FEB48B6600001247FA0004D7FC000001B0
+S11806A514200B6000009447FA0004D7FC0000010A200B60005B
+S11806BA008441FA0004D1FC0000008A205047FA0004D7FC0085
+S11806CF000082B1CB6600001247FA0004D7FC000000E0200B79
+S11806E46000005847FA0004D7FC000000D2200B600000484147
+S11806F9FA0004D1FC0000004E43FA0004D3FC0000003EB3D0FE
+S118070E6600001247FA0004D7FC000000AE200B6000001E47A4
+S1180723FA0004D7FC000000A6200B6000000E47FA0004D7FC95
+S118073800000098200B4E5E4E740004000053756E65000000D8
+S118074D0007464F74746F00000000000A0000000C50656C6CFD
+S118076265000000075E5374696E61004B6172696E00000000C0
+S11807770500000768000000030000076E5075747465004B61BF
+S118078C6C6C65005374696E613100004B6172696E31000000C1
+S11807A1000033000007900000001F0000079878797A7A0000D2
+S11807B64F6C6C650000370038005065746572005376756C6C19
+S11807CB6F00003900536C75740000000000000000074C000072
+S11507E007640000077800000780000007A4000007AC34
+S9030000FC
diff --git a/ld/testsuite/ld-versados/versados.exp b/ld/testsuite/ld-versados/versados.exp new file mode 100644 index 0000000..2d2c066 --- /dev/null +++ b/ld/testsuite/ld-versados/versados.exp @@ -0,0 +1,99 @@ +# Expect script for ld-versados tests +# Copyright (C) 1995, 1996, 1997 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Written by Steve Chamberlain (sac@cygnus.com) +# + +# Make sure that ld can read versados images and +# generate binaries which are identical to the customer's +# old method. + +# This test can only be run if ld generates native executables. + +# This test can only be run on 68k coff targets +# Square bracket expressions seem to confuse istarget. +if { ![istarget m68k-*-coff*] } then { + return +} + +set testname "LD VERSADOS" + + +proc inspect { whichone } { + global objdump + global exec_output + global srcdir + global subdir + global testname + + send_log "$objdump -s tmpdir/$whichone.out >tmpdir/$whichone.dump\n" + catch "exec $objdump -s tmpdir/$whichone.out | grep -v srec >tmpdir/$whichone.dump" exec_output + + if ![string match "" $exec_output] { + send_log "$exec_output\n" + verbose $exec_output + unresolved $testname + return 0 + } + + send_log "$objdump -s $srcdir/$subdir/$whichone.ook >tmpdir/$whichone.dok\n" + catch "exec $objdump -s $srcdir/$subdir/$whichone.ook | grep -v srec >tmpdir/$whichone.dok" exec_output + + if ![string match "" $exec_output] { + send_log "$exec_output\n" + verbose $exec_output + unresolved $testname + return 0 + } + + # compare it with the correct output + catch "exec diff tmpdir/$whichone.dump tmpdir/$whichone.dok" exec_output + if ![string match "" $exec_output] { + send_log "$exec_output\n" + verbose $exec_output + fail $testname + return 0 + } + + return 1 +} + +if ![ld_simple_link $ld tmpdir/t1.out \ + " -T $srcdir/$subdir/t1.ld $srcdir/$subdir/t1-1.ro $srcdir/$subdir/t1-2.ro"] { + fail $testname + return +} else { + # Get a dump of what we've got, and what we should have + if ![inspect t1] { + return + } +} + + +if ![ld_simple_link $ld tmpdir/t2.out \ + " -T $srcdir/$subdir/t2.ld $srcdir/$subdir/t2-2.ro \ + $srcdir/$subdir/t2-1.ro $srcdir/$subdir/t2-3.ro"] { + fail $testname + return +} else { + # Get a dump of what we've got, and what we should have + if ![inspect t2] { + return + } +} + +pass $testname diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp new file mode 100644 index 0000000..24a4131 --- /dev/null +++ b/ld/testsuite/lib/ld-lib.exp @@ -0,0 +1,327 @@ +# +# default_ld_version +# extract and print the version number of ld +# +proc default_ld_version { ld } { + global host_triplet + + if { [which $ld] == 0 } then { + perror "$ld does not exist" + exit 1 + } + + catch "exec $ld --version" tmp + set tmp [prune_warnings $tmp] + regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number + if [info exists number] then { + clone_output "$ld $number\n" + } +} + +# +# default_ld_relocate +# link an object using relocation +# +proc default_ld_relocate { ld target objects } { + global HOSTING_EMU + global host_triplet + + if { [which $ld] == 0 } then { + perror "$ld does not exist" + return 0 + } + + verbose -log "$ld $HOSTING_EMU -o $target -r $objects" + + catch "exec $ld $HOSTING_EMU -o $target -r $objects" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + return 1 + } else { + verbose -log "$exec_output" + return 0 + } +} + + +# +# default_ld_link +# link a program using ld +# +proc default_ld_link { ld target objects } { + global HOSTING_EMU + global HOSTING_CRT0 + global HOSTING_LIBS + global host_triplet + + set objs "$HOSTING_CRT0 $objects" + set libs "$HOSTING_LIBS" + + if { [which $ld] == 0 } then { + perror "$ld does not exist" + return 0 + } + + verbose -log "$ld $HOSTING_EMU -o $target $objs $libs" + + catch "exec $ld $HOSTING_EMU -o $target $objs $libs" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + return 1 + } else { + verbose -log "$exec_output" + return 0 + } +} + +# +# default_ld_simple_link +# link a program using ld, without including any libraries +# +proc default_ld_simple_link { ld target objects } { + global host_triplet + + if { [which $ld] == 0 } then { + perror "$ld does not exist" + return 0 + } + + verbose -log "$ld -o $target $objects" + + catch "exec $ld -o $target $objects" exec_output + set exec_output [prune_warnings $exec_output] + + # We don't care if we get a warning about a non-existent start + # symbol, since the default linker script might use ENTRY. + regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output + + if [string match "" $exec_output] then { + return 1 + } else { + verbose -log "$exec_output" + return 0 + } +} + +# +# default_ld_compile +# compile an object using cc +# +proc default_ld_compile { cc source object } { + global CFLAGS + global srcdir + global subdir + global host_triplet + global gcc_gas_flag + + set cc_prog $cc + if {[llength $cc_prog] > 1} then { + set cc_prog [lindex $cc_prog 0] + } + if {[which $cc_prog] == 0} then { + perror "$cc_prog does not exist" + return 0 + } + + catch "exec rm -f $object" exec_output + + set flags "-I$srcdir/$subdir $CFLAGS" + + # If we are compiling with gcc, we want to add gcc_gas_flag to + # flags. Rather than determine this in some complex way, we guess + # based on the name of the compiler. + if {[string match "*gcc*" $cc] || [string match "*++*" $cc]} then { + set flags "$gcc_gas_flag $flags" + } + + verbose -log "$cc $flags -c $source -o $object" + + catch "exec $cc $flags -c $source -o $object" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + if {![file exists $object]} then { + regexp ".*/(\[^/\]*)$" $source all dobj + regsub "\\.c" $dobj ".o" realobj + verbose "looking for $realobj" + if {[file exists $realobj]} then { + verbose -log "mv $realobj $object" + catch "exec mv $realobj $object" exec_output + set exec_output [prune_warnings $exec_output] + if {![string match "" $exec_output]} then { + verbose -log "$exec_output" + perror "could not move $realobj to $object" + return 0 + } + } else { + perror "$object not found after compilation" + return 0 + } + } + return 1 + } else { + verbose -log "$exec_output" + perror "$source: compilation failed" + return 0 + } +} + +# +# default_ld_assemble +# assemble a file +# +proc default_ld_assemble { as source object } { + global ASFLAGS + global host_triplet + + if {[which $as] == 0} then { + perror "$as does not exist" + return 0 + } + + if ![info exists ASFLAGS] { set ASFLAGS "" } + + verbose -log "$as $ASFLAGS -o $object $source" + + catch "exec $as $ASFLAGS -o $object $source" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + return 1 + } else { + verbose -log "$exec_output" + perror "$source: assembly failed" + return 0 + } +} + +# +# default_ld_nm +# run nm on a file, putting the result in the array nm_output +# +proc default_ld_nm { nm object } { + global NMFLAGS + global nm_output + global host_triplet + + if {[which $nm] == 0} then { + perror "$nm does not exist" + return 0 + } + + if ![info exists NMFLAGS] { set NMFLAGS "" } + + verbose -log "$nm $NMFLAGS $object >tmpdir/nm.out" + + catch "exec $nm $NMFLAGS $object >tmpdir/nm.out" exec_output + set exec_output [prune_warnings $exec_output] + if [string match "" $exec_output] then { + set file [open tmpdir/nm.out r] + while { [gets $file line] != -1 } { + verbose "$line" 2 + if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] (.+)$" $line whole value name] { + set name [string trimleft $name "_"] + verbose "Setting nm_output($name) to 0x$value" 2 + set nm_output($name) 0x$value + } + } + close $file + return 1 + } else { + verbose -log "$exec_output" + perror "$object: nm failed" + return 0 + } +} + +# +# simple_diff +# compares two files line-by-line +# returns differences if exist +# returns null if file(s) cannot be opened +# +proc simple_diff { file_1 file_2 } { + global target + + set eof -1 + set differences 0 + + if [file exists $file_1] then { + set file_a [open $file_1 r] + } else { + warning "$file_1 doesn't exist" + return + } + + if [file exists $file_2] then { + set file_b [open $file_2 r] + } else { + fail "$file_2 doesn't exist" + return + } + + verbose "# Diff'ing: $file_1 $file_2\n" 2 + + while { [gets $file_a line] != $eof } { + if [regexp "^#.*$" $line] then { + continue + } else { + lappend list_a $line + } + } + close $file_a + + while { [gets $file_b line] != $eof } { + if [regexp "^#.*$" $line] then { + continue + } else { + lappend list_b $line + } + } + close $file_b + + for { set i 0 } { $i < [llength $list_a] } { incr i } { + set line_a [lindex $list_a $i] + set line_b [lindex $list_b $i] + + verbose "\t$file_1: $i: $line_a\n" 3 + verbose "\t$file_2: $i: $line_b\n" 3 + if [string compare $line_a $line_b] then { + verbose -log "\t$file_1: $i: $line_a\n" + verbose -log "\t$file_2: $i: $line_b\n" + + fail "Test: $target" + return + } + } + + if { [llength $list_a] != [llength $list_b] } { + fail "Test: $target" + return + } + + if $differences<1 then { + pass "Test: $target" + } +} + +# This definition is taken from an unreleased version of DejaGnu. Once +# that version gets released, and has been out in the world for a few +# months at least, it may be safe to delete this copy. +if ![string length [info proc prune_warnings]] { + # + # prune_warnings -- delete various system verbosities from TEXT + # + # An example is: + # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9 + # + # Sites with particular verbose os's may wish to override this in site.exp. + # + proc prune_warnings { text } { + # This is from sun4's. Do it for all machines for now. + # The "\\1" is to try to preserve a "\n" but only if necessary. + regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text + + # It might be tempting to get carried away and delete blank lines, etc. + # Just delete *exactly* what we're ask to, and that's it. + return $text + } +} |