* 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.
This commit is contained in:
Ian Lance Taylor 1996-07-29 21:33:26 +00:00
parent f2bf454e0f
commit 86bc0974cb
10 changed files with 904 additions and 174 deletions

View File

@ -39,6 +39,8 @@ configure.tgt
dep-in.sed dep-in.sed
emulparams emulparams
emultempl emultempl
fnmatch.c
fnmatch.h
genscripts.sh genscripts.sh
h8-doc.texi h8-doc.texi
ld.1 ld.1

View 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 start-sanitize-d10v
Wed Jul 24 12:16:38 1996 Martin M. Hunt <hunt@pizza.cygnus.com> Wed Jul 24 12:16:38 1996 Martin M. Hunt <hunt@pizza.cygnus.com>

View File

@ -285,18 +285,18 @@ ALL_EMULATIONS = \
CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \ CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.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 \ HFILES = config.h ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
ldlang.h ldlex.h ldmain.h ldmisc.h ldver.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_CFILES = ldgram.c ldlex.c
GENERATED_HFILES = ldgram.h ldemul-list.h GENERATED_HFILES = ldgram.h ldemul-list.h
OFILES = ldgram.o ldlex.o lexsup.o ldlang.o mri.o ldctor.o ldmain.o \ 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 \ 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)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
$(INCDIR)/libiberty.h $(INCDIR)/bfdlink.h ld.h ldmain.h \ $(INCDIR)/libiberty.h $(INCDIR)/bfdlink.h ld.h ldmain.h \
ldgram.h ldexp.h ldlang.h ldemul.h ldlex.h ldmisc.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 \ ldmain.o: ldmain.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
$(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \ $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
$(INCDIR)/libiberty.h $(INCDIR)/progress.h $(INCDIR)/bfdlink.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 ldlang.h ldwrite.h ldmisc.h ldgram.h ldmain.h
lexsup.o: lexsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ lexsup.o: lexsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
$(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \ $(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
$(INCDIR)/getopt.h $(INCDIR)/bfdlink.h ld.h ldmain.h \ $(INCDIR)/libiberty.h $(INCDIR)/getopt.h $(INCDIR)/bfdlink.h \
ldmisc.h ldexp.h ldlang.h ldgram.h ldlex.h ldfile.h \ ld.h ldmain.h ldmisc.h ldexp.h ldlang.h ldgram.h ldlex.h \
ldver.h ldemul.h ldfile.h ldver.h ldemul.h
mri.o: mri.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/obstack.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 \ sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldexp.h \
ldlang.h ldmisc.h mri.h ldgram.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)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.h \
$(INCDIR)/bfdlink.h $(INCDIR)/libiberty.h ld.h ldmain.h \ $(INCDIR)/bfdlink.h $(INCDIR)/libiberty.h ld.h ldmain.h \
ldmisc.h ldmisc.h
fnmatch.o: fnmatch.c
ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \ ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
$(INCDIR)/obstack.h sysdep.h config.h $(INCDIR)/fopen-same.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 \ $(INCDIR)/bfdlink.h ld.h ldexp.h ldver.h ldlang.h ldemul.h \

32
ld/NEWS
View File

@ -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: Changes since version 2.5:
* When an ELF section name is representable as a C identifier (this is not true * 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. * New options -split-by-reloc and -split-by-file.
* The linker now supports linking PIC compiled code on SPARC SunOS. It can * 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 also create SPARC SunOS shared libraries, and, like the native SunOS linker,
when linking code which has an undefined symbol, but the GNU linker requires will do so whenever there is an undefined symbol in the link and neither the -e
the -shared option. For convenience when used with gcc -shared, the GNU linker nor the -r option was used.
will also create a shared library when given the -assert pure-text option,
although this is not really what -assert pure-text should mean. * 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 * 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 enums, so that even if the same type is defined in multiple input files it will

214
ld/fnmatch.c Normal file
View File

@ -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__. */

69
ld/fnmatch.h Normal file
View File

@ -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 */

View 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 within the shared library. This option is only meaningful on ELF
platforms which support shared libraries. 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 @cindex symbols, from command line
@kindex --defsym @var{symbol}=@var{exp} @kindex --defsym @var{symbol}=@var{exp}
@item --defsym @var{symbol}=@var{expression} @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 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 following kinds of statement. You can include as many of these as you
like in a single section definition, separated from one another by like in a single section definition, separated from one another by
whitespace. whitespace.
@table @code @table @code
@kindex @var{filename} @kindex @var{filename}
@ -1949,8 +1962,23 @@ were in an input-file section named @code{COMMON}, regardless of the
input file's format. input file's format.
@end table @end table
For example, the following command script arranges the output file into In any place where you may use a specific file or section name, you may
three consecutive sections, named @code{.text}, @code{.data}, and 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 @code{.bss}, taking the input for each from the correspondingly named
sections of all the input files: sections of all the input files:
@ -1995,6 +2023,24 @@ SECTIONS @{
@end group @end group
@end smallexample @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 @node Section Data Expressions
@subsection Section Data Expressions @subsection Section Data Expressions

View 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). Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
This file is part of GNU ld. 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 #define YYDEBUG 1
#endif #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; char *name;
int token; int token;
union etree_union *etree; 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 <integer> fill_opt
%type <name> memspec_opt casesymlist %type <name> memspec_opt casesymlist
%token <integer> INT %token <integer> INT
%token <name> NAME LNAME %token <name> NAME LNAME
%type <integer> length %type <integer> length
%type <phdr> phdr_qualifiers
%right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
%right <token> '?' ':' %right <token> '?' ':'
@ -94,8 +102,8 @@ static int error_index;
%right UNARY %right UNARY
%token END %token END
%left <token> '(' %left <token> '('
%token <token> ALIGN_K BLOCK QUAD LONG SHORT BYTE %token <token> ALIGN_K BLOCK BIND QUAD LONG SHORT BYTE
%token SECTIONS %token SECTIONS PHDRS
%token '{' '}' %token '{' '}'
%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
%token SIZEOF_HEADERS %token SIZEOF_HEADERS
@ -108,7 +116,7 @@ static int error_index;
%token ORIGIN FILL %token ORIGIN FILL
%token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
%token ALIGNMOD AT PROVIDE %token ALIGNMOD AT PROVIDE
%type <token> assign_op %type <token> assign_op atype
%type <name> filename %type <name> filename
%token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD
%token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
@ -136,12 +144,15 @@ defsym_expr:
/* SYNTAX WITHIN AN MRI SCRIPT FILE */ /* SYNTAX WITHIN AN MRI SCRIPT FILE */
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);} { mri_output_section($2, $4);}
| ALIGN_K NAME '=' exp | ALIGN_K NAME '=' exp
{ mri_align($2,$4); } { mri_align($2,$4); }
| ALIGN_K NAME ',' exp
{ mri_align($2,$4); }
| ALIGNMOD NAME '=' exp | ALIGNMOD NAME '=' exp
{ mri_alignmod($2,$4); } { mri_alignmod($2,$4); }
| ALIGNMOD NAME ',' exp
{ mri_alignmod($2,$4); }
| ABSOLUTE mri_abs_name_list | ABSOLUTE mri_abs_name_list
| LOAD mri_load_name_list | LOAD mri_load_name_list
| NAMEWORD NAME | NAMEWORD NAME
@ -196,7 +211,7 @@ mri_script_command:
| INCLUDE filename | INCLUDE filename
{ ldfile_open_command_file ($2); } mri_script_lines END { ldfile_open_command_file ($2); } mri_script_lines END
| START NAME | START NAME
{ lang_add_entry ($2, 0); } { lang_add_entry ($2, false); }
| |
; ;
@ -253,6 +268,7 @@ ifile_list:
ifile_p1: ifile_p1:
memory memory
| sections | sections
| phdrs
| startup | startup
| high_level_library | high_level_library
| low_level_library | low_level_library
@ -318,15 +334,25 @@ sec_or_group_p1:
statement_anywhere: statement_anywhere:
ENTRY '(' NAME ')' 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: file_NAME_list:
NAME 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); lang_add_attribute(lang_constructors_statement_enum);
} }
| input_section_spec | 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 lang_add_fill
(exp_get_value_int($3, (exp_get_value_int($3,
@ -623,36 +656,57 @@ opt_at:
section: NAME { ldlex_expression(); } section: NAME { ldlex_expression(); }
opt_exp_with_type 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; } NOLOAD { sectype = noload_section; }
| DSECT { typebits = 0; } | DSECT { sectype = dsect_section; }
| COPY { typebits = 0; } | COPY { sectype = copy_section; }
| INFO { typebits = 0; } | INFO { sectype = info_section; }
| OVERLAY { typebits = 0; } | OVERLAY { sectype = overlay_section; }
| { typebits = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; }
; ;
atype:
'(' type ')'
| /* EMPTY */ { sectype = normal_section; }
;
opt_exp_with_type: opt_exp_with_type:
exp ':' { $$ = $1; typebits =0;} exp atype ':' { $$ = $1; }
| exp '(' type ')' ':' { $$ = $1; } | atype ':' { $$ = (etree_type *)NULL; }
| ':' { $$= (etree_type *)NULL; typebits = 0; } | /* The BIND cases are to support the gcc svr3.ifile
| '(' type ')' ':' { $$= (etree_type *)NULL; } 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; } { $$ = $2; }
| { $$ = "*default*"; } | { $$ = "*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 void
yyerror(arg) yyerror(arg)

View File

@ -32,6 +32,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307
#include "ldmisc.h" #include "ldmisc.h"
#include "ldctor.h" #include "ldctor.h"
#include "ldfile.h" #include "ldfile.h"
#include "fnmatch.h"
/* FORWARDS */ /* FORWARDS */
static lang_statement_union_type *new_statement PARAMS ((enum statement_enum, 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, PARAMS ((const char *name, lang_input_file_enum_type file_type,
const char *target, boolean add_to_list)); const char *target, boolean add_to_list));
static void init_os PARAMS ((lang_output_section_statement_type *s)); 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, static void wild_section PARAMS ((lang_wild_statement_type *ptr,
const char *section, const char *section,
lang_input_statement_type *file, 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 lang_input_statement_type *lookup_name PARAMS ((const char *name));
static void load_symbols PARAMS ((lang_input_statement_type *entry, static void load_symbols PARAMS ((lang_input_statement_type *entry,
lang_statement_list_type *)); 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, static void wild PARAMS ((lang_wild_statement_type *s,
const char *section, const char *file, const char *section, const char *file,
const char *target, const char *target,
@ -283,7 +289,6 @@ new_afile (name, file_type, target, add_to_list)
lang_has_input_file = true; lang_has_input_file = true;
p->target = target; p->target = target;
p->complained = false;
switch (file_type) switch (file_type)
{ {
case lang_input_file_is_symbols_only_enum: 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_real_file = (lang_statement_union_type *) NULL;
p->next = (lang_statement_union_type *) NULL; p->next = (lang_statement_union_type *) NULL;
p->symbol_count = 0; p->symbol_count = 0;
p->common_output_section = (asection *) NULL;
p->dynamic = config.dynamic_link; p->dynamic = config.dynamic_link;
p->whole_archive = whole_archive; p->whole_archive = whole_archive;
p->loaded = false; p->loaded = false;
@ -490,7 +494,7 @@ lang_output_section_statement_lookup (name)
lookup->next = (lang_statement_union_type *) NULL; lookup->next = (lang_statement_union_type *) NULL;
lookup->bfd_section = (asection *) NULL; lookup->bfd_section = (asection *) NULL;
lookup->processed = false; lookup->processed = false;
lookup->loadable = 1; lookup->sectype = normal_section;
lookup->addr_tree = (etree_type *) NULL; lookup->addr_tree = (etree_type *) NULL;
lang_list_init (&lookup->children); lang_list_init (&lookup->children);
@ -543,15 +547,17 @@ lang_map ()
print_statements (); print_statements ();
} }
/* /* Initialize an output section. */
*
*/
static void static void
init_os (s) 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) if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
einfo ("%P%F: Illegal use of `%s' section", DISCARD_SECTION_NAME); 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 */ /* vma to allow us to output a section through itself */
s->bfd_section->output_offset = 0; s->bfd_section->output_offset = 0;
get_userdata (s->bfd_section) = (PTR) new; 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 explicit actions, like foo.o(.text), bar.o(.text) and
foo.o(.text, .data). */ 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 /* Add SECTION to the output section OUTPUT. Do this by creating a
lang_input_section statement which is placed at PTR. FILE is the lang_input_section statement which is placed at PTR. FILE is the
input file which holds SECTION. */ 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 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). 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 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.
section->output_section->flags |=
section->flags & (flagword) (~ SEC_NEVER_LOAD);
if (! output->loadable) 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->flags & (flagword) (~ (SEC_NEVER_LOAD
| (! link_info.relocateable
? SEC_LINK_ONCE | SEC_LINK_DUPLICATES
: 0)));
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_LOAD;
output->bfd_section->flags |= SEC_NEVER_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) if (file->just_syms_flag == false)
{ {
register asection *s; 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, /* Attach all sections named SECTION. If SECTION is NULL,
then attach all sections. 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. section. I did not understand that, and I took it out.
--ian@cygnus.com. */ --ian@cygnus.com. */
if (section == NULL if (section == NULL)
|| strcmp (bfd_get_section_name (file->the_bfd, s), match = true;
section) == 0) 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, /* Handle a wild statement. SECTION or FILE or both may be NULL,
indicating that it is a wildcard. Separate lang_input_section indicating that it is a wildcard. Separate lang_input_section
statements are created for each part of the expansion; they are 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 *) NULL;
f = (lang_input_statement_type *) f->next) 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 else
{ {
/* Perform the iteration over a single file */ /* Perform the iteration over a single file */
f = lookup_name (file); f = lookup_name (file);
if (f->the_bfd == NULL wild_file (s, section, f, output);
|| ! 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);
}
}
} }
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; break;
case lang_wild_statement_enum: case lang_wild_statement_enum:
/* Maybe we should load the file's symbols */ /* 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); (void) lookup_name (s->wild_statement.filename);
open_input_bfds (s->wild_statement.children.head, force); open_input_bfds (s->wild_statement.children.head, force);
break; break;
@ -1269,13 +1404,21 @@ map_input_to_output_sections (s, target, output_section_statement)
case lang_object_symbols_statement_enum: case lang_object_symbols_statement_enum:
case lang_data_statement_enum: case lang_data_statement_enum:
case lang_reloc_statement_enum: case lang_reloc_statement_enum:
case lang_assignment_statement_enum:
case lang_padding_statement_enum: case lang_padding_statement_enum:
case lang_input_statement_enum: case lang_input_statement_enum:
if (output_section_statement != NULL if (output_section_statement != NULL
&& output_section_statement->bfd_section == NULL) && output_section_statement->bfd_section == NULL)
init_os (output_section_statement); init_os (output_section_statement);
break; 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: case lang_afile_asection_pair_statement_enum:
FAIL (); FAIL ();
break; break;
@ -1594,7 +1737,7 @@ print_padding_statement (s)
minfo ("0x%V %W", addr, s->size); minfo ("0x%V %W", addr, s->size);
if (s->fill != 0) 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); print_statement_list (s, abs_output_section);
else else
{ {
while (--n >= 0) while (s && --n >= 0)
{ {
print_statement (s, abs_output_section); print_statement (s, abs_output_section);
s = s->next; s = s->next;
@ -2609,19 +2752,22 @@ lang_place_orphans ()
s->output_section = bfd_abs_section_ptr; s->output_section = bfd_abs_section_ptr;
s->output_offset = s->vma; 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 /* This is a lonely common section which must have
have come from an archive. We attatch to the come from an archive. We attach to the section
section with the wildcard */ 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 == if (default_common_section == NULL)
(lang_output_section_statement_type *) 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 = default_common_section =
lang_output_section_statement_lookup (".bss"); lang_output_section_statement_lookup (".bss");
@ -2815,13 +2961,14 @@ topower (x)
return 0; return 0;
} }
void void
lang_enter_output_section_statement (output_section_statement_name, lang_enter_output_section_statement (output_section_statement_name,
address_exp, flags, block_value, address_exp, sectype, block_value,
align, subalign, ebase) align, subalign, ebase)
const char *output_section_statement_name; const char *output_section_statement_name;
etree_type * address_exp; etree_type * address_exp;
int flags; enum section_type sectype;
bfd_vma block_value; bfd_vma block_value;
etree_type *align; etree_type *align;
etree_type *subalign; etree_type *subalign;
@ -2846,11 +2993,11 @@ lang_enter_output_section_statement (output_section_statement_name,
os->addr_tree = os->addr_tree =
address_exp; address_exp;
} }
os->flags = flags; os->sectype = sectype;
if (flags & SEC_NEVER_LOAD) if (sectype != noload_section)
os->loadable = 0; os->flags = SEC_NO_FLAGS;
else else
os->loadable = 1; os->flags = SEC_NEVER_LOAD;
os->block_value = block_value ? block_value : 1; os->block_value = block_value ? block_value : 1;
stat_ptr = &os->children; stat_ptr = &os->children;
@ -3404,7 +3551,7 @@ lang_record_phdrs ()
last = pl; last = pl;
else else
{ {
if (! os->loadable if (os->sectype == noload_section
|| os->bfd_section == NULL || os->bfd_section == NULL
|| (os->bfd_section->flags & SEC_ALLOC) == 0) || (os->bfd_section->flags & SEC_ALLOC) == 0)
continue; continue;

View 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 You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to 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 <ansidecl.h>
#include <stdio.h> #include <stdio.h>
/* start-sanitize-mpw */ #include <ctype.h>
#ifdef MPW #ifdef MPW
/* Prevent enum redefinition problems. */ /* Prevent enum redefinition problems. */
#define TRUE_FALSE_ALREADY_DEFINED #define TRUE_FALSE_ALREADY_DEFINED
#endif /* MPW */ #endif /* MPW */
/* end-sanitize-mpw */
#include "bfd.h" #include "bfd.h"
#include "sysdep.h" #include "sysdep.h"
#include "ld.h" #include "ld.h"
@ -54,9 +55,14 @@ int hex_mode;
(FIXME Actually, it doesn't appear to get reset for each file?) */ (FIXME Actually, it doesn't appear to get reset for each file?) */
unsigned int lineno = 1; 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). /* Support for flex reading from more than one input file (stream).
`include_stack' is flex's input state for each open file; `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. If `include_stack_ptr' is 0, we haven't started reading anything yet.
Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid. */ Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid. */
@ -66,7 +72,8 @@ unsigned int lineno = 1;
#define MAX_INCLUDE_DEPTH 10 #define MAX_INCLUDE_DEPTH 10
static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; 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 unsigned int include_stack_ptr = 0;
static YY_BUFFER_STATE yy_create_string_buffer PARAMS ((const char *string, 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\/\.\\\$\_\~] FILENAMECHAR1 [_a-zA-Z\/\.\\\$\_\~]
SYMBOLCHARN [_a-zA-Z\/\.\\0-9] SYMBOLCHARN [_a-zA-Z\/\.\\0-9]
FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~] FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~]
FILENAME {FILENAMECHAR}+ WILDCHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~\?\*]
WHITE [ \t\n\r]+ WHITE [ \t\n\r]+
NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] 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 ; int ibase ;
switch (yytext[yyleng-1]) { switch (yytext[yyleng-1]) {
case 'X': case 'X':
case 'x':
case 'H': case 'H':
case 'h':
ibase = 16; ibase = 16;
break; break;
case 'O': case 'O':
case 'o':
ibase = 8; ibase = 8;
break; break;
case 'B': case 'B':
case 'b':
ibase = 2; ibase = 2;
break; break;
default: default:
ibase = 10; ibase = 10;
} }
yylval.integer = bfd_scan_vma (yytext+1, 0, yylval.integer = bfd_scan_vma (yytext, 0,
ibase); ibase);
return INT; return INT;
} }
@ -172,47 +183,48 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
} }
return INT; return INT;
} }
<BOTH,SCRIPT,EXPRESSION>"]" { RTOKEN(']');} <BOTH,SCRIPT,EXPRESSION,MRI>"]" { RTOKEN(']');}
<BOTH,SCRIPT,EXPRESSION>"[" { RTOKEN('[');} <BOTH,SCRIPT,EXPRESSION,MRI>"[" { RTOKEN('[');}
<BOTH,SCRIPT,EXPRESSION>"<<=" { RTOKEN(LSHIFTEQ);} <BOTH,SCRIPT,EXPRESSION,MRI>"<<=" { RTOKEN(LSHIFTEQ);}
<BOTH,SCRIPT,EXPRESSION>">>=" { RTOKEN(RSHIFTEQ);} <BOTH,SCRIPT,EXPRESSION,MRI>">>=" { RTOKEN(RSHIFTEQ);}
<BOTH,SCRIPT,EXPRESSION>"||" { RTOKEN(OROR);} <BOTH,SCRIPT,EXPRESSION,MRI>"||" { RTOKEN(OROR);}
<BOTH,SCRIPT,EXPRESSION>"==" { RTOKEN(EQ);} <BOTH,SCRIPT,EXPRESSION,MRI>"==" { RTOKEN(EQ);}
<BOTH,SCRIPT,EXPRESSION>"!=" { RTOKEN(NE);} <BOTH,SCRIPT,EXPRESSION,MRI>"!=" { RTOKEN(NE);}
<BOTH,SCRIPT,EXPRESSION>">=" { RTOKEN(GE);} <BOTH,SCRIPT,EXPRESSION,MRI>">=" { RTOKEN(GE);}
<BOTH,SCRIPT,EXPRESSION>"<=" { RTOKEN(LE);} <BOTH,SCRIPT,EXPRESSION,MRI>"<=" { RTOKEN(LE);}
<BOTH,SCRIPT,EXPRESSION>"<<" { RTOKEN(LSHIFT);} <BOTH,SCRIPT,EXPRESSION,MRI>"<<" { RTOKEN(LSHIFT);}
<BOTH,SCRIPT,EXPRESSION>">>" { RTOKEN(RSHIFT);} <BOTH,SCRIPT,EXPRESSION,MRI>">>" { RTOKEN(RSHIFT);}
<BOTH,SCRIPT,EXPRESSION>"+=" { RTOKEN(PLUSEQ);} <BOTH,SCRIPT,EXPRESSION,MRI>"+=" { RTOKEN(PLUSEQ);}
<BOTH,SCRIPT,EXPRESSION>"-=" { RTOKEN(MINUSEQ);} <BOTH,SCRIPT,EXPRESSION,MRI>"-=" { RTOKEN(MINUSEQ);}
<BOTH,SCRIPT,EXPRESSION>"*=" { RTOKEN(MULTEQ);} <BOTH,SCRIPT,EXPRESSION,MRI>"*=" { RTOKEN(MULTEQ);}
<BOTH,SCRIPT,EXPRESSION>"/=" { RTOKEN(DIVEQ);} <BOTH,SCRIPT,EXPRESSION,MRI>"/=" { RTOKEN(DIVEQ);}
<BOTH,SCRIPT,EXPRESSION>"&=" { RTOKEN(ANDEQ);} <BOTH,SCRIPT,EXPRESSION,MRI>"&=" { RTOKEN(ANDEQ);}
<BOTH,SCRIPT,EXPRESSION>"|=" { RTOKEN(OREQ);} <BOTH,SCRIPT,EXPRESSION,MRI>"|=" { RTOKEN(OREQ);}
<BOTH,SCRIPT,EXPRESSION>"&&" { RTOKEN(ANDAND);} <BOTH,SCRIPT,EXPRESSION,MRI>"&&" { RTOKEN(ANDAND);}
<BOTH,SCRIPT,EXPRESSION>">" { RTOKEN('>');} <BOTH,SCRIPT,EXPRESSION,MRI>">" { RTOKEN('>');}
<MRI,BOTH,SCRIPT,EXPRESSION>"," { RTOKEN(',');} <BOTH,SCRIPT,EXPRESSION,MRI>"," { RTOKEN(',');}
<BOTH,SCRIPT,EXPRESSION>"&" { RTOKEN('&');} <BOTH,SCRIPT,EXPRESSION,MRI>"&" { RTOKEN('&');}
<BOTH,SCRIPT,EXPRESSION>"|" { RTOKEN('|');} <BOTH,SCRIPT,EXPRESSION,MRI>"|" { RTOKEN('|');}
<BOTH,SCRIPT,EXPRESSION>"~" { RTOKEN('~');} <BOTH,SCRIPT,EXPRESSION,MRI>"~" { RTOKEN('~');}
<BOTH,SCRIPT,EXPRESSION>"!" { RTOKEN('!');} <BOTH,SCRIPT,EXPRESSION,MRI>"!" { RTOKEN('!');}
<BOTH,SCRIPT,EXPRESSION>"?" { RTOKEN('?');} <BOTH,SCRIPT,EXPRESSION,MRI>"?" { RTOKEN('?');}
<BOTH,SCRIPT,EXPRESSION>"*" { RTOKEN('*');} <BOTH,SCRIPT,EXPRESSION,MRI>"*" { RTOKEN('*');}
<BOTH,SCRIPT,EXPRESSION>"+" { RTOKEN('+');} <BOTH,SCRIPT,EXPRESSION,MRI>"+" { RTOKEN('+');}
<BOTH,SCRIPT,EXPRESSION>"-" { RTOKEN('-');} <BOTH,SCRIPT,EXPRESSION,MRI>"-" { RTOKEN('-');}
<BOTH,SCRIPT,EXPRESSION>"/" { RTOKEN('/');} <BOTH,SCRIPT,EXPRESSION,MRI>"/" { RTOKEN('/');}
<BOTH,SCRIPT,EXPRESSION>"%" { RTOKEN('%');} <BOTH,SCRIPT,EXPRESSION,MRI>"%" { RTOKEN('%');}
<BOTH,SCRIPT,EXPRESSION>"<" { RTOKEN('<');} <BOTH,SCRIPT,EXPRESSION,MRI>"<" { RTOKEN('<');}
<MRI,BOTH,SCRIPT,EXPRESSION>"=" { RTOKEN('=');} <BOTH,SCRIPT,EXPRESSION,MRI>"=" { RTOKEN('=');}
<BOTH,SCRIPT,EXPRESSION>"}" { RTOKEN('}') ; } <BOTH,SCRIPT,EXPRESSION,MRI>"}" { RTOKEN('}') ; }
<BOTH,SCRIPT,EXPRESSION>"{" { RTOKEN('{'); } <BOTH,SCRIPT,EXPRESSION,MRI>"{" { RTOKEN('{'); }
<BOTH,SCRIPT,EXPRESSION>")" { RTOKEN(')');} <BOTH,SCRIPT,EXPRESSION,MRI>")" { RTOKEN(')');}
<BOTH,SCRIPT,EXPRESSION>"(" { RTOKEN('(');} <BOTH,SCRIPT,EXPRESSION,MRI>"(" { RTOKEN('(');}
<BOTH,SCRIPT,EXPRESSION>":" { RTOKEN(':'); } <BOTH,SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); }
<BOTH,SCRIPT,EXPRESSION>";" { RTOKEN(';');} <BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');}
<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);} <BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
<BOTH,SCRIPT>"ORIGIN" { RTOKEN(ORIGIN);} <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);} <BOTH,SCRIPT>"LENGTH" { RTOKEN(LENGTH);}
<EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);} <EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);}
<EXPRESSION,BOTH,SCRIPT>"ADDR" { RTOKEN(ADDR);} <EXPRESSION,BOTH,SCRIPT>"ADDR" { RTOKEN(ADDR);}
@ -226,6 +238,7 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
<BOTH,SCRIPT>"SEARCH_DIR" { RTOKEN(SEARCH_DIR);} <BOTH,SCRIPT>"SEARCH_DIR" { RTOKEN(SEARCH_DIR);}
<BOTH,SCRIPT>"OUTPUT" { RTOKEN(OUTPUT);} <BOTH,SCRIPT>"OUTPUT" { RTOKEN(OUTPUT);}
<BOTH,SCRIPT>"INPUT" { RTOKEN(INPUT);} <BOTH,SCRIPT>"INPUT" { RTOKEN(INPUT);}
<EXPRESSION,BOTH,SCRIPT>"GROUP" { RTOKEN(GROUP);}
<EXPRESSION,BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);} <EXPRESSION,BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);}
<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);} <BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);}
<BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);} <BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);}
@ -243,25 +256,27 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
<BOTH,SCRIPT>"SHORT" { RTOKEN( SHORT);} <BOTH,SCRIPT>"SHORT" { RTOKEN( SHORT);}
<BOTH,SCRIPT>"BYTE" { RTOKEN( BYTE);} <BOTH,SCRIPT>"BYTE" { RTOKEN( BYTE);}
<BOTH,SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT);} <BOTH,SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT);}
<EXPRESSION,BOTH,SCRIPT>"NOLOAD" { RTOKEN(NOLOAD);} <EXPRESSION,BOTH,SCRIPT>"NOLOAD" { RTOKEN(NOLOAD);}
<BOTH,SCRIPT>"DSECT" { RTOKEN(DSECT);} <EXPRESSION,BOTH,SCRIPT>"DSECT" { RTOKEN(DSECT);}
<BOTH,SCRIPT>"COPY" { RTOKEN(COPY);} <EXPRESSION,BOTH,SCRIPT>"COPY" { RTOKEN(COPY);}
<BOTH,SCRIPT>"INFO" { RTOKEN(INFO);} <EXPRESSION,BOTH,SCRIPT>"INFO" { RTOKEN(INFO);}
<BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY);} <EXPRESSION,BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY);}
<BOTH,SCRIPT>"o" { RTOKEN(ORIGIN);} <BOTH,SCRIPT>"o" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"org" { RTOKEN(ORIGIN);} <BOTH,SCRIPT>"org" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"l" { RTOKEN( LENGTH);} <BOTH,SCRIPT>"l" { RTOKEN( LENGTH);}
<BOTH,SCRIPT>"len" { RTOKEN( LENGTH);} <BOTH,SCRIPT>"len" { RTOKEN( LENGTH);}
<BOTH,SCRIPT>"INCLUDE" { RTOKEN(INCLUDE);} <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>"\n" { ++ lineno; RTOKEN(NEWLINE); }
<MRI>"\r" { ++ lineno; RTOKEN(NEWLINE); } <MRI>"\r" { ++ lineno; RTOKEN(NEWLINE); }
<MRI>"*".* { /* Mri comment line */ } <MRI>"*".* { /* Mri comment line */ }
<MRI>";".* { /* Mri comment line */ }
<MRI>"END" { RTOKEN(ENDWORD); } <MRI>"END" { RTOKEN(ENDWORD); }
<MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);} <MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);}
<MRI>"ALIGN" { RTOKEN(ALIGN_K);} <MRI>"ALIGN" { RTOKEN(ALIGN_K);}
<MRI>"CHIP" { RTOKEN(CHIP); } <MRI>"CHIP" { RTOKEN(CHIP); }
<MRI>"BASE" { RTOKEN(BASE); } <MRI>"BASE" { RTOKEN(BASE); }
<MRI>"ALIAS" { RTOKEN(ALIAS); } <MRI>"ALIAS" { RTOKEN(ALIAS); }
@ -271,15 +286,27 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
<MRI>"ORDER" { RTOKEN(ORDER); } <MRI>"ORDER" { RTOKEN(ORDER); }
<MRI>"NAME" { RTOKEN(NAMEWORD); } <MRI>"NAME" { RTOKEN(NAMEWORD); }
<MRI>"FORMAT" { RTOKEN(FORMAT); } <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>"LIST".* { RTOKEN(LIST); /* LIST and ignore to end of line */ }
<MRI>"SECT" { RTOKEN(SECT); } <MRI>"SECT" { RTOKEN(SECT); }
<EXPRESSION,BOTH,SCRIPT,MRI>"ABSOLUTE" { RTOKEN(ABSOLUTE); } <EXPRESSION,BOTH,SCRIPT,MRI>"ABSOLUTE" { RTOKEN(ABSOLUTE); }
<MRI>"end" { RTOKEN(ENDWORD); } <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>"order" { RTOKEN(ORDER); }
<MRI>"name" { RTOKEN(NAMEWORD); } <MRI>"name" { RTOKEN(NAMEWORD); }
<MRI>"format" { RTOKEN(FORMAT); } <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>"list".* { RTOKEN(LIST); /* LIST and ignore to end of line */ }
<MRI>"sect" { RTOKEN(SECT); } <MRI>"sect" { RTOKEN(SECT); }
<EXPRESSION,BOTH,SCRIPT,MRI>"absolute" { RTOKEN(ABSOLUTE); } <EXPRESSION,BOTH,SCRIPT,MRI>"absolute" { RTOKEN(ABSOLUTE); }
@ -295,9 +322,11 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
yylval.name = buystring(yytext); yylval.name = buystring(yytext);
return NAME; return NAME;
} }
<SCRIPT>{FILENAMECHAR}* { yylval.name = buystring(yytext); <BOTH,EXPRESSION>"-l"{FILENAMECHAR}+ {
return NAME; yylval.name = buystring (yytext + 2);
return LNAME;
} }
<SCRIPT>{WILDCHAR}* { yylval.name = buystring(yytext); return NAME; }
<EXPRESSION,BOTH,SCRIPT>"\""[^\"]*"\"" { <EXPRESSION,BOTH,SCRIPT>"\""[^\"]*"\"" {
/* No matter the state, quotes /* 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 void
lex_push_file (file, name) lex_push_file (file, name)
FILE *file; FILE *file;
char *name; const char *name;
{ {
if (include_stack_ptr >= MAX_INCLUDE_DEPTH) if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
{ {
einfo("%F:includes nested too deeply\n"); einfo("%F:includes nested too deeply\n");
} }
file_name_stack[include_stack_ptr] = name; file_name_stack[include_stack_ptr] = name;
lineno_stack[include_stack_ptr] = 1;
include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
include_stack_ptr++; 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 /* yy_ch_buf has to be 2 characters longer than the size given because
we need to put in 2 end-of-buffer characters. */ 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'; b->yy_ch_buf[0] = '\n';
strcpy (b->yy_ch_buf+1, string); 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_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR;
b->yy_n_chars = size+1; b->yy_n_chars = size+1;
b->yy_buf_pos = &b->yy_ch_buf[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"); einfo("%F: macros nested too deeply\n");
} }
file_name_stack[include_stack_ptr] = "redirect"; file_name_stack[include_stack_ptr] = "redirect";
lineno_stack[include_stack_ptr] = 0;
include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
include_stack_ptr++; include_stack_ptr++;
tmp = yy_create_string_buffer (string, strlen (string)); tmp = yy_create_string_buffer (string, strlen (string));
@ -520,7 +559,23 @@ static void
lex_warn_invalid (where, what) lex_warn_invalid (where, what)
char *where, *what; char *where, *what;
{ {
fprintf(stderr, char buf[5];
"%s: ignoring invalid character `%s'%s\n",
program_name, what, where); /* 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);
} }