Line 111... |
Line 111... |
|
|
%}
|
%}
|
|
|
%union {
|
%union {
|
char *id;
|
char *id;
|
|
const char *id_const;
|
int number;
|
int number;
|
char *digits;
|
char *digits;
|
};
|
};
|
|
|
%token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
|
%token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
|
Line 125... |
Line 126... |
%token DIGITS
|
%token DIGITS
|
%type NUMBER
|
%type NUMBER
|
%type opt_digits
|
%type opt_digits
|
%type opt_base opt_ordinal
|
%type opt_base opt_ordinal
|
%type attr attr_list opt_number exp_opt_list exp_opt
|
%type attr attr_list opt_number exp_opt_list exp_opt
|
%type opt_name opt_equal_name dot_name anylang_id opt_id
|
%type opt_name opt_name2 opt_equal_name anylang_id opt_id
|
%type opt_equalequal_name
|
%type opt_equalequal_name
|
|
%type keyword_as_name
|
|
|
%%
|
%%
|
|
|
start: start command
|
start: start command
|
| command
|
| command
|
Line 162... |
Line 164... |
|
|
expline:
|
expline:
|
/* The opt_comma is necessary to support both the usual
|
/* The opt_comma is necessary to support both the usual
|
DEF file syntax as well as .drectve syntax which
|
DEF file syntax as well as .drectve syntax which
|
mandates ,. */
|
mandates ,. */
|
dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
|
opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
|
{ def_exports ($1, $2, $3, $5, $7); }
|
{ def_exports ($1, $2, $3, $5, $7); }
|
;
|
;
|
exp_opt_list:
|
exp_opt_list:
|
/* The opt_comma is necessary to support both the usual
|
/* The opt_comma is necessary to support both the usual
|
DEF file syntax as well as .drectve syntax which
|
DEF file syntax as well as .drectve syntax which
|
Line 232... |
Line 234... |
| WRITE { $$ = 2;}
|
| WRITE { $$ = 2;}
|
| EXECUTE { $$=4;}
|
| EXECUTE { $$=4;}
|
| SHARED { $$=8;}
|
| SHARED { $$=8;}
|
;
|
;
|
|
|
opt_name: ID { $$ = $1; }
|
|
| '.' ID
|
keyword_as_name: BASE { $$ = "BASE"; }
|
|
| CODE { $$ = "CODE"; }
|
|
| CONSTANTU { $$ = "CONSTANT"; }
|
|
| CONSTANTL { $$ = "constant"; }
|
|
| DATAU { $$ = "DATA"; }
|
|
| DATAL { $$ = "data"; }
|
|
| DESCRIPTION { $$ = "DESCRIPTION"; }
|
|
| DIRECTIVE { $$ = "DIRECTIVE"; }
|
|
| EXECUTE { $$ = "EXECUTE"; }
|
|
| EXPORTS { $$ = "EXPORTS"; }
|
|
| HEAPSIZE { $$ = "HEAPSIZE"; }
|
|
| IMPORTS { $$ = "IMPORTS"; }
|
|
/* Disable LIBRARY keyword as valid symbol-name. This is necessary
|
|
for libtool, which places this command after EXPORTS command.
|
|
This behavior is illegal by specification, but sadly required by
|
|
by compatibility reasons.
|
|
See PR binutils/13710
|
|
| LIBRARY { $$ = "LIBRARY"; } */
|
|
| NAME { $$ = "NAME"; }
|
|
| NONAMEU { $$ = "NONAME"; }
|
|
| NONAMEL { $$ = "noname"; }
|
|
| PRIVATEU { $$ = "PRIVATE"; }
|
|
| PRIVATEL { $$ = "private"; }
|
|
| READ { $$ = "READ"; }
|
|
| SHARED { $$ = "SHARED"; }
|
|
| STACKSIZE_K { $$ = "STACKSIZE"; }
|
|
| VERSIONK { $$ = "VERSION"; }
|
|
| WRITE { $$ = "WRITE"; }
|
|
;
|
|
|
|
opt_name2: ID { $$ = $1; }
|
|
| '.' keyword_as_name
|
|
{
|
|
char *name = xmalloc (strlen ($2) + 2);
|
|
sprintf (name, ".%s", $2);
|
|
$$ = name;
|
|
}
|
|
| '.' opt_name2
|
{
|
{
|
char *name = def_pool_alloc (strlen ($2) + 2);
|
char *name = def_pool_alloc (strlen ($2) + 2);
|
sprintf (name, ".%s", $2);
|
sprintf (name, ".%s", $2);
|
$$ = name;
|
$$ = name;
|
}
|
}
|
| ID '.' ID
|
| keyword_as_name '.' opt_name2
|
{
|
{
|
char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
|
char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
|
sprintf (name, "%s.%s", $1, $3);
|
sprintf (name, "%s.%s", $1, $3);
|
$$ = name;
|
$$ = name;
|
}
|
}
|
|
| ID '.' opt_name2
|
|
{
|
|
char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
|
|
sprintf (name, "%s.%s", $1, $3);
|
|
$$ = name;
|
|
}
|
|
;
|
|
|
|
opt_name: opt_name2 { $$ = $1; }
|
| { $$ = ""; }
|
| { $$ = ""; }
|
;
|
;
|
|
|
opt_equalequal_name: EQUAL ID { $$ = $2; }
|
opt_equalequal_name: EQUAL ID { $$ = $2; }
|
| { $$ = 0; }
|
| { $$ = 0; }
|
Line 258... |
Line 306... |
'@' NUMBER { $$ = $2;}
|
'@' NUMBER { $$ = $2;}
|
| { $$ = -1;}
|
| { $$ = -1;}
|
;
|
;
|
|
|
opt_equal_name:
|
opt_equal_name:
|
'=' dot_name { $$ = $2; }
|
'=' opt_name2 { $$ = $2; }
|
| { $$ = 0; }
|
| { $$ = 0; }
|
;
|
;
|
|
|
opt_base: BASE '=' NUMBER { $$ = $3;}
|
opt_base: BASE '=' NUMBER { $$ = $3;}
|
| { $$ = -1;}
|
| { $$ = -1;}
|
;
|
;
|
|
|
dot_name: ID { $$ = $1; }
|
|
| '.' ID
|
|
{
|
|
char *name = def_pool_alloc (strlen ($2) + 2);
|
|
sprintf (name, ".%s", $2);
|
|
$$ = name;
|
|
}
|
|
| dot_name '.' ID
|
|
{
|
|
char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
|
|
sprintf (name, "%s.%s", $1, $3);
|
|
$$ = name;
|
|
}
|
|
;
|
|
|
|
anylang_id: ID { $$ = $1; }
|
anylang_id: ID { $$ = $1; }
|
| '.' ID
|
| '.' ID
|
{
|
{
|
char *id = def_pool_alloc (strlen ($2) + 2);
|
char *id = def_pool_alloc (strlen ($2) + 2);
|
sprintf (id, ".%s", $2);
|
sprintf (id, ".%s", $2);
|
Line 592... |
Line 625... |
|
|
*is_ident = 0;
|
*is_ident = 0;
|
if (!max)
|
if (!max)
|
return 0;
|
return 0;
|
if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
|
if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
|
|
{
|
|
if (!e)
|
|
*is_ident = 1;
|
return 0;
|
return 0;
|
|
}
|
if (max == 1)
|
if (max == 1)
|
return 1;
|
return 1;
|
if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
|
if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
|
return max;
|
return max;
|
else if (!e || max == 2)
|
else if (!e || max == 2)
|
|
{
|
|
if (!e)
|
|
*is_ident = 1;
|
return max - 1;
|
return max - 1;
|
|
}
|
l = 0; r = max - 1;
|
l = 0; r = max - 1;
|
while (l < r)
|
while (l < r)
|
{
|
{
|
p = (l + r) / 2;
|
p = (l + r) / 2;
|
e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
|
e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
|
Line 703... |
Line 744... |
const char *in_name, const char *module,
|
const char *in_name, const char *module,
|
int ord)
|
int ord)
|
{
|
{
|
int r;
|
int r;
|
|
|
|
if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
|
|
return r;
|
if ((r = are_names_equal (ex_name, e->name)) != 0)
|
if ((r = are_names_equal (ex_name, e->name)) != 0)
|
return r;
|
return r;
|
if ((r = are_names_equal (in_name, e->internal_name)) != 0)
|
if ((r = are_names_equal (in_name, e->internal_name)) != 0)
|
return r;
|
return r;
|
if (ord != e->ordinal)
|
if (ord != e->ordinal)
|
return (ord < e->ordinal ? -1 : 1);
|
return (ord < e->ordinal ? -1 : 1);
|
return are_names_equal (module, (e->module ? e->module->name : NULL));
|
return 0;
|
}
|
}
|
|
|
/* Search the position of the identical element, or returns the position
|
/* Search the position of the identical element, or returns the position
|
of the next higher element. If last valid element is smaller, then MAX
|
of the next higher element. If last valid element is smaller, then MAX
|
is returned. */
|
is returned. */
|
Line 727... |
Line 770... |
|
|
*is_ident = 0;
|
*is_ident = 0;
|
if (!max)
|
if (!max)
|
return 0;
|
return 0;
|
if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
|
if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
|
|
{
|
|
if (!e)
|
|
*is_ident = 1;
|
return 0;
|
return 0;
|
|
}
|
if (max == 1)
|
if (max == 1)
|
return 1;
|
return 1;
|
if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
|
if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
|
return max;
|
return max;
|
else if (!e || max == 2)
|
else if (!e || max == 2)
|
|
{
|
|
if (!e)
|
|
*is_ident = 1;
|
return max - 1;
|
return max - 1;
|
|
}
|
l = 0; r = max - 1;
|
l = 0; r = max - 1;
|
while (l < r)
|
while (l < r)
|
{
|
{
|
p = (l + r) / 2;
|
p = (l + r) / 2;
|
e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
|
e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
|