/* BFD support for the ns32k architecture.
- Copyright 1990, 1991, 1994, 1995, 1998, 2000, 2001, 2002
- 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 symbol_cache_entry *, 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 symbol_cache_entry *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;
return bfd_reloc_ok;
}
- /* If we are not producing relocateable output, return an error if
+ /* 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.) */
of the location within the section. Some targets arrange for
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.
+ i386-aout, pcrel_offset is FALSE. Some other targets do not
+ include the position of the location; for example, ELF.
+ For those targets, pcrel_offset is TRUE.
- If we are producing relocateable output, then we must ensure
+ If we are producing relocatable output, then we must ensure
that this reloc will be correctly computed when the final
- relocation is done. If pcrel_offset is false we want to wind
+ relocation is done. If pcrel_offset is FALSE we want to wind
up with the negative of the location within the section,
which means we must adjust the existing addend by the change
- in the location within the section. If pcrel_offset is true
+ in the location within the section. If pcrel_offset is TRUE
we do not want to adjust the existing addend at all.
FIXME: This seems logical to me, but for the case of
- producing relocateable output it is not what the code
+ producing relocatable output it is not what the code
actually does. I don't want to change it, because it seems
far too likely that something will break. */
relocation -=
/* 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.
should not have any tests that depend upon the flavour. It's
seem like entirely the wrong place for such a thing. The
second obvious point is that the current code ignores the
- reloc addend when producing relocateable output for COFF.
+ reloc addend when producing relocatable output for COFF.
That's peculiar. In fact, I really have no idea what the
point of the line you want to remove is.
(coff-i386 does subtract the old value, to be compatible with
existing coff-i386 targets, like SCO).
- So everything works fine when not producing relocateable
- output. When we are producing relocateable output, logically
+ So everything works fine when not producing relocatable
+ output. When we are producing relocatable output, logically
we should do exactly what we do when not producing
- relocateable output. Therefore, your patch is correct. In
+ relocatable output. Therefore, your patch is correct. In
fact, it should probably always just set reloc_entry->addend
to 0 for all cases, since it is, in fact, going to add the
value into the object file. This won't hurt the COFF code,
to other formats (the thing to check for would be whether
any formats both use the addend and set partial_inplace).
- When I wanted to make coff-i386 produce relocateable output,
+ When I wanted to make coff-i386 produce relocatable output,
I ran into the problem that you are running into: I wanted
to remove that line. Rather than risk it, I made the
coff-i386 relocs use a special function; it's coff_i386_reloc
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;
- boolean overflow;
+ bfd_boolean overflow;
/* If the size is negative, negate RELOCATION. This isn't very
general. */
switch (size)
{
default:
- case 0:
abort ();
+ case 0:
+ return bfd_reloc_ok;
case 1:
case 2:
case 4:
which we don't check for. We must either check at every single
operation, which would be tedious, or we must do the computations
in a type larger than bfd_vma, which would be inefficient. */
- overflow = false;
+ overflow = FALSE;
if (howto->complain_on_overflow != complain_overflow_dont)
{
bfd_vma check;
/* 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
if (signed_check > reloc_signed_max
|| signed_check < reloc_signed_min)
- overflow = true;
+ overflow = TRUE;
}
break;
case complain_overflow_unsigned:
(((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
if (check > reloc_unsigned_max)
- overflow = true;
+ overflow = TRUE;
}
break;
case complain_overflow_bitfield:
if ((check & ~reloc_bits) != 0
&& (((bfd_vma) signed_check & ~reloc_bits)
!= (-(bfd_vma) 1 & ~reloc_bits)))
- overflow = true;
+ overflow = TRUE;
}
break;
default:
}
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 symbol_cache_entry *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 symbol_cache_entry *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)