Discussion:
[PATCH] bfd/arc: Allow non-instruction relocations within .text sections
(too old to reply)
Andrew Burgess
2016-01-06 13:45:50 UTC
Permalink
On a little endian arc, a 4-byte instruction ABCD, where A is the most
significant byte, and D is the least significant byte would be stored in
memory (low to high) as BADC. That is, each 2-byte chunk is stored in
little endian order in memory.

Currently, when a relocation is applied to such a 4-byte instruction, we
make use of arc_bfd_get_32 and arc_bfd_put_32, which perform byte
manipulation to correct for this in memory byte ordering.

This byte ordering correction is applied to all relocations within
executable sections (for little endian arc) when really the correction
should only be applied to instruction relocations; it is the instruction
fetch mechanism that loads 4-byte instructions 2-bytes at a time.

It is possible to place data into an executable section, for example it
might be more efficient to place small jump tables inline within the
code rather than placing them into a data section.

The problem then, is that these two aspects, the byte order correction,
and inline data, conflict. Placing a 4-byte label relocation inline in
the code results in the byte-order correction being applied to it,
which, when the label is loaded using a standard arc load instruction,
returns a corrupted address.

Before the recent arc rewrite, placing data inline into the executable
sections did work. This was thanks to using a different code path to
patch instruction related relocations, to the code that patched data
related relocations. The instruction related relocations therefore
received the byte order correction, while the data related relocations
didn't.

After the recent rewrite this feature was lost, though I believe this
was by accident, rather than design. This commit brings this feature
back, though the implementation is different, in order to fit with the
new arc design.

All arc relocations receive a new field that indicates if the relocation
is an instruction relocation, or not. Instruction relocations can then
apply the byte order correction (for little endian arcs only). Data
relocations never apply byte order correction.

bfd/ChangeLog:

* elf32-arc.c (ARC_RELOC_HOWTO): Add new 'IS_ME' parameter to each
definition of this macro. The new parameter is ignored in all
cases except for in 'arc_do_relocation' where we perform endian
correction if required.
(arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(get_middle_endian_relocation): Delete.
(ME): Delete.

include/ChangeLog:

* elf/arc-reloc.def: Add field to indicate if each relocation
requires middle-endian correction.
* elf/arc.h (ARC_RELOC_HOWTO): Add, and ignore, 'IS_ME' field.

gas/ChangeLog:

* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
---
bfd/ChangeLog | 11 ++++++
bfd/elf32-arc.c | 59 +++++++++----------------------
gas/ChangeLog | 5 +++
gas/testsuite/gas/arc/inline-data-1.d | 7 ++++
gas/testsuite/gas/arc/inline-data-1.s | 4 +++
include/ChangeLog | 6 ++++
include/elf/arc-reloc.def | 66 +++++++++++++++++++++++++++++++++++
include/elf/arc.h | 2 +-
8 files changed, 116 insertions(+), 44 deletions(-)
create mode 100644 gas/testsuite/gas/arc/inline-data-1.d
create mode 100644 gas/testsuite/gas/arc/inline-data-1.s

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 063cd14..381521b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2016-01-05 Andrew Burgess <***@embecosm.com>
+
+ * elf32-arc.c (ARC_RELOC_HOWTO): Add new 'IS_ME' parameter to each
+ definition of this macro. The new parameter is ignored in all
+ cases except for in 'arc_do_relocation' where we perform endian
+ correction if required.
+ (arc_bfd_get_32): Becomes an alias for bfd_get_32.
+ (arc_bfd_put_32): Becomes an alias for bfd_put_32.
+ (get_middle_endian_relocation): Delete.
+ (ME): Delete.
+
2016-01-01 Alan Modra <***@gmail.com>

Update year range in copyright notice of all files.
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
index e9e299c..b08f94d 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -90,7 +90,7 @@ char * init_str = INIT_SYM_STRING;
char * fini_str = FINI_SYM_STRING;


-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
case VALUE: \
return #TYPE; \
break;
@@ -140,32 +140,10 @@ is_reloc_for_PLT (reloc_howto_type * howto)

#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
#define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
#define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
-
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section)
-{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section)
-{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)

static bfd_reloc_status_type
arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
@@ -193,7 +171,7 @@ arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
}


-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
TYPE = VALUE,
enum howto_list
{
@@ -202,7 +180,7 @@ enum howto_list
};
#undef ARC_RELOC_HOWTO

-#define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
[TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, #TYPE, FALSE, 0, 0, FALSE),

static struct reloc_howto_struct elf_arc_howto_table[] =
@@ -228,7 +206,7 @@ static struct reloc_howto_struct elf_arc_howto_table[] =

static void arc_elf_howto_init (void)
{
-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
elf_arc_howto_table[TYPE].pc_relative = \
(strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0);
@@ -238,7 +216,7 @@ static void arc_elf_howto_init (void)
#undef ARC_RELOC_HOWTO


-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
[TYPE] = VALUE,
const int howto_table_lookup[] =
{
@@ -262,7 +240,7 @@ struct arc_reloc_map
unsigned char elf_reloc_val;
};

-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
{ BFD_RELOC_##TYPE, R_##TYPE },
static const struct arc_reloc_map arc_reloc_map[] =
{
@@ -473,17 +451,6 @@ debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}

-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc)
-{
- bfd_vma ret =
- ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
-}
-
-#define ME(RELOC) (get_middle_endian_reloction(RELOC))
-
#define S (reloc_data.sym_value \
+ reloc_data.sym_section->output_offset \
+ reloc_data.sym_section->output_section->vma)
@@ -513,12 +480,18 @@ get_middle_endian_relocation (bfd_vma reloc)

#define none (0)

-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
case R_##TYPE: \
{ \
- bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
+ bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
+ if (IS_ME && !bfd_big_endian (reloc_data.input_section->owner)) \
+ insn = (((0x0000fffff & insn) << 16) \
+ | ((0xffff0000 & insn) >> 16)); \
relocation = FORMULA ; \
insn = RELOC_FUNCTION (insn, relocation); \
+ if (IS_ME && !bfd_big_endian (reloc_data.input_section->owner)) \
+ insn = (((0x0000fffff & insn) << 16) \
+ | ((0xffff0000 & insn) >> 16)); \
} \
break;

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 64eeded..400f67a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-06 Andrew Burgess <***@embecosm.com>
+
+ * testsuite/gas/arc/inline-data-1.d: New file.
+ * testsuite/gas/arc/inline-data-1.s: New file.
+
2016-01-01 Alan Modra <***@gmail.com>

Update year range in copyright notice of all files.
diff --git a/gas/testsuite/gas/arc/inline-data-1.d b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+Contents of section .text:
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/ChangeLog b/include/ChangeLog
index 70e19b7..0872d0e 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+2016-01-06 Andrew Burgess <***@embecosm.com>
+
+ * elf/arc-reloc.def: Add field to indicate if each relocation
+ requires middle-endian correction.
+ * elf/arc.h (ARC_RELOC_HOWTO): Add, and ignore, 'IS_ME' field.
+
2016-01-01 Alan Modra <***@gmail.com>

Update year range in copyright notice of all files.
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def
index 893291f..07a5e66 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -1,4 +1,5 @@
ARC_RELOC_HOWTO(ARC_NONE, 0, \
+ FALSE,
2, \
32, \
replace_none, \
@@ -6,6 +7,7 @@ ARC_RELOC_HOWTO(ARC_NONE, 0, \
0)

ARC_RELOC_HOWTO(ARC_8, 1, \
+ FALSE,
0, \
8, \
replace_bits8, \
@@ -13,6 +15,7 @@ ARC_RELOC_HOWTO(ARC_8, 1, \
( S + A ))

ARC_RELOC_HOWTO(ARC_16, 2, \
+ FALSE,
1, \
16, \
replace_bits16, \
@@ -20,6 +23,7 @@ ARC_RELOC_HOWTO(ARC_16, 2, \
( S + A ))

ARC_RELOC_HOWTO(ARC_24, 3, \
+ FALSE,
2, \
24, \
replace_bits24, \
@@ -27,6 +31,7 @@ ARC_RELOC_HOWTO(ARC_24, 3, \
( S + A ))

ARC_RELOC_HOWTO(ARC_32, 4, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -34,6 +39,7 @@ ARC_RELOC_HOWTO(ARC_32, 4, \
( S + A ))

ARC_RELOC_HOWTO(ARC_N8, 8, \
+ FALSE,
0, \
8, \
replace_bits8, \
@@ -41,6 +47,7 @@ ARC_RELOC_HOWTO(ARC_N8, 8, \
( S - A ))

ARC_RELOC_HOWTO(ARC_N16, 9, \
+ FALSE,
1, \
16, \
replace_bits16, \
@@ -48,6 +55,7 @@ ARC_RELOC_HOWTO(ARC_N16, 9, \
( S - A ))

ARC_RELOC_HOWTO(ARC_N24, 10, \
+ FALSE,
2, \
24, \
replace_bits24, \
@@ -55,6 +63,7 @@ ARC_RELOC_HOWTO(ARC_N24, 10, \
( S - A ))

ARC_RELOC_HOWTO(ARC_N32, 11, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -62,6 +71,7 @@ ARC_RELOC_HOWTO(ARC_N32, 11, \
( S - A ))

ARC_RELOC_HOWTO(ARC_SDA, 12, \
+ FALSE,
2, \
9, \
replace_disp9, \
@@ -69,6 +79,7 @@ ARC_RELOC_HOWTO(ARC_SDA, 12, \
( S + A ))

ARC_RELOC_HOWTO(ARC_SECTOFF, 13, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -76,6 +87,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF, 13, \
( ( S - SECTSTART ) + A ))

ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
+ TRUE,
2, \
20, \
replace_disp21h, \
@@ -83,6 +95,7 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
( ( ( S + A ) - P ) >> 1 ))

ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
+ TRUE,
2, \
19, \
replace_disp21w, \
@@ -90,6 +103,7 @@ ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
( ( ( S + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
+ TRUE,
2, \
24, \
replace_disp25h, \
@@ -97,6 +111,7 @@ ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
( ( ( S + A ) - P ) >> 1 ))

ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
+ TRUE,
2, \
23, \
replace_disp25w, \
@@ -104,6 +119,7 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
( ( ( S + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SDA32, 18, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -111,6 +127,7 @@ ARC_RELOC_HOWTO(ARC_SDA32, 18, \
( ( S + A ) - _SDA_BASE_ ))

ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
+ TRUE,
2, \
9, \
replace_disp9ls, \
@@ -118,6 +135,7 @@ ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
( ( S + A ) - _SDA_BASE_ ))

ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
+ TRUE,
2, \
9, \
replace_disp9ls, \
@@ -125,6 +143,7 @@ ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))

ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
+ TRUE,
2, \
9, \
replace_disp9ls, \
@@ -132,6 +151,7 @@ ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
+ FALSE,
1, \
9, \
replace_disp9s, \
@@ -139,6 +159,7 @@ ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
( ( S + A ) - _SDA_BASE_ ))

ARC_RELOC_HOWTO(ARC_SDA16_LD1, 23, \
+ FALSE,
1, \
9, \
replace_disp9s, \
@@ -146,6 +167,7 @@ ARC_RELOC_HOWTO(ARC_SDA16_LD1, 23, \
( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))

ARC_RELOC_HOWTO(ARC_SDA16_LD2, 24, \
+ FALSE,
1, \
9, \
replace_disp9s, \
@@ -153,6 +175,7 @@ ARC_RELOC_HOWTO(ARC_SDA16_LD2, 24, \
( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))

ARC_RELOC_HOWTO(ARC_S13_PCREL, 25, \
+ FALSE,
1, \
11, \
replace_disp13s, \
@@ -160,6 +183,7 @@ ARC_RELOC_HOWTO(ARC_S13_PCREL, 25, \
( ( ( S + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_W, 26, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -167,6 +191,7 @@ ARC_RELOC_HOWTO(ARC_W, 26, \
( ( S + A ) & ( ~3 ) ))

ARC_RELOC_HOWTO(ARC_32_ME, 27, \
+ TRUE,
2, \
32, \
replace_limm, \
@@ -174,6 +199,7 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
( S + A ))

ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
+ TRUE,
2, \
32, \
replace_limms, \
@@ -181,6 +207,7 @@ ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
( S + A ))

ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -188,6 +215,7 @@ ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
( S - A ))

ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -195,6 +223,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
( ( S - SECTSTART ) + A ))

ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
+ TRUE,
2, \
32, \
replace_limm, \
@@ -202,6 +231,7 @@ ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
( ( S + A ) - _SDA_BASE_ ))

ARC_RELOC_HOWTO(ARC_W_ME, 31, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -209,6 +239,7 @@ ARC_RELOC_HOWTO(ARC_W_ME, 31, \
( S + A ))

ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -216,6 +247,7 @@ ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
( ( S + A ) - SECTSTART ))

ARC_RELOC_HOWTO(AC_SECTOFF_U8_1, 36, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -223,6 +255,7 @@ ARC_RELOC_HOWTO(AC_SECTOFF_U8_1, 36, \
( ( ( S + A ) - SECTSTART ) >> 1 ))

ARC_RELOC_HOWTO(AC_SECTOFF_U8_2, 37, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -230,6 +263,7 @@ ARC_RELOC_HOWTO(AC_SECTOFF_U8_2, 37, \
( ( ( S + A ) - SECTSTART ) >> 2 ))

ARC_RELOC_HOWTO(AC_SECTFOFF_S9, 38, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -237,6 +271,7 @@ ARC_RELOC_HOWTO(AC_SECTFOFF_S9, 38, \
( ( S + A ) - SECTSTART ))

ARC_RELOC_HOWTO(AC_SECTFOFF_S9_1, 39, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -244,6 +279,7 @@ ARC_RELOC_HOWTO(AC_SECTFOFF_S9_1, 39, \
( ( ( S + A ) - SECTSTART ) >> 1 ))

ARC_RELOC_HOWTO(AC_SECTFOFF_S9_2, 40, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -251,6 +287,7 @@ ARC_RELOC_HOWTO(AC_SECTFOFF_S9_2, 40, \
( ( ( S + A ) - SECTSTART ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -258,6 +295,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
( ( ( S - SECTSTART ) + A ) >> 1 ))

ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -265,6 +303,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
( ( ( S - SECTSTART ) + A ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -272,6 +311,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
( ( ( S - SECTSTART ) + A ) >> 1 ))

ARC_RELOC_HOWTO(ARC_SECTOFF_2, 44, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -279,6 +319,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_2, 44, \
( ( ( S - SECTSTART ) + A ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SDA16_ST2, 48, \
+ FALSE,
1, \
9, \
replace_disp9s1, \
@@ -286,6 +327,7 @@ ARC_RELOC_HOWTO(ARC_SDA16_ST2, 48, \
( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))

ARC_RELOC_HOWTO(ARC_32_PCREL, 49, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -293,6 +335,7 @@ ARC_RELOC_HOWTO(ARC_32_PCREL, 49, \
( ( S + A ) - PDATA ))

ARC_RELOC_HOWTO(ARC_PC32, 50, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -300,6 +343,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
( ( S + A ) - P ))

ARC_RELOC_HOWTO(ARC_GOT32, 59, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -307,6 +351,7 @@ ARC_RELOC_HOWTO(ARC_GOT32, 59, \
( G + A ))

ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -314,6 +359,7 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
( ( ( GOT + G ) + A ) - P ))

ARC_RELOC_HOWTO(ARC_PLT32, 52, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -321,6 +367,7 @@ ARC_RELOC_HOWTO(ARC_PLT32, 52, \
( ( L + A ) - P ))

ARC_RELOC_HOWTO(ARC_COPY, 53, \
+ TRUE,
2, \
0, \
replace_none, \
@@ -328,6 +375,7 @@ ARC_RELOC_HOWTO(ARC_COPY, 53, \
none)

ARC_RELOC_HOWTO(ARC_GLOB_DAT, 54, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -335,6 +383,7 @@ ARC_RELOC_HOWTO(ARC_GLOB_DAT, 54, \
S)

ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -342,6 +391,7 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
S)

ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -349,6 +399,7 @@ ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
( B + A ))

ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -356,6 +407,7 @@ ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
( ( S + A ) - GOT ))

ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -363,6 +415,7 @@ ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
( ( GOT + A ) - P ))

ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
+ TRUE,
2, \
19, \
replace_disp21w, \
@@ -370,6 +423,7 @@ ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
( ( ( L + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
+ TRUE,
2, \
24, \
replace_disp25h, \
@@ -377,6 +431,7 @@ ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
( ( ( L + A ) - P ) >> 1 ))

ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -384,6 +439,7 @@ ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
0)

ARC_RELOC_HOWTO(ARC_TLS_TPOFF, 68, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -391,6 +447,7 @@ ARC_RELOC_HOWTO(ARC_TLS_TPOFF, 68, \
0)

ARC_RELOC_HOWTO(ARC_TLS_GD_GOT, 69, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -398,6 +455,7 @@ ARC_RELOC_HOWTO(ARC_TLS_GD_GOT, 69, \
0)

ARC_RELOC_HOWTO(ARC_TLS_GD_LD, 70, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -405,6 +463,7 @@ ARC_RELOC_HOWTO(ARC_TLS_GD_LD, 70, \
0)

ARC_RELOC_HOWTO(ARC_TLS_GD_CALL, 71, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -412,6 +471,7 @@ ARC_RELOC_HOWTO(ARC_TLS_GD_CALL, 71, \
0)

ARC_RELOC_HOWTO(ARC_TLS_IE_GOT, 72, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -419,6 +479,7 @@ ARC_RELOC_HOWTO(ARC_TLS_IE_GOT, 72, \
0)

ARC_RELOC_HOWTO(ARC_TLS_DTPOFF, 67, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -426,6 +487,7 @@ ARC_RELOC_HOWTO(ARC_TLS_DTPOFF, 67, \
0)

ARC_RELOC_HOWTO(ARC_TLS_DTPOFF_S9, 73, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -433,6 +495,7 @@ ARC_RELOC_HOWTO(ARC_TLS_DTPOFF_S9, 73, \
0)

ARC_RELOC_HOWTO(ARC_TLS_LE_S9, 74, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -440,6 +503,7 @@ ARC_RELOC_HOWTO(ARC_TLS_LE_S9, 74, \
0)

ARC_RELOC_HOWTO(ARC_TLS_LE_32, 75, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -447,6 +511,7 @@ ARC_RELOC_HOWTO(ARC_TLS_LE_32, 75, \
0)

ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
+ TRUE,
2, \
23, \
replace_disp25w, \
@@ -454,6 +519,7 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
( ( ( L + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
+ TRUE,
2, \
20, \
replace_disp21h, \
diff --git a/include/elf/arc.h b/include/elf/arc.h
index e535f24..06aa00c 100644
--- a/include/elf/arc.h
+++ b/include/elf/arc.h
@@ -28,7 +28,7 @@

/* Relocations. */

-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
RELOC_NUMBER(R_##TYPE, VALUE)

START_RELOC_NUMBERS (elf_arc_reloc_type)
--
2.5.1
Cupertino Miranda
2016-01-06 15:56:24 UTC
Permalink
Hi Andrew,

We are currently finishing cleaning up a patch to integrate support for Linux (PIC and TLS).
I am glad to say that we have realized this mistake and would intend to address it soon after the upcoming patch.
Nevertheless, your implementation does it a little different from how we would like to address it.

More precisely we do not define a new field in the RELOC_HOWTO but implement it through the FORMULA field using the ME preprocessor macro.

ARC_RELOC_HOWTO(ARC_PC32, 50, \
2, \
32, \
replace_word32, \
signed, \
( ME ( ( S + A ) - P ) ))

ME macro instead of deleted gets replaced by:
#define ME(RELOC) (RELOC)

And the remaining part does pretty much the same as your code, but resorting to the FORMULA to check if ME is present.

static bfd_vma
middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
if (do_it)
{
insn =
((insn & 0xffff0000) >> 16) |
((insn & 0xffff) << 16);
}
return insn;
}

#define IS_ME(FORMULA) (strstr(#FORMULA, "ME") != NULL)

#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
case R_##TYPE: \
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
relocation = FORMULA ; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
} \
break;

Our view is to keep relocation definitions to be limited to this FORMULA concept, instead of adding new fields to the relocation table.

-----Original Message-----
From: Andrew Burgess [mailto:***@embecosm.com]
Sent: Wednesday, January 06, 2016 2:46 PM
To: ***@sourceware.org
Cc: ***@synopsys.com; ***@synopsys.com; Andrew Burgess
Subject: [PATCH] bfd/arc: Allow non-instruction relocations within .text sections

On a little endian arc, a 4-byte instruction ABCD, where A is the most significant byte, and D is the least significant byte would be stored in memory (low to high) as BADC. That is, each 2-byte chunk is stored in little endian order in memory.

Currently, when a relocation is applied to such a 4-byte instruction, we make use of arc_bfd_get_32 and arc_bfd_put_32, which perform byte manipulation to correct for this in memory byte ordering.

This byte ordering correction is applied to all relocations within executable sections (for little endian arc) when really the correction should only be applied to instruction relocations; it is the instruction fetch mechanism that loads 4-byte instructions 2-bytes at a time.

It is possible to place data into an executable section, for example it might be more efficient to place small jump tables inline within the code rather than placing them into a data section.

The problem then, is that these two aspects, the byte order correction, and inline data, conflict. Placing a 4-byte label relocation inline in the code results in the byte-order correction being applied to it, which, when the label is loaded using a standard arc load instruction, returns a corrupted address.

Before the recent arc rewrite, placing data inline into the executable sections did work. This was thanks to using a different code path to patch instruction related relocations, to the code that patched data related relocations. The instruction related relocations therefore received the byte order correction, while the data related relocations didn't.

After the recent rewrite this feature was lost, though I believe this was by accident, rather than design. This commit brings this feature back, though the implementation is different, in order to fit with the new arc design.

All arc relocations receive a new field that indicates if the relocation is an instruction relocation, or not. Instruction relocations can then apply the byte order correction (for little endian arcs only). Data relocations never apply byte order correction.

bfd/ChangeLog:

* elf32-arc.c (ARC_RELOC_HOWTO): Add new 'IS_ME' parameter to each
definition of this macro. The new parameter is ignored in all
cases except for in 'arc_do_relocation' where we perform endian
correction if required.
(arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(get_middle_endian_relocation): Delete.
(ME): Delete.

include/ChangeLog:

* elf/arc-reloc.def: Add field to indicate if each relocation
requires middle-endian correction.
* elf/arc.h (ARC_RELOC_HOWTO): Add, and ignore, 'IS_ME' field.

gas/ChangeLog:

* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
---
bfd/ChangeLog | 11 ++++++
bfd/elf32-arc.c | 59 +++++++++----------------------
gas/ChangeLog | 5 +++
gas/testsuite/gas/arc/inline-data-1.d | 7 ++++ gas/testsuite/gas/arc/inline-data-1.s | 4 +++
include/ChangeLog | 6 ++++
include/elf/arc-reloc.def | 66 +++++++++++++++++++++++++++++++++++
include/elf/arc.h | 2 +-
8 files changed, 116 insertions(+), 44 deletions(-) create mode 100644 gas/testsuite/gas/arc/inline-data-1.d
create mode 100644 gas/testsuite/gas/arc/inline-data-1.s

diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 063cd14..381521b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2016-01-05 Andrew Burgess <***@embecosm.com>
+
+ * elf32-arc.c (ARC_RELOC_HOWTO): Add new 'IS_ME' parameter to each
+ definition of this macro. The new parameter is ignored in all
+ cases except for in 'arc_do_relocation' where we perform endian
+ correction if required.
+ (arc_bfd_get_32): Becomes an alias for bfd_get_32.
+ (arc_bfd_put_32): Becomes an alias for bfd_put_32.
+ (get_middle_endian_relocation): Delete.
+ (ME): Delete.
+
2016-01-01 Alan Modra <***@gmail.com>

Update year range in copyright notice of all files.
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index e9e299c..b08f94d 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -90,7 +90,7 @@ char * init_str = INIT_SYM_STRING; char * fini_str = FINI_SYM_STRING;


-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE,
+RELOC_FUNCTION, OVERFLOW, FORMULA) \
case VALUE: \
return #TYPE; \
break;
@@ -140,32 +140,10 @@ is_reloc_for_PLT (reloc_howto_type * howto)

#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B) #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C) #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
-
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section) -{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section) -{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)

static bfd_reloc_status_type
arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED, @@ -193,7 +171,7 @@ arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED, }


-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE,
+RELOC_FUNCTION, OVERFLOW, FORMULA) \
TYPE = VALUE,
enum howto_list
{
@@ -202,7 +180,7 @@ enum howto_list
};
#undef ARC_RELOC_HOWTO

-#define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, RSIZE, BITSIZE,
+RELOC_FUNCTION, OVERFLOW, FORMULA) \
[TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, #TYPE, FALSE, 0, 0, FALSE),

static struct reloc_howto_struct elf_arc_howto_table[] = @@ -228,7 +206,7 @@ static struct reloc_howto_struct elf_arc_howto_table[] =

static void arc_elf_howto_init (void)
{
-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE,
+RELOC_FUNCTION, OVERFLOW, FORMULA) \
elf_arc_howto_table[TYPE].pc_relative = \
(strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); @@ -238,7 +216,7 @@ static void arc_elf_howto_init (void) #undef ARC_RELOC_HOWTO


-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE,
+RELOC_FUNCTION, OVERFLOW, FORMULA) \
[TYPE] = VALUE,
const int howto_table_lookup[] =
{
@@ -262,7 +240,7 @@ struct arc_reloc_map
unsigned char elf_reloc_val;
};

-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE,
+RELOC_FUNCTION, OVERFLOW, FORMULA) \
{ BFD_RELOC_##TYPE, R_##TYPE },
static const struct arc_reloc_map arc_reloc_map[] = { @@ -473,17 +451,6 @@ debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}

-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc) -{
- bfd_vma ret =
- ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
-}
-
-#define ME(RELOC) (get_middle_endian_reloction(RELOC))
-
#define S (reloc_data.sym_value \
+ reloc_data.sym_section->output_offset \
+ reloc_data.sym_section->output_section->vma)
@@ -513,12 +480,18 @@ get_middle_endian_relocation (bfd_vma reloc)

#define none (0)

-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE,
+RELOC_FUNCTION, OVERFLOW, FORMULA) \
case R_##TYPE: \
{ \
- bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
+ bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
+ if (IS_ME && !bfd_big_endian (reloc_data.input_section->owner)) \
+ insn = (((0x0000fffff & insn) << 16) \
+ | ((0xffff0000 & insn) >> 16)); \
relocation = FORMULA ; \
insn = RELOC_FUNCTION (insn, relocation); \
+ if (IS_ME && !bfd_big_endian (reloc_data.input_section->owner)) \
+ insn = (((0x0000fffff & insn) << 16) \
+ | ((0xffff0000 & insn) >> 16)); \
} \
break;

diff --git a/gas/ChangeLog b/gas/ChangeLog index 64eeded..400f67a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-06 Andrew Burgess <***@embecosm.com>
+
+ * testsuite/gas/arc/inline-data-1.d: New file.
+ * testsuite/gas/arc/inline-data-1.s: New file.
+
2016-01-01 Alan Modra <***@gmail.com>

Update year range in copyright notice of all files.
diff --git a/gas/testsuite/gas/arc/inline-data-1.d b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+Contents of section .text:
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/ChangeLog b/include/ChangeLog index 70e19b7..0872d0e 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+2016-01-06 Andrew Burgess <***@embecosm.com>
+
+ * elf/arc-reloc.def: Add field to indicate if each relocation
+ requires middle-endian correction.
+ * elf/arc.h (ARC_RELOC_HOWTO): Add, and ignore, 'IS_ME' field.
+
2016-01-01 Alan Modra <***@gmail.com>

Update year range in copyright notice of all files.
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def index 893291f..07a5e66 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -1,4 +1,5 @@
ARC_RELOC_HOWTO(ARC_NONE, 0, \
+ FALSE,
2, \
32, \
replace_none, \
@@ -6,6 +7,7 @@ ARC_RELOC_HOWTO(ARC_NONE, 0, \
0)

ARC_RELOC_HOWTO(ARC_8, 1, \
+ FALSE,
0, \
8, \
replace_bits8, \
@@ -13,6 +15,7 @@ ARC_RELOC_HOWTO(ARC_8, 1, \
( S + A ))

ARC_RELOC_HOWTO(ARC_16, 2, \
+ FALSE,
1, \
16, \
replace_bits16, \
@@ -20,6 +23,7 @@ ARC_RELOC_HOWTO(ARC_16, 2, \
( S + A ))

ARC_RELOC_HOWTO(ARC_24, 3, \
+ FALSE,
2, \
24, \
replace_bits24, \
@@ -27,6 +31,7 @@ ARC_RELOC_HOWTO(ARC_24, 3, \
( S + A ))

ARC_RELOC_HOWTO(ARC_32, 4, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -34,6 +39,7 @@ ARC_RELOC_HOWTO(ARC_32, 4, \
( S + A ))

ARC_RELOC_HOWTO(ARC_N8, 8, \
+ FALSE,
0, \
8, \
replace_bits8, \
@@ -41,6 +47,7 @@ ARC_RELOC_HOWTO(ARC_N8, 8, \
( S - A ))

ARC_RELOC_HOWTO(ARC_N16, 9, \
+ FALSE,
1, \
16, \
replace_bits16, \
@@ -48,6 +55,7 @@ ARC_RELOC_HOWTO(ARC_N16, 9, \
( S - A ))

ARC_RELOC_HOWTO(ARC_N24, 10, \
+ FALSE,
2, \
24, \
replace_bits24, \
@@ -55,6 +63,7 @@ ARC_RELOC_HOWTO(ARC_N24, 10, \
( S - A ))

ARC_RELOC_HOWTO(ARC_N32, 11, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -62,6 +71,7 @@ ARC_RELOC_HOWTO(ARC_N32, 11, \
( S - A ))

ARC_RELOC_HOWTO(ARC_SDA, 12, \
+ FALSE,
2, \
9, \
replace_disp9, \
@@ -69,6 +79,7 @@ ARC_RELOC_HOWTO(ARC_SDA, 12, \
( S + A ))

ARC_RELOC_HOWTO(ARC_SECTOFF, 13, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -76,6 +87,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF, 13, \
( ( S - SECTSTART ) + A ))

ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
+ TRUE,
2, \
20, \
replace_disp21h, \
@@ -83,6 +95,7 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
( ( ( S + A ) - P ) >> 1 ))

ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
+ TRUE,
2, \
19, \
replace_disp21w, \
@@ -90,6 +103,7 @@ ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
( ( ( S + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
+ TRUE,
2, \
24, \
replace_disp25h, \
@@ -97,6 +111,7 @@ ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
( ( ( S + A ) - P ) >> 1 ))

ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
+ TRUE,
2, \
23, \
replace_disp25w, \
@@ -104,6 +119,7 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
( ( ( S + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SDA32, 18, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -111,6 +127,7 @@ ARC_RELOC_HOWTO(ARC_SDA32, 18, \
( ( S + A ) - _SDA_BASE_ ))

ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
+ TRUE,
2, \
9, \
replace_disp9ls, \
@@ -118,6 +135,7 @@ ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
( ( S + A ) - _SDA_BASE_ ))

ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
+ TRUE,
2, \
9, \
replace_disp9ls, \
@@ -125,6 +143,7 @@ ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))

ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
+ TRUE,
2, \
9, \
replace_disp9ls, \
@@ -132,6 +151,7 @@ ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
+ FALSE,
1, \
9, \
replace_disp9s, \
@@ -139,6 +159,7 @@ ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
( ( S + A ) - _SDA_BASE_ ))

ARC_RELOC_HOWTO(ARC_SDA16_LD1, 23, \
+ FALSE,
1, \
9, \
replace_disp9s, \
@@ -146,6 +167,7 @@ ARC_RELOC_HOWTO(ARC_SDA16_LD1, 23, \
( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))

ARC_RELOC_HOWTO(ARC_SDA16_LD2, 24, \
+ FALSE,
1, \
9, \
replace_disp9s, \
@@ -153,6 +175,7 @@ ARC_RELOC_HOWTO(ARC_SDA16_LD2, 24, \
( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))

ARC_RELOC_HOWTO(ARC_S13_PCREL, 25, \
+ FALSE,
1, \
11, \
replace_disp13s, \
@@ -160,6 +183,7 @@ ARC_RELOC_HOWTO(ARC_S13_PCREL, 25, \
( ( ( S + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_W, 26, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -167,6 +191,7 @@ ARC_RELOC_HOWTO(ARC_W, 26, \
( ( S + A ) & ( ~3 ) ))

ARC_RELOC_HOWTO(ARC_32_ME, 27, \
+ TRUE,
2, \
32, \
replace_limm, \
@@ -174,6 +199,7 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
( S + A ))

ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
+ TRUE,
2, \
32, \
replace_limms, \
@@ -181,6 +207,7 @@ ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
( S + A ))

ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -188,6 +215,7 @@ ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
( S - A ))

ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -195,6 +223,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
( ( S - SECTSTART ) + A ))

ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
+ TRUE,
2, \
32, \
replace_limm, \
@@ -202,6 +231,7 @@ ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
( ( S + A ) - _SDA_BASE_ ))

ARC_RELOC_HOWTO(ARC_W_ME, 31, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -209,6 +239,7 @@ ARC_RELOC_HOWTO(ARC_W_ME, 31, \
( S + A ))

ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -216,6 +247,7 @@ ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
( ( S + A ) - SECTSTART ))

ARC_RELOC_HOWTO(AC_SECTOFF_U8_1, 36, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -223,6 +255,7 @@ ARC_RELOC_HOWTO(AC_SECTOFF_U8_1, 36, \
( ( ( S + A ) - SECTSTART ) >> 1 ))

ARC_RELOC_HOWTO(AC_SECTOFF_U8_2, 37, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -230,6 +263,7 @@ ARC_RELOC_HOWTO(AC_SECTOFF_U8_2, 37, \
( ( ( S + A ) - SECTSTART ) >> 2 ))

ARC_RELOC_HOWTO(AC_SECTFOFF_S9, 38, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -237,6 +271,7 @@ ARC_RELOC_HOWTO(AC_SECTFOFF_S9, 38, \
( ( S + A ) - SECTSTART ))

ARC_RELOC_HOWTO(AC_SECTFOFF_S9_1, 39, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -244,6 +279,7 @@ ARC_RELOC_HOWTO(AC_SECTFOFF_S9_1, 39, \
( ( ( S + A ) - SECTSTART ) >> 1 ))

ARC_RELOC_HOWTO(AC_SECTFOFF_S9_2, 40, \
+ FALSE,
2, \
9, \
replace_disp9ls, \
@@ -251,6 +287,7 @@ ARC_RELOC_HOWTO(AC_SECTFOFF_S9_2, 40, \
( ( ( S + A ) - SECTSTART ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -258,6 +295,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
( ( ( S - SECTSTART ) + A ) >> 1 ))

ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -265,6 +303,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
( ( ( S - SECTSTART ) + A ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -272,6 +311,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
( ( ( S - SECTSTART ) + A ) >> 1 ))

ARC_RELOC_HOWTO(ARC_SECTOFF_2, 44, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -279,6 +319,7 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_2, 44, \
( ( ( S - SECTSTART ) + A ) >> 2 ))

ARC_RELOC_HOWTO(ARC_SDA16_ST2, 48, \
+ FALSE,
1, \
9, \
replace_disp9s1, \
@@ -286,6 +327,7 @@ ARC_RELOC_HOWTO(ARC_SDA16_ST2, 48, \
( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))

ARC_RELOC_HOWTO(ARC_32_PCREL, 49, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -293,6 +335,7 @@ ARC_RELOC_HOWTO(ARC_32_PCREL, 49, \
( ( S + A ) - PDATA ))

ARC_RELOC_HOWTO(ARC_PC32, 50, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -300,6 +343,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
( ( S + A ) - P ))

ARC_RELOC_HOWTO(ARC_GOT32, 59, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -307,6 +351,7 @@ ARC_RELOC_HOWTO(ARC_GOT32, 59, \
( G + A ))

ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -314,6 +359,7 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
( ( ( GOT + G ) + A ) - P ))

ARC_RELOC_HOWTO(ARC_PLT32, 52, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -321,6 +367,7 @@ ARC_RELOC_HOWTO(ARC_PLT32, 52, \
( ( L + A ) - P ))

ARC_RELOC_HOWTO(ARC_COPY, 53, \
+ TRUE,
2, \
0, \
replace_none, \
@@ -328,6 +375,7 @@ ARC_RELOC_HOWTO(ARC_COPY, 53, \
none)

ARC_RELOC_HOWTO(ARC_GLOB_DAT, 54, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -335,6 +383,7 @@ ARC_RELOC_HOWTO(ARC_GLOB_DAT, 54, \
S)

ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -342,6 +391,7 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
S)

ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -349,6 +399,7 @@ ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
( B + A ))

ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -356,6 +407,7 @@ ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
( ( S + A ) - GOT ))

ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -363,6 +415,7 @@ ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
( ( GOT + A ) - P ))

ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
+ TRUE,
2, \
19, \
replace_disp21w, \
@@ -370,6 +423,7 @@ ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
( ( ( L + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
+ TRUE,
2, \
24, \
replace_disp25h, \
@@ -377,6 +431,7 @@ ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
( ( ( L + A ) - P ) >> 1 ))

ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -384,6 +439,7 @@ ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
0)

ARC_RELOC_HOWTO(ARC_TLS_TPOFF, 68, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -391,6 +447,7 @@ ARC_RELOC_HOWTO(ARC_TLS_TPOFF, 68, \
0)

ARC_RELOC_HOWTO(ARC_TLS_GD_GOT, 69, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -398,6 +455,7 @@ ARC_RELOC_HOWTO(ARC_TLS_GD_GOT, 69, \
0)

ARC_RELOC_HOWTO(ARC_TLS_GD_LD, 70, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -405,6 +463,7 @@ ARC_RELOC_HOWTO(ARC_TLS_GD_LD, 70, \
0)

ARC_RELOC_HOWTO(ARC_TLS_GD_CALL, 71, \
+ FALSE,
2, \
32, \
replace_word32, \
@@ -412,6 +471,7 @@ ARC_RELOC_HOWTO(ARC_TLS_GD_CALL, 71, \
0)

ARC_RELOC_HOWTO(ARC_TLS_IE_GOT, 72, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -419,6 +479,7 @@ ARC_RELOC_HOWTO(ARC_TLS_IE_GOT, 72, \
0)

ARC_RELOC_HOWTO(ARC_TLS_DTPOFF, 67, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -426,6 +487,7 @@ ARC_RELOC_HOWTO(ARC_TLS_DTPOFF, 67, \
0)

ARC_RELOC_HOWTO(ARC_TLS_DTPOFF_S9, 73, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -433,6 +495,7 @@ ARC_RELOC_HOWTO(ARC_TLS_DTPOFF_S9, 73, \
0)

ARC_RELOC_HOWTO(ARC_TLS_LE_S9, 74, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -440,6 +503,7 @@ ARC_RELOC_HOWTO(ARC_TLS_LE_S9, 74, \
0)

ARC_RELOC_HOWTO(ARC_TLS_LE_32, 75, \
+ TRUE,
2, \
32, \
replace_word32, \
@@ -447,6 +511,7 @@ ARC_RELOC_HOWTO(ARC_TLS_LE_32, 75, \
0)

ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
+ TRUE,
2, \
23, \
replace_disp25w, \
@@ -454,6 +519,7 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
( ( ( L + A ) - P ) >> 2 ))

ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
+ TRUE,
2, \
20, \
replace_disp21h, \
diff --git a/include/elf/arc.h b/include/elf/arc.h index e535f24..06aa00c 100644
--- a/include/elf/arc.h
+++ b/include/elf/arc.h
@@ -28,7 +28,7 @@

/* Relocations. */

-#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+#define ARC_RELOC_HOWTO(TYPE, VALUE, IS_ME, SIZE, BITSIZE,
+RELOC_FUNCTION, OVERFLOW, FORMULA) \
RELOC_NUMBER(R_##TYPE, VALUE)

START_RELOC_NUMBERS (elf_arc_reloc_type)
--
2.5.1
Andrew Burgess
2016-01-07 14:44:06 UTC
Permalink
Post by Cupertino Miranda
Hi Andrew,
We are currently finishing cleaning up a patch to integrate support for Linux (PIC and TLS).
I am glad to say that we have realized this mistake and would intend to address it soon after the upcoming patch.
Nevertheless, your implementation does it a little different from how we would like to address it.
More precisely we do not define a new field in the RELOC_HOWTO but implement it through the FORMULA field using the ME preprocessor macro.
ARC_RELOC_HOWTO(ARC_PC32, 50, \
2, \
32, \
replace_word32, \
signed, \
( ME ( ( S + A ) - P ) ))
#define ME(RELOC) (RELOC)
And the remaining part does pretty much the same as your code, but resorting to the FORMULA to check if ME is present.
static bfd_vma
middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
if (do_it)
{
insn =
((insn & 0xffff0000) >> 16) |
((insn & 0xffff) << 16);
}
return insn;
}
#define IS_ME(FORMULA) (strstr(#FORMULA, "ME") != NULL)
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
case R_##TYPE: \
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
relocation = FORMULA ; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
} \
break;
Our view is to keep relocation definitions to be limited to this
FORMULA concept, instead of adding new fields to the relocation
table.
The patch below is a rewrite inline with the description above. The
only change is that I have extended the IS_ME macro to consider
whether the bfd is big or little endian, and I believe that this makes
a difference as to whether the byte shuffling is required.

Is this good with you?

Does my list of formula modifications match the list of changes you
have? I built my list based on how relocations were handled before
the big rewrite, but that doesn't mean it's correct, just that I've
not seen any test regressions either in binutils or GCC.

Thanks,
Andrew

---

On a little endian arc, a 4-byte instruction ABCD, where A is the most
significant byte, and D is the least significant byte would be stored in
memory (low to high) as BADC. That is, each 2-byte chunk is stored in
little endian order in memory.

Currently, when a relocation is applied to such a 4-byte instruction, we
make use of arc_bfd_get_32 and arc_bfd_put_32, which perform byte
manipulation to correct for this in memory byte ordering.

This byte ordering correction is applied to all relocations within
executable sections (for little endian arc) when really the correction
should only be applied to instruction relocations; it is the instruction
fetch mechanism that loads 4-byte instructions 2-bytes at a time.

It is possible to place data into an executable section, for example it
might be more efficient to place small jump tables inline within the
code rather than placing them into a data section.

The problem then, is that these two aspects, the byte order correction,
and inline data, conflict. Placing a 4-byte label relocation inline in
the code results in the byte-order correction being applied to it,
which, when the label is loaded using a standard arc load instruction,
returns a corrupted address.

Before the recent arc rewrite, placing data inline into the executable
sections did work. This was thanks to using a different code path to
patch instruction related relocations, to the code that patched data
related relocations. The instruction related relocations therefore
received the byte order correction, while the data related relocations
didn't.

After the recent rewrite this feature was lost, though I believe this
was by accident, rather than design. This commit brings this feature
back, though the implementation is different, in order to fit with the
new arc design.

The formula field, in those relocations that should have the byte
ordering fix applied, is extended to include a call to a new macro ME,
this macro is then used within the bfd library to trigger the
application of the byte ordering fix when appropriate. This design is
discussed here:
https://sourceware.org/ml/binutils/2016-01/msg00021.html

bfd/ChangeLog:

* elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(get_middle_endian_relocation): Delete.
(middle_endian_convert): New function.
(ME): Redefine, now does nothing.
(IS_ME): New define.
(arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
definition to call middle_endian_convert. Add a new local
variable and make use of this throughout.

include/ChangeLog:

* elf/arc-reloc.def: Add a call to ME within the formula for each
relocation that requires middle-endian correction.

gas/ChangeLog:

* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
---
bfd/ChangeLog | 13 ++++++++
bfd/elf32-arc.c | 59 ++++++++++++++---------------------
gas/ChangeLog | 5 +++
gas/testsuite/gas/arc/inline-data-1.d | 7 +++++
gas/testsuite/gas/arc/inline-data-1.s | 4 +++
include/ChangeLog | 6 ++++
include/elf/arc-reloc.def | 54 ++++++++++++++++----------------
7 files changed, 85 insertions(+), 63 deletions(-)
create mode 100644 gas/testsuite/gas/arc/inline-data-1.d
create mode 100644 gas/testsuite/gas/arc/inline-data-1.s

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 063cd14..1f92602 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+2016-01-05 Cupertino Miranda <***@synopsys.com>
+ Andrew Burgess <***@embecosm.com>
+
+ * elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
+ (arc_bfd_put_32): Becomes an alias for bfd_put_32.
+ (get_middle_endian_relocation): Delete.
+ (middle_endian_convert): New function.
+ (ME): Redefine, now does nothing.
+ (IS_ME): New define.
+ (arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
+ definition to call middle_endian_convert. Add a new local
+ variable and make use of this throughout.
+
2016-01-01 Alan Modra <***@gmail.com>

Update year range in copyright notice of all files.
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
index e9e299c..bf505fc 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -140,32 +140,10 @@ is_reloc_for_PLT (reloc_howto_type * howto)

#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
#define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
#define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
-
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section)
-{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section)
-{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)

static bfd_reloc_status_type
arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
@@ -473,16 +451,22 @@ debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}

-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc)
+static bfd_vma
+middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
- bfd_vma ret =
- ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
+ if (do_it)
+ {
+ insn =
+ ((insn & 0xffff0000) >> 16) |
+ ((insn & 0xffff) << 16);
+ }
+ return insn;
}

-#define ME(RELOC) (get_middle_endian_reloction(RELOC))
+#define ME(reloc) (reloc)
+
+#define IS_ME(FORMULA,BFD) ((strstr(#FORMULA, "ME") != NULL) && \
+ !bfd_big_endian (BFD))

#define S (reloc_data.sym_value \
+ reloc_data.sym_section->output_offset \
@@ -518,7 +502,9 @@ get_middle_endian_relocation (bfd_vma reloc)
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
relocation = FORMULA ; \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
insn = RELOC_FUNCTION (insn, relocation); \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
} \
break;

@@ -528,6 +514,7 @@ arc_do_relocation (bfd_byte * contents, struct arc_relocation_data reloc_data)
bfd_vma relocation = 0;
bfd_vma insn;
bfd_vma orig_insn ATTRIBUTE_UNUSED;
+ bfd * abfd = reloc_data.input_section->owner;

if (reloc_data.should_relocate == FALSE)
return bfd_reloc_notsupported;
@@ -535,13 +522,13 @@ arc_do_relocation (bfd_byte * contents, struct arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
case 2:
- insn = arc_bfd_get_32 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_32 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
case 1:
case 0:
- insn = arc_bfd_get_16 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_16 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
@@ -569,7 +556,7 @@ arc_do_relocation (bfd_byte * contents, struct arc_relocation_data reloc_data)
flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
reloc_data.howto->bitsize,
reloc_data.howto->rightshift,
- bfd_arch_bits_per_address (reloc_data.input_section->owner),
+ bfd_arch_bits_per_address (abfd),
relocation);

#undef DEBUG_ARC_RELOC
@@ -594,13 +581,13 @@ arc_do_relocation (bfd_byte * contents, struct arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
case 2:
- arc_bfd_put_32 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_32 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
case 1:
case 0:
- arc_bfd_put_16 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_16 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 64eeded..400f67a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-06 Andrew Burgess <***@embecosm.com>
+
+ * testsuite/gas/arc/inline-data-1.d: New file.
+ * testsuite/gas/arc/inline-data-1.s: New file.
+
2016-01-01 Alan Modra <***@gmail.com>

Update year range in copyright notice of all files.
diff --git a/gas/testsuite/gas/arc/inline-data-1.d b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+Contents of section .text:
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/ChangeLog b/include/ChangeLog
index 70e19b7..9f2a5d6 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+2016-01-06 Andrew Burgess <***@embecosm.com>
+ Cupertino Miranda <***@synopsys.com>
+
+ * elf/arc-reloc.def: Add a call to ME within the formula for each
+ relocation that requires middle-endian correction.
+
2016-01-01 Alan Modra <***@gmail.com>

Update year range in copyright notice of all files.
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def
index 893291f..cb43a21 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -80,56 +80,56 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
20, \
replace_disp21h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))

ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))

ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))

ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
2, \
23, \
replace_disp25w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))

ARC_RELOC_HOWTO(ARC_SDA32, 18, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))

ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))

ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 1 )))

ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 2 )))

ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
1, \
@@ -171,42 +171,42 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
32, \
replace_limm, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))

ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
2, \
32, \
replace_limms, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))

ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S - A ))
+ ( ME ( S - A )))

ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( S - SECTSTART ) + A ))
+ ( ME ( ( S - SECTSTART ) + A )))

ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
2, \
32, \
replace_limm, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))

ARC_RELOC_HOWTO(ARC_W_ME, 31, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S + A ))
+ ( ME ( S + A )))

ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
2, \
@@ -255,14 +255,14 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 1 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 1 )))

ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 2 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 2 )))

ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
2, \
@@ -297,7 +297,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - P ))
+ ( ME ( ( S + A ) - P )))

ARC_RELOC_HOWTO(ARC_GOT32, 59, \
2, \
@@ -311,14 +311,14 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
32, \
replace_word32, \
signed, \
- ( ( ( GOT + G ) + A ) - P ))
+ ( ME ( ( ( GOT + G ) + A ) - P )))

ARC_RELOC_HOWTO(ARC_PLT32, 52, \
2, \
32, \
replace_word32, \
signed, \
- ( ( L + A ) - P ))
+ ( ME ( ( L + A ) - P )))

ARC_RELOC_HOWTO(ARC_COPY, 53, \
2, \
@@ -339,42 +339,42 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
32, \
replace_word32, \
signed, \
- S)
+ ( ME ( S )))

ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
2, \
32, \
replace_word32, \
signed, \
- ( B + A ))
+ ( ME ( B + A )))

ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - GOT ))
+ ( ME ( ( S + A ) - GOT )))

ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
2, \
32, \
replace_word32, \
signed, \
- ( ( GOT + A ) - P ))
+ ( ME ( ( GOT + A ) - P )))

ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))

ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))

ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
2, \
@@ -451,12 +451,12 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
23, \
replace_disp25w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))

ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
2, \
20, \
replace_disp21h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
--
2.6.4
Claudiu Zissulescu
2016-01-07 15:14:34 UTC
Permalink
Hi guys,

I have two remarks/questions for you:
1. It seems to me adding ME modifier for relocations that are handling short immediate values is superfluous, as the final values are written taken into account the entire instruction, and the big-endian/little-endian flags. Hence, if it is a long instruction always we write it in the form dictated by the endianess (ME for little-endian), if it is short then ME switch is not needed at all. However, if you say that this is ok, then it is fine for me as well.
2. The relocations which are handled by dynamic linker are marked also ME (e.g., JMP_SLOT), is it required?

Best,
Claudiu
Post by Cupertino Miranda
-----Original Message-----
Sent: Thursday, January 07, 2016 3:44 PM
To: Cupertino Miranda
Subject: Re: [PATCH] bfd/arc: Allow non-instruction relocations within .text
sections
Post by Cupertino Miranda
Hi Andrew,
We are currently finishing cleaning up a patch to integrate support for Linux
(PIC and TLS).
Post by Cupertino Miranda
I am glad to say that we have realized this mistake and would intend to
address it soon after the upcoming patch.
Post by Cupertino Miranda
Nevertheless, your implementation does it a little different from how we
would like to address it.
Post by Cupertino Miranda
More precisely we do not define a new field in the RELOC_HOWTO but
implement it through the FORMULA field using the ME preprocessor macro.
Post by Cupertino Miranda
ARC_RELOC_HOWTO(ARC_PC32, 50, \
2, \
32, \
replace_word32, \
signed, \
( ME ( ( S + A ) - P ) ))
#define ME(RELOC) (RELOC)
And the remaining part does pretty much the same as your code, but
resorting to the FORMULA to check if ME is present.
Post by Cupertino Miranda
static bfd_vma
middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
if (do_it)
{
insn =
((insn & 0xffff0000) >> 16) |
((insn & 0xffff) << 16);
}
return insn;
}
#define IS_ME(FORMULA) (strstr(#FORMULA, "ME") != NULL)
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE,
RELOC_FUNCTION, OVERFLOW, FORMULA) \
Post by Cupertino Miranda
case R_##TYPE: \
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
relocation = FORMULA ; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
} \
break;
Our view is to keep relocation definitions to be limited to this
FORMULA concept, instead of adding new fields to the relocation table.
The patch below is a rewrite inline with the description above. The only
change is that I have extended the IS_ME macro to consider whether the bfd
is big or little endian, and I believe that this makes a difference as to whether
the byte shuffling is required.
Is this good with you?
Does my list of formula modifications match the list of changes you have? I
built my list based on how relocations were handled before the big rewrite,
but that doesn't mean it's correct, just that I've not seen any test regressions
either in binutils or GCC.
Thanks,
Andrew
---
On a little endian arc, a 4-byte instruction ABCD, where A is the most
significant byte, and D is the least significant byte would be stored in memory
(low to high) as BADC. That is, each 2-byte chunk is stored in little endian
order in memory.
Currently, when a relocation is applied to such a 4-byte instruction, we make
use of arc_bfd_get_32 and arc_bfd_put_32, which perform byte
manipulation to correct for this in memory byte ordering.
This byte ordering correction is applied to all relocations within executable
sections (for little endian arc) when really the correction should only be
applied to instruction relocations; it is the instruction fetch mechanism that
loads 4-byte instructions 2-bytes at a time.
It is possible to place data into an executable section, for example it might be
more efficient to place small jump tables inline within the code rather than
placing them into a data section.
The problem then, is that these two aspects, the byte order correction, and
inline data, conflict. Placing a 4-byte label relocation inline in the code results
in the byte-order correction being applied to it, which, when the label is
loaded using a standard arc load instruction, returns a corrupted address.
Before the recent arc rewrite, placing data inline into the executable sections
did work. This was thanks to using a different code path to patch instruction
related relocations, to the code that patched data related relocations. The
instruction related relocations therefore received the byte order correction,
while the data related relocations didn't.
After the recent rewrite this feature was lost, though I believe this was by
accident, rather than design. This commit brings this feature back, though
the implementation is different, in order to fit with the new arc design.
The formula field, in those relocations that should have the byte ordering fix
applied, is extended to include a call to a new macro ME, this macro is then
used within the bfd library to trigger the application of the byte ordering fix
https://sourceware.org/ml/binutils/2016-01/msg00021.html
* elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(get_middle_endian_relocation): Delete.
(middle_endian_convert): New function.
(ME): Redefine, now does nothing.
(IS_ME): New define.
(arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
definition to call middle_endian_convert. Add a new local
variable and make use of this throughout.
* elf/arc-reloc.def: Add a call to ME within the formula for each
relocation that requires middle-endian correction.
* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
---
bfd/ChangeLog | 13 ++++++++
bfd/elf32-arc.c | 59 ++++++++++++++---------------------
gas/ChangeLog | 5 +++
gas/testsuite/gas/arc/inline-data-1.d | 7 +++++
gas/testsuite/gas/arc/inline-data-1.s | 4 +++
include/ChangeLog | 6 ++++
include/elf/arc-reloc.def | 54 ++++++++++++++++----------------
7 files changed, 85 insertions(+), 63 deletions(-) create mode 100644
gas/testsuite/gas/arc/inline-data-1.d
create mode 100644 gas/testsuite/gas/arc/inline-data-1.s
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 063cd14..1f92602 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+
+ * elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
+ (arc_bfd_put_32): Becomes an alias for bfd_put_32.
+ (get_middle_endian_relocation): Delete.
+ (middle_endian_convert): New function.
+ (ME): Redefine, now does nothing.
+ (IS_ME): New define.
+ (arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
+ definition to call middle_endian_convert. Add a new local
+ variable and make use of this throughout.
+
Update year range in copyright notice of all files.
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index e9e299c..bf505fc 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -140,32 +140,10 @@ is_reloc_for_PLT (reloc_howto_type * howto)
#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B) #define
arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C) #define
arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
-
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section) -{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section) -{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
static bfd_reloc_status_type
debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}
-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc)
+static bfd_vma
+middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
- bfd_vma ret =
- ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
+ if (do_it)
+ {
+ insn =
+ ((insn & 0xffff0000) >> 16) |
+ ((insn & 0xffff) << 16);
+ }
+ return insn;
}
-#define ME(RELOC) (get_middle_endian_reloction(RELOC))
+#define ME(reloc) (reloc)
+
+#define IS_ME(FORMULA,BFD) ((strstr(#FORMULA, "ME") != NULL) && \
+ !bfd_big_endian (BFD))
#define S (reloc_data.sym_value \
get_middle_endian_relocation (bfd_vma reloc)
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
relocation = FORMULA ; \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
insn = RELOC_FUNCTION (insn, relocation); \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
} \
break;
@@ -528,6 +514,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
bfd_vma relocation = 0;
bfd_vma insn;
bfd_vma orig_insn ATTRIBUTE_UNUSED;
+ bfd * abfd = reloc_data.input_section->owner;
if (reloc_data.should_relocate == FALSE)
return bfd_reloc_notsupported;
@@ -535,13 +522,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- insn = arc_bfd_get_32 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_32 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- insn = arc_bfd_get_16 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_16 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
@@ -569,7 +556,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
reloc_data.howto->bitsize,
reloc_data.howto->rightshift,
- bfd_arch_bits_per_address
(reloc_data.input_section->owner),
+ bfd_arch_bits_per_address (abfd),
relocation);
#undef DEBUG_ARC_RELOC
@@ -594,13 +581,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- arc_bfd_put_32 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_32 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- arc_bfd_put_16 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_16 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
diff --git a/gas/ChangeLog b/gas/ChangeLog index 64eeded..400f67a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+
+ * testsuite/gas/arc/inline-data-1.d: New file.
+ * testsuite/gas/arc/inline-data-1.s: New file.
+
Update year range in copyright notice of all files.
diff --git a/gas/testsuite/gas/arc/inline-data-1.d
b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s
b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/ChangeLog b/include/ChangeLog index 70e19b7..9f2a5d6
100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+
+ * elf/arc-reloc.def: Add a call to ME within the formula for each
+ relocation that requires middle-endian correction.
+
Update year range in copyright notice of all files.
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def index
893291f..cb43a21 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -80,56 +80,56 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
20, \
replace_disp21h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
2, \
23, \
replace_disp25w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA32, 18, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
1, \
@@ -171,42 +171,42 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
32, \
replace_limm, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
2, \
32, \
replace_limms, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S - A ))
+ ( ME ( S - A )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( S - SECTSTART ) + A ))
+ ( ME ( ( S - SECTSTART ) + A )))
ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
2, \
32, \
replace_limm, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_W_ME, 31, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
2, \
@@ -255,14 +255,14 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 1 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 2 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
2, \
@@ -297,7 +297,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - P ))
+ ( ME ( ( S + A ) - P )))
ARC_RELOC_HOWTO(ARC_GOT32, 59, \
2, \
@@ -311,14 +311,14 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
32, \
replace_word32, \
signed, \
- ( ( ( GOT + G ) + A ) - P ))
+ ( ME ( ( ( GOT + G ) + A ) - P )))
ARC_RELOC_HOWTO(ARC_PLT32, 52, \
2, \
32, \
replace_word32, \
signed, \
- ( ( L + A ) - P ))
+ ( ME ( ( L + A ) - P )))
ARC_RELOC_HOWTO(ARC_COPY, 53, \
2, \
@@ -339,42 +339,42 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
32, \
replace_word32, \
signed, \
- S)
+ ( ME ( S )))
ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
2, \
32, \
replace_word32, \
signed, \
- ( B + A ))
+ ( ME ( B + A )))
ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - GOT ))
+ ( ME ( ( S + A ) - GOT )))
ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
2, \
32, \
replace_word32, \
signed, \
- ( ( GOT + A ) - P ))
+ ( ME ( ( GOT + A ) - P )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
2, \
@@ -451,12 +451,12 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
23, \
replace_disp25w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
2, \
20, \
replace_disp21h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
--
2.6.4
Cupertino Miranda
2016-01-07 16:16:22 UTC
Permalink
Hi guys,

The first statement from Claudiu doesn't apply, because the instruction is what suffers the ME conversion, so all short instructions must suffer through ME decoding/encoding..
The reality is that being ME or not is not a property of the relocation but of the memory region, or better, the type of usage given to the particular address, being patched.
Moreover, now looking back to it, I think we should not try to move this information from the relocation, but to understand which cases we should be careful and pay special attention to perform or not to perform middle endianess conversion.

In our current development code (my local fix), I keep the ME conversion in bfd_get_32 and bfd_put_32, but I perform a unME conversion before applying the relocation, if that is a requirement for the relocation type.
Up until now we only identified a single relocation type where ME should not be applied in a SEC_CODE section, more precisely:

ARC_RELOC_HOWTO(ARC_32, 4, \
2, \
32, \
replace_word32, \
bitfield, \
(NON_ME ( S + A ) ))

#define NON_ME(VALUE) reverse_me(reloc_data, VALUE)

bfd_vma
reverse_me(struct arc_relocation_data reloc_data, bfd_vma relocation)
{
if(reloc_data.input_section && reloc_data.input_section->flags & SEC_CODE)
return ((0x0000fffff & relocation) << 16) | ((0xffff0000 & relocation) >> 16);
else
return relocation;
}

This is the case when we have jump tables that get defined in a code section. In this case although the address patched is in a code section it should be treated as a data section, as its content is retrieved with a ld instruction. The interrupt vectors is another case.

I am personally confident that we might not be lacking any other relocation or any big mistakes, as we are currently booting and running fully compiled Linux with the new tools.

I would say that we should spend some more time to define how this middle endian conversion should be done.
Moreover, I won't be able to give the confidence that your patch would not create some problems, as the current upstreamed code is limited to baremetal applications, not allowing me to fully test all the relocation types involved.
Furthermore, it would make more sense to fix this issue right after we apply the upcoming feature intensive patch, supporting Linux and making use of all the relocation types. At that stage both of us can verify and validate the impact of the patch in an overnight regression test. ;-)


-----Original Message-----
From: Claudiu Zissulescu [mailto:***@synopsys.com]
Sent: Thursday, January 07, 2016 4:15 PM
To: Andrew Burgess; Cupertino Miranda
Cc: ***@sourceware.org
Subject: RE: [PATCH] bfd/arc: Allow non-instruction relocations within .text sections

Hi guys,

I have two remarks/questions for you:
1. It seems to me adding ME modifier for relocations that are handling short immediate values is superfluous, as the final values are written taken into account the entire instruction, and the big-endian/little-endian flags. Hence, if it is a long instruction always we write it in the form dictated by the endianess (ME for little-endian), if it is short then ME switch is not needed at all. However, if you say that this is ok, then it is fine for me as well.
2. The relocations which are handled by dynamic linker are marked also ME (e.g., JMP_SLOT), is it required?

Best,
Claudiu
Post by Cupertino Miranda
-----Original Message-----
Sent: Thursday, January 07, 2016 3:44 PM
To: Cupertino Miranda
Subject: Re: [PATCH] bfd/arc: Allow non-instruction relocations within
.text sections
Post by Cupertino Miranda
Hi Andrew,
We are currently finishing cleaning up a patch to integrate support for Linux
(PIC and TLS).
Post by Cupertino Miranda
I am glad to say that we have realized this mistake and would intend to
address it soon after the upcoming patch.
Post by Cupertino Miranda
Nevertheless, your implementation does it a little different from how we
would like to address it.
Post by Cupertino Miranda
More precisely we do not define a new field in the RELOC_HOWTO but
implement it through the FORMULA field using the ME preprocessor macro.
Post by Cupertino Miranda
ARC_RELOC_HOWTO(ARC_PC32, 50, \
2, \
32, \
replace_word32, \
signed, \
( ME ( ( S + A ) - P ) ))
#define ME(RELOC) (RELOC)
And the remaining part does pretty much the same as your code, but
resorting to the FORMULA to check if ME is present.
Post by Cupertino Miranda
static bfd_vma
middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
if (do_it)
{
insn =
((insn & 0xffff0000) >> 16) |
((insn & 0xffff) << 16);
}
return insn;
}
#define IS_ME(FORMULA) (strstr(#FORMULA, "ME") != NULL)
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE,
RELOC_FUNCTION, OVERFLOW, FORMULA) \
Post by Cupertino Miranda
case R_##TYPE: \
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
relocation = FORMULA ; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
} \
break;
Our view is to keep relocation definitions to be limited to this
FORMULA concept, instead of adding new fields to the relocation table.
The patch below is a rewrite inline with the description above. The
only change is that I have extended the IS_ME macro to consider
whether the bfd is big or little endian, and I believe that this makes
a difference as to whether the byte shuffling is required.
Is this good with you?
Does my list of formula modifications match the list of changes you
have? I built my list based on how relocations were handled before
the big rewrite, but that doesn't mean it's correct, just that I've
not seen any test regressions either in binutils or GCC.
Thanks,
Andrew
---
On a little endian arc, a 4-byte instruction ABCD, where A is the most
significant byte, and D is the least significant byte would be stored
in memory (low to high) as BADC. That is, each 2-byte chunk is stored
in little endian order in memory.
Currently, when a relocation is applied to such a 4-byte instruction,
we make use of arc_bfd_get_32 and arc_bfd_put_32, which perform byte
manipulation to correct for this in memory byte ordering.
This byte ordering correction is applied to all relocations within
executable sections (for little endian arc) when really the correction
should only be applied to instruction relocations; it is the
instruction fetch mechanism that loads 4-byte instructions 2-bytes at a time.
It is possible to place data into an executable section, for example
it might be more efficient to place small jump tables inline within
the code rather than placing them into a data section.
The problem then, is that these two aspects, the byte order
correction, and inline data, conflict. Placing a 4-byte label
relocation inline in the code results in the byte-order correction
being applied to it, which, when the label is loaded using a standard arc load instruction, returns a corrupted address.
Before the recent arc rewrite, placing data inline into the executable
sections did work. This was thanks to using a different code path to
patch instruction related relocations, to the code that patched data
related relocations. The instruction related relocations therefore
received the byte order correction, while the data related relocations didn't.
After the recent rewrite this feature was lost, though I believe this
was by accident, rather than design. This commit brings this feature
back, though the implementation is different, in order to fit with the new arc design.
The formula field, in those relocations that should have the byte
ordering fix applied, is extended to include a call to a new macro ME,
this macro is then used within the bfd library to trigger the
https://sourceware.org/ml/binutils/2016-01/msg00021.html
* elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(get_middle_endian_relocation): Delete.
(middle_endian_convert): New function.
(ME): Redefine, now does nothing.
(IS_ME): New define.
(arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
definition to call middle_endian_convert. Add a new local
variable and make use of this throughout.
* elf/arc-reloc.def: Add a call to ME within the formula for each
relocation that requires middle-endian correction.
* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
---
bfd/ChangeLog | 13 ++++++++
bfd/elf32-arc.c | 59 ++++++++++++++---------------------
gas/ChangeLog | 5 +++
gas/testsuite/gas/arc/inline-data-1.d | 7 +++++
gas/testsuite/gas/arc/inline-data-1.s | 4 +++
include/ChangeLog | 6 ++++
include/elf/arc-reloc.def | 54 ++++++++++++++++----------------
7 files changed, 85 insertions(+), 63 deletions(-) create mode
100644 gas/testsuite/gas/arc/inline-data-1.d
create mode 100644 gas/testsuite/gas/arc/inline-data-1.s
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 063cd14..1f92602 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+
+ * elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
+ (arc_bfd_put_32): Becomes an alias for bfd_put_32.
+ (get_middle_endian_relocation): Delete.
+ (middle_endian_convert): New function.
+ (ME): Redefine, now does nothing.
+ (IS_ME): New define.
+ (arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
+ definition to call middle_endian_convert. Add a new local
+ variable and make use of this throughout.
+
Update year range in copyright notice of all files.
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index e9e299c..bf505fc 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -140,32 +140,10 @@ is_reloc_for_PLT (reloc_howto_type * howto)
#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B) #define
arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C) #define
arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
-
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section) -{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection *
input_section) -{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
static bfd_reloc_status_type
debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}
-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc)
+static bfd_vma
+middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
- bfd_vma ret =
- ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
+ if (do_it)
+ {
+ insn =
+ ((insn & 0xffff0000) >> 16) |
+ ((insn & 0xffff) << 16);
+ }
+ return insn;
}
-#define ME(RELOC) (get_middle_endian_reloction(RELOC))
+#define ME(reloc) (reloc)
+
+#define IS_ME(FORMULA,BFD) ((strstr(#FORMULA, "ME") != NULL) && \
+ !bfd_big_endian (BFD))
#define S (reloc_data.sym_value \
get_middle_endian_relocation (bfd_vma reloc)
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
relocation = FORMULA ; \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
insn = RELOC_FUNCTION (insn, relocation); \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
} \
break;
@@ -528,6 +514,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
bfd_vma relocation = 0;
bfd_vma insn;
bfd_vma orig_insn ATTRIBUTE_UNUSED;
+ bfd * abfd = reloc_data.input_section->owner;
if (reloc_data.should_relocate == FALSE)
return bfd_reloc_notsupported;
@@ -535,13 +522,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- insn = arc_bfd_get_32 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_32 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- insn = arc_bfd_get_16 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_16 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
@@ -569,7 +556,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
reloc_data.howto->bitsize,
reloc_data.howto->rightshift,
- bfd_arch_bits_per_address
(reloc_data.input_section->owner),
+ bfd_arch_bits_per_address (abfd),
relocation);
#undef DEBUG_ARC_RELOC
@@ -594,13 +581,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- arc_bfd_put_32 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_32 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- arc_bfd_put_16 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_16 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
diff --git a/gas/ChangeLog b/gas/ChangeLog index 64eeded..400f67a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+
+ * testsuite/gas/arc/inline-data-1.d: New file.
+ * testsuite/gas/arc/inline-data-1.s: New file.
+
Update year range in copyright notice of all files.
diff --git a/gas/testsuite/gas/arc/inline-data-1.d
b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s
b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/ChangeLog b/include/ChangeLog index
70e19b7..9f2a5d6
100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+
+ * elf/arc-reloc.def: Add a call to ME within the formula for each
+ relocation that requires middle-endian correction.
+
Update year range in copyright notice of all files.
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def index
893291f..cb43a21 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -80,56 +80,56 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
20, \
replace_disp21h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
2, \
23, \
replace_disp25w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA32, 18, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
1, \
@@ -171,42 +171,42 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
32, \
replace_limm, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
2, \
32, \
replace_limms, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S - A ))
+ ( ME ( S - A )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( S - SECTSTART ) + A ))
+ ( ME ( ( S - SECTSTART ) + A )))
ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
2, \
32, \
replace_limm, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_W_ME, 31, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
2, \
@@ -255,14 +255,14 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 1 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 2 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
2, \
@@ -297,7 +297,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - P ))
+ ( ME ( ( S + A ) - P )))
ARC_RELOC_HOWTO(ARC_GOT32, 59, \
2, \
@@ -311,14 +311,14 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
32, \
replace_word32, \
signed, \
- ( ( ( GOT + G ) + A ) - P ))
+ ( ME ( ( ( GOT + G ) + A ) - P )))
ARC_RELOC_HOWTO(ARC_PLT32, 52, \
2, \
32, \
replace_word32, \
signed, \
- ( ( L + A ) - P ))
+ ( ME ( ( L + A ) - P )))
ARC_RELOC_HOWTO(ARC_COPY, 53, \
2, \
@@ -339,42 +339,42 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
32, \
replace_word32, \
signed, \
- S)
+ ( ME ( S )))
ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
2, \
32, \
replace_word32, \
signed, \
- ( B + A ))
+ ( ME ( B + A )))
ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - GOT ))
+ ( ME ( ( S + A ) - GOT )))
ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
2, \
32, \
replace_word32, \
signed, \
- ( ( GOT + A ) - P ))
+ ( ME ( ( GOT + A ) - P )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
2, \
@@ -451,12 +451,12 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
23, \
replace_disp25w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
2, \
20, \
replace_disp21h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
--
2.6.4
Cupertino Miranda
2016-01-07 16:45:49 UTC
Permalink
Just a tiny correction to one of the sentences ...

Hi guys,

The first statement from Claudiu doesn't apply, because the instruction is what suffers the ME conversion, so all short instructions must suffer through ME decoding/encoding..
The reality is that being ME or not is not a property of the relocation but of the memory region, or better, the type of usage given to the particular address, being patched.
Moreover, now looking back to it, I think we should not try to move this information (not from but) to the relocation, but to understand which cases we should be careful and pay special attention to perform or not to perform middle endianess conversion.

In our current development code (my local fix), I keep the ME conversion in bfd_get_32 and bfd_put_32, but I perform a unME conversion before applying the relocation, if that is a requirement for the relocation type.
Up until now we only identified a single relocation type where ME should not be applied in a SEC_CODE section, more precisely:

ARC_RELOC_HOWTO(ARC_32, 4, \
2, \
32, \
replace_word32, \
bitfield, \
(NON_ME ( S + A ) ))

#define NON_ME(VALUE) reverse_me(reloc_data, VALUE)

bfd_vma
reverse_me(struct arc_relocation_data reloc_data, bfd_vma relocation) {
if(reloc_data.input_section && reloc_data.input_section->flags & SEC_CODE)
return ((0x0000fffff & relocation) << 16) | ((0xffff0000 & relocation) >> 16);
else
return relocation;
}

This is the case when we have jump tables that get defined in a code section. In this case although the address patched is in a code section it should be treated as a data section, as its content is retrieved with a ld instruction. The interrupt vectors is another case.

I am personally confident that we might not be lacking any other relocation or any big mistakes, as we are currently booting and running fully compiled Linux with the new tools.

I would say that we should spend some more time to define how this middle endian conversion should be done.
Moreover, I won't be able to give the confidence that your patch would not create some problems, as the current upstreamed code is limited to baremetal applications, not allowing me to fully test all the relocation types involved.
Furthermore, it would make more sense to fix this issue right after we apply the upcoming feature intensive patch, supporting Linux and making use of all the relocation types. At that stage both of us can verify and validate the impact of the patch in an overnight regression test. ;-)


-----Original Message-----
From: Claudiu Zissulescu [mailto:***@synopsys.com]
Sent: Thursday, January 07, 2016 4:15 PM
To: Andrew Burgess; Cupertino Miranda
Cc: ***@sourceware.org
Subject: RE: [PATCH] bfd/arc: Allow non-instruction relocations within .text sections

Hi guys,

I have two remarks/questions for you:
1. It seems to me adding ME modifier for relocations that are handling short immediate values is superfluous, as the final values are written taken into account the entire instruction, and the big-endian/little-endian flags. Hence, if it is a long instruction always we write it in the form dictated by the endianess (ME for little-endian), if it is short then ME switch is not needed at all. However, if you say that this is ok, then it is fine for me as well.
2. The relocations which are handled by dynamic linker are marked also ME (e.g., JMP_SLOT), is it required?

Best,
Claudiu
Post by Cupertino Miranda
-----Original Message-----
Sent: Thursday, January 07, 2016 3:44 PM
To: Cupertino Miranda
Subject: Re: [PATCH] bfd/arc: Allow non-instruction relocations within
.text sections
Post by Cupertino Miranda
Hi Andrew,
We are currently finishing cleaning up a patch to integrate support for Linux
(PIC and TLS).
Post by Cupertino Miranda
I am glad to say that we have realized this mistake and would intend to
address it soon after the upcoming patch.
Post by Cupertino Miranda
Nevertheless, your implementation does it a little different from how we
would like to address it.
Post by Cupertino Miranda
More precisely we do not define a new field in the RELOC_HOWTO but
implement it through the FORMULA field using the ME preprocessor macro.
Post by Cupertino Miranda
ARC_RELOC_HOWTO(ARC_PC32, 50, \
2, \
32, \
replace_word32, \
signed, \
( ME ( ( S + A ) - P ) ))
#define ME(RELOC) (RELOC)
And the remaining part does pretty much the same as your code, but
resorting to the FORMULA to check if ME is present.
Post by Cupertino Miranda
static bfd_vma
middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
if (do_it)
{
insn =
((insn & 0xffff0000) >> 16) |
((insn & 0xffff) << 16);
}
return insn;
}
#define IS_ME(FORMULA) (strstr(#FORMULA, "ME") != NULL)
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE,
RELOC_FUNCTION, OVERFLOW, FORMULA) \
Post by Cupertino Miranda
case R_##TYPE: \
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
relocation = FORMULA ; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
} \
break;
Our view is to keep relocation definitions to be limited to this
FORMULA concept, instead of adding new fields to the relocation table.
The patch below is a rewrite inline with the description above. The
only change is that I have extended the IS_ME macro to consider
whether the bfd is big or little endian, and I believe that this makes
a difference as to whether the byte shuffling is required.
Is this good with you?
Does my list of formula modifications match the list of changes you
have? I built my list based on how relocations were handled before
the big rewrite, but that doesn't mean it's correct, just that I've
not seen any test regressions either in binutils or GCC.
Thanks,
Andrew
---
On a little endian arc, a 4-byte instruction ABCD, where A is the most
significant byte, and D is the least significant byte would be stored
in memory (low to high) as BADC. That is, each 2-byte chunk is stored
in little endian order in memory.
Currently, when a relocation is applied to such a 4-byte instruction,
we make use of arc_bfd_get_32 and arc_bfd_put_32, which perform byte
manipulation to correct for this in memory byte ordering.
This byte ordering correction is applied to all relocations within
executable sections (for little endian arc) when really the correction
should only be applied to instruction relocations; it is the
instruction fetch mechanism that loads 4-byte instructions 2-bytes at a time.
It is possible to place data into an executable section, for example
it might be more efficient to place small jump tables inline within
the code rather than placing them into a data section.
The problem then, is that these two aspects, the byte order
correction, and inline data, conflict. Placing a 4-byte label
relocation inline in the code results in the byte-order correction
being applied to it, which, when the label is loaded using a standard arc load instruction, returns a corrupted address.
Before the recent arc rewrite, placing data inline into the executable
sections did work. This was thanks to using a different code path to
patch instruction related relocations, to the code that patched data
related relocations. The instruction related relocations therefore
received the byte order correction, while the data related relocations didn't.
After the recent rewrite this feature was lost, though I believe this
was by accident, rather than design. This commit brings this feature
back, though the implementation is different, in order to fit with the new arc design.
The formula field, in those relocations that should have the byte
ordering fix applied, is extended to include a call to a new macro ME,
this macro is then used within the bfd library to trigger the
https://sourceware.org/ml/binutils/2016-01/msg00021.html
* elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(get_middle_endian_relocation): Delete.
(middle_endian_convert): New function.
(ME): Redefine, now does nothing.
(IS_ME): New define.
(arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
definition to call middle_endian_convert. Add a new local
variable and make use of this throughout.
* elf/arc-reloc.def: Add a call to ME within the formula for each
relocation that requires middle-endian correction.
* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
---
bfd/ChangeLog | 13 ++++++++
bfd/elf32-arc.c | 59 ++++++++++++++---------------------
gas/ChangeLog | 5 +++
gas/testsuite/gas/arc/inline-data-1.d | 7 +++++
gas/testsuite/gas/arc/inline-data-1.s | 4 +++
include/ChangeLog | 6 ++++
include/elf/arc-reloc.def | 54 ++++++++++++++++----------------
7 files changed, 85 insertions(+), 63 deletions(-) create mode
100644 gas/testsuite/gas/arc/inline-data-1.d
create mode 100644 gas/testsuite/gas/arc/inline-data-1.s
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 063cd14..1f92602 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+
+ * elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
+ (arc_bfd_put_32): Becomes an alias for bfd_put_32.
+ (get_middle_endian_relocation): Delete.
+ (middle_endian_convert): New function.
+ (ME): Redefine, now does nothing.
+ (IS_ME): New define.
+ (arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
+ definition to call middle_endian_convert. Add a new local
+ variable and make use of this throughout.
+
Update year range in copyright notice of all files.
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index e9e299c..bf505fc 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -140,32 +140,10 @@ is_reloc_for_PLT (reloc_howto_type * howto)
#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B) #define
arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C) #define
arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
-
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section) -{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection *
input_section) -{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
static bfd_reloc_status_type
debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}
-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc)
+static bfd_vma
+middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
- bfd_vma ret =
- ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
+ if (do_it)
+ {
+ insn =
+ ((insn & 0xffff0000) >> 16) |
+ ((insn & 0xffff) << 16);
+ }
+ return insn;
}
-#define ME(RELOC) (get_middle_endian_reloction(RELOC))
+#define ME(reloc) (reloc)
+
+#define IS_ME(FORMULA,BFD) ((strstr(#FORMULA, "ME") != NULL) && \
+ !bfd_big_endian (BFD))
#define S (reloc_data.sym_value \
get_middle_endian_relocation (bfd_vma reloc)
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
relocation = FORMULA ; \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
insn = RELOC_FUNCTION (insn, relocation); \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
} \
break;
@@ -528,6 +514,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
bfd_vma relocation = 0;
bfd_vma insn;
bfd_vma orig_insn ATTRIBUTE_UNUSED;
+ bfd * abfd = reloc_data.input_section->owner;
if (reloc_data.should_relocate == FALSE)
return bfd_reloc_notsupported;
@@ -535,13 +522,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- insn = arc_bfd_get_32 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_32 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- insn = arc_bfd_get_16 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_16 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
@@ -569,7 +556,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
reloc_data.howto->bitsize,
reloc_data.howto->rightshift,
- bfd_arch_bits_per_address
(reloc_data.input_section->owner),
+ bfd_arch_bits_per_address (abfd),
relocation);
#undef DEBUG_ARC_RELOC
@@ -594,13 +581,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- arc_bfd_put_32 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_32 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- arc_bfd_put_16 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_16 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
diff --git a/gas/ChangeLog b/gas/ChangeLog index 64eeded..400f67a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+
+ * testsuite/gas/arc/inline-data-1.d: New file.
+ * testsuite/gas/arc/inline-data-1.s: New file.
+
Update year range in copyright notice of all files.
diff --git a/gas/testsuite/gas/arc/inline-data-1.d
b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s
b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/ChangeLog b/include/ChangeLog index
70e19b7..9f2a5d6
100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+
+ * elf/arc-reloc.def: Add a call to ME within the formula for each
+ relocation that requires middle-endian correction.
+
Update year range in copyright notice of all files.
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def index
893291f..cb43a21 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -80,56 +80,56 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
20, \
replace_disp21h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
2, \
23, \
replace_disp25w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA32, 18, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
1, \
@@ -171,42 +171,42 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
32, \
replace_limm, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
2, \
32, \
replace_limms, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S - A ))
+ ( ME ( S - A )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( S - SECTSTART ) + A ))
+ ( ME ( ( S - SECTSTART ) + A )))
ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
2, \
32, \
replace_limm, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_W_ME, 31, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
2, \
@@ -255,14 +255,14 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 1 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 2 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
2, \
@@ -297,7 +297,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - P ))
+ ( ME ( ( S + A ) - P )))
ARC_RELOC_HOWTO(ARC_GOT32, 59, \
2, \
@@ -311,14 +311,14 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
32, \
replace_word32, \
signed, \
- ( ( ( GOT + G ) + A ) - P ))
+ ( ME ( ( ( GOT + G ) + A ) - P )))
ARC_RELOC_HOWTO(ARC_PLT32, 52, \
2, \
32, \
replace_word32, \
signed, \
- ( ( L + A ) - P ))
+ ( ME ( ( L + A ) - P )))
ARC_RELOC_HOWTO(ARC_COPY, 53, \
2, \
@@ -339,42 +339,42 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
32, \
replace_word32, \
signed, \
- S)
+ ( ME ( S )))
ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
2, \
32, \
replace_word32, \
signed, \
- ( B + A ))
+ ( ME ( B + A )))
ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - GOT ))
+ ( ME ( ( S + A ) - GOT )))
ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
2, \
32, \
replace_word32, \
signed, \
- ( ( GOT + A ) - P ))
+ ( ME ( ( GOT + A ) - P )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
2, \
@@ -451,12 +451,12 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
23, \
replace_disp25w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
2, \
20, \
replace_disp21h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
--
2.6.4
Andrew Burgess
2016-01-07 18:48:21 UTC
Permalink
Post by Cupertino Miranda
The first statement from Claudiu doesn't apply, because the
instruction is what suffers the ME conversion, so all short
instructions must suffer through ME decoding/encoding.. The reality
is that being ME or not is not a property of the relocation but of
the memory region, or better, the type of usage given to the
particular address, being patched.
I agree, though I believe that the way that this memory-region / use
relationship is captured is with difference relocation types. So I
think that something along the lines of either of the two patches I
have now posted is the way to go.
Post by Cupertino Miranda
Moreover, now looking back to
it, I think we should not try to move this information (not from
but) to the relocation, but to understand which cases we should be
careful and pay special attention to perform or not to perform
middle endianess conversion.
I agree. That is what I've done in both of the patches I've posted
right? The middle-endian conversion is moved out of the get/put
methods, and into relocation specific code.

So far I think that we're in complete agreement.
Post by Cupertino Miranda
In our current development code (my local fix), I keep the ME
conversion in bfd_get_32 and bfd_put_32, but I perform a unME
conversion before applying the relocation, if that is a requirement
for the relocation type.
I don't think that's a good idea. Given that this get/put is only
used in the one location, that feels like we're just working around a
get/put that's doing the wrong thing. This also feels like it goes
against what you said above; the conversion should be attached to the
relocation, not to generic code.
Post by Cupertino Miranda
Up until now we only identified a single
relocation type where ME should not be applied in a SEC_CODE
OK, I admit that marking up those relocation where ME _should_ be
applied will result in more being marked than if we simply mark those
to which is does not apply. But I think that's easier to understand,
so that doesn't seem like much of a negative to me.
Post by Cupertino Miranda
I would say that we should spend some more time to define how this
middle endian conversion should be done.
Well, I've put forward two patches now, the first (which I prefer),
then the second, which was based on your feedback in:

https://sourceware.org/ml/binutils/2016-01/msg00021.html

So, I'm confused what more there is to discuss. Though I prefer the
first patch, I'll take the second version if it's what you prefer.
Post by Cupertino Miranda
Moreover, I won't be able
to give the confidence that your patch would not create some
problems, as the current upstreamed code is limited to baremetal
applications, not allowing me to fully test all the relocation types
involved.
Given how small this patch is, merging into your local world and
testing should be pretty straight forward I'd have though.
Post by Cupertino Miranda
Furthermore, it would make more sense to fix this issue
right after we apply the upcoming feature intensive patch,
supporting Linux and making use of all the relocation types.
Do you have a date for when the second patch will arrive? This is a
blocking issue for me, and I'd like to see a solution merged sooner
rather than later.

As a counter proposal, given how small that patch is, why don't we
merge the second version of this patch, which sounds like the closest
to whatever you're proposing, then when your next big patch arrives
you can rewrite this code as fits your design.

What do you think?

Thanks,
Andrew
Post by Cupertino Miranda
-----Original Message-----
Sent: Thursday, January 07, 2016 4:15 PM
To: Andrew Burgess; Cupertino Miranda
Subject: RE: [PATCH] bfd/arc: Allow non-instruction relocations within .text sections
Hi guys,
1. It seems to me adding ME modifier for relocations that are handling short immediate values is superfluous, as the final values are written taken into account the entire instruction, and the big-endian/little-endian flags. Hence, if it is a long instruction always we write it in the form dictated by the endianess (ME for little-endian), if it is short then ME switch is not needed at all. However, if you say that this is ok, then it is fine for me as well.
2. The relocations which are handled by dynamic linker are marked also ME (e.g., JMP_SLOT), is it required?
Best,
Claudiu
Post by Cupertino Miranda
-----Original Message-----
Sent: Thursday, January 07, 2016 3:44 PM
To: Cupertino Miranda
Subject: Re: [PATCH] bfd/arc: Allow non-instruction relocations within
.text sections
Post by Cupertino Miranda
Hi Andrew,
We are currently finishing cleaning up a patch to integrate support for Linux
(PIC and TLS).
Post by Cupertino Miranda
I am glad to say that we have realized this mistake and would intend to
address it soon after the upcoming patch.
Post by Cupertino Miranda
Nevertheless, your implementation does it a little different from how we
would like to address it.
Post by Cupertino Miranda
More precisely we do not define a new field in the RELOC_HOWTO but
implement it through the FORMULA field using the ME preprocessor macro.
Post by Cupertino Miranda
ARC_RELOC_HOWTO(ARC_PC32, 50, \
2, \
32, \
replace_word32, \
signed, \
( ME ( ( S + A ) - P ) ))
#define ME(RELOC) (RELOC)
And the remaining part does pretty much the same as your code, but
resorting to the FORMULA to check if ME is present.
Post by Cupertino Miranda
static bfd_vma
middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
if (do_it)
{
insn =
((insn & 0xffff0000) >> 16) |
((insn & 0xffff) << 16);
}
return insn;
}
#define IS_ME(FORMULA) (strstr(#FORMULA, "ME") != NULL)
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE,
RELOC_FUNCTION, OVERFLOW, FORMULA) \
Post by Cupertino Miranda
case R_##TYPE: \
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
relocation = FORMULA ; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
} \
break;
Our view is to keep relocation definitions to be limited to this
FORMULA concept, instead of adding new fields to the relocation table.
The patch below is a rewrite inline with the description above. The
only change is that I have extended the IS_ME macro to consider
whether the bfd is big or little endian, and I believe that this makes
a difference as to whether the byte shuffling is required.
Is this good with you?
Does my list of formula modifications match the list of changes you
have? I built my list based on how relocations were handled before
the big rewrite, but that doesn't mean it's correct, just that I've
not seen any test regressions either in binutils or GCC.
Thanks,
Andrew
---
On a little endian arc, a 4-byte instruction ABCD, where A is the most
significant byte, and D is the least significant byte would be stored
in memory (low to high) as BADC. That is, each 2-byte chunk is stored
in little endian order in memory.
Currently, when a relocation is applied to such a 4-byte instruction,
we make use of arc_bfd_get_32 and arc_bfd_put_32, which perform byte
manipulation to correct for this in memory byte ordering.
This byte ordering correction is applied to all relocations within
executable sections (for little endian arc) when really the correction
should only be applied to instruction relocations; it is the
instruction fetch mechanism that loads 4-byte instructions 2-bytes at a time.
It is possible to place data into an executable section, for example
it might be more efficient to place small jump tables inline within
the code rather than placing them into a data section.
The problem then, is that these two aspects, the byte order
correction, and inline data, conflict. Placing a 4-byte label
relocation inline in the code results in the byte-order correction
being applied to it, which, when the label is loaded using a standard arc load instruction, returns a corrupted address.
Before the recent arc rewrite, placing data inline into the executable
sections did work. This was thanks to using a different code path to
patch instruction related relocations, to the code that patched data
related relocations. The instruction related relocations therefore
received the byte order correction, while the data related relocations didn't.
After the recent rewrite this feature was lost, though I believe this
was by accident, rather than design. This commit brings this feature
back, though the implementation is different, in order to fit with the new arc design.
The formula field, in those relocations that should have the byte
ordering fix applied, is extended to include a call to a new macro ME,
this macro is then used within the bfd library to trigger the
https://sourceware.org/ml/binutils/2016-01/msg00021.html
* elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(get_middle_endian_relocation): Delete.
(middle_endian_convert): New function.
(ME): Redefine, now does nothing.
(IS_ME): New define.
(arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
definition to call middle_endian_convert. Add a new local
variable and make use of this throughout.
* elf/arc-reloc.def: Add a call to ME within the formula for each
relocation that requires middle-endian correction.
* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
---
bfd/ChangeLog | 13 ++++++++
bfd/elf32-arc.c | 59 ++++++++++++++---------------------
gas/ChangeLog | 5 +++
gas/testsuite/gas/arc/inline-data-1.d | 7 +++++
gas/testsuite/gas/arc/inline-data-1.s | 4 +++
include/ChangeLog | 6 ++++
include/elf/arc-reloc.def | 54 ++++++++++++++++----------------
7 files changed, 85 insertions(+), 63 deletions(-) create mode
100644 gas/testsuite/gas/arc/inline-data-1.d
create mode 100644 gas/testsuite/gas/arc/inline-data-1.s
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 063cd14..1f92602 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+
+ * elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
+ (arc_bfd_put_32): Becomes an alias for bfd_put_32.
+ (get_middle_endian_relocation): Delete.
+ (middle_endian_convert): New function.
+ (ME): Redefine, now does nothing.
+ (IS_ME): New define.
+ (arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
+ definition to call middle_endian_convert. Add a new local
+ variable and make use of this throughout.
+
Update year range in copyright notice of all files.
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index e9e299c..bf505fc 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -140,32 +140,10 @@ is_reloc_for_PLT (reloc_howto_type * howto)
#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B) #define
arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C) #define
arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
-
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section) -{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section) -{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
static bfd_reloc_status_type
debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}
-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc)
+static bfd_vma
+middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
- bfd_vma ret =
- ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
+ if (do_it)
+ {
+ insn =
+ ((insn & 0xffff0000) >> 16) |
+ ((insn & 0xffff) << 16);
+ }
+ return insn;
}
-#define ME(RELOC) (get_middle_endian_reloction(RELOC))
+#define ME(reloc) (reloc)
+
+#define IS_ME(FORMULA,BFD) ((strstr(#FORMULA, "ME") != NULL) && \
+ !bfd_big_endian (BFD))
#define S (reloc_data.sym_value \
get_middle_endian_relocation (bfd_vma reloc)
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
relocation = FORMULA ; \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
insn = RELOC_FUNCTION (insn, relocation); \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
} \
break;
@@ -528,6 +514,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
bfd_vma relocation = 0;
bfd_vma insn;
bfd_vma orig_insn ATTRIBUTE_UNUSED;
+ bfd * abfd = reloc_data.input_section->owner;
if (reloc_data.should_relocate == FALSE)
return bfd_reloc_notsupported;
@@ -535,13 +522,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- insn = arc_bfd_get_32 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_32 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- insn = arc_bfd_get_16 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_16 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
@@ -569,7 +556,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
reloc_data.howto->bitsize,
reloc_data.howto->rightshift,
- bfd_arch_bits_per_address
(reloc_data.input_section->owner),
+ bfd_arch_bits_per_address (abfd),
relocation);
#undef DEBUG_ARC_RELOC
@@ -594,13 +581,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- arc_bfd_put_32 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_32 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- arc_bfd_put_16 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_16 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
diff --git a/gas/ChangeLog b/gas/ChangeLog index 64eeded..400f67a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+
+ * testsuite/gas/arc/inline-data-1.d: New file.
+ * testsuite/gas/arc/inline-data-1.s: New file.
+
Update year range in copyright notice of all files.
diff --git a/gas/testsuite/gas/arc/inline-data-1.d
b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s
b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/ChangeLog b/include/ChangeLog index
70e19b7..9f2a5d6
100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+
+ * elf/arc-reloc.def: Add a call to ME within the formula for each
+ relocation that requires middle-endian correction.
+
Update year range in copyright notice of all files.
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def index
893291f..cb43a21 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -80,56 +80,56 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
20, \
replace_disp21h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
2, \
23, \
replace_disp25w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA32, 18, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
1, \
@@ -171,42 +171,42 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
32, \
replace_limm, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
2, \
32, \
replace_limms, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S - A ))
+ ( ME ( S - A )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( S - SECTSTART ) + A ))
+ ( ME ( ( S - SECTSTART ) + A )))
ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
2, \
32, \
replace_limm, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_W_ME, 31, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
2, \
@@ -255,14 +255,14 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 1 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 2 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
2, \
@@ -297,7 +297,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - P ))
+ ( ME ( ( S + A ) - P )))
ARC_RELOC_HOWTO(ARC_GOT32, 59, \
2, \
@@ -311,14 +311,14 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
32, \
replace_word32, \
signed, \
- ( ( ( GOT + G ) + A ) - P ))
+ ( ME ( ( ( GOT + G ) + A ) - P )))
ARC_RELOC_HOWTO(ARC_PLT32, 52, \
2, \
32, \
replace_word32, \
signed, \
- ( ( L + A ) - P ))
+ ( ME ( ( L + A ) - P )))
ARC_RELOC_HOWTO(ARC_COPY, 53, \
2, \
@@ -339,42 +339,42 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
32, \
replace_word32, \
signed, \
- S)
+ ( ME ( S )))
ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
2, \
32, \
replace_word32, \
signed, \
- ( B + A ))
+ ( ME ( B + A )))
ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - GOT ))
+ ( ME ( ( S + A ) - GOT )))
ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
2, \
32, \
replace_word32, \
signed, \
- ( ( GOT + A ) - P ))
+ ( ME ( ( GOT + A ) - P )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
2, \
@@ -451,12 +451,12 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
23, \
replace_disp25w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
2, \
20, \
replace_disp21h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
--
2.6.4
Cupertino Miranda
2016-01-08 10:30:48 UTC
Permalink
Hi Andrew,
Post by Andrew Burgess
Post by Cupertino Miranda
The first statement from Claudiu doesn't apply, because the
instruction is what suffers the ME conversion, so all short
instructions must suffer through ME decoding/encoding.. The reality
is that being ME or not is not a property of the relocation but of the
memory region, or better, the type of usage given to the particular
address, being patched.
I agree, though I believe that the way that this memory-region / use
relationship is captured is with difference relocation types. So I think that
something along the lines of either of the two patches I have now posted is
the way to go.
Post by Cupertino Miranda
Moreover, now looking back to it,
I think we should not try to move this information (not from
but) to the relocation, but to understand which cases we should be
careful and pay special attention to perform or not to perform middle
endianess conversion.
I agree. That is what I've done in both of the patches I've posted right?
No, I made a correction to the sentence and made it confusing.
It should have been read like:
" I think we should not try to move this information to the relocation, but to understand which cases we should be careful and pay special attention to perform or not the middle endianess conversion."
This middle endianess for the tools can be a property of whatever we want, however for the architecture, it is clearly a property of what is going to use the data being patched/relocated. More precisely, who is reading/writing the data (the instruction decoder, or an instruction being executed).
- If it is the instruction decoder, then the data should always be recovered and rewritten with middle endian format conversion.
- If it is an instruction (an ld for example), then independently of the type of section the relocation should happen, we should write it in non middle endian format.
- This happens to be the case only in ARC_32 like I specified in the previous email.
Post by Andrew Burgess
The middle-endian conversion is moved out of the get/put methods, and into
relocation specific code.
So far I think that we're in complete agreement.
Post by Cupertino Miranda
In our current development code (my local fix), I keep the ME
conversion in bfd_get_32 and bfd_put_32, but I perform a unME
conversion before applying the relocation, if that is a requirement
for the relocation type.
I don't think that's a good idea. Given that this get/put is only used in the
one location, that feels like we're just working around a get/put that's doing
the wrong thing. This also feels like it goes against what you said above; the
conversion should be attached to the relocation, not to generic code.
I tried to say the opposite. :-)
Post by Andrew Burgess
Post by Cupertino Miranda
Up until now we only identified a single
relocation type where ME should not be applied in a SEC_CODE section,
OK, I admit that marking up those relocation where ME _should_ be applied
will result in more being marked than if we simply mark those to which is
does not apply. But I think that's easier to understand, so that doesn't seem
like much of a negative to me.
Post by Cupertino Miranda
I would say that we should spend some more time to define how this
middle endian conversion should be done.
Well, I've put forward two patches now, the first (which I prefer), then the
https://sourceware.org/ml/binutils/2016-01/msg00021.html
So, I'm confused what more there is to discuss. Though I prefer the first
patch, I'll take the second version if it's what you prefer.
Post by Cupertino Miranda
Moreover, I won't be able to
give the confidence that your patch would not create some problems, as
the current upstreamed code is limited to baremetal applications, not
allowing me to fully test all the relocation types involved.
Given how small this patch is, merging into your local world and testing
should be pretty straight forward I'd have though.
Post by Cupertino Miranda
Furthermore, it would make more sense to fix this issue
right after we apply the upcoming feature intensive patch, supporting
Linux and making use of all the relocation types.
Do you have a date for when the second patch will arrive? This is a blocking
issue for me, and I'd like to see a solution merged sooner rather than later.
We will send the patch with PIC and TLS support by Monday/Tuesday.
Post by Andrew Burgess
As a counter proposal, given how small that patch is, why don't we merge the
second version of this patch, which sounds like the closest to whatever
you're proposing, then when your next big patch arrives you can rewrite this
code as fits your design.
Although it is a small patch, it makes a fundamental changes to how the relocations are performed.
To be honest, at the moment I cannot test your changes and validate if they are all correct up until I send my patches (Monday/Tuesday).
Also, I would like to validate them with the PIC and TLS support as well, as the current version (baremetal only) does not makes use of many of the changed relocations in your patch.
Post by Andrew Burgess
What do you think?
After some further discussions locally, both me and Claudiu agree with the strategy to move ME to the relocations, however up until further testing we are not fully certain all of the changes are correct.
Nevertheless, we accept the patch. :-)

Kind regards,
Cupertino
Post by Andrew Burgess
Thanks,
Andrew
Post by Cupertino Miranda
-----Original Message-----
Sent: Thursday, January 07, 2016 4:15 PM
To: Andrew Burgess; Cupertino Miranda
Subject: RE: [PATCH] bfd/arc: Allow non-instruction relocations within .text sections
Hi guys,
1. It seems to me adding ME modifier for relocations that are
handling short immediate values is superfluous, as the final values are
written taken into account the entire instruction, and the big-endian/little-
endian flags. Hence, if it is a long instruction always we write it in the form
dictated by the endianess (ME for little-endian), if it is short then ME switch is
not needed at all. However, if you say that this is ok, then it is fine for me as
well.
Post by Cupertino Miranda
2. The relocations which are handled by dynamic linker are marked
also ME (e.g., JMP_SLOT), is it required?
Post by Cupertino Miranda
Best,
Claudiu
Post by Cupertino Miranda
-----Original Message-----
Sent: Thursday, January 07, 2016 3:44 PM
To: Cupertino Miranda
Subject: Re: [PATCH] bfd/arc: Allow non-instruction relocations
within .text sections
Post by Cupertino Miranda
Hi Andrew,
We are currently finishing cleaning up a patch to integrate support for Linux
(PIC and TLS).
Post by Cupertino Miranda
I am glad to say that we have realized this mistake and would intend to
address it soon after the upcoming patch.
Post by Cupertino Miranda
Nevertheless, your implementation does it a little different from how we
would like to address it.
Post by Cupertino Miranda
More precisely we do not define a new field in the RELOC_HOWTO but
implement it through the FORMULA field using the ME preprocessor
macro.
Post by Cupertino Miranda
Post by Cupertino Miranda
Post by Cupertino Miranda
ARC_RELOC_HOWTO(ARC_PC32, 50, \
2, \
32, \
replace_word32, \
signed, \
( ME ( ( S + A ) - P ) ))
#define ME(RELOC) (RELOC)
And the remaining part does pretty much the same as your code, but
resorting to the FORMULA to check if ME is present.
Post by Cupertino Miranda
static bfd_vma
middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
if (do_it)
{
insn =
((insn & 0xffff0000) >> 16) |
((insn & 0xffff) << 16);
}
return insn;
}
#define IS_ME(FORMULA) (strstr(#FORMULA, "ME") != NULL)
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE,
RELOC_FUNCTION, OVERFLOW, FORMULA) \
Post by Cupertino Miranda
case R_##TYPE: \
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
relocation = FORMULA ; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
} \
break;
Our view is to keep relocation definitions to be limited to this
FORMULA concept, instead of adding new fields to the relocation table.
The patch below is a rewrite inline with the description above. The
only change is that I have extended the IS_ME macro to consider
whether the bfd is big or little endian, and I believe that this
makes a difference as to whether the byte shuffling is required.
Is this good with you?
Does my list of formula modifications match the list of changes you
have? I built my list based on how relocations were handled before
the big rewrite, but that doesn't mean it's correct, just that I've
not seen any test regressions either in binutils or GCC.
Thanks,
Andrew
---
On a little endian arc, a 4-byte instruction ABCD, where A is the
most significant byte, and D is the least significant byte would be
stored in memory (low to high) as BADC. That is, each 2-byte chunk
is stored in little endian order in memory.
Currently, when a relocation is applied to such a 4-byte
instruction, we make use of arc_bfd_get_32 and arc_bfd_put_32, which
perform byte manipulation to correct for this in memory byte ordering.
This byte ordering correction is applied to all relocations within
executable sections (for little endian arc) when really the
correction should only be applied to instruction relocations; it is
the instruction fetch mechanism that loads 4-byte instructions 2-bytes at
a time.
Post by Cupertino Miranda
Post by Cupertino Miranda
It is possible to place data into an executable section, for example
it might be more efficient to place small jump tables inline within
the code rather than placing them into a data section.
The problem then, is that these two aspects, the byte order
correction, and inline data, conflict. Placing a 4-byte label
relocation inline in the code results in the byte-order correction
being applied to it, which, when the label is loaded using a standard arc
load instruction, returns a corrupted address.
Post by Cupertino Miranda
Post by Cupertino Miranda
Before the recent arc rewrite, placing data inline into the
executable sections did work. This was thanks to using a different
code path to patch instruction related relocations, to the code that
patched data related relocations. The instruction related
relocations therefore received the byte order correction, while the data
related relocations didn't.
Post by Cupertino Miranda
Post by Cupertino Miranda
After the recent rewrite this feature was lost, though I believe
this was by accident, rather than design. This commit brings this
feature back, though the implementation is different, in order to fit with
the new arc design.
Post by Cupertino Miranda
Post by Cupertino Miranda
The formula field, in those relocations that should have the byte
ordering fix applied, is extended to include a call to a new macro
ME, this macro is then used within the bfd library to trigger the
application of the byte ordering fix when appropriate. This design is
https://sourceware.org/ml/binutils/2016-01/msg00021.html
* elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(get_middle_endian_relocation): Delete.
(middle_endian_convert): New function.
(ME): Redefine, now does nothing.
(IS_ME): New define.
(arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
definition to call middle_endian_convert. Add a new local
variable and make use of this throughout.
* elf/arc-reloc.def: Add a call to ME within the formula for each
relocation that requires middle-endian correction.
* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
---
bfd/ChangeLog | 13 ++++++++
bfd/elf32-arc.c | 59 ++++++++++++++---------------------
gas/ChangeLog | 5 +++
gas/testsuite/gas/arc/inline-data-1.d | 7 +++++
gas/testsuite/gas/arc/inline-data-1.s | 4 +++
include/ChangeLog | 6 ++++
include/elf/arc-reloc.def | 54 ++++++++++++++++----------------
7 files changed, 85 insertions(+), 63 deletions(-) create mode
100644 gas/testsuite/gas/arc/inline-data-1.d
create mode 100644 gas/testsuite/gas/arc/inline-data-1.s
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 063cd14..1f92602 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+
+ * elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
+ (arc_bfd_put_32): Becomes an alias for bfd_put_32.
+ (get_middle_endian_relocation): Delete.
+ (middle_endian_convert): New function.
+ (ME): Redefine, now does nothing.
+ (IS_ME): New define.
+ (arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
+ definition to call middle_endian_convert. Add a new local
+ variable and make use of this throughout.
+
Update year range in copyright notice of all files.
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index
e9e299c..bf505fc
100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -140,32 +140,10 @@ is_reloc_for_PLT (reloc_howto_type * howto)
#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B) #define
arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C) #define
arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
-
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section) -{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section) -{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
static bfd_reloc_status_type
debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}
-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc)
+static bfd_vma
+middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
- bfd_vma ret =
- ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
+ if (do_it)
+ {
+ insn =
+ ((insn & 0xffff0000) >> 16) |
+ ((insn & 0xffff) << 16);
+ }
+ return insn;
}
-#define ME(RELOC) (get_middle_endian_reloction(RELOC))
+#define ME(reloc) (reloc)
+
+#define IS_ME(FORMULA,BFD) ((strstr(#FORMULA, "ME") != NULL) &&
\
Post by Cupertino Miranda
Post by Cupertino Miranda
+ !bfd_big_endian (BFD))
#define S (reloc_data.sym_value \
get_middle_endian_relocation (bfd_vma reloc)
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
relocation = FORMULA ; \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
insn = RELOC_FUNCTION (insn, relocation); \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd)); \
} \
break;
@@ -528,6 +514,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
bfd_vma relocation = 0;
bfd_vma insn;
bfd_vma orig_insn ATTRIBUTE_UNUSED;
+ bfd * abfd = reloc_data.input_section->owner;
if (reloc_data.should_relocate == FALSE)
return bfd_reloc_notsupported;
@@ -535,13 +522,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- insn = arc_bfd_get_32 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_32 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- insn = arc_bfd_get_16 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_16 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
@@ -569,7 +556,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
flag = bfd_check_overflow (reloc_data.howto-
complain_on_overflow,
Post by Cupertino Miranda
reloc_data.howto->bitsize,
reloc_data.howto->rightshift,
- bfd_arch_bits_per_address
(reloc_data.input_section->owner),
+ bfd_arch_bits_per_address (abfd),
relocation);
#undef DEBUG_ARC_RELOC
@@ -594,13 +581,13 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- arc_bfd_put_32 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_32 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- arc_bfd_put_16 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_16 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
diff --git a/gas/ChangeLog b/gas/ChangeLog index 64eeded..400f67a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+
+ * testsuite/gas/arc/inline-data-1.d: New file.
+ * testsuite/gas/arc/inline-data-1.s: New file.
+
Update year range in copyright notice of all files.
diff --git a/gas/testsuite/gas/arc/inline-data-1.d
b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s
b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/ChangeLog b/include/ChangeLog index
70e19b7..9f2a5d6
100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+
+ * elf/arc-reloc.def: Add a call to ME within the formula for each
+ relocation that requires middle-endian correction.
+
Update year range in copyright notice of all files.
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def index
893291f..cb43a21 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -80,56 +80,56 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
20, \
replace_disp21h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
2, \
23, \
replace_disp25w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA32, 18, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
1, \
@@ -171,42 +171,42 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
32, \
replace_limm, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
2, \
32, \
replace_limms, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S - A ))
+ ( ME ( S - A )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( S - SECTSTART ) + A ))
+ ( ME ( ( S - SECTSTART ) + A )))
ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
2, \
32, \
replace_limm, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_W_ME, 31, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
2, \
@@ -255,14 +255,14 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41,
\
Post by Cupertino Miranda
Post by Cupertino Miranda
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 1 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 2 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
2, \
@@ -297,7 +297,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - P ))
+ ( ME ( ( S + A ) - P )))
ARC_RELOC_HOWTO(ARC_GOT32, 59, \
2, \
@@ -311,14 +311,14 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
32, \
replace_word32, \
signed, \
- ( ( ( GOT + G ) + A ) - P ))
+ ( ME ( ( ( GOT + G ) + A ) - P )))
ARC_RELOC_HOWTO(ARC_PLT32, 52, \
2, \
32, \
replace_word32, \
signed, \
- ( ( L + A ) - P ))
+ ( ME ( ( L + A ) - P )))
ARC_RELOC_HOWTO(ARC_COPY, 53, \
2, \
@@ -339,42 +339,42 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
32, \
replace_word32, \
signed, \
- S)
+ ( ME ( S )))
ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
2, \
32, \
replace_word32, \
signed, \
- ( B + A ))
+ ( ME ( B + A )))
ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - GOT ))
+ ( ME ( ( S + A ) - GOT )))
ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
2, \
32, \
replace_word32, \
signed, \
- ( ( GOT + A ) - P ))
+ ( ME ( ( GOT + A ) - P )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
2, \
@@ -451,12 +451,12 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT,
76, \
Post by Cupertino Miranda
Post by Cupertino Miranda
23, \
replace_disp25w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
2, \
20, \
replace_disp21h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
--
2.6.4
Cupertino Miranda
2016-02-25 11:03:05 UTC
Permalink
Hi Andrew and all,

I have tested and fixed this patch. The attached one should now work for all of the ARC variant emulations/targets.
I have also included a fix for all 8 bit relocs which were wrong for big endian format.

Andrew: Do you have any comments on the patch as it is?

Best regards,
Cupertino

bfd/ChangeLog:

Cupertino Miranda <***@synopsys.com>
Andrew Burgess <***@embecosm.com>

* elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(arc_elf_howto_init): Added assert to validate relocations.
(get_middle_endian_relocation): Delete.
(middle_endian_convert): New function.
(ME): Redefine, now does nothing.
(IS_ME): New define.
(arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
definition to call middle_endian_convert. Add a new local
variable and make use of this throughout. Added call to
arc_bfd_get_8 and arc_bfd_put_8 for 8 bit relocations.

gas/ChangeLog:
Andrew Burgess <***@embecosm.com>
* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.

include/ChangeLog:
Cupertino Miranda <***@synopsys.com>
Andrew Burgess <***@embecosm.com>

* elf/arc-reloc.def: Add a call to ME within the formula for each
relocation that requires middle-endian correction.
Post by Cupertino Miranda
-----Original Message-----
Sent: Friday, January 08, 2016 11:31 AM
To: Andrew Burgess; Cupertino Miranda
Subject: RE: [PATCH] bfd/arc: Allow non-instruction relocations within .text sections
Hi Andrew,
Post by Andrew Burgess
Post by Cupertino Miranda
The first statement from Claudiu doesn't apply, because the
instruction is what suffers the ME conversion, so all short
instructions must suffer through ME decoding/encoding.. The reality
is that being ME or not is not a property of the relocation but of
the memory region, or better, the type of usage given to the
particular address, being patched.
I agree, though I believe that the way that this memory-region / use
relationship is captured is with difference relocation types. So I
think that something along the lines of either of the two patches I
have now posted is the way to go.
Post by Cupertino Miranda
Moreover, now looking back to
it, I think we should not try to move this information (not from
but) to the relocation, but to understand which cases we should be
careful and pay special attention to perform or not to perform
middle endianess conversion.
I agree. That is what I've done in both of the patches I've posted right?
No, I made a correction to the sentence and made it confusing.
" I think we should not try to move this information to the relocation, but to
understand which cases we should be careful and pay special attention to
perform or not the middle endianess conversion."
This middle endianess for the tools can be a property of whatever we want,
however for the architecture, it is clearly a property of what is going to use
the data being patched/relocated. More precisely, who is reading/writing the
data (the instruction decoder, or an instruction being executed).
- If it is the instruction decoder, then the data should always be recovered
and rewritten with middle endian format conversion.
- If it is an instruction (an ld for example), then independently of the type of
section the relocation should happen, we should write it in non middle
endian format.
- This happens to be the case only in ARC_32 like I specified in the previous email.
Post by Andrew Burgess
The middle-endian conversion is moved out of the get/put methods, and
into relocation specific code.
So far I think that we're in complete agreement.
Post by Cupertino Miranda
In our current development code (my local fix), I keep the ME
conversion in bfd_get_32 and bfd_put_32, but I perform a unME
conversion before applying the relocation, if that is a requirement
for the relocation type.
I don't think that's a good idea. Given that this get/put is only
used in the one location, that feels like we're just working around a
get/put that's doing the wrong thing. This also feels like it goes
against what you said above; the conversion should be attached to the
relocation, not to generic code.
I tried to say the opposite. :-)
Post by Andrew Burgess
Post by Cupertino Miranda
Up until now we only identified a single
relocation type where ME should not be applied in a SEC_CODE
OK, I admit that marking up those relocation where ME _should_ be
applied will result in more being marked than if we simply mark those
to which is does not apply. But I think that's easier to understand,
so that doesn't seem like much of a negative to me.
Post by Cupertino Miranda
I would say that we should spend some more time to define how this
middle endian conversion should be done.
Well, I've put forward two patches now, the first (which I prefer),
https://sourceware.org/ml/binutils/2016-01/msg00021.html
So, I'm confused what more there is to discuss. Though I prefer the
first patch, I'll take the second version if it's what you prefer.
Post by Cupertino Miranda
Moreover, I won't be able
to give the confidence that your patch would not create some
problems, as the current upstreamed code is limited to baremetal
applications, not allowing me to fully test all the relocation types involved.
Given how small this patch is, merging into your local world and
testing should be pretty straight forward I'd have though.
Post by Cupertino Miranda
Furthermore, it would make more sense to fix this issue
right after we apply the upcoming feature intensive patch,
supporting Linux and making use of all the relocation types.
Do you have a date for when the second patch will arrive? This is a
blocking issue for me, and I'd like to see a solution merged sooner rather
than later.
We will send the patch with PIC and TLS support by Monday/Tuesday.
Post by Andrew Burgess
As a counter proposal, given how small that patch is, why don't we
merge the second version of this patch, which sounds like the closest
to whatever you're proposing, then when your next big patch arrives
you can rewrite this code as fits your design.
Although it is a small patch, it makes a fundamental changes to how the
relocations are performed.
To be honest, at the moment I cannot test your changes and validate if they
are all correct up until I send my patches (Monday/Tuesday).
Also, I would like to validate them with the PIC and TLS support as well, as the
current version (baremetal only) does not makes use of many of the
changed relocations in your patch.
Post by Andrew Burgess
What do you think?
After some further discussions locally, both me and Claudiu agree with the
strategy to move ME to the relocations, however up until further testing we
are not fully certain all of the changes are correct.
Nevertheless, we accept the patch. :-)
Kind regards,
Cupertino
Post by Andrew Burgess
Thanks,
Andrew
Post by Cupertino Miranda
-----Original Message-----
Sent: Thursday, January 07, 2016 4:15 PM
To: Andrew Burgess; Cupertino Miranda
Subject: RE: [PATCH] bfd/arc: Allow non-instruction relocations
within .text sections
Hi guys,
1. It seems to me adding ME modifier for relocations that are
handling short immediate values is superfluous, as the final values
are written taken into account the entire instruction, and the
big-endian/little- endian flags. Hence, if it is a long instruction
always we write it in the form dictated by the endianess (ME for
little-endian), if it is short then ME switch is not needed at all.
However, if you say that this is ok, then it is fine for me as well.
Post by Cupertino Miranda
2. The relocations which are handled by dynamic linker are marked
also ME (e.g., JMP_SLOT), is it required?
Post by Cupertino Miranda
Best,
Claudiu
Post by Cupertino Miranda
-----Original Message-----
Sent: Thursday, January 07, 2016 3:44 PM
To: Cupertino Miranda
Subject: Re: [PATCH] bfd/arc: Allow non-instruction relocations
within .text sections
Post by Cupertino Miranda
Hi Andrew,
We are currently finishing cleaning up a patch to integrate
support for Linux
(PIC and TLS).
Post by Cupertino Miranda
I am glad to say that we have realized this mistake and would intend to
address it soon after the upcoming patch.
Post by Cupertino Miranda
Nevertheless, your implementation does it a little different from how we
would like to address it.
Post by Cupertino Miranda
More precisely we do not define a new field in the RELOC_HOWTO but
implement it through the FORMULA field using the ME preprocessor
macro.
Post by Cupertino Miranda
Post by Cupertino Miranda
Post by Cupertino Miranda
ARC_RELOC_HOWTO(ARC_PC32, 50, \
2, \
32, \
replace_word32, \
signed, \
( ME ( ( S + A ) - P ) ))
#define ME(RELOC) (RELOC)
And the remaining part does pretty much the same as your code, but
resorting to the FORMULA to check if ME is present.
Post by Cupertino Miranda
static bfd_vma
middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
if (do_it)
{
insn =
((insn & 0xffff0000) >> 16) |
((insn & 0xffff) << 16);
}
return insn;
}
#define IS_ME(FORMULA) (strstr(#FORMULA, "ME") != NULL)
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE,
RELOC_FUNCTION, OVERFLOW, FORMULA) \
Post by Cupertino Miranda
case R_##TYPE: \
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
relocation = FORMULA ; \
insn = middle_endian_convert (insn, IS_ME(FORMULA)); \
} \
break;
Our view is to keep relocation definitions to be limited to this
FORMULA concept, instead of adding new fields to the relocation
table.
Post by Andrew Burgess
Post by Cupertino Miranda
Post by Cupertino Miranda
The patch below is a rewrite inline with the description above.
The only change is that I have extended the IS_ME macro to
consider whether the bfd is big or little endian, and I believe
that this makes a difference as to whether the byte shuffling is
required.
Post by Andrew Burgess
Post by Cupertino Miranda
Post by Cupertino Miranda
Is this good with you?
Does my list of formula modifications match the list of changes
you have? I built my list based on how relocations were handled
before the big rewrite, but that doesn't mean it's correct, just
that I've not seen any test regressions either in binutils or GCC.
Thanks,
Andrew
---
On a little endian arc, a 4-byte instruction ABCD, where A is the
most significant byte, and D is the least significant byte would
be stored in memory (low to high) as BADC. That is, each 2-byte
chunk is stored in little endian order in memory.
Currently, when a relocation is applied to such a 4-byte
instruction, we make use of arc_bfd_get_32 and arc_bfd_put_32,
which perform byte manipulation to correct for this in memory byte
ordering.
Post by Andrew Burgess
Post by Cupertino Miranda
Post by Cupertino Miranda
This byte ordering correction is applied to all relocations within
executable sections (for little endian arc) when really the
correction should only be applied to instruction relocations; it
is the instruction fetch mechanism that loads 4-byte instructions
2-bytes at
a time.
Post by Cupertino Miranda
Post by Cupertino Miranda
It is possible to place data into an executable section, for
example it might be more efficient to place small jump tables
inline within the code rather than placing them into a data section.
The problem then, is that these two aspects, the byte order
correction, and inline data, conflict. Placing a 4-byte label
relocation inline in the code results in the byte-order correction
being applied to it, which, when the label is loaded using a standard arc
load instruction, returns a corrupted address.
Post by Cupertino Miranda
Post by Cupertino Miranda
Before the recent arc rewrite, placing data inline into the
executable sections did work. This was thanks to using a
different code path to patch instruction related relocations, to
the code that patched data related relocations. The instruction
related relocations therefore received the byte order correction,
while the data
related relocations didn't.
Post by Cupertino Miranda
Post by Cupertino Miranda
After the recent rewrite this feature was lost, though I believe
this was by accident, rather than design. This commit brings this
feature back, though the implementation is different, in order to fit with
the new arc design.
Post by Cupertino Miranda
Post by Cupertino Miranda
The formula field, in those relocations that should have the byte
ordering fix applied, is extended to include a call to a new macro
ME, this macro is then used within the bfd library to trigger the
application of the byte ordering fix when appropriate. This design is
https://sourceware.org/ml/binutils/2016-01/msg00021.html
* elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
(arc_bfd_put_32): Becomes an alias for bfd_put_32.
(get_middle_endian_relocation): Delete.
(middle_endian_convert): New function.
(ME): Redefine, now does nothing.
(IS_ME): New define.
(arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
definition to call middle_endian_convert. Add a new local
variable and make use of this throughout.
* elf/arc-reloc.def: Add a call to ME within the formula for each
relocation that requires middle-endian correction.
* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
---
bfd/ChangeLog | 13 ++++++++
bfd/elf32-arc.c | 59 ++++++++++++++---------------------
gas/ChangeLog | 5 +++
gas/testsuite/gas/arc/inline-data-1.d | 7 +++++
gas/testsuite/gas/arc/inline-data-1.s | 4 +++
include/ChangeLog | 6 ++++
include/elf/arc-reloc.def | 54 ++++++++++++++++----------------
7 files changed, 85 insertions(+), 63 deletions(-) create mode
100644 gas/testsuite/gas/arc/inline-data-1.d
create mode 100644 gas/testsuite/gas/arc/inline-data-1.s
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 063cd14..1f92602 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+
+ * elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32.
+ (arc_bfd_put_32): Becomes an alias for bfd_put_32.
+ (get_middle_endian_relocation): Delete.
+ (middle_endian_convert): New function.
+ (ME): Redefine, now does nothing.
+ (IS_ME): New define.
+ (arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO'
+ definition to call middle_endian_convert. Add a new local
+ variable and make use of this throughout.
+
Update year range in copyright notice of all files.
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index
e9e299c..bf505fc
100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -140,32 +140,10 @@ is_reloc_for_PLT (reloc_howto_type *
howto)
Post by Andrew Burgess
Post by Cupertino Miranda
Post by Cupertino Miranda
#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B) #define
arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C) #define
arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
-
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section) -{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section) -{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
static bfd_reloc_status_type
@@
Post by Andrew Burgess
Post by Cupertino Miranda
Post by Cupertino Miranda
debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}
-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc)
+static bfd_vma
+middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
- bfd_vma ret =
- ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
+ if (do_it)
+ {
+ insn =
+ ((insn & 0xffff0000) >> 16) |
+ ((insn & 0xffff) << 16);
+ }
+ return insn;
}
-#define ME(RELOC) (get_middle_endian_reloction(RELOC))
+#define ME(reloc) (reloc)
+
+#define IS_ME(FORMULA,BFD) ((strstr(#FORMULA, "ME") != NULL)
&&
Post by Andrew Burgess
\
Post by Cupertino Miranda
Post by Cupertino Miranda
+ !bfd_big_endian (BFD))
#define S (reloc_data.sym_value \
get_middle_endian_relocation (bfd_vma reloc)
{ \
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
relocation = FORMULA ; \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd));
+ \
insn = RELOC_FUNCTION (insn, relocation); \
+ insn = middle_endian_convert (insn, IS_ME (FORMULA, abfd));
+ \
} \
break;
@@ -528,6 +514,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
bfd_vma relocation = 0;
bfd_vma insn;
bfd_vma orig_insn ATTRIBUTE_UNUSED;
+ bfd * abfd = reloc_data.input_section->owner;
if (reloc_data.should_relocate == FALSE)
arc_do_relocation (bfd_byte * contents, struct arc_relocation_data
reloc_data)
switch (reloc_data.howto->size)
{
- insn = arc_bfd_get_32 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_32 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- insn = arc_bfd_get_16 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_16 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
@@ -569,7 +556,7 @@ arc_do_relocation (bfd_byte * contents, struct
arc_relocation_data reloc_data)
flag = bfd_check_overflow (reloc_data.howto-
complain_on_overflow,
Post by Cupertino Miranda
reloc_data.howto->bitsize,
reloc_data.howto->rightshift,
- bfd_arch_bits_per_address
(reloc_data.input_section->owner),
+ bfd_arch_bits_per_address (abfd),
relocation);
#undef DEBUG_ARC_RELOC
@@ -594,13 +581,13 @@ arc_do_relocation (bfd_byte * contents,
struct arc_relocation_data reloc_data)
switch (reloc_data.howto->size)
{
- arc_bfd_put_32 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_32 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
- arc_bfd_put_16 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_16 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
diff --git a/gas/ChangeLog b/gas/ChangeLog index 64eeded..400f67a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+
+ * testsuite/gas/arc/inline-data-1.d: New file.
+ * testsuite/gas/arc/inline-data-1.s: New file.
+
Update year range in copyright notice of all files.
diff --git a/gas/testsuite/gas/arc/inline-data-1.d
b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s
b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/ChangeLog b/include/ChangeLog index
70e19b7..9f2a5d6
100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+
+ * elf/arc-reloc.def: Add a call to ME within the formula for each
+ relocation that requires middle-endian correction.
+
Update year range in copyright notice of all files.
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def index
893291f..cb43a21 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -80,56 +80,56 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
20, \
replace_disp21h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( S + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
2, \
23, \
replace_disp25w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( S + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA32, 18, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
1, \
@@ -171,42 +171,42 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
32, \
replace_limm, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
2, \
32, \
replace_limms, \
signed, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S - A ))
+ ( ME ( S - A )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( S - SECTSTART ) + A ))
+ ( ME ( ( S - SECTSTART ) + A )))
ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
2, \
32, \
replace_limm, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( S + A ) - _SDA_BASE_ )))
ARC_RELOC_HOWTO(ARC_W_ME, 31, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S + A ))
+ ( ME ( S + A )))
ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
2, \
@@ -255,14 +255,14 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1,
41,
Post by Andrew Burgess
\
Post by Cupertino Miranda
Post by Cupertino Miranda
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 1 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 1 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 2 ))
+ ( ME ( ( ( S - SECTSTART ) + A ) >> 2 )))
ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
2, \
@@ -297,7 +297,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - P ))
+ ( ME ( ( S + A ) - P )))
ARC_RELOC_HOWTO(ARC_GOT32, 59, \
2, \
@@ -311,14 +311,14 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
32, \
replace_word32, \
signed, \
- ( ( ( GOT + G ) + A ) - P ))
+ ( ME ( ( ( GOT + G ) + A ) - P )))
ARC_RELOC_HOWTO(ARC_PLT32, 52, \
2, \
32, \
replace_word32, \
signed, \
- ( ( L + A ) - P ))
+ ( ME ( ( L + A ) - P )))
ARC_RELOC_HOWTO(ARC_COPY, 53, \
2, \
@@ -339,42 +339,42 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
32, \
replace_word32, \
signed, \
- S)
+ ( ME ( S )))
ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
2, \
32, \
replace_word32, \
signed, \
- ( B + A ))
+ ( ME ( B + A )))
ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - GOT ))
+ ( ME ( ( S + A ) - GOT )))
ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
2, \
32, \
replace_word32, \
signed, \
- ( ( GOT + A ) - P ))
+ ( ME ( ( GOT + A ) - P )))
ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
2, \
@@ -451,12 +451,12 @@ ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT,
76, \
Post by Cupertino Miranda
Post by Cupertino Miranda
23, \
replace_disp25w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( L + A ) - P ) >> 2 )))
ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
2, \
20, \
replace_disp21h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( L + A ) - P ) >> 1 )))
--
2.6.4
Andrew Burgess
2016-02-25 11:29:52 UTC
Permalink
Post by Cupertino Miranda
I have tested and fixed this patch. The attached one should now work for all of the ARC variant emulations/targets.
I have also included a fix for all 8 bit relocs which were wrong for big endian format.
Andrew: Do you have any comments on the patch as it is?
As far as the approach taken, then Synopsys are driving the ARC
design, personally, I think you're trying to hard to use the formula,
but, so long as the test now passes, I'm happy :-)

There's a few minor formatting issues inline. I'm not a maintainer
though, so you'll need the final OK from someone else.

Thanks,
Andrew
Post by Cupertino Miranda
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
index ab2512d..a926b80 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -252,32 +252,11 @@ is_reloc_for_TLS (reloc_howto_type *howto)
#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
#define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
+#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
#define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
+#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
-static long
-arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section) -{
- long insn = bfd_get_32 (abfd, loc);
-
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- return insn;
-}
-
-static void
-arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section) -{
- if (!bfd_big_endian (abfd)
- && input_section
- && (input_section->flags & SEC_CODE))
- insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
-
- bfd_put_32 (abfd, insn, loc);
-}
static bfd_reloc_status_type
arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
@@ -344,9 +323,14 @@ static void arc_elf_howto_init (void)
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
elf_arc_howto_table[TYPE].pc_relative = \
(strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
- elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0);
+ elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
Missing space after RELOC_FUNCTION.
Post by Cupertino Miranda
+ /* Only 32 bit data relocations should be marked as ME. */ \
+ if (strstr (#FORMULA, " ME ") != NULL) { \
+ BFD_ASSERT (SIZE == 2); \
+ }
#include "elf/arc-reloc.def"
+
}
#undef ARC_RELOC_HOWTO
@@ -771,14 +755,23 @@ debug_arc_reloc (struct arc_relocation_data reloc_data)
}
}
-static ATTRIBUTE_UNUSED bfd_vma
-get_middle_endian_relocation (bfd_vma reloc)
+static bfd_vma
+middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
{
- bfd_vma ret = ((reloc & 0xffff0000) >> 16) |
- ((reloc & 0xffff) << 16);
- return ret;
+ if (do_it)
+ {
+ insn =
+ ((insn & 0xffff0000) >> 16) |
+ ((insn & 0xffff) << 16);
+ }
I think GNU coding standard is not to use braces around single
expressions.
Post by Cupertino Miranda
+ return insn;
}
+#define ME(reloc) (reloc)
+
+#define IS_ME(FORMULA,BFD) ((strstr(FORMULA, "ME") != NULL) && \
+ (!bfd_big_endian (BFD)))
+
Missing space after 'strstr'/
Post by Cupertino Miranda
#define S (reloc_data.sym_value \
+ (reloc_data.sym_section->output_section != NULL ? \
(reloc_data.sym_section->output_offset \
@@ -818,8 +811,6 @@ get_middle_endian_relocation (bfd_vma reloc)
#define TLS_TBSS (8)
#define TCB_SIZE (8)
-#define NON_ME(VALUE) (reverse_me (reloc_data, VALUE))
-
#define none (0)
#define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
@@ -870,20 +861,13 @@ get_middle_endian_relocation (bfd_vma reloc)
bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
relocation = FORMULA ; \
PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
+ insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
insn = RELOC_FUNCTION (insn, relocation); \
+ insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
PRINT_DEBUG_RELOC_INFO_AFTER \
} \
break;
-static bfd_vma
-reverse_me (struct arc_relocation_data reloc_data, bfd_vma reloc)
-{
- if (reloc_data.input_section && reloc_data.input_section->flags & SEC_CODE)
- return ((0x0000fffff & reloc) << 16) | ((0xffff0000 & reloc) >> 16);
- else
- return reloc;
-}
-
static bfd_reloc_status_type
arc_do_relocation (bfd_byte * contents,
struct arc_relocation_data reloc_data,
@@ -892,6 +876,7 @@ arc_do_relocation (bfd_byte * contents,
bfd_vma relocation = 0;
bfd_vma insn;
bfd_vma orig_insn ATTRIBUTE_UNUSED;
+ bfd * abfd = reloc_data.input_section->owner;
struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
if (reloc_data.should_relocate == FALSE)
@@ -900,13 +885,17 @@ arc_do_relocation (bfd_byte * contents,
switch (reloc_data.howto->size)
{
- insn = arc_bfd_get_32 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_32 (abfd,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
+ insn = arc_bfd_get_16 (abfd,
+ contents + reloc_data.reloc_offset,
+ reloc_data.input_section);
+ break;
- insn = arc_bfd_get_16 (reloc_data.input_section->owner,
+ insn = arc_bfd_get_8 (abfd,
You should probably re-indent the following lines here.
Post by Cupertino Miranda
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
@@ -934,7 +923,7 @@ arc_do_relocation (bfd_byte * contents,
flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
reloc_data.howto->bitsize,
reloc_data.howto->rightshift,
- bfd_arch_bits_per_address (reloc_data.input_section->owner),
+ bfd_arch_bits_per_address (abfd),
relocation);
#undef DEBUG_ARC_RELOC
@@ -960,13 +949,17 @@ arc_do_relocation (bfd_byte * contents,
switch (reloc_data.howto->size)
{
- arc_bfd_put_32 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_32 (abfd, insn,
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
+ arc_bfd_put_16 (abfd, insn,
+ contents + reloc_data.reloc_offset,
+ reloc_data.input_section);
+ break;
- arc_bfd_put_16 (reloc_data.input_section->owner, insn,
+ arc_bfd_put_8 (abfd, insn,
You should probably re-indent the following lines here.
Post by Cupertino Miranda
contents + reloc_data.reloc_offset,
reloc_data.input_section);
break;
diff --git a/gas/testsuite/gas/arc/inline-data-1.d b/gas/testsuite/gas/arc/inline-data-1.d
new file mode 100644
index 0000000..ce5c272
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.d
@@ -0,0 +1,7 @@
+#as: -mcpu=arc700
+#objdump: -sj .text
+
+.*: +file format .*arc.*
+
+ [0-9a-f]+ ddccbbaa ffee .*
diff --git a/gas/testsuite/gas/arc/inline-data-1.s b/gas/testsuite/gas/arc/inline-data-1.s
new file mode 100644
index 0000000..e63bf06
--- /dev/null
+++ b/gas/testsuite/gas/arc/inline-data-1.s
@@ -0,0 +1,4 @@
+ .text
+
+ .word 0xaabbccdd
+ .short 0xeeff
diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def
index 96123de..36a3516 100644
--- a/include/elf/arc-reloc.def
+++ b/include/elf/arc-reloc.def
@@ -1,3 +1,34 @@
+/* ARC relocation types
+ Copyright (C) 2015-2016 Free Software Foundation, Inc.
Should this year not be just 2016?
Post by Cupertino Miranda
+
+ 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.
+
+ GAS/GDB 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, or (at your option)
+ any later version.
+
+ GAS/GDB 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 GAS or GDB; see the file COPYING3. If not, write to
+ the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
ARC_RELOC_HOWTO(ARC_NONE, 0, \
2, \
32, \
@@ -31,7 +62,7 @@ ARC_RELOC_HOWTO(ARC_32, 4, \
32, \
replace_word32, \
bitfield, \
- (NON_ME ( S + A ) ))
+ ( S + A ))
ARC_RELOC_HOWTO(ARC_N8, 8, \
0, \
@@ -80,84 +111,84 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \
20, \
replace_disp21h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( ( S + A ) - P ) >> 1 ) ) ))
ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( ( S + A ) - P ) >> 2 ) ) ))
ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( S + A ) - P ) >> 1 ))
+ ( ME ( ( ( ( S + A ) - P ) >> 1 ) ) ))
ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \
2, \
23, \
replace_disp25w, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ME ( ( ( ( S + A ) - P ) >> 2 ) ) ))
ARC_RELOC_HOWTO(ARC_SDA32, 18, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) ) ))
ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) ) ))
ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))
+ ( ME ( ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ) ) ))
ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \
2, \
9, \
replace_disp9ls, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
+ ( ME ( ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ) ) ))
ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \
1, \
9, \
replace_disp9s, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ( ( S + A ) - _SDA_BASE_ ) ))
ARC_RELOC_HOWTO(ARC_SDA16_LD1, 23, \
1, \
9, \
replace_disp9s, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ))
+ ( ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ) ))
ARC_RELOC_HOWTO(ARC_SDA16_LD2, 24, \
1, \
9, \
replace_disp9s, \
signed, \
- ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
+ ( ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ) ))
ARC_RELOC_HOWTO(ARC_S13_PCREL, 25, \
1, \
11, \
replace_disp13s, \
signed, \
- ( ( ( S + A ) - P ) >> 2 ))
+ ( ( ( ( S + A ) - P ) >> 2 ) ))
ARC_RELOC_HOWTO(ARC_W, 26, \
2, \
@@ -171,42 +202,42 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \
32, \
replace_limm, \
signed, \
- ( S + A ))
+ ( ME ( ( S + A ) ) ))
ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \
2, \
32, \
replace_limms, \
signed, \
- ( S + A ))
+ ( ME ( ( S + A ) ) ))
ARC_RELOC_HOWTO(ARC_N32_ME, 28, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S - A ))
+ ( ME ( ( S - A ) ) ))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( S - SECTSTART ) + A ))
+ ( ME ( ( ( S - SECTSTART ) + A ) ) ))
ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \
2, \
32, \
replace_limm, \
signed, \
- ( ( S + A ) - _SDA_BASE_ ))
+ ( ME ( ( ( S + A ) - _SDA_BASE_ ) ) ))
ARC_RELOC_HOWTO(ARC_W_ME, 31, \
2, \
32, \
replace_word32, \
bitfield, \
- ( S + A ))
+ ( ME ( ( ( S + A ) & ( ~3 ) ) ) ))
ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \
2, \
@@ -255,14 +286,14 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 1 ))
+ ( ME ( ( ( ( S - SECTSTART ) + A ) >> 1 ) ) ))
ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \
2, \
32, \
replace_word32, \
bitfield, \
- ( ( ( S - SECTSTART ) + A ) >> 2 ))
+ ( ME ( ( ( ( S - SECTSTART ) + A ) >> 2 ) ) ))
ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \
2, \
@@ -297,7 +328,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - P ))
+ ( ME ( ( ( S + A ) - P ) ) ))
ARC_RELOC_HOWTO(ARC_GOT32, 59, \
2, \
@@ -311,14 +342,14 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \
32, \
replace_word32, \
signed, \
- ( ( ( GOT + G ) + A ) - P ))
+ ( ME ( ( ( ( GOT + G ) + A ) - P ) ) ))
ARC_RELOC_HOWTO(ARC_PLT32, 52, \
2, \
32, \
replace_word32, \
signed, \
- ( ( L + A ) - P ))
+ ( ME ( ( ( L + A ) - P ) ) ))
ARC_RELOC_HOWTO(ARC_COPY, 53, \
2, \
@@ -339,42 +370,42 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \
32, \
replace_word32, \
signed, \
- S)
+ ( ME ( S ) ))
ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \
2, \
32, \
replace_word32, \
signed, \
- ( B + A ))
+ ( ME ( ( B + A ) ) ))
ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \
2, \
32, \
replace_word32, \
signed, \
- ( ( S + A ) - GOT ))
+ ( ME ( ( ( S + A ) - GOT ) ) ))
ARC_RELOC_HOWTO(ARC_GOTPC, 58, \
2, \
32, \
replace_word32, \
signed, \
- ( GOT_BEGIN - P ))
+ ( ME ( ( GOT_BEGIN - P ) ) ))
ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \
2, \
19, \
replace_disp21w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( ( L + A ) - P ) >> 2 ) ) ))
ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \
2, \
24, \
replace_disp25h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
+ ( ME ( ( ( ( L + A ) - P ) >> 1 ) ) ))
ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
2, \
@@ -395,7 +426,7 @@ ARC_RELOC_HOWTO(ARC_TLS_GD_GOT, 69, \
32, \
replace_word32, \
dont, \
- ( G + GOT - P))
+ ( ME ( ( ( G + GOT ) - P ) ) ))
ARC_RELOC_HOWTO(ARC_TLS_GD_LD, 70, \
2, \
@@ -416,47 +447,46 @@ ARC_RELOC_HOWTO(ARC_TLS_IE_GOT, 72, \
32, \
replace_word32, \
dont, \
- ( G + GOT - P))
+ ( ME ( ( ( G + GOT ) - P ) ) ))
ARC_RELOC_HOWTO(ARC_TLS_DTPOFF, 67, \
2, \
32, \
replace_word32, \
dont, \
- ( S - TLS_REL ))
+ ( ME ( ( S - TLS_REL ) ) ))
ARC_RELOC_HOWTO(ARC_TLS_DTPOFF_S9, 73, \
2, \
32, \
replace_word32, \
dont, \
- ( S - TLS_REL ))
+ ( ME ( ( S - TLS_REL ) ) ))
ARC_RELOC_HOWTO(ARC_TLS_LE_S9, 74, \
2, \
32, \
replace_word32, \
dont, \
- ( ( S + TCB_SIZE ) - TLS_REL ))
+ ( ME ( ( ( S + TCB_SIZE ) - TLS_REL ) ) ))
ARC_RELOC_HOWTO(ARC_TLS_LE_32, 75, \
2, \
32, \
replace_word32, \
dont, \
- ( ( S + A + TCB_SIZE ) - TLS_REL ))
+ ( ME ( ( ( ( S + A ) + TCB_SIZE ) - TLS_REL ) ) ))
ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \
2, \
23, \
replace_disp25w, \
signed, \
- ( ( ( L + A ) - P ) >> 2 ))
+ ( ME ( ( ( ( L + A ) - P ) >> 2 ) ) ))
ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
2, \
20, \
replace_disp21h, \
signed, \
- ( ( ( L + A ) - P ) >> 1 ))
-
+ ( ME ( ( ( ( L + A ) - P ) >> 1 ) ) ))
diff --git a/include/opcode/arc-func.h b/include/opcode/arc-func.h
index 96ffcff..47451a6 100644
--- a/include/opcode/arc-func.h
+++ b/include/opcode/arc-func.h
@@ -66,8 +66,8 @@ replace_bits16 (unsigned insn, int value ATTRIBUTE_UNUSED)
ATTRIBUTE_UNUSED static unsigned
replace_bits24 (unsigned insn, int value ATTRIBUTE_UNUSED)
{
- insn = insn & ~0xffffff;
- insn |= ((value >> 0) & 0xffffff) << 0;
+ insn = insn & ~0xffffff00;
+ insn |= ((value >> 0) & 0xffffff) << 8;
return insn;
}
Loading...