1 2002-11-22 Jakub Jelinek <jakub@redhat.com>
3 * ldgram.y (sect_constraint): New.
4 (ONLY_IF_RO, ONLY_IF_RW): New tokens.
5 (section): Add sect_constraint. Pass additional argument
6 to lang_enter_output_section_statement.
7 * mri.c (mri_draw_tree): Pass additional argument to
8 lang_enter_output_section_statement.
9 * emultempl/pe.em (place_orphan): Likewise.
10 (output_prev_sec_find): Disregard output section statements with
12 * emultempl/mmo.em (output_prev_sec_find): Likewise.
13 (mmo_place_orphan): Pass additional argument to
14 lang_enter_output_section_statement.
15 * emultempl/elf32.em (output_prev_sec_find): Disregard output section
16 statements with constraint == -1.
17 (place_orphan): Pass additional argument to
18 lang_enter_output_section_statement.
19 * ldlang.c (lang_enter_overlay_section): Likewise.
20 (lang_output_section_find_1): New.
21 (lang_output_section_find): Use it.
22 (lang_output_section_statement_lookup_1): New.
23 (lang_output_section_statement_lookup): Use it.
24 (check_section_callback, check_input_sections): New.
25 (map_input_to_output_sections): Check if all input sections
26 are readonly if ONLY_IF_RO or ONLY_IF_RW was seen.
27 (strip_excluded_output_sections): Disregard output section statements
28 with constraint == -1.
29 (lang_record_phdrs): Likewise.
30 (lang_enter_output_section_statement): Add constraint argument.
31 Use lang_output_section_statement_lookup_1.
32 * ldlang.h (lang_output_section_statement_type): Add constraint
33 and all_input_readonly fields.
34 (lang_enter_output_section_statement): Adjust prototype.
35 * ldlex.l (ONLY_IF_RO, ONLY_IF_RW): New tokens.
36 * scripttempl/elf.sc (.eh_frame, .gcc_except_table): Move into text
37 segment if all input sections are readonly.
39 --- binutils-2.13.90.0.16/ld/ldgram.y.jj 2002-10-14 13:30:34.000000000 +0200
40 +++ binutils-2.13.90.0.16/ld/ldgram.y 2002-11-22 22:27:18.000000000 +0100
41 @@ -143,14 +143,14 @@ static int error_index;
43 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
44 %token ALIGNMOD AT PROVIDE
45 -%type <token> assign_op atype attributes_opt
46 +%type <token> assign_op atype attributes_opt sect_constraint
48 %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
49 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
50 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
51 %token <name> VERS_TAG VERS_IDENTIFIER
52 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
54 +%token KEEP ONLY_IF_RO ONLY_IF_RW
56 %type <versyms> vers_defns
57 %type <versnode> vers_tag
58 @@ -828,21 +828,28 @@ opt_at:
63 + ONLY_IF_RO { $$ = ONLY_IF_RO; }
64 + | ONLY_IF_RW { $$ = ONLY_IF_RW; }
68 section: NAME { ldlex_expression(); }
70 opt_at { ldlex_popstate (); ldlex_script (); }
74 lang_enter_output_section_statement($1, $3,
80 '}' { ldlex_popstate (); ldlex_expression (); }
81 memspec_opt memspec_at_opt phdr_opt fill_opt
84 - lang_leave_output_section_statement ($14, $11, $13, $12);
85 + lang_leave_output_section_statement ($15, $12, $14, $13);
89 --- binutils-2.13.90.0.16/ld/mri.c.jj 2002-10-31 19:10:42.000000000 +0100
90 +++ binutils-2.13.90.0.16/ld/mri.c 2002-11-22 18:38:27.000000000 +0100
91 @@ -237,7 +237,7 @@ mri_draw_tree ()
92 lang_enter_output_section_statement (p->name, base,
93 p->ok_to_load ? 0 : noload_section,
95 - (etree_type *) NULL);
96 + (etree_type *) NULL, 0);
98 tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
100 --- binutils-2.13.90.0.16/ld/emultempl/mmo.em.jj 2002-07-30 16:20:15.000000000 +0200
101 +++ binutils-2.13.90.0.16/ld/emultempl/mmo.em 2002-11-22 22:42:44.000000000 +0100
102 @@ -56,6 +56,8 @@ output_prev_sec_find (os)
105 lookup = &u->output_section_statement;
106 + if (lookup->constraint == -1)
110 if (lookup->bfd_section != NULL
111 @@ -141,7 +143,7 @@ mmo_place_orphan (file, s)
115 - (etree_type *) NULL);
116 + (etree_type *) NULL, 0);
118 lang_add_section (&os->children, s, os, file);
120 --- binutils-2.13.90.0.16/ld/emultempl/pe.em.jj 2002-11-21 15:58:51.000000000 +0100
121 +++ binutils-2.13.90.0.16/ld/emultempl/pe.em 2002-11-22 22:43:02.000000000 +0100
122 @@ -1489,6 +1489,8 @@ output_prev_sec_find (os)
125 lookup = &u->output_section_statement;
126 + if (lookup->constraint == -1)
131 @@ -1655,7 +1657,7 @@ gld_${EMULATION_NAME}_place_orphan (file
135 - (etree_type *) NULL);
136 + (etree_type *) NULL, 0);
138 lang_add_section (&add_child, s, os, file);
140 --- binutils-2.13.90.0.16/ld/emultempl/elf32.em.jj 2002-10-31 19:10:44.000000000 +0100
141 +++ binutils-2.13.90.0.16/ld/emultempl/elf32.em 2002-11-22 22:42:16.000000000 +0100
142 @@ -1009,7 +1009,8 @@ output_rel_find (sec)
143 for (u = lang_output_section_statement.head; u; u = lookup->next)
145 lookup = &u->output_section_statement;
146 - if (strncmp (".rel", lookup->name, 4) == 0)
147 + if (lookup->constraint != -1
148 + && strncmp (".rel", lookup->name, 4) == 0)
150 /* Don't place after .rel.plt as doing so results in wrong
151 dynamic tags. Also, place allocated reloc sections before
152 @@ -1236,7 +1237,7 @@ gld${EMULATION_NAME}_place_orphan (file,
156 - (etree_type *) NULL);
157 + (etree_type *) NULL, 0);
159 lang_add_section (&os->children, s, os, file);
161 --- binutils-2.13.90.0.16/ld/scripttempl/elf.sc.jj 2002-09-25 11:21:42.000000000 +0200
162 +++ binutils-2.13.90.0.16/ld/scripttempl/elf.sc 2002-11-22 22:35:47.000000000 +0100
163 @@ -280,6 +280,8 @@ cat <<EOF
164 ${CREATE_SHLIB-${SBSS2}}
165 ${OTHER_READONLY_SECTIONS}
166 .eh_frame_hdr : { *(.eh_frame_hdr) }
167 + .eh_frame ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.eh_frame)) }
168 + .gcc_except_table ${RELOCATING-0} : ONLY_IF_RO { *(.gcc_except_table) }
170 /* Adjust the address for the data segment. We want to adjust up to
171 the same address within the page on the next page up. */
172 @@ -312,8 +314,8 @@ cat <<EOF
173 .data1 ${RELOCATING-0} : { *(.data1) }
174 .tdata ${RELOCATING-0} : { *(.tdata${RELOCATING+ .tdata.* .gnu.linkonce.td.*}) }
175 .tbss ${RELOCATING-0} : { *(.tbss${RELOCATING+ .tbss.* .gnu.linkonce.tb.*})${RELOCATING+ *(.tcommon)} }
176 - .eh_frame ${RELOCATING-0} : { KEEP (*(.eh_frame)) }
177 - .gcc_except_table ${RELOCATING-0} : { *(.gcc_except_table) }
178 + .eh_frame ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.eh_frame)) }
179 + .gcc_except_table ${RELOCATING-0} : ONLY_IF_RW { *(.gcc_except_table) }
180 ${WRITABLE_RODATA+${RODATA}}
181 ${OTHER_READWRITE_SECTIONS}
182 ${TEXT_DYNAMIC-${DYNAMIC}}
183 --- binutils-2.13.90.0.16/ld/ldlang.h.jj 2002-10-10 00:53:07.000000000 +0200
184 +++ binutils-2.13.90.0.16/ld/ldlang.h 2002-11-22 22:27:37.000000000 +0100
185 @@ -132,6 +132,8 @@ typedef struct lang_output_section_state
187 int subsection_alignment; /* alignment of components */
188 int section_alignment; /* alignment of start of section */
190 + boolean all_input_readonly;
192 union etree_union *load_base;
194 @@ -385,7 +387,7 @@ extern lang_output_section_statement_typ
197 etree_type *subalign,
199 + etree_type *, int));
200 extern void lang_final PARAMS ((void));
201 extern void lang_process PARAMS ((void));
202 extern void lang_section_start PARAMS ((const char *, union etree_union *));
203 --- binutils-2.13.90.0.16/ld/ldlang.c.jj 2002-11-14 14:06:22.000000000 +0100
204 +++ binutils-2.13.90.0.16/ld/ldlang.c 2002-11-22 22:41:51.000000000 +0100
205 @@ -71,6 +71,10 @@ static void lang_for_each_statement_work
206 static lang_input_statement_type *new_afile
207 PARAMS ((const char *, lang_input_file_enum_type, const char *, boolean));
208 static lang_memory_region_type *lang_memory_default PARAMS ((asection *));
209 +static lang_output_section_statement_type * lang_output_section_find_1
210 + PARAMS ((const char *, int));
211 +static lang_output_section_statement_type *
212 + lang_output_section_statement_lookup_1 PARAMS ((const char *, int));
213 static void lang_map_flags PARAMS ((flagword));
214 static void init_os PARAMS ((lang_output_section_statement_type *));
215 static void exp_init_os PARAMS ((etree_type *));
216 @@ -86,6 +90,9 @@ static lang_statement_union_type *wild_s
217 static void output_section_callback
218 PARAMS ((lang_wild_statement_type *, struct wildcard_list *, asection *,
219 lang_input_statement_type *, PTR));
220 +static void check_section_callback
221 + PARAMS ((lang_wild_statement_type *, struct wildcard_list *, asection *,
222 + lang_input_statement_type *, PTR));
223 static lang_input_statement_type *lookup_name PARAMS ((const char *));
224 static boolean load_symbols
225 PARAMS ((lang_input_statement_type *, lang_statement_list_type *));
226 @@ -98,6 +105,9 @@ static void open_input_bfds PARAMS ((lan
227 static void lang_reasonable_defaults PARAMS ((void));
228 static void insert_undefined PARAMS ((const char *));
229 static void lang_place_undefineds PARAMS ((void));
230 +static void check_input_sections
231 + PARAMS ((lang_statement_union_type *,
232 + lang_output_section_statement_type *));
233 static void map_input_to_output_sections
234 PARAMS ((lang_statement_union_type *, const char *,
235 lang_output_section_statement_type *));
236 @@ -700,9 +710,10 @@ lang_memory_default (section)
237 return lang_memory_region_lookup ("*default*");
240 -lang_output_section_statement_type *
241 -lang_output_section_find (name)
242 +static lang_output_section_statement_type *
243 +lang_output_section_find_1 (name, constraint)
244 const char *const name;
247 lang_statement_union_type *u;
248 lang_output_section_statement_type *lookup;
249 @@ -712,7 +723,9 @@ lang_output_section_find (name)
252 lookup = &u->output_section_statement;
253 - if (strcmp (name, lookup->name) == 0)
254 + if (strcmp (name, lookup->name) == 0
255 + && lookup->constraint != -1
256 + && (constraint == 0 || constraint == lookup->constraint))
260 @@ -721,12 +734,20 @@ lang_output_section_find (name)
263 lang_output_section_statement_type *
264 -lang_output_section_statement_lookup (name)
265 +lang_output_section_find (name)
266 + const char *const name;
268 + return lang_output_section_find_1 (name, 0);
271 +static lang_output_section_statement_type *
272 +lang_output_section_statement_lookup_1 (name, constraint)
273 const char *const name;
276 lang_output_section_statement_type *lookup;
278 - lookup = lang_output_section_find (name);
279 + lookup = lang_output_section_find_1 (name, constraint);
280 if (lookup == (lang_output_section_statement_type *) NULL)
283 @@ -741,6 +762,7 @@ lang_output_section_statement_lookup (na
284 lookup->next = (lang_statement_union_type *) NULL;
285 lookup->bfd_section = (asection *) NULL;
286 lookup->processed = false;
287 + lookup->constraint = constraint;
288 lookup->sectype = normal_section;
289 lookup->addr_tree = (etree_type *) NULL;
290 lang_list_init (&lookup->children);
291 @@ -760,6 +782,13 @@ lang_output_section_statement_lookup (na
295 +lang_output_section_statement_type *
296 +lang_output_section_statement_lookup (name)
297 + const char *const name;
299 + return lang_output_section_statement_lookup_1 (name, 0);
303 lang_map_flags (flag)
305 @@ -1434,6 +1463,31 @@ output_section_callback (ptr, sec, secti
309 +/* Check if all sections in a wild statement for a particular FILE
313 +check_section_callback (ptr, sec, section, file, output)
314 + lang_wild_statement_type *ptr ATTRIBUTE_UNUSED;
315 + struct wildcard_list *sec ATTRIBUTE_UNUSED;
317 + lang_input_statement_type *file ATTRIBUTE_UNUSED;
320 + /* Exclude sections that match UNIQUE_SECTION_LIST. */
321 + if (unique_section_p (bfd_get_section_name (file->the_bfd, section)))
324 + if (section->output_section == NULL)
326 + flagword flags = bfd_get_section_flags (section->owner, section);
328 + if ((flags & SEC_READONLY) == 0)
329 + ((lang_output_section_statement_type *) output)->all_input_readonly
334 /* This is passed a file name which must have been seen already and
335 added to the statement tree. We will see if it has been opened
336 already and had its symbols read. If not then we'll read it. */
337 @@ -2099,6 +2153,41 @@ lang_place_undefineds ()
341 +/* Check for all readonly or some readwrite sections. */
344 +check_input_sections (s, output_section_statement)
345 + lang_statement_union_type *s;
346 + lang_output_section_statement_type *output_section_statement;
348 + for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
350 + switch (s->header.type)
352 + case lang_wild_statement_enum:
353 + walk_wild (&s->wild_statement, check_section_callback,
354 + output_section_statement);
355 + if (! output_section_statement->all_input_readonly)
358 + case lang_constructors_statement_enum:
359 + check_input_sections (constructor_list.head,
360 + output_section_statement);
361 + if (! output_section_statement->all_input_readonly)
364 + case lang_group_statement_enum:
365 + check_input_sections (s->group_statement.children.head,
366 + output_section_statement);
367 + if (! output_section_statement->all_input_readonly)
376 /* Open input files and attatch to output sections. */
379 @@ -2120,6 +2209,23 @@ map_input_to_output_sections (s, target,
380 output_section_statement);
382 case lang_output_section_statement_enum:
383 + if (s->output_section_statement.constraint)
385 + if (s->output_section_statement.constraint == -1)
387 + s->output_section_statement.all_input_readonly = true;
388 + check_input_sections (s->output_section_statement.children.head,
389 + &s->output_section_statement);
390 + if ((s->output_section_statement.all_input_readonly
391 + && s->output_section_statement.constraint == ONLY_IF_RW)
392 + || (!s->output_section_statement.all_input_readonly
393 + && s->output_section_statement.constraint == ONLY_IF_RO))
395 + s->output_section_statement.constraint = -1;
400 map_input_to_output_sections (s->output_section_statement.children.head,
402 &s->output_section_statement);
403 @@ -2190,6 +2296,8 @@ strip_excluded_output_sections ()
406 os = &u->output_section_statement;
407 + if (os->constraint == -1)
410 if (s != NULL && (s->flags & SEC_EXCLUDE) != 0)
412 @@ -4056,7 +4164,7 @@ topower (x)
413 lang_output_section_statement_type *
414 lang_enter_output_section_statement (output_section_statement_name,
415 address_exp, sectype, block_value,
416 - align, subalign, ebase)
417 + align, subalign, ebase, constraint)
418 const char *output_section_statement_name;
419 etree_type *address_exp;
420 enum section_type sectype;
421 @@ -4064,12 +4172,14 @@ lang_enter_output_section_statement (out
423 etree_type *subalign;
427 lang_output_section_statement_type *os;
431 - lang_output_section_statement_lookup (output_section_statement_name);
432 + lang_output_section_statement_lookup_1 (output_section_statement_name,
435 /* Add this statement to tree. */
437 @@ -4784,6 +4894,8 @@ lang_record_phdrs ()
438 struct lang_output_section_phdr_list *pl;
440 os = &u->output_section_statement;
441 + if (os->constraint == -1)
446 @@ -4844,7 +4956,8 @@ lang_record_phdrs ()
448 struct lang_output_section_phdr_list *pl;
450 - if (u->output_section_statement.bfd_section == NULL)
451 + if (u->output_section_statement.constraint == -1
452 + || u->output_section_statement.bfd_section == NULL)
455 for (pl = u->output_section_statement.phdrs;
456 @@ -4914,7 +5027,7 @@ lang_enter_overlay_section (name)
459 lang_enter_output_section_statement (name, overlay_vma, normal_section,
463 /* If this is the first section, then base the VMA of future
464 sections on this one. This will work correctly even if `.' is
465 --- binutils-2.13.90.0.16/ld/ldlex.l.jj 2002-10-31 19:10:42.000000000 +0100
466 +++ binutils-2.13.90.0.16/ld/ldlex.l 2002-11-22 17:29:14.000000000 +0100
467 @@ -303,6 +303,8 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^]([*?
468 <EXPRESSION,BOTH,SCRIPT>"COPY" { RTOKEN(COPY);}
469 <EXPRESSION,BOTH,SCRIPT>"INFO" { RTOKEN(INFO);}
470 <EXPRESSION,BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY);}
471 +<EXPRESSION,BOTH,SCRIPT>"ONLY_IF_RO" { RTOKEN(ONLY_IF_RO); }
472 +<EXPRESSION,BOTH,SCRIPT>"ONLY_IF_RW" { RTOKEN(ONLY_IF_RW); }
473 <BOTH,SCRIPT>"o" { RTOKEN(ORIGIN);}
474 <BOTH,SCRIPT>"org" { RTOKEN(ORIGIN);}
475 <BOTH,SCRIPT>"l" { RTOKEN( LENGTH);}