diff --git a/ld/Makefile.in b/ld/Makefile.in index 2181f43940..d38501492d 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -41,9 +41,10 @@ man9dir = $(mandir)/man9 infodir = $(prefix)/info includedir = $(prefix)/include docdir = $(datadir)/doc +# 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/ld +scriptdir = $(tooldir)/lib gcclibdir = $(libdir)/gcc/$(target_alias) @@ -112,6 +113,9 @@ LINTFLAGS = $(INCLUDES) $(EXTRA_DEF) .SUFFIXES: .y $(SUFFIXES) .cc +# Suppress smart makes who think they know how to automake Yacc files +.y.c: + .cc.o: $(C++) -c -I$(srcdir) $(CFLAGS) $< @@ -162,23 +166,17 @@ BFDSOURCES=../../bfd/common/*.c SOURCES= $(LDSOURCES) $(BFDSOURCES) LINTSOURCES= $(LDCSOURCES) $(BFDSOURCES) $(GENERATED_SOURCES) -STAGESTUFF = emulations/* $(GENERATED_SOURCES) $(GENERATED_HEADERS) $(OFILES) +STAGESTUFF = ldscripts/* $(GENERATED_SOURCES) $(GENERATED_HEADERS) $(OFILES) all: $(LD_PROG) info: ld.info -# This somewhat odd makefile construction prevents a parallel gnu make -# from spinning off two bison processes concurrently. This is -# important because yacc uses static file names and multiple instances -# will collide. -ldgram.h ldgram.c: ldgram-files -ldgram-files: ldgram.y +ldgram.h ldgram.c: ldgram.y $(BISON) $(BISONFLAGS) -d $(srcdir)/ldgram.y mv -f y.tab.c ldgram.c mv -f y.tab.h ldgram.h - DEF_EMUL = ` if [ -z "$(EMUL)" ] ; then \ echo "you must set a default emulation" 1>&2 ; \ exit 1 ; \ @@ -187,7 +185,7 @@ DEF_EMUL = ` if [ -z "$(EMUL)" ] ; then \ fi` ldmain.o: ldmain.c - $(CC) -c $(INCLUDES) $(HDEFINES) $(TDEFINES) $(CDEFINES) $(DEF_EMUL) -DSCRIPTDIR='"$(scriptdir)"' $(CFLAGS) $< + $(CC) -c $(INCLUDES) $(HDEFINES) $(TDEFINES) $(CDEFINES) $(DEF_EMUL) $(CFLAGS) $< ldemul-list.h: (echo "/* This file is automatically generated. DO NOT EDIT! */";\ @@ -314,18 +312,18 @@ installcheck: # Rules for testing by relinking ld itself. ld-partial.o: ld.new - ./ld.new -Lemulations $(HOSTING_EMU) -o ld-partial.o -r $(OFILES) + ./ld.new -L. $(HOSTING_EMU) -o ld-partial.o -r $(OFILES) ld1: ld-partial.o - ./ld.new -Lemulations $(HOSTING_EMU) -o ld1 $(HOSTING_CRT0) ld-partial.o $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + ./ld.new -L. $(HOSTING_EMU) -o ld1 $(HOSTING_CRT0) ld-partial.o $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) ld1-full: ld.new - ./ld.new -Lemulations $(HOSTING_EMU) -o ld1-full $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + ./ld.new -L. $(HOSTING_EMU) -o ld1-full $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) ld2: ld1 - ./ld1 -Lemulations $(HOSTING_EMU) -o ld2 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + ./ld1 -L. $(HOSTING_EMU) -o ld2 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) ld3: ld2 - ./ld2 -Lemulations $(HOSTING_EMU) -o ld3 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) + ./ld2 -L. $(HOSTING_EMU) -o ld3 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS) bootstrap: ld3 cmp ld2 ld3 @@ -333,7 +331,7 @@ bootstrap: ld3 # A test program for C++ constructors and destructors. cdtest: cdtest-main.o cdtest-func.o cdtest-foo.o ld.new - ./ld.new -Lemulations $(HOSTING_EMU) -o cdtest $(HOSTING_CRT0) \ + ./ld.new -L. $(HOSTING_EMU) -o cdtest $(HOSTING_CRT0) \ cdtest-main.o cdtest-func.o cdtest-foo.o $(HOSTING_LIBS) check-cdtest: cdtest $(srcdir)/cdtest.exp @@ -441,7 +439,6 @@ ld-index.me: ld.me ldlex.o: ldlex.c ldgram.h ldgram.o: ldgram.c -ldgram.c:ldgram.y ldexp.o: ldexp.c ldgram.h ldctor.o: ldctor.c ldgram.h ldlang.o: ldlang.c ldgram.h @@ -501,7 +498,7 @@ mostlyclean: clean: mostlyclean -rm -f $(LD_PROG) distclean: clean - -rm -f Makefile config.status TAGS sysdep.h + -rm -fr Makefile config.status TAGS sysdep.h ldscripts realclean: distclean -rm -f $(LDDISTSTUFF) @@ -527,8 +524,8 @@ objdump:objdump.c install: $(INSTALL_XFORM) ld.new $(bindir)/ld $(INSTALL_XFORM1) $(srcdir)/ld.1 $(man1dir)/ld.1 - for f in emulations/*; do \ - $(INSTALL_DATA) $$f $(scriptdir)/`basename $$f` ; \ + for f in ldscripts/*; do \ + $(INSTALL_DATA) $$f $(scriptdir)/$$f ; \ done -n=`t='$(program_transform_name)'; echo ld | sed -e "" $$t`; \ rm -f $(tooldir)/bin/ld; \ diff --git a/ld/configure.in b/ld/configure.in index f9e0a7d2e3..d3a45b48ff 100644 --- a/ld/configure.in +++ b/ld/configure.in @@ -79,10 +79,8 @@ case "${target}" in ;; h8500-*-hms) my_target=coff-h8500 ;; -# start-sanitize-sh sh-*-*) my_target=coff-sh ;; -# end-sanitize-sh m68k-sony-*) my_target=news ;; m68k-hp-bsd*) my_target=hp300bsd @@ -125,4 +123,4 @@ if [ ! -r ${srcdir}/${target_makefile_frag} ]; then exit 1 fi -mkdir emulations 2>/dev/null +mkdir ldscripts 2>/dev/null diff --git a/ld/genscripts.sh b/ld/genscripts.sh index 7882a418bf..99434eefc0 100755 --- a/ld/genscripts.sh +++ b/ld/genscripts.sh @@ -1,61 +1,94 @@ +# genscripts.sh # This shell script does the work of generating the ld-emulation-target # specific information from a specific file of paramaters. -# Usage: genscripts.sh srcdir host_alias target_alias emulation_name +# Usage: genscripts.sh srcdir tooldirlib libdir host_alias target_alias emulation_name +# Sample usage: +# genscripts.sh /offsite/djm/work/devo/ld /usr/local/sparc-sun-sunos4.1.3/lib /usr/local/lib sparc-sun-sunos4.1.3 sparc-sun-sunos4.1.3 sun3.sh +# produces sun3.x sun3.xbn sun3.xn sun3.xr sun3.xu em_sun3.c srcdir=$1 -host_alias=$2 -target_alias=$3 +tooldirlib=$2 +libdir=$3 +host_alias=$4 +target_alias=$5 -# Include the emulation-specic parameters: -. ${srcdir}/$4 +# Include the emulation-specific parameters: +. ${srcdir}/emulparams/$6 -# Set the library search path (for libraries named by -lfoo). -# If LIB_PATH is defined (and non-empty), it is used. -# (The format is the usual list of colon-separated directories.) -# (To force a logically empty LIB_PATH, do LIBPATH=":".) -# Otherwise, the default is /lib:/usr/lib:/usr/local/lib, -# unless cross-compiling, in which case the default remains empty. +# 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" -a "x${host_alias}" = "x${target_alias}" ] ; then - LIB_PATH=/lib:/usr/lib:/usr/local/lib +if [ "x${LIB_PATH}" = "x" ] ; then + if [ "x${host_alias}" = "x${target_alias}" ] ; then + # Native. + LIB_PATH=/lib:/usr/lib:${tooldirlib}:${libdir} + if [ "${libdir}" != /usr/local/lib ] ; then + LIB_PATH=${LIB_PATH}:/usr/local/lib + fi + else + # Cross. + LIB_PATH=${tooldirlib} + fi fi LIB_SEARCH_DIRS=`echo ${LIB_PATH} | tr ':' ' ' | sed -e 's/\([^ ][^ ]*\)/SEARCH_DIR(\1);/g'` -# This script generates 5 script files from the master script template -# in ${srcdir}/${SCRIPT_NAME}.sh. Which one of the 5 script files -# is actually used depends on command line flags given to ld. -# The actual script is filtered through the mkscript program -# to convert it to a form suitable for including in a C program -# as a C string literal. +# Generate 5 script files from a master script template in +# ${srcdir}/scripttempl/${SCRIPT_NAME}.sh. Which one of the 5 script files +# is actually used depends on command line options given to ld. # # 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 .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). -THIS_TEXT_START_ADDR=${TEXT_START_ADDR} SEGMENT_SIZE=${SEGMENT_SIZE-${PAGE_SIZE}} -DATA_ALIGNMENT="ALIGN(${SEGMENT_SIZE})" -FILTER_SCRIPT="" -(. ${srcdir}/${SCRIPT_NAME}.sc-sh) | sed -e '/^ *$/d' | ./mkscript \ - >${EMULATION_NAME}.xr +# Determine DATA_ALIGNMENT for the 5 variants, using +# values specified in the emulparams/.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}/${SCRIPT_NAME}.sc-sh) | sed -e '/^ *$/d' | ./mkscript \ - >${EMULATION_NAME}.xu +(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \ + ldscripts/${EMULATION_NAME}.xu + +LD_FLAG= +DATA_ALIGNMENT=${DATA_ALIGNMENT_} RELOCATING= -(. ${srcdir}/${SCRIPT_NAME}.sc-sh) | sed -e '/^ *$/d' | ./mkscript \ - >${EMULATION_NAME}.x -THIS_TEXT_START_ADDR=${NONPAGED_TEXT_START_ADDR-${TEXT_START_ADDR}} -(. ${srcdir}/${SCRIPT_NAME}.sc-sh) | sed -e '/^ *$/d' | ./mkscript \ - >${EMULATION_NAME}.xn -DATA_ALIGNMENT="." -(. ${srcdir}/${SCRIPT_NAME}.sc-sh) | sed -e '/^ *$/d' | ./mkscript \ - >${EMULATION_NAME}.xN +(. ${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 #sed -e s/""/${EMULATION_NAME}/g -e s/""/${ARCH}/g \ # -e s/""/${EMULATION_NAME}/g -e s/""/${OUTPUT_FORMAT}/g \ -# <${srcdir}/${TEMPLATE_NAME-ldtemplate} >ld__${EMULATION_NAME}.c +# <${srcdir}/${TEMPLATE_NAME-ldtemplate} >em_${EMULATION_NAME}.c -. ${srcdir}/${TEMPLATE_NAME-generic}.em +# Generate em_${EMULATION_NAME}.c. +. ${srcdir}/emultempl/${TEMPLATE_NAME-generic}.em diff --git a/ld/ldlang.c b/ld/ldlang.c index 6b784786ab..0fa415831f 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -2441,10 +2441,10 @@ lang_process () { /* Read the emulation's appropriate default script. */ char *scriptname = ldemul_get_script (); - size_t size = strlen (scriptname) + 3; + size_t size = strlen (scriptname) + 13; char *buf = (char *) ldmalloc(size); - sprintf (buf, "-T%s", scriptname); + sprintf (buf, "-Tldscripts/%s", scriptname); parse_line (buf, 0); free (buf); } @@ -2788,11 +2788,12 @@ lang_statement_append (list, element, field) list->tail = field; } -/* Set the output format type */ +/* Set the output format type. -oformat overrides scripts. */ void -lang_add_output_format (format) +lang_add_output_format (format, from_script) CONST char *format; + int from_script; { - output_target = format; + if (!from_script || output_target == NULL) + output_target = format; } - diff --git a/ld/ldmain.c b/ld/ldmain.c index 137368bfcf..36a6f0d52e 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -60,6 +60,9 @@ int had_y; /* The local symbol prefix */ char lprefix = 'L'; +/* Set by -G argument, for MIPS ECOFF target. */ +int g_switch_value = 8; + /* Count the number of global symbols multiply defined. */ int multiple_def_count; @@ -92,9 +95,6 @@ boolean trace_files; /* 1 => write load map. */ boolean write_map; - -int unix_relocate; - #ifdef GNU960 /* Indicates whether output file will be b.out (default) or coff */ enum target_flavour output_flavor = BFD_BOUT_FORMAT; @@ -115,48 +115,72 @@ unsigned int total_symbols_seen; */ unsigned int total_files_seen; -/* IMPORTS */ args_type command_line; + ld_config_type config; + void main (argc, argv) char **argv; int argc; { char *emulation; + int i; program_name = argv[0]; - output_filename = "a.out"; bfd_init (); -#ifdef GNU960 - { - int i; + /* We need to find any explicitly given emulation before we initialize the + state that's needed by the lex&yacc argument parser (parse_args). */ - check_v960 (argc, argv); - emulation = "gld960"; - for (i = 1; i < argc; i++) - { - if (!strcmp (argv[i], "-Fcoff")) - { - emulation = "lnk960"; - output_flavor = BFD_COFF_FORMAT; - break; - } - } - } +#ifdef GNU960 + check_v960 (argc, argv); + emulation = "gld960"; + for (i = 1; i < argc; i++) + { + if (!strcmp (argv[i], "-Fcoff")) + { + emulation = "lnk960"; + output_flavor = BFD_COFF_FORMAT; + break; + } + } #else emulation = (char *) getenv (EMULATION_ENVIRON); #endif + 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 + { + /* -mEMUL */ + emulation = &argv[i][2]; + } + } + } + /* Initialize the data about options. */ trace_files = false; write_map = false; config.relocateable_output = false; - unix_relocate = 0; command_line.force_common_definition = false; init_bfd_error_vector (); @@ -331,9 +355,9 @@ definitions seen, undefined global symbols and pending commons. extern boolean relaxing; void -DEFUN (Q_enter_global_ref, (nlist_p, name), - asymbol ** nlist_p AND /* pointer into symbol table from incoming bfd */ - CONST char *name /* name of symbol in linker table */ ) +Q_enter_global_ref (nlist_p, name) + asymbol ** nlist_p; /* pointer into symbol table from incoming bfd */ + CONST char *name; /* name of symbol in linker table */ { asymbol *sym = *nlist_p; ldsym_type *sp; @@ -932,6 +956,9 @@ subfile_wanted_p (entry) { asymbol **q; + if (entry->symbol_count == 0) + return false; + for (q = entry->asymbols; *q; q++) { asymbol *p = *q;