diff options
author | Alan Modra <amodra@gmail.com> | 2000-09-15 10:24:50 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2000-09-15 10:24:50 +0000 |
commit | d5c73c2f38b17820d1fbde17df133640725bb7af (patch) | |
tree | 327de076e2bf93db1191607ea61a55ea7174358c /bfd/elf32-hppa.c | |
parent | ad525611ab268633d98432f83156b27d8ad457cd (diff) | |
download | gdb-d5c73c2f38b17820d1fbde17df133640725bb7af.zip gdb-d5c73c2f38b17820d1fbde17df133640725bb7af.tar.gz gdb-d5c73c2f38b17820d1fbde17df133640725bb7af.tar.bz2 |
Find the first .init and .fini sections correctly.
Clobber millicode syms via a hash traversal here. elf_adjust_dynamic_symbol
really ought to let us look at all dynamic symbols, but it doesn't.
Diffstat (limited to 'bfd/elf32-hppa.c')
-rw-r--r-- | bfd/elf32-hppa.c | 135 |
1 files changed, 78 insertions, 57 deletions
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index e2f7e10..5b2d1c9 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -345,6 +345,9 @@ static boolean hppa_discard_copies PARAMS ((struct elf_link_hash_entry *, PTR)); #endif +static boolean clobber_millicode_symbols + PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *)); + static boolean elf32_hppa_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); @@ -621,27 +624,11 @@ hppa_add_stub (stub_name, section, sec_count, info) stub_sec = hplink->stub_section_created[sec_count]; if (stub_sec == NULL) { - int special_sec = 0; - - /* We only want one stub for .init and .fini because glibc - splits the _init and _fini functions into two parts. We - don't want to put a stub in the middle of a function. - It would be better to merge all the stub sections for an - output section if the output section + stubs is small enough. - This would fix the .init and .fini case and also allow stubs - to be merged. It's more linker work though. */ if (strncmp (section->name, ".init", 5) == 0) - { - if (hplink->first_init_sec != 0) - stub_sec = hplink->stub_section_created[hplink->first_init_sec-1]; - special_sec = 1; - } + stub_sec = hplink->stub_section_created[hplink->first_init_sec - 1]; else if (strncmp (section->name, ".fini", 5) == 0) - { - if (hplink->first_fini_sec != 0) - stub_sec = hplink->stub_section_created[hplink->first_fini_sec-1]; - special_sec = 2; - } + stub_sec = hplink->stub_section_created[hplink->first_fini_sec - 1]; + if (stub_sec == NULL) { size_t len; @@ -657,14 +644,6 @@ hppa_add_stub (stub_name, section, sec_count, info) stub_sec = (*hplink->add_stub_section) (s_name, section); if (stub_sec == NULL) return NULL; - - if (special_sec != 0) - { - if (special_sec == 1) - hplink->first_init_sec = sec_count + 1; - else - hplink->first_fini_sec = sec_count + 1; - } } hplink->stub_section_created[sec_count] = stub_sec; } @@ -2127,6 +2106,27 @@ hppa_discard_copies (h, inf) #endif +/* This function is called via elf_link_hash_traverse to force + millicode symbols local so they do not end up as globals in the + dynamic symbol table. We ought to be able to do this in + adjust_dynamic_symbol, but our adjust_dynamic_symbol is not called + for all dynamic symbols. Arguably, this is a bug in + elf_adjust_dynamic_symbol. */ + +static boolean +clobber_millicode_symbols (h, info) + struct elf_link_hash_entry *h; + struct bfd_link_info *info; +{ + if (h->type == STT_PARISC_MILLI) + { + h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL; + elf32_hppa_hide_symbol(info, h); + } + return true; +} + + /* Set the sizes of the dynamic sections. */ static boolean @@ -2158,6 +2158,11 @@ elf32_hppa_size_dynamic_sections (output_bfd, info) s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; } + /* Force millicode symbols local. */ + elf_link_hash_traverse (&hplink->root, + clobber_millicode_symbols, + info); + /* DT_INIT and DT_FINI need a .plt entry. Make sure they have one. */ funcname = info->init_function; @@ -2511,6 +2516,50 @@ elf32_hppa_size_stubs (stub_bfd, multi_subspace, info, /* Now we can free the external symbols. */ free (ext_syms); + /* Go looking for .init and .fini sections. We only want one + stub section for each of .init* and .fini* because glibc + splits the _init and _fini functions into multiple parts, and + putting a stub in the middle of a function is not a good idea. + It would be better to merge all the stub sections for an + output section if the output section + stubs is small enough. + This would fix the .init and .fini case and also allow stubs + to be merged. It's more linker work though. */ + for (section = input_bfd->sections; + section != NULL; + section = section->next, sec_count++) + { + if (hplink->first_init_sec == 0) + { + if (strncmp (section->name, ".init", 5) == 0) + hplink->first_init_sec = sec_count + 1; + } + if (hplink->first_fini_sec == 0) + { + if (strncmp (section->name, ".fini", 5) == 0) + hplink->first_fini_sec = sec_count + 1; + } + +#if ! LONG_BRANCH_PIC_IN_SHLIB + /* If this is a shared link, find all the stub reloc + sections. */ + if (info->shared) + { + char *name; + asection *reloc_sec; + + name = bfd_malloc (strlen (section->name) + + sizeof STUB_SUFFIX + + 5); + if (name == NULL) + return false; + sprintf (name, ".rela%s%s", section->name, STUB_SUFFIX); + reloc_sec = bfd_get_section_by_name (hplink->root.dynobj, name); + hplink->reloc_section_created[sec_count] = reloc_sec; + free (name); + } +#endif + } + if (info->shared && hplink->multi_subspace) { unsigned int symndx; @@ -2558,7 +2607,8 @@ elf32_hppa_size_stubs (stub_bfd, multi_subspace, info, { stub_entry = hppa_add_stub (stub_name, sec, - sec_count + sec->index, + (sec_count + sec->index + - input_bfd->section_count), info); if (!stub_entry) goto error_ret_free_local; @@ -2578,30 +2628,6 @@ elf32_hppa_size_stubs (stub_bfd, multi_subspace, info, } } } -#if LONG_BRANCH_PIC_IN_SHLIB - sec_count += input_bfd->section_count; -#else - if (! info->shared) - sec_count += input_bfd->section_count; - else - for (section = input_bfd->sections; - section != NULL; - section = section->next, sec_count++) - { - char *name; - asection *reloc_sec; - - name = bfd_malloc (strlen (section->name) - + sizeof STUB_SUFFIX - + 5); - if (name == NULL) - return false; - sprintf (name, ".rela%s%s", section->name, STUB_SUFFIX); - reloc_sec = bfd_get_section_by_name (hplink->root.dynobj, name); - hplink->reloc_section_created[sec_count] = reloc_sec; - free (name); - } -#endif } while (1) @@ -3735,11 +3761,6 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) hplink = hppa_link_hash_table (info); dynobj = hplink->root.dynobj; - /* Millicode symbols should not be put in the dynamic - symbol table under any circumstances. */ - if (ELF_ST_TYPE (sym->st_info) == STT_PARISC_MILLI) - h->dynindx = -1; - if (h->plt.offset != (bfd_vma) -1) { bfd_vma value; |