%{ /* deffilep.y - parser for .def files */
-/* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+/* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
+ 2007, 2009 Free Software Foundation, Inc.
This file is part of GNU Binutils.
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 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
-#include <stdio.h>
+#include "sysdep.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "bfd.h"
-#include "sysdep.h"
#include "ld.h"
#include "ldmisc.h"
#include "deffile.h"
static void def_heapsize (int, int);
static void def_import (const char *, const char *, const char *, const char *,
int);
-static void def_library (const char *, int);
-static void def_name (const char *, int);
+static void def_image_name (const char *, int, int);
static void def_section (const char *, int);
static void def_section_alt (const char *, const char *);
static void def_stacksize (int, int);
static void def_version (int, int);
static void def_directive (char *);
+static void def_aligncomm (char *str, int align);
static int def_parse (void);
static int def_error (const char *);
static int def_lex (void);
%union {
char *id;
int number;
+ char *digits;
};
-%token NAME LIBRARY DESCRIPTION STACKSIZE HEAPSIZE CODE DATAU DATAL
+%token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
%token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
-%token PRIVATEU PRIVATEL
+%token PRIVATEU PRIVATEL ALIGNCOMM
%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
%token <id> ID
-%token <number> NUMBER
+%token <digits> DIGITS
+%type <number> NUMBER
+%type <digits> opt_digits
%type <number> opt_base opt_ordinal
%type <number> attr attr_list opt_number exp_opt_list exp_opt
-%type <id> opt_name opt_equal_name dot_name
+%type <id> opt_name opt_equal_name dot_name anylang_id opt_id
%%
;
command:
- NAME opt_name opt_base { def_name ($2, $3); }
- | LIBRARY opt_name opt_base { def_library ($2, $3); }
+ NAME opt_name opt_base { def_image_name ($2, $3, 0); }
+ | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
| DESCRIPTION ID { def_description ($2);}
- | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
+ | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
| HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
| CODE attr_list { def_section ("CODE", $2);}
| DATAU attr_list { def_section ("DATA", $2);}
| VERSIONK NUMBER { def_version ($2, 0);}
| VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
| DIRECTIVE ID { def_directive ($2);}
+ | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
;
$$ = name;
}
;
-
+
+anylang_id: ID { $$ = $1; }
+ | anylang_id '.' opt_digits opt_id
+ {
+ char *id = xmalloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
+ sprintf (id, "%s.%s%s", $1, $3, $4);
+ $$ = id;
+ }
+ ;
+
+opt_digits: DIGITS { $$ = $1; }
+ | { $$ = ""; }
+ ;
+
+opt_id: ID { $$ = $1; }
+ | { $$ = ""; }
+ ;
+
+NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
%%
free (m);
}
+ while (def->aligncomms)
+ {
+ def_file_aligncomm *c = def->aligncomms;
+ def->aligncomms = def->aligncomms->next;
+ free (c->symbol_name);
+ free (c);
+ }
+
free (def);
}
diropts[] =
{
{ "-heap", HEAPSIZE },
- { "-stack", STACKSIZE },
+ { "-stack", STACKSIZE_K },
{ "-attr", SECTIONS },
{ "-export", EXPORTS },
+ { "-aligncomm", ALIGNCOMM },
{ 0, 0 }
};
/* Parser Callbacks. */
static void
-def_name (const char *name, int base)
+def_image_name (const char *name, int base, int is_dll)
{
- if (def->name)
- free (def->name);
- def->name = xstrdup (name);
- def->base_address = base;
- def->is_dll = 0;
-}
+ /* If a LIBRARY or NAME statement is specified without a name, there is nothing
+ to do here. We retain the output filename specified on command line. */
+ if (*name)
+ {
+ const char* image_name = lbasename (name);
+ if (image_name != name)
+ einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
+ def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
+ name);
+ if (def->name)
+ free (def->name);
+ /* Append the default suffix, if none specified. */
+ if (strchr (image_name, '.') == 0)
+ {
+ const char * suffix = is_dll ? ".dll" : ".exe";
-static void
-def_library (const char *name, int base)
-{
- if (def->name)
- free (def->name);
- def->name = xstrdup (name);
+ def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
+ sprintf (def->name, "%s%s", image_name, suffix);
+ }
+ else
+ def->name = xstrdup (image_name);
+ }
+
+ /* Honor a BASE address statement, even if LIBRARY string is empty. */
def->base_address = base;
- def->is_dll = 1;
+ def->is_dll = is_dll;
}
static void
d->len = strlen (str);
}
+static void
+def_aligncomm (char *str, int align)
+{
+ def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
+
+ c->symbol_name = xstrdup (str);
+ c->alignment = (unsigned int) align;
+
+ c->next = def->aligncomms;
+ def->aligncomms = c;
+}
+
static int
def_error (const char *err)
{
{ "SECTIONS", SECTIONS },
{ "SEGMENTS", SECTIONS },
{ "SHARED", SHARED },
- { "STACKSIZE", STACKSIZE },
+ { "STACKSIZE", STACKSIZE_K },
{ "VERSION", VERSIONK },
{ "WRITE", WRITE },
{ 0, 0 }
}
if (c != EOF)
def_ungetc (c);
- yylval.number = strtoul (buffer, 0, 0);
+ yylval.digits = xstrdup (buffer);
#if TRACE
- printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
+ printf ("lex: `%s' returns DIGITS\n", buffer);
#endif
- return NUMBER;
+ return DIGITS;
}
if (ISALPHA (c) || strchr ("$:-_?@", c))