1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000 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; }
219 char * name
= xmalloc
(strlen
($1) + 1 + strlen
($3) + 1);
220 sprintf
(name
, "%s.%s", $1, $3);
227 '@' NUMBER
{ $$
= $2;}
236 opt_base: BASE
'=' NUMBER
{ $$
= $3;}
244 /*****************************************************************************
246 *****************************************************************************/
248 static FILE *the_file
;
249 static const char *def_filename
;
250 static int linenumber
;
251 static def_file
*def
;
252 static int saw_newline
;
256 struct directive
*next
;
261 static struct directive
*directives
= 0;
266 def_file
*rv
= (def_file
*) xmalloc
(sizeof
(def_file
));
267 memset
(rv
, 0, sizeof
(def_file
));
269 rv
->base_address
= (bfd_vma
) (-1);
270 rv
->stack_reserve
= rv
->stack_commit
= -1;
271 rv
->heap_reserve
= rv
->heap_commit
= -1;
272 rv
->version_major
= rv
->version_minor
= -1;
277 def_file_parse
(filename
, add_to
)
278 const char *filename
;
283 the_file
= fopen
(filename
, "r");
284 def_filename
= filename
;
297 def
= def_file_empty
();
310 for
(d
= directives
; d
; d
= d
->next
)
313 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
315 def_file_add_directive
(def
, d
->name
, d
->len
);
330 if
(def
->description
)
331 free
(def
->description
);
333 if
(def
->section_defs
)
335 for
(i
= 0; i
< def
->num_section_defs
; i
++)
337 if
(def
->section_defs
[i
].name
)
338 free
(def
->section_defs
[i
].name
);
339 if
(def
->section_defs
[i
].class
)
340 free
(def
->section_defs
[i
].class
);
342 free
(def
->section_defs
);
347 for
(i
= 0; i
< def
->num_exports
; i
++)
349 if
(def
->exports
[i
].internal_name
350 && def
->exports
[i
].internal_name
!= def
->exports
[i
].name
)
351 free
(def
->exports
[i
].internal_name
);
352 if
(def
->exports
[i
].name
)
353 free
(def
->exports
[i
].name
);
360 for
(i
= 0; i
< def
->num_imports
; i
++)
362 if
(def
->imports
[i
].internal_name
363 && def
->imports
[i
].internal_name
!= def
->imports
[i
].name
)
364 free
(def
->imports
[i
].internal_name
);
365 if
(def
->imports
[i
].name
)
366 free
(def
->imports
[i
].name
);
373 def_file_module
*m
= def
->modules
;
374 def
->modules
= def
->modules
->next
;
381 #ifdef DEF_FILE_PRINT
383 def_file_print
(file
, def
)
388 fprintf
(file
, ">>>> def_file at 0x%08x\n", def
);
390 fprintf
(file
, " name: %s\n", def
->name ? def
->name
: "(unspecified)");
391 if
(def
->is_dll
!= -1)
392 fprintf
(file
, " is dll: %s\n", def
->is_dll ?
"yes" : "no");
393 if
(def
->base_address
!= (bfd_vma
) (-1))
394 fprintf
(file
, " base address: 0x%08x\n", def
->base_address
);
395 if
(def
->description
)
396 fprintf
(file
, " description: `%s'\n", def
->description
);
397 if
(def
->stack_reserve
!= -1)
398 fprintf
(file
, " stack reserve: 0x%08x\n", def
->stack_reserve
);
399 if
(def
->stack_commit
!= -1)
400 fprintf
(file
, " stack commit: 0x%08x\n", def
->stack_commit
);
401 if
(def
->heap_reserve
!= -1)
402 fprintf
(file
, " heap reserve: 0x%08x\n", def
->heap_reserve
);
403 if
(def
->heap_commit
!= -1)
404 fprintf
(file
, " heap commit: 0x%08x\n", def
->heap_commit
);
406 if
(def
->num_section_defs
> 0)
408 fprintf
(file
, " section defs:\n");
409 for
(i
= 0; i
< def
->num_section_defs
; i
++)
411 fprintf
(file
, " name: `%s', class: `%s', flags:",
412 def
->section_defs
[i
].name
, def
->section_defs
[i
].class
);
413 if
(def
->section_defs
[i
].flag_read
)
414 fprintf
(file
, " R");
415 if
(def
->section_defs
[i
].flag_write
)
416 fprintf
(file
, " W");
417 if
(def
->section_defs
[i
].flag_execute
)
418 fprintf
(file
, " X");
419 if
(def
->section_defs
[i
].flag_shared
)
420 fprintf
(file
, " S");
421 fprintf
(file
, "\n");
425 if
(def
->num_exports
> 0)
427 fprintf
(file
, " exports:\n");
428 for
(i
= 0; i
< def
->num_exports
; i
++)
430 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
431 def
->exports
[i
].name
, def
->exports
[i
].internal_name
,
432 def
->exports
[i
].ordinal
);
433 if
(def
->exports
[i
].flag_private
)
434 fprintf
(file
, " P");
435 if
(def
->exports
[i
].flag_constant
)
436 fprintf
(file
, " C");
437 if
(def
->exports
[i
].flag_noname
)
438 fprintf
(file
, " N");
439 if
(def
->exports
[i
].flag_data
)
440 fprintf
(file
, " D");
441 fprintf
(file
, "\n");
445 if
(def
->num_imports
> 0)
447 fprintf
(file
, " imports:\n");
448 for
(i
= 0; i
< def
->num_imports
; i
++)
450 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
451 def
->imports
[i
].internal_name
,
452 def
->imports
[i
].module
,
453 def
->imports
[i
].name
,
454 def
->imports
[i
].ordinal
);
457 if
(def
->version_major
!= -1)
458 fprintf
(file
, " version: %d.%d\n", def
->version_major
, def
->version_minor
);
459 fprintf
(file
, "<<<< def_file at 0x%08x\n", def
);
464 def_file_add_export
(def
, external_name
, internal_name
, ordinal
)
466 const char *external_name
;
467 const char *internal_name
;
471 int max_exports
= ROUND_UP
(def
->num_exports
, 32);
472 if
(def
->num_exports
>= max_exports
)
474 max_exports
= ROUND_UP
(def
->num_exports
+1, 32);
476 def
->exports
= (def_file_export
*) xrealloc
(def
->exports
, max_exports
* sizeof
(def_file_export
));
478 def
->exports
= (def_file_export
*) xmalloc
(max_exports
* sizeof
(def_file_export
));
480 e
= def
->exports
+ def
->num_exports
;
481 memset
(e
, 0, sizeof
(def_file_export
));
482 if
(internal_name
&& !external_name
)
483 external_name
= internal_name
;
484 if
(external_name
&& !internal_name
)
485 internal_name
= external_name
;
486 e
->name
= xstrdup
(external_name
);
487 e
->internal_name
= xstrdup
(internal_name
);
488 e
->ordinal
= ordinal
;
493 static def_file_module
*
494 def_stash_module
(def
, name
)
499 for
(s
=def
->modules
; s
; s
=s
->next
)
500 if
(strcmp
(s
->name
, name
) == 0)
502 s
= (def_file_module
*) xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
503 s
->next
= def
->modules
;
506 strcpy
(s
->name
, name
);
511 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
)
516 const char *internal_name
;
519 int max_imports
= ROUND_UP
(def
->num_imports
, 16);
520 if
(def
->num_imports
>= max_imports
)
522 max_imports
= ROUND_UP
(def
->num_imports
+1, 16);
524 def
->imports
= (def_file_import
*) xrealloc
(def
->imports
, max_imports
* sizeof
(def_file_import
));
526 def
->imports
= (def_file_import
*) xmalloc
(max_imports
* sizeof
(def_file_import
));
528 i
= def
->imports
+ def
->num_imports
;
529 memset
(i
, 0, sizeof
(def_file_import
));
531 i
->name
= xstrdup
(name
);
533 i
->module
= def_stash_module
(def
, module
);
534 i
->ordinal
= ordinal
;
536 i
->internal_name
= xstrdup
(internal_name
);
538 i
->internal_name
= i
->name
;
550 { "-heap", HEAPSIZE
},
551 { "-stack", STACKSIZE
},
552 { "-attr", SECTIONS
},
553 { "-export", EXPORTS
},
558 def_file_add_directive
(my_def
, param
, len
)
563 def_file
*save_def
= def
;
564 const char *pend
= param
+ len
;
565 const char *tend
= param
;
572 while
(param
< pend
&& isspace
(*param
))
574 for
(tend
= param
+ 1;
575 tend
< pend
&& !(isspace
(tend
[-1]) && *tend
== '-');
578 for
(i
= 0; diropts
[i
].param
; i
++)
580 int len
= strlen
(diropts
[i
].param
);
581 if
(tend
- param
>= len
582 && strncmp
(param
, diropts
[i
].param
, len
) == 0
583 && (param
[len
] == ':' || param
[len
] == ' '))
585 lex_parse_string_end
= tend
;
586 lex_parse_string
= param
+ len
+ 1;
587 lex_forced_token
= diropts
[i
].token
;
594 if
(!diropts
[i
].param
)
596 /* xgettext:c-format */
597 einfo
(_
("Warning: .drectve `%.*s' unrecognized\n"),
598 tend
- param
, param
);
600 lex_parse_string
= 0;
607 /*****************************************************************************
609 *****************************************************************************/
612 def_name
(name
, base
)
618 def
->name
= xstrdup
(name
);
619 def
->base_address
= base
;
624 def_library
(name
, base
)
630 def
->name
= xstrdup
(name
);
631 def
->base_address
= base
;
636 def_description
(text
)
639 int len
= def
->description ? strlen
(def
->description
) : 0;
640 len
+= strlen
(text
) + 1;
641 if
(def
->description
)
643 def
->description
= (char *) xrealloc
(def
->description
, len
);
644 strcat
(def
->description
, text
);
648 def
->description
= (char *) xmalloc
(len
);
649 strcpy
(def
->description
, text
);
654 def_stacksize
(reserve
, commit
)
658 def
->stack_reserve
= reserve
;
659 def
->stack_commit
= commit
;
663 def_heapsize
(reserve
, commit
)
667 def
->heap_reserve
= reserve
;
668 def
->heap_commit
= commit
;
672 def_section
(name
, attr
)
677 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
678 if
(def
->num_section_defs
>= max_sections
)
680 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
681 if
(def
->section_defs
)
682 def
->section_defs
= (def_file_section
*) xrealloc
(def
->section_defs
, max_sections
* sizeof
(def_file_import
));
684 def
->section_defs
= (def_file_section
*) xmalloc
(max_sections
* sizeof
(def_file_import
));
686 s
= def
->section_defs
+ def
->num_section_defs
;
687 memset
(s
, 0, sizeof
(def_file_section
));
688 s
->name
= xstrdup
(name
);
698 def
->num_section_defs
++;
702 def_section_alt
(name
, attr
)
707 for
(; *attr
; attr
++)
729 def_section
(name
, aval
);
733 def_exports
(external_name
, internal_name
, ordinal
, flags
)
734 const char *external_name
;
735 const char *internal_name
;
739 def_file_export
*dfe
;
741 if
(!internal_name
&& external_name
)
742 internal_name
= external_name
;
744 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
747 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
);
749 dfe
->flag_noname
= 1;
751 dfe
->flag_constant
= 1;
755 dfe
->flag_private
= 1;
759 def_import
(internal_name
, module
, dllext
, name
, ordinal
)
760 const char *internal_name
;
770 buf
= (char *) xmalloc
(strlen
(module
) + strlen
(dllext
) + 2);
771 sprintf
(buf
, "%s.%s", module
, dllext
);
775 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
);
781 def_version
(major
, minor
)
785 def
->version_major
= major
;
786 def
->version_minor
= minor
;
793 struct directive
*d
= (struct directive
*) xmalloc
(sizeof
(struct directive
));
794 d
->next
= directives
;
796 d
->name
= xstrdup
(str
);
797 d
->len
= strlen
(str
);
804 einfo
("%P: %s:%d: %s\n", def_filename
, linenumber
, err
);
810 /*****************************************************************************
812 *****************************************************************************/
817 /* Never freed, but always reused as needed, so no real leak */
818 static char *buffer
= 0;
819 static int buflen
= 0;
820 static int bufptr
= 0;
826 if
(bufptr
== buflen
)
828 buflen
+= 50; /* overly reasonable, eh? */
830 buffer
= (char *) xrealloc
(buffer
, buflen
+ 1);
832 buffer
= (char *) xmalloc
(buflen
+ 1);
834 buffer
[bufptr
++] = c
;
835 buffer
[bufptr
] = 0; /* not optimal, but very convenient */
847 { "CONSTANT", CONSTANTU
},
848 { "constant", CONSTANTL
},
851 { "DESCRIPTION", DESCRIPTION
},
852 { "DIRECTIVE", DIRECTIVE
},
853 { "EXECUTE", EXECUTE
},
854 { "EXPORTS", EXPORTS
},
855 { "HEAPSIZE", HEAPSIZE
},
856 { "IMPORTS", IMPORTS
},
857 { "LIBRARY", LIBRARY
},
859 { "NONAME", NONAMEU
},
860 { "noname", NONAMEL
},
861 { "PRIVATE", PRIVATEU
},
862 { "private", PRIVATEL
},
864 { "SECTIONS", SECTIONS
},
865 { "SEGMENTS", SECTIONS
},
866 { "SHARED", SHARED
},
867 { "STACKSIZE", STACKSIZE
},
868 { "VERSION", VERSIONK
},
877 if
(lex_parse_string
)
879 if
(lex_parse_string
>= lex_parse_string_end
)
882 rv
= *lex_parse_string
++;
886 rv
= fgetc
(the_file
);
897 if
(lex_parse_string
)
903 return ungetc
(c
, the_file
);
911 if
(lex_forced_token
)
913 i
= lex_forced_token
;
914 lex_forced_token
= 0;
916 printf
("lex: forcing token %d\n", i
);
923 /* trim leading whitespace */
924 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
930 printf
("lex: EOF\n");
935 if
(saw_newline
&& c
== ';')
941 while
(c
!= EOF
&& c
!= '\n');
946 /* must be something else */
952 while
(c
!= EOF
&& (isxdigit
(c
) ||
(c
== 'x')))
959 yylval.number
= strtoul
(buffer
, 0, 0);
961 printf
("lex: `%s' returns NUMBER %d\n", buffer
, yylval.number
);
966 if
(isalpha
(c
) || strchr
("$:-_?", c
))
969 while
(c
!= EOF
&& (isalnum
(c
) || strchr
("$:-_?/@", c
)))
976 for
(i
= 0; tokens
[i
].name
; i
++)
977 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
980 printf
("lex: `%s' is a string token\n", buffer
);
982 return tokens
[i
].token
;
985 printf
("lex: `%s' returns ID\n", buffer
);
987 yylval.id
= xstrdup
(buffer
);
991 if
(c
== '\'' || c
== '"')
996 while
(c
!= EOF
&& c
!= q
)
1001 yylval.id
= xstrdup
(buffer
);
1003 printf
("lex: `%s' returns ID\n", buffer
);
1008 if
(c
== '=' || c
== '.' || c
== '@' || c
== ',')
1011 printf
("lex: `%c' returns itself\n", c
);
1022 /*printf ("lex: 0x%02x ignored\n", c); */