diff options
author | Jakub Jelinek <jakub@redhat.com> | 2001-04-13 00:34:36 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2001-04-13 00:34:36 +0000 |
commit | f5fa8ca231d47662321addbfbde105e2bed0be07 (patch) | |
tree | f7627630ea5563084aff4b9d1cfe756113ee8a85 /bfd/elflink.h | |
parent | 6c98e688d5bbc670851c9e092c132a565eb67519 (diff) | |
download | gdb-f5fa8ca231d47662321addbfbde105e2bed0be07.zip gdb-f5fa8ca231d47662321addbfbde105e2bed0be07.tar.gz gdb-f5fa8ca231d47662321addbfbde105e2bed0be07.tar.bz2 |
bfd/
* libbfd-in.h (_bfd_merge_section): New.
(_bfd_write_merged_section): New.
(_bfd_merged_section_offset): New.
* libbfd.h: Rebuilt.
* linker.c (_bfd_generic_link_output_symbols): Handle
discard_sec_merge.
* aoutx.h (aout_link_write_symbols): Likewise.
* pdp11.c (aout_link_write_symbols): Likewise.
* elflink.h (elf_link_add_object_symbols): Call _bfd_merge_section.
(elf_bfd_final_link): Adjust global symbols pointing into SEC_MERGE
sections.
(elf_link_sec_merge_syms): New.
(elf_link_input_bfd): Call _bfd_merged_section_offset
and _bfd_write_merged_section.
Handle discard_sec_merge.
* elf-bfd.h (struct elf_link_hash_table): Add merge_info
field.
(struct bfd_elf_section_data): Likewise.
* elf.c (_bfd_elf_make_section_from_shdr): Set SEC_MERGE and
SEC_STRINGS section flags and entsize from their ELF counterparts.
(_bfd_elf_link_hash_table_init): Initialize merge_info.
(elf_fake_sections): Set SHF_MERGE, SHF_STRINGS and sh_entsize
from their BFD counterparts.
* merge.c: New file.
* Makefile.am: Add strtab.lo.
* Makefile.in: Rebuilt.
include/
* bfdlink.h (bfd_link_discard): Add discard_sec_merge.
gas/
* config/obj-elf.c (obj_elf_change_section): Add entsize argument,
handle SHF_MERGE and SHF_STRINGS.
(obj_elf_parse_section_letters): Set SHF_MERGE and SHF_STRINGS.
(obj_elf_section): Allow additional argument specifying entity size.
* write.c (adjust_reloc_syms): Keep relocations against local symbols
in SEC_MERGE sections.
ld/
* ldmain.c (main): Default to discard_sec_merge.
* lexsup.c (OPTION_DISCARD_NONE): Define.
(ld_options): Add --discard-none.
(parse_args): Handle OPTION_DISCARD_NONE.
* ldlang.c (wild_doit): SEC_MERGE should be set in the output
section only if SEC_MERGE and SEC_STRINGS flags and entsize of
all its input sections match.
Diffstat (limited to 'bfd/elflink.h')
-rw-r--r-- | bfd/elflink.h | 86 |
1 files changed, 76 insertions, 10 deletions
diff --git a/bfd/elflink.h b/bfd/elflink.h index 554713b..d175223 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -2167,6 +2167,18 @@ elf_link_add_object_symbols (abfd, info) } } + if (! info->relocateable && ! dynamic) + { + asection *s; + + for (s = abfd->sections; s != NULL; s = s->next) + if ((s->flags & SEC_MERGE) + && ! _bfd_merge_section (abfd, + &elf_hash_table (info)->merge_info, + s, &elf_section_data (s)->merge_info)) + goto error_return; + } + return true; error_return: @@ -4069,6 +4081,8 @@ static boolean elf_link_flush_output_syms PARAMS ((struct elf_final_link_info *)); static boolean elf_link_output_extsym PARAMS ((struct elf_link_hash_entry *, PTR)); +static boolean elf_link_sec_merge_syms + PARAMS ((struct elf_link_hash_entry *, PTR)); static boolean elf_link_input_bfd PARAMS ((struct elf_final_link_info *, bfd *)); static boolean elf_reloc_link_order @@ -4218,6 +4232,7 @@ elf_bfd_final_link (abfd, info) Elf_Internal_Shdr *symstrtab_hdr; struct elf_backend_data *bed = get_elf_backend_data (abfd); struct elf_outext_info eoinfo; + boolean merged; if (info->shared) abfd->flags |= DYNAMIC; @@ -4263,6 +4278,7 @@ elf_bfd_final_link (abfd, info) max_external_reloc_size = 0; max_internal_reloc_count = 0; max_sym_count = 0; + merged = false; for (o = abfd->sections; o != (asection *) NULL; o = o->next) { o->reloc_count = 0; @@ -4284,6 +4300,9 @@ elf_bfd_final_link (abfd, info) the linker has decided to not include. */ sec->linker_mark = true; + if (sec->flags & SEC_MERGE) + merged = true; + if (info->relocateable || info->emitrelocations) o->reloc_count += sec->reloc_count; @@ -4341,6 +4360,10 @@ elf_bfd_final_link (abfd, info) o->vma = 0; } + if (! info->relocateable && merged) + elf_link_hash_traverse (elf_hash_table (info), + elf_link_sec_merge_syms, (PTR) abfd); + /* Figure out the file positions for everything but the symbol table and the relocs. We set symcount to force assign_section_numbers to create a symbol table. */ @@ -5060,6 +5083,33 @@ elf_link_flush_output_syms (finfo) return true; } +/* Adjust all external symbols pointing into SEC_MERGE sections + to reflect the object merging within the sections. */ + +static boolean +elf_link_sec_merge_syms (h, data) + struct elf_link_hash_entry *h; + PTR data; +{ + asection *sec; + + if ((h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && ((sec = h->root.u.def.section)->flags & SEC_MERGE) + && elf_section_data (sec)->merge_info) + { + bfd *output_bfd = (bfd *) data; + + h->root.u.def.value = + _bfd_merged_section_offset (output_bfd, + &h->root.u.def.section, + elf_section_data (sec)->merge_info, + h->root.u.def.value, (bfd_vma) 0); + } + + return true; +} + /* Add an external symbol to the symbol table. This is called from the hash table traversal routine. When generating a shared object, we go through the symbol table twice. The first time we output @@ -5525,7 +5575,15 @@ elf_link_input_bfd (finfo, input_bfd) name = isec->name; } else if (isym->st_shndx > 0 && isym->st_shndx < SHN_LORESERVE) - isec = section_from_elf_index (input_bfd, isym->st_shndx); + { + isec = section_from_elf_index (input_bfd, isym->st_shndx); + if (isec && elf_section_data (isec)->merge_info + && ELF_ST_TYPE (isym->st_info) != STT_SECTION) + isym->st_value = + _bfd_merged_section_offset (output_bfd, &isec, + elf_section_data (isec)->merge_info, + isym->st_value, (bfd_vma) 0); + } else if (isym->st_shndx == SHN_ABS) { isec = bfd_abs_section_ptr; @@ -5627,7 +5685,9 @@ elf_link_input_bfd (finfo, input_bfd) if ((finfo->info->strip == strip_some && (bfd_hash_lookup (finfo->info->keep_hash, name, false, false) == NULL)) - || (finfo->info->discard == discard_l + || (((finfo->info->discard == discard_sec_merge + && (isec->flags & SEC_MERGE) && ! finfo->info->relocateable) + || finfo->info->discard == discard_l) && bfd_is_local_label_name (input_bfd, name))) continue; @@ -5889,7 +5949,20 @@ elf_link_input_bfd (finfo, input_bfd) } /* Write out the modified section contents. */ - if (elf_section_data (o)->stab_info == NULL) + if (elf_section_data (o)->stab_info) + { + if (! (_bfd_write_section_stabs + (output_bfd, &elf_hash_table (finfo->info)->stab_info, + o, &elf_section_data (o)->stab_info, contents))) + return false; + } + else if (elf_section_data (o)->merge_info) + { + if (! (_bfd_write_merged_section + (output_bfd, o, elf_section_data (o)->merge_info))) + return false; + } + else { if (! (o->flags & SEC_EXCLUDE) && ! bfd_set_section_contents (output_bfd, o->output_section, @@ -5899,13 +5972,6 @@ elf_link_input_bfd (finfo, input_bfd) : o->_raw_size))) return false; } - else - { - if (! (_bfd_write_section_stabs - (output_bfd, &elf_hash_table (finfo->info)->stab_info, - o, &elf_section_data (o)->stab_info, contents))) - return false; - } } return true; |