/* BFD back-end for HP PA-RISC ELF files.
- Copyright (C) 1990-1991 Free Software Foundation, Inc.
+ Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Written by
#include "sysdep.h"
#include "libbfd.h"
#include "obstack.h"
+#include "bfdlink.h"
#include "libelf.h"
/* ELF32/HPPA relocation support
/* ELF/PA relocation howto entries */
-static bfd_reloc_status_type hppa_elf_reloc ();
+static bfd_reloc_status_type hppa_elf_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
{
static boolean symext_chain_built;
static unsigned long
-DEFUN (hppa_elf_rebuild_insn, (abfd, insn, value, r_type, r_field, r_format),
- bfd * abfd AND
- unsigned long insn AND
- unsigned long value AND
- unsigned short r_type AND
- unsigned short r_field AND
- unsigned short r_format)
+hppa_elf_rebuild_insn (abfd, insn, value, r_type, r_field, r_format)
+ bfd *abfd;
+ unsigned long insn;
+ unsigned long value;
+ unsigned short r_type;
+ unsigned short r_field;
+ unsigned short r_format;
{
unsigned long const_part; /* part of the instruction that does not change */
unsigned long rebuilt_part;
}
static unsigned long
-DEFUN (hppa_elf_relocate_insn,
- (abfd, input_sect,
- insn, address, symp, sym_value, r_addend,
- r_type, r_format, r_field, pcrel),
- bfd * abfd AND
- asection * input_sect AND
- unsigned long insn AND
- unsigned long address AND
- asymbol * symp AND
- long sym_value AND
- long r_addend AND
- unsigned short r_type AND
- unsigned short r_format AND
- unsigned short r_field AND
- unsigned char pcrel)
+hppa_elf_relocate_insn (abfd, input_sect,
+ insn, address, symp, sym_value, r_addend,
+ r_type, r_format, r_field, pcrel)
+ bfd *abfd;
+ asection *input_sect;
+ unsigned long insn;
+ unsigned long address;
+ asymbol *symp;
+ long sym_value;
+ long r_addend;
+ unsigned short r_type;
+ unsigned short r_format;
+ unsigned short r_field;
+ unsigned char pcrel;
{
unsigned char opcode = get_opcode (insn);
long constant_value;
}
static void
-DEFUN (hppa_elf_relocate_unwind_table,
- (abfd, input_sect,
- data, address, symp, sym_value, r_addend,
- r_type, r_format, r_field, pcrel),
- bfd * abfd AND
- asection * input_sect AND
- PTR data AND
- unsigned long address AND
- asymbol * symp AND
- long sym_value AND
- long r_addend AND
- unsigned short r_type AND
- unsigned short r_format AND
- unsigned short r_field AND
- unsigned char pcrel)
+hppa_elf_relocate_unwind_table (abfd, input_sect,
+ data, address, symp, sym_value, r_addend,
+ r_type, r_format, r_field, pcrel)
+ bfd *abfd;
+ asection *input_sect;
+ PTR data;
+ unsigned long address;
+ asymbol *symp;
+ long sym_value;
+ long r_addend;
+ unsigned short r_type;
+ unsigned short r_format;
+ unsigned short r_field;
+ unsigned char pcrel;
{
bfd_byte *hit_data = address + (bfd_byte *) (data);
long start_offset;
final_type = R_HPPA_PLABEL_32;
break;
case e_tsel:
- final_type == R_HPPA_DLT_32;
+ final_type = R_HPPA_DLT_32;
break;
default:
UNDEFINED;
static int global_sym_defined;
static bfd_reloc_status_type
-hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
+hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol_in;
PTR data;
asection *input_section;
bfd *output_bfd;
+ char **error_message;
{
unsigned long insn;
long sym_value = 0;
break;
default:
- fprintf (stderr, "Relocation problem : ");
- fprintf (stderr, "Unrecognized reloc type %d, in module %s\n",
- r_type, abfd->filename);
+ *error_message = (char *) "Unrecognized reloc";
return bfd_reloc_dangerous;
}
void
-DEFUN (elf_hppa_tc_symbol, (abfd, symbolP, sym_idx),
- bfd * abfd AND
- elf_symbol_type * symbolP AND
- int sym_idx)
+elf_hppa_tc_symbol (abfd, symbolP, sym_idx)
+ bfd *abfd;
+ elf_symbol_type *symbolP;
+ int sym_idx;
{
symext_chainS *symextP;
unsigned int arg_reloc;
static unsigned int symextn_contents_real_size;
void
-DEFUN (elf_hppa_tc_make_sections, (abfd, ignored),
- bfd * abfd AND
- PTR ignored)
+elf_hppa_tc_make_sections (abfd, ignored)
+ bfd *abfd;
+ PTR ignored;
{
symext_chainS *symextP;
int size;
int *stub_secp; /* pointer to the next available location in the buffer */
char *stub_contents; /* contents of the stubs for this bfd */
elf32_hppa_stub_name_list *stub_listP;
+ struct bfd_link_info *link_info;
}
elf32_hppa_stub_description;
}
static elf32_hppa_stub_description *
-new_stub (abfd, stub_sec)
+new_stub (abfd, stub_sec, link_info)
bfd *abfd;
asection *stub_sec;
+ struct bfd_link_info *link_info;
{
elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
stub->allocated_size = 0;
stub->stub_contents = NULL;
stub->stub_secp = NULL;
+ stub->link_info = link_info;
stub->next = elf_hppa_stub_rootP;
elf_hppa_stub_rootP = stub;
/* Locate the stub by the given name. */
static elf32_hppa_stub_name_list *
-add_stub_by_name(abfd, stub_sec, sym)
+add_stub_by_name(abfd, stub_sec, sym, link_info)
bfd *abfd;
asection *stub_sec;
asymbol *sym;
+ struct bfd_link_info *link_info;
{
elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
elf32_hppa_stub_name_list *stub_entry;
if (!stub)
- stub = new_stub(abfd, stub_sec);
+ stub = new_stub(abfd, stub_sec, link_info);
if (stub)
{
hppa_elf_stub_finish (output_bfd)
bfd *output_bfd;
{
- extern bfd_error_vector_type bfd_error_vector;
elf32_hppa_stub_description *stub_list = elf_hppa_stub_rootP;
/* All the stubs have been built. Finish up building */
/* stub section. Apply relocations to the section. */
for (parent = reloc_vector; *parent != (arelent *) NULL;
parent++)
{
+ char *err = (char *) NULL;
bfd_reloc_status_type r =
- bfd_perform_relocation (stub_bfd,
- *parent,
- stub_list->stub_contents,
- stub_sec, 0);
+ bfd_perform_relocation (stub_bfd,
+ *parent,
+ stub_list->stub_contents,
+ stub_sec, (bfd *) NULL, &err);
if (r != bfd_reloc_ok)
{
+ struct bfd_link_info *link_info = stub_list->link_info;
+
switch (r)
{
case bfd_reloc_undefined:
- bfd_error_vector.undefined_symbol (*parent, NULL);
+ if (! ((*link_info->callbacks->undefined_symbol)
+ (link_info,
+ bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ stub_bfd, stub_sec, (*parent)->address)))
+ abort ();
break;
case bfd_reloc_dangerous:
- bfd_error_vector.reloc_dangerous (*parent, NULL);
+ if (! ((*link_info->callbacks->reloc_dangerous)
+ (link_info, err, stub_bfd, stub_sec,
+ (*parent)->address)))
+ abort ();
break;
- case bfd_reloc_outofrange:
case bfd_reloc_overflow:
- bfd_error_vector.reloc_value_truncated (*parent, NULL);
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info,
+ bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ (*parent)->howto->name,
+ (*parent)->addend,
+ stub_bfd, stub_sec,
+ (*parent)->address)))
+ abort ();
+ }
break;
+ case bfd_reloc_outofrange:
default:
abort ();
break;
{
stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
- stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
+ stub_desc->stub_sec->relocation = (arelent *) bfd_zmalloc (size);
}
else
{
target_sym, /* the target symbol */
offset, /* the offset within the stub buffer (pre-calculated) */
type)
-elf32_hppa_stub_description *stub_desc;
-bfd *output_bfd;
-asymbol *target_sym;
-int offset;
-elf32_hppa_reloc_type type;
+ elf32_hppa_stub_description *stub_desc;
+ bfd *output_bfd;
+ asymbol *target_sym;
+ int offset;
+ elf32_hppa_reloc_type type;
{
/* Allocate a new relocation entry. */
arelent relent;
{
stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
- stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
+ stub_desc->stub_sec->relocation = (arelent *) bfd_zmalloc (size);
}
else
{
}
asymbol *
-hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
+hppa_elf_build_arg_reloc_stub (abfd, output_bfd, link_info, reloc_entry,
stub_types, rtn_adjust, data)
bfd *abfd;
bfd *output_bfd;
+ struct bfd_link_info *link_info;
arelent *reloc_entry;
int stub_types[5];
int rtn_adjust;
stub_sec->output_section = output_text_section->output_section;
stub_sec->output_offset = 0;
bfd_set_section_alignment (abfd, stub_sec, 2);
- stub_desc = new_stub (abfd, stub_sec);
+ stub_desc = new_stub (abfd, stub_sec, link_info);
}
/* Make the stub if we did not find one already. */
if (!stub_desc)
- stub_desc = new_stub (abfd, stub_sec);
+ stub_desc = new_stub (abfd, stub_sec, link_info);
/* Allocate space to write the stub.
FIXME. Why using realloc?!? */
= (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
stub_sym->section = stub_sec;
stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
- stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym);
+ stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
/* Redirect the original relocation from the old symbol (a function)
to the stub (the stub calls the function). Change the type of
{
NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
}
+ else
+ NEW_INSTRUCTION (stub_entry, COPY_31_2);
/* Save the return address. */
NEW_INSTRUCTION (stub_entry, STW_RP_M8SP);
}
asymbol *
-hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
+hppa_elf_build_long_branch_stub (abfd, output_bfd, link_info, reloc_entry,
+ symbol, data)
bfd *abfd;
bfd *output_bfd;
+ struct bfd_link_info *link_info;
arelent *reloc_entry;
asymbol *symbol;
unsigned *data;
}
bfd_set_section_alignment (abfd, stub_sec, 2);
- stub_desc = new_stub (abfd, stub_sec);
+ stub_desc = new_stub (abfd, stub_sec, link_info);
}
if (!stub_desc)
- stub_desc = new_stub (abfd, stub_sec);
+ stub_desc = new_stub (abfd, stub_sec, link_info);
/* Allocate memory to contain the stub. FIXME. Why isn't this using
the BFD memory allocation routines? */
= (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
stub_sym->section = stub_sec;
stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
- stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym);
+ stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
/* Change symbol associated with the original relocation to point
to the stub.
asymbol *
hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
- syms, new_sym_cnt)
+ syms, new_sym_cnt, link_info)
bfd *stub_bfd;
bfd *abfd;
bfd *output_bfd;
asection *asec;
asymbol **syms;
int *new_sym_cnt;
+ struct bfd_link_info *link_info;
{
int i;
int stub_types[5];
R_HPPA_STUB_CALL_17) it will be possible to perform
the code reorientation. */
r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
- rle, stub_types,
+ link_info, rle,
+ stub_types,
true, insn);
new_syms[new_cnt++] = *r;
}
realloc (new_syms, (new_max * sizeof (asymbol)));
}
r = hppa_elf_build_long_branch_stub (stub_bfd, output_bfd,
- rle,
+ link_info, rle,
rle->sym_ptr_ptr[0],
insn);
new_syms[new_cnt++] = *r;
}
}
r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
- rle, stub_types,
+ link_info, rle,
+ stub_types,
rtn_adjust, insn);
new_syms[new_cnt++] = *r;
}
#define STUB_ALLOC_INCR 100
boolean
-DEFUN (hppa_elf_set_section_contents, (abfd, section, location, offset, count),
- bfd * abfd AND
- sec_ptr section AND
- PTR location AND
- file_ptr offset AND
- bfd_size_type count)
+hppa_elf_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
{
if ( strcmp(section->name, ".hppa_linker_stubs") == 0 )
{
}
static void
-DEFUN (elf_info_to_howto, (abfd, cache_ptr, dst),
- bfd * abfd AND
- arelent * cache_ptr AND
- Elf32_Internal_Rela * dst)
+elf_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rela *dst;
{
BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_HPPA_UNIMPLEMENTED);
cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE(dst->r_info)];
}
static void
-DEFUN (elf32_hppa_backend_symbol_processing, (abfd, sym),
- bfd * abfd AND
- asymbol * sym)
+elf32_hppa_backend_symbol_processing (abfd, sym)
+ bfd *abfd;
+ asymbol *sym;
{
/* Is this a definition of $global$? If so, keep it because it will be
needed if any relocations are performed. */
static int elf32_hppa_symextn_map_size;
static boolean
-DEFUN (elf32_hppa_backend_symbol_table_processing, (abfd, esyms,symcnt),
- bfd * abfd AND
- elf_symbol_type *esyms AND
- int symcnt)
+elf32_hppa_backend_symbol_table_processing (abfd, esyms,symcnt)
+ bfd *abfd;
+ elf_symbol_type *esyms;
+ int symcnt;
{
Elf32_Internal_Shdr *symextn_hdr = bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME);
int i;
#define elf_backend_symbol_table_processing elf32_hppa_backend_symbol_table_processing
static boolean
-DEFUN (elf32_hppa_backend_section_processing, (abfd, secthdr),
- bfd * abfd AND
- Elf32_Internal_Shdr *secthdr)
+elf32_hppa_backend_section_processing (abfd, secthdr)
+ bfd *abfd;
+ Elf32_Internal_Shdr *secthdr;
{
int i,j,k;
#define elf_backend_section_processing elf32_hppa_backend_section_processing
static boolean
-DEFUN (elf32_hppa_backend_section_from_shdr, (abfd, hdr, name),
- bfd * abfd AND
- Elf32_Internal_Shdr *hdr AND
- char * name)
+elf32_hppa_backend_section_from_shdr (abfd, hdr, name)
+ bfd *abfd;
+ Elf32_Internal_Shdr *hdr;
+ char *name;
{
asection *newsect;
#define elf_backend_section_from_shdr elf32_hppa_backend_section_from_shdr
static boolean
-DEFUN (elf32_hppa_backend_fake_sections, (abfd, secthdr, asect),
- bfd * abfd AND
- Elf_Internal_Shdr *secthdr AND
- asection *asect)
+elf32_hppa_backend_fake_sections (abfd, secthdr, asect)
+ bfd *abfd;
+ Elf_Internal_Shdr *secthdr;
+ asection *asect;
{
if ( strcmp(asect->name, ".hppa_symextn") == 0 )
#define elf_backend_fake_sections elf32_hppa_backend_fake_sections
static boolean
-DEFUN (elf32_hppa_backend_section_from_bfd_section, (abfd, hdr, asect, retval),
- bfd *abfd AND
- Elf32_Internal_Shdr *hdr AND
- asection *asect AND
- int *retval)
+elf32_hppa_backend_section_from_bfd_section (abfd, hdr, asect, retval)
+ bfd *abfd;
+ Elf32_Internal_Shdr *hdr;
+ asection *asect;
+ int *retval;
{
-
if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
{
if (hdr->rawdata)