summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/elf32-crx.c102
-rw-r--r--bfd/reloc.c6
-rw-r--r--include/elf/ChangeLog5
-rw-r--r--include/elf/crx.h3
-rw-r--r--opcodes/ChangeLog4
-rw-r--r--opcodes/crx-opc.c24
8 files changed, 140 insertions, 15 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3b7a2d5fc46..9ea925801fd 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2004-07-27 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * reloc.c: Add BFD_RELOC_CRX_SWITCH8, BFD_RELOC_CRX_SWITCH16,
+ BFD_RELOC_CRX_SWITCH32.
+ * bfd-in2.h: Regenerate.
+ * elf32-crx.c: Support relocation/relaxation of
+ BFD_RELOC_CRX_SWITCH* types.
+
2004-07-27 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c: Correct "Linker stubs" comment.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index f6618898f6d..b6d14ff565d 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -3463,6 +3463,9 @@ This is the 5 bits of a value. */
BFD_RELOC_CRX_NUM32,
BFD_RELOC_CRX_IMM16,
BFD_RELOC_CRX_IMM32,
+ BFD_RELOC_CRX_SWITCH8,
+ BFD_RELOC_CRX_SWITCH16,
+ BFD_RELOC_CRX_SWITCH32,
/* These relocs are only used within the CRIS assembler. They are not
(at present) written to any object files. */
diff --git a/bfd/elf32-crx.c b/bfd/elf32-crx.c
index 03575f23260..79b9c64feac 100644
--- a/bfd/elf32-crx.c
+++ b/bfd/elf32-crx.c
@@ -77,7 +77,10 @@ static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
{BFD_RELOC_CRX_NUM16, R_CRX_NUM16},
{BFD_RELOC_CRX_NUM32, R_CRX_NUM32},
{BFD_RELOC_CRX_IMM16, R_CRX_IMM16},
- {BFD_RELOC_CRX_IMM32, R_CRX_IMM32}
+ {BFD_RELOC_CRX_IMM32, R_CRX_IMM32},
+ {BFD_RELOC_CRX_SWITCH8, R_CRX_SWITCH8},
+ {BFD_RELOC_CRX_SWITCH16, R_CRX_SWITCH16},
+ {BFD_RELOC_CRX_SWITCH32, R_CRX_SWITCH32}
};
static reloc_howto_type crx_elf_howto_table[] =
@@ -332,7 +335,58 @@ static reloc_howto_type crx_elf_howto_table[] =
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE) /* pcrel_offset */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit switch table entry. This is generated for an expression
+ such as ``.byte L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_CRX_SWITCH8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_SWITCH8", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit switch table entry. This is generated for an expression
+ such as ``.word L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_CRX_SWITCH16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_SWITCH16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 32 bit switch table entry. This is generated for an expression
+ such as ``.long L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_CRX_SWITCH32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_SWITCH32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE) /* pcrel_offset */
};
/* Retrieve a howto ptr using a BFD reloc_code. */
@@ -406,6 +460,13 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
return bfd_reloc_ok;
break;
+ case R_CRX_SWITCH8:
+ case R_CRX_SWITCH16:
+ case R_CRX_SWITCH32:
+ /* We only care about the addend, where the difference between
+ expressions is kept. */
+ Rvalue = 0;
+
default:
break;
}
@@ -483,7 +544,7 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
- if (r_type == R_CRX_NUM32)
+ if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
/* Relocation on DATA is purely little-endian, that is, for a
multi-byte datum, the lowest address in memory contains the
little end of the datum, that is, the least significant byte.
@@ -562,7 +623,40 @@ elf32_crx_relax_delete_bytes (bfd *abfd, asection *sec,
if (isym->st_shndx == sec_shndx
&& isym->st_value > addr
&& isym->st_value < toaddr)
- isym->st_value -= count;
+ {
+ /* Adjust the addend of SWITCH relocations in this section,
+ which reference this local symbol. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ unsigned long r_symndx;
+ Elf_Internal_Sym *rsym;
+ bfd_vma addsym, subsym;
+
+ /* Skip if not a SWITCH relocation. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
+ continue;
+
+ r_symndx = ELF32_R_SYM (irel->r_info);
+ rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
+
+ /* Skip if not the local adjusted symbol. */
+ if (rsym != isym)
+ continue;
+
+ addsym = isym->st_value;
+ subsym = addsym - irel->r_addend;
+
+ /* Fix the addend only when -->> (addsym > addr >= subsym). */
+ if (subsym <= addr)
+ irel->r_addend -= count;
+ else
+ continue;
+ }
+
+ isym->st_value -= count;
+ }
}
/* Now adjust the global symbols defined in this section. */
diff --git a/bfd/reloc.c b/bfd/reloc.c
index e8279d21057..b997437889d 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -3888,6 +3888,12 @@ ENUMX
BFD_RELOC_CRX_IMM16
ENUMX
BFD_RELOC_CRX_IMM32
+ENUMX
+ BFD_RELOC_CRX_SWITCH8
+ENUMX
+ BFD_RELOC_CRX_SWITCH16
+ENUMX
+ BFD_RELOC_CRX_SWITCH32
ENUMDOC
NS CRX Relocations.
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index 5563ddbeeac..408088587b2 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,3 +1,8 @@
+2004-07-27 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * crx.h: Add BFD_RELOC_CRX_SWITCH8, BFD_RELOC_CRX_SWITCH16,
+ BFD_RELOC_CRX_SWITCH32.
+
2004-07-06 Tomer Levi <Tomer.Levi@nsc.com>
* common.h (EM_CRX): Define.
diff --git a/include/elf/crx.h b/include/elf/crx.h
index 755a6109d1d..33ba0051478 100644
--- a/include/elf/crx.h
+++ b/include/elf/crx.h
@@ -45,6 +45,9 @@ START_RELOC_NUMBERS(elf_crx_reloc_type)
RELOC_NUMBER (R_CRX_NUM32, 15)
RELOC_NUMBER (R_CRX_IMM16, 16)
RELOC_NUMBER (R_CRX_IMM32, 17)
+ RELOC_NUMBER (R_CRX_SWITCH8, 18)
+ RELOC_NUMBER (R_CRX_SWITCH16, 19)
+ RELOC_NUMBER (R_CRX_SWITCH32, 20)
END_RELOC_NUMBERS(R_CRX_MAX)
#endif /* _ELF_CRX_H */
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 159f6d0f1dc..5cdcfc8538c 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,7 @@
+2004-07-27 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * crx-opc.c: Add popx,pushx insns. Indent code, fix comments.
+
2004-07-22 Nick Clifton <nickc@redhat.com>
PR/280
diff --git a/opcodes/crx-opc.c b/opcodes/crx-opc.c
index da1e3228846..1a6b3137c65 100644
--- a/opcodes/crx-opc.c
+++ b/opcodes/crx-opc.c
@@ -357,7 +357,7 @@ const inst crx_instruction[] =
/* opc12 r rbase ridx scl2 disps22 */ \
{NAME, 3, 0x33C+OPC1, 20, LD_STOR_INS | REVERSE_MATCH, {{rbase_ridx_scl2_dispu22,0}, {regr,16}}}
- LD_REG_INST ("loadb", 0x0, 0x0, DISPUB4),
+ LD_REG_INST ("loadb", 0x0, 0x0, DISPUB4),
LD_REG_INST ("loadw", 0x1, 0x1, DISPUW4),
LD_REG_INST ("loadd", 0x2, 0x2, DISPUD4),
@@ -439,42 +439,44 @@ const inst crx_instruction[] =
CSTBIT_INST ("cbitw", i4, 0x382, 0x10, 20, 0xBD),
CSTBIT_INST ("cbitd", i5, 0x1C3, 0x8, 21, 0x7B),
{"cbitd", 2, 0x300838, 8, CSTBIT_INS, {{regr,4}, {regr,0}}},
- {"cbitd", 2, 0x18047B, 9, CSTBIT_INS, {{i5,4}, {regr,0}}},
+ {"cbitd", 2, 0x18047B, 9, CSTBIT_INS, {{i5,4}, {regr,0}}},
CSTBIT_INST ("sbitb", i3, 0x701, 0x20, 19, 0x1FD),
CSTBIT_INST ("sbitw", i4, 0x383, 0x10, 20, 0xBE),
CSTBIT_INST ("sbitd", i5, 0x1C4, 0x8, 21, 0x7C),
{"sbitd", 2, 0x300839, 8, CSTBIT_INS, {{regr,4}, {regr,0}}},
- {"sbitd", 2, 0x18047C, 9, CSTBIT_INS, {{i5,4}, {regr,0}}},
+ {"sbitd", 2, 0x18047C, 9, CSTBIT_INS, {{i5,4}, {regr,0}}},
CSTBIT_INST ("tbitb", i3, 0x702, 0x20, 19, 0x1FE),
CSTBIT_INST ("tbitw", i4, 0x384, 0x10, 20, 0xBF),
CSTBIT_INST ("tbitd", i5, 0x1C5, 0x8, 21, 0x7D),
{"tbitd", 2, 0x30083A, 8, CSTBIT_INS, {{regr,4}, {regr,0}}},
- {"tbitd", 2, 0x18047D, 9, CSTBIT_INS, {{i5,4}, {regr,0}}},
+ {"tbitd", 2, 0x18047D, 9, CSTBIT_INS, {{i5,4}, {regr,0}}},
/* Instructions including a register list (opcode is represented as a mask). */
#define REGLIST_INST(NAME, OPC) \
/* opc12 r mask16 */ \
{NAME, 2, OPC, 20, REG_LIST, {{regr,16}, {i16,0}}}
- REG1_INST ("getrfid", 0xFF9),
- REG1_INST ("setrfid", 0xFFA),
+ REG1_INST ("getrfid", 0xFF9),
+ REG1_INST ("setrfid", 0xFFA),
REGLIST_INST ("push", 0x346),
REG1_INST ("push", 0xFFB),
+ REGLIST_INST ("pushx", 0x347),
REGLIST_INST ("pop", 0x324),
REG1_INST ("pop", 0xFFC),
+ REGLIST_INST ("popx", 0x327),
REGLIST_INST ("popret", 0x326),
REG1_INST ("popret", 0xFFD),
- REGLIST_INST ("loadm", 0x324),
+ REGLIST_INST ("loadm", 0x324),
REGLIST_INST ("loadma", 0x325),
- REGLIST_INST ("popma", 0x325),
+ REGLIST_INST ("popma", 0x325),
- REGLIST_INST ("storm", 0x344),
+ REGLIST_INST ("storm", 0x344),
REGLIST_INST ("storma", 0x345),
REGLIST_INST ("pushma", 0x345),
@@ -560,7 +562,7 @@ const reg_entry crx_regtab[] =
REG(ra, 0xe, CRX_R_REGTYPE),
REG(sp, 0xf, CRX_R_REGTYPE),
-/* Build a user register ur<N>. */
+/* Build a user register u<N>. */
#define REG_U(N) REG(CONCAT2(u,N), 0x80 + N, CRX_U_REGTYPE)
REG_U(0), REG_U(1), REG_U(2), REG_U(3),
@@ -607,7 +609,7 @@ const reg_entry crx_copregtab[] =
REG_C(8), REG_C(9), REG_C(10), REG_C(11),
REG_C(12), REG_C(13), REG_C(14), REG_C(15),
-/* Build a Coprocessor Special register c<N>. */
+/* Build a Coprocessor Special register cs<N>. */
#define REG_CS(N) REG(CONCAT2(cs,N), N, CRX_CS_REGTYPE)
REG_CS(0), REG_CS(1), REG_CS(2), REG_CS(3),