%{ /* deffilep.y - parser for .def files */
-/* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
- 2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2019 Free Software Foundation, Inc.
This file is part of GNU Binutils.
#include "libiberty.h"
#include "safe-ctype.h"
#include "bfd.h"
+#include "bfdlink.h"
#include "ld.h"
#include "ldmisc.h"
#include "deffile.h"
#define yylval def_lval
#define yychar def_char
#define yydebug def_debug
-#define yypact def_pact
-#define yyr1 def_r1
-#define yyr2 def_r2
-#define yydef def_def
-#define yychk def_chk
-#define yypgo def_pgo
-#define yyact def_act
+#define yypact def_pact
+#define yyr1 def_r1
+#define yyr2 def_r2
+#define yydef def_def
+#define yychk def_chk
+#define yypgo def_pgo
+#define yyact def_act
#define yyexca def_exca
#define yyerrflag def_errflag
#define yynerrs def_nerrs
static void def_heapsize (int, int);
static void def_import (const char *, const char *, const char *, const char *,
int, const char *);
-static void def_image_name (const char *, int, int);
+static void def_image_name (const char *, bfd_vma, int);
static void def_section (const char *, int);
static void def_section_alt (const char *, const char *);
static void def_stacksize (int, int);
char *id;
const char *id_const;
int number;
+ bfd_vma vma;
char *digits;
};
%token <id> ID
%token <digits> DIGITS
%type <number> NUMBER
+%type <vma> VMA opt_base
%type <digits> opt_digits
-%type <number> opt_base opt_ordinal
+%type <number> opt_ordinal
%type <number> attr attr_list opt_number exp_opt_list exp_opt
%type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
%type <id> opt_equalequal_name
| command
;
-command:
+command:
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);}
| CODE attr_list { def_section ("CODE", $2);}
| DATAU attr_list { def_section ("DATA", $2);}
| SECTIONS seclist
- | EXPORTS explist
+ | EXPORTS explist
| IMPORTS implist
| VERSIONK NUMBER { def_version ($2, 0);}
| VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
| PRIVATEU { $$ = 8; }
| PRIVATEL { $$ = 8; }
;
-implist:
+implist:
implist impline
| impline
;
impline:
- ID '=' ID '.' ID '.' ID opt_equalequal_name
- { def_import ($1, $3, $5, $7, -1, $8); }
+ 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); }
+ { def_import ($1, $3, 0, $5, -1, $6); }
| ID '=' ID '.' NUMBER opt_equalequal_name
- { def_import ($1, $3, 0, 0, $5, $6); }
+ { def_import ($1, $3, 0, 0, $5, $6); }
| ID '.' ID '.' ID opt_equalequal_name
- { def_import( 0, $1, $3, $5, -1, $6); }
+ { def_import( 0, $1, $3, $5, -1, $6); }
| ID '.' ID opt_equalequal_name
- { def_import ( 0, $1, 0, $3, -1, $4); }
+ { def_import ( 0, $1, 0, $3, -1, $4); }
;
seclist:
opt_comma:
','
- |
+ |
;
opt_number: ',' NUMBER { $$=$2;}
| { $$=-1;}
;
-
+
attr:
READ { $$ = 1;}
- | WRITE { $$ = 2;}
+ | WRITE { $$ = 2;}
| EXECUTE { $$=4;}
| SHARED { $$=8;}
;
$$ = name;
}
| '.' opt_name2
- {
+ {
char *name = def_pool_alloc (strlen ($2) + 2);
sprintf (name, ".%s", $2);
$$ = name;
}
| keyword_as_name '.' opt_name2
- {
+ {
char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
sprintf (name, "%s.%s", $1, $3);
$$ = name;
}
| ID '.' opt_name2
- {
+ {
char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
sprintf (name, "%s.%s", $1, $3);
$$ = name;
| { $$ = 0; }
;
-opt_ordinal:
+opt_ordinal:
'@' NUMBER { $$ = $2;}
| { $$ = -1;}
;
opt_equal_name:
- '=' opt_name2 { $$ = $2; }
- | { $$ = 0; }
+ '=' opt_name2 { $$ = $2; }
+ | { $$ = 0; }
;
-opt_base: BASE '=' NUMBER { $$ = $3;}
- | { $$ = -1;}
+opt_base: BASE '=' VMA { $$ = $3;}
+ | { $$ = (bfd_vma) -1;}
;
anylang_id: ID { $$ = $1; }
;
NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
+ ;
+VMA: DIGITS { $$ = (bfd_vma) strtoull ($1, 0, 0); }
%%
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);
+ {
+ fprintf (file, " base address: 0x");
+ fprintf_vma (file, fdef->base_address);
+ fprintf (file, "\n");
+ }
if (fdef->description)
fprintf (file, " description: `%s'\n", fdef->description);
if (fdef->stack_reserve != -1)
if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
{
if (!e)
- *is_ident = 1;
+ *is_ident = 1;
return 0;
}
if (max == 1)
p = (l + r) / 2;
e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
if (!e)
- {
- *is_ident = 1;
- return p;
- }
+ {
+ *is_ident = 1;
+ return p;
+ }
else if (e < 0)
- r = p - 1;
+ r = p - 1;
else if (e > 0)
- l = p + 1;
+ l = p + 1;
}
if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
++l;
if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
{
if (!e)
- *is_ident = 1;
+ *is_ident = 1;
return 0;
}
if (max == 1)
else if (!e || max == 2)
{
if (!e)
- *is_ident = 1;
+ *is_ident = 1;
return max - 1;
}
l = 0; r = max - 1;
p = (l + r) / 2;
e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
if (!e)
- {
- *is_ident = 1;
- return p;
- }
+ {
+ *is_ident = 1;
+ return p;
+ }
else if (e < 0)
- r = p - 1;
+ r = p - 1;
else if (e > 0)
- l = p + 1;
+ l = p + 1;
}
if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
++l;
return l;
}
+static void
+fill_in_import (def_file_import *i,
+ const char *name,
+ def_file_module *module,
+ int ordinal,
+ const char *internal_name,
+ const char *its_name)
+{
+ memset (i, 0, sizeof (def_file_import));
+ if (name)
+ i->name = xstrdup (name);
+ i->module = module;
+ i->ordinal = ordinal;
+ if (internal_name)
+ i->internal_name = xstrdup (internal_name);
+ else
+ i->internal_name = i->name;
+ i->its_name = (its_name ? xstrdup (its_name) : NULL);
+}
+
def_file_import *
def_file_add_import (def_file *fdef,
const char *name,
}
i = fdef->imports + pos;
if (pos != fdef->num_imports)
- memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
- memset (i, 0, sizeof (def_file_import));
- if (name)
- i->name = xstrdup (name);
- if (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;
- i->its_name = (its_name ? xstrdup (its_name) : NULL);
+ memmove (i + 1, i, sizeof (def_file_import) * (fdef->num_imports - pos));
+
+ fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
+ internal_name, its_name);
+ fdef->num_imports++;
+
+ return i;
+}
+
+int
+def_file_add_import_from (def_file *fdef,
+ int num_imports,
+ const char *name,
+ const char *module,
+ int ordinal,
+ const char *internal_name,
+ const char *its_name ATTRIBUTE_UNUSED)
+{
+ def_file_import *i;
+ int is_dup;
+ int pos;
+ int max_imports = ROUND_UP (fdef->num_imports, 16);
+
+ /* We need to avoid here duplicates. */
+ is_dup = 0;
+ pos = find_import_in_list (fdef->imports, fdef->num_imports,
+ name, internal_name ? internal_name : name,
+ module, ordinal, &is_dup);
+ if (is_dup != 0)
+ return -1;
+ if (fdef->imports && pos != fdef->num_imports)
+ {
+ i = fdef->imports + pos;
+ if (i->module && strcmp (i->module->name, module) == 0)
+ return -1;
+ }
+
+ if (fdef->num_imports + num_imports - 1 >= max_imports)
+ {
+ max_imports = ROUND_UP (fdef->num_imports + num_imports, 16);
+
+ if (fdef->imports)
+ fdef->imports = xrealloc (fdef->imports,
+ max_imports * sizeof (def_file_import));
+ else
+ fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
+ }
+ i = fdef->imports + pos;
+ if (pos != fdef->num_imports)
+ memmove (i + num_imports, i,
+ sizeof (def_file_import) * (fdef->num_imports - pos));
+
+ return pos;
+}
+
+def_file_import *
+def_file_add_import_at (def_file *fdef,
+ int pos,
+ const char *name,
+ const char *module,
+ int ordinal,
+ const char *internal_name,
+ const char *its_name)
+{
+ def_file_import *i = fdef->imports + pos;
+
+ fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
+ internal_name, its_name);
fdef->num_imports++;
return i;
break;
/* Scan forward until we encounter any of:
- - the end of the buffer
+ - the end of the buffer
- the start of a new option
- - a newline seperating options
- - a NUL seperating options. */
+ - a newline separating options
+ - a NUL separating options. */
for (tend = (char *) (param + 1);
(tend < pend
&& !(ISSPACE (tend[-1]) && *tend == '-')
if (!diropts[i].param)
{
- char saved;
+ if (tend < pend)
+ {
+ char saved;
- saved = * tend;
- * tend = 0;
- /* xgettext:c-format */
- einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
- * tend = saved;
+ saved = * tend;
+ * tend = 0;
+ /* xgettext:c-format */
+ einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
+ * tend = saved;
+ }
+ else
+ {
+ einfo (_("Warning: corrupt .drectve at end of def file\n"));
+ }
}
lex_parse_string = 0;
/* Parser Callbacks. */
static void
-def_image_name (const char *name, int base, int is_dll)
+def_image_name (const char *name, bfd_vma base, int is_dll)
{
/* 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. */
name);
if (def->name)
free (def->name);
- /* Append the default suffix, if none specified. */
+ /* Append the default suffix, if none specified. */
if (strchr (image_name, '.') == 0)
{
const char * suffix = is_dll ? ".dll" : ".exe";
def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
sprintf (def->name, "%s%s", image_name, suffix);
- }
+ }
else
def->name = xstrdup (image_name);
}
char *buf = 0;
const char *ext = dllext ? dllext : "dll";
int is_dup = 0;
-
+
buf = xmalloc (strlen (module) + strlen (ext) + 2);
sprintf (buf, "%s.%s", module, ext);
module = buf;
def_aligncomm (char *str, int align)
{
def_file_aligncomm *c, *p;
-
+
p = NULL;
c = def->aligncomms;
while (c != NULL)
return;
}
if (e > 0)
- break;
+ break;
c = (p = c)->next;
}
if (q == '@')
{
- if (ISBLANK (c) ) /* '@' followed by whitespace. */
+ if (ISBLANK (c) ) /* '@' followed by whitespace. */
return (q);
- else if (ISDIGIT (c)) /* '@' followed by digit. */
- {
+ else if (ISDIGIT (c)) /* '@' followed by digit. */
+ {
def_ungetc (c);
- return (q);
+ return (q);
}
#if TRACE
printf ("lex: @ returns itself\n");
def_ungetc (c);
if (ISALPHA (q)) /* Check for tokens. */
{
- for (i = 0; tokens[i].name; i++)
+ for (i = 0; tokens[i].name; i++)
if (strcmp (tokens[i].name, buffer) == 0)
{
#if TRACE
{
c = def_getc ();
if (c == '=')
- {
+ {
#if TRACE
- printf ("lex: `==' returns EQUAL\n");
+ printf ("lex: `==' returns EQUAL\n");
#endif
- return EQUAL;
- }
+ return EQUAL;
+ }
def_ungetc (c);
#if TRACE
printf ("lex: `=' returns itself\n");