GNU Binutils with patches for OS216
Révision | 66c103b772fdbc413d4727efa329babcab6617c5 (tree) |
---|---|
l'heure | 2008-09-07 13:02:31 |
Auteur | Alan Modra <amodra@gmai...> |
Commiter | Alan Modra |
* ldlang.h (lang_output_section_find): Define.
(lang_output_section_statement_lookup): Update prototype.
* ldlang.c (lang_output_section_find,
lang_output_section_statement_lookup_1): Merge into..
(lang_output_section_statement_lookup): ..here. Update all callers.
(process_insert_statements): Set constraint negative
for output section statements we might be inserting. Make error
fatal on not finding insertion section.
(lang_output_section_find): Rather than comparing
output_section_statement.constraint against -1, test whether
it is postive.
(lang_output_section_statement_lookup_1): Likewise.
(output_prev_sec_find, strip_excluded_output_sections): Likewise.
(lang_record_phdrs): Likewise.
* emultempl/elf32.em (output_rel_find): Likewise.
* NEWS: Mention INSERT.
@@ -1,3 +1,22 @@ | ||
1 | +2008-09-07 Alan Modra <amodra@bigpond.net.au> | |
2 | + | |
3 | + * ldlang.h (lang_output_section_find): Define. | |
4 | + (lang_output_section_statement_lookup): Update prototype. | |
5 | + * ldlang.c (lang_output_section_find, | |
6 | + lang_output_section_statement_lookup_1): Merge into.. | |
7 | + (lang_output_section_statement_lookup): ..here. Update all callers. | |
8 | + (process_insert_statements): Set constraint negative | |
9 | + for output section statements we might be inserting. Make error | |
10 | + fatal on not finding insertion section. | |
11 | + (lang_output_section_find): Rather than comparing | |
12 | + output_section_statement.constraint against -1, test whether | |
13 | + it is postive. | |
14 | + (lang_output_section_statement_lookup_1): Likewise. | |
15 | + (output_prev_sec_find, strip_excluded_output_sections): Likewise. | |
16 | + (lang_record_phdrs): Likewise. | |
17 | + * emultempl/elf32.em (output_rel_find): Likewise. | |
18 | + * NEWS: Mention INSERT. | |
19 | + | |
1 | 20 | 2008-08-26 Nick Clifton <nickc@redhat.com> |
2 | 21 | |
3 | 22 | PR 6727 |
@@ -1,6 +1,9 @@ | ||
1 | 1 | -*- text -*- |
2 | +* Linker scripts support a new INSERT command that makes it easier to | |
3 | + augment the default script. | |
4 | + | |
2 | 5 | * Linker script input section filespecs may now specify a file within an |
3 | - archive by writing "archive:file". | |
6 | + archive by writing "archive:file". | |
4 | 7 | |
5 | 8 | * The --sort-common switch now has an optional argument which specifies the |
6 | 9 | direction of sorting. |
@@ -8,9 +11,9 @@ | ||
8 | 11 | * The M68K linker now supports multiple GOT generation schemes controlled via |
9 | 12 | the --got=<type> command line option. |
10 | 13 | |
11 | -* The ARM EABI linker will now generate stubs for function calls to symbols that | |
12 | - are too far away. The placement of the stubs is controlled by a new linker | |
13 | - command line option: --stub-group-size=N. | |
14 | +* The ARM EABI linker will now generate stubs for function calls to symbols | |
15 | + that are too far away. The placement of the stubs is controlled by a new | |
16 | + linker command line option: --stub-group-size=N. | |
14 | 17 | |
15 | 18 | Changes in 2.18: |
16 | 19 |
@@ -1583,7 +1583,7 @@ output_rel_find (asection *sec, int isdyn) | ||
1583 | 1583 | lookup != NULL; |
1584 | 1584 | lookup = lookup->next) |
1585 | 1585 | { |
1586 | - if (lookup->constraint != -1 | |
1586 | + if (lookup->constraint >= 0 | |
1587 | 1587 | && CONST_STRNEQ (lookup->name, ".rel")) |
1588 | 1588 | { |
1589 | 1589 | int lookrela = lookup->name[4] == 'a'; |
@@ -1149,7 +1149,7 @@ lang_init (void) | ||
1149 | 1149 | first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum, |
1150 | 1150 | NULL); |
1151 | 1151 | abs_output_section = |
1152 | - lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME); | |
1152 | + lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME, 0, TRUE); | |
1153 | 1153 | |
1154 | 1154 | abs_output_section->bfd_section = bfd_abs_section_ptr; |
1155 | 1155 |
@@ -1255,44 +1255,19 @@ lang_memory_default (asection *section) | ||
1255 | 1255 | } |
1256 | 1256 | |
1257 | 1257 | lang_output_section_statement_type * |
1258 | -lang_output_section_find (const char *const name) | |
1258 | +lang_output_section_statement_lookup (const char *const name, | |
1259 | + int constraint, | |
1260 | + bfd_boolean create) | |
1259 | 1261 | { |
1260 | 1262 | struct out_section_hash_entry *entry; |
1261 | - unsigned long hash; | |
1262 | 1263 | |
1263 | 1264 | entry = ((struct out_section_hash_entry *) |
1264 | 1265 | bfd_hash_lookup (&output_section_statement_table, name, |
1265 | - FALSE, FALSE)); | |
1266 | + create, FALSE)); | |
1266 | 1267 | if (entry == NULL) |
1267 | - return NULL; | |
1268 | - | |
1269 | - hash = entry->root.hash; | |
1270 | - do | |
1271 | 1268 | { |
1272 | - if (entry->s.output_section_statement.constraint != -1) | |
1273 | - return &entry->s.output_section_statement; | |
1274 | - entry = (struct out_section_hash_entry *) entry->root.next; | |
1275 | - } | |
1276 | - while (entry != NULL | |
1277 | - && entry->root.hash == hash | |
1278 | - && strcmp (name, entry->s.output_section_statement.name) == 0); | |
1279 | - | |
1280 | - return NULL; | |
1281 | -} | |
1282 | - | |
1283 | -static lang_output_section_statement_type * | |
1284 | -lang_output_section_statement_lookup_1 (const char *const name, int constraint) | |
1285 | -{ | |
1286 | - struct out_section_hash_entry *entry; | |
1287 | - struct out_section_hash_entry *last_ent; | |
1288 | - unsigned long hash; | |
1289 | - | |
1290 | - entry = ((struct out_section_hash_entry *) | |
1291 | - bfd_hash_lookup (&output_section_statement_table, name, | |
1292 | - TRUE, FALSE)); | |
1293 | - if (entry == NULL) | |
1294 | - { | |
1295 | - einfo (_("%P%F: failed creating section `%s': %E\n"), name); | |
1269 | + if (create) | |
1270 | + einfo (_("%P%F: failed creating section `%s': %E\n"), name); | |
1296 | 1271 | return NULL; |
1297 | 1272 | } |
1298 | 1273 |
@@ -1300,10 +1275,12 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint) | ||
1300 | 1275 | { |
1301 | 1276 | /* We have a section of this name, but it might not have the correct |
1302 | 1277 | constraint. */ |
1303 | - hash = entry->root.hash; | |
1278 | + struct out_section_hash_entry *last_ent; | |
1279 | + unsigned long hash = entry->root.hash; | |
1280 | + | |
1304 | 1281 | do |
1305 | 1282 | { |
1306 | - if (entry->s.output_section_statement.constraint != -1 | |
1283 | + if (entry->s.output_section_statement.constraint >= 0 | |
1307 | 1284 | && (constraint == 0 |
1308 | 1285 | || (constraint == entry->s.output_section_statement.constraint |
1309 | 1286 | && constraint != SPECIAL))) |
@@ -1315,6 +1292,9 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint) | ||
1315 | 1292 | && entry->root.hash == hash |
1316 | 1293 | && strcmp (name, entry->s.output_section_statement.name) == 0); |
1317 | 1294 | |
1295 | + if (!create) | |
1296 | + return NULL; | |
1297 | + | |
1318 | 1298 | entry |
1319 | 1299 | = ((struct out_section_hash_entry *) |
1320 | 1300 | output_section_statement_newfunc (NULL, |
@@ -1334,12 +1314,6 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint) | ||
1334 | 1314 | return &entry->s.output_section_statement; |
1335 | 1315 | } |
1336 | 1316 | |
1337 | -lang_output_section_statement_type * | |
1338 | -lang_output_section_statement_lookup (const char *const name) | |
1339 | -{ | |
1340 | - return lang_output_section_statement_lookup_1 (name, 0); | |
1341 | -} | |
1342 | - | |
1343 | 1317 | /* A variant of lang_output_section_find used by place_orphan. |
1344 | 1318 | Returns the output statement that should precede a new output |
1345 | 1319 | statement for SEC. If an exact match is found on certain flags, |
@@ -1502,7 +1476,7 @@ output_prev_sec_find (lang_output_section_statement_type *os) | ||
1502 | 1476 | |
1503 | 1477 | for (lookup = os->prev; lookup != NULL; lookup = lookup->prev) |
1504 | 1478 | { |
1505 | - if (lookup->constraint == -1) | |
1479 | + if (lookup->constraint < 0) | |
1506 | 1480 | continue; |
1507 | 1481 | |
1508 | 1482 | if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL) |
@@ -3378,7 +3352,7 @@ map_input_to_output_sections | ||
3378 | 3352 | { |
3379 | 3353 | lang_output_section_statement_type *aos |
3380 | 3354 | = (lang_output_section_statement_lookup |
3381 | - (s->address_statement.section_name)); | |
3355 | + (s->address_statement.section_name, 0, TRUE)); | |
3382 | 3356 | |
3383 | 3357 | if (aos->bfd_section == NULL) |
3384 | 3358 | init_os (aos, NULL, 0); |
@@ -3403,6 +3377,7 @@ process_insert_statements (void) | ||
3403 | 3377 | lang_statement_union_type **s; |
3404 | 3378 | lang_output_section_statement_type *first_os = NULL; |
3405 | 3379 | lang_output_section_statement_type *last_os = NULL; |
3380 | + lang_output_section_statement_type *os; | |
3406 | 3381 | |
3407 | 3382 | /* "start of list" is actually the statement immediately after |
3408 | 3383 | the special abs_section output statement, so that it isn't |
@@ -3415,6 +3390,12 @@ process_insert_statements (void) | ||
3415 | 3390 | /* Keep pointers to the first and last output section |
3416 | 3391 | statement in the sequence we may be about to move. */ |
3417 | 3392 | last_os = &(*s)->output_section_statement; |
3393 | + | |
3394 | + /* Set constraint negative so that lang_output_section_find | |
3395 | + won't match this output section statement. At this | |
3396 | + stage in linking constraint has values in the range | |
3397 | + [-1, ONLY_IN_RW]. */ | |
3398 | + last_os->constraint = -2 - last_os->constraint; | |
3418 | 3399 | if (first_os == NULL) |
3419 | 3400 | first_os = last_os; |
3420 | 3401 | } |
@@ -3422,7 +3403,6 @@ process_insert_statements (void) | ||
3422 | 3403 | { |
3423 | 3404 | lang_insert_statement_type *i = &(*s)->insert_statement; |
3424 | 3405 | lang_output_section_statement_type *where; |
3425 | - lang_output_section_statement_type *os; | |
3426 | 3406 | lang_statement_union_type **ptr; |
3427 | 3407 | lang_statement_union_type *first; |
3428 | 3408 |
@@ -3431,21 +3411,12 @@ process_insert_statements (void) | ||
3431 | 3411 | { |
3432 | 3412 | do |
3433 | 3413 | where = where->prev; |
3434 | - while (where != NULL && where->constraint == -1); | |
3414 | + while (where != NULL && where->constraint < 0); | |
3435 | 3415 | } |
3436 | 3416 | if (where == NULL) |
3437 | 3417 | { |
3438 | - einfo (_("%X%P: %s not found for insert\n"), i->where); | |
3439 | - continue; | |
3440 | - } | |
3441 | - /* You can't insert into the list you are moving. */ | |
3442 | - for (os = first_os; os != NULL; os = os->next) | |
3443 | - if (os == where || os == last_os) | |
3444 | - break; | |
3445 | - if (os == where) | |
3446 | - { | |
3447 | - einfo (_("%X%P: %s not found for insert\n"), i->where); | |
3448 | - continue; | |
3418 | + einfo (_("%F%P: %s not found for insert\n"), i->where); | |
3419 | + return; | |
3449 | 3420 | } |
3450 | 3421 | |
3451 | 3422 | /* Deal with reordering the output section statement list. */ |
@@ -3482,6 +3453,7 @@ process_insert_statements (void) | ||
3482 | 3453 | last_sec = NULL; |
3483 | 3454 | for (os = first_os; os != NULL; os = os->next) |
3484 | 3455 | { |
3456 | + os->constraint = -2 - os->constraint; | |
3485 | 3457 | if (os->bfd_section != NULL |
3486 | 3458 | && os->bfd_section->owner != NULL) |
3487 | 3459 | { |
@@ -3542,6 +3514,14 @@ process_insert_statements (void) | ||
3542 | 3514 | s = &lang_output_section_statement.head; |
3543 | 3515 | } |
3544 | 3516 | } |
3517 | + | |
3518 | + /* Undo constraint twiddling. */ | |
3519 | + for (os = first_os; os != NULL; os = os->next) | |
3520 | + { | |
3521 | + os->constraint = -2 - os->constraint; | |
3522 | + if (os == last_os) | |
3523 | + break; | |
3524 | + } | |
3545 | 3525 | } |
3546 | 3526 | |
3547 | 3527 | /* An output section might have been removed after its statement was |
@@ -3569,7 +3549,7 @@ strip_excluded_output_sections (void) | ||
3569 | 3549 | asection *output_section; |
3570 | 3550 | bfd_boolean exclude; |
3571 | 3551 | |
3572 | - if (os->constraint == -1) | |
3552 | + if (os->constraint < 0) | |
3573 | 3553 | continue; |
3574 | 3554 | |
3575 | 3555 | output_section = os->bfd_section; |
@@ -5665,11 +5645,9 @@ lang_place_orphans (void) | ||
5665 | 5645 | || command_line.force_common_definition) |
5666 | 5646 | { |
5667 | 5647 | if (default_common_section == NULL) |
5668 | - { | |
5669 | - default_common_section = | |
5670 | - lang_output_section_statement_lookup (".bss"); | |
5671 | - | |
5672 | - } | |
5648 | + default_common_section | |
5649 | + = lang_output_section_statement_lookup (".bss", 0, | |
5650 | + TRUE); | |
5673 | 5651 | lang_add_section (&default_common_section->children, s, |
5674 | 5652 | default_common_section); |
5675 | 5653 | } |
@@ -5680,7 +5658,7 @@ lang_place_orphans (void) | ||
5680 | 5658 | { |
5681 | 5659 | lang_output_section_statement_type *os; |
5682 | 5660 | |
5683 | - os = lang_output_section_statement_lookup (s->name); | |
5661 | + os = lang_output_section_statement_lookup (s->name, 0, TRUE); | |
5684 | 5662 | lang_add_section (&os->children, s, os); |
5685 | 5663 | } |
5686 | 5664 | } |
@@ -5827,12 +5805,10 @@ lang_enter_output_section_statement (const char *output_section_statement_name, | ||
5827 | 5805 | { |
5828 | 5806 | lang_output_section_statement_type *os; |
5829 | 5807 | |
5830 | - os = lang_output_section_statement_lookup_1 (output_section_statement_name, | |
5831 | - constraint); | |
5808 | + os = lang_output_section_statement_lookup (output_section_statement_name, | |
5809 | + constraint, TRUE); | |
5832 | 5810 | current_section = os; |
5833 | 5811 | |
5834 | - /* Make next things chain into subchain of this. */ | |
5835 | - | |
5836 | 5812 | if (os->addr_tree == NULL) |
5837 | 5813 | { |
5838 | 5814 | os->addr_tree = address_exp; |
@@ -5843,6 +5819,8 @@ lang_enter_output_section_statement (const char *output_section_statement_name, | ||
5843 | 5819 | else |
5844 | 5820 | os->flags = SEC_NEVER_LOAD; |
5845 | 5821 | os->block_value = 1; |
5822 | + | |
5823 | + /* Make next things chain into subchain of this. */ | |
5846 | 5824 | stat_ptr = &os->children; |
5847 | 5825 | |
5848 | 5826 | os->subsection_alignment = |
@@ -6639,7 +6617,7 @@ lang_record_phdrs (void) | ||
6639 | 6617 | { |
6640 | 6618 | lang_output_section_phdr_list *pl; |
6641 | 6619 | |
6642 | - if (os->constraint == -1) | |
6620 | + if (os->constraint < 0) | |
6643 | 6621 | continue; |
6644 | 6622 | |
6645 | 6623 | pl = os->phdrs; |
@@ -6720,7 +6698,7 @@ lang_record_phdrs (void) | ||
6720 | 6698 | { |
6721 | 6699 | lang_output_section_phdr_list *pl; |
6722 | 6700 | |
6723 | - if (os->constraint == -1 | |
6701 | + if (os->constraint < 0 | |
6724 | 6702 | || os->bfd_section == NULL) |
6725 | 6703 | continue; |
6726 | 6704 |
@@ -525,12 +525,13 @@ extern void lang_do_assignments | ||
525 | 525 | statement != (lang_input_statement_type *) NULL; \ |
526 | 526 | statement = (lang_input_statement_type *) statement->next) \ |
527 | 527 | |
528 | +#define lang_output_section_find(NAME) \ | |
529 | + lang_output_section_statement_lookup (NAME, 0, FALSE) | |
530 | + | |
528 | 531 | extern void lang_process |
529 | 532 | (void); |
530 | 533 | extern void ldlang_add_file |
531 | 534 | (lang_input_statement_type *); |
532 | -extern lang_output_section_statement_type *lang_output_section_find | |
533 | - (const char * const); | |
534 | 535 | extern lang_output_section_statement_type *lang_output_section_find_by_flags |
535 | 536 | (const asection *, lang_output_section_statement_type **, |
536 | 537 | lang_match_sec_type_func); |
@@ -541,9 +542,8 @@ extern lang_input_statement_type *lang_add_input_file | ||
541 | 542 | (const char *, lang_input_file_enum_type, const char *); |
542 | 543 | extern void lang_add_keepsyms_file |
543 | 544 | (const char *); |
544 | -extern lang_output_section_statement_type * | |
545 | - lang_output_section_statement_lookup | |
546 | - (const char *const); | |
545 | +extern lang_output_section_statement_type *lang_output_section_statement_lookup | |
546 | + (const char *const, int, bfd_boolean); | |
547 | 547 | extern void ldlang_add_undef |
548 | 548 | (const char *const); |
549 | 549 | extern void lang_add_output_format |