* 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
emulparams
emultempl
fnmatch.c
fnmatch.h
genscripts.sh
h8-doc.texi
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
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 \
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 \
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 \
ldfile.o ldcref.o ${EMULATION_OFILES}
ldfile.o ldcref.o fnmatch.o ${EMULATION_OFILES}
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 \
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 \
@ -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 \
$(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
@ -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
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 \

32
ld/NEWS
View File

@ -1,5 +1,25 @@
-*- 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
@ -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
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

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
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}
@ -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
whitespace.
whitespace.
@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
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:
@ -1995,6 +2023,24 @@ SECTIONS @{
@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

View File

@ -1,5 +1,5 @@
/* 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.
@ -43,7 +43,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define YYDEBUG 1
#endif
static int typebits;
static enum section_type sectype;
lang_memory_region_type *region;
@ -68,14 +68,22 @@ static int error_index;
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 <phdr> phdr_qualifiers
%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> '('
%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
@ -108,7 +116,7 @@ static int error_index;
%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
@ -136,12 +144,15 @@ defsym_expr:
/* 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
{ 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); }
| ALIGN_K NAME ',' exp
{ mri_align($2,$4); }
| ALIGNMOD NAME '=' exp
{ mri_alignmod($2,$4); }
| ALIGNMOD NAME ',' exp
{ mri_alignmod($2,$4); }
| ABSOLUTE mri_abs_name_list
| LOAD mri_load_name_list
| NAMEWORD NAME
@ -196,7 +211,7 @@ mri_script_command:
| 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
| phdrs
| startup
| high_level_library
| low_level_library
@ -318,15 +334,25 @@ sec_or_group_p1:
statement_anywhere:
ENTRY '(' NAME ')'
{ lang_add_entry ($3, 0); }
{ lang_add_entry ($3, false); }
| assignment end
;
/* The '*' and '?' cases are there because the lexer returns them as
separate tokens rather than as 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
{ 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:
@ -342,7 +368,14 @@ input_section_spec:
']'
| 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 ')'
| '*'
@ -365,12 +398,12 @@ statement:
lang_add_attribute(lang_constructors_statement_enum);
}
| input_section_spec
| length '(' exp ')'
| length '(' mustbe_exp ')'
{
lang_add_data((int) $1,$3);
}
| FILL '(' exp ')'
| FILL '(' mustbe_exp ')'
{
lang_add_fill
(exp_get_value_int($3,
@ -623,36 +656,57 @@ opt_at:
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
'}' {ldlex_expression();} memspec_opt fill_opt
'}' { ldlex_popstate (); ldlex_expression (); }
memspec_opt phdr_opt fill_opt
{
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:
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:
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:
@ -660,6 +714,99 @@ memspec_opt:
{ $$ = $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)

View 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 "fnmatch.h"
/* 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));
static void exp_init_os PARAMS ((etree_type *));
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,
@ -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 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,
@ -283,7 +289,6 @@ new_afile (name, file_type, target, add_to_list)
lang_has_input_file = true;
p->target = target;
p->complained = false;
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->common_output_section = (asection *) NULL;
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->loadable = 1;
lookup->sectype = normal_section;
lookup->addr_tree = (etree_type *) NULL;
lang_list_init (&lookup->children);
@ -543,15 +547,17 @@ lang_map ()
print_statements ();
}
/*
*
*/
/* Initialize an output section. */
static void
init_os (s)
lang_output_section_statement_type * s;
lang_output_section_statement_type *s;
{
section_userdata_type *new;
if (s->bfd_section != NULL)
return;
if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
einfo ("%P%F: Illegal use of `%s' section", DISCARD_SECTION_NAME);
@ -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;
/* 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
@ -661,6 +720,23 @@ section_already_linked (abfd, sec, ignore)
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. */
@ -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
the embedded SEC_NEVER_LOAD section into a fill. */
section->output_section->flags |=
section->flags & (flagword) (~ SEC_NEVER_LOAD);
the embedded SEC_NEVER_LOAD section into a fill.
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_NEVER_LOAD;
break;
}
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;
boolean wildcard;
if (section == NULL)
wildcard = false;
else
wildcard = wildcardp (section);
for (s = file->the_bfd->sections; s != NULL; s = s->next)
{
boolean match;
/* Attach all sections named SECTION. If SECTION is NULL,
then attach all sections.
@ -769,9 +871,19 @@ wild_section (ptr, section, file, output)
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);
}
}
@ -922,6 +1034,44 @@ load_symbols (entry, place)
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
@ -944,40 +1094,24 @@ wild (s, section, file, target, output)
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);
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
@ -1016,7 +1150,7 @@ open_output (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;*/
@ -1089,7 +1223,8 @@ open_input_bfds (s, force)
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;
@ -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_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_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;
@ -1594,7 +1737,7 @@ print_padding_statement (s)
minfo ("0x%V %W", addr, s->size);
if (s->fill != 0)
minfo (" 0x%x", s->fill);
minfo (" %u", s->fill);
print_nl ();
@ -1746,7 +1889,7 @@ dprint_statement (s, n)
print_statement_list (s, abs_output_section);
else
{
while (--n >= 0)
while (s && --n >= 0)
{
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;
}
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
&& ! 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");
#endif
default_common_section =
lang_output_section_statement_lookup (".bss");
@ -2815,13 +2961,14 @@ topower (x)
return 0;
}
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;
int flags;
enum section_type sectype;
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->flags = flags;
if (flags & SEC_NEVER_LOAD)
os->loadable = 0;
os->sectype = sectype;
if (sectype != noload_section)
os->flags = SEC_NO_FLAGS;
else
os->loadable = 1;
os->flags = SEC_NEVER_LOAD;
os->block_value = block_value ? block_value : 1;
stat_ptr = &os->children;
@ -3404,7 +3551,7 @@ lang_record_phdrs ()
last = pl;
else
{
if (! os->loadable
if (os->sectype == noload_section
|| os->bfd_section == NULL
|| (os->bfd_section->flags & SEC_ALLOC) == 0)
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.
@ -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
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
@ -26,12 +26,13 @@ This was written by steve chamberlain
#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 */
/* end-sanitize-mpw */
#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;
/* The string we are currently lexing, or NULL if we are reading a
file. */
const char *lex_string = NULL;
/* Support for flex reading from more than one input file (stream).
`include_stack' is flex's input state for each open file;
`file_name_stack' is the file names.
`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. */
@ -66,7 +72,8 @@ unsigned int lineno = 1;
#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,
@ -99,7 +106,7 @@ CMDFILENAMECHAR1 [_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\/\.\-\_\+\$\:\[\]\\\~]
@ -139,23 +146,27 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
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':
case 'x':
case 'H':
case 'h':
ibase = 16;
break;
case 'O':
case 'o':
ibase = 8;
break;
case 'B':
case 'b':
ibase = 2;
break;
default:
ibase = 10;
}
yylval.integer = bfd_scan_vma (yytext+1, 0,
yylval.integer = bfd_scan_vma (yytext, 0,
ibase);
return INT;
}
@ -172,47 +183,48 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
}
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>"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);}
@ -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);}
<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);}
@ -243,25 +256,27 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
<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>"PHDRS" { RTOKEN (PHDRS); }
<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>";".* { /* Mri comment line */ }
<MRI>"END" { RTOKEN(ENDWORD); }
<MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);}
<MRI>"ALIGN" { RTOKEN(ALIGN_K);}
<MRI>"CHIP" { RTOKEN(CHIP); }
<MRI>"BASE" { RTOKEN(BASE); }
<MRI>"ALIAS" { RTOKEN(ALIAS); }
@ -271,15 +286,27 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
<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>"alignmod" { RTOKEN(ALIGNMOD);}
<MRI>"align" { RTOKEN(ALIGN_K);}
<MRI>"chip" { RTOKEN(CHIP); }
<MRI>"base" { RTOKEN(BASE); }
<MRI>"alias" { RTOKEN(ALIAS); }
<MRI>"truncate" { RTOKEN(TRUNCATE); }
<MRI>"load" { RTOKEN(LOAD); }
<MRI>"public" { RTOKEN(PUBLIC); }
<MRI>"order" { RTOKEN(ORDER); }
<MRI>"name" { RTOKEN(NAMEWORD); }
<MRI>"format" { RTOKEN(FORMAT); }
<MRI>"case" { RTOKEN(CASE); }
<MRI>"extern" { RTOKEN(EXTERN); }
<MRI>"start" { RTOKEN(START); }
<MRI>"list".* { RTOKEN(LIST); /* LIST and ignore to end of line */ }
<MRI>"sect" { RTOKEN(SECT); }
<EXPRESSION,BOTH,SCRIPT,MRI>"absolute" { RTOKEN(ABSOLUTE); }
@ -295,9 +322,11 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
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
@ -323,7 +352,8 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
}
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;
}
@ -340,13 +370,14 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
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;
lineno_stack[include_stack_ptr] = 1;
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. */
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);
@ -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];
/* flex 2.4.7 changed the interface. FIXME: We should not be using
a flex internal interface in the first place! */
#ifdef YY_BUFFER_NEW
b->yy_buffer_status = YY_BUFFER_NEW;
#else
b->yy_eof_status = EOF_NOT_SEEN;
#endif
return b;
}
@ -400,6 +438,7 @@ lex_redirect (string)
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));
@ -520,7 +559,23 @@ static void
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);
}