%{ /* 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"
#define yycheck def_yycheck
static void def_description (const char *);
-static void def_exports (const char *, const char *, int, int);
+static void def_exports (const char *, const char *, int, int, const char *);
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);
+ int, const char *);
+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 SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANTU, CONSTANTL
-%token PRIVATEU, PRIVATEL
-%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
+%token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
+%token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
+%token PRIVATEU PRIVATEL ALIGNCOMM
+%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
%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
+%type <id> opt_equalequal_name
%%
;
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);}
;
/* The opt_comma is necessary to support both the usual
DEF file syntax as well as .drectve syntax which
mandates <expsym>,<expoptlist>. */
- dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
- { def_exports ($1, $2, $3, $5); }
+ dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
+ { def_exports ($1, $2, $3, $5, $7); }
;
exp_opt_list:
/* The opt_comma is necessary to support both the usual
;
impline:
- ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
- | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
- | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
- | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
- | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
- | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
+ ID '=' ID '.' ID '.' ID opt_equalequal_name
+ { def_import ($1, $3, $5, $7, -1, $8); }
+ | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
+ { def_import ($1, $3, $5, 0, $7, $8); }
+ | ID '=' ID '.' ID opt_equalequal_name
+ { def_import ($1, $3, 0, $5, -1, $6); }
+ | ID '=' ID '.' NUMBER opt_equalequal_name
+ { def_import ($1, $3, 0, 0, $5, $6); }
+ | ID '.' ID '.' ID opt_equalequal_name
+ { def_import( 0, $1, $3, $5, -1, $6); }
+ | ID '.' ID opt_equalequal_name
+ { def_import ( 0, $1, 0, $3, -1, $4); }
;
seclist:
;
opt_name: ID { $$ = $1; }
+ | '.' ID
+ {
+ char *name = xmalloc (strlen ($2) + 2);
+ sprintf (name, ".%s", $2);
+ $$ = name;
+ }
| ID '.' ID
{
char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
| { $$ = ""; }
;
+opt_equalequal_name: EQUAL ID { $$ = $2; }
+ | { $$ = 0; }
+ ;
+
opt_ordinal:
'@' NUMBER { $$ = $2;}
| { $$ = -1;}
;
dot_name: ID { $$ = $1; }
+ | '.' ID
+ {
+ char *name = xmalloc (strlen ($2) + 2);
+ sprintf (name, ".%s", $2);
+ $$ = name;
+ }
| dot_name '.' ID
{
char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
$$ = name;
}
;
-
+
+anylang_id: ID { $$ = $1; }
+ | '.' ID
+ {
+ char *id = xmalloc (strlen ($2) + 2);
+ sprintf (id, ".%s", $2);
+ $$ = id;
+ }
+ | 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); }
%%
}
void
-def_file_free (def_file *def)
+def_file_free (def_file *fdef)
{
int i;
- if (!def)
+ if (!fdef)
return;
- if (def->name)
- free (def->name);
- if (def->description)
- free (def->description);
+ if (fdef->name)
+ free (fdef->name);
+ if (fdef->description)
+ free (fdef->description);
- if (def->section_defs)
+ if (fdef->section_defs)
{
- for (i = 0; i < def->num_section_defs; i++)
+ for (i = 0; i < fdef->num_section_defs; i++)
{
- if (def->section_defs[i].name)
- free (def->section_defs[i].name);
- if (def->section_defs[i].class)
- free (def->section_defs[i].class);
+ if (fdef->section_defs[i].name)
+ free (fdef->section_defs[i].name);
+ if (fdef->section_defs[i].class)
+ free (fdef->section_defs[i].class);
}
- free (def->section_defs);
+ free (fdef->section_defs);
}
- if (def->exports)
+ if (fdef->exports)
{
- for (i = 0; i < def->num_exports; i++)
+ for (i = 0; i < fdef->num_exports; i++)
{
- if (def->exports[i].internal_name
- && def->exports[i].internal_name != def->exports[i].name)
- free (def->exports[i].internal_name);
- if (def->exports[i].name)
- free (def->exports[i].name);
+ if (fdef->exports[i].internal_name
+ && fdef->exports[i].internal_name != fdef->exports[i].name)
+ free (fdef->exports[i].internal_name);
+ if (fdef->exports[i].name)
+ free (fdef->exports[i].name);
+ if (fdef->exports[i].its_name)
+ free (fdef->exports[i].its_name);
}
- free (def->exports);
+ free (fdef->exports);
}
- if (def->imports)
+ if (fdef->imports)
{
- for (i = 0; i < def->num_imports; i++)
+ for (i = 0; i < fdef->num_imports; i++)
{
- if (def->imports[i].internal_name
- && def->imports[i].internal_name != def->imports[i].name)
- free (def->imports[i].internal_name);
- if (def->imports[i].name)
- free (def->imports[i].name);
+ if (fdef->imports[i].internal_name
+ && fdef->imports[i].internal_name != fdef->imports[i].name)
+ free (fdef->imports[i].internal_name);
+ if (fdef->imports[i].name)
+ free (fdef->imports[i].name);
+ if (fdef->imports[i].its_name)
+ free (fdef->imports[i].its_name);
}
- free (def->imports);
+ free (fdef->imports);
}
- while (def->modules)
+ while (fdef->modules)
{
- def_file_module *m = def->modules;
- def->modules = def->modules->next;
+ def_file_module *m = fdef->modules;
+
+ fdef->modules = fdef->modules->next;
free (m);
}
- free (def);
+ while (fdef->aligncomms)
+ {
+ def_file_aligncomm *c = fdef->aligncomms;
+
+ fdef->aligncomms = fdef->aligncomms->next;
+ free (c->symbol_name);
+ free (c);
+ }
+
+ free (fdef);
}
#ifdef DEF_FILE_PRINT
void
-def_file_print (FILE *file, def_file *def)
+def_file_print (FILE *file, def_file *fdef)
{
int i;
- fprintf (file, ">>>> def_file at 0x%08x\n", def);
- if (def->name)
- fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
- if (def->is_dll != -1)
- fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
- if (def->base_address != (bfd_vma) -1)
- fprintf (file, " base address: 0x%08x\n", def->base_address);
- if (def->description)
- fprintf (file, " description: `%s'\n", def->description);
- if (def->stack_reserve != -1)
- fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
- if (def->stack_commit != -1)
- fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
- if (def->heap_reserve != -1)
- fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
- if (def->heap_commit != -1)
- fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
-
- if (def->num_section_defs > 0)
+ fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
+ if (fdef->name)
+ fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
+ if (fdef->is_dll != -1)
+ fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
+ if (fdef->base_address != (bfd_vma) -1)
+ fprintf (file, " base address: 0x%08x\n", fdef->base_address);
+ if (fdef->description)
+ fprintf (file, " description: `%s'\n", fdef->description);
+ if (fdef->stack_reserve != -1)
+ fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
+ if (fdef->stack_commit != -1)
+ fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
+ if (fdef->heap_reserve != -1)
+ fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
+ if (fdef->heap_commit != -1)
+ fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
+
+ if (fdef->num_section_defs > 0)
{
fprintf (file, " section defs:\n");
- for (i = 0; i < def->num_section_defs; i++)
+ for (i = 0; i < fdef->num_section_defs; i++)
{
fprintf (file, " name: `%s', class: `%s', flags:",
- def->section_defs[i].name, def->section_defs[i].class);
- if (def->section_defs[i].flag_read)
+ fdef->section_defs[i].name, fdef->section_defs[i].class);
+ if (fdef->section_defs[i].flag_read)
fprintf (file, " R");
- if (def->section_defs[i].flag_write)
+ if (fdef->section_defs[i].flag_write)
fprintf (file, " W");
- if (def->section_defs[i].flag_execute)
+ if (fdef->section_defs[i].flag_execute)
fprintf (file, " X");
- if (def->section_defs[i].flag_shared)
+ if (fdef->section_defs[i].flag_shared)
fprintf (file, " S");
fprintf (file, "\n");
}
}
- if (def->num_exports > 0)
+ if (fdef->num_exports > 0)
{
fprintf (file, " exports:\n");
- for (i = 0; i < def->num_exports; i++)
+ for (i = 0; i < fdef->num_exports; i++)
{
fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
- def->exports[i].name, def->exports[i].internal_name,
- def->exports[i].ordinal);
- if (def->exports[i].flag_private)
+ fdef->exports[i].name, fdef->exports[i].internal_name,
+ fdef->exports[i].ordinal);
+ if (fdef->exports[i].flag_private)
fprintf (file, " P");
- if (def->exports[i].flag_constant)
+ if (fdef->exports[i].flag_constant)
fprintf (file, " C");
- if (def->exports[i].flag_noname)
+ if (fdef->exports[i].flag_noname)
fprintf (file, " N");
- if (def->exports[i].flag_data)
+ if (fdef->exports[i].flag_data)
fprintf (file, " D");
fprintf (file, "\n");
}
}
- if (def->num_imports > 0)
+ if (fdef->num_imports > 0)
{
fprintf (file, " imports:\n");
- for (i = 0; i < def->num_imports; i++)
+ for (i = 0; i < fdef->num_imports; i++)
{
fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
- def->imports[i].internal_name,
- def->imports[i].module,
- def->imports[i].name,
- def->imports[i].ordinal);
+ fdef->imports[i].internal_name,
+ fdef->imports[i].module,
+ fdef->imports[i].name,
+ fdef->imports[i].ordinal);
}
}
- if (def->version_major != -1)
- fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
+ if (fdef->version_major != -1)
+ fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
- fprintf (file, "<<<< def_file at 0x%08x\n", def);
+ fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
}
#endif
def_file_export *
-def_file_add_export (def_file *def,
+def_file_add_export (def_file *fdef,
const char *external_name,
const char *internal_name,
- int ordinal)
+ int ordinal,
+ const char *its_name)
{
def_file_export *e;
- int max_exports = ROUND_UP(def->num_exports, 32);
+ int max_exports = ROUND_UP(fdef->num_exports, 32);
- if (def->num_exports >= max_exports)
+ if (fdef->num_exports >= max_exports)
{
- max_exports = ROUND_UP(def->num_exports + 1, 32);
- if (def->exports)
- def->exports = xrealloc (def->exports,
+ max_exports = ROUND_UP(fdef->num_exports + 1, 32);
+ if (fdef->exports)
+ fdef->exports = xrealloc (fdef->exports,
max_exports * sizeof (def_file_export));
else
- def->exports = xmalloc (max_exports * sizeof (def_file_export));
+ fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
}
- e = def->exports + def->num_exports;
+ e = fdef->exports + fdef->num_exports;
memset (e, 0, sizeof (def_file_export));
if (internal_name && !external_name)
external_name = internal_name;
internal_name = external_name;
e->name = xstrdup (external_name);
e->internal_name = xstrdup (internal_name);
+ e->its_name = (its_name ? xstrdup (its_name) : NULL);
e->ordinal = ordinal;
- def->num_exports++;
+ fdef->num_exports++;
return e;
}
def_file_module *
-def_get_module (def_file *def, const char *name)
+def_get_module (def_file *fdef, const char *name)
{
def_file_module *s;
- for (s = def->modules; s; s = s->next)
+ for (s = fdef->modules; s; s = s->next)
if (strcmp (s->name, name) == 0)
return s;
}
static def_file_module *
-def_stash_module (def_file *def, const char *name)
+def_stash_module (def_file *fdef, const char *name)
{
def_file_module *s;
- if ((s = def_get_module (def, name)) != NULL)
+ if ((s = def_get_module (fdef, name)) != NULL)
return s;
s = xmalloc (sizeof (def_file_module) + strlen (name));
- s->next = def->modules;
- def->modules = s;
+ s->next = fdef->modules;
+ fdef->modules = s;
s->user_data = 0;
strcpy (s->name, name);
return s;
}
def_file_import *
-def_file_add_import (def_file *def,
+def_file_add_import (def_file *fdef,
const char *name,
const char *module,
int ordinal,
- const char *internal_name)
+ const char *internal_name,
+ const char *its_name)
{
def_file_import *i;
- int max_imports = ROUND_UP (def->num_imports, 16);
+ int max_imports = ROUND_UP (fdef->num_imports, 16);
- if (def->num_imports >= max_imports)
+ if (fdef->num_imports >= max_imports)
{
- max_imports = ROUND_UP (def->num_imports+1, 16);
+ max_imports = ROUND_UP (fdef->num_imports+1, 16);
- if (def->imports)
- def->imports = xrealloc (def->imports,
+ if (fdef->imports)
+ fdef->imports = xrealloc (fdef->imports,
max_imports * sizeof (def_file_import));
else
- def->imports = xmalloc (max_imports * sizeof (def_file_import));
+ fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
}
- i = def->imports + def->num_imports;
+ i = fdef->imports + fdef->num_imports;
memset (i, 0, sizeof (def_file_import));
if (name)
i->name = xstrdup (name);
if (module)
- i->module = def_stash_module (def, module);
+ i->module = def_stash_module (fdef, module);
i->ordinal = ordinal;
if (internal_name)
i->internal_name = xstrdup (internal_name);
else
i->internal_name = i->name;
- def->num_imports++;
+ i->its_name = (its_name ? xstrdup (its_name) : NULL);
+ fdef->num_imports++;
return i;
}
diropts[] =
{
{ "-heap", HEAPSIZE },
- { "-stack", STACKSIZE },
+ { "-stack", STACKSIZE_K },
{ "-attr", SECTIONS },
{ "-export", EXPORTS },
+ { "-aligncomm", ALIGNCOMM },
{ 0, 0 }
};
for (i = 0; diropts[i].param; i++)
{
- int len = strlen (diropts[i].param);
+ len = strlen (diropts[i].param);
if (tend - param >= len
&& strncmp (param, diropts[i].param, len) == 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
def_exports (const char *external_name,
const char *internal_name,
int ordinal,
- int flags)
+ int flags,
+ const char *its_name)
{
def_file_export *dfe;
printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
#endif
- dfe = def_file_add_export (def, external_name, internal_name, ordinal);
+ dfe = def_file_add_export (def, external_name, internal_name, ordinal,
+ its_name);
if (flags & 1)
dfe->flag_noname = 1;
if (flags & 2)
const char *module,
const char *dllext,
const char *name,
- int ordinal)
+ int ordinal,
+ const char *its_name)
{
char *buf = 0;
const char *ext = dllext ? dllext : "dll";
sprintf (buf, "%s.%s", module, ext);
module = buf;
- def_file_add_import (def, name, module, ordinal, internal_name);
+ def_file_add_import (def, name, module, ordinal, internal_name, its_name);
if (buf)
free (buf);
}
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))
#endif
}
- while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
+ while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
{
put_buf (c);
c = def_getc ();
return ID;
}
- if (c == '=' || c == '.' || c == ',')
+ if ( c == '=')
+ {
+ c = def_getc ();
+ if (c == '=')
+ {
+#if TRACE
+ printf ("lex: `==' returns EQUAL\n");
+#endif
+ return EQUAL;
+ }
+ def_ungetc (c);
+#if TRACE
+ printf ("lex: `=' returns itself\n");
+#endif
+ return '=';
+ }
+ if (c == '.' || c == ',')
{
#if TRACE
printf ("lex: `%c' returns itself\n", c);