diff options
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index 8e59383..d2dc17d 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -9062,6 +9062,63 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) continue; } + if (finfo->info->relocatable + && (o->flags & (SEC_LINKER_CREATED | SEC_GROUP)) == SEC_GROUP) + { + /* Deal with the group signature symbol. */ + struct bfd_elf_section_data *sec_data = elf_section_data (o); + unsigned long symndx = sec_data->this_hdr.sh_info; + asection *osec = o->output_section; + + if (symndx >= locsymcount + || (elf_bad_symtab (input_bfd) + && finfo->sections[symndx] == NULL)) + { + struct elf_link_hash_entry *h = sym_hashes[symndx - extsymoff]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + /* Arrange for symbol to be output. */ + h->indx = -2; + elf_section_data (osec)->this_hdr.sh_info = -2; + } + else if (ELF_ST_TYPE (isymbuf[symndx].st_info) == STT_SECTION) + { + /* We'll use the output section target_index. */ + asection *sec = finfo->sections[symndx]->output_section; + elf_section_data (osec)->this_hdr.sh_info = sec->target_index; + } + else + { + if (finfo->indices[symndx] == -1) + { + /* Otherwise output the local symbol now. */ + Elf_Internal_Sym sym = isymbuf[symndx]; + asection *sec = finfo->sections[symndx]->output_section; + const char *name; + + name = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym.st_name); + if (name == NULL) + return FALSE; + + sym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, + sec); + if (sym.st_shndx == SHN_BAD) + return FALSE; + + sym.st_value += o->output_offset; + + finfo->indices[symndx] = bfd_get_symcount (output_bfd); + if (! elf_link_output_sym (finfo, name, &sym, o, NULL)) + return FALSE; + } + elf_section_data (osec)->this_hdr.sh_info + = finfo->indices[symndx]; + } + } + if ((o->flags & SEC_HAS_CONTENTS) == 0 || (o->size == 0 && (o->flags & SEC_RELOC) == 0)) continue; |