/* BFD support for the ns32k architecture.
- Copyright 1990, 1991, 1994, 1995, 1998, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1990-2020 Free Software Foundation, Inc.
Almost totally rewritten by Ian Dall from initial work
by Andrew Cagney.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "libbfd.h"
#include "ns32k.h"
#define N(machine, printable, d, next) \
-{ 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compatible,bfd_default_scan, next, }
+ { 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d, \
+ bfd_default_compatible,bfd_default_scan,bfd_arch_default_fill,next, 0 }
static const bfd_arch_info_type arch_info_struct[] =
{
- N(32532,"ns32k:32532",TRUE, 0), /* The word ns32k will match this too. */
+ 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 bfd_reloc_status_type do_ns32k_reloc
- PARAMS ((bfd *, arelent *, struct bfd_symbol *, PTR, asection *,
- bfd *, char **,
- bfd_vma (*) (bfd_byte *, int),
- void (*) (bfd_vma, bfd_byte *, int)));
+ N (32032, "ns32k:32032", FALSE, &arch_info_struct[0]);
bfd_vma
-_bfd_ns32k_get_displacement (buffer, size)
- bfd_byte *buffer;
- int size;
+_bfd_ns32k_get_displacement (bfd_byte *buffer, int size)
{
bfd_signed_vma value;
}
void
-_bfd_ns32k_put_displacement (value, buffer, size)
- bfd_vma value;
- bfd_byte *buffer;
- int size;
+_bfd_ns32k_put_displacement (bfd_vma value, bfd_byte *buffer, int size)
{
switch (size)
{
}
bfd_vma
-_bfd_ns32k_get_immediate (buffer, size)
- bfd_byte *buffer;
- int size;
+_bfd_ns32k_get_immediate (bfd_byte *buffer, int size)
{
bfd_vma value = 0;
case 4:
value = (value << 8) | (*buffer++ & 0xff);
value = (value << 8) | (*buffer++ & 0xff);
+ /* Fall through. */
case 2:
value = (value << 8) | (*buffer++ & 0xff);
+ /* Fall through. */
case 1:
value = (value << 8) | (*buffer++ & 0xff);
break;
}
void
-_bfd_ns32k_put_immediate (value, buffer, size)
- bfd_vma value;
- bfd_byte *buffer;
- int size;
+_bfd_ns32k_put_immediate (bfd_vma value, bfd_byte *buffer, int size)
{
buffer += size - 1;
switch (size)
case 4:
*buffer-- = (value & 0xff); value >>= 8;
*buffer-- = (value & 0xff); value >>= 8;
+ /* Fall through. */
case 2:
*buffer-- = (value & 0xff); value >>= 8;
+ /* Fall through. */
case 1:
*buffer-- = (value & 0xff); value >>= 8;
}
needs to be! */
static bfd_reloc_status_type
-do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
- error_message, get_data, put_data)
- bfd *abfd;
- arelent *reloc_entry;
- struct bfd_symbol *symbol;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message ATTRIBUTE_UNUSED;
- bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
- void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
+do_ns32k_reloc (bfd * abfd,
+ arelent * reloc_entry,
+ struct bfd_symbol * symbol,
+ void * data,
+ asection * input_section,
+ bfd * output_bfd,
+ char ** error_message ATTRIBUTE_UNUSED,
+ bfd_vma (* get_data) (bfd_byte *, int),
+ void (* put_data) (bfd_vma, bfd_byte *, int))
{
int overflow = 0;
bfd_vma relocation;
asection *reloc_target_output_section;
bfd_byte *location;
- if ((symbol->section == &bfd_abs_section)
+ if (bfd_is_abs_section (symbol->section)
&& output_bfd != (bfd *) NULL)
{
reloc_entry->address += input_section->output_offset;
/* If we are not producing relocatable output, return an error if
the symbol is not defined. An undefined weak symbol is
considered to have a value of zero (SVR4 ABI, p. 4-27). */
- if (symbol->section == &bfd_und_section
+ if (bfd_is_und_section (symbol->section)
&& (symbol->flags & BSF_WEAK) == 0
&& 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)
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
return bfd_reloc_outofrange;
- /* Work out which section the relocation is targetted at and the
+ /* Work out which section the relocation is targeted at and the
initial relocation command value. */
/* Get symbol value. (Common symbols are special.) */
the addend to be the negative of the position of the location
within the section; for example, i386-aout does this. For
i386-aout, pcrel_offset is FALSE. Some other targets do not
- include the position of the location; for example, m88kbcs,
- or ELF. For those targets, pcrel_offset is TRUE.
+ include the position of the location; for example, ELF.
+ For those targets, pcrel_offset is TRUE.
If we are producing relocatable output, then we must ensure
that this reloc will be correctly computed when the final
/* WTF?? */
if (abfd->xvec->flavour == bfd_target_coff_flavour)
{
-#if 1
/* For m68k-coff, the addend was being subtracted twice during
relocation with -r. Removing the line below this comment
fixes that problem; see PR 2953.
7) if they are different you have to figure out which
version is right. */
relocation -= reloc_entry->addend;
-#endif
reloc_entry->addend = 0;
}
else
R result
Do this:
- i i i i i o o o o o from bfd_get<size>
- and S S S S S to get the size offset we want
- + r r r r r r r r r r to get the final value to place
- and D D D D D to chop to right size
+ i i i i i o o o o o from bfd_get<size>
+ and S S S S S to get the size offset we want
+ + r r r r r r r r r r to get the final value to place
+ and D D D D D to chop to right size
-----------------------
A A A A A
And this:
- ... i i i i i o o o o o from bfd_get<size>
- and N N N N N get instruction
+ ... i i i i i o o o o o from bfd_get<size>
+ and N N N N N get instruction
-----------------------
... B B B B B
And then:
B B B B B
- or A A A A A
+ or A A A A A
-----------------------
- R R R R R R R R R R put into bfd_put<size>. */
+ R R R R R R R R R R put into bfd_put<size>. */
+
+ if (howto->negate)
+ relocation = -relocation;
#define DOIT(x) \
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
put_data ((bfd_vma) x, location, 4);
}
break;
- case -2:
- {
- bfd_vma x = get_data (location, 4);
- relocation = -relocation;
- DOIT(x);
- put_data ((bfd_vma) x, location, 4);
- }
- break;
case 3:
/* Do nothing. */
/* Relocate a given location using a given value and howto. */
bfd_reloc_status_type
-_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;
- bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
- void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
+_bfd_do_ns32k_reloc_contents (reloc_howto_type *howto,
+ bfd *input_bfd ATTRIBUTE_UNUSED,
+ bfd_vma relocation,
+ bfd_byte *location,
+ bfd_vma (*get_data) (bfd_byte *, int),
+ void (*put_data) (bfd_vma, bfd_byte *, int))
{
int size;
bfd_vma x;
switch (size)
{
default:
- case 0:
abort ();
+ case 0:
+ return bfd_reloc_ok;
case 1:
case 2:
case 4:
/* For the signed case we use ADD, rather than SIGNED_ADD,
to avoid warnings from SVR4 cc. This is OK since we
- explictly handle the sign bits. */
+ explicitly handle the sign bits. */
if (signed_add >= 0)
signed_check += add >> howto->bitpos;
else
}
bfd_reloc_status_type
-_bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
- output_bfd, error_message)
- bfd *abfd;
- arelent *reloc_entry;
- struct bfd_symbol *symbol;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message;
+_bfd_ns32k_reloc_disp (bfd *abfd,
+ arelent *reloc_entry,
+ struct bfd_symbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
{
return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
output_bfd, error_message,
}
bfd_reloc_status_type
-_bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
- output_bfd, error_message)
- bfd *abfd;
- arelent *reloc_entry;
- struct bfd_symbol *symbol;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message;
+_bfd_ns32k_reloc_imm (bfd *abfd,
+ arelent *reloc_entry,
+ struct bfd_symbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
{
return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
output_bfd, error_message, _bfd_ns32k_get_immediate,
}
bfd_reloc_status_type
-_bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
- address, value, addend)
- reloc_howto_type *howto;
- bfd *input_bfd;
- asection *input_section;
- bfd_byte *contents;
- bfd_vma address;
- bfd_vma value;
- bfd_vma addend;
+_bfd_ns32k_final_link_relocate (reloc_howto_type *howto,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_vma address,
+ bfd_vma value,
+ bfd_vma addend)
{
bfd_vma relocation;
/* Sanity check the address. */
- if (address > input_section->_cooked_size)
+ if (address > bfd_get_section_limit (input_bfd, input_section))
return bfd_reloc_outofrange;
/* This function assumes that we are dealing with a basic relocation
/* If the relocation is PC relative, we want to set RELOCATION to
the distance between the symbol (currently in RELOCATION) and the
- location we are relocating. Some targets (e.g., i386-aout)
- arrange for the contents of the section to be the negative of the
- offset of the location within the section; for such targets
- pcrel_offset is FALSE. Other targets (e.g., m88kbcs or ELF)
- simply leave the contents of the section as zero; for such
- targets pcrel_offset is TRUE. If pcrel_offset is FALSE we do not
+ location we are relocating. If pcrel_offset is FALSE we do not
need to subtract out the offset of the location within the
section (which is just ADDRESS). */
if (howto->pc_relative)