+/* Return the name of the group signature symbol. Why isn't the
+ signature just a string? */
+
+static const char *
+group_signature (abfd, ghdr)
+ bfd *abfd;
+ Elf_Internal_Shdr *ghdr;
+{
+ struct elf_backend_data *bed;
+ file_ptr pos;
+ bfd_size_type amt;
+ Elf_Internal_Shdr *hdr;
+ Elf_Internal_Shdr *shndx_hdr;
+ unsigned char esym[sizeof (Elf64_External_Sym)];
+ Elf_External_Sym_Shndx eshndx;
+ Elf_Internal_Sym isym;
+ unsigned int iname;
+ unsigned int shindex;
+
+ /* First we need to ensure the symbol table is available. */
+ if (! bfd_section_from_shdr (abfd, ghdr->sh_link))
+ return NULL;
+
+ /* Go read the symbol. */
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ bed = get_elf_backend_data (abfd);
+ amt = bed->s->sizeof_sym;
+ pos = hdr->sh_offset + ghdr->sh_info * amt;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bread (esym, amt, abfd) != amt)
+ return NULL;
+
+ /* And possibly the symbol section index extension. */
+ shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (elf_elfsections (abfd) != NULL
+ && elf_elfsections (abfd)[shndx_hdr->sh_link] == hdr)
+ {
+ amt = sizeof (Elf_External_Sym_Shndx);
+ pos = shndx_hdr->sh_offset + ghdr->sh_info * amt;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bread ((PTR) &eshndx, amt, abfd) != amt)
+ return NULL;
+ }
+
+ /* Convert to internal format. */
+ (*bed->s->swap_symbol_in) (abfd, (const PTR *) &esym, (const PTR *) &eshndx,
+ &isym);
+
+ /* Look up the symbol name. */
+ iname = isym.st_name;
+ shindex = hdr->sh_link;
+ if (iname == 0 && ELF_ST_TYPE (isym.st_info) == STT_SECTION)
+ {
+ iname = elf_elfsections (abfd)[isym.st_shndx]->sh_name;
+ shindex = elf_elfheader (abfd)->e_shstrndx;
+ }
+
+ return bfd_elf_string_from_elf_section (abfd, shindex, iname);
+}
+