blob: 09d26aed10b30475bc06ec6d10611e10aefb5469 [file] [log] [blame]
/* NDS32-specific support for 32-bit ELF.
Copyright (C) 2012-2016 Free Software Foundation, Inc.
Contributed by Andes Technology Corporation.
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 3 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., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#include "sysdep.h"
#include "bfd.h"
#include "bfd_stdint.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "libiberty.h"
#include "bfd_stdint.h"
#include "elf/nds32.h"
#include "opcode/nds32.h"
#include "elf32-nds32.h"
#include "opcode/cgen.h"
#include "../opcodes/nds32-opc.h"
/* Relocation HOWTO functions. */
static bfd_reloc_status_type nds32_elf_ignore_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type nds32_elf_9_pcrel_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type nds32_elf_hi20_reloc
(bfd *, arelent *, asymbol *, void *,
asection *, bfd *, char **);
static bfd_reloc_status_type nds32_elf_lo12_reloc
(bfd *, arelent *, asymbol *, void *,
asection *, bfd *, char **);
static bfd_reloc_status_type nds32_elf_generic_reloc
(bfd *, arelent *, asymbol *, void *,
asection *, bfd *, char **);
static bfd_reloc_status_type nds32_elf_sda15_reloc
(bfd *, arelent *, asymbol *, void *,
asection *, bfd *, char **);
/* Helper functions for HOWTO. */
static bfd_reloc_status_type nds32_elf_do_9_pcrel_reloc
(bfd *, reloc_howto_type *, asection *, bfd_byte *, bfd_vma,
asection *, bfd_vma, bfd_vma);
static void nds32_elf_relocate_hi20
(bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, bfd_vma);
static reloc_howto_type *bfd_elf32_bfd_reloc_type_table_lookup
(enum elf_nds32_reloc_type);
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
(bfd *, bfd_reloc_code_real_type);
/* Target hooks. */
static void nds32_info_to_howto_rel
(bfd *, arelent *, Elf_Internal_Rela *dst);
static void nds32_info_to_howto
(bfd *, arelent *, Elf_Internal_Rela *dst);
static bfd_boolean nds32_elf_add_symbol_hook
(bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
flagword *, asection **, bfd_vma *);
static bfd_boolean nds32_elf_relocate_section
(bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
static bfd_boolean nds32_elf_object_p (bfd *);
static void nds32_elf_final_write_processing (bfd *, bfd_boolean);
static bfd_boolean nds32_elf_set_private_flags (bfd *, flagword);
static bfd_boolean nds32_elf_merge_private_bfd_data (bfd *, bfd *);
static bfd_boolean nds32_elf_print_private_bfd_data (bfd *, void *);
static bfd_boolean nds32_elf_gc_sweep_hook
(bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
static bfd_boolean nds32_elf_check_relocs
(bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
static asection *nds32_elf_gc_mark_hook
(asection *, struct bfd_link_info *, Elf_Internal_Rela *,
struct elf_link_hash_entry *, Elf_Internal_Sym *);
static bfd_boolean nds32_elf_adjust_dynamic_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *);
static bfd_boolean nds32_elf_size_dynamic_sections
(bfd *, struct bfd_link_info *);
static bfd_boolean nds32_elf_create_dynamic_sections
(bfd *, struct bfd_link_info *);
static bfd_boolean nds32_elf_finish_dynamic_sections
(bfd *, struct bfd_link_info *info);
static bfd_boolean nds32_elf_finish_dynamic_symbol
(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
Elf_Internal_Sym *);
static bfd_boolean nds32_elf_mkobject (bfd *);
/* Nds32 helper functions. */
static bfd_reloc_status_type nds32_elf_final_sda_base
(bfd *, struct bfd_link_info *, bfd_vma *, bfd_boolean);
static bfd_boolean allocate_dynrelocs (struct elf_link_hash_entry *, void *);
static bfd_boolean readonly_dynrelocs (struct elf_link_hash_entry *, void *);
static Elf_Internal_Rela *find_relocs_at_address
(Elf_Internal_Rela *, Elf_Internal_Rela *,
Elf_Internal_Rela *, enum elf_nds32_reloc_type);
static bfd_vma calculate_memory_address
(bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *);
static int nds32_get_section_contents (bfd *, asection *,
bfd_byte **, bfd_boolean);
static bfd_boolean nds32_elf_ex9_build_hash_table
(bfd *, asection *, struct bfd_link_info *);
static bfd_boolean nds32_elf_ex9_itb_base (struct bfd_link_info *);
static void nds32_elf_ex9_import_table (struct bfd_link_info *);
static void nds32_elf_ex9_finish (struct bfd_link_info *);
static void nds32_elf_ex9_reloc_jmp (struct bfd_link_info *);
static void nds32_elf_get_insn_with_reg
(Elf_Internal_Rela *, uint32_t, uint32_t *);
static int nds32_get_local_syms (bfd *, asection *ATTRIBUTE_UNUSED,
Elf_Internal_Sym **);
static bfd_boolean nds32_elf_ex9_replace_instruction
(struct bfd_link_info *, bfd *, asection *);
static bfd_boolean nds32_elf_ifc_calc (struct bfd_link_info *, bfd *,
asection *);
static bfd_boolean nds32_elf_ifc_finish (struct bfd_link_info *);
static bfd_boolean nds32_elf_ifc_replace (struct bfd_link_info *);
static bfd_boolean nds32_elf_ifc_reloc (void);
static bfd_boolean nds32_relax_fp_as_gp
(struct bfd_link_info *link_info, bfd *abfd, asection *sec,
Elf_Internal_Rela *internal_relocs, Elf_Internal_Rela *irelend,
Elf_Internal_Sym *isymbuf);
static bfd_boolean nds32_fag_remove_unused_fpbase
(bfd *abfd, asection *sec, Elf_Internal_Rela *internal_relocs,
Elf_Internal_Rela *irelend);
static bfd_byte *
nds32_elf_get_relocated_section_contents (bfd *abfd,
struct bfd_link_info *link_info,
struct bfd_link_order *link_order,
bfd_byte *data,
bfd_boolean relocatable,
asymbol **symbols);
enum
{
MACH_V1 = bfd_mach_n1h,
MACH_V2 = bfd_mach_n1h_v2,
MACH_V3 = bfd_mach_n1h_v3,
MACH_V3M = bfd_mach_n1h_v3m
};
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
/* The name of the dynamic interpreter. This is put in the .interp
section. */
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
/* The nop opcode we use. */
#define NDS32_NOP32 0x40000009
#define NDS32_NOP16 0x9200
/* The size in bytes of an entry in the procedure linkage table. */
#define PLT_ENTRY_SIZE 24
#define PLT_HEADER_SIZE 24
/* The first entry in a procedure linkage table are reserved,
and the initial contents are unimportant (we zero them out).
Subsequent entries look like this. */
#define PLT0_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(.got+4) */
#define PLT0_ENTRY_WORD1 0x58f78000 /* ori r15, r25, LO12(.got+4) */
#define PLT0_ENTRY_WORD2 0x05178000 /* lwi r17, [r15+0] */
#define PLT0_ENTRY_WORD3 0x04f78001 /* lwi r15, [r15+4] */
#define PLT0_ENTRY_WORD4 0x4a003c00 /* jr r15 */
/* $ta is change to $r15 (from $r25). */
#define PLT0_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[1]@GOT) */
#define PLT0_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[1]@GOT) */
#define PLT0_PIC_ENTRY_WORD2 0x40f7f400 /* add r15, gp, r15 */
#define PLT0_PIC_ENTRY_WORD3 0x05178000 /* lwi r17, [r15+0] */
#define PLT0_PIC_ENTRY_WORD4 0x04f78001 /* lwi r15, [r15+4] */
#define PLT0_PIC_ENTRY_WORD5 0x4a003c00 /* jr r15 */
#define PLT_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(&got[n+3]) */
#define PLT_ENTRY_WORD1 0x04f78000 /* lwi r15, r15, LO12(&got[n+3]) */
#define PLT_ENTRY_WORD2 0x4a003c00 /* jr r15 */
#define PLT_ENTRY_WORD3 0x45000000 /* movi r16, sizeof(RELA) * n */
#define PLT_ENTRY_WORD4 0x48000000 /* j .plt0. */
#define PLT_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[n+3]@GOT) */
#define PLT_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[n+3]@GOT) */
#define PLT_PIC_ENTRY_WORD2 0x38febc02 /* lw r15, [gp+r15] */
#define PLT_PIC_ENTRY_WORD3 0x4a003c00 /* jr r15 */
#define PLT_PIC_ENTRY_WORD4 0x45000000 /* movi r16, sizeof(RELA) * n */
#define PLT_PIC_ENTRY_WORD5 0x48000000 /* j .plt0 */
/* These are macros used to get the relocation accurate value. */
#define ACCURATE_8BIT_S1 (0x100)
#define ACCURATE_U9BIT_S1 (0x400)
#define ACCURATE_12BIT_S1 (0x2000)
#define ACCURATE_14BIT_S1 (0x4000)
#define ACCURATE_19BIT (0x40000)
/* These are macros used to get the relocation conservative value. */
#define CONSERVATIVE_8BIT_S1 (0x100 - 4)
#define CONSERVATIVE_14BIT_S1 (0x4000 - 4)
#define CONSERVATIVE_16BIT_S1 (0x10000 - 4)
#define CONSERVATIVE_24BIT_S1 (0x1000000 - 4)
/* These must be more conservative because the address may be in
different segment. */
#define CONSERVATIVE_15BIT (0x4000 - 0x1000)
#define CONSERVATIVE_15BIT_S1 (0x8000 - 0x1000)
#define CONSERVATIVE_15BIT_S2 (0x10000 - 0x1000)
#define CONSERVATIVE_19BIT (0x40000 - 0x1000)
#define CONSERVATIVE_20BIT (0x80000 - 0x1000)
/* Size of small data/bss sections, used to calculate SDA_BASE. */
static long got_size = 0;
static int is_SDA_BASE_set = 0;
static int is_ITB_BASE_set = 0;
/* Convert ELF-VER in eflags to string for debugging purpose. */
static const char *const nds32_elfver_strtab[] =
{
"ELF-1.2",
"ELF-1.3",
"ELF-1.4",
};
/* The nds32 linker needs to keep track of the number of relocs that it
decides to copy in check_relocs for each symbol. This is so that
it can discard PC relative relocs if it doesn't need them when
linking with -Bsymbolic. We store the information in a field
extending the regular ELF linker hash table. */
/* This structure keeps track of the number of PC relative relocs we
have copied for a given symbol. */
struct elf_nds32_pcrel_relocs_copied
{
/* Next section. */
struct elf_nds32_pcrel_relocs_copied *next;
/* A section in dynobj. */
asection *section;
/* Number of relocs copied in this section. */
bfd_size_type count;
};
/* The sh linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct elf_nds32_dyn_relocs
{
struct elf_nds32_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* Nds32 ELF linker hash entry. */
struct elf_nds32_link_hash_entry
{
struct elf_link_hash_entry root;
/* Track dynamic relocs copied for this symbol. */
struct elf_nds32_dyn_relocs *dyn_relocs;
/* For checking relocation type. */
#define GOT_UNKNOWN 0
#define GOT_NORMAL 1
#define GOT_TLS_IE 2
unsigned int tls_type;
};
/* Get the nds32 ELF linker hash table from a link_info structure. */
#define FP_BASE_NAME "_FP_BASE_"
static int check_start_export_sym = 0;
static size_t ex9_relax_size = 0; /* Save ex9 predicted reducing size. */
/* The offset for executable tls relaxation. */
#define TP_OFFSET 0x0
struct elf_nds32_obj_tdata
{
struct elf_obj_tdata root;
/* tls_type for each local got entry. */
char *local_got_tls_type;
};
#define elf_nds32_tdata(bfd) \
((struct elf_nds32_obj_tdata *) (bfd)->tdata.any)
#define elf32_nds32_local_got_tls_type(bfd) \
(elf_nds32_tdata (bfd)->local_got_tls_type)
#define elf32_nds32_hash_entry(ent) ((struct elf_nds32_link_hash_entry *)(ent))
static bfd_boolean
nds32_elf_mkobject (bfd *abfd)
{
return bfd_elf_allocate_object (abfd, sizeof (struct elf_nds32_obj_tdata),
NDS32_ELF_DATA);
}
/* Relocations used for relocation. */
static reloc_howto_type nds32_elf_howto_table[] =
{
/* This reloc does nothing. */
HOWTO (R_NDS32_NONE, /* type */
0, /* rightshift */
3, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_NONE", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 16 bit absolute relocation. */
HOWTO (R_NDS32_16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
nds32_elf_generic_reloc, /* special_function */
"R_NDS32_16", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 32 bit absolute relocation. */
HOWTO (R_NDS32_32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
nds32_elf_generic_reloc, /* special_function */
"R_NDS32_32", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 20 bit address. */
HOWTO (R_NDS32_20, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_unsigned, /* complain_on_overflow */
nds32_elf_generic_reloc, /* special_function */
"R_NDS32_20", /* name */
FALSE, /* partial_inplace */
0xfffff, /* src_mask */
0xfffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An PC Relative 9-bit relocation, shifted by 2.
This reloc is complicated because relocations are relative to pc & -4.
i.e. branches in the right insn slot use the address of the left insn
slot for pc. */
/* ??? It's not clear whether this should have partial_inplace set or not.
Branch relaxing in the assembler can store the addend in the insn,
and if bfd_install_relocation gets called the addend may get added
again. */
HOWTO (R_NDS32_9_PCREL, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
nds32_elf_9_pcrel_reloc, /* special_function */
"R_NDS32_9_PCREL", /* name */
FALSE, /* partial_inplace */
0xff, /* src_mask */
0xff, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 15 bit relocation, right shifted by 1. */
HOWTO (R_NDS32_15_PCREL, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
14, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_15_PCREL", /* name */
FALSE, /* partial_inplace */
0x3fff, /* src_mask */
0x3fff, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 17 bit relocation, right shifted by 1. */
HOWTO (R_NDS32_17_PCREL, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_17_PCREL", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 25 bit relocation, right shifted by 1. */
/* ??? It's not clear whether this should have partial_inplace set or not.
Branch relaxing in the assembler can store the addend in the insn,
and if bfd_install_relocation gets called the addend may get added
again. */
HOWTO (R_NDS32_25_PCREL, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
24, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_25_PCREL", /* name */
FALSE, /* partial_inplace */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* High 20 bits of address when lower 12 is or'd in. */
HOWTO (R_NDS32_HI20, /* type */
12, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_hi20_reloc, /* special_function */
"R_NDS32_HI20", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S3, /* type */
3, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
9, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_lo12_reloc, /* special_function */
"R_NDS32_LO12S3", /* name */
FALSE, /* partial_inplace */
0x000001ff, /* src_mask */
0x000001ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S2, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
10, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_lo12_reloc, /* special_function */
"R_NDS32_LO12S2", /* name */
FALSE, /* partial_inplace */
0x000003ff, /* src_mask */
0x000003ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S1, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
11, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_lo12_reloc, /* special_function */
"R_NDS32_LO12S1", /* name */
FALSE, /* partial_inplace */
0x000007ff, /* src_mask */
0x000007ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S0, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_lo12_reloc, /* special_function */
"R_NDS32_LO12S0", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 15 bits offset. */
HOWTO (R_NDS32_SDA15S3, /* type */
3, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
nds32_elf_sda15_reloc, /* special_function */
"R_NDS32_SDA15S3", /* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 15 bits offset. */
HOWTO (R_NDS32_SDA15S2, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
nds32_elf_sda15_reloc, /* special_function */
"R_NDS32_SDA15S2", /* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 15 bits offset. */
HOWTO (R_NDS32_SDA15S1, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
nds32_elf_sda15_reloc, /* special_function */
"R_NDS32_SDA15S1", /* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 15 bits offset. */
HOWTO (R_NDS32_SDA15S0, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
nds32_elf_sda15_reloc, /* special_function */
"R_NDS32_SDA15S0", /* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable hierarchy */
HOWTO (R_NDS32_GNU_VTINHERIT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
NULL, /* special_function */
"R_NDS32_GNU_VTINHERIT", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable member usage */
HOWTO (R_NDS32_GNU_VTENTRY, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
_bfd_elf_rel_vtable_reloc_fn, /* special_function */
"R_NDS32_GNU_VTENTRY", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 16 bit absolute relocation. */
HOWTO (R_NDS32_16_RELA, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_16_RELA", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 32 bit absolute relocation. */
HOWTO (R_NDS32_32_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_32_RELA", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 20 bit address. */
HOWTO (R_NDS32_20_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_20_RELA", /* name */
FALSE, /* partial_inplace */
0xfffff, /* src_mask */
0xfffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_9_PCREL_RELA, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_9_PCREL_RELA",/* name */
FALSE, /* partial_inplace */
0xff, /* src_mask */
0xff, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 15 bit relocation, right shifted by 1. */
HOWTO (R_NDS32_15_PCREL_RELA, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
14, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_15_PCREL_RELA", /* name */
FALSE, /* partial_inplace */
0x3fff, /* src_mask */
0x3fff, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 17 bit relocation, right shifted by 1. */
HOWTO (R_NDS32_17_PCREL_RELA, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_17_PCREL_RELA", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 25 bit relocation, right shifted by 2. */
HOWTO (R_NDS32_25_PCREL_RELA, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
24, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_25_PCREL_RELA", /* name */
FALSE, /* partial_inplace */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* High 20 bits of address when lower 16 is or'd in. */
HOWTO (R_NDS32_HI20_RELA, /* type */
12, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_HI20_RELA", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S3_RELA, /* type */
3, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
9, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_LO12S3_RELA", /* name */
FALSE, /* partial_inplace */
0x000001ff, /* src_mask */
0x000001ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S2_RELA, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
10, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_LO12S2_RELA", /* name */
FALSE, /* partial_inplace */
0x000003ff, /* src_mask */
0x000003ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S1_RELA, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
11, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_LO12S1_RELA", /* name */
FALSE, /* partial_inplace */
0x000007ff, /* src_mask */
0x000007ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S0_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_LO12S0_RELA", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 15 bits offset. */
HOWTO (R_NDS32_SDA15S3_RELA, /* type */
3, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA15S3_RELA",/* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 15 bits offset. */
HOWTO (R_NDS32_SDA15S2_RELA, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA15S2_RELA",/* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_SDA15S1_RELA, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA15S1_RELA",/* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_SDA15S0_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA15S0_RELA",/* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable hierarchy */
HOWTO (R_NDS32_RELA_GNU_VTINHERIT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
NULL, /* special_function */
"R_NDS32_RELA_GNU_VTINHERIT", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable member usage */
HOWTO (R_NDS32_RELA_GNU_VTENTRY, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
_bfd_elf_rel_vtable_reloc_fn, /* special_function */
"R_NDS32_RELA_GNU_VTENTRY", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_NDS32_20, but referring to the GOT table entry for
the symbol. */
HOWTO (R_NDS32_GOT20, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOT20", /* name */
FALSE, /* partial_inplace */
0xfffff, /* src_mask */
0xfffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_NDS32_PCREL, but referring to the procedure linkage table
entry for the symbol. */
HOWTO (R_NDS32_25_PLTREL, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
24, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_25_PLTREL", /* name */
FALSE, /* partial_inplace */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* This is used only by the dynamic linker. The symbol should exist
both in the object being run and in some shared library. The
dynamic linker copies the data addressed by the symbol from the
shared library into the object, because the object being
run has to have the data at some particular address. */
HOWTO (R_NDS32_COPY, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_COPY", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_NDS32_20, but used when setting global offset table
entries. */
HOWTO (R_NDS32_GLOB_DAT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GLOB_DAT", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Marks a procedure linkage table entry for a symbol. */
HOWTO (R_NDS32_JMP_SLOT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_JMP_SLOT", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Used only by the dynamic linker. When the object is run, this
longword is set to the load address of the object, plus the
addend. */
HOWTO (R_NDS32_RELATIVE, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_RELATIVE", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_GOTOFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOTOFF", /* name */
FALSE, /* partial_inplace */
0xfffff, /* src_mask */
0xfffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An PC Relative 20-bit relocation used when setting PIC offset
table register. */
HOWTO (R_NDS32_GOTPC20, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOTPC20", /* name */
FALSE, /* partial_inplace */
0xfffff, /* src_mask */
0xfffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* Like R_NDS32_HI20, but referring to the GOT table entry for
the symbol. */
HOWTO (R_NDS32_GOT_HI20, /* type */
12, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOT_HI20", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_GOT_LO12, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOT_LO12", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An PC Relative relocation used when setting PIC offset table register.
Like R_NDS32_HI20, but referring to the GOT table entry for
the symbol. */
HOWTO (R_NDS32_GOTPC_HI20, /* type */
12, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOTPC_HI20", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
TRUE), /* pcrel_offset */
HOWTO (R_NDS32_GOTPC_LO12, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOTPC_LO12", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
TRUE), /* pcrel_offset */
HOWTO (R_NDS32_GOTOFF_HI20, /* type */
12, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOTOFF_HI20", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_GOTOFF_LO12, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOTOFF_LO12", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Alignment hint for relaxable instruction. This is used with
R_NDS32_LABEL as a pair. Relax this instruction from 4 bytes to 2
in order to make next label aligned on word boundary. */
HOWTO (R_NDS32_INSN16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_INSN16", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Alignment hint for label. */
HOWTO (R_NDS32_LABEL, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_LABEL", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for unconditional call sequence */
HOWTO (R_NDS32_LONGCALL1, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_LONGCALL1", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for conditional call sequence. */
HOWTO (R_NDS32_LONGCALL2, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_LONGCALL2", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for conditional call sequence. */
HOWTO (R_NDS32_LONGCALL3, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_LONGCALL3", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for unconditional branch sequence. */
HOWTO (R_NDS32_LONGJUMP1, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_LONGJUMP1", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for conditional branch sequence. */
HOWTO (R_NDS32_LONGJUMP2, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_LONGJUMP2", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for conditional branch sequence. */
HOWTO (R_NDS32_LONGJUMP3, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_LONGJUMP3", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for load/store sequence. */
HOWTO (R_NDS32_LOADSTORE, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_LOADSTORE", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for load/store sequence. */
HOWTO (R_NDS32_9_FIXED_RELA, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_9_FIXED_RELA",/* name */
FALSE, /* partial_inplace */
0x000000ff, /* src_mask */
0x000000ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for load/store sequence. */
HOWTO (R_NDS32_15_FIXED_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_15_FIXED_RELA", /* name */
FALSE, /* partial_inplace */
0x00003fff, /* src_mask */
0x00003fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for load/store sequence. */
HOWTO (R_NDS32_17_FIXED_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_17_FIXED_RELA", /* name */
FALSE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for load/store sequence. */
HOWTO (R_NDS32_25_FIXED_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_25_FIXED_RELA", /* name */
FALSE, /* partial_inplace */
0x00ffffff, /* src_mask */
0x00ffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* High 20 bits of PLT symbol offset relative to PC. */
HOWTO (R_NDS32_PLTREL_HI20, /* type */
12, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_PLTREL_HI20", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Low 12 bits of PLT symbol offset relative to PC. */
HOWTO (R_NDS32_PLTREL_LO12, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_PLTREL_LO12", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* High 20 bits of PLT symbol offset relative to GOT (GP). */
HOWTO (R_NDS32_PLT_GOTREL_HI20, /* type */
12, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_PLT_GOTREL_HI20", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Low 12 bits of PLT symbol offset relative to GOT (GP). */
HOWTO (R_NDS32_PLT_GOTREL_LO12, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_PLT_GOTREL_LO12", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 12 bits offset. */
HOWTO (R_NDS32_SDA12S2_DP_RELA, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA12S2_DP_RELA", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 12 bits offset. */
HOWTO (R_NDS32_SDA12S2_SP_RELA, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA12S2_SP_RELA", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S2_DP_RELA, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
10, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_LO12S2_DP_RELA", /* name */
FALSE, /* partial_inplace */
0x000003ff, /* src_mask */
0x000003ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. */
HOWTO (R_NDS32_LO12S2_SP_RELA,/* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
10, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_LO12S2_SP_RELA", /* name */
FALSE, /* partial_inplace */
0x000003ff, /* src_mask */
0x000003ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Lower 12 bits of address. Special identity for or case. */
HOWTO (R_NDS32_LO12S0_ORI_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_LO12S0_ORI_RELA", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 19 bits offset. */
HOWTO (R_NDS32_SDA16S3_RELA, /* type */
3, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA16S3_RELA",/* name */
FALSE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Small data area 15 bits offset. */
HOWTO (R_NDS32_SDA17S2_RELA, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
17, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA17S2_RELA",/* name */
FALSE, /* partial_inplace */
0x0001ffff, /* src_mask */
0x0001ffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_SDA18S1_RELA, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
18, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA18S1_RELA",/* name */
FALSE, /* partial_inplace */
0x0003ffff, /* src_mask */
0x0003ffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_SDA19S0_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
19, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA19S0_RELA",/* name */
FALSE, /* partial_inplace */
0x0007ffff, /* src_mask */
0x0007ffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_DWARF2_OP1_RELA, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_DWARF2_OP1_RELA", /* name */
FALSE, /* partial_inplace */
0xff, /* src_mask */
0xff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_DWARF2_OP2_RELA, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_DWARF2_OP2_RELA", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_DWARF2_LEB_RELA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_DWARF2_LEB_RELA", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_UPDATE_TA_RELA,/* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_UPDATE_TA_RELA", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_NDS32_PCREL, but referring to the procedure linkage table
entry for the symbol. */
HOWTO (R_NDS32_9_PLTREL, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_9_PLTREL", /* name */
FALSE, /* partial_inplace */
0xff, /* src_mask */
0xff, /* dst_mask */
TRUE), /* pcrel_offset */
/* Low 20 bits of PLT symbol offset relative to GOT (GP). */
HOWTO (R_NDS32_PLT_GOTREL_LO20, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_PLT_GOTREL_LO20", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* low 15 bits of PLT symbol offset relative to GOT (GP) */
HOWTO (R_NDS32_PLT_GOTREL_LO15, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_PLT_GOTREL_LO15", /* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Low 19 bits of PLT symbol offset relative to GOT (GP). */
HOWTO (R_NDS32_PLT_GOTREL_LO19, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
19, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_PLT_GOTREL_LO19", /* name */
FALSE, /* partial_inplace */
0x0007ffff, /* src_mask */
0x0007ffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_GOT_LO15, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOT_LO15", /* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_GOT_LO19, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
19, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOT_LO19", /* name */
FALSE, /* partial_inplace */
0x0007ffff, /* src_mask */
0x0007ffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_GOTOFF_LO15, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOTOFF_LO15", /* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_GOTOFF_LO19, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
19, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOTOFF_LO19", /* name */
FALSE, /* partial_inplace */
0x0007ffff, /* src_mask */
0x0007ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* GOT 15 bits offset. */
HOWTO (R_NDS32_GOT15S2_RELA, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOT15S2_RELA",/* name */
FALSE, /* partial_inplace */
0x00007fff, /* src_mask */
0x00007fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* GOT 17 bits offset. */
HOWTO (R_NDS32_GOT17S2_RELA, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
17, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_GOT17S2_RELA",/* name */
FALSE, /* partial_inplace */
0x0001ffff, /* src_mask */
0x0001ffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 5 bit address. */
HOWTO (R_NDS32_5_RELA, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
5, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_5_RELA", /* name */
FALSE, /* partial_inplace */
0x1f, /* src_mask */
0x1f, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_10_UPCREL_RELA,/* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
9, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_unsigned, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_10_UPCREL_RELA", /* name */
FALSE, /* partial_inplace */
0x1ff, /* src_mask */
0x1ff, /* dst_mask */
TRUE), /* pcrel_offset */
HOWTO (R_NDS32_SDA_FP7U2_RELA,/* type */
2, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
7, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_unsigned, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_SDA_FP7U2_RELA", /* name */
FALSE, /* partial_inplace */
0x0000007f, /* src_mask */
0x0000007f, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_WORD_9_PCREL_RELA, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_WORD_9_PCREL_RELA", /* name */
FALSE, /* partial_inplace */
0xff, /* src_mask */
0xff, /* dst_mask */
TRUE), /* pcrel_offset */
HOWTO (R_NDS32_25_ABS_RELA, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
24, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_25_ABS_RELA", /* name */
FALSE, /* partial_inplace */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A relative 17 bit relocation for ifc, right shifted by 1. */
HOWTO (R_NDS32_17IFC_PCREL_RELA, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_17IFC_PCREL_RELA", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative unsigned 10 bit relocation for ifc, right shifted by 1. */
HOWTO (R_NDS32_10IFCU_PCREL_RELA, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
9, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_unsigned, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_10IFCU_PCREL_RELA", /* name */
FALSE, /* partial_inplace */
0x1ff, /* src_mask */
0x1ff, /* dst_mask */
TRUE), /* pcrel_offset */
/* Like R_NDS32_HI20, but referring to the TLS entry for the symbol. */
HOWTO (R_NDS32_TLS_LE_HI20, /* type */
12, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_TLS_LE_HI20", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_TLS_LE_LO12, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_TLS_LE_LO12", /* name */
FALSE, /* partial_inplace */
0x00000fff, /* src_mask */
0x00000fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_NDS32_HI20, but referring to the TLS entry for the symbol. */
HOWTO (R_NDS32_TLS_IE_HI20, /* type */
12, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_TLS_IE_HI20", /* name */
FALSE, /* partial_inplace */
0x000fffff, /* src_mask */
0x000fffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_TLS_IE_LO12S2, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
10, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_TLS_IE_LO12S2", /* name */
FALSE, /* partial_inplace */
0x000003ff, /* src_mask */
0x000003ff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Mark a TLS IE entry in GOT. */
HOWTO (R_NDS32_TLS_TPOFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_TLS_TPOFF", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 20 bit address. */
HOWTO (R_NDS32_TLS_LE_20, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
20, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_TLS_LE_20", /* name */
FALSE, /* partial_inplace */
0xfffff, /* src_mask */
0xfffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_TLS_LE_15S0, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_TLS_LE_15S0", /* name */
FALSE, /* partial_inplace */
0x7fff, /* src_mask */
0x7fff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_TLS_LE_15S1, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_TLS_LE_15S1", /* name */
FALSE, /* partial_inplace */
0x7fff, /* src_mask */
0x7fff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_TLS_LE_15S2, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
15, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_NDS32_TLS_LE_15S2", /* name */
FALSE, /* partial_inplace */
0x7fff, /* src_mask */
0x7fff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for unconditional call sequence */
HOWTO (R_NDS32_LONGCALL4, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_LONGCALL4", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for conditional call sequence. */
HOWTO (R_NDS32_LONGCALL5, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_LONGCALL5", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for conditional call sequence. */
HOWTO (R_NDS32_LONGCALL6, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_LONGCALL6", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for unconditional branch sequence. */
HOWTO (R_NDS32_LONGJUMP4, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_LONGJUMP4", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for conditional branch sequence. */
HOWTO (R_NDS32_LONGJUMP5, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_LONGJUMP5", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for conditional branch sequence. */
HOWTO (R_NDS32_LONGJUMP6, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_LONGJUMP6", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Relax hint for conditional branch sequence. */
HOWTO (R_NDS32_LONGJUMP7, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_LONGJUMP7", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
};
/* Relocations used for relaxation. */
static reloc_howto_type nds32_elf_relax_howto_table[] =
{
HOWTO (R_NDS32_RELAX_ENTRY, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_RELAX_ENTRY", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_GOT_SUFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_GOT_SUFF", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_GOTOFF_SUFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_GOTOFF_SUFF", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_PLT_GOT_SUFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_PLT_GOT_SUFF",/* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_MULCALL_SUFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_MULCALL_SUFF",/* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_PTR, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_PTR", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_PTR_COUNT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_PTR_COUNT", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_PTR_RESOLVED, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_PTR_RESOLVED",/* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_PLTBLOCK, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_PLTBLOCK", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_RELAX_REGION_BEGIN, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_RELAX_REGION_BEGIN", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_RELAX_REGION_END, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_RELAX_REGION_END", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_MINUEND, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_MINUEND", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_SUBTRAHEND, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_SUBTRAHEND", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_DIFF8, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_DIFF8", /* name */
FALSE, /* partial_inplace */
0x000000ff, /* src_mask */
0x000000ff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_DIFF16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_DIFF16", /* name */
FALSE, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_DIFF32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_DIFF32", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_DIFF_ULEB128, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_DIFF_ULEB128",/* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_DATA, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_DATA", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_TRAN, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
nds32_elf_ignore_reloc,/* special_function */
"R_NDS32_TRAN", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_TLS_LE_ADD, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_TLS_LE_ADD", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_TLS_LE_LS, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_TLS_LE_LS", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_NDS32_EMPTY, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
nds32_elf_ignore_reloc, /* special_function */
"R_NDS32_EMPTY", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
};
/* nds32_insertion_sort sorts an array with nmemb elements of size size.
This prototype is the same as qsort (). */
void
nds32_insertion_sort (void *base, size_t nmemb, size_t size,
int (*compar) (const void *lhs, const void *rhs))
{
char *ptr = (char *) base;
int i, j;
char *tmp = xmalloc (size);
/* If i is less than j, i is inserted before j.
|---- j ----- i --------------|
\ / \ /
sorted unsorted
*/
for (i = 1; i < (int) nmemb; i++)
{
for (j = (i - 1); j >= 0; j--)
if (compar (ptr + i * size, ptr + j * size) >= 0)
break;
j++;
if (i == j)
continue; /* i is in order. */
memcpy (tmp, ptr + i * size, size);
memmove (ptr + (j + 1) * size, ptr + j * size, (i - j) * size);
memcpy (ptr + j * size, tmp, size);
}
free (tmp);
}
/* Sort relocation by r_offset.
We didn't use qsort () in stdlib, because quick-sort is not a stable sorting
algorithm. Relocations at the same r_offset must keep their order.
For example, RELAX_ENTRY must be the very first relocation entry.
Currently, this function implements insertion-sort.
FIXME: If we already sort them in assembler, why bother sort them
here again? */
static int
compar_reloc (const void *lhs, const void *rhs)
{
const Elf_Internal_Rela *l = (const Elf_Internal_Rela *) lhs;
const Elf_Internal_Rela *r = (const Elf_Internal_Rela *) rhs;
if (l->r_offset > r->r_offset)
return 1;
else if (l->r_offset == r->r_offset)
return 0;
else
return -1;
}
/* Functions listed below are only used for old relocs.
* nds32_elf_9_pcrel_reloc
* nds32_elf_do_9_pcrel_reloc
* nds32_elf_hi20_reloc
* nds32_elf_relocate_hi20
* nds32_elf_lo12_reloc
* nds32_elf_sda15_reloc
* nds32_elf_generic_reloc
*/
/* Handle the R_NDS32_9_PCREL & R_NDS32_9_PCREL_RELA reloc. */
static bfd_reloc_status_type
nds32_elf_9_pcrel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section, bfd *output_bfd,
char **error_message ATTRIBUTE_UNUSED)
{
/* This part is from bfd_elf_generic_reloc. */
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;
}
if (output_bfd != NULL)
{
/* FIXME: See bfd_perform_relocation. Is this right? */
return bfd_reloc_continue;
}
return nds32_elf_do_9_pcrel_reloc (abfd, reloc_entry->howto,
input_section,
data, reloc_entry->address,
symbol->section,
(symbol->value
+ symbol->section->output_section->vma
+ symbol->section->output_offset),
reloc_entry->addend);
}
/* Utility to actually perform an R_NDS32_9_PCREL reloc. */
#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1)
static bfd_reloc_status_type
nds32_elf_do_9_pcrel_reloc (bfd *abfd, reloc_howto_type *howto,
asection *input_section, bfd_byte *data,
bfd_vma offset,
asection *symbol_section ATTRIBUTE_UNUSED,
bfd_vma symbol_value, bfd_vma addend)
{
bfd_signed_vma relocation;
unsigned short x;
bfd_reloc_status_type status;
/* Sanity check the address (offset in section). */
if (offset > bfd_get_section_limit (abfd, input_section))
return bfd_reloc_outofrange;
relocation = symbol_value + addend;
/* Make it pc relative. */
relocation -= (input_section->output_section->vma
+ input_section->output_offset);
/* These jumps mask off the lower two bits of the current address
before doing pcrel calculations. */
relocation -= (offset & -(bfd_vma) 2);
if (relocation < -ACCURATE_8BIT_S1 || relocation >= ACCURATE_8BIT_S1)
status = bfd_reloc_overflow;
else
status = bfd_reloc_ok;
x = bfd_getb16 (data + offset);
relocation >>= howto->rightshift;
relocation <<= howto->bitpos;
x = (x & ~howto->dst_mask)
| (((x & howto->src_mask) + relocation) & howto->dst_mask);
bfd_putb16 ((bfd_vma) x, data + offset);
return status;
}
/* Handle the R_NDS32_HI20_[SU]LO relocs.
HI20_SLO is for the add3 and load/store with displacement instructions.
HI20 is for the or3 instruction.
For R_NDS32_HI20_SLO, the lower 16 bits are sign extended when added to
the high 16 bytes so if the lower 16 bits are negative (bit 15 == 1) then
we must add one to the high 16 bytes (which will get subtracted off when
the low 16 bits are added).
These relocs have to be done in combination with an R_NDS32_LO12 reloc
because there is a carry from the LO12 to the HI20. Here we just save
the information we need; we do the actual relocation when we see the LO12.
This code is copied from the elf32-mips.c. We also support an arbitrary
number of HI20 relocs to be associated with a single LO12 reloc. The
assembler sorts the relocs to ensure each HI20 immediately precedes its
LO12. However if there are multiple copies, the assembler may not find
the real LO12 so it picks the first one it finds. */
struct nds32_hi20
{
struct nds32_hi20 *next;
bfd_byte *addr;
bfd_vma addend;
};
static struct nds32_hi20 *nds32_hi20_list;
static bfd_reloc_status_type
nds32_elf_hi20_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
asymbol *symbol, void *data, asection *input_section,
bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
{
bfd_reloc_status_type ret;
bfd_vma relocation;
struct nds32_hi20 *n;
/* This part is from bfd_elf_generic_reloc.
If we're relocating, and this an external symbol, we don't want
to change anything. */
if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0)
{
reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}
/* Sanity check the address (offset in section). */
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
return bfd_reloc_outofrange;
ret = bfd_reloc_ok;
if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
ret = bfd_reloc_undefined;
if (bfd_is_com_section (symbol->section))
relocation = 0;
else
relocation = symbol->value;
relocation += symbol->section->output_section->vma;
relocation += symbol->section->output_offset;
relocation += reloc_entry->addend;
/* Save the information, and let LO12 do the actual relocation. */
n = (struct nds32_hi20 *) bfd_malloc ((bfd_size_type) sizeof *n);
if (n == NULL)
return bfd_reloc_outofrange;
n->addr = (bfd_byte *) data + reloc_entry->address;
n->addend = relocation;
n->next = nds32_hi20_list;
nds32_hi20_list = n;
if (output_bfd != (bfd *) NULL)
reloc_entry->address += input_section->output_offset;
return ret;
}
/* Handle an NDS32 ELF HI20 reloc. */
static void
nds32_elf_relocate_hi20 (bfd *input_bfd ATTRIBUTE_UNUSED,
int type ATTRIBUTE_UNUSED, Elf_Internal_Rela *relhi,
Elf_Internal_Rela *rello, bfd_byte *contents,
bfd_vma addend)
{
unsigned long insn;
bfd_vma addlo;
insn = bfd_getb32 (contents + relhi->r_offset);
addlo = bfd_getb32 (contents + rello->r_offset);
addlo &= 0xfff;
addend += ((insn & 0xfffff) << 20) + addlo;
insn = (insn & 0xfff00000) | ((addend >> 12) & 0xfffff);
bfd_putb32 (insn, contents + relhi->r_offset);
}
/* Do an R_NDS32_LO12 relocation. This is a straightforward 12 bit
inplace relocation; this function exists in order to do the
R_NDS32_HI20_[SU]LO relocation described above. */
static bfd_reloc_status_type
nds32_elf_lo12_reloc (bfd *input_bfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section, bfd *output_bfd,
char **error_message)
{
/* This part is from bfd_elf_generic_reloc.
If we're relocating, and this an external symbol, we don't want
to change anything. */
if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0
&& reloc_entry->addend == 0)
{
reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}
if (nds32_hi20_list != NULL)
{
struct nds32_hi20 *l;
l = nds32_hi20_list;
while (l != NULL)
{
unsigned long insn;
unsigned long val;
unsigned long vallo;
struct nds32_hi20 *next;
/* Do the HI20 relocation. Note that we actually don't need
to know anything about the LO12 itself, except where to
find the low 12 bits of the addend needed by the LO12. */
insn = bfd_getb32 (l->addr);
vallo = bfd_getb32 ((bfd_byte *) data + reloc_entry->address);
vallo &= 0xfff;
switch (reloc_entry->howto->type)
{
case R_NDS32_LO12S3:
vallo <<= 3;
break;
case R_NDS32_LO12S2:
vallo <<= 2;
break;
case R_NDS32_LO12S1:
vallo <<= 1;
break;
case R_NDS32_LO12S0:
vallo <<= 0;
break;
}
val = ((insn & 0xfffff) << 12) + vallo;
val += l->addend;
insn = (insn & ~(bfd_vma) 0xfffff) | ((val >> 12) & 0xfffff);
bfd_putb32 ((bfd_vma) insn, l->addr);
next = l->next;
free (l);
l = next;
}
nds32_hi20_list = NULL;
}
/* Now do the LO12 reloc in the usual way.
??? It would be nice to call bfd_elf_generic_reloc here,
but we have partial_inplace set. bfd_elf_generic_reloc will
pass the handling back to bfd_install_relocation which will install
a section relative addend which is wrong. */
return nds32_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
}
/* Do generic partial_inplace relocation.
This is a local replacement for bfd_elf_generic_reloc. */
static bfd_reloc_status_type
nds32_elf_generic_reloc (bfd *input_bfd, arelent *reloc_entry,
asymbol *symbol, void *data, asection *input_section,
bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
{
bfd_reloc_status_type ret;
bfd_vma relocation;
bfd_byte *inplace_address;
/* This part is from bfd_elf_generic_reloc.
If we're relocating, and this an external symbol, we don't want
to change anything. */
if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0
&& reloc_entry->addend == 0)
{
reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}
/* Now do the reloc in the usual way.
??? It would be nice to call bfd_elf_generic_reloc here,
but we have partial_inplace set. bfd_elf_generic_reloc will
pass the handling back to bfd_install_relocation which will install
a section relative addend which is wrong. */
/* Sanity check the address (offset in section). */
if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section))
return bfd_reloc_outofrange;
ret = bfd_reloc_ok;
if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
ret = bfd_reloc_undefined;
if (bfd_is_com_section (symbol->section) || output_bfd != (bfd *) NULL)
relocation = 0;
else
relocation = symbol->value;
/* Only do this for a final link. */
if (output_bfd == (bfd *) NULL)
{
relocation += symbol->section->output_section->vma;
relocation += symbol->section->output_offset;
}
relocation += reloc_entry->addend;
switch (reloc_entry->howto->type)
{
case R_NDS32_LO12S3:
relocation >>= 3;
break;
case R_NDS32_LO12S2:
relocation >>= 2;
break;
case R_NDS32_LO12S1:
relocation >>= 1;
break;
case R_NDS32_LO12S0:
default:
relocation >>= 0;
break;
}
inplace_address = (bfd_byte *) data + reloc_entry->address;
#define DOIT(x) \
x = ((x & ~reloc_entry->howto->dst_mask) | \
(((x & reloc_entry->howto->src_mask) + relocation) & \
reloc_entry->howto->dst_mask))
switch (reloc_entry->howto->size)
{
case 1:
{
short x = bfd_getb16 (inplace_address);
DOIT (x);
bfd_putb16 ((bfd_vma) x, inplace_address);
}
break;
case 2:
{
unsigned long x = bfd_getb32 (inplace_address);
DOIT (x);
bfd_putb32 ((bfd_vma) x, inplace_address);
}
break;
default:
BFD_ASSERT (0);
}
if (output_bfd != (bfd *) NULL)
reloc_entry->address += input_section->output_offset;
return ret;
}
/* Handle the R_NDS32_SDA15 reloc.
This reloc is used to compute the address of objects in the small data area
and to perform loads and stores from that area.
The lower 15 bits are sign extended and added to the register specified
in the instruction, which is assumed to point to _SDA_BASE_.
Since the lower 15 bits offset is left-shifted 0, 1 or 2 bits depending on
the access size, this must be taken care of. */
static bfd_reloc_status_type
nds32_elf_sda15_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
asymbol *symbol, void *data ATTRIBUTE_UNUSED,
asection *input_section, bfd *output_bfd,
char **error_message ATTRIBUTE_UNUSED)
{
/* This part is from bfd_elf_generic_reloc. */
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;
}
if (output_bfd != NULL)
{
/* FIXME: See bfd_perform_relocation. Is this right? */
return bfd_reloc_continue;
}
/* FIXME: not sure what to do here yet. But then again, the linker
may never call us. */
abort ();
}
/* nds32_elf_ignore_reloc is the special function for
relocation types which don't need to be relocated
like relaxation relocation types.
This function simply return bfd_reloc_ok when it is
invoked. */
static bfd_reloc_status_type
nds32_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
asymbol *symbol ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED, asection *input_section,
bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
{
if (output_bfd != NULL)
reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}
/* Map BFD reloc types to NDS32 ELF reloc types. */
struct nds32_reloc_map_entry
{
bfd_reloc_code_real_type bfd_reloc_val;
unsigned char elf_reloc_val;
};
static const struct nds32_reloc_map_entry nds32_reloc_map[] =
{
{BFD_RELOC_NONE, R_NDS32_NONE},
{BFD_RELOC_16, R_NDS32_16_RELA},
{BFD_RELOC_32, R_NDS32_32_RELA},
{BFD_RELOC_NDS32_20, R_NDS32_20_RELA},
{BFD_RELOC_NDS32_5, R_NDS32_5_RELA},
{BFD_RELOC_NDS32_9_PCREL, R_NDS32_9_PCREL_RELA},
{BFD_RELOC_NDS32_WORD_9_PCREL, R_NDS32_WORD_9_PCREL_RELA},
{BFD_RELOC_NDS32_15_PCREL, R_NDS32_15_PCREL_RELA},
{BFD_RELOC_NDS32_17_PCREL, R_NDS32_17_PCREL_RELA},
{BFD_RELOC_NDS32_25_PCREL, R_NDS32_25_PCREL_RELA},
{BFD_RELOC_NDS32_10_UPCREL, R_NDS32_10_UPCREL_RELA},
{BFD_RELOC_NDS32_HI20, R_NDS32_HI20_RELA},
{BFD_RELOC_NDS32_LO12S3, R_NDS32_LO12S3_RELA},
{BFD_RELOC_NDS32_LO12S2, R_NDS32_LO12S2_RELA},
{BFD_RELOC_NDS32_LO12S1, R_NDS32_LO12S1_RELA},
{BFD_RELOC_NDS32_LO12S0, R_NDS32_LO12S0_RELA},
{BFD_RELOC_NDS32_LO12S0_ORI, R_NDS32_LO12S0_ORI_RELA},
{BFD_RELOC_NDS32_SDA15S3, R_NDS32_SDA15S3_RELA},
{BFD_RELOC_NDS32_SDA15S2, R_NDS32_SDA15S2_RELA},
{BFD_RELOC_NDS32_SDA15S1, R_NDS32_SDA15S1_RELA},
{BFD_RELOC_NDS32_SDA15S0, R_NDS32_SDA15S0_RELA},
{BFD_RELOC_VTABLE_INHERIT, R_NDS32_RELA_GNU_VTINHERIT},
{BFD_RELOC_VTABLE_ENTRY, R_NDS32_RELA_GNU_VTENTRY},
{BFD_RELOC_NDS32_GOT20, R_NDS32_GOT20},
{BFD_RELOC_NDS32_9_PLTREL, R_NDS32_9_PLTREL},
{BFD_RELOC_NDS32_25_PLTREL, R_NDS32_25_PLTREL},
{BFD_RELOC_NDS32_COPY, R_NDS32_COPY},
{BFD_RELOC_NDS32_GLOB_DAT, R_NDS32_GLOB_DAT},
{BFD_RELOC_NDS32_JMP_SLOT, R_NDS32_JMP_SLOT},
{BFD_RELOC_NDS32_RELATIVE, R_NDS32_RELATIVE},
{BFD_RELOC_NDS32_GOTOFF, R_NDS32_GOTOFF},
{BFD_RELOC_NDS32_GOTPC20, R_NDS32_GOTPC20},
{BFD_RELOC_NDS32_GOT_HI20, R_NDS32_GOT_HI20},
{BFD_RELOC_NDS32_GOT_LO12, R_NDS32_GOT_LO12},
{BFD_RELOC_NDS32_GOT_LO15, R_NDS32_GOT_LO15},
{BFD_RELOC_NDS32_GOT_LO19, R_NDS32_GOT_LO19},
{BFD_RELOC_NDS32_GOTPC_HI20, R_NDS32_GOTPC_HI20},
{BFD_RELOC_NDS32_GOTPC_LO12, R_NDS32_GOTPC_LO12},
{BFD_RELOC_NDS32_GOTOFF_HI20, R_NDS32_GOTOFF_HI20},
{BFD_RELOC_NDS32_GOTOFF_LO12, R_NDS32_GOTOFF_LO12},
{BFD_RELOC_NDS32_GOTOFF_LO15, R_NDS32_GOTOFF_LO15},
{BFD_RELOC_NDS32_GOTOFF_LO19, R_NDS32_GOTOFF_LO19},
{BFD_RELOC_NDS32_INSN16, R_NDS32_INSN16},
{BFD_RELOC_NDS32_LABEL, R_NDS32_LABEL},
{BFD_RELOC_NDS32_LONGCALL1, R_NDS32_LONGCALL1},
{BFD_RELOC_NDS32_LONGCALL2, R_NDS32_LONGCALL2},
{BFD_RELOC_NDS32_LONGCALL3, R_NDS32_LONGCALL3},
{BFD_RELOC_NDS32_LONGCALL4, R_NDS32_LONGCALL4},
{BFD_RELOC_NDS32_LONGCALL5, R_NDS32_LONGCALL5},
{BFD_RELOC_NDS32_LONGCALL6, R_NDS32_LONGCALL6},
{BFD_RELOC_NDS32_LONGJUMP1, R_NDS32_LONGJUMP1},
{BFD_RELOC_NDS32_LONGJUMP2, R_NDS32_LONGJUMP2},
{BFD_RELOC_NDS32_LONGJUMP3, R_NDS32_LONGJUMP3},
{BFD_RELOC_NDS32_LONGJUMP4, R_NDS32_LONGJUMP4},
{BFD_RELOC_NDS32_LONGJUMP5, R_NDS32_LONGJUMP5},