diff options
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index 6ee3f84..3d2cc99 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6102,6 +6102,55 @@ lang_one_common (struct bfd_link_hash_entry *h, void *info) return TRUE; } +/* Handle a single orphan section S, placing the orphan into an appropriate + output section. The effects of the --orphan-handling command line + option are handled here. */ + +static void +ldlang_place_orphan (asection *s) +{ + if (config.orphan_handling == orphan_handling_discard) + { + lang_output_section_statement_type *os; + os = lang_output_section_statement_lookup (DISCARD_SECTION_NAME, 0, + TRUE); + if (os->addr_tree == NULL + && (bfd_link_relocatable (&link_info) + || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)) + os->addr_tree = exp_intop (0); + lang_add_section (&os->children, s, NULL, os); + } + else + { + lang_output_section_statement_type *os; + const char *name = s->name; + int constraint = 0; + + if (config.orphan_handling == orphan_handling_error) + einfo ("%X%P: error: unplaced orphan section `%A' from `%B'.\n", + s, s->owner); + + if (config.unique_orphan_sections || unique_section_p (s, NULL)) + constraint = SPECIAL; + + os = ldemul_place_orphan (s, name, constraint); + if (os == NULL) + { + os = lang_output_section_statement_lookup (name, constraint, TRUE); + if (os->addr_tree == NULL + && (bfd_link_relocatable (&link_info) + || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)) + os->addr_tree = exp_intop (0); + lang_add_section (&os->children, s, NULL, os); + } + + if (config.orphan_handling == orphan_handling_warn) + einfo ("%P: warning: orphan section `%A' from `%B' being " + "placed in section `%s'.\n", + s, s->owner, os->name); + } +} + /* Run through the input files and ensure that every input section has somewhere to go. If one is found without a destination then create an input request and place it into the statement tree. */ @@ -6141,27 +6190,7 @@ lang_place_orphans (void) } } else - { - const char *name = s->name; - int constraint = 0; - - if (config.unique_orphan_sections - || unique_section_p (s, NULL)) - constraint = SPECIAL; - - if (!ldemul_place_orphan (s, name, constraint)) - { - lang_output_section_statement_type *os; - os = lang_output_section_statement_lookup (name, - constraint, - TRUE); - if (os->addr_tree == NULL - && (bfd_link_relocatable (&link_info) - || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)) - os->addr_tree = exp_intop (0); - lang_add_section (&os->children, s, NULL, os); - } - } + ldlang_place_orphan (s); } } } |