diff options
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index 2106b3e..f9dbd88 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -151,6 +151,7 @@ static void lang_gc_wild PARAMS ((lang_wild_statement_type *, const char *, const char *)); static void lang_gc_sections_1 PARAMS ((lang_statement_union_type *)); static void lang_gc_sections PARAMS ((void)); +static void lang_do_version_exports_section PARAMS ((void)); /* EXPORTS */ @@ -1253,6 +1254,9 @@ load_symbols (entry, place) return; } + if (ldemul_recognized_file (entry)) + return; + /* We don't call ldlang_add_file for an archive. Instead, the add_symbols entry point will call ldlang_add_file, via the add_archive_element callback, for each element of the archive @@ -2089,7 +2093,10 @@ print_statement (s, os) case lang_constructors_statement_enum: if (constructor_list.head != NULL) { - minfo (" CONSTRUCTORS\n"); + if (constructors_sorted) + minfo (" SORT (CONSTRUCTORS)\n"); + else + minfo (" CONSTRUCTORS\n"); print_statement_list (constructor_list.head, os); } break; @@ -3549,6 +3556,8 @@ lang_gc_sections_1 (s) case lang_group_statement_enum: lang_gc_sections_1 (s->group_statement.children.head); break; + default: + break; } } } @@ -3567,7 +3576,7 @@ lang_gc_sections () Handle the entry symbol at the same time. */ fake_list_start.next = ldlang_undef_chain_list_head; - fake_list_start.name = entry_symbol; + fake_list_start.name = (char *) entry_symbol; for (ulist = &fake_list_start; ulist; ulist = ulist->next) { @@ -3612,6 +3621,10 @@ lang_process () link. */ lang_check (); + /* Handle .exports instead of a version script if we're told to do so. */ + if (command_line.version_exports_section) + lang_do_version_exports_section (); + /* Build all sets based on the information gathered from the input files. */ ldctor_build_sets (); @@ -3655,6 +3668,10 @@ lang_process () relax_again = false; + /* Note: pe-dll.c does something like this also. If you find + you need to change this code, you probably need to change + pe-dll.c also. DJ */ + /* Do all the assignments with our current guesses as to section sizes. */ lang_do_assignments (statement_list.head, @@ -3836,7 +3853,7 @@ lang_add_reloc (reloc, howto, section, name, addend) p->output_vma = 0; } -void +lang_assignment_statement_type * lang_add_assignment (exp) etree_type * exp; { @@ -3844,6 +3861,7 @@ lang_add_assignment (exp) stat_ptr); new->exp = exp; + return new; } void @@ -4476,3 +4494,40 @@ lang_add_vers_depend (list, name) return ret; } + +static void +lang_do_version_exports_section () +{ + struct bfd_elf_version_expr *greg = NULL, *lreg; + + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + asection *sec = bfd_get_section_by_name (is->the_bfd, ".exports"); + char *contents, *p; + bfd_size_type len; + + if (sec == NULL) + continue; + + len = bfd_section_size (is->the_bfd, sec); + contents = xmalloc (len); + if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len)) + einfo (_("%X%P: unable to read .exports section contents"), sec); + + while (p < contents+len) + { + greg = lang_new_vers_regex (greg, p); + p = strchr (p, '\0') + 1; + } + + free (contents); + + /* Do not include this section in the link. */ + bfd_set_section_flags (is->the_bfd, sec, + bfd_get_section_flags (is->the_bfd, sec) | SEC_EXCLUDE); + } + + lreg = lang_new_vers_regex (NULL, "*"); + lang_register_vers_node (command_line.version_exports_section, + lang_new_vers_node (greg, lreg), NULL); +} |