summaryrefslogtreecommitdiff
path: root/bfd/elf32-i960.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf32-i960.c')
-rw-r--r--bfd/elf32-i960.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/bfd/elf32-i960.c b/bfd/elf32-i960.c
new file mode 100644
index 00000000000..7a3fd56d996
--- /dev/null
+++ b/bfd/elf32-i960.c
@@ -0,0 +1,167 @@
+/* Intel 860 specific support for 32-bit ELF
+ Copyright 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+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. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/i960.h"
+
+static bfd_reloc_status_type elf32_i960_relocate
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *elf32_i960_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+
+#define USE_REL 1
+
+#define bfd_elf32_bfd_reloc_type_lookup elf32_i960_reloc_type_lookup
+#define elf_info_to_howto elf32_i960_info_to_howto
+#define elf_info_to_howto_rel elf32_i960_info_to_howto_rel
+
+static reloc_howto_type elf_howto_table[]=
+{
+ HOWTO(R_960_NONE, 0, 0, 0, false, 0, complain_overflow_bitfield,
+ elf32_i960_relocate, "R_960_NONE", true,
+ 0x00000000, 0x00000000, false),
+ { 1 },
+ HOWTO (R_960_32, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ elf32_i960_relocate, "R_960_32", true,
+ 0xffffffff, 0xffffffff, false),
+ HOWTO (R_960_IP24, 0, 2, 24, true, 0, complain_overflow_signed,
+ elf32_i960_relocate, "R_960_IP24 ", true,
+ 0x00ffffff, 0x00ffffff, false),
+ { 4 },
+ { 5 },
+ { 6 },
+ { 7 }
+};
+
+static enum elf_i960_reloc_type
+elf32_i960_bfd_to_reloc_type (bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ default:
+ return R_960_NONE;
+ case BFD_RELOC_I960_CALLJ:
+ return R_960_OPTCALL;
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ return R_960_32;
+ case BFD_RELOC_24_PCREL:
+ return R_960_IP24;
+ }
+}
+
+static void
+elf32_i960_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rela *dst;
+{
+ abort ();
+}
+
+static void
+elf32_i960_info_to_howto_rel (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rel *dst;
+{
+ enum elf_i960_reloc_type type;
+
+ type = (enum elf_i960_reloc_type) ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (type < R_960_max);
+
+ cache_ptr->howto = &elf_howto_table[(int) type];
+}
+
+/* ELF relocs are against symbols. If we are producing relocateable
+ output, and the reloc is against an external symbol, and nothing
+ has given us any additional addend, the resulting reloc will also
+ be against the same symbol. In such a case, we don't want to
+ change anything about the way the reloc is handled, since it will
+ all be done at final link time. Rather than put special case code
+ into bfd_perform_relocation, all the reloc types use this howto
+ function. It just short circuits the reloc if producing
+ relocateable output against an external symbol. */
+
+/*ARGSUSED*/
+bfd_reloc_status_type
+elf32_i960_relocate (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* HACK: I think this first condition is necessary when producing
+ relocatable output. After the end of HACK, the code is identical
+ to bfd_elf_generic_reloc(). I would _guess_ the first change
+ belongs there rather than here. martindo 1998-10-23. */
+ if (output_bfd != (bfd *) NULL
+ && reloc_entry->howto->pc_relative
+ && !reloc_entry->howto->pcrel_offset)
+ {
+ reloc_entry->addend -= symbol->value;
+ }
+ /* This is more dubious. */
+ else if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) != 0)
+ {
+ reloc_entry->addend -= symbol->section->output_section->vma;
+ }
+ else
+ {
+ /* end of HACK */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc_entry->howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+ }
+
+ return bfd_reloc_continue;
+}
+
+static reloc_howto_type *
+elf32_i960_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ return elf_howto_table + elf32_i960_bfd_to_reloc_type (code);
+}
+
+#define TARGET_LITTLE_SYM bfd_elf32_i960_vec
+#define TARGET_LITTLE_NAME "elf32-i960"
+#define ELF_ARCH bfd_arch_i960
+#define ELF_MACHINE_CODE EM_960
+
+#include "elf32-target.h"