struct elf_x86_relative_reloc_data *relative_reloc,
Elf_Internal_Rela *rel, asection *sec,
asection *sym_sec, struct elf_link_hash_entry *h,
- Elf_Internal_Sym *sym, bfd_vma offset)
+ Elf_Internal_Sym *sym, bfd_vma offset, bool *keep_symbuf_p)
{
bfd_size_type newidx;
{
relative_reloc->data[newidx].sym = sym;
relative_reloc->data[newidx].u.sym_sec = sym_sec;
+ /* We must keep the symbol buffer since SYM will be used later. */
+ *keep_symbuf_p = true;
}
relative_reloc->data[newidx].offset = offset;
relative_reloc->data[newidx].address = 0;
bfd_vma *local_got_offsets;
bool is_x86_64;
bool unaligned_section;
+ bool return_status = false;
+ bool keep_symbuf = false;
if (bfd_link_relocatable (info))
return true;
/* Load the relocations for this section. */
internal_relocs =
- _bfd_elf_link_read_relocs (abfd, input_section, NULL,
- (Elf_Internal_Rela *) NULL,
- info->keep_memory);
+ _bfd_elf_link_info_read_relocs (abfd, info, input_section, NULL,
+ (Elf_Internal_Rela *) NULL,
+ info->keep_memory);
if (internal_relocs == NULL)
return false;
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
- isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
- symtab_hdr->sh_info, 0,
- NULL, NULL, NULL);
- if (isymbuf == NULL)
- goto error_return;
+ {
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info,
+ 0, NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
}
isym = isymbuf + r_symndx;
if (!elf_x86_relative_reloc_record_add (info,
&htab->relative_reloc,
irel, htab->elf.sgot,
- sec, h, isym, offset))
+ sec, h, isym, offset,
+ &keep_symbuf))
goto error_return;
continue;
((unaligned_section || unaligned_offset)
? &htab->unaligned_relative_reloc
: &htab->relative_reloc),
- irel, input_section, sec, h, isym, offset))
+ irel, input_section, sec, h, isym, offset,
+ &keep_symbuf))
goto error_return;
}
}
input_section->relative_reloc_packed = 1;
- return true;
+ return_status = true;
error_return:
if ((unsigned char *) isymbuf != symtab_hdr->contents)
- free (isymbuf);
+ {
+ /* Cache the symbol buffer if it must be kept. */
+ if (keep_symbuf)
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ else
+ free (isymbuf);
+ }
if (elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
- return false;
+ return return_status;
}
/* Add an entry to the 64-bit DT_RELR bitmap. */