1 /* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
2 Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
4 Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
6 This file is part of GNU ld.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 #define DONTDECLARE_MALLOC
48 static enum section_type sectype
;
50 lang_memory_region_type
*region
;
52 struct wildcard_spec current_file
;
53 boolean ldgram_want_filename
= true
;
54 boolean had_script
= false
;
55 boolean force_make_executable
= false
;
57 boolean ldgram_in_script
= false
;
58 boolean ldgram_had_equals
= false
;
59 boolean ldgram_had_keep
= false
;
60 char *ldgram_vers_current_lang
= NULL
;
62 #define ERROR_NAME_MAX 20
63 static char *error_names
[ERROR_NAME_MAX
];
64 static int error_index
;
65 #define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
66 #define POP_ERROR() error_index--;
72 struct wildcard_spec wildcard
;
74 union etree_union
*etree
;
79 union etree_union
*at
;
80 union etree_union
*flags
;
82 struct lang_nocrossref
*nocrossref
;
83 struct lang_output_section_phdr_list
*section_phdr
;
84 struct bfd_elf_version_deps
*deflist
;
85 struct bfd_elf_version_expr
*versyms
;
86 struct bfd_elf_version_tree
*versnode
;
89 %type
<etree
> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
90 %type
<etree
> opt_exp_without_type
91 %type
<integer
> fill_opt
92 %type
<name
> memspec_opt casesymlist
93 %type
<cname
> wildcard_name
94 %type
<wildcard
> wildcard_spec
96 %token
<name
> NAME LNAME
97 %type
<integer
> length
98 %type
<phdr
> phdr_qualifiers
99 %type
<nocrossref
> nocrossref_list
100 %type
<section_phdr
> phdr_opt
101 %type
<integer
> opt_nocrossrefs
103 %right
<token
> PLUSEQ MINUSEQ MULTEQ DIVEQ
'=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
104 %right
<token
> '?' ':'
111 %left
<token
> '<' '>' LE GE
112 %left
<token
> LSHIFT RSHIFT
114 %left
<token
> '+' '-'
115 %left
<token
> '*' '/' '%'
120 %token
<token
> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
121 %token SECTIONS PHDRS SORT
123 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
124 %token SIZEOF_HEADERS
126 %token MEMORY DEFSYMEND
127 %token NOLOAD DSECT COPY INFO OVERLAY
128 %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
129 %token
<integer
> NEXT
130 %token SIZEOF ADDR LOADADDR MAX_K MIN_K
131 %token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS
133 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
134 %token ALIGNMOD AT PROVIDE
135 %type
<token
> assign_op atype attributes_opt
136 %type
<name
> filename
137 %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
138 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
139 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
140 %token
<name
> VERS_TAG VERS_IDENTIFIER
141 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
144 %type
<versyms
> vers_defns
145 %type
<versnode
> vers_tag
146 %type
<deflist
> verdep
151 INPUT_SCRIPT script_file
152 | INPUT_MRI_SCRIPT mri_script_file
153 | INPUT_VERSION_SCRIPT version_script_file
154 | INPUT_DEFSYM defsym_expr
166 lang_add_assignment
(exp_assop
($3,$2,$4));
169 /* SYNTAX WITHIN AN MRI SCRIPT FILE */
173 PUSH_ERROR
(_
("MRI style script"));
184 mri_script_lines mri_script_command NEWLINE
192 einfo
(_
("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1);
195 config.map_filename
= "-";
197 | ORDER ordernamelist
199 | PUBLIC NAME
'=' exp
200 { mri_public
($2, $4); }
201 | PUBLIC NAME
',' exp
202 { mri_public
($2, $4); }
204 { mri_public
($2, $3); }
208 { mri_output_section
($2, $4);}
210 { mri_output_section
($2, $3);}
212 { mri_output_section
($2, $4);}
213 | ALIGN_K NAME
'=' exp
214 { mri_align
($2,$4); }
215 | ALIGN_K NAME
',' exp
216 { mri_align
($2,$4); }
217 | ALIGNMOD NAME
'=' exp
218 { mri_alignmod
($2,$4); }
219 | ALIGNMOD NAME
',' exp
220 { mri_alignmod
($2,$4); }
221 | ABSOLUTE mri_abs_name_list
222 | LOAD mri_load_name_list
225 | ALIAS NAME
',' NAME
226 { mri_alias
($2,$4,0);}
228 { mri_alias
($2,0,(int) $4);}
232 { mri_truncate
((unsigned int) $2); }
234 | EXTERN extern_name_list
236 { ldfile_open_command_file
($2); } mri_script_lines END
238 { lang_add_entry
($2, false
); }
243 ordernamelist
',' NAME
{ mri_order
($3); }
244 | ordernamelist NAME
{ mri_order
($2); }
251 | mri_load_name_list
',' NAME
{ mri_load
($3); }
256 { mri_only_load
($1); }
257 | mri_abs_name_list
',' NAME
258 { mri_only_load
($3); }
262 /* empty */ { $$
= NULL
; }
264 | casesymlist
',' NAME
269 { ldlang_add_undef
($1); }
270 | extern_name_list NAME
271 { ldlang_add_undef
($2); }
272 | extern_name_list
',' NAME
273 { ldlang_add_undef
($3); }
301 | floating_point_support
305 | TARGET_K
'(' NAME
')'
306 { lang_add_target
($3); }
307 | SEARCH_DIR
'(' filename
')'
308 { ldfile_add_library_path
($3, false
); }
309 | OUTPUT
'(' filename
')'
310 { lang_add_output
($3, 1); }
311 | OUTPUT_FORMAT
'(' NAME
')'
312 { lang_add_output_format
($3, (char *) NULL
,
314 | OUTPUT_FORMAT
'(' NAME
',' NAME
',' NAME
')'
315 { lang_add_output_format
($3, $5, $7, 1); }
316 | OUTPUT_ARCH
'(' NAME
')'
317 { ldfile_set_output_arch
($3); }
318 | FORCE_COMMON_ALLOCATION
319 { command_line.force_common_definition
= true
; }
320 | INPUT
'(' input_list
')'
322 { lang_enter_group
(); }
324 { lang_leave_group
(); }
325 | MAP
'(' filename
')'
326 { lang_add_map
($3); }
328 { ldfile_open_command_file
($2); } ifile_list END
329 | NOCROSSREFS
'(' nocrossref_list
')'
331 lang_add_nocrossref
($3);
333 | EXTERN
'(' extern_name_list
')'
338 { lang_add_input_file
($1,lang_input_file_is_search_file_enum
,
340 | input_list
',' NAME
341 { lang_add_input_file
($3,lang_input_file_is_search_file_enum
,
344 { lang_add_input_file
($2,lang_input_file_is_search_file_enum
,
347 { lang_add_input_file
($1,lang_input_file_is_l_enum
,
349 | input_list
',' LNAME
350 { lang_add_input_file
($3,lang_input_file_is_l_enum
,
353 { lang_add_input_file
($2,lang_input_file_is_l_enum
,
358 SECTIONS
'{' sec_or_group_p1
'}'
362 sec_or_group_p1 section
363 | sec_or_group_p1 statement_anywhere
369 { lang_add_entry
($3, false
); }
373 /* The '*' and '?' cases are there because the lexer returns them as
374 separate tokens rather than as NAME. */
395 $$.exclude_name
= NULL
;
397 | EXCLUDE_FILE
'(' wildcard_name
')' wildcard_name
401 $$.exclude_name
= $3;
403 | SORT
'(' wildcard_name
')'
407 $$.exclude_name
= NULL
;
409 | SORT
'(' EXCLUDE_FILE
'(' wildcard_name
')' wildcard_name
')'
413 $$.exclude_name
= $5;
421 lang_add_wild
($1.name
, $1.sorted
,
424 ldgram_had_keep
, $1.exclude_name
);
426 | file_NAME_list opt_comma wildcard_spec
428 lang_add_wild
($3.name
, $3.sorted
,
431 ldgram_had_keep
, $3.exclude_name
);
435 input_section_spec_no_keep:
438 lang_add_wild
(NULL
, false
, $1, false
,
439 ldgram_had_keep
, NULL
);
443 current_file.name
= NULL
;
444 current_file.sorted
= false
;
450 /* '*' matches any file name. */
451 if
(strcmp
(current_file.name
, "*") == 0)
452 current_file.name
= NULL
;
454 '(' file_NAME_list
')'
458 input_section_spec_no_keep
460 { ldgram_had_keep
= true
; }
461 input_section_spec_no_keep
')'
462 { ldgram_had_keep
= false
; }
467 | CREATE_OBJECT_SYMBOLS
469 lang_add_attribute
(lang_object_symbols_statement_enum
);
475 lang_add_attribute
(lang_constructors_statement_enum
);
477 | SORT
'(' CONSTRUCTORS
')'
479 constructors_sorted
= true
;
480 lang_add_attribute
(lang_constructors_statement_enum
);
483 | length
'(' mustbe_exp
')'
485 lang_add_data
((int) $1,$3);
488 | FILL
'(' mustbe_exp
')'
491 (exp_get_value_int
($3,
494 lang_first_phase_enum
));
499 statement_list statement
524 $$
= exp_get_value_int
($2,
527 lang_first_phase_enum
);
561 lang_add_assignment
(exp_assop
($2, $1, $3));
563 | NAME assign_op mustbe_exp
565 lang_add_assignment
(exp_assop
('=', $1,
571 | PROVIDE
'(' NAME
'=' mustbe_exp
')'
573 lang_add_assignment
(exp_provide
($3, $5));
583 MEMORY
'{' memory_spec memory_spec_list
'}'
587 memory_spec_list memory_spec
588 | memory_spec_list
',' memory_spec
594 { region
= lang_memory_region_lookup
($1); }
596 origin_spec opt_comma length_spec
599 ORIGIN
'=' mustbe_exp
602 exp_get_vma
($3, 0L,"origin", lang_first_phase_enum
);
607 LENGTH
'=' mustbe_exp
608 { region
->length
= exp_get_vma
($3,
611 lang_first_phase_enum
);
617 { /* dummy action to avoid bison 1.25 error message */ }
618 |
'(' attributes_list
')'
623 | attributes_list attributes_string
628 { lang_set_flags
(region
, $1, 0); }
630 { lang_set_flags
(region
, $2, 1); }
634 STARTUP
'(' filename
')'
635 { lang_startup
($3); }
639 HLL
'(' high_level_library_NAME_list
')'
641 { ldemul_hll
((char *)NULL
); }
644 high_level_library_NAME_list:
645 high_level_library_NAME_list opt_comma filename
653 SYSLIB
'(' low_level_library_NAME_list
')'
654 ; low_level_library_NAME_list
:
655 low_level_library_NAME_list opt_comma filename
656 { ldemul_syslib
($3); }
660 floating_point_support:
662 { lang_float
(true
); }
664 { lang_float
(false
); }
672 | NAME nocrossref_list
674 struct lang_nocrossref
*n
;
676 n
= (struct lang_nocrossref
*) xmalloc
(sizeof
*n
);
681 | NAME
',' nocrossref_list
683 struct lang_nocrossref
*n
;
685 n
= (struct lang_nocrossref
*) xmalloc
(sizeof
*n
);
692 mustbe_exp: { ldlex_expression
(); }
694 { ldlex_popstate
(); $$
=$2;}
699 { $$
= exp_unop
('-', $2); }
702 | NEXT
'(' exp
')' %prec UNARY
703 { $$
= exp_unop
((int) $1,$3); }
704 |
'!' exp %prec UNARY
705 { $$
= exp_unop
('!', $2); }
706 |
'+' exp %prec UNARY
708 |
'~' exp %prec UNARY
709 { $$
= exp_unop
('~', $2);}
712 { $$
= exp_binop
('*', $1, $3); }
714 { $$
= exp_binop
('/', $1, $3); }
716 { $$
= exp_binop
('%', $1, $3); }
718 { $$
= exp_binop
('+', $1, $3); }
720 { $$
= exp_binop
('-' , $1, $3); }
722 { $$
= exp_binop
(LSHIFT
, $1, $3); }
724 { $$
= exp_binop
(RSHIFT
, $1, $3); }
726 { $$
= exp_binop
(EQ
, $1, $3); }
728 { $$
= exp_binop
(NE
, $1, $3); }
730 { $$
= exp_binop
(LE
, $1, $3); }
732 { $$
= exp_binop
(GE
, $1, $3); }
734 { $$
= exp_binop
('<' , $1, $3); }
736 { $$
= exp_binop
('>' , $1, $3); }
738 { $$
= exp_binop
('&' , $1, $3); }
740 { $$
= exp_binop
('^' , $1, $3); }
742 { $$
= exp_binop
('|' , $1, $3); }
743 | exp
'?' exp
':' exp
744 { $$
= exp_trinop
('?' , $1, $3, $5); }
746 { $$
= exp_binop
(ANDAND
, $1, $3); }
748 { $$
= exp_binop
(OROR
, $1, $3); }
749 | DEFINED
'(' NAME
')'
750 { $$
= exp_nameop
(DEFINED
, $3); }
752 { $$
= exp_intop
($1); }
754 { $$
= exp_nameop
(SIZEOF_HEADERS
,0); }
756 | SIZEOF
'(' NAME
')'
757 { $$
= exp_nameop
(SIZEOF
,$3); }
759 { $$
= exp_nameop
(ADDR
,$3); }
760 | LOADADDR
'(' NAME
')'
761 { $$
= exp_nameop
(LOADADDR
,$3); }
762 | ABSOLUTE
'(' exp
')'
763 { $$
= exp_unop
(ABSOLUTE
, $3); }
764 | ALIGN_K
'(' exp
')'
765 { $$
= exp_unop
(ALIGN_K
,$3); }
767 { $$
= exp_unop
(ALIGN_K
,$3); }
769 { $$
= exp_nameop
(NAME
,$1); }
770 | MAX_K
'(' exp
',' exp
')'
771 { $$
= exp_binop
(MAX_K
, $3, $5 ); }
772 | MIN_K
'(' exp
',' exp
')'
773 { $$
= exp_binop
(MIN_K
, $3, $5 ); }
774 | ASSERT_K
'(' exp
',' NAME
')'
775 { $$
= exp_assert
($3, $5); }
780 AT
'(' exp
')' { $$
= $3; }
784 section: NAME
{ ldlex_expression
(); }
786 opt_at
{ ldlex_popstate
(); ldlex_script
(); }
789 lang_enter_output_section_statement
($1, $3,
794 '}' { ldlex_popstate
(); ldlex_expression
(); }
795 memspec_opt phdr_opt fill_opt
798 lang_leave_output_section_statement
($13, $11, $12);
802 { ldlex_expression
(); }
803 opt_exp_without_type opt_nocrossrefs opt_at
804 { ldlex_popstate
(); ldlex_script
(); }
807 lang_enter_overlay
($3, $5, (int) $4);
811 { ldlex_popstate
(); ldlex_expression
(); }
812 memspec_opt phdr_opt fill_opt
815 lang_leave_overlay
($14, $12, $13);
818 |
/* The GROUP case is just enough to support the gcc
819 svr3.ifile script. It is not intended to be full
820 support. I'm not even sure what GROUP is supposed
822 GROUP
{ ldlex_expression
(); }
826 lang_add_assignment
(exp_assop
('=', ".", $3));
828 '{' sec_or_group_p1
'}'
832 NOLOAD
{ sectype
= noload_section
; }
833 | DSECT
{ sectype
= dsect_section
; }
834 | COPY
{ sectype
= copy_section
; }
835 | INFO
{ sectype
= info_section
; }
836 | OVERLAY
{ sectype
= overlay_section
; }
841 |
/* EMPTY */ { sectype
= normal_section
; }
842 |
'(' ')' { sectype
= normal_section
; }
846 exp atype
':' { $$
= $1; }
847 | atype
':' { $$
= (etree_type
*)NULL
; }
848 |
/* The BIND cases are to support the gcc svr3.ifile
849 script. They aren't intended to implement full
850 support for the BIND keyword. I'm not even sure
851 what BIND is supposed to mean. */
852 BIND
'(' exp
')' atype
':' { $$
= $3; }
853 | BIND
'(' exp
')' BLOCK
'(' exp
')' atype
':'
857 opt_exp_without_type:
859 |
':' { $$
= (etree_type
*) NULL
; }
872 |
{ $$
= "*default*"; }
882 struct lang_output_section_phdr_list
*n
;
884 n
= ((struct lang_output_section_phdr_list
*)
885 xmalloc
(sizeof
*n
));
899 lang_enter_overlay_section
($2);
901 '{' statement_list_opt
'}'
902 { ldlex_popstate
(); ldlex_expression
(); }
906 lang_leave_overlay_section
($9, $8);
912 PHDRS
'{' phdr_list
'}'
921 NAME
{ ldlex_expression
(); }
922 phdr_type phdr_qualifiers
{ ldlex_popstate
(); }
925 lang_new_phdr
($1, $3, $4.filehdr
, $4.phdrs
, $4.at
,
935 if
($1->type.node_class
== etree_name
936 && $1->type.node_code
== NAME
)
940 static const char * const phdr_types
[] =
942 "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
943 "PT_INTERP", "PT_NOTE", "PT_SHLIB",
949 i
< sizeof phdr_types
/ sizeof phdr_types
[0];
951 if
(strcmp
(s
, phdr_types
[i
]) == 0)
963 memset
(&$$
, 0, sizeof
(struct phdr_info
));
965 | NAME phdr_val phdr_qualifiers
968 if
(strcmp
($1, "FILEHDR") == 0 && $2 == NULL
)
970 else if
(strcmp
($1, "PHDRS") == 0 && $2 == NULL
)
972 else if
(strcmp
($1, "FLAGS") == 0 && $2 != NULL
)
975 einfo
(_
("%X%P:%S: PHDRS syntax error at `%s'\n"), $1);
977 | AT
'(' exp
')' phdr_qualifiers
995 /* This syntax is used within an external version script file. */
999 ldlex_version_file
();
1000 PUSH_ERROR
(_
("VERSION script"));
1009 /* This is used within a normal linker script file. */
1013 ldlex_version_script
();
1015 VERSIONK
'{' vers_nodes
'}'
1023 | vers_nodes vers_node
1027 VERS_TAG
'{' vers_tag
'}' ';'
1029 lang_register_vers_node
($1, $3, NULL
);
1031 | VERS_TAG
'{' vers_tag
'}' verdep
';'
1033 lang_register_vers_node
($1, $3, $5);
1040 $$
= lang_add_vers_depend
(NULL
, $1);
1044 $$
= lang_add_vers_depend
($1, $2);
1051 $$
= lang_new_vers_node
(NULL
, NULL
);
1055 $$
= lang_new_vers_node
($1, NULL
);
1057 | GLOBAL
':' vers_defns
';'
1059 $$
= lang_new_vers_node
($3, NULL
);
1061 | LOCAL
':' vers_defns
';'
1063 $$
= lang_new_vers_node
(NULL
, $3);
1065 | GLOBAL
':' vers_defns
';' LOCAL
':' vers_defns
';'
1067 $$
= lang_new_vers_node
($3, $7);
1074 $$
= lang_new_vers_regex
(NULL
, $1, ldgram_vers_current_lang
);
1076 | vers_defns
';' VERS_IDENTIFIER
1078 $$
= lang_new_vers_regex
($1, $3, ldgram_vers_current_lang
);
1082 $
<name
>$
= ldgram_vers_current_lang
;
1083 ldgram_vers_current_lang
= $2;
1087 ldgram_vers_current_lang
= $
<name
>4;
1096 if
(ldfile_assumed_script
)
1097 einfo
(_
("%P:%s: file format not recognized; treating as linker script\n"),
1098 ldfile_input_filename
);
1099 if
(error_index
> 0 && error_index
< ERROR_NAME_MAX
)
1100 einfo
("%P%F:%S: %s in %s\n", arg
, error_names
[error_index
-1]);
1102 einfo
("%P%F:%S: %s\n", arg
);