%{ /* deffilep.y - parser for .def files */
-/* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
- 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.
#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);
+ 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_K HEAPSIZE CODE DATAU DATAL
%token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
-%token PRIVATEU PRIVATEL
-%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
+%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
%%
| 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_equalequal_name: EQUAL ID { $$ = $2; }
+ | { $$ = 0; }
+ ;
+
opt_ordinal:
'@' NUMBER { $$ = $2;}
| { $$ = -1;}
$$ = 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 (def->exports[i].internal_name);
if (def->exports[i].name)
free (def->exports[i].name);
+ if (def->exports[i].its_name)
+ free (def->exports[i].its_name);
}
free (def->exports);
}
free (def->imports[i].internal_name);
if (def->imports[i].name)
free (def->imports[i].name);
+ if (def->imports[i].its_name)
+ free (def->imports[i].its_name);
}
free (def->imports);
}
free (m);
}
+ while (def->aligncomms)
+ {
+ def_file_aligncomm *c = def->aligncomms;
+ def->aligncomms = def->aligncomms->next;
+ free (c->symbol_name);
+ free (c);
+ }
+
free (def);
}
def_file_add_export (def_file *def,
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);
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++;
return e;
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);
i->internal_name = xstrdup (internal_name);
else
i->internal_name = i->name;
+ i->its_name = (its_name ? xstrdup (its_name) : NULL);
def->num_imports++;
return i;
{ "-stack", STACKSIZE_K },
{ "-attr", SECTIONS },
{ "-export", EXPORTS },
+ { "-aligncomm", ALIGNCOMM },
{ 0, 0 }
};
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)
{
}
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);