/* BFD back-end for HP PA-RISC ELF files.
- Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+ Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
Written by
static bfd_reloc_status_type hppa_elf_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd*, char **));
-static CONST reloc_howto_type * elf_hppa_reloc_type_lookup
+static reloc_howto_type * elf_hppa_reloc_type_lookup
PARAMS ((bfd *, bfd_reloc_code_real_type));
static boolean elf32_hppa_set_section_contents
const char **, flagword *, asection **, bfd_vma *));
static bfd_reloc_status_type elf32_hppa_bfd_final_link_relocate
- PARAMS ((const reloc_howto_type *, bfd *, bfd *, asection *,
+ PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
bfd_byte *, bfd_vma, bfd_vma, bfd_vma, struct bfd_link_info *,
asection *, const char *, int));
for (; rel < relend; rel++)
{
int r_type;
- const reloc_howto_type *howto;
+ reloc_howto_type *howto;
long r_symndx;
struct elf_link_hash_entry *h;
Elf_Internal_Sym *sym;
indx = r_symndx - symtab_hdr->sh_info;
h = elf_sym_hashes (input_bfd)[indx];
- if (h->root.type == bfd_link_hash_defined)
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
{
sym_sec = h->root.u.def.section;
relocation = (h->root.u.def.value
+ sym_sec->output_offset
+ sym_sec->output_section->vma);
}
- else if (h->root.type == bfd_link_hash_weak)
+ else if (h->root.type == bfd_link_hash_undefweak)
relocation = 0;
else
{
(info, h->root.root.string, input_bfd,
input_section, rel->r_offset)))
return false;
- relocation = 0;
+ break;
}
}
sym_name = h->root.root.string;
else
{
- sym_name = elf_string_from_elf_section (input_bfd,
- symtab_hdr->sh_link,
- sym->st_name);
+ sym_name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
if (sym_name == NULL)
return false;
if (*sym_name == '\0')
{
switch (r)
{
+ /* This can happen for DP relative relocs if $global$ is
+ undefined. This is a panic situation so we don't try
+ to continue. */
+ case bfd_reloc_undefined:
+ case bfd_reloc_notsupported:
+ if (!((*info->callbacks->undefined_symbol)
+ (info, "$global$", input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ return false;
case bfd_reloc_dangerous:
{
/* We use this return value to indicate that we performed
if (!strcmp (section->name, ".PARISC.symextn") && !symext_chain_size)
return true;
else
- return bfd_elf32_set_section_contents (abfd, section, location,
- offset, count);
+ return _bfd_elf_set_section_contents (abfd, section, location,
+ offset, count);
}
/* Translate from an elf into field into a howto relocation pointer. */
elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd,
input_section, contents, offset, value,
addend, info, sym_sec, sym_name, is_local)
- const reloc_howto_type *howto;
+ reloc_howto_type *howto;
bfd *input_bfd;
bfd *output_bfd;
asection *input_section;
if (h == NULL)
return bfd_reloc_notsupported;
+ /* If $global$ isn't a defined symbol, then we're still in deep
+ trouble. */
+ if (h->root.type != bfd_link_hash_defined)
+ return bfd_reloc_undefined;
+
sec = h->root.u.def.section;
elf32_hppa_hash_table (info)->global_value = (h->root.u.def.value
+ sec->output_section->vma
case R_PARISC_DPREL21L:
r_field = e_lrsel;
if (sym_sec->flags & SEC_CODE)
- insn &= ~0x03e00000;
+ {
+ if ((insn & 0xfc000000) >> 26 == 0xa
+ && (insn & 0x03e00000) >> 21 == 0x1b)
+ insn &= ~0x03e00000;
+ }
else
value -= elf32_hppa_hash_table (info)->global_value;
goto do_basic_type_1;
/* Return the address of the howto table entry to perform the CODE
relocation for an ARCH machine. */
-static CONST reloc_howto_type *
+static reloc_howto_type *
elf_hppa_reloc_type_lookup (abfd, code)
bfd *abfd;
bfd_reloc_code_real_type code;
hdr = elf_elfsections (input_bfd)[local_syms[current_index].st_shndx];
sym_sec = hdr->bfd_section;
- sym_name = elf_string_from_elf_section (input_bfd,
+ sym_name = bfd_elf_string_from_elf_section (input_bfd,
symtab_hdr->sh_link,
local_syms[current_index].st_name);
len = strlen (sym_name) + 10;
struct bfd_link_info *link_info;
{
bfd *input_bfd;
- asection *section, *stub_sec;
+ asection *section, *stub_sec = 0;
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Sym *local_syms, *isym, **all_local_syms;
Elf32_External_Sym *ext_syms, *esym;
sym = local_syms + r_index;
hdr = elf_elfsections (input_bfd)[sym->st_shndx];
sym_sec = hdr->bfd_section;
- sym_name = elf_string_from_elf_section (input_bfd,
- symtab_hdr->sh_link,
- sym->st_name);
+ sym_name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
sym_value = (ELF_ST_TYPE (sym->st_info) == STT_SECTION
? 0 : sym->st_value);
destination = (sym_value
index = r_index - symtab_hdr->sh_info;
hash = elf_sym_hashes (input_bfd)[index];
- if (hash->root.type == bfd_link_hash_defined)
+ if (hash->root.type == bfd_link_hash_defined
+ || hash->root.type == bfd_link_hash_defweak)
{
sym_sec = hash->root.u.def.section;
sym_name = hash->root.root.string;
elf32_hppa_hash_table(link_info)->args_hash_table = NULL;
free (args_hash_table);
}
+ /* Set the size of the stub section to zero since we're never going
+ to create them. Avoids losing when we try to get its contents
+ too. */
+ bfd_set_section_size (stub_bfd, stub_sec, 0);
return false;
}