* fnmatch.h, fnmatch.c: New files.
authorIan Lance Taylor <ian@airs.com>
Mon, 29 Jul 1996 21:33:26 +0000 (21:33 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 29 Jul 1996 21:33:26 +0000 (21:33 +0000)
* 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.

ld/.Sanitize
ld/ChangeLog
ld/Makefile.in
ld/NEWS
ld/fnmatch.c [new file with mode: 0644]
ld/fnmatch.h [new file with mode: 0644]
ld/ld.texinfo
ld/ldgram.y
ld/ldlang.c
ld/ldlex.l

index a68cbf9d0cbc0261598fafcafac00aa1ef571af3..bf804aeccd2abbbaabea88f205ed060577538bd6 100644 (file)
@@ -39,6 +39,8 @@ configure.tgt
 dep-in.sed
 emulparams
 emultempl
 dep-in.sed
 emulparams
 emultempl
+fnmatch.c
+fnmatch.h
 genscripts.sh
 h8-doc.texi
 ld.1
 genscripts.sh
 h8-doc.texi
 ld.1
index 8ec49026bb4fd66c652788d70f4984c31b08146b..581227002cb7f88c0316a07d50d5718aabf6dffd 100644 (file)
@@ -1,3 +1,30 @@
+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.
+
 start-sanitize-d10v
        Wed Jul 24 12:16:38 1996  Martin M. Hunt  <hunt@pizza.cygnus.com>
 
 start-sanitize-d10v
        Wed Jul 24 12:16:38 1996  Martin M. Hunt  <hunt@pizza.cygnus.com>
 
index b83befef4ae33ebf6a025e718b808c4fbb9ac6b6..b9cb1f23963b68f5b092eeed10c4086193a8dc6f 100644 (file)
@@ -285,18 +285,18 @@ ALL_EMULATIONS = \
 
 CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
        ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
 
 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
+       mri.c ldcref.c fnmatch.c
 
 HFILES = config.h ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
        ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \
 
 HFILES = config.h ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
        ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \
-       ldwrite.h mri.h
+       ldwrite.h mri.h fnmatch.h
 
 GENERATED_CFILES = ldgram.c ldlex.c
 GENERATED_HFILES = ldgram.h ldemul-list.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 \
 
 GENERATED_CFILES = ldgram.c ldlex.c
 GENERATED_HFILES = ldgram.h ldemul-list.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}
+       ldfile.o ldcref.o fnmatch.o ${EMULATION_OFILES}
 
 LINTSOURCES = $(CFILES) $(GENERATED_CFILES) e*.c
 
 
 LINTSOURCES = $(CFILES) $(GENERATED_CFILES) e*.c
 
@@ -1015,7 +1015,7 @@ ldlang.o: ldlang.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
   $(INCDIR)/libiberty.h $(INCDIR)/bfdlink.h ld.h ldmain.h \
   ldgram.h ldexp.h ldlang.h ldemul.h ldlex.h ldmisc.h \
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
   $(INCDIR)/libiberty.h $(INCDIR)/bfdlink.h ld.h ldmain.h \
   ldgram.h ldexp.h ldlang.h ldemul.h ldlex.h ldmisc.h \
-  ldctor.h ldfile.h
+  ldctor.h ldfile.h fnmatch.h
 ldmain.o: ldmain.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
   $(INCDIR)/libiberty.h $(INCDIR)/progress.h $(INCDIR)/bfdlink.h \
 ldmain.o: ldmain.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
   $(INCDIR)/libiberty.h $(INCDIR)/progress.h $(INCDIR)/bfdlink.h \
@@ -1034,9 +1034,9 @@ ldwrite.o: ldwrite.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   ldlang.h ldwrite.h ldmisc.h ldgram.h ldmain.h
 lexsup.o: lexsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
   ldlang.h ldwrite.h ldmisc.h ldgram.h ldmain.h
 lexsup.o: lexsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.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
+  $(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 $(INCDIR)/obstack.h \
   sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldexp.h \
   ldlang.h ldmisc.h mri.h ldgram.h
 mri.o: mri.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/obstack.h \
   sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldexp.h \
   ldlang.h ldmisc.h mri.h ldgram.h
@@ -1044,6 +1044,7 @@ ldcref.o: ldcref.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/libiberty.h ld.h ldmain.h \
   ldmisc.h
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/libiberty.h ld.h ldmain.h \
   ldmisc.h
+fnmatch.o: fnmatch.c
 ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
   $(INCDIR)/bfdlink.h ld.h ldexp.h ldver.h ldlang.h ldemul.h \
 ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
   $(INCDIR)/bfdlink.h ld.h ldexp.h ldver.h ldlang.h ldemul.h \
diff --git a/ld/NEWS b/ld/NEWS
index 7eb77a61ea09bf42829a3f5a552cf7d00efa7735..50cb3550a7e3875a3ac73c215a8c6e176cba7879 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,25 @@
 -*- text -*-
 
 -*- text -*-
 
+Changes since version 2.7:
+
+* Linker scripts may now contain shell wildcard characters for file and section
+  names.
+
+Changes since version 2.6:
+
+* 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 since version 2.5:
 
 * When an ELF section name is representable as a C identifier (this is not true
 Changes since version 2.5:
 
 * When an ELF section name is representable as a C identifier (this is not true
@@ -20,11 +40,13 @@ glibc.
 * New options -split-by-reloc and -split-by-file.
 
 * The linker now supports linking PIC compiled code on SPARC SunOS.  It can
 * 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.  The native SunOS linker will do this
-when linking code which has an undefined symbol, but the GNU linker requires
-the -shared option.  For convenience when used with gcc -shared, the GNU linker
-will also create a shared library when given the -assert pure-text option,
-although this is not really what -assert pure-text should mean.
+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
 
 * 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
diff --git a/ld/fnmatch.c b/ld/fnmatch.c
new file mode 100644 (file)
index 0000000..11f896f
--- /dev/null
@@ -0,0 +1,214 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#if defined (CONFIG_BROKETS)
+/* We use <config.h> instead of "config.h" so that a compilation
+   using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
+   (which it would do because it found this file in $srcdir).  */
+#include <config.h>
+#else
+#include "config.h"
+#endif
+#endif
+
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <fnmatch.h>
+#include <ctype.h>
+
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
+extern int errno;
+#endif
+
+/* Match STRING against the filename pattern PATTERN, returning zero if
+   it matches, nonzero if not.  */
+int
+fnmatch (pattern, string, flags)
+     const char *pattern;
+     const char *string;
+     int flags;
+{
+  register const char *p = pattern, *n = string;
+  register char c;
+
+/* Note that this evalutes C many times.  */
+#define FOLD(c)        ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
+
+  while ((c = *p++) != '\0')
+    {
+      c = FOLD (c);
+
+      switch (c)
+       {
+       case '?':
+         if (*n == '\0')
+           return FNM_NOMATCH;
+         else if ((flags & FNM_FILE_NAME) && *n == '/')
+           return FNM_NOMATCH;
+         else if ((flags & FNM_PERIOD) && *n == '.' &&
+                  (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+           return FNM_NOMATCH;
+         break;
+
+       case '\\':
+         if (!(flags & FNM_NOESCAPE))
+           {
+             c = *p++;
+             c = FOLD (c);
+           }
+         if (FOLD (*n) != c)
+           return FNM_NOMATCH;
+         break;
+
+       case '*':
+         if ((flags & FNM_PERIOD) && *n == '.' &&
+             (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+           return FNM_NOMATCH;
+
+         for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
+           if (((flags & FNM_FILE_NAME) && *n == '/') ||
+               (c == '?' && *n == '\0'))
+             return FNM_NOMATCH;
+
+         if (c == '\0')
+           return 0;
+
+         {
+           char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+           c1 = FOLD (c1);
+           for (--p; *n != '\0'; ++n)
+             if ((c == '[' || FOLD (*n) == c1) &&
+                 fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+               return 0;
+           return FNM_NOMATCH;
+         }
+
+       case '[':
+         {
+           /* Nonzero if the sense of the character class is inverted.  */
+           register int not;
+
+           if (*n == '\0')
+             return FNM_NOMATCH;
+
+           if ((flags & FNM_PERIOD) && *n == '.' &&
+               (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+             return FNM_NOMATCH;
+
+           not = (*p == '!' || *p == '^');
+           if (not)
+             ++p;
+
+           c = *p++;
+           for (;;)
+             {
+               register char cstart = c, cend = c;
+
+               if (!(flags & FNM_NOESCAPE) && c == '\\')
+                 cstart = cend = *p++;
+
+               cstart = cend = FOLD (cstart);
+
+               if (c == '\0')
+                 /* [ (unterminated) loses.  */
+                 return FNM_NOMATCH;
+
+               c = *p++;
+               c = FOLD (c);
+
+               if ((flags & FNM_FILE_NAME) && c == '/')
+                 /* [/] can never match.  */
+                 return FNM_NOMATCH;
+
+               if (c == '-' && *p != ']')
+                 {
+                   cend = *p++;
+                   if (!(flags & FNM_NOESCAPE) && cend == '\\')
+                     cend = *p++;
+                   if (cend == '\0')
+                     return FNM_NOMATCH;
+                   cend = FOLD (cend);
+
+                   c = *p++;
+                 }
+
+               if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
+                 goto matched;
+
+               if (c == ']')
+                 break;
+             }
+           if (!not)
+             return FNM_NOMATCH;
+           break;
+
+         matched:;
+           /* Skip the rest of the [...] that already matched.  */
+           while (c != ']')
+             {
+               if (c == '\0')
+                 /* [... (unterminated) loses.  */
+                 return FNM_NOMATCH;
+
+               c = *p++;
+               if (!(flags & FNM_NOESCAPE) && c == '\\')
+                 /* XXX 1003.2d11 is unclear if this is right.  */
+                 ++p;
+             }
+           if (not)
+             return FNM_NOMATCH;
+         }
+         break;
+
+       default:
+         if (c != FOLD (*n))
+           return FNM_NOMATCH;
+       }
+
+      ++n;
+    }
+
+  if (*n == '\0')
+    return 0;
+
+  if ((flags & FNM_LEADING_DIR) && *n == '/')
+    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
+    return 0;
+
+  return FNM_NOMATCH;
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__.  */
diff --git a/ld/fnmatch.h b/ld/fnmatch.h
new file mode 100644 (file)
index 0000000..1a653ab
--- /dev/null
@@ -0,0 +1,69 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef        _FNMATCH_H
+
+#define        _FNMATCH_H      1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
+#undef __P
+#define        __P(args)       args
+#else /* Not C++ or ANSI C.  */
+#undef __P
+#define        __P(args)       ()
+/* We can get away without defining `const' here only because in this file
+   it is used only inside the prototype for `fnmatch', which is elided in
+   non-ANSI C where `const' is problematical.  */
+#endif /* C++ or ANSI C.  */
+
+
+/* We #undef these before defining them because some losing systems
+   (HP-UX A.08.07 for example) define these in <unistd.h>.  */
+#undef FNM_PATHNAME
+#undef FNM_NOESCAPE
+#undef FNM_PERIOD
+
+/* Bits set in the FLAGS argument to `fnmatch'.  */
+#define        FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
+#define        FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special chars.  */
+#define        FNM_PERIOD      (1 << 2) /* Leading `.' is matched only explicitly.  */
+
+#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
+#define        FNM_FILE_NAME   FNM_PATHNAME /* Preferred GNU name.  */
+#define        FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match.  */
+#define        FNM_CASEFOLD    (1 << 4) /* Compare without regard to case.  */
+#endif
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN.  */
+#define        FNM_NOMATCH     1
+
+/* Match STRING against the filename pattern PATTERN,
+   returning zero if it matches, FNM_NOMATCH if not.  */
+extern int fnmatch __P ((const char *__pattern, const char *__string,
+                        int __flags));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* fnmatch.h */
index bdb7644c2e3aba5bba1131a731109d6362e96875..73057c4490baccfd90cf4826e7511fcdca08fdb3 100644 (file)
@@ -642,6 +642,19 @@ 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.
 
 within the shared library.  This option is only meaningful on ELF
 platforms which support shared libraries.
 
+@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}
 @cindex symbols, from command line
 @kindex --defsym @var{symbol}=@var{exp}
 @item --defsym @var{symbol}=@var{expression}
@@ -1864,7 +1877,7 @@ beginning of the section.
 The @var{contents} of a section definition may include any of the
 following kinds of statement.  You can include as many of these as you
 like in a single section definition, separated from one another by
 The @var{contents} of a section definition may include any of the
 following kinds of statement.  You can include as many of these as you
 like in a single section definition, separated from one another by
-whitespace. 
+whitespace.
 
 @table @code
 @kindex @var{filename}
 
 @table @code
 @kindex @var{filename}
@@ -1949,8 +1962,23 @@ were in an input-file section named @code{COMMON}, regardless of the
 input file's format.
 @end table
 
 input file's format.
 @end table
 
-For example, the following command script arranges the output file into
-three consecutive sections, named @code{.text}, @code{.data}, and
+In any place where you may use a specific file or section name, you may
+also use a wildcard pattern.  The wildcard handling is similar to that
+used by the Unix shell.  A @samp{*} character matches any number of
+characters.  A @samp{?} character matches any single character.  The
+sequence @samp{[@var{chars}]} will match 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.  A
+@samp{\} character may be used to quote the following character.
+
+When using a wildcard to match a file name, 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.  The wildcard characters
+will match a @samp{/} character in a section name.
+
+In the following example, the command script arranges the output file
+into three consecutive sections, named @code{.text}, @code{.data}, and
 @code{.bss}, taking the input for each from the correspondingly named
 sections of all the input files:
 
 @code{.bss}, taking the input for each from the correspondingly named
 sections of all the input files:
 
@@ -1995,6 +2023,24 @@ SECTIONS @{
 @end group
 @end smallexample        
 
 @end group
 @end smallexample        
 
+This example shows how wildcard patterns might be used to partition
+files.  All @code{.text} sections are placed in @code{.text}, and all
+@code{.bss} sections are placed in @code{.bss}.  For all files beginning
+with an upper case character, the @code{.data} section is placed into
+@code{.DATA}; for all other files, the @code{.data} section is placed
+into @code{.data}.
+
+@smallexample
+@group
+SECTIONS @{
+  .text : @{ *(.text) @}
+  .DATA : @{ [A-Z]*(.data) @}
+  .data : @{ *(.data) @}
+  .bss : @{ *(.bss) @}
+@}
+@end group
+@end smallexample
+
 @node Section Data Expressions
 @subsection Section Data Expressions
 
 @node Section Data Expressions
 @subsection Section Data Expressions
 
index 7e6f1e8e0b1dbda640602f57b6b95995b04b9cec..92ba5bc9f8046a2e66ceb62eea9a79d7a1a3c470 100644 (file)
@@ -1,5 +1,5 @@
 /* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
 /* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
-   Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
    Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
 
 This file is part of GNU ld.
    Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
 
 This file is part of GNU ld.
@@ -43,7 +43,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define YYDEBUG 1
 #endif
 
 #define YYDEBUG 1
 #endif
 
-static int typebits;
+static enum section_type sectype;
 
 lang_memory_region_type *region;
 
 
 lang_memory_region_type *region;
 
@@ -68,14 +68,22 @@ static int error_index;
   char *name;
   int token;
   union etree_union *etree;
   char *name;
   int token;
   union etree_union *etree;
+  struct phdr_info
+    {
+      boolean filehdr;
+      boolean phdrs;
+      union etree_union *at;
+      union etree_union *flags;
+    } phdr;
 }
 
 }
 
-%type <etree> exp  opt_exp_with_type  mustbe_exp opt_at
+%type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
 %type <integer> fill_opt
 %type <name> memspec_opt casesymlist
 %token <integer> INT  
 %token <name> NAME LNAME
 %type  <integer> length
 %type <integer> fill_opt
 %type <name> memspec_opt casesymlist
 %token <integer> INT  
 %token <name> NAME LNAME
 %type  <integer> length
+%type <phdr> phdr_qualifiers
 
 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ 
 %right <token> '?' ':'
 
 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ 
 %right <token> '?' ':'
@@ -94,8 +102,8 @@ static int error_index;
 %right UNARY
 %token END 
 %left <token> '('
 %right UNARY
 %token END 
 %left <token> '('
-%token <token> ALIGN_K BLOCK QUAD LONG SHORT BYTE
-%token SECTIONS
+%token <token> ALIGN_K BLOCK BIND QUAD LONG SHORT BYTE
+%token SECTIONS PHDRS
 %token '{' '}'
 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
 %token SIZEOF_HEADERS
 %token '{' '}'
 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
 %token SIZEOF_HEADERS
@@ -108,7 +116,7 @@ static int error_index;
 %token ORIGIN FILL
 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
 %token ALIGNMOD AT PROVIDE
 %token ORIGIN FILL
 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
 %token ALIGNMOD AT PROVIDE
-%type <token> assign_op 
+%type <token> assign_op atype
 %type <name>  filename
 %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD
 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
 %type <name>  filename
 %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD
 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
@@ -136,12 +144,15 @@ defsym_expr:
 
 /* SYNTAX WITHIN AN MRI SCRIPT FILE */  
 mri_script_file:
 
 /* SYNTAX WITHIN AN MRI SCRIPT FILE */  
 mri_script_file:
-               {       ldlex_mri_script();
-                       PUSH_ERROR("MRI style script");
+               {
+                 ldlex_mri_script ();
+                 PUSH_ERROR ("MRI style script");
                }
             mri_script_lines
                }
             mri_script_lines
-               {       ldlex_popstate(); 
-                       POP_ERROR();
+               {
+                 ldlex_popstate ();
+                 mri_draw_tree ();
+                 POP_ERROR ();
                }
        ;
 
                }
        ;
 
@@ -177,8 +188,12 @@ mri_script_command:
                        { mri_output_section($2, $4);}
        |       ALIGN_K NAME '=' exp
                        { mri_align($2,$4); }
                        { 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); }
+       |       ALIGNMOD NAME ',' exp
+                       { mri_alignmod($2,$4); }
        |       ABSOLUTE mri_abs_name_list
        |       LOAD     mri_load_name_list
        |       NAMEWORD NAME 
        |       ABSOLUTE mri_abs_name_list
        |       LOAD     mri_load_name_list
        |       NAMEWORD NAME 
@@ -196,7 +211,7 @@ mri_script_command:
        |       INCLUDE filename
                { ldfile_open_command_file ($2); } mri_script_lines END
        |       START NAME
        |       INCLUDE filename
                { ldfile_open_command_file ($2); } mri_script_lines END
        |       START NAME
-               { lang_add_entry ($2, 0); }
+               { lang_add_entry ($2, false); }
         |
        ;
 
         |
        ;
 
@@ -253,6 +268,7 @@ ifile_list:
 ifile_p1:
                memory
        |       sections
 ifile_p1:
                memory
        |       sections
+       |       phdrs
        |       startup
        |       high_level_library
        |       low_level_library
        |       startup
        |       high_level_library
        |       low_level_library
@@ -318,15 +334,25 @@ sec_or_group_p1:
 
 statement_anywhere:
                ENTRY '(' NAME ')'
 
 statement_anywhere:
                ENTRY '(' NAME ')'
-               { lang_add_entry ($3, 0); }
+               { lang_add_entry ($3, false); }
        |       assignment end
        ;
 
        |       assignment end
        ;
 
+/* The '*' and '?' cases are there because the lexer returns them as
+   separate tokens rather than as NAME.  */
 file_NAME_list:
                NAME
 file_NAME_list:
                NAME
-                       { lang_add_wild($1, current_file); }
+                       { lang_add_wild ($1, current_file); }
+       |       '*'
+                       { lang_add_wild ("*", current_file); }
+       |       '?'
+                       { lang_add_wild ("?", current_file); }
        |       file_NAME_list opt_comma NAME
        |       file_NAME_list opt_comma NAME
-                       { lang_add_wild($3, current_file); }
+                       { lang_add_wild ($3, current_file); }
+       |       file_NAME_list opt_comma '*'
+                       { lang_add_wild ("*", current_file); }
+       |       file_NAME_list opt_comma '?'
+                       { lang_add_wild ("?", current_file); }
        ;
 
 input_section_spec:
        ;
 
 input_section_spec:
@@ -342,7 +368,14 @@ input_section_spec:
                ']'
        |       NAME
                        {
                ']'
        |       NAME
                        {
-                       current_file =$1;
+                       current_file = $1;
+                       }
+               '(' file_NAME_list ')'
+       |       '?'
+               /* This case is needed because the lexer returns a
+                   single question mark as '?' rather than NAME.  */
+                       {
+                       current_file = "?";
                        }
                '(' file_NAME_list ')'
        |       '*'
                        }
                '(' file_NAME_list ')'
        |       '*'
@@ -365,12 +398,12 @@ statement:
                  lang_add_attribute(lang_constructors_statement_enum); 
                }
        | input_section_spec
                  lang_add_attribute(lang_constructors_statement_enum); 
                }
        | input_section_spec
-        | length '(' exp ')'
+        | length '(' mustbe_exp ')'
                        {
                        lang_add_data((int) $1,$3);
                        }
   
                        {
                        lang_add_data((int) $1,$3);
                        }
   
-       | FILL '(' exp ')'
+       | FILL '(' mustbe_exp ')'
                        {
                          lang_add_fill
                            (exp_get_value_int($3,
                        {
                          lang_add_fill
                            (exp_get_value_int($3,
@@ -623,36 +656,57 @@ opt_at:
 
 section:       NAME            { ldlex_expression(); }
                opt_exp_with_type 
 
 section:       NAME            { ldlex_expression(); }
                opt_exp_with_type 
-               opt_at          { ldlex_popstate(); }
+               opt_at          { ldlex_popstate (); ldlex_script (); }
                '{'
                        {
                '{'
                        {
-                       lang_enter_output_section_statement($1,$3,typebits,0,0,0,$4);
+                         lang_enter_output_section_statement($1, $3,
+                                                             sectype,
+                                                             0, 0, 0, $4);
                        }
                statement_list_opt      
                        }
                statement_list_opt      
-               '}' {ldlex_expression();} memspec_opt fill_opt
+               '}' { ldlex_popstate (); ldlex_expression (); }
+               memspec_opt phdr_opt fill_opt
                {
                  ldlex_popstate();
                {
                  ldlex_popstate();
-                 lang_leave_output_section_statement($12, $11);
+                 lang_leave_output_section_statement($13, $11);
                }
                }
-opt_comma
-
+               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:
        ;
 
 type:
-          NOLOAD  { typebits = SEC_NEVER_LOAD; }
-       |  DSECT   { typebits = 0; }
-       |  COPY    { typebits = 0; }
-       |  INFO    { typebits = 0; }
-       |  OVERLAY { typebits = 0; }
-       | { typebits = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; }
+          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; }
+       ;
 
 opt_exp_with_type:
 
 opt_exp_with_type:
-               exp ':'                 { $$ = $1; typebits =0;}
-       |       exp '(' type ')' ':'    { $$ = $1; }
-       |       ':'                     { $$= (etree_type *)NULL; typebits = 0; }
-       |       '(' type ')' ':'        { $$= (etree_type *)NULL;  }
+               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; }
        ;
 
 memspec_opt:
        ;
 
 memspec_opt:
@@ -660,6 +714,99 @@ memspec_opt:
                { $$ = $2; }
        |       { $$ = "*default*"; }
        ;
                { $$ = $2; }
        |       { $$ = "*default*"; }
        ;
+
+phdr_opt:
+               /* empty */
+       |       phdr_opt ':' NAME
+               {
+                 lang_section_in_phdr ($3);
+               }
+       ;
+
+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;
+               }
+       ;
+
 %%
 void
 yyerror(arg) 
 %%
 void
 yyerror(arg) 
index d3924a0a56d301f67abff5211aa011570ee96c7a..94f58f9a56d9f1d878f441edaff18d02ffc22fed 100644 (file)
@@ -32,6 +32,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307
 #include "ldmisc.h"
 #include "ldctor.h"
 #include "ldfile.h"
 #include "ldmisc.h"
 #include "ldctor.h"
 #include "ldfile.h"
+#include "fnmatch.h"
 
 /* FORWARDS */
 static lang_statement_union_type *new_statement PARAMS ((enum statement_enum,
 
 /* FORWARDS */
 static lang_statement_union_type *new_statement PARAMS ((enum statement_enum,
@@ -64,7 +65,9 @@ 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));
   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 void section_already_linked PARAMS ((bfd *, asection *, PTR));
+static boolean wildcardp PARAMS ((const char *));
 static void wild_section PARAMS ((lang_wild_statement_type *ptr,
                                  const char *section,
                                  lang_input_statement_type *file,
 static void wild_section PARAMS ((lang_wild_statement_type *ptr,
                                  const char *section,
                                  lang_input_statement_type *file,
@@ -72,6 +75,9 @@ static void wild_section PARAMS ((lang_wild_statement_type *ptr,
 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 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,
 static void wild PARAMS ((lang_wild_statement_type *s,
                          const char *section, const char *file,
                          const char *target,
@@ -283,7 +289,6 @@ new_afile (name, file_type, target, add_to_list)
 
   lang_has_input_file = true;
   p->target = target;
 
   lang_has_input_file = true;
   p->target = target;
-  p->complained = false;
   switch (file_type)
     {
     case lang_input_file_is_symbols_only_enum:
   switch (file_type)
     {
     case lang_input_file_is_symbols_only_enum:
@@ -342,7 +347,6 @@ new_afile (name, file_type, target, add_to_list)
   p->next_real_file = (lang_statement_union_type *) NULL;
   p->next = (lang_statement_union_type *) NULL;
   p->symbol_count = 0;
   p->next_real_file = (lang_statement_union_type *) NULL;
   p->next = (lang_statement_union_type *) NULL;
   p->symbol_count = 0;
-  p->common_output_section = (asection *) NULL;
   p->dynamic = config.dynamic_link;
   p->whole_archive = whole_archive;
   p->loaded = false;
   p->dynamic = config.dynamic_link;
   p->whole_archive = whole_archive;
   p->loaded = false;
@@ -490,7 +494,7 @@ lang_output_section_statement_lookup (name)
       lookup->next = (lang_statement_union_type *) NULL;
       lookup->bfd_section = (asection *) NULL;
       lookup->processed = false;
       lookup->next = (lang_statement_union_type *) NULL;
       lookup->bfd_section = (asection *) NULL;
       lookup->processed = false;
-      lookup->loadable = 1;
+      lookup->sectype = normal_section;
       lookup->addr_tree = (etree_type *) NULL;
       lang_list_init (&lookup->children);
 
       lookup->addr_tree = (etree_type *) NULL;
       lang_list_init (&lookup->children);
 
@@ -543,15 +547,17 @@ lang_map ()
   print_statements ();
 }
 
   print_statements ();
 }
 
-/*
- *
- */
+/* Initialize an output section.  */
+
 static void
 init_os (s)
 static void
 init_os (s)
-     lang_output_section_statement_type * s;
+     lang_output_section_statement_type *s;
 {
   section_userdata_type *new;
 
 {
   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);
 
   if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
     einfo ("%P%F: Illegal use of `%s' section", DISCARD_SECTION_NAME);
 
@@ -572,6 +578,59 @@ init_os (s)
   /* vma to allow us to output a section through itself */
   s->bfd_section->output_offset = 0;
   get_userdata (s->bfd_section) = (PTR) new;
   /* 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 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
 }
 
 /* Sections marked with the SEC_LINK_ONCE flag should only be linked
@@ -661,6 +720,23 @@ section_already_linked (abfd, sec, ignore)
    explicit actions, like foo.o(.text), bar.o(.text) and
    foo.o(.text, .data).  */
 
    explicit actions, like foo.o(.text), bar.o(.text) and
    foo.o(.text, .data).  */
 
+/* Return true if the PATTERN argument is a wildcard pattern.  */
+
+static boolean
+wildcardp (pattern)
+     const char *pattern;
+{
+  const char *s;
+
+  for (s = pattern; *s != '\0'; ++s)
+    if (*s == '?'
+       || *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.  */
 /* 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.  */
@@ -725,15 +801,33 @@ wild_doit (ptr, section, output, file)
         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
         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.  */
+        the embedded SEC_NEVER_LOAD section into a fill.
+
+        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.  */
+
       section->output_section->flags |=
       section->output_section->flags |=
-       section->flags & (flagword) (~ SEC_NEVER_LOAD);
+       section->flags & (flagword) (~ (SEC_NEVER_LOAD
+                                       | (! link_info.relocateable
+                                          ? SEC_LINK_ONCE | SEC_LINK_DUPLICATES
+                                          : 0)));
 
 
-      if (! output->loadable) 
+      switch (output->sectype)
        {
        {
-         /* Turn off load flag */
+       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;
          output->bfd_section->flags &= ~SEC_LOAD;
          output->bfd_section->flags |= SEC_NEVER_LOAD;
+         break;
        }
 
       if (section->alignment_power > output->bfd_section->alignment_power)
        }
 
       if (section->alignment_power > output->bfd_section->alignment_power)
@@ -758,9 +852,17 @@ wild_section (ptr, section, file, output)
   if (file->just_syms_flag == false)
     {
       register asection *s;
   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)
        {
 
       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.
 
          /* Attach all sections named SECTION.  If SECTION is NULL,
             then attach all sections.
 
@@ -769,9 +871,19 @@ wild_section (ptr, section, file, output)
             section.  I did not understand that, and I took it out.
             --ian@cygnus.com.  */
 
             section.  I did not understand that, and I took it out.
             --ian@cygnus.com.  */
 
-         if (section == NULL
-             || strcmp (bfd_get_section_name (file->the_bfd, s),
-                        section) == 0)
+         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)
            wild_doit (&ptr->children, s, output, file);
        }
     }
            wild_doit (&ptr->children, s, output, file);
        }
     }
@@ -922,6 +1034,44 @@ load_symbols (entry, place)
   entry->loaded = true;
 }
 
   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
 /* 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
@@ -944,40 +1094,24 @@ wild (s, section, file, target, output)
           f != (lang_input_statement_type *) NULL;
           f = (lang_input_statement_type *) f->next)
        {
           f != (lang_input_statement_type *) NULL;
           f = (lang_input_statement_type *) f->next)
        {
-         wild_section (s, section, f, output);
+         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);
        }
     }
   else
     {
       /* Perform the iteration over a single file */
       f = lookup_name (file);
-      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);
-           }
-       }
+      wild_file (s, section, f, output);
     }
 
   if (section != (char *) NULL
     }
 
   if (section != (char *) NULL
@@ -1016,7 +1150,7 @@ open_output (name)
       einfo ("%P%F: cannot open output file %s: %E\n", name);
     }
 
       einfo ("%P%F: cannot open output file %s: %E\n", name);
     }
 
-  delete_output_file_on_failure = 1;
+  delete_output_file_on_failure = true;
 
   /*  output->flags |= D_PAGED;*/
 
 
   /*  output->flags |= D_PAGED;*/
 
@@ -1089,7 +1223,8 @@ open_input_bfds (s, force)
          break;
        case lang_wild_statement_enum:
          /* Maybe we should load the file's symbols */
          break;
        case lang_wild_statement_enum:
          /* Maybe we should load the file's symbols */
-         if (s->wild_statement.filename)
+         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;
            (void) lookup_name (s->wild_statement.filename);
          open_input_bfds (s->wild_statement.children.head, force);
          break;
@@ -1269,13 +1404,21 @@ map_input_to_output_sections (s, target, output_section_statement)
        case lang_object_symbols_statement_enum:
        case lang_data_statement_enum:
        case lang_reloc_statement_enum:
        case lang_object_symbols_statement_enum:
        case lang_data_statement_enum:
        case lang_reloc_statement_enum:
-       case lang_assignment_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_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_afile_asection_pair_statement_enum:
          FAIL ();
          break;
@@ -1594,7 +1737,7 @@ print_padding_statement (s)
   minfo ("0x%V %W", addr, s->size);
 
   if (s->fill != 0)
   minfo ("0x%V %W", addr, s->size);
 
   if (s->fill != 0)
-    minfo (" 0x%x", s->fill);
+    minfo (" %u", s->fill);
 
   print_nl ();
 
 
   print_nl ();
 
@@ -1746,7 +1889,7 @@ dprint_statement (s, n)
     print_statement_list (s, abs_output_section);
   else
     {
     print_statement_list (s, abs_output_section);
   else
     {
-      while (--n >= 0)
+      while (s && --n >= 0)
        {
          print_statement (s, abs_output_section);
          s = s->next;
        {
          print_statement (s, abs_output_section);
          s = s->next;
@@ -2609,19 +2752,22 @@ lang_place_orphans ()
                  s->output_section = bfd_abs_section_ptr;
                  s->output_offset = s->vma;
                }
                  s->output_section = bfd_abs_section_ptr;
                  s->output_offset = s->vma;
                }
-             else if (file->common_section == s)
+             else if (strcmp (s->name, "COMMON") == 0)
                {
                {
-                 /* This is a lonely common section which must
-                    have come from an archive. We attatch to the
-                    section with the wildcard  */
+                 /* 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
                  if (! link_info.relocateable
-                     && ! command_line.force_common_definition)
+                     || command_line.force_common_definition)
                    {
                    {
-                     if (default_common_section ==
-                         (lang_output_section_statement_type *) NULL)
+                     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");
                          info_msg ("%P: no [COMMON] command, defaulting to .bss\n");
-
+#endif
                          default_common_section =
                            lang_output_section_statement_lookup (".bss");
 
                          default_common_section =
                            lang_output_section_statement_lookup (".bss");
 
@@ -2815,13 +2961,14 @@ topower (x)
 
   return 0;
 }
 
   return 0;
 }
+
 void
 lang_enter_output_section_statement (output_section_statement_name,
 void
 lang_enter_output_section_statement (output_section_statement_name,
-                                    address_exp, flags, block_value,
+                                    address_exp, sectype, block_value,
                                     align, subalign, ebase)
      const char *output_section_statement_name;
      etree_type * address_exp;
                                     align, subalign, ebase)
      const char *output_section_statement_name;
      etree_type * address_exp;
-     int flags;
+     enum section_type sectype;
      bfd_vma block_value;
      etree_type *align;
      etree_type *subalign;
      bfd_vma block_value;
      etree_type *align;
      etree_type *subalign;
@@ -2846,11 +2993,11 @@ lang_enter_output_section_statement (output_section_statement_name,
     os->addr_tree =
      address_exp;
   }
     os->addr_tree =
      address_exp;
   }
-  os->flags = flags;
-  if (flags & SEC_NEVER_LOAD)
-   os->loadable = 0;
+  os->sectype = sectype;
+  if (sectype != noload_section)
+    os->flags = SEC_NO_FLAGS;
   else
   else
-   os->loadable = 1;
+    os->flags = SEC_NEVER_LOAD;
   os->block_value = block_value ? block_value : 1;
   stat_ptr = &os->children;
 
   os->block_value = block_value ? block_value : 1;
   stat_ptr = &os->children;
 
@@ -3404,7 +3551,7 @@ lang_record_phdrs ()
            last = pl;
          else
            {
            last = pl;
          else
            {
-             if (! os->loadable
+             if (os->sectype == noload_section
                  || os->bfd_section == NULL
                  || (os->bfd_section->flags & SEC_ALLOC) == 0)
                continue;
                  || os->bfd_section == NULL
                  || (os->bfd_section->flags & SEC_ALLOC) == 0)
                continue;
index 47048ef117f897258400b992fc5cba499ab03645..6c85f5af35caf11469edcd97072409030805fa41 100644 (file)
@@ -1,6 +1,6 @@
 %{
 
 %{
 
-/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
 
 This file is part of GLD, the Gnu Linker.
 
 
 This file is part of GLD, the Gnu Linker.
 
@@ -16,7 +16,7 @@ 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
 
 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
 This was written by steve chamberlain
 
 /*
 This was written by steve chamberlain
@@ -26,12 +26,13 @@ This was written by steve chamberlain
 
 #include <ansidecl.h>
 #include <stdio.h>
 
 #include <ansidecl.h>
 #include <stdio.h>
-/* start-sanitize-mpw */
+#include <ctype.h>
+
 #ifdef MPW
 /* Prevent enum redefinition problems. */
 #define TRUE_FALSE_ALREADY_DEFINED
 #endif /* MPW */
 #ifdef MPW
 /* Prevent enum redefinition problems. */
 #define TRUE_FALSE_ALREADY_DEFINED
 #endif /* MPW */
-/* end-sanitize-mpw */
+
 #include "bfd.h"
 #include "sysdep.h"
 #include "ld.h"
 #include "bfd.h"
 #include "sysdep.h"
 #include "ld.h"
@@ -54,9 +55,14 @@ int hex_mode;
    (FIXME Actually, it doesn't appear to get reset for each file?)  */
 unsigned int lineno = 1;
 
    (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;
 /* 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.
+   `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.  */
 
    If `include_stack_ptr' is 0, we haven't started reading anything yet.
    Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid.  */
@@ -66,7 +72,8 @@ unsigned int lineno = 1;
 
 #define MAX_INCLUDE_DEPTH 10
 static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
 
 #define MAX_INCLUDE_DEPTH 10
 static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
-static char *file_name_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 YY_BUFFER_STATE yy_create_string_buffer PARAMS ((const char *string,
 static unsigned int include_stack_ptr = 0;
 
 static YY_BUFFER_STATE yy_create_string_buffer PARAMS ((const char *string,
@@ -99,7 +106,7 @@ CMDFILENAMECHAR1  [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\~]
 FILENAMECHAR1  [_a-zA-Z\/\.\\\$\_\~]
 SYMBOLCHARN     [_a-zA-Z\/\.\\0-9]
 FILENAMECHAR   [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~]
 FILENAMECHAR1  [_a-zA-Z\/\.\\\$\_\~]
 SYMBOLCHARN     [_a-zA-Z\/\.\\0-9]
 FILENAMECHAR   [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~]
-FILENAME       {FILENAMECHAR}+
+WILDCHAR       [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~\?\*]
 WHITE          [ \t\n\r]+ 
 
 NOCFILENAMECHAR        [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
 WHITE          [ \t\n\r]+ 
 
 NOCFILENAMECHAR        [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
@@ -139,23 +146,27 @@ NOCFILENAMECHAR   [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
                                return INT;
                        }
 
                                return INT;
                        }
 
-<MRI,EXPRESSION>([0-9A-Fa-f])+(H|X|B|O|D) {
+<MRI,EXPRESSION>([0-9A-Fa-f])+(H|h|X|x|B|b|O|o|D|d) {
                                   int ibase ;
                                   switch (yytext[yyleng-1]) {
                                    case 'X': 
                                   int ibase ;
                                   switch (yytext[yyleng-1]) {
                                    case 'X': 
+                                   case 'x':
                                    case 'H':
                                    case 'H':
+                                   case 'h':
                                     ibase = 16;
                                     break;
                                    case 'O':
                                     ibase = 16;
                                     break;
                                    case 'O':
+                                   case 'o':
                                     ibase = 8;
                                     break;
                                    case 'B':
                                     ibase = 8;
                                     break;
                                    case 'B':
+                                   case 'b':
                                     ibase = 2;
                                     break;
                                    default:
                                     ibase = 10;
                                   }
                                     ibase = 2;
                                     break;
                                    default:
                                     ibase = 10;
                                   }
-                                  yylval.integer = bfd_scan_vma (yytext+1, 0,
+                                  yylval.integer = bfd_scan_vma (yytext, 0,
                                                                  ibase);
                                   return INT;
                                 }
                                                                  ibase);
                                   return INT;
                                 }
@@ -172,47 +183,48 @@ NOCFILENAMECHAR   [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
                                    }           
                                  return INT;
                                }
                                    }           
                                  return INT;
                                }
-<BOTH,SCRIPT,EXPRESSION>"]"            { RTOKEN(']');}
-<BOTH,SCRIPT,EXPRESSION>"["            { RTOKEN('[');}
-<BOTH,SCRIPT,EXPRESSION>"<<="  { RTOKEN(LSHIFTEQ);}
-<BOTH,SCRIPT,EXPRESSION>">>="  { RTOKEN(RSHIFTEQ);}
-<BOTH,SCRIPT,EXPRESSION>"||"   { RTOKEN(OROR);}
-<BOTH,SCRIPT,EXPRESSION>"=="   { RTOKEN(EQ);}
-<BOTH,SCRIPT,EXPRESSION>"!="   { RTOKEN(NE);}
-<BOTH,SCRIPT,EXPRESSION>">="   { RTOKEN(GE);}
-<BOTH,SCRIPT,EXPRESSION>"<="   { RTOKEN(LE);}
-<BOTH,SCRIPT,EXPRESSION>"<<"   { RTOKEN(LSHIFT);}
-<BOTH,SCRIPT,EXPRESSION>">>"   { RTOKEN(RSHIFT);}
-<BOTH,SCRIPT,EXPRESSION>"+="   { RTOKEN(PLUSEQ);}
-<BOTH,SCRIPT,EXPRESSION>"-="   { RTOKEN(MINUSEQ);}
-<BOTH,SCRIPT,EXPRESSION>"*="   { RTOKEN(MULTEQ);}
-<BOTH,SCRIPT,EXPRESSION>"/="   { RTOKEN(DIVEQ);}
-<BOTH,SCRIPT,EXPRESSION>"&="   { RTOKEN(ANDEQ);}
-<BOTH,SCRIPT,EXPRESSION>"|="   { RTOKEN(OREQ);}
-<BOTH,SCRIPT,EXPRESSION>"&&"   { RTOKEN(ANDAND);}
-<BOTH,SCRIPT,EXPRESSION>">"            { RTOKEN('>');}
-<MRI,BOTH,SCRIPT,EXPRESSION>","                { RTOKEN(',');}
-<BOTH,SCRIPT,EXPRESSION>"&"            { RTOKEN('&');}
-<BOTH,SCRIPT,EXPRESSION>"|"            { RTOKEN('|');}
-<BOTH,SCRIPT,EXPRESSION>"~"            { RTOKEN('~');}
-<BOTH,SCRIPT,EXPRESSION>"!"            { RTOKEN('!');}
-<BOTH,SCRIPT,EXPRESSION>"?"            { RTOKEN('?');}
-<BOTH,SCRIPT,EXPRESSION>"*"            { RTOKEN('*');}
-<BOTH,SCRIPT,EXPRESSION>"+"            { RTOKEN('+');}
-<BOTH,SCRIPT,EXPRESSION>"-"            { RTOKEN('-');}
-<BOTH,SCRIPT,EXPRESSION>"/"            { RTOKEN('/');}
-<BOTH,SCRIPT,EXPRESSION>"%"            { RTOKEN('%');}
-<BOTH,SCRIPT,EXPRESSION>"<"            { RTOKEN('<');}
-<MRI,BOTH,SCRIPT,EXPRESSION>"="          { RTOKEN('=');}
-<BOTH,SCRIPT,EXPRESSION>"}"                    { RTOKEN('}') ; }
-<BOTH,SCRIPT,EXPRESSION>"{"                    { RTOKEN('{'); }
-<BOTH,SCRIPT,EXPRESSION>")"                    { RTOKEN(')');}
-<BOTH,SCRIPT,EXPRESSION>"("                    { RTOKEN('(');}
-<BOTH,SCRIPT,EXPRESSION>":"            { RTOKEN(':'); }
-<BOTH,SCRIPT,EXPRESSION>";"            { RTOKEN(';');}
+<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>"MEMORY"          { RTOKEN(MEMORY);}
 <BOTH,SCRIPT>"ORIGIN"          { RTOKEN(ORIGIN);}
-<BOTH,SCRIPT>"BLOCK"                   { RTOKEN(BLOCK);}
+<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);}
 <BOTH,SCRIPT>"LENGTH"          { RTOKEN(LENGTH);}
 <EXPRESSION,BOTH,SCRIPT>"ALIGN"                        { RTOKEN(ALIGN_K);}
 <EXPRESSION,BOTH,SCRIPT>"ADDR"                 { RTOKEN(ADDR);}
@@ -226,6 +238,7 @@ NOCFILENAMECHAR     [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
 <BOTH,SCRIPT>"SEARCH_DIR"              { RTOKEN(SEARCH_DIR);}
 <BOTH,SCRIPT>"OUTPUT"          { RTOKEN(OUTPUT);}
 <BOTH,SCRIPT>"INPUT"                   { RTOKEN(INPUT);}
 <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);}
 <EXPRESSION,BOTH,SCRIPT>"DEFINED"              { RTOKEN(DEFINED);}
 <BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS"   { RTOKEN(CREATE_OBJECT_SYMBOLS);}
 <BOTH,SCRIPT>"CONSTRUCTORS"            { RTOKEN( CONSTRUCTORS);}
@@ -243,25 +256,27 @@ NOCFILENAMECHAR   [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
 <BOTH,SCRIPT>"SHORT"                   { RTOKEN( SHORT);}
 <BOTH,SCRIPT>"BYTE"                    { RTOKEN( BYTE);}
 <BOTH,SCRIPT>"NOFLOAT"         { RTOKEN(NOFLOAT);}
 <BOTH,SCRIPT>"SHORT"                   { RTOKEN( SHORT);}
 <BOTH,SCRIPT>"BYTE"                    { RTOKEN( BYTE);}
 <BOTH,SCRIPT>"NOFLOAT"         { RTOKEN(NOFLOAT);}
-<EXPRESSION,BOTH,SCRIPT>"NOLOAD"               { RTOKEN(NOLOAD);}
-<BOTH,SCRIPT>"DSECT"                   { RTOKEN(DSECT);}
-<BOTH,SCRIPT>"COPY"                    { RTOKEN(COPY);}
-<BOTH,SCRIPT>"INFO"                    { RTOKEN(INFO);}
-<BOTH,SCRIPT>"OVERLAY"         { RTOKEN(OVERLAY);}
+<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>"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>"AT"                   { RTOKEN(AT);}
-<BOTH,SCRIPT>"PROVIDE"                 { RTOKEN(PROVIDE); }
+<EXPRESSION,BOTH,SCRIPT>"PROVIDE"              { RTOKEN(PROVIDE); }
+<MRI>"#".*\n?\r?               { ++ lineno; }
 <MRI>"\n"                      { ++ lineno;  RTOKEN(NEWLINE); }
 <MRI>"\r"                      { ++ lineno;  RTOKEN(NEWLINE); }
 <MRI>"*".*                     { /* Mri comment line */ }
 <MRI>"\n"                      { ++ lineno;  RTOKEN(NEWLINE); }
 <MRI>"\r"                      { ++ 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>"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>"CHIP"                     { RTOKEN(CHIP); }
 <MRI>"BASE"                     { RTOKEN(BASE); }
 <MRI>"ALIAS"                     { RTOKEN(ALIAS); }
@@ -271,15 +286,27 @@ NOCFILENAMECHAR   [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
 <MRI>"ORDER"                    { RTOKEN(ORDER); }
 <MRI>"NAME"                     { RTOKEN(NAMEWORD); }
 <MRI>"FORMAT"                   { RTOKEN(FORMAT); }
 <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>"end"                      { RTOKEN(ENDWORD); }
 <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>"chip"                     { RTOKEN(CHIP); }
+<MRI>"base"                     { RTOKEN(BASE); }
+<MRI>"alias"                     { RTOKEN(ALIAS); }
+<MRI>"truncate"                     { RTOKEN(TRUNCATE); }
 <MRI>"load"                     { RTOKEN(LOAD); }
 <MRI>"load"                     { RTOKEN(LOAD); }
+<MRI>"public"                   { RTOKEN(PUBLIC); }
 <MRI>"order"                    { RTOKEN(ORDER); }
 <MRI>"name"                     { RTOKEN(NAMEWORD); }
 <MRI>"format"                   { RTOKEN(FORMAT); }
 <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>"list".*                   { RTOKEN(LIST); /* LIST and ignore to end of line */ }
 <MRI>"sect"                    { RTOKEN(SECT); }
 <EXPRESSION,BOTH,SCRIPT,MRI>"absolute"                 { RTOKEN(ABSOLUTE); }
@@ -295,9 +322,11 @@ NOCFILENAMECHAR    [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
                                 yylval.name = buystring(yytext); 
                                  return NAME;
                                }
                                 yylval.name = buystring(yytext); 
                                  return NAME;
                                }
-<SCRIPT>{FILENAMECHAR}* { yylval.name = buystring(yytext); 
-                                 return NAME;
+<BOTH,EXPRESSION>"-l"{FILENAMECHAR}+ {
+                                 yylval.name = buystring (yytext + 2);
+                                 return LNAME;
                                }
                                }
+<SCRIPT>{WILDCHAR}* { yylval.name = buystring(yytext); return NAME; }
 
 <EXPRESSION,BOTH,SCRIPT>"\""[^\"]*"\"" {
                                        /* No matter the state, quotes
 
 <EXPRESSION,BOTH,SCRIPT>"\""[^\"]*"\"" {
                                        /* No matter the state, quotes
@@ -323,7 +352,8 @@ NOCFILENAMECHAR     [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
 
   }
   BEGIN(SCRIPT);
 
   }
   BEGIN(SCRIPT);
-  ldfile_input_filename = file_name_stack[include_stack_ptr-1];
+  ldfile_input_filename = file_name_stack[include_stack_ptr - 1];
+  lineno = lineno_stack[include_stack_ptr - 1];
 
   return END;
 }
 
   return END;
 }
@@ -340,13 +370,14 @@ NOCFILENAMECHAR   [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
 void
 lex_push_file (file, name)
      FILE *file;
 void
 lex_push_file (file, name)
      FILE *file;
-     char *name;
+     const char *name;
 {
   if (include_stack_ptr >= MAX_INCLUDE_DEPTH) 
     {
       einfo("%F:includes nested too deeply\n");
     }
   file_name_stack[include_stack_ptr] = 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++;
   include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
 
   include_stack_ptr++;
@@ -372,7 +403,7 @@ yy_create_string_buffer (string, 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.  */
 
   /* 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 = (YY_CHAR *) malloc ((unsigned) (b->yy_buf_size + 3));
+  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[0] = '\n';
   strcpy (b->yy_ch_buf+1, string);
@@ -380,7 +411,14 @@ yy_create_string_buffer (string, size)
   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];
   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;
   b->yy_eof_status = EOF_NOT_SEEN;
+#endif
 
   return b;
 }
 
   return b;
 }
@@ -400,6 +438,7 @@ lex_redirect (string)
       einfo("%F: macros nested too deeply\n");
     }
   file_name_stack[include_stack_ptr] = "redirect";
       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));
   include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
   include_stack_ptr++;
   tmp = yy_create_string_buffer (string, strlen (string));
@@ -520,7 +559,23 @@ static void
 lex_warn_invalid (where, what)
      char *where, *what;
 {
 lex_warn_invalid (where, what)
      char *where, *what;
 {
-  fprintf(stderr,
-         "%s: ignoring invalid character `%s'%s\n",
-         program_name, what, where);
+  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);
 }
 }
This page took 0.057253 seconds and 4 git commands to generate.