/* BFD support for the ns32k architecture.
- Copyright (C) 1990, 91, 94, 95, 96, 1998 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1994, 1995, 1998, 2000, 2001
+ Free Software Foundation, Inc.
Almost totally rewritten by Ian Dall from initial work
by Andrew Cagney.
{ 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compatible,bfd_default_scan, next, }
static const bfd_arch_info_type arch_info_struct[] =
-{
+{
N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
};
const bfd_arch_info_type bfd_ns32k_arch =
N(32032,"ns32k:32032",false, &arch_info_struct[0]);
-static long
-ns32k_sign_extend(value, bits)
- int value;
- int bits;
-{
- value = value & ((1 << bits) - 1);
- return (value & (1 << (bits-1))
- ? value | (~((1 << bits) - 1))
- : value);
-}
+static bfd_reloc_status_type do_ns32k_reloc
+ PARAMS ((bfd *, arelent *, struct symbol_cache_entry *, PTR, asection *,
+ bfd *, char **,
+ bfd_vma (*) (bfd_byte *, int),
+ int (*) (bfd_vma, bfd_byte *, int)));
-long
-_bfd_ns32k_get_displacement(buffer, offset, size)
+bfd_vma
+_bfd_ns32k_get_displacement (buffer, size)
bfd_byte *buffer;
- long offset;
- long size;
+ int size;
{
- long value;
- buffer += offset;
+ bfd_signed_vma value;
switch (size)
{
case 1:
- value = ns32k_sign_extend (*buffer, 7);
+ value = ((*buffer & 0x7f) ^ 0x40) - 0x40;
break;
+
case 2:
- value = ns32k_sign_extend(*buffer++, 6);
+ value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
value = (value << 8) | (0xff & *buffer);
break;
+
case 4:
- value = ns32k_sign_extend(*buffer++, 6);
+ value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
value = (value << 8) | (0xff & *buffer++);
value = (value << 8) | (0xff & *buffer++);
value = (value << 8) | (0xff & *buffer);
break;
+
default:
abort ();
return 0;
}
int
-_bfd_ns32k_put_displacement(value, buffer, offset, size)
- long value;
+_bfd_ns32k_put_displacement (value, buffer, size)
+ bfd_vma value;
bfd_byte *buffer;
- long offset;
- long size;
+ int size;
{
- buffer += offset;
switch (size)
{
case 1:
- if (value < -64 || value > 63)
+ if (value + 0x40 > 0x7f)
return -1;
- value&=0x7f;
- *buffer++=value;
+ value &= 0x7f;
+ *buffer++ = value;
break;
+
case 2:
- if (value < -8192 || value > 8191)
+ if (value + 0x2000 > 0x3fff)
return -1;
- value&=0x3fff;
- value|=0x8000;
- *buffer++=(value>>8);
- *buffer++=value;
+ value &= 0x3fff;
+ value |= 0x8000;
+ *buffer++ = (value >> 8);
+ *buffer++ = value;
break;
+
case 4:
- if (value < -0x1f000000 || value >= 0x20000000)
+ /* FIXME: is this correct? -0x1f000000 <= value < 0x2000000 */
+ if (value + 0x1f000000 > 0x3effffff)
return -1;
- value|=0xc0000000;
- *buffer++=(value>>24);
- *buffer++=(value>>16);
- *buffer++=(value>>8);
- *buffer++=value;
+ value |= (bfd_vma) 0xc0000000;
+ *buffer++ = (value >> 24);
+ *buffer++ = (value >> 16);
+ *buffer++ = (value >> 8);
+ *buffer++ = value;
break;
default:
return -1;
return 0;
}
-long
-_bfd_ns32k_get_immediate (buffer, offset, size)
+bfd_vma
+_bfd_ns32k_get_immediate (buffer, size)
bfd_byte *buffer;
- long offset;
- long size;
+ int size;
{
- long value = 0;
- buffer += offset;
+ bfd_vma value = 0;
switch (size)
{
+ case 8:
+ value = (value << 8) | (*buffer++ & 0xff);
+ value = (value << 8) | (*buffer++ & 0xff);
+ value = (value << 8) | (*buffer++ & 0xff);
+ value = (value << 8) | (*buffer++ & 0xff);
case 4:
value = (value << 8) | (*buffer++ & 0xff);
- case 3:
value = (value << 8) | (*buffer++ & 0xff);
case 2:
value = (value << 8) | (*buffer++ & 0xff);
}
int
-_bfd_ns32k_put_immediate (value, buffer, offset, size)
- long value;
+_bfd_ns32k_put_immediate (value, buffer, size)
+ bfd_vma value;
bfd_byte *buffer;
- long offset;
- long size;
+ int size;
{
- buffer += offset + size - 1;
+ buffer += size - 1;
switch (size)
{
+ case 8:
+ *buffer-- = (value & 0xff); value >>= 8;
+ *buffer-- = (value & 0xff); value >>= 8;
+ *buffer-- = (value & 0xff); value >>= 8;
+ *buffer-- = (value & 0xff); value >>= 8;
case 4:
*buffer-- = (value & 0xff); value >>= 8;
- case 3:
*buffer-- = (value & 0xff); value >>= 8;
case 2:
*buffer-- = (value & 0xff); value >>= 8;
PTR data;
asection *input_section;
bfd *output_bfd;
- char **error_message;
- long (*get_data)();
- int (*put_data)();
+ char **error_message ATTRIBUTE_UNUSED;
+ bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
+ int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
{
int overflow = 0;
bfd_vma relocation;
bfd_vma output_base = 0;
reloc_howto_type *howto = reloc_entry->howto;
asection *reloc_target_output_section;
+ bfd_byte *location;
if ((symbol->section == &bfd_abs_section)
&& output_bfd != (bfd *) NULL)
&& output_bfd == (bfd *) NULL)
flag = bfd_reloc_undefined;
-
/* Is the address of the relocation really within the section? */
if (reloc_entry->address > input_section->_cooked_size)
return bfd_reloc_outofrange;
else
relocation = symbol->value;
-
reloc_target_output_section = symbol->section->output_section;
/* Convert input-section-relative symbol value to absolute. */
reloc_entry->address += input_section->output_offset;
/* WTF?? */
- if (abfd->xvec->flavour == bfd_target_coff_flavour
- && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0)
+ if (abfd->xvec->flavour == bfd_target_coff_flavour)
{
#if 1
/* For m68k-coff, the addend was being subtracted twice during
bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
if (((bfd_vma) check & ~reloc_bits) != 0
- && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+ && (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 1 & ~reloc_bits)))
{
/* The above right shift is incorrect for a signed
value. See if turning on the upper bits fixes the
check |= ((bfd_vma) - 1
& ~((bfd_vma) - 1
>> (howto->rightshift - howto->bitpos)));
- if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+ if (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 1 & ~reloc_bits))
flag = bfd_reloc_overflow;
}
else
#define DOIT(x) \
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
+ location = (bfd_byte *) data + addr;
switch (howto->size)
{
case 0:
{
- char x = get_data (data, addr, 1);
+ char x = get_data (location, 1);
DOIT (x);
- overflow = put_data(x, data, addr, 1);
+ overflow = put_data ((bfd_vma) x, location, 1);
}
break;
case 1:
if (relocation)
{
- short x = get_data (data, addr, 2);
+ short x = get_data (location, 2);
DOIT (x);
- overflow = put_data(x, (unsigned char *) data, addr, 2);
+ overflow = put_data ((bfd_vma) x, location, 2);
}
break;
case 2:
if (relocation)
{
- long x = get_data (data, addr, 4);
+ long x = get_data (location, 4);
DOIT (x);
- overflow = put_data(x, data, addr, 4);
+ overflow = put_data ((bfd_vma) x, location, 4);
}
break;
case -2:
{
- long x = get_data(data, addr, 4);
+ long x = get_data (location, 4);
relocation = -relocation;
DOIT(x);
- overflow = put_data(x, data , addr, 4);
+ overflow = put_data ((bfd_vma) x, location, 4);
}
break;
#ifdef BFD64
if (relocation)
{
- bfd_vma x = get_data (data, addr, 8);
+ bfd_vma x = get_data (location, 8);
DOIT (x);
- overflow = put_data(x, data, addr, 8);
+ overflow = put_data (x, location, 8);
}
#else
abort ();
/* Relocate a given location using a given value and howto. */
bfd_reloc_status_type
-_bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
+_bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation, location,
get_data, put_data)
reloc_howto_type *howto;
- bfd *input_bfd;
+ bfd *input_bfd ATTRIBUTE_UNUSED;
bfd_vma relocation;
bfd_byte *location;
- long (*get_data)();
- int (*put_data)();
+ bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
+ int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
{
int size;
bfd_vma x;
#ifdef BFD64
case 8:
#endif
- x = get_data (location, 0, size);
+ x = get_data (location, size);
break;
}
if ((check & ~reloc_bits) != 0
&& (((bfd_vma) signed_check & ~reloc_bits)
- != (-1 & ~reloc_bits)))
+ != (-(bfd_vma) 1 & ~reloc_bits)))
overflow = true;
}
break;
#ifdef BFD64
case 8:
#endif
- put_data(x, location, 0, size);
+ put_data (x, location, size);
break;
}