1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "libiberty.h"
32 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
34 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
35 as well as gratuitiously global symbol names, so we can have multiple
36 yacc generated parsers in ld. Note that these are only the variables
37 produced by yacc. If other parser generators (bison, byacc, etc) produce
38 additional global names that conflict at link time, then those parser
39 generators need to be fixed instead of adding those names to this list. */
41 #define yymaxdepth def_maxdepth
42 #define yyparse def_parse
44 #define yyerror def_error
45 #define yylval def_lval
46 #define yychar def_char
47 #define yydebug def_debug
48 #define yypact def_pact
55 #define yyexca def_exca
56 #define yyerrflag def_errflag
57 #define yynerrs def_nerrs
61 #define yy_yys def_yys
62 #define yystate def_state
65 #define yy_yyv def_yyv
67 #define yylloc def_lloc
68 #define yyreds def_reds /* With YYDEBUG defined */
69 #define yytoks def_toks /* With YYDEBUG defined */
70 #define yylhs def_yylhs
71 #define yylen def_yylen
72 #define yydefred def_yydefred
73 #define yydgoto def_yydgoto
74 #define yysindex def_yysindex
75 #define yyrindex def_yyrindex
76 #define yygindex def_yygindex
77 #define yytable def_yytable
78 #define yycheck def_yycheck
80 static int def_lex
();
82 static void def_description PARAMS
((const char *));
83 static void def_exports PARAMS
((const char *, const char *, int, int));
84 static void def_heapsize PARAMS
((int, int));
85 static void def_import
86 PARAMS
((const char *, const char *, const char *, const char *, int));
87 static void def_library PARAMS
((const char *, int));
88 static void def_name PARAMS
((const char *, int));
89 static void def_section PARAMS
((const char *, int));
90 static void def_section_alt PARAMS
((const char *, const char *));
91 static void def_stacksize PARAMS
((int, int));
92 static void def_version PARAMS
((int, int));
93 static void def_directive PARAMS
((char *));
94 static int def_parse PARAMS
((void));
95 static int def_error PARAMS
((const char *));
96 static int def_lex PARAMS
((void));
98 static int lex_forced_token
= 0;
99 static const char *lex_parse_string
= 0;
100 static const char *lex_parse_string_end
= 0;
109 %token NAME
, LIBRARY
, DESCRIPTION
, STACKSIZE
, HEAPSIZE
, CODE
, DATAU
, DATAL
110 %token SECTIONS
, EXPORTS
, IMPORTS
, VERSIONK
, BASE
, CONSTANTU
, CONSTANTL
111 %token PRIVATEU
, PRIVATEL
112 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
114 %token
<number
> NUMBER
115 %type
<number
> opt_base opt_ordinal
116 %type
<number
> attr attr_list opt_number exp_opt_list exp_opt
117 %type
<id
> opt_name opt_equal_name
126 NAME opt_name opt_base
{ def_name
($2, $3); }
127 | LIBRARY opt_name opt_base
{ def_library
($2, $3); }
128 | DESCRIPTION ID
{ def_description
($2);}
129 | STACKSIZE NUMBER opt_number
{ def_stacksize
($2, $3);}
130 | HEAPSIZE NUMBER opt_number
{ def_heapsize
($2, $3);}
131 | CODE attr_list
{ def_section
("CODE", $2);}
132 | DATAU attr_list
{ def_section
("DATA", $2);}
136 | VERSIONK NUMBER
{ def_version
($2, 0);}
137 | VERSIONK NUMBER
'.' NUMBER
{ def_version
($2, $4);}
138 | DIRECTIVE ID
{ def_directive
($2);}
149 /* The opt_comma is necessary to support both the usual
150 DEF file syntax as well as .drectve syntax which
151 mandates <expsym>,<expoptlist>. */
152 ID opt_equal_name opt_ordinal opt_comma exp_opt_list
153 { def_exports
($1, $2, $3, $5); }
156 /* The opt_comma is necessary to support both the usual
157 DEF file syntax as well as .drectve syntax which
158 allows for comma separated opt list. */
159 exp_opt opt_comma exp_opt_list
{ $$
= $1 |
$3; }
164 | NONAMEL
{ $$
= 1; }
165 | CONSTANTU
{ $$
= 2; }
166 | CONSTANTL
{ $$
= 2; }
169 | PRIVATEU
{ $$
= 8; }
170 | PRIVATEL
{ $$
= 8; }
178 ID
'=' ID
'.' ID
'.' ID
{ def_import
($1, $3, $5, $7, -1); }
179 | ID
'=' ID
'.' ID
'.' NUMBER
{ def_import
($1, $3, $5, 0, $7); }
180 | ID
'=' ID
'.' ID
{ def_import
($1, $3, 0, $5, -1); }
181 | ID
'=' ID
'.' NUMBER
{ def_import
($1, $3, 0, 0, $5); }
182 | ID
'.' ID
'.' ID
{ def_import
( 0, $1, $3, $5, -1); }
183 | ID
'.' ID
{ def_import
( 0, $1, 0, $3, -1); }
192 ID attr_list
{ def_section
($1, $2);}
193 | ID ID
{ def_section_alt
($1, $2);}
197 attr_list opt_comma attr
{ $$
= $1 |
$3; }
205 opt_number: ',' NUMBER
{ $$
=$2;}
216 opt_name: ID
{ $$
= $1; }
221 '@' NUMBER
{ $$
= $2;}
230 opt_base: BASE
'=' NUMBER
{ $$
= $3;}
238 /*****************************************************************************
240 *****************************************************************************/
242 static FILE *the_file
;
243 static const char *def_filename
;
244 static int linenumber
;
245 static def_file
*def
;
246 static int saw_newline
;
250 struct directive
*next
;
255 static struct directive
*directives
= 0;
260 def_file
*rv
= (def_file
*) xmalloc
(sizeof
(def_file
));
261 memset
(rv
, 0, sizeof
(def_file
));
263 rv
->base_address
= (bfd_vma
) (-1);
264 rv
->stack_reserve
= rv
->stack_commit
= -1;
265 rv
->heap_reserve
= rv
->heap_commit
= -1;
266 rv
->version_major
= rv
->version_minor
= -1;
271 def_file_parse
(filename
, add_to
)
272 const char *filename
;
277 the_file
= fopen
(filename
, "r");
278 def_filename
= filename
;
291 def
= def_file_empty
();
304 for
(d
= directives
; d
; d
= d
->next
)
307 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
309 def_file_add_directive
(def
, d
->name
, d
->len
);
324 if
(def
->description
)
325 free
(def
->description
);
327 if
(def
->section_defs
)
329 for
(i
= 0; i
< def
->num_section_defs
; i
++)
331 if
(def
->section_defs
[i
].name
)
332 free
(def
->section_defs
[i
].name
);
333 if
(def
->section_defs
[i
].class
)
334 free
(def
->section_defs
[i
].class
);
336 free
(def
->section_defs
);
341 for
(i
= 0; i
< def
->num_exports
; i
++)
343 if
(def
->exports
[i
].internal_name
344 && def
->exports
[i
].internal_name
!= def
->exports
[i
].name
)
345 free
(def
->exports
[i
].internal_name
);
346 if
(def
->exports
[i
].name
)
347 free
(def
->exports
[i
].name
);
354 for
(i
= 0; i
< def
->num_imports
; i
++)
356 if
(def
->imports
[i
].internal_name
357 && def
->imports
[i
].internal_name
!= def
->imports
[i
].name
)
358 free
(def
->imports
[i
].internal_name
);
359 if
(def
->imports
[i
].name
)
360 free
(def
->imports
[i
].name
);
367 def_file_module
*m
= def
->modules
;
368 def
->modules
= def
->modules
->next
;
375 #ifdef DEF_FILE_PRINT
377 def_file_print
(file
, def
)
382 fprintf
(file
, ">>>> def_file at 0x%08x\n", def
);
384 fprintf
(file
, " name: %s\n", def
->name ? def
->name
: "(unspecified)");
385 if
(def
->is_dll
!= -1)
386 fprintf
(file
, " is dll: %s\n", def
->is_dll ?
"yes" : "no");
387 if
(def
->base_address
!= (bfd_vma
) (-1))
388 fprintf
(file
, " base address: 0x%08x\n", def
->base_address
);
389 if
(def
->description
)
390 fprintf
(file
, " description: `%s'\n", def
->description
);
391 if
(def
->stack_reserve
!= -1)
392 fprintf
(file
, " stack reserve: 0x%08x\n", def
->stack_reserve
);
393 if
(def
->stack_commit
!= -1)
394 fprintf
(file
, " stack commit: 0x%08x\n", def
->stack_commit
);
395 if
(def
->heap_reserve
!= -1)
396 fprintf
(file
, " heap reserve: 0x%08x\n", def
->heap_reserve
);
397 if
(def
->heap_commit
!= -1)
398 fprintf
(file
, " heap commit: 0x%08x\n", def
->heap_commit
);
400 if
(def
->num_section_defs
> 0)
402 fprintf
(file
, " section defs:\n");
403 for
(i
= 0; i
< def
->num_section_defs
; i
++)
405 fprintf
(file
, " name: `%s', class: `%s', flags:",
406 def
->section_defs
[i
].name
, def
->section_defs
[i
].class
);
407 if
(def
->section_defs
[i
].flag_read
)
408 fprintf
(file
, " R");
409 if
(def
->section_defs
[i
].flag_write
)
410 fprintf
(file
, " W");
411 if
(def
->section_defs
[i
].flag_execute
)
412 fprintf
(file
, " X");
413 if
(def
->section_defs
[i
].flag_shared
)
414 fprintf
(file
, " S");
415 fprintf
(file
, "\n");
419 if
(def
->num_exports
> 0)
421 fprintf
(file
, " exports:\n");
422 for
(i
= 0; i
< def
->num_exports
; i
++)
424 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
425 def
->exports
[i
].name
, def
->exports
[i
].internal_name
,
426 def
->exports
[i
].ordinal
);
427 if
(def
->exports
[i
].flag_private
)
428 fprintf
(file
, " P");
429 if
(def
->exports
[i
].flag_constant
)
430 fprintf
(file
, " C");
431 if
(def
->exports
[i
].flag_noname
)
432 fprintf
(file
, " N");
433 if
(def
->exports
[i
].flag_data
)
434 fprintf
(file
, " D");
435 fprintf
(file
, "\n");
439 if
(def
->num_imports
> 0)
441 fprintf
(file
, " imports:\n");
442 for
(i
= 0; i
< def
->num_imports
; i
++)
444 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
445 def
->imports
[i
].internal_name
,
446 def
->imports
[i
].module
,
447 def
->imports
[i
].name
,
448 def
->imports
[i
].ordinal
);
451 if
(def
->version_major
!= -1)
452 fprintf
(file
, " version: %d.%d\n", def
->version_major
, def
->version_minor
);
453 fprintf
(file
, "<<<< def_file at 0x%08x\n", def
);
458 def_file_add_export
(def
, external_name
, internal_name
, ordinal
)
460 const char *external_name
;
461 const char *internal_name
;
465 int max_exports
= ROUND_UP
(def
->num_exports
, 32);
466 if
(def
->num_exports
>= max_exports
)
468 max_exports
= ROUND_UP
(def
->num_exports
+1, 32);
470 def
->exports
= (def_file_export
*) xrealloc
(def
->exports
, max_exports
* sizeof
(def_file_export
));
472 def
->exports
= (def_file_export
*) xmalloc
(max_exports
* sizeof
(def_file_export
));
474 e
= def
->exports
+ def
->num_exports
;
475 memset
(e
, 0, sizeof
(def_file_export
));
476 if
(internal_name
&& !external_name
)
477 external_name
= internal_name
;
478 if
(external_name
&& !internal_name
)
479 internal_name
= external_name
;
480 e
->name
= xstrdup
(external_name
);
481 e
->internal_name
= xstrdup
(internal_name
);
482 e
->ordinal
= ordinal
;
487 static def_file_module
*
488 def_stash_module
(def
, name
)
493 for
(s
=def
->modules
; s
; s
=s
->next
)
494 if
(strcmp
(s
->name
, name
) == 0)
496 s
= (def_file_module
*) xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
497 s
->next
= def
->modules
;
500 strcpy
(s
->name
, name
);
505 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
)
510 const char *internal_name
;
513 int max_imports
= ROUND_UP
(def
->num_imports
, 16);
514 if
(def
->num_imports
>= max_imports
)
516 max_imports
= ROUND_UP
(def
->num_imports
+1, 16);
518 def
->imports
= (def_file_import
*) xrealloc
(def
->imports
, max_imports
* sizeof
(def_file_import
));
520 def
->imports
= (def_file_import
*) xmalloc
(max_imports
* sizeof
(def_file_import
));
522 i
= def
->imports
+ def
->num_imports
;
523 memset
(i
, 0, sizeof
(def_file_import
));
525 i
->name
= xstrdup
(name
);
527 i
->module
= def_stash_module
(def
, module
);
528 i
->ordinal
= ordinal
;
530 i
->internal_name
= xstrdup
(internal_name
);
532 i
->internal_name
= i
->name
;
544 { "-heap", HEAPSIZE
},
545 { "-stack", STACKSIZE
},
546 { "-attr", SECTIONS
},
547 { "-export", EXPORTS
},
552 def_file_add_directive
(my_def
, param
, len
)
557 def_file
*save_def
= def
;
558 const char *pend
= param
+ len
;
559 const char *tend
= param
;
566 while
(param
< pend
&& isspace
(*param
))
568 for
(tend
= param
+ 1;
569 tend
< pend
&& !(isspace
(tend
[-1]) && *tend
== '-');
572 for
(i
= 0; diropts
[i
].param
; i
++)
574 int len
= strlen
(diropts
[i
].param
);
575 if
(tend
- param
>= len
576 && strncmp
(param
, diropts
[i
].param
, len
) == 0
577 && (param
[len
] == ':' || param
[len
] == ' '))
579 lex_parse_string_end
= tend
;
580 lex_parse_string
= param
+ len
+ 1;
581 lex_forced_token
= diropts
[i
].token
;
588 if
(!diropts
[i
].param
)
590 /* xgettext:c-format */
591 einfo
(_
("Warning: .drectve `%.*s' unrecognized\n"),
592 tend
- param
, param
);
594 lex_parse_string
= 0;
601 /*****************************************************************************
603 *****************************************************************************/
606 def_name
(name
, base
)
612 def
->name
= xstrdup
(name
);
613 def
->base_address
= base
;
618 def_library
(name
, base
)
624 def
->name
= xstrdup
(name
);
625 def
->base_address
= base
;
630 def_description
(text
)
633 int len
= def
->description ? strlen
(def
->description
) : 0;
634 len
+= strlen
(text
) + 1;
635 if
(def
->description
)
637 def
->description
= (char *) xrealloc
(def
->description
, len
);
638 strcat
(def
->description
, text
);
642 def
->description
= (char *) xmalloc
(len
);
643 strcpy
(def
->description
, text
);
648 def_stacksize
(reserve
, commit
)
652 def
->stack_reserve
= reserve
;
653 def
->stack_commit
= commit
;
657 def_heapsize
(reserve
, commit
)
661 def
->heap_reserve
= reserve
;
662 def
->heap_commit
= commit
;
666 def_section
(name
, attr
)
671 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
672 if
(def
->num_section_defs
>= max_sections
)
674 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
675 if
(def
->section_defs
)
676 def
->section_defs
= (def_file_section
*) xrealloc
(def
->section_defs
, max_sections
* sizeof
(def_file_import
));
678 def
->section_defs
= (def_file_section
*) xmalloc
(max_sections
* sizeof
(def_file_import
));
680 s
= def
->section_defs
+ def
->num_section_defs
;
681 memset
(s
, 0, sizeof
(def_file_section
));
682 s
->name
= xstrdup
(name
);
692 def
->num_section_defs
++;
696 def_section_alt
(name
, attr
)
701 for
(; *attr
; attr
++)
723 def_section
(name
, aval
);
727 def_exports
(external_name
, internal_name
, ordinal
, flags
)
728 const char *external_name
;
729 const char *internal_name
;
733 def_file_export
*dfe
;
735 if
(!internal_name
&& external_name
)
736 internal_name
= external_name
;
738 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
741 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
);
743 dfe
->flag_noname
= 1;
745 dfe
->flag_constant
= 1;
749 dfe
->flag_private
= 1;
753 def_import
(internal_name
, module
, dllext
, name
, ordinal
)
754 const char *internal_name
;
764 buf
= (char *) xmalloc
(strlen
(module
) + strlen
(dllext
) + 2);
765 sprintf
(buf
, "%s.%s", module
, dllext
);
769 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
);
775 def_version
(major
, minor
)
779 def
->version_major
= major
;
780 def
->version_minor
= minor
;
787 struct directive
*d
= (struct directive
*) xmalloc
(sizeof
(struct directive
));
788 d
->next
= directives
;
790 d
->name
= xstrdup
(str
);
791 d
->len
= strlen
(str
);
798 einfo
("%P: %s:%d: %s\n", def_filename
, linenumber
, err
);
804 /*****************************************************************************
806 *****************************************************************************/
811 /* Never freed, but always reused as needed, so no real leak */
812 static char *buffer
= 0;
813 static int buflen
= 0;
814 static int bufptr
= 0;
820 if
(bufptr
== buflen
)
822 buflen
+= 50; /* overly reasonable, eh? */
824 buffer
= (char *) xrealloc
(buffer
, buflen
+ 1);
826 buffer
= (char *) xmalloc
(buflen
+ 1);
828 buffer
[bufptr
++] = c
;
829 buffer
[bufptr
] = 0; /* not optimal, but very convenient */
841 { "CONSTANT", CONSTANTU
},
842 { "constant", CONSTANTL
},
845 { "DESCRIPTION", DESCRIPTION
},
846 { "DIRECTIVE", DIRECTIVE
},
847 { "EXECUTE", EXECUTE
},
848 { "EXPORTS", EXPORTS
},
849 { "HEAPSIZE", HEAPSIZE
},
850 { "IMPORTS", IMPORTS
},
851 { "LIBRARY", LIBRARY
},
853 { "NONAME", NONAMEU
},
854 { "noname", NONAMEL
},
855 { "PRIVATE", PRIVATEU
},
856 { "private", PRIVATEL
},
858 { "SECTIONS", SECTIONS
},
859 { "SEGMENTS", SECTIONS
},
860 { "SHARED", SHARED
},
861 { "STACKSIZE", STACKSIZE
},
862 { "VERSION", VERSIONK
},
871 if
(lex_parse_string
)
873 if
(lex_parse_string
>= lex_parse_string_end
)
876 rv
= *lex_parse_string
++;
880 rv
= fgetc
(the_file
);
891 if
(lex_parse_string
)
897 return ungetc
(c
, the_file
);
905 if
(lex_forced_token
)
907 i
= lex_forced_token
;
908 lex_forced_token
= 0;
910 printf
("lex: forcing token %d\n", i
);
917 /* trim leading whitespace */
918 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
924 printf
("lex: EOF\n");
929 if
(saw_newline
&& c
== ';')
935 while
(c
!= EOF
&& c
!= '\n');
940 /* must be something else */
946 while
(c
!= EOF
&& (isxdigit
(c
) ||
(c
== 'x')))
953 yylval.number
= strtoul
(buffer
, 0, 0);
955 printf
("lex: `%s' returns NUMBER %d\n", buffer
, yylval.number
);
960 if
(isalpha
(c
) || strchr
("$:-_?", c
))
963 while
(c
!= EOF
&& (isalnum
(c
) || strchr
("$:-_?/@", c
)))
970 for
(i
= 0; tokens
[i
].name
; i
++)
971 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
974 printf
("lex: `%s' is a string token\n", buffer
);
976 return tokens
[i
].token
;
979 printf
("lex: `%s' returns ID\n", buffer
);
981 yylval.id
= xstrdup
(buffer
);
985 if
(c
== '\'' || c
== '"')
990 while
(c
!= EOF
&& c
!= q
)
995 yylval.id
= xstrdup
(buffer
);
997 printf
("lex: `%s' returns ID\n", buffer
);
1002 if
(c
== '=' || c
== '.' || c
== '@' || c
== ',')
1005 printf
("lex: `%c' returns itself\n", c
);
1016 /*printf ("lex: 0x%02x ignored\n", c); */