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)
.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) $<
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 ; \
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! */";\
# 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
# 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
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
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)
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; \
;;
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
exit 1
fi
-mkdir emulations 2>/dev/null
+mkdir ldscripts 2>/dev/null
+# 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/<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}/${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/"<ldtarget>"/${EMULATION_NAME}/g -e s/"<arch>"/${ARCH}/g \
# -e s/"<target>"/${EMULATION_NAME}/g -e s/"<target_name>"/${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
{
/* 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);
}
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;
}
-
/* 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;
/* 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;
*/
unsigned int total_files_seen;
-/* IMPORTS */
args_type command_line;
+
ld_config_type config;
+\f
void
main (argc, argv)
char **argv;
int argc;
{
char *emulation;
+ int i;
program_name = argv[0];
- output_filename = "a.out";
bfd_init ();
+ /* We need to find any explicitly given emulation before we initialize the
+ state that's needed by the lex&yacc argument parser (parse_args). */
+
#ifdef GNU960
- {
- int i;
-
- 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;
- }
- }
- }
+ 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 ();
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;
{
asymbol **q;
+ if (entry->symbol_count == 0)
+ return false;
+
for (q = entry->asymbols; *q; q++)
{
asymbol *p = *q;