diff options
author | Alan Modra <amodra@gmail.com> | 2008-10-03 09:40:49 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2008-10-03 09:40:49 +0000 |
commit | bcacc0f587e22ba46333d9377e7e9e4576c90f74 (patch) | |
tree | 0035a6958c007460d3837b1e245b5f89edeb3661 /bfd/elflink.c | |
parent | 81ab4297b7f533d6750f073cad0fe6169f567e85 (diff) | |
download | gdb-bcacc0f587e22ba46333d9377e7e9e4576c90f74.zip gdb-bcacc0f587e22ba46333d9377e7e9e4576c90f74.tar.gz gdb-bcacc0f587e22ba46333d9377e7e9e4576c90f74.tar.bz2 |
bfd/
* elf.c (bfd_elf_set_group_contents): Assign sh_info for ld -r when
the signature symbol is global.
* elflink.c (elf_link_input_bfd): Ensure group signature symbol
is output when ld -r. Set group sh_info when local.
* linker.c (default_indirect_link_order): Handle group sections
specially.
ld/
* ldemul.c (ldemul_place_orphan): Add "name" param.
* ldemul.h (ldemul_place_orphan): Update prototype.
(struct ld_emulation_xfer_struct <place_orphan>): Likewise.
* ldlang.c (lang_place_orphans): Generate unique section names here..
* emultempl/elf32.em (place_orphan): ..rather than here. Don't
directly use an existing output section statement that has no
bfd section.
* emultempl/pe.em (place_orphan): Likewise.
* emultempl/pep.em (place_orphan): Likewise.
* emultempl/beos.em (place_orphan): Adjust.
* emultempl/spuelf.em (spu_place_special_section): Adjust
place_orphan call.
* emultempl/genelf.em (gld${EMULATION_NAME}_after_open): New function.
(LDEMUL_AFTER_OPEN): Define.
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; |