+/* Convert the relocs R[0] thru R[-NUM_REL+1], which are all no-symbol
+ forms, to the equivalent relocs against the global symbol given by
+ STUB_ENTRY->H. */
+
+static bfd_boolean
+use_global_in_relocs (struct ppc_link_hash_table *htab,
+ struct ppc_stub_hash_entry *stub_entry,
+ Elf_Internal_Rela *r, unsigned int num_rel)
+{
+ struct elf_link_hash_entry **hashes;
+ unsigned long symndx;
+ struct ppc_link_hash_entry *h;
+ bfd_vma symval;
+
+ /* Relocs are always against symbols in their own object file. Fake
+ up global sym hashes for the stub bfd (which has no symbols). */
+ hashes = elf_sym_hashes (htab->params->stub_bfd);
+ if (hashes == NULL)
+ {
+ bfd_size_type hsize;
+
+ /* When called the first time, stub_globals will contain the
+ total number of symbols seen during stub sizing. After
+ allocating, stub_globals is used as an index to fill the
+ hashes array. */
+ hsize = (htab->stub_globals + 1) * sizeof (*hashes);
+ hashes = bfd_zalloc (htab->params->stub_bfd, hsize);
+ if (hashes == NULL)
+ return FALSE;
+ elf_sym_hashes (htab->params->stub_bfd) = hashes;
+ htab->stub_globals = 1;
+ }
+ symndx = htab->stub_globals++;
+ h = stub_entry->h;
+ hashes[symndx] = &h->elf;
+ if (h->oh != NULL && h->oh->is_func)
+ h = ppc_follow_link (h->oh);
+ BFD_ASSERT (h->elf.root.type == bfd_link_hash_defined
+ || h->elf.root.type == bfd_link_hash_defweak);
+ symval = (h->elf.root.u.def.value
+ + h->elf.root.u.def.section->output_offset
+ + h->elf.root.u.def.section->output_section->vma);
+ while (num_rel-- != 0)
+ {
+ r->r_info = ELF64_R_INFO (symndx, ELF64_R_TYPE (r->r_info));
+ if (h->elf.root.u.def.section != stub_entry->target_section)
+ {
+ /* H is an opd symbol. The addend must be zero, and the
+ branch reloc is the only one we can convert. */
+ r->r_addend = 0;
+ break;
+ }
+ else
+ r->r_addend -= symval;
+ --r;
+ }
+ return TRUE;
+}
+