#define TARGETNAME "a.out-hp300hpux"
#define MY(OP) CONCAT2 (hp300hpux_,OP)
#define external_exec hp300hpux_exec_bytes
#define external_nlist hp300hpux_nlist_bytes
#include "aout/hp300hpux.h"
#define e_strx e_shlib
#define e_other e_length
#define e_desc e_almod
#define AR_PAD_CHAR '/'
#define TARGET_IS_BIG_ENDIAN_P
#define DEFAULT_ARCH bfd_arch_m68k
#define MY_get_section_contents aout_32_get_section_contents
#define MY_slurp_armap bfd_slurp_bsd_armap_f2
#define MY_canonicalize_symtab hp300hpux_canonicalize_symtab
#define MY_get_symtab_upper_bound hp300hpux_get_symtab_upper_bound
#define MY_canonicalize_reloc hp300hpux_canonicalize_reloc
#define MY_write_object_contents hp300hpux_write_object_contents
#define MY_read_minisymbols _bfd_generic_read_minisymbols
#define MY_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
#define MY_final_link_callback unused
#define MY_bfd_final_link _bfd_generic_final_link
#define MY_bfd_free_cached_info bfd_true
#define hp300hpux_write_syms aout_32_write_syms
#define MY_callback MY(callback)
#define MY_exec_hdr_flags 0x2
#define NAME_swap_exec_header_in NAME(hp300hpux_32_,swap_exec_header_in)
#define HP_SYMTYPE_UNDEFINED 0x00
#define HP_SYMTYPE_ABSOLUTE 0x01
#define HP_SYMTYPE_TEXT 0x02
#define HP_SYMTYPE_DATA 0x03
#define HP_SYMTYPE_BSS 0x04
#define HP_SYMTYPE_COMMON 0x05
#define HP_SYMTYPE_TYPE 0x0F
#define HP_SYMTYPE_FILENAME 0x1F
#define HP_SYMTYPE_ALIGN 0x10
#define HP_SYMTYPE_EXTERNAL 0x20
#define HP_SECONDARY_SYMBOL 0x40
#define HP_RSEGMENT_TEXT 0x00
#define HP_RSEGMENT_DATA 0x01
#define HP_RSEGMENT_BSS 0x02
#define HP_RSEGMENT_EXTERNAL 0x03
#define HP_RSEGMENT_PCREL 0x04
#define HP_RSEGMENT_RDLT 0x05
#define HP_RSEGMENT_RPLT 0x06
#define HP_RSEGMENT_NOOP 0x3F
#define HP_RLENGTH_BYTE 0x00
#define HP_RLENGTH_WORD 0x01
#define HP_RLENGTH_LONG 0x02
#define HP_RLENGTH_ALIGN 0x03
#define NAME(x,y) CONCAT3 (hp300hpux,_32_,y)
#define ARCH_SIZE 32
#define BMAGIC HPUX_DOT_O_MAGIC
#define QMAGIC 0314
#include "aoutx.h"
static const bfd_target * MY (callback)
PARAMS ((bfd *));
static bfd_boolean MY (write_object_contents)
PARAMS ((bfd *));
static void convert_sym_type
PARAMS ((struct external_nlist *, aout_symbol_type *, bfd *));
bfd_boolean MY (slurp_symbol_table)
PARAMS ((bfd *));
void MY (swap_std_reloc_in)
PARAMS ((bfd *, struct hp300hpux_reloc *, arelent *, asymbol **,
bfd_size_type));
bfd_boolean MY (slurp_reloc_table)
PARAMS ((bfd *, sec_ptr, asymbol **));
long MY (canonicalize_symtab)
PARAMS ((bfd *, asymbol **));
long MY (get_symtab_upper_bound)
PARAMS ((bfd *));
long MY (canonicalize_reloc)
PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
#define SYM_EXTRA_BYTES 1024
static const bfd_target *
MY (callback) (abfd)
bfd *abfd;
{
struct internal_exec *execp = exec_hdr (abfd);
obj_textsec (abfd)->size = N_TXTSIZE (*execp);
obj_textsec (abfd)->vma = N_TXTADDR (*execp);
obj_datasec (abfd)->vma = N_DATADDR (*execp);
obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
obj_datasec (abfd)->filepos = N_DATOFF (*execp);
obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
obj_sym_filepos (abfd) = N_SYMOFF (*execp);
obj_str_filepos (abfd) = N_STROFF (*execp);
#ifdef SET_ARCH_MACH
SET_ARCH_MACH (abfd, *execp);
#else
bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0);
#endif
if (obj_aout_subformat (abfd) == gnu_encap_format)
{
obj_textsec (abfd)->rel_filepos = N_GNU_TRELOFF (*execp);
obj_datasec (abfd)->rel_filepos = N_GNU_DRELOFF (*execp);
obj_sym_filepos (abfd) = N_GNU_SYMOFF (*execp);
obj_str_filepos (abfd) = (obj_sym_filepos (abfd) + execp->a_syms);
abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
bfd_get_symcount (abfd) = execp->a_syms / 12;
obj_symbol_entry_size (abfd) = 12;
obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
}
return abfd->xvec;
}
extern bfd_boolean aout_32_write_syms
PARAMS ((bfd * abfd));
static bfd_boolean
MY (write_object_contents) (abfd)
bfd *abfd;
{
struct external_exec exec_bytes;
struct internal_exec *execp = exec_hdr (abfd);
bfd_size_type text_size;
file_ptr text_end;
memset (&exec_bytes, 0, sizeof (exec_bytes));
obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
if (adata (abfd).magic == undecided_magic)
NAME (aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
execp->a_syms = 0;
execp->a_entry = bfd_get_start_address (abfd);
execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
obj_reloc_entry_size (abfd));
execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
obj_reloc_entry_size (abfd));
N_SET_MACHTYPE (*execp, 0xc);
N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
NAME (aout,swap_exec_header_out) (abfd, execp, &exec_bytes);
H_PUT_32 (abfd, (bfd_get_symcount (abfd) * 12), exec_bytes.e_drelocs);
if (bfd_seek (abfd, (file_ptr) 0, FALSE) != 0
|| (bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
!= EXEC_BYTES_SIZE))
return FALSE;
if (bfd_get_symcount (abfd) != 0)
{
if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp) + execp->a_drsize),
SEEK_SET) != 0)
return FALSE;
}
if (!MY (write_syms) (abfd))
return FALSE;
if (bfd_get_symcount (abfd) != 0)
{
if (bfd_seek (abfd, (file_ptr) N_TRELOFF (*execp), SEEK_CUR) != 0)
return FALSE;
if (!NAME (aout,squirt_out_relocs) (abfd, obj_textsec (abfd)))
return FALSE;
if (bfd_seek (abfd, (file_ptr) N_DRELOFF (*execp), SEEK_CUR) != 0)
return FALSE;
if (!NAME (aout,squirt_out_relocs) (abfd, obj_datasec (abfd)))
return FALSE;
}
return TRUE;
}
static void
convert_sym_type (sym_pointer, cache_ptr, abfd)
struct external_nlist *sym_pointer ATTRIBUTE_UNUSED;
aout_symbol_type *cache_ptr;
bfd *abfd ATTRIBUTE_UNUSED;
{
int name_type;
int new_type;
name_type = (cache_ptr->type);
new_type = 0;
if ((name_type & HP_SYMTYPE_ALIGN) != 0)
{
name_type = 0;
}
if (name_type == HP_SYMTYPE_FILENAME)
new_type = N_FN;
else
{
switch (name_type & HP_SYMTYPE_TYPE)
{
case HP_SYMTYPE_UNDEFINED:
new_type = N_UNDF;
break;
case HP_SYMTYPE_ABSOLUTE:
new_type = N_ABS;
break;
case HP_SYMTYPE_TEXT:
new_type = N_TEXT;
break;
case HP_SYMTYPE_DATA:
new_type = N_DATA;
break;
case HP_SYMTYPE_BSS:
new_type = N_BSS;
break;
case HP_SYMTYPE_COMMON:
new_type = N_COMM;
break;
default:
abort ();
break;
}
if (name_type & HP_SYMTYPE_EXTERNAL)
new_type |= N_EXT;
if (name_type & HP_SECONDARY_SYMBOL)
{
switch (new_type)
{
default:
abort ();
case N_UNDF | N_EXT:
if (cache_ptr->symbol.value == 0)
new_type = N_WEAKU;
break;
case N_ABS | N_EXT:
new_type = N_WEAKA;
break;
case N_TEXT | N_EXT:
new_type = N_WEAKT;
break;
case N_DATA | N_EXT:
new_type = N_WEAKD;
break;
case N_BSS | N_EXT:
new_type = N_WEAKB;
break;
}
}
}
cache_ptr->type = new_type;
}
void
NAME (aout,swap_exec_header_in) (abfd, raw_bytes, execp)
bfd *abfd;
struct external_exec *raw_bytes;
struct internal_exec *execp;
{
struct external_exec *bytes = (struct external_exec *) raw_bytes;
memset (execp, 0, sizeof (struct internal_exec));
execp->a_info = H_GET_32 (abfd, bytes->e_info);
execp->a_text = GET_WORD (abfd, bytes->e_text);
execp->a_data = GET_WORD (abfd, bytes->e_data);
execp->a_bss = GET_WORD (abfd, bytes->e_bss);
execp->a_syms = GET_WORD (abfd, bytes->e_syms);
execp->a_entry = GET_WORD (abfd, bytes->e_entry);
execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
do
{
long syms;
struct aout_data_struct *rawptr;
bfd_size_type amt;
if (H_GET_32 (abfd, bytes->e_passize) != 0)
break;
if (H_GET_32 (abfd, bytes->e_syms) != 0)
break;
if (H_GET_32 (abfd, bytes->e_supsize) != 0)
break;
syms = H_GET_32 (abfd, bytes->e_drelocs);
if (syms == 0)
break;
execp->a_syms = syms;
amt = sizeof (*rawptr);
rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
if (rawptr == NULL)
return;
abfd->tdata.aout_data = rawptr;
obj_aout_subformat (abfd) = gnu_encap_format;
}
while (0);
}
bfd_boolean
MY (slurp_symbol_table) (abfd)
bfd *abfd;
{
bfd_size_type symbol_bytes;
struct external_nlist *syms;
struct external_nlist *sym_pointer;
struct external_nlist *sym_end;
char *strings;
aout_symbol_type *cached;
unsigned num_syms = 0;
bfd_size_type amt;
if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
return TRUE;
symbol_bytes = exec_hdr (abfd)->a_syms;
amt = symbol_bytes + SYM_EXTRA_BYTES;
strings = (char *) bfd_alloc (abfd, amt);
if (!strings)
return FALSE;
syms = (struct external_nlist *) (strings + SYM_EXTRA_BYTES);
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
|| bfd_bread ((PTR) syms, symbol_bytes, abfd) != symbol_bytes)
{
bfd_release (abfd, syms);
return FALSE;
}
sym_end = (struct external_nlist *) (((char *) syms) + symbol_bytes);
for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++, num_syms++)
{
sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +
sym_pointer->e_length[0]);
}
bfd_get_symcount (abfd) = num_syms;
amt = num_syms;
amt *= sizeof (aout_symbol_type);
cached = (aout_symbol_type *) bfd_zalloc (abfd, amt);
if (cached == NULL && num_syms != 0)
return FALSE;
{
aout_symbol_type *cache_ptr = cached;
aout_symbol_type cache_save;
for (sym_pointer = syms, cache_ptr = cached;
sym_pointer < sym_end; sym_pointer++, cache_ptr++)
{
unsigned int length;
cache_ptr->symbol.the_bfd = abfd;
cache_ptr->symbol.value = GET_SWORD (abfd, sym_pointer->e_value);
cache_ptr->desc = bfd_get_16 (abfd, sym_pointer->e_almod);
cache_ptr->type = bfd_get_8 (abfd, sym_pointer->e_type);
cache_ptr->symbol.udata.p = NULL;
length = bfd_get_8 (abfd, sym_pointer->e_length);
cache_ptr->other = length;
cache_save = *cache_ptr;
convert_sym_type (sym_pointer, cache_ptr, abfd);
if (!translate_from_native_sym_flags (abfd, cache_ptr))
return FALSE;
if (length)
{
cache_ptr->symbol.name = strings;
memcpy (strings, sym_pointer + 1, length);
strings[length] = '\0';
strings += length + 1;
}
else
cache_ptr->symbol.name = (char *) NULL;
sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +
length);
}
}
obj_aout_symbols (abfd) = cached;
return TRUE;
}
void
MY (swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
bfd *abfd;
struct hp300hpux_reloc *bytes;
arelent *cache_ptr;
asymbol **symbols;
bfd_size_type symcount ATTRIBUTE_UNUSED;
{
int r_index;
int r_extern = 0;
unsigned int r_length;
int r_pcrel = 0;
struct aoutdata *su = &(abfd->tdata.aout_data->a);
cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
r_index = H_GET_16 (abfd, bytes->r_index);
switch (bytes->r_type[0])
{
case HP_RSEGMENT_TEXT:
r_index = N_TEXT;
break;
case HP_RSEGMENT_DATA:
r_index = N_DATA;
break;
case HP_RSEGMENT_BSS:
r_index = N_BSS;
break;
case HP_RSEGMENT_EXTERNAL:
r_extern = 1;
break;
case HP_RSEGMENT_PCREL:
r_extern = 1;
r_pcrel = 1;
break;
case HP_RSEGMENT_RDLT:
break;
case HP_RSEGMENT_RPLT:
break;
case HP_RSEGMENT_NOOP:
break;
default:
abort ();
break;
}
switch (bytes->r_length[0])
{
case HP_RLENGTH_BYTE:
r_length = 0;
break;
case HP_RLENGTH_WORD:
r_length = 1;
break;
case HP_RLENGTH_LONG:
r_length = 2;
break;
default:
abort ();
break;
}
cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
if (r_pcrel && r_extern)
{
MOVE_ADDRESS (-cache_ptr->address);
}
else
{
MOVE_ADDRESS (0);
}
}
bfd_boolean
MY (slurp_reloc_table) (abfd, asect, symbols)
bfd *abfd;
sec_ptr asect;
asymbol **symbols;
{
bfd_size_type count;
bfd_size_type reloc_size;
PTR relocs;
arelent *reloc_cache;
size_t each_size;
struct hp300hpux_reloc *rptr;
unsigned int counter;
arelent *cache_ptr;
if (asect->relocation)
return TRUE;
if (asect->flags & SEC_CONSTRUCTOR)
return TRUE;
if (asect == obj_datasec (abfd))
{
reloc_size = exec_hdr (abfd)->a_drsize;
goto doit;
}
if (asect == obj_textsec (abfd))
{
reloc_size = exec_hdr (abfd)->a_trsize;
goto doit;
}
bfd_set_error (bfd_error_invalid_operation);
return FALSE;
doit:
if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
return FALSE;
each_size = obj_reloc_entry_size (abfd);
count = reloc_size / each_size;
reloc_cache = (arelent *) bfd_zalloc (abfd, count * sizeof (arelent));
if (!reloc_cache && count != 0)
return FALSE;
relocs = (PTR) bfd_alloc (abfd, reloc_size);
if (!relocs && reloc_size != 0)
{
bfd_release (abfd, reloc_cache);
return FALSE;
}
if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
{
bfd_release (abfd, relocs);
bfd_release (abfd, reloc_cache);
return FALSE;
}
rptr = (struct hp300hpux_reloc *) relocs;
counter = 0;
cache_ptr = reloc_cache;
for (; counter < count; counter++, rptr++, cache_ptr++)
{
MY (swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
(bfd_size_type) bfd_get_symcount (abfd));
}
bfd_release (abfd, relocs);
asect->relocation = reloc_cache;
asect->reloc_count = count;
return TRUE;
}
long aout_32_canonicalize_symtab
PARAMS ((bfd * abfd, asymbol ** location));
long aout_32_get_symtab_upper_bound
PARAMS ((bfd * abfd));
long aout_32_canonicalize_reloc
PARAMS ((bfd * abfd, sec_ptr section, arelent ** relptr,
asymbol ** symbols));
long
MY (canonicalize_symtab) (abfd, location)
bfd *abfd;
asymbol **location;
{
unsigned int counter = 0;
aout_symbol_type *symbase;
if (obj_aout_subformat (abfd) == gnu_encap_format)
return aout_32_canonicalize_symtab (abfd, location);
if (!MY (slurp_symbol_table) (abfd))
return -1;
for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
*(location++) = (asymbol *) (symbase++);
*location++ = 0;
return bfd_get_symcount (abfd);
}
long
MY (get_symtab_upper_bound) (abfd)
bfd *abfd;
{
if (obj_aout_subformat (abfd) == gnu_encap_format)
return aout_32_get_symtab_upper_bound (abfd);
if (!MY (slurp_symbol_table) (abfd))
return -1;
return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));
}
long
MY (canonicalize_reloc) (abfd, section, relptr, symbols)
bfd *abfd;
sec_ptr section;
arelent **relptr;
asymbol **symbols;
{
arelent *tblptr = section->relocation;
unsigned int count;
if (obj_aout_subformat (abfd) == gnu_encap_format)
return aout_32_canonicalize_reloc (abfd, section, relptr, symbols);
if (!(tblptr || MY (slurp_reloc_table) (abfd, section, symbols)))
return -1;
if (section->flags & SEC_CONSTRUCTOR)
{
arelent_chain *chain = section->constructor_chain;
for (count = 0; count < section->reloc_count; count++)
{
*relptr++ = &chain->relent;
chain = chain->next;
}
}
else
{
tblptr = section->relocation;
for (count = 0; count++ < section->reloc_count;)
{
*relptr++ = tblptr++;
}
}
*relptr = 0;
return section->reloc_count;
}
#include "aout-target.h"