diff options
Diffstat (limited to 'bfd/cpu-ns32k.c')
-rw-r--r-- | bfd/cpu-ns32k.c | 150 |
1 files changed, 78 insertions, 72 deletions
diff --git a/bfd/cpu-ns32k.c b/bfd/cpu-ns32k.c index c01599e080a..2cfa26fe7d4 100644 --- a/bfd/cpu-ns32k.c +++ b/bfd/cpu-ns32k.c @@ -1,5 +1,5 @@ /* BFD support for the ns32k architecture. - Copyright 1990, 1991, 1994, 1995, 1998, 2000 + Copyright 1990, 1991, 1994, 1995, 1998, 2000, 2001 Free Software Foundation, Inc. Almost totally rewritten by Ian Dall from initial work by Andrew Cagney. @@ -36,40 +36,36 @@ static const bfd_arch_info_type arch_info_struct[] = 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; @@ -78,37 +74,38 @@ _bfd_ns32k_get_displacement(buffer, offset, size) } 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; @@ -116,19 +113,21 @@ _bfd_ns32k_put_displacement(value, buffer, offset, size) 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); @@ -139,18 +138,21 @@ _bfd_ns32k_get_immediate (buffer, offset, size) } 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; @@ -175,8 +177,8 @@ do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, asection *input_section; bfd *output_bfd; char **error_message ATTRIBUTE_UNUSED; - long (*get_data) (); - int (*put_data) (); + bfd_vma (*get_data) PARAMS ((bfd_byte *, int)); + int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int)); { int overflow = 0; bfd_vma relocation; @@ -185,6 +187,7 @@ do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, 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) @@ -433,7 +436,8 @@ space consuming. For each target: 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 @@ -444,7 +448,8 @@ space consuming. For each target: 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 @@ -528,38 +533,39 @@ space consuming. For each target: #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; @@ -571,9 +577,9 @@ space consuming. For each target: #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 (); @@ -591,14 +597,14 @@ space consuming. For each target: /* 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 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; @@ -622,7 +628,7 @@ _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location, #ifdef BFD64 case 8: #endif - x = get_data (location, 0, size); + x = get_data (location, size); break; } @@ -729,7 +735,7 @@ _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location, if ((check & ~reloc_bits) != 0 && (((bfd_vma) signed_check & ~reloc_bits) - != (-1 & ~reloc_bits))) + != (-(bfd_vma) 1 & ~reloc_bits))) overflow = true; } break; @@ -758,7 +764,7 @@ _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location, #ifdef BFD64 case 8: #endif - put_data(x, location, 0, size); + put_data (x, location, size); break; } |