From 2500aa69b35b0817cc2fe989473e5fbee5524514 Mon Sep 17 00:00:00 2001 From: Nathan Rossi Date: Mon, 8 Jul 2013 17:42:52 +1000 Subject: binutils: Added MicroBlaze specific patches * Patches are backported from upstream binutils Signed-off-by: Nathan Rossi --- .../binutils-cross-canadian_2.23.2.bbappend | 1 + .../binutils/binutils-cross_2.23.2.bbappend | 1 + .../binutils/binutils-crosssdk_2.23.2.bbappend | 1 + .../binutils/binutils-microblaze-2.23.2.inc | 18 + recipes-devtools/binutils/binutils_2.23.2.bbappend | 1 + ...-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch | 243 ++++ ...-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch | 30 + ...-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch | 632 +++++++++ ...-58deb49b33812b048a1061553c1ca6f010af59f4.patch | 63 + ...-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch | 89 ++ ...-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch | 143 ++ ...-e2be436cc342d130ac0ba6b4a31724d71e473684.patch | 76 ++ ...-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch | 207 +++ ...-b66f7d905a679685476fbfbc793541adb8829a6c.patch | 149 +++ ...-7de425548753461fd2768017d3be677ba2b2a583.patch | 83 ++ ...-77625f8c77d14a67bc542bb790e6f826c725de4c.patch | 89 ++ ...-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch | 1371 ++++++++++++++++++++ ...-19e05575d97b6dc83dae1b8309624da3102d7a74.patch | 310 +++++ 18 files changed, 3507 insertions(+) create mode 100644 recipes-devtools/binutils/binutils-cross-canadian_2.23.2.bbappend create mode 100644 recipes-devtools/binutils/binutils-cross_2.23.2.bbappend create mode 100644 recipes-devtools/binutils/binutils-crosssdk_2.23.2.bbappend create mode 100644 recipes-devtools/binutils/binutils-microblaze-2.23.2.inc create mode 100644 recipes-devtools/binutils/binutils_2.23.2.bbappend create mode 100644 recipes-devtools/binutils/files/0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch create mode 100644 recipes-devtools/binutils/files/0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch create mode 100644 recipes-devtools/binutils/files/0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch create mode 100644 recipes-devtools/binutils/files/0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch create mode 100644 recipes-devtools/binutils/files/0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch create mode 100644 recipes-devtools/binutils/files/0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch create mode 100644 recipes-devtools/binutils/files/0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch create mode 100644 recipes-devtools/binutils/files/0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch create mode 100644 recipes-devtools/binutils/files/0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch create mode 100644 recipes-devtools/binutils/files/0010-7de425548753461fd2768017d3be677ba2b2a583.patch create mode 100644 recipes-devtools/binutils/files/0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch create mode 100644 recipes-devtools/binutils/files/0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch create mode 100644 recipes-devtools/binutils/files/0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch diff --git a/recipes-devtools/binutils/binutils-cross-canadian_2.23.2.bbappend b/recipes-devtools/binutils/binutils-cross-canadian_2.23.2.bbappend new file mode 100644 index 00000000..e42e7a60 --- /dev/null +++ b/recipes-devtools/binutils/binutils-cross-canadian_2.23.2.bbappend @@ -0,0 +1 @@ +require binutils-microblaze-${PV}.inc diff --git a/recipes-devtools/binutils/binutils-cross_2.23.2.bbappend b/recipes-devtools/binutils/binutils-cross_2.23.2.bbappend new file mode 100644 index 00000000..e42e7a60 --- /dev/null +++ b/recipes-devtools/binutils/binutils-cross_2.23.2.bbappend @@ -0,0 +1 @@ +require binutils-microblaze-${PV}.inc diff --git a/recipes-devtools/binutils/binutils-crosssdk_2.23.2.bbappend b/recipes-devtools/binutils/binutils-crosssdk_2.23.2.bbappend new file mode 100644 index 00000000..e42e7a60 --- /dev/null +++ b/recipes-devtools/binutils/binutils-crosssdk_2.23.2.bbappend @@ -0,0 +1 @@ +require binutils-microblaze-${PV}.inc diff --git a/recipes-devtools/binutils/binutils-microblaze-2.23.2.inc b/recipes-devtools/binutils/binutils-microblaze-2.23.2.inc new file mode 100644 index 00000000..71112efb --- /dev/null +++ b/recipes-devtools/binutils/binutils-microblaze-2.23.2.inc @@ -0,0 +1,18 @@ + +# Add MicroBlaze Patches +FILESEXTRAPATHS_append := "${THISDIR}/files:" +SRC_URI_append += " \ + file://0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch \ + file://0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch \ + file://0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch \ + file://0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch \ + file://0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch \ + file://0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch \ + file://0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch \ + file://0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch \ + file://0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch \ + file://0010-7de425548753461fd2768017d3be677ba2b2a583.patch \ + file://0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch \ + file://0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch \ + file://0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch \ + " diff --git a/recipes-devtools/binutils/binutils_2.23.2.bbappend b/recipes-devtools/binutils/binutils_2.23.2.bbappend new file mode 100644 index 00000000..e42e7a60 --- /dev/null +++ b/recipes-devtools/binutils/binutils_2.23.2.bbappend @@ -0,0 +1 @@ +require binutils-microblaze-${PV}.inc diff --git a/recipes-devtools/binutils/files/0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch b/recipes-devtools/binutils/files/0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch new file mode 100644 index 00000000..4f0993eb --- /dev/null +++ b/recipes-devtools/binutils/files/0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch @@ -0,0 +1,243 @@ +From 9f0cfcdd4c342cc2a97bb4591c5542507f073435 Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Wed, 31 Oct 2012 15:27:35 +0000 +Subject: 2012-10-31 David Holsgrove + + * config/tc-microblaze.c: Check for weak symbols before + emitting relocation. + +2012-10-31 David Holsgrove + + * gas/microblaze: New. + * gas/microblaze/reloc_sym.exp: Add test case. + * gas/microblaze/reloc_strongsym.s: Likewise. + * gas/microblaze/reloc_weaksym.s: Likewise. + * gas/microblaze/reloc_sym.d: Likewise. + +Upstream-Status: Backport + +diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c +index 3ab854f..86ac90b 100644 +--- a/gas/config/tc-microblaze.c ++++ b/gas/config/tc-microblaze.c +@@ -2065,7 +2065,8 @@ md_estimate_size_before_relax (fragS * fragP, + as_bad (_("Absolute PC-relative value in relaxation code. Assembler error.....")); + abort (); + } +- else if ((S_GET_SEGMENT (fragP->fr_symbol) == segment_type)) ++ else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type && ++ !S_IS_WEAK (fragP->fr_symbol)) + { + fragP->fr_subtype = DEFINED_PC_OFFSET; + /* Don't know now whether we need an imm instruction. */ +diff --git a/gas/testsuite/gas/microblaze/reloc_strongsym.s b/gas/testsuite/gas/microblaze/reloc_strongsym.s +new file mode 100644 +index 0000000..8f34028 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/reloc_strongsym.s +@@ -0,0 +1,20 @@ ++ .section ".testsection" ++ .align 2 ++ .globl test_start ++ .ent test_start ++ .type test_start, @function ++test_start: ++ .frame r19,8,r15 # vars= 0, regs= 1, args= 0 ++ .mask 0x00080000 ++ addik r1,r1,-8 ++ swi r19,r1,4 ++ addk r19,r1,r0 ++ addk r1,r19,r0 ++ lwi r19,r1,4 ++ addik r1,r1,8 ++ rtsd r15,8 ++ nop # Unfilled delay slot ++ ++ .end test_start ++$Lfe1: ++ .size test_start,$Lfe1-test_start +diff --git a/gas/testsuite/gas/microblaze/reloc_sym.d b/gas/testsuite/gas/microblaze/reloc_sym.d +new file mode 100644 +index 0000000..212d0bb +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/reloc_sym.d +@@ -0,0 +1,45 @@ ++ ++reloc_sym.x: file format elf32-microblaze ++ ++ ++Disassembly of section .text: ++ ++10000054 <__def_start>: ++10000054: 3021fff8 addik r1, r1, -8 ++10000058: fa610004 swi r19, r1, 4 ++1000005c: 12610000 addk r19, r1, r0 ++10000060: 10330000 addk r1, r19, r0 ++10000064: ea610004 lwi r19, r1, 4 ++10000068: 30210008 addik r1, r1, 8 ++1000006c: b60f0008 rtsd r15, 8 ++10000070: 80000000 or r0, r0, r0 ++ ++10000074
: ++10000074: 3021ffe0 addik r1, r1, -32 ++10000078: f9e10000 swi r15, r1, 0 ++1000007c: fa61001c swi r19, r1, 28 ++10000080: 12610000 addk r19, r1, r0 ++10000084: b000efff imm -4097 ++10000088: b9f4ff7c brlid r15, -132 // 4 ++1000008c: 80000000 or r0, r0, r0 ++10000090: b9f4ffc4 brlid r15, -60 // 10000054 <__def_start> ++10000094: 80000000 or r0, r0, r0 ++10000098: 10600000 addk r3, r0, r0 ++1000009c: e9e10000 lwi r15, r1, 0 ++100000a0: 10330000 addk r1, r19, r0 ++100000a4: ea61001c lwi r19, r1, 28 ++100000a8: 30210020 addik r1, r1, 32 ++100000ac: b60f0008 rtsd r15, 8 ++100000b0: 80000000 or r0, r0, r0 ++ ++Disassembly of section .testsection: ++ ++00000004 : ++ 4: 3021fff8 addik r1, r1, -8 ++ 8: fa610004 swi r19, r1, 4 ++ c: 12610000 addk r19, r1, r0 ++ 10: 10330000 addk r1, r19, r0 ++ 14: ea610004 lwi r19, r1, 4 ++ 18: 30210008 addik r1, r1, 8 ++ 1c: b60f0008 rtsd r15, 8 ++ 20: 80000000 or r0, r0, r0 +diff --git a/gas/testsuite/gas/microblaze/reloc_sym.exp b/gas/testsuite/gas/microblaze/reloc_sym.exp +new file mode 100644 +index 0000000..c7f7322 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/reloc_sym.exp +@@ -0,0 +1,27 @@ ++# Relocation test. ++ ++proc ld_test { objects ldflags dest test } { ++ set ld_output [target_link $objects $dest $ldflags] ++ if [string match "" $ld_output] then { pass $test } else { fail $test } ++} ++ ++proc objdump_test { exec flags dest test } { ++ set objcopy [find_binutils_prog objdump] ++ verbose -log "$objcopy $flags $exec > $dest" ++ catch "exec $objcopy $flags $exec > $dest" objdump_output ++ if [string match "" $objdump_output] then { pass $test } else { fail $test } ++} ++ ++proc regexp_test { file1 file2 test } { ++ if [regexp_diff $file1 $file2] then { fail $test } else { pass $test } ++} ++ ++ ++global srcdir subdir ++if [istarget microblaze*-*-*] { ++ gas_test "reloc_strongsym.s" {-o reloc_strongsym.o} {} {assembling reloc_strongsym} ++ gas_test "reloc_weaksym.s" {-o reloc_weaksym.o} {} {assembling reloc_weaksym} ++ ld_test {reloc_strongsym.o reloc_weaksym.o} {-e 0 -section-start .text=0x10000054 -section-start .testsection=0x4} {reloc_sym.x} {linking reloc_sym.x} ++ objdump_test {reloc_sym.x} {-d --section=.text --section=.testsection} {reloc_sym.dump} {disassembling reloc_sym.x} ++ regexp_test {reloc_sym.dump} "$srcdir/$subdir/reloc_sym.d" {matching disassembly} ++} +diff --git a/gas/testsuite/gas/microblaze/reloc_weaksym.s b/gas/testsuite/gas/microblaze/reloc_weaksym.s +new file mode 100644 +index 0000000..7dd9b98 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/reloc_weaksym.s +@@ -0,0 +1,52 @@ ++ .text ++ .align 2 ++ .globl __def_start ++ .ent __def_start ++ .type __def_start, @function ++__def_start: ++ .frame r19,8,r15 # vars= 0, regs= 1, args= 0 ++ .mask 0x00080000 ++ addik r1,r1,-8 ++ swi r19,r1,4 ++ addk r19,r1,r0 ++ addk r1,r19,r0 ++ lwi r19,r1,4 ++ addik r1,r1,8 ++ rtsd r15,8 ++ nop # Unfilled delay slot ++ ++ .end __def_start ++$Lfe1: ++ .size __def_start,$Lfe1-__def_start ++ .align 2 ++ .globl main ++ .ent main ++ .type main, @function ++main: ++ .frame r19,32,r15 # vars= 0, regs= 1, args= 24 ++ .mask 0x00088000 ++ addik r1,r1,-32 ++ swi r15,r1,0 ++ swi r19,r1,28 ++ addk r19,r1,r0 ++ brlid r15,test_start ++ nop # Unfilled delay slot ++ ++ brlid r15,test_start_strong ++ nop # Unfilled delay slot ++ ++ addk r3,r0,r0 ++ lwi r15,r1,0 ++ addk r1,r19,r0 ++ lwi r19,r1,28 ++ addik r1,r1,32 ++ rtsd r15,8 ++ nop # Unfilled delay slot ++ ++ .end main ++$Lfe2: ++ .size main,$Lfe2-main ++ .weakext test_start ++ test_start = __def_start ++ .globl test_start_strong ++ test_start_strong = __def_start +diff --git a/gas/testsuite/gas/microblaze/special_reg.d b/gas/testsuite/gas/microblaze/special_reg.d +new file mode 100644 +index 0000000..aad0131 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/special_reg.d +@@ -0,0 +1,14 @@ ++#as: ++#objdump: -ds ++ ++.*: file format .* ++ ++Contents of section .text: ++ 0000 9409d000 6c00d000 001ff800 ....l....... ++ ++Disassembly of section .text: ++ ++00000000 <.text>: ++ 0: 9409d000 mts rpid, r9 ++ 4: 6c00d000 tnput rfsl0 ++ 8: 001ff800 add r0, r31, r31 +diff --git a/gas/testsuite/gas/microblaze/special_reg.exp b/gas/testsuite/gas/microblaze/special_reg.exp +new file mode 100644 +index 0000000..4824f76 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/special_reg.exp +@@ -0,0 +1,5 @@ ++# MicroBlaze test for special register. ++ ++if [istarget microblaze*-*-*] { ++ run_dump_test "special_reg" ++} +diff --git a/gas/testsuite/gas/microblaze/special_reg.s b/gas/testsuite/gas/microblaze/special_reg.s +new file mode 100644 +index 0000000..d92ee4d +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/special_reg.s +@@ -0,0 +1,3 @@ ++ mts rpid, r9 ++ tnput rfsl0 ++ add r0, r31, r31 +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch b/recipes-devtools/binutils/files/0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch new file mode 100644 index 00000000..e8ee3673 --- /dev/null +++ b/recipes-devtools/binutils/files/0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch @@ -0,0 +1,30 @@ +From 297486a0aa2156f8a9a03ec95d43fe4ee0cb159a Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Wed, 7 Nov 2012 15:36:08 +0000 +Subject: 2012-11-07 David Holsgrove + + * config/tc-microblaze.c: Remove special register condition check + for INST_TYPE_RFSL related instructions. + +2012-11-07 David Holsgrove + + * testsuite/gas/microblaze/special_reg.exp: Add test case. + * testsuite/gas/microblaze/special_reg.s: Likewise. + * testsuite/gas/microblaze/special_reg.d: Likewise. + +Upstream-Status: Backport + +diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c +index 86ac90b..de0efda 100644 +--- a/gas/config/tc-microblaze.c ++++ b/gas/config/tc-microblaze.c +@@ -1198,9 +1198,6 @@ md_assemble (char * str) + as_fatal (_("Error in statement syntax")); + immed = 0; + } +- /* Check for spl registers. */ +- if (check_spl_reg (®1)) +- as_fatal (_("Cannot use special register with this instruction")); + inst |= (immed << IMM_LOW) & RFSL_MASK; + output = frag_more (isize); + break; diff --git a/recipes-devtools/binutils/files/0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch b/recipes-devtools/binutils/files/0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch new file mode 100644 index 00000000..1504b5aa --- /dev/null +++ b/recipes-devtools/binutils/files/0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch @@ -0,0 +1,632 @@ +From eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Fri, 9 Nov 2012 16:24:57 +0000 +Subject: Add microblazeel target support to bfd, gas and ld. + +binutils/bfd/Changelog + + 2012-11-09 Edgar E. Iglesias + + * config.bfd: Add microblazeel-*-* + * configure.in: Likewise. + * configure: Regenerate. + * elf32-microblaze.c (microblaze_elf_relocate_section): + Add endian awareness. + (microblaze_elf_merge_private_bfd_data): New. + (microblaze_bfd_write_imm_value_32): New. + (microblaze_bfd_write_imm_value_64): New. + (microblaze_elf_relax_section): Add endian awareness. + (microblaze_elf_add_symbol_hook): Define TARGET_LITTLE_NAME, + TARGET_LITTLE_SYM and bfd_elf32_bfd_merge_private_bfd_data. + * targets.c: Add bfd target bfd_elf32_microblazeel_vec. + +binutils/gas/Changelog + + 2012-11-09 Edgar E. Iglesias + + * tc-microblaze.c (md_longopts): Define OPTION_EB and + OPTION_EL for target. + (md_parse_option): Likewise. + * tc-microblaze.h: Set elf32-microblazeel if not + target_big_endian for TARGET_FORMAT. + * configure.tgt: Add microblazeel and set endian per target. + +binutils/gas/testsuite/Changelog + + 2012-11-09 David Holsgrove + + * gas/microblaze/endian.exp: New file - endian + testcase for microblaze / microblazeel. + * gas/microblaze/endian.s: Likewise. + * gas/microblaze/endian_be.d: Likewise. + * gas/microblaze/endian_le.d: Likewise. + * gas/microblaze/endian_le_elf.d: Likewise. + * gas/microblaze/reloc_sym.d: Update to accept targets + other than elf32-microblaze. + * gas/microblaze/special_reg.d: Likewise. + +binutils/ld/Changelog + + 2012-11-09 Edgar E. Iglesias + + * Makefile.am: Add eelf32microblazeel.c and eelf32mbel_linux.c. + * Makefile.in: Regenerated. + * configure.tgt: Add microblazeel and set endian per target. + * emulparams/elf32mb_linux.sh: Add OUTPUT_FORMAT. + * emulparams/elf32microblaze.sh: Likewise. + * emulparams/elf32mbel_linux.sh: New file. + * emulparams/elf32microblazeel.sh: Likewise. + +Upstream-Status: Backport + +diff --git a/bfd/config.bfd b/bfd/config.bfd +index 7def642..e59ab25 100644 +--- a/bfd/config.bfd ++++ b/bfd/config.bfd +@@ -916,8 +916,14 @@ case "${targ}" in + targ_selvecs=bfd_elf32_mep_little_vec + ;; + ++ microblazeel*-*) ++ targ_defvec=bfd_elf32_microblazeel_vec ++ targ_selvecs=bfd_elf32_microblaze_vec ++ ;; ++ + microblaze*-*) + targ_defvec=bfd_elf32_microblaze_vec ++ targ_selvecs=bfd_elf32_microblazeel_vec + ;; + + mips*-big-*) +diff --git a/bfd/configure b/bfd/configure +index 43bff03..7b073cc 100755 +--- a/bfd/configure ++++ b/bfd/configure +@@ -15283,6 +15283,7 @@ do + bfd_elf32_mcore_little_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;; + bfd_elf32_mep_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;; + bfd_elf32_mep_little_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;; ++ bfd_elf32_microblazeel_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;; + bfd_elf32_microblaze_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;; + bfd_elf32_mn10200_vec) tb="$tb elf-m10200.lo elf32.lo $elf" ;; + bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;; +diff --git a/bfd/configure.in b/bfd/configure.in +index f7e3929..78f2744 100644 +--- a/bfd/configure.in ++++ b/bfd/configure.in +@@ -764,6 +764,7 @@ do + bfd_elf32_mcore_little_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;; + bfd_elf32_mep_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;; + bfd_elf32_mep_little_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;; ++ bfd_elf32_microblazeel_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;; + bfd_elf32_microblaze_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;; + bfd_elf32_mn10200_vec) tb="$tb elf-m10200.lo elf32.lo $elf" ;; + bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;; +diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c +index c000424..be2de13 100644 +--- a/bfd/elf32-microblaze.c ++++ b/bfd/elf32-microblaze.c +@@ -702,6 +702,7 @@ microblaze_elf_relocate_section (bfd *output_bfd, + Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); + Elf_Internal_Rela *rel, *relend; ++ int endian = (bfd_little_endian (output_bfd)) ? 0 : 2; + /* Assume success. */ + bfd_boolean ret = TRUE; + asection *sreloc; +@@ -933,9 +934,9 @@ microblaze_elf_relocate_section (bfd *output_bfd, + + offset + INST_WORD_SIZE); + relocation += addend; + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, +- contents + offset + 2); ++ contents + offset + endian); + bfd_put_16 (input_bfd, relocation & 0xffff, +- contents + offset + 2 + INST_WORD_SIZE); ++ contents + offset + endian + INST_WORD_SIZE); + break; + + case (int) R_MICROBLAZE_PLT_64: +@@ -952,9 +953,9 @@ microblaze_elf_relocate_section (bfd *output_bfd, + + input_section->output_offset + + offset + INST_WORD_SIZE); + bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff, +- contents + offset + 2); ++ contents + offset + endian); + bfd_put_16 (input_bfd, immediate & 0xffff, +- contents + offset + 2 + INST_WORD_SIZE); ++ contents + offset + endian + INST_WORD_SIZE); + } + else + { +@@ -963,9 +964,9 @@ microblaze_elf_relocate_section (bfd *output_bfd, + + offset + INST_WORD_SIZE); + immediate = relocation; + bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff, +- contents + offset + 2); ++ contents + offset + endian); + bfd_put_16 (input_bfd, immediate & 0xffff, +- contents + offset + 2 + INST_WORD_SIZE); ++ contents + offset + endian + INST_WORD_SIZE); + } + break; + } +@@ -1031,9 +1032,9 @@ microblaze_elf_relocate_section (bfd *output_bfd, + abort (); /* ??? */ + } + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, +- contents + offset + 2); ++ contents + offset + endian); + bfd_put_16 (input_bfd, relocation & 0xffff, +- contents + offset + 2 + INST_WORD_SIZE); ++ contents + offset + endian + INST_WORD_SIZE); + break; + } + +@@ -1048,8 +1049,8 @@ microblaze_elf_relocate_section (bfd *output_bfd, + immediate = relocation; + lo = immediate & 0x0000ffff; + high = (immediate >> 16) & 0x0000ffff; +- bfd_put_16 (input_bfd, high, contents + offset + 2); +- bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + 2); ++ bfd_put_16 (input_bfd, high, contents + offset + endian); ++ bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian); + break; + } + +@@ -1082,9 +1083,9 @@ microblaze_elf_relocate_section (bfd *output_bfd, + + input_section->output_offset + + offset + INST_WORD_SIZE); + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, +- contents + offset + 2); ++ contents + offset + endian); + bfd_put_16 (input_bfd, relocation & 0xffff, +- contents + offset + 2 + INST_WORD_SIZE); ++ contents + offset + endian + INST_WORD_SIZE); + } + break; + } +@@ -1176,9 +1177,9 @@ microblaze_elf_relocate_section (bfd *output_bfd, + + input_section->output_offset + + offset + INST_WORD_SIZE); + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, +- contents + offset + 2); ++ contents + offset + endian); + bfd_put_16 (input_bfd, relocation & 0xffff, +- contents + offset + 2 + INST_WORD_SIZE); ++ contents + offset + endian + INST_WORD_SIZE); + } + break; + } +@@ -1253,6 +1254,21 @@ microblaze_elf_relocate_section (bfd *output_bfd, + + return ret; + } ++ ++/* Merge backend specific data from an object file to the output ++ object file when linking. ++ ++ Note: We only use this hook to catch endian mismatches. */ ++static bfd_boolean ++microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) ++{ ++ /* Check if we have the same endianess. */ ++ if (! _bfd_generic_verify_endian_match (ibfd, obfd)) ++ return FALSE; ++ ++ return TRUE; ++} ++ + + /* Calculate fixup value for reference. */ + +@@ -1275,6 +1291,36 @@ calc_fixup (bfd_vma addr, asection *sec) + return fixup; + } + ++/* Read-modify-write into the bfd, an immediate value into appropriate fields of ++ a 32-bit instruction. */ ++static void ++microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val) ++{ ++ unsigned long instr = bfd_get_32 (abfd, bfd_addr); ++ instr &= ~0x0000ffff; ++ instr |= (val & 0x0000ffff); ++ bfd_put_32 (abfd, instr, bfd_addr); ++} ++ ++/* Read-modify-write into the bfd, an immediate value into appropriate fields of ++ two consecutive 32-bit instructions. */ ++static void ++microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val) ++{ ++ unsigned long instr_hi; ++ unsigned long instr_lo; ++ ++ instr_hi = bfd_get_32 (abfd, bfd_addr); ++ instr_hi &= ~0x0000ffff; ++ instr_hi |= ((val >> 16) & 0x0000ffff); ++ bfd_put_32 (abfd, instr_hi, bfd_addr); ++ ++ instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE); ++ instr_lo &= ~0x0000ffff; ++ instr_lo |= (val & 0x0000ffff); ++ bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE); ++} ++ + static bfd_boolean + microblaze_elf_relax_section (bfd *abfd, + asection *sec, +@@ -1305,7 +1351,8 @@ microblaze_elf_relax_section (bfd *abfd, + /* Only do this for a text section. */ + if (link_info->relocatable + || (sec->flags & SEC_RELOC) == 0 +- || (sec->reloc_count == 0)) ++ || (sec->reloc_count == 0) ++ || (sec->flags & SEC_CODE) == 0) + return TRUE; + + BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0)); +@@ -1485,7 +1532,8 @@ microblaze_elf_relax_section (bfd *abfd, + efix = calc_fixup (target_address, sec); + irel->r_addend -= (efix - sfix); + /* Should use HOWTO. */ +- bfd_put_16 (abfd, irel->r_addend, contents + irel->r_offset + 2); ++ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset, ++ irel->r_addend); + } + break; + case R_MICROBLAZE_64_NONE: +@@ -1498,8 +1546,8 @@ microblaze_elf_relax_section (bfd *abfd, + sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, sec); + efix = calc_fixup (target_address, sec); + irel->r_addend -= (efix - sfix); +- bfd_put_16 (abfd, irel->r_addend, contents + irel->r_offset +- + INST_WORD_SIZE + 2); ++ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset ++ + INST_WORD_SIZE, irel->r_addend); + } + break; + } +@@ -1627,13 +1675,14 @@ microblaze_elf_relax_section (bfd *abfd, + } + } + +- immediate = (unsigned short) bfd_get_16 (abfd, ocontents + +- irelscan->r_offset + 2); ++ unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset); ++ immediate = instr & 0x0000ffff; + target_address = immediate; + offset = calc_fixup (target_address, sec); + immediate -= offset; + irelscan->r_addend -= offset; +- bfd_put_16 (abfd, immediate, ocontents + irelscan->r_offset + 2); ++ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset, ++ irelscan->r_addend); + } + } + +@@ -1669,15 +1718,13 @@ microblaze_elf_relax_section (bfd *abfd, + elf_section_data (o)->this_hdr.contents = ocontents; + } + } +- immediate = (unsigned short) (bfd_get_16 (abfd, ocontents +- + irelscan->r_offset +- + 2) << 16) +- & 0xffff0000; +- immediate += (unsigned short) (bfd_get_16 (abfd, ocontents +- + irelscan->r_offset +- + INST_WORD_SIZE + 2)) +- & 0x0000ffff; +- ++ unsigned long instr_hi = bfd_get_32 (abfd, ocontents ++ + irelscan->r_offset); ++ unsigned long instr_lo = bfd_get_32 (abfd, ocontents ++ + irelscan->r_offset ++ + INST_WORD_SIZE); ++ immediate = (instr_hi & 0x0000ffff) << 16; ++ immediate |= (instr_lo & 0x0000ffff); + offset = calc_fixup (irelscan->r_addend, sec); + immediate -= offset; + irelscan->r_addend -= offset; +@@ -1715,22 +1762,19 @@ microblaze_elf_relax_section (bfd *abfd, + elf_section_data (o)->this_hdr.contents = ocontents; + } + } +- +- immediate = (unsigned short) +- (bfd_get_16 (abfd, ocontents + irelscan->r_offset + 2) << 16) +- & 0xffff0000; +- immediate += (unsigned short) +- (bfd_get_16 (abfd, ocontents + irelscan->r_offset +- + INST_WORD_SIZE + 2)) +- & 0x0000ffff; ++ unsigned long instr_hi = bfd_get_32 (abfd, ocontents ++ + irelscan->r_offset); ++ unsigned long instr_lo = bfd_get_32 (abfd, ocontents ++ + irelscan->r_offset ++ + INST_WORD_SIZE); ++ immediate = (instr_hi & 0x0000ffff) << 16; ++ immediate |= (instr_lo & 0x0000ffff); + target_address = immediate; + offset = calc_fixup (target_address, sec); + immediate -= offset; + irelscan->r_addend -= offset; +- bfd_put_16 (abfd, ((immediate >> 16) & 0x0000ffff), +- ocontents + irelscan->r_offset + 2); +- bfd_put_16 (abfd, (immediate & 0x0000ffff), +- ocontents + irelscan->r_offset + INST_WORD_SIZE + 2); ++ microblaze_bfd_write_imm_value_64 (abfd, ocontents ++ + irelscan->r_offset, immediate); + } + } + } +@@ -1800,9 +1844,12 @@ microblaze_elf_relax_section (bfd *abfd, + + if (sec->relax_count == 0) + { ++ *again = FALSE; + free (sec->relax); + sec->relax = NULL; + } ++ else ++ *again = TRUE; + return TRUE; + + error_return: +@@ -3016,6 +3063,8 @@ microblaze_elf_add_symbol_hook (bfd *abfd, + return TRUE; + } + ++#define TARGET_LITTLE_SYM bfd_elf32_microblazeel_vec ++#define TARGET_LITTLE_NAME "elf32-microblazeel" + + #define TARGET_BIG_SYM bfd_elf32_microblaze_vec + #define TARGET_BIG_NAME "elf32-microblaze" +@@ -3032,6 +3081,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd, + #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name + #define elf_backend_relocate_section microblaze_elf_relocate_section + #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section ++#define bfd_elf32_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data + #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup + + #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook +diff --git a/bfd/targets.c b/bfd/targets.c +index 621bf8d..442cb8f 100644 +--- a/bfd/targets.c ++++ b/bfd/targets.c +@@ -659,6 +659,7 @@ extern const bfd_target bfd_elf32_mcore_big_vec; + extern const bfd_target bfd_elf32_mcore_little_vec; + extern const bfd_target bfd_elf32_mep_vec; + extern const bfd_target bfd_elf32_mep_little_vec; ++extern const bfd_target bfd_elf32_microblazeel_vec; + extern const bfd_target bfd_elf32_microblaze_vec; + extern const bfd_target bfd_elf32_mn10200_vec; + extern const bfd_target bfd_elf32_mn10300_vec; +diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c +index de0efda..04dfa1e 100644 +--- a/gas/config/tc-microblaze.c ++++ b/gas/config/tc-microblaze.c +@@ -35,6 +35,9 @@ + #define streq(a,b) (strcmp (a, b) == 0) + #endif + ++#define OPTION_EB (OPTION_MD_BASE + 0) ++#define OPTION_EL (OPTION_MD_BASE + 1) ++ + void microblaze_generate_symbol (char *sym); + static bfd_boolean check_spl_reg (unsigned *); + +@@ -1707,6 +1710,8 @@ const char * md_shortopts = ""; + + struct option md_longopts[] = + { ++ {"EB", no_argument, NULL, OPTION_EB}, ++ {"EL", no_argument, NULL, OPTION_EL}, + { NULL, no_argument, NULL, 0} + }; + +@@ -2304,6 +2309,12 @@ md_parse_option (int c, char * arg ATTRIBUTE_UNUSED) + { + switch (c) + { ++ case OPTION_EB: ++ target_big_endian = 1; ++ break; ++ case OPTION_EL: ++ target_big_endian = 0; ++ break; + default: + return 0; + } +diff --git a/gas/config/tc-microblaze.h b/gas/config/tc-microblaze.h +index db8d227..0651040 100644 +--- a/gas/config/tc-microblaze.h ++++ b/gas/config/tc-microblaze.h +@@ -23,8 +23,10 @@ + #define TC_MICROBLAZE 1 + + #define TARGET_ARCH bfd_arch_microblaze ++#ifndef TARGET_BYTES_BIG_ENDIAN + /* Used to initialise target_big_endian. */ + #define TARGET_BYTES_BIG_ENDIAN 1 ++#endif + + #define IGNORE_NONSTANDARD_ESCAPES + +@@ -75,7 +77,7 @@ extern const struct relax_type md_relax_table[]; + + #ifdef OBJ_ELF + +-#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblaze-little") ++#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblazeel") + + #define ELF_TC_SPECIAL_SECTIONS \ + { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \ +diff --git a/gas/configure.tgt b/gas/configure.tgt +index ff4cb3f..774031e 100644 +--- a/gas/configure.tgt ++++ b/gas/configure.tgt +@@ -57,7 +57,8 @@ case ${cpu} in + m6811|m6812|m68hc12) cpu_type=m68hc11 ;; + m683??) cpu_type=m68k ;; + mep) cpu_type=mep endian=little ;; +- microblaze*) cpu_type=microblaze ;; ++ microblazeel*) cpu_type=microblaze endian=little;; ++ microblaze*) cpu_type=microblaze endian=big;; + mips*el) cpu_type=mips endian=little ;; + mips*) cpu_type=mips endian=big ;; + mt) cpu_type=mt endian=big ;; +diff --git a/gas/testsuite/gas/microblaze/reloc_sym.d b/gas/testsuite/gas/microblaze/reloc_sym.d +index 212d0bb..571ffe1 100644 +--- a/gas/testsuite/gas/microblaze/reloc_sym.d ++++ b/gas/testsuite/gas/microblaze/reloc_sym.d +@@ -1,6 +1,5 @@ + +-reloc_sym.x: file format elf32-microblaze +- ++.*: +file format .* + + Disassembly of section .text: + +diff --git a/gas/testsuite/gas/microblaze/special_reg.d b/gas/testsuite/gas/microblaze/special_reg.d +index aad0131..c2041fd 100644 +--- a/gas/testsuite/gas/microblaze/special_reg.d ++++ b/gas/testsuite/gas/microblaze/special_reg.d +@@ -1,10 +1,7 @@ + #as: +-#objdump: -ds ++#objdump: -d + +-.*: file format .* +- +-Contents of section .text: +- 0000 9409d000 6c00d000 001ff800 ....l....... ++.*: +file format .* + + Disassembly of section .text: + +diff --git a/ld/Makefile.am b/ld/Makefile.am +index 4c692ea..f6f814f 100644 +--- a/ld/Makefile.am ++++ b/ld/Makefile.am +@@ -237,6 +237,7 @@ ALL_EMULATION_SOURCES = \ + eelf32mb_linux.c \ + eelf32mcore.c \ + eelf32mep.c \ ++ eelf32microblazeel.c \ + eelf32microblaze.c \ + eelf32mipswindiss.c \ + eelf32moxie.c \ +@@ -1107,6 +1108,9 @@ eelf32m32c.c: $(srcdir)/emulparams/elf32m32c.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/needrelax.em \ + $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32m32c "$(tdir_m32c)" ++eelf32mbel_linux.c: $(srcdir)/emulparams/elf32mbel_linux.sh \ ++ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ++ ${GENSCRIPTS} elf32mbel_linux "$(tdir_microblazeel)" + eelf32mb_linux.c: $(srcdir)/emulparams/elf32mb_linux.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32mb_linux "$(tdir_microblaze)" +@@ -1116,6 +1120,9 @@ eelf32mcore.c: $(srcdir)/emulparams/elf32mcore.sh \ + eelf32mep.c: $(srcdir)/emulparams/elf32mep.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/mep.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32mep "$(tdir_mep)" ++eelf32microblazeel.c: $(srcdir)/emulparams/elf32microblazeel.sh \ ++ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS} ++ ${GENSCRIPTS} elf32microblazeel "$(tdir_microblazeel)" + eelf32microblaze.c: $(srcdir)/emulparams/elf32microblaze.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32microblaze "$(tdir_microblaze)" +diff --git a/ld/Makefile.in b/ld/Makefile.in +index a675d01..fb0c21e 100644 +--- a/ld/Makefile.in ++++ b/ld/Makefile.in +@@ -544,6 +544,7 @@ ALL_EMULATION_SOURCES = \ + eelf32mb_linux.c \ + eelf32mcore.c \ + eelf32mep.c \ ++ eelf32microblazeel.c \ + eelf32microblaze.c \ + eelf32mipswindiss.c \ + eelf32moxie.c \ +@@ -1166,6 +1167,7 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mcore.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mep.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblaze.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblazeel.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32moxie.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mt.Po@am__quote@ +@@ -2577,6 +2579,9 @@ eelf32m32c.c: $(srcdir)/emulparams/elf32m32c.sh \ + $(ELF_DEPS) $(srcdir)/emultempl/needrelax.em \ + $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32m32c "$(tdir_m32c)" ++eelf32mbel_linux.c: $(srcdir)/emulparams/elf32mbel_linux.sh \ ++ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ++ ${GENSCRIPTS} elf32mbel_linux "$(tdir_microblazeel)" + eelf32mb_linux.c: $(srcdir)/emulparams/elf32mb_linux.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32mb_linux "$(tdir_microblaze)" +@@ -2586,6 +2591,9 @@ eelf32mcore.c: $(srcdir)/emulparams/elf32mcore.sh \ + eelf32mep.c: $(srcdir)/emulparams/elf32mep.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/mep.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32mep "$(tdir_mep)" ++eelf32microblazeel.c: $(srcdir)/emulparams/elf32microblazeel.sh \ ++ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS} ++ ${GENSCRIPTS} elf32microblazeel "$(tdir_microblazeel)" + eelf32microblaze.c: $(srcdir)/emulparams/elf32microblaze.sh \ + $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf32microblaze "$(tdir_microblaze)" +diff --git a/ld/configure.tgt b/ld/configure.tgt +index 0e62b52..9f0025a 100644 +--- a/ld/configure.tgt ++++ b/ld/configure.tgt +@@ -395,9 +395,18 @@ mcore-*-pe) targ_emul=mcorepe ; + mcore-*-elf) targ_emul=elf32mcore + ;; + mep-*-elf) targ_emul=elf32mep ;; +-microblaze*-linux*) +- targ_emul="elf32mb_linux" ;; +-microblaze*) targ_emul=elf32microblaze ;; ++microblazeel*-linux*) targ_emul="elf32mbel_linux" ++ targ_extra_emuls="elf32mb_linux" ++ ;; ++microblaze*-linux*) targ_emul="elf32mb_linux" ++ targ_extra_emuls="elf32mbel_linux" ++ ;; ++microblazeel*) targ_emul=elf32microblazeel ++ targ_extra_emuls=elf32microblaze ++ ;; ++microblaze*) targ_emul=elf32microblaze ++ targ_extra_emuls=elf32microblazeel ++ ;; + mips*-*-pe) targ_emul=mipspe ; + targ_extra_ofiles="deffilep.o pe-dll.o" ;; + mips*-dec-ultrix*) targ_emul=mipslit ;; +diff --git a/ld/emulparams/elf32mb_linux.sh b/ld/emulparams/elf32mb_linux.sh +index f26f1a0..bb60d1f 100644 +--- a/ld/emulparams/elf32mb_linux.sh ++++ b/ld/emulparams/elf32mb_linux.sh +@@ -1,5 +1,7 @@ + SCRIPT_NAME=elf + OUTPUT_FORMAT="elf32-microblaze" ++BIG_OUTPUT_FORMAT="elf32-microblaze" ++LITTLE_OUTPUT_FORMAT="elf32-microblazeel" + TEXT_START_ADDR=0x10000000 + NONPAGED_TEXT_START_ADDR=0x28 + ALIGNMENT=4 +diff --git a/ld/emulparams/elf32microblaze.sh b/ld/emulparams/elf32microblaze.sh +index ccc20d1..1f80447 100644 +--- a/ld/emulparams/elf32microblaze.sh ++++ b/ld/emulparams/elf32microblaze.sh +@@ -1,5 +1,7 @@ + SCRIPT_NAME=elfmicroblaze + OUTPUT_FORMAT="elf32-microblaze" ++BIG_OUTPUT_FORMAT="elf32-microblaze" ++LITTLE_OUTPUT_FORMAT="elf32-microblazeel" + #TEXT_START_ADDR=0 + NONPAGED_TEXT_START_ADDR=0x28 + ALIGNMENT=4 +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch b/recipes-devtools/binutils/files/0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch new file mode 100644 index 00000000..e3db8ea4 --- /dev/null +++ b/recipes-devtools/binutils/files/0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch @@ -0,0 +1,63 @@ +From 58deb49b33812b048a1061553c1ca6f010af59f4 Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Fri, 9 Nov 2012 22:43:28 +0000 +Subject: Files missing from previous commit. + +Upstream-Status: Backport + +diff --git a/ld/emulparams/elf32mbel_linux.sh b/ld/emulparams/elf32mbel_linux.sh +new file mode 100644 +index 0000000..2980e82 +--- /dev/null ++++ b/ld/emulparams/elf32mbel_linux.sh +@@ -0,0 +1,18 @@ ++SCRIPT_NAME=elf ++OUTPUT_FORMAT="elf32-microblazeel" ++BIG_OUTPUT_FORMAT="elf32-microblaze" ++LITTLE_OUTPUT_FORMAT="elf32-microblazeel" ++TEXT_START_ADDR=0x10000000 ++NONPAGED_TEXT_START_ADDR=0x28 ++ALIGNMENT=4 ++MAXPAGESIZE=0x1000 ++COMMONPAGESIZE=0x1000 ++ARCH=microblaze ++ ++NOP=0x80000000 ++ ++TEMPLATE_NAME=elf32 ++GENERATE_SHLIB_SCRIPT=yes ++GENERATE_PIE_SCRIPT=yes ++NO_SMALL_DATA=yes ++SEPARATE_GOTPLT=12 +diff --git a/ld/emulparams/elf32microblazeel.sh b/ld/emulparams/elf32microblazeel.sh +new file mode 100644 +index 0000000..86268b0 +--- /dev/null ++++ b/ld/emulparams/elf32microblazeel.sh +@@ -0,0 +1,23 @@ ++SCRIPT_NAME=elfmicroblaze ++OUTPUT_FORMAT="elf32-microblazeel" ++BIG_OUTPUT_FORMAT="elf32-microblaze" ++LITTLE_OUTPUT_FORMAT="elf32-microblazeel" ++#TEXT_START_ADDR=0 ++NONPAGED_TEXT_START_ADDR=0x28 ++ALIGNMENT=4 ++MAXPAGESIZE=4 ++ARCH=microblaze ++EMBEDDED=yes ++ ++NOP=0x80000000 ++ ++# Hmmm, there's got to be a better way. This sets the stack to the ++# top of the simulator memory (2^19 bytes). ++#PAGE_SIZE=0x1000 ++#DATA_ADDR=0x10000 ++#OTHER_RELOCATING_SECTIONS='.stack 0x7000 : { _stack = .; *(.stack) }' ++#$@{RELOCATING+ PROVIDE (__stack = 0x7000);@} ++#OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);' ++ ++TEMPLATE_NAME=elf32 ++#GENERATE_SHLIB_SCRIPT=yes +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch b/recipes-devtools/binutils/files/0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch new file mode 100644 index 00000000..977fbfcd --- /dev/null +++ b/recipes-devtools/binutils/files/0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch @@ -0,0 +1,89 @@ +From de1b485c223f0799e7f2f88d2fa6c010191bd1ed Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Mon, 12 Nov 2012 00:23:25 +0000 +Subject: Add missing test cases. * gas/microblaze/endian.exp: New + file - endian testcase for microblaze / microblazeel. * + gas/microblaze/endian.s: Likewise. * + gas/microblaze/endian_be.d: Likewise. * + gas/microblaze/endian_le.d: Likewise. * + gas/microblaze/endian_le_elf.d: Likewise. + +Upstream-Status: Backport + +diff --git a/gas/testsuite/gas/microblaze/endian.exp b/gas/testsuite/gas/microblaze/endian.exp +new file mode 100644 +index 0000000..2ec2112 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/endian.exp +@@ -0,0 +1,12 @@ ++# MicroBlaze test for special register. ++ ++if [istarget microblaze-*-*] { ++ run_dump_test "endian_be" ++ if [istarget microblaze-*-elf] { ++ run_dump_test "endian_le_elf" ++ } ++} ++ ++if [istarget microblazeel-*-*] { ++ run_dump_test "endian_le" ++} +diff --git a/gas/testsuite/gas/microblaze/endian.s b/gas/testsuite/gas/microblaze/endian.s +new file mode 100644 +index 0000000..1274d89 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/endian.s +@@ -0,0 +1,5 @@ ++ .text ++start: ++ addi r1,r0,1234 ++ .long 0x12345678 ++ .word 0x1234, 0 +diff --git a/gas/testsuite/gas/microblaze/endian_be.d b/gas/testsuite/gas/microblaze/endian_be.d +new file mode 100644 +index 0000000..266d3f3 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/endian_be.d +@@ -0,0 +1,9 @@ ++#as: ++#objdump: -s ++#name: MicroBlaze Big Endian ++#source: endian.s ++ ++.*: file format elf32-microblaze ++ ++Contents of section .text: ++ 0000 202004d2 12345678 00001234 00000000 ...4Vx...4.... +diff --git a/gas/testsuite/gas/microblaze/endian_le.d b/gas/testsuite/gas/microblaze/endian_le.d +new file mode 100644 +index 0000000..9aa5931 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/endian_le.d +@@ -0,0 +1,9 @@ ++#as: ++#objdump: -s ++#name: MicroBlaze Little Endian ++#source: endian.s ++ ++.*: file format elf32-microblazeel ++ ++Contents of section .text: ++ 0000 d2042020 78563412 34120000 00000000 .. xV4.4....... +diff --git a/gas/testsuite/gas/microblaze/endian_le_elf.d b/gas/testsuite/gas/microblaze/endian_le_elf.d +new file mode 100644 +index 0000000..e3647b6 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/endian_le_elf.d +@@ -0,0 +1,9 @@ ++#as: -EL ++#objdump: -s ++#name: MicroBlaze Little Endian ++#source: endian.s ++ ++.*: file format elf32-microblazeel ++ ++Contents of section .text: ++ 0000 d2042020 78563412 34120000 00000000 .. xV4.4....... +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch b/recipes-devtools/binutils/files/0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch new file mode 100644 index 00000000..c3961afe --- /dev/null +++ b/recipes-devtools/binutils/files/0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch @@ -0,0 +1,143 @@ +From 1e6eff13a8f06601a76ca70b9b74651016ef042d Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Wed, 14 Nov 2012 16:19:28 +0000 +Subject: Add the endian reversing versions of load/store instructions; + +2012-11-14 Edgar E. Iglesias + + * microblaze-opc.h: Increase MAX_OPCODES (op_code_struct): add lbur, + lhur, lwr, sbr, shr, swr + * microblaze-opcm.h (microblaze_instr): add lbur, lhur, lwr, sbr, shr, + swr + +2012-11-14 David Holsgrove + + * gas/microblaze/allinsn.exp: New file - test newly added opcodes + * gas/microblaze/allinsn.s: Likewise + * gas/microblaze/allinsn.d: Likewise + +Upstream-Status: Backport + +diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d +new file mode 100644 +index 0000000..79064ba +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/allinsn.d +@@ -0,0 +1,24 @@ ++#as: ++#objdump: -d ++ ++.*: +file format .* ++ ++Disassembly of section .text: ++ ++00000000 : ++ 0: c0000200 lbur r0, r0, r0 ++ ++00000004 : ++ 4: c4000200 lhur r0, r0, r0 ++ ++00000008 : ++ 8: c8000200 lwr r0, r0, r0 ++ ++0000000c : ++ c: d0000200 sbr r0, r0, r0 ++ ++00000010 : ++ 10: d4000200 shr r0, r0, r0 ++ ++00000014 : ++ 14: d8000200 swr r0, r0, r0 +diff --git a/gas/testsuite/gas/microblaze/allinsn.exp b/gas/testsuite/gas/microblaze/allinsn.exp +new file mode 100644 +index 0000000..d1b1dea +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/allinsn.exp +@@ -0,0 +1,5 @@ ++# MicroBlaze test for special register. ++ ++if [istarget microblaze*-*-*] { ++ run_dump_test "allinsn" ++} +diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s +new file mode 100644 +index 0000000..8bb3ef5 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/allinsn.s +@@ -0,0 +1,27 @@ ++ .text ++footext: ++ .text ++ .global lbur ++lbur: ++ lbur r0,r0,r0 ++ .text ++ .global lhur ++lhur: ++ lhur r0,r0,r0 ++ .text ++ .global lwr ++lwr: ++ lwr r0,r0,r0 ++ .text ++ .global sbr ++sbr: ++ sbr r0,r0,r0 ++ .text ++ .global shr ++shr: ++ shr r0,r0,r0 ++ .text ++ .global swr ++swr: ++ swr r0,r0,r0 ++ +diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h +index 02ac83f..44c9d38 100644 +--- a/opcodes/microblaze-opc.h ++++ b/opcodes/microblaze-opc.h +@@ -96,7 +96,7 @@ + #define DELAY_SLOT 1 + #define NO_DELAY_SLOT 0 + +-#define MAX_OPCODES 280 ++#define MAX_OPCODES 284 + + struct op_code_struct + { +@@ -220,12 +220,18 @@ struct op_code_struct + {"bgei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBCA00000, OPCODE_MASK_H1, bgei, branch_inst }, + {"bgeid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBEA00000, OPCODE_MASK_H1, bgeid, branch_inst }, + {"lbu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC0000000, OPCODE_MASK_H4, lbu, memory_load_inst }, ++ {"lbur", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC0000200, OPCODE_MASK_H4, lbur, memory_load_inst }, + {"lhu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC4000000, OPCODE_MASK_H4, lhu, memory_load_inst }, ++ {"lhur", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC4000200, OPCODE_MASK_H4, lhur, memory_load_inst }, + {"lw", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000000, OPCODE_MASK_H4, lw, memory_load_inst }, ++ {"lwr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000200, OPCODE_MASK_H4, lwr, memory_load_inst }, + {"lwx", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000400, OPCODE_MASK_H4, lwx, memory_load_inst }, + {"sb", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD0000000, OPCODE_MASK_H4, sb, memory_store_inst }, ++ {"sbr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD0000200, OPCODE_MASK_H4, sbr, memory_store_inst }, + {"sh", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD4000000, OPCODE_MASK_H4, sh, memory_store_inst }, ++ {"shr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD4000200, OPCODE_MASK_H4, shr, memory_store_inst }, + {"sw", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000000, OPCODE_MASK_H4, sw, memory_store_inst }, ++ {"swr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000200, OPCODE_MASK_H4, swr, memory_store_inst }, + {"swx", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000400, OPCODE_MASK_H4, swx, memory_store_inst }, + {"lbui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE0000000, OPCODE_MASK_H, lbui, memory_load_inst }, + {"lhui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE4000000, OPCODE_MASK_H, lhui, memory_load_inst }, +diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h +index 10acacf..a3bec49 100644 +--- a/opcodes/microblaze-opcm.h ++++ b/opcodes/microblaze-opcm.h +@@ -36,7 +36,8 @@ enum microblaze_instr + bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni, + imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid, + brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti, +- bgtid, bgei, bgeid, lbu, lhu, lw, lwx, sb, sh, sw, swx, lbui, lhui, lwi, ++ bgtid, bgei, bgeid, lbu, lbur, lhu, lhur, lw, lwr, lwx, sb, sbr, sh, ++ shr, sw, swr, swx, lbui, lhui, lwi, + sbi, shi, swi, msrset, msrclr, tuqula, fadd, frsub, fmul, fdiv, + fcmp_lt, fcmp_eq, fcmp_le, fcmp_gt, fcmp_ne, fcmp_ge, fcmp_un, flt, + fint, fsqrt, +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch b/recipes-devtools/binutils/files/0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch new file mode 100644 index 00000000..caa22a0a --- /dev/null +++ b/recipes-devtools/binutils/files/0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch @@ -0,0 +1,76 @@ +From e2be436cc342d130ac0ba6b4a31724d71e473684 Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Wed, 14 Nov 2012 16:45:00 +0000 +Subject: Add clz opcode. + +opcodes/ + * microblaze-opc.h: Increase MAX_OPCODES (op_code_struct): add clz insn + * microblaze-opcm.h (microblaze_instr): add clz + +gas/testsuite/ + * gas/microblaze/allinsn.s: Add clz insn + * gas/microblaze/allinsn.d: Likewise + +Upstream-Status: Backport + +diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d +index 79064ba..c7854f1 100644 +--- a/gas/testsuite/gas/microblaze/allinsn.d ++++ b/gas/testsuite/gas/microblaze/allinsn.d +@@ -22,3 +22,6 @@ Disassembly of section .text: + + 00000014 : + 14: d8000200 swr r0, r0, r0 ++ ++00000018 : ++ 18: 900000e0 clz r0, r0 +diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s +index 8bb3ef5..0e4271d 100644 +--- a/gas/testsuite/gas/microblaze/allinsn.s ++++ b/gas/testsuite/gas/microblaze/allinsn.s +@@ -24,4 +24,8 @@ shr: + .global swr + swr: + swr r0,r0,r0 ++ .text ++ .global clz ++clz: ++ clz r0,r0 + +diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h +index 44c9d38..132b951 100644 +--- a/opcodes/microblaze-opc.h ++++ b/opcodes/microblaze-opc.h +@@ -96,7 +96,7 @@ + #define DELAY_SLOT 1 + #define NO_DELAY_SLOT 0 + +-#define MAX_OPCODES 284 ++#define MAX_OPCODES 285 + + struct op_code_struct + { +@@ -394,6 +394,7 @@ struct op_code_struct + {"tneaputd", INST_TYPE_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C0006E0, OPCODE_MASK_H34C, tneaputd, anyware_inst }, + {"necaputd", INST_TYPE_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C000760, OPCODE_MASK_H34C, necaputd, anyware_inst }, + {"tnecaputd", INST_TYPE_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C0007E0, OPCODE_MASK_H34C, tnecaputd, anyware_inst }, ++ {"clz", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900000E0, OPCODE_MASK_H34, clz, special_inst }, + {"", 0, 0, 0, 0, 0, 0, 0, 0}, + }; + +diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h +index a3bec49..58e6fd4 100644 +--- a/opcodes/microblaze-opcm.h ++++ b/opcodes/microblaze-opcm.h +@@ -25,7 +25,7 @@ + + enum microblaze_instr + { +- add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, cmp, cmpu, ++ add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, clz, cmp, cmpu, + addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul, + mulh, mulhu, mulhsu, + idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput, +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch b/recipes-devtools/binutils/files/0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch new file mode 100644 index 00000000..6da0bf6a --- /dev/null +++ b/recipes-devtools/binutils/files/0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch @@ -0,0 +1,207 @@ +From b5ab1aad93379ce5546b54321d2a7d577e8f0ccd Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Wed, 14 Nov 2012 17:05:20 +0000 +Subject: opcodes/ * microblaze-opc.h: Define new instruction type + INST_TYPE_IMM5, update OPCODE_MASK_H13S, add OPCODE_MASK_HN, + define MIN_IMM5 / MAX_IMM5, and increase MAX_OPCODES. + (op_code_struct): add mbar and sleep * microblaze-opcm.h + (microblaze_instr): add mbar Define IMM_MBAR and IMM5_MBAR_MASK + * microblaze-dis.c: Add get_field_imm5_mbar + (print_insn_microblaze): Add support for INST_TYPE_IMM5 and + INST_TYPE_NONE + +gas/ + * config/tc-microblaze.c (md_assemble): Add support for INST_TYPE_IMM5 + +gas/testsuite/ + * gas/microblaze/allinsn.s: Add mbar and sleep + * gas/microblaze/allinsn.d: Likewise + +Upstream-Status: Backport + +diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c +index 04dfa1e..b71383b 100644 +--- a/gas/config/tc-microblaze.c ++++ b/gas/config/tc-microblaze.c +@@ -1605,6 +1605,24 @@ md_assemble (char * str) + output = frag_more (isize); + break; + ++ case INST_TYPE_IMM5: ++ if (strcmp(op_end, "")) ++ op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5); ++ else ++ as_fatal(_("Error in statement syntax")); ++ if (exp.X_op != O_constant) { ++ as_warn(_("Symbol used as immediate for mbar instruction")); ++ } else { ++ output = frag_more (isize); ++ immed = exp.X_add_number; ++ } ++ if (immed != (immed % 32)) { ++ as_warn(_("Immediate value for mbar > 32. using ")); ++ immed = immed % 32; ++ } ++ inst |= (immed << IMM_MBAR); ++ break; ++ + default: + as_fatal (_("unimplemented opcode \"%s\""), name); + } +diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d +index c7854f1..ec14020 100644 +--- a/gas/testsuite/gas/microblaze/allinsn.d ++++ b/gas/testsuite/gas/microblaze/allinsn.d +@@ -25,3 +25,9 @@ Disassembly of section .text: + + 00000018 : + 18: 900000e0 clz r0, r0 ++ ++0000001c : ++ 1c: b8420004 mbar 2 ++ ++00000020 : ++ 20: ba020004 sleep +diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s +index 0e4271d..582da17 100644 +--- a/gas/testsuite/gas/microblaze/allinsn.s ++++ b/gas/testsuite/gas/microblaze/allinsn.s +@@ -28,4 +28,12 @@ swr: + .global clz + clz: + clz r0,r0 ++ .text ++ .global mbar ++mbar: ++ mbar 2 ++ .text ++ .global sleep ++sleep: ++ sleep + +diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c +index bdbf831..e204e36 100644 +--- a/opcodes/microblaze-dis.c ++++ b/opcodes/microblaze-dis.c +@@ -65,6 +65,15 @@ get_field_imm5 (long instr) + } + + static char * ++get_field_imm5_mbar (long instr) ++{ ++ char tmpstr[25]; ++ ++ sprintf(tmpstr, "%d", (short)((instr & IMM5_MBAR_MASK) >> IMM_MBAR)); ++ return(strdup(tmpstr)); ++} ++ ++static char * + get_field_rfsl (long instr) + { + char tmpstr[25]; +@@ -374,6 +383,13 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info) + case INST_TYPE_RD_IMM15: + print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_imm15 (inst)); + break; ++ /* For mbar insn. */ ++ case INST_TYPE_IMM5: ++ print_func (stream, "\t%s", get_field_imm5_mbar (inst)); ++ break; ++ /* For mbar 16 or sleep insn. */ ++ case INST_TYPE_NONE: ++ break; + /* For tuqula instruction */ + case INST_TYPE_RD: + print_func (stream, "\t%s", get_field_rd (inst)); +diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h +index 132b951..0447fc5 100644 +--- a/opcodes/microblaze-opc.h ++++ b/opcodes/microblaze-opc.h +@@ -56,6 +56,9 @@ + /* New insn type for t*put. */ + #define INST_TYPE_RFSL 19 + ++/* For mbar. */ ++#define INST_TYPE_IMM5 20 ++ + #define INST_TYPE_NONE 25 + + +@@ -76,8 +79,8 @@ + #define OPCODE_MASK_H2 0xFC1F0000 /* High 6 and bits 20-16. */ + #define OPCODE_MASK_H12 0xFFFF0000 /* High 16. */ + #define OPCODE_MASK_H4 0xFC0007FF /* High 6 and low 11 bits. */ +-#define OPCODE_MASK_H13S 0xFFE0EFF0 /* High 11 and 15:1 bits and last +- nibble of last byte for spr. */ ++#define OPCODE_MASK_H13S 0xFFE0E7F0 /* High 11 16:18 21:27 bits, 19:20 bits ++ and last nibble of last byte for spr. */ + #define OPCODE_MASK_H23S 0xFC1FC000 /* High 6, 20-16 and 15:1 bits and last + nibble of last byte for spr. */ + #define OPCODE_MASK_H34 0xFC00FFFF /* High 6 and low 16 bits. */ +@@ -92,11 +95,13 @@ + + /* New Mask for msrset, msrclr insns. */ + #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */ ++/* Mask for mbar insn. */ ++#define OPCODE_MASK_HN 0xFF020004 /* High 16 bits and bits 14, 29. */ + + #define DELAY_SLOT 1 + #define NO_DELAY_SLOT 0 + +-#define MAX_OPCODES 285 ++#define MAX_OPCODES 287 + + struct op_code_struct + { +@@ -395,6 +400,8 @@ struct op_code_struct + {"necaputd", INST_TYPE_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C000760, OPCODE_MASK_H34C, necaputd, anyware_inst }, + {"tnecaputd", INST_TYPE_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C0007E0, OPCODE_MASK_H34C, tnecaputd, anyware_inst }, + {"clz", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900000E0, OPCODE_MASK_H34, clz, special_inst }, ++ {"mbar", INST_TYPE_IMM5, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8020004, OPCODE_MASK_HN, mbar, special_inst }, ++ {"sleep", INST_TYPE_NONE, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBA020004, OPCODE_MASK_HN, invalid_inst, special_inst }, /* translates to mbar 16. */ + {"", 0, 0, 0, 0, 0, 0, 0, 0}, + }; + +@@ -412,5 +419,8 @@ char pvr_register_prefix[] = "rpvr"; + #define MIN_IMM15 ((int) 0x0000) + #define MAX_IMM15 ((int) 0x7fff) + ++#define MIN_IMM5 ((int) 0x00000000) ++#define MAX_IMM5 ((int) 0x0000001f) ++ + #endif /* MICROBLAZE_OPC */ + +diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h +index 58e6fd4..867263e 100644 +--- a/opcodes/microblaze-opcm.h ++++ b/opcodes/microblaze-opcm.h +@@ -31,7 +31,7 @@ enum microblaze_instr + idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput, + ncget, ncput, muli, bslli, bsrai, bsrli, mului, or, and, xor, + andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16, +- wic, wdc, wdcclear, wdcflush, mts, mfs, br, brd, ++ wic, wdc, wdcclear, wdcflush, mts, mfs, mbar, br, brd, + brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt, + bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni, + imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid, +@@ -122,6 +122,7 @@ enum microblaze_instr_type + #define RA_LOW 16 /* Low bit for RA. */ + #define RB_LOW 11 /* Low bit for RB. */ + #define IMM_LOW 0 /* Low bit for immediate. */ ++#define IMM_MBAR 21 /* low bit for mbar instruction. */ + + #define RD_MASK 0x03E00000 + #define RA_MASK 0x001F0000 +@@ -131,6 +132,9 @@ enum microblaze_instr_type + /* Imm mask for barrel shifts. */ + #define IMM5_MASK 0x0000001F + ++/* Imm mask for mbar. */ ++#define IMM5_MBAR_MASK 0x03E00000 ++ + /* FSL imm mask for get, put instructions. */ + #define RFSL_MASK 0x000000F + +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch b/recipes-devtools/binutils/files/0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch new file mode 100644 index 00000000..28b5672d --- /dev/null +++ b/recipes-devtools/binutils/files/0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch @@ -0,0 +1,149 @@ +From b66f7d905a679685476fbfbc793541adb8829a6c Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Wed, 21 Nov 2012 17:34:11 +0000 +Subject: Add stack high register and stack low register for MicroBlaze + hardware assisted stack protection, stores stack low / stack high + limits for detecting stack overflow / underflow + +binutils/opcodes + * microblaze-opcm.h: Add REG_SLR_MASK, REG_SHR_MASK, REG_SHR and REG_SLR + * microblaze-dis.c (get_field_special): Handle REG_SLR_MASK and REG_SHR_MASK +binutils/gas + * config/tc-microblaze.c (parse_reg): Parse REG_SLR, REG_SHR +binutils/gas + * gas/microblaze/allinsn.s: Test use of SHR, SLR + * gas/microblaze/allinsn.d: Likewise + +Upstream-Status: Backport + +diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c +index b71383b..5a427a0 100644 +--- a/gas/config/tc-microblaze.c ++++ b/gas/config/tc-microblaze.c +@@ -531,6 +531,17 @@ parse_reg (char * s, unsigned * reg) + } + return s; + } ++ /* Stack protection registers. */ ++ else if (strncasecmp (s, "rshr", 4) == 0) ++ { ++ *reg = REG_SHR; ++ return s + 4; ++ } ++ else if (strncasecmp (s, "rslr", 4) == 0) ++ { ++ *reg = REG_SLR; ++ return s + 4; ++ } + else + { + if (TOLOWER (s[0]) == 'r') +@@ -760,6 +771,7 @@ check_spl_reg (unsigned * reg) + || (*reg == REG_PID) || (*reg == REG_ZPR) + || (*reg == REG_TLBX) || (*reg == REG_TLBLO) + || (*reg == REG_TLBHI) || (*reg == REG_TLBSX) ++ || (*reg == REG_SHR) || (*reg == REG_SLR) + || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM)) + return TRUE; + +@@ -1280,6 +1292,10 @@ md_assemble (char * str) + immed = opcode->immval_mask | REG_TLBLO_MASK; + else if (reg2 == REG_TLBHI) + immed = opcode->immval_mask | REG_TLBHI_MASK; ++ else if (reg2 == REG_SHR) ++ immed = opcode->immval_mask | REG_SHR_MASK; ++ else if (reg2 == REG_SLR) ++ immed = opcode->immval_mask | REG_SLR_MASK; + else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM)) + immed = opcode->immval_mask | REG_PVR_MASK | reg2; + else +@@ -1331,6 +1347,10 @@ md_assemble (char * str) + immed = opcode->immval_mask | REG_TLBHI_MASK; + else if (reg1 == REG_TLBSX) + immed = opcode->immval_mask | REG_TLBSX_MASK; ++ else if (reg1 == REG_SHR) ++ immed = opcode->immval_mask | REG_SHR_MASK; ++ else if (reg1 == REG_SLR) ++ immed = opcode->immval_mask | REG_SLR_MASK; + else + as_fatal (_("invalid value for special purpose register")); + inst |= (reg2 << RA_LOW) & RA_MASK; +diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d +index ec14020..4a03340 100644 +--- a/gas/testsuite/gas/microblaze/allinsn.d ++++ b/gas/testsuite/gas/microblaze/allinsn.d +@@ -31,3 +31,13 @@ Disassembly of section .text: + + 00000020 : + 20: ba020004 sleep ++ ++00000024 : ++ 24: b0000000 imm 0 ++ 28: 31600000 addik r11, r0, 0 ++ 2c: 940bc800 mts rslr, r11 ++ ++00000030 : ++ 30: b0000000 imm 0 ++ 34: 31600000 addik r11, r0, 0 ++ 38: 940bc802 mts rshr, r11 +diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s +index 582da17..437444f 100644 +--- a/gas/testsuite/gas/microblaze/allinsn.s ++++ b/gas/testsuite/gas/microblaze/allinsn.s +@@ -36,4 +36,14 @@ mbar: + .global sleep + sleep: + sleep ++ .text ++ .global regslr ++regslr: ++ la r11,r0,r0 ++ mts rslr,r11 ++ .text ++ .global regshr ++regshr: ++ la r11,r0,r0 ++ mts rshr,r11 + +diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c +index e204e36..7e3a546 100644 +--- a/opcodes/microblaze-dis.c ++++ b/opcodes/microblaze-dis.c +@@ -139,6 +139,12 @@ get_field_special (long instr, struct op_code_struct * op) + case REG_TLBSX_MASK : + strcpy (spr, "tlbsx"); + break; ++ case REG_SHR_MASK : ++ strcpy (spr, "shr"); ++ break; ++ case REG_SLR_MASK : ++ strcpy (spr, "slr"); ++ break; + default : + if (((((instr & IMM_MASK) >> IMM_LOW) ^ op->immval_mask) & 0xE000) + == REG_PVR_MASK) +diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h +index 867263e..a2a42d0 100644 +--- a/opcodes/microblaze-opcm.h ++++ b/opcodes/microblaze-opcm.h +@@ -79,6 +79,8 @@ enum microblaze_instr_type + #define REG_BTR_MASK 0x800b + #define REG_EDR_MASK 0x800d + #define REG_PVR_MASK 0xa000 ++#define REG_SLR_MASK 0x8800 ++#define REG_SHR_MASK 0x8802 + + #define REG_PID_MASK 0x9000 + #define REG_ZPR_MASK 0x9001 +@@ -100,6 +102,8 @@ enum microblaze_instr_type + #define REG_FSR 39 /* FPU Status reg. */ + #define REG_BTR 43 /* Branch Target reg. */ + #define REG_EDR 45 /* Exception reg. */ ++#define REG_SHR 50 /* Stack High reg. */ ++#define REG_SLR 51 /* Stack Low reg. */ + #define REG_PVR 40960 /* Program Verification reg. */ + + #define REG_PID 36864 /* MMU: Process ID reg. */ +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0010-7de425548753461fd2768017d3be677ba2b2a583.patch b/recipes-devtools/binutils/files/0010-7de425548753461fd2768017d3be677ba2b2a583.patch new file mode 100644 index 00000000..fbd3744f --- /dev/null +++ b/recipes-devtools/binutils/files/0010-7de425548753461fd2768017d3be677ba2b2a583.patch @@ -0,0 +1,83 @@ +From 7de425548753461fd2768017d3be677ba2b2a583 Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Wed, 21 Nov 2012 17:54:09 +0000 +Subject: Add swap byte (swapb) and swap halfword (swaph) opcodes. + +binutils/opcodes + * microblaze-opc.h (op_code_struct): Add swapb, swaph Increase MAX_OPCODES. + * microblaze-opcm.h (microblaze_instr): Likewise +binutils/gas/testsuite + * gas/microblaze/allinsn.s: Add swapb, swaph + * gas/microblaze/allinsn.d: Likewise + +Upstream-Status: Backport + +diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d +index 4a03340..b454fdb 100644 +--- a/gas/testsuite/gas/microblaze/allinsn.d ++++ b/gas/testsuite/gas/microblaze/allinsn.d +@@ -41,3 +41,9 @@ Disassembly of section .text: + 30: b0000000 imm 0 + 34: 31600000 addik r11, r0, 0 + 38: 940bc802 mts rshr, r11 ++ ++0000003c : ++ 3c: 900001e0 swapb r0, r0 ++ ++00000040 : ++ 40: 900001e2 swaph r0, r0 +diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s +index 437444f..ffe91ca 100644 +--- a/gas/testsuite/gas/microblaze/allinsn.s ++++ b/gas/testsuite/gas/microblaze/allinsn.s +@@ -46,4 +46,12 @@ regslr: + regshr: + la r11,r0,r0 + mts rshr,r11 ++ .text ++ .global swapb ++swapb: ++ swapb r0,r0 ++ .text ++ .global swaph ++swaph: ++ swaph r0,r0 + +diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h +index 0447fc5..404985b 100644 +--- a/opcodes/microblaze-opc.h ++++ b/opcodes/microblaze-opc.h +@@ -101,7 +101,7 @@ + #define DELAY_SLOT 1 + #define NO_DELAY_SLOT 0 + +-#define MAX_OPCODES 287 ++#define MAX_OPCODES 289 + + struct op_code_struct + { +@@ -402,6 +402,8 @@ struct op_code_struct + {"clz", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900000E0, OPCODE_MASK_H34, clz, special_inst }, + {"mbar", INST_TYPE_IMM5, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8020004, OPCODE_MASK_HN, mbar, special_inst }, + {"sleep", INST_TYPE_NONE, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBA020004, OPCODE_MASK_HN, invalid_inst, special_inst }, /* translates to mbar 16. */ ++ {"swapb", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E0, OPCODE_MASK_H4, swapb, arithmetic_inst }, ++ {"swaph", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E2, OPCODE_MASK_H4, swaph, arithmetic_inst }, + {"", 0, 0, 0, 0, 0, 0, 0, 0}, + }; + +diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h +index a2a42d0..124cdec 100644 +--- a/opcodes/microblaze-opcm.h ++++ b/opcodes/microblaze-opcm.h +@@ -27,7 +27,7 @@ enum microblaze_instr + { + add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, clz, cmp, cmpu, + addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul, +- mulh, mulhu, mulhsu, ++ mulh, mulhu, mulhsu,swapb,swaph, + idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput, + ncget, ncput, muli, bslli, bsrai, bsrli, mului, or, and, xor, + andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16, +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch b/recipes-devtools/binutils/files/0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch new file mode 100644 index 00000000..60205e53 --- /dev/null +++ b/recipes-devtools/binutils/files/0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch @@ -0,0 +1,89 @@ +From 77625f8c77d14a67bc542bb790e6f826c725de4c Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Thu, 29 Nov 2012 21:08:59 +0000 +Subject: opcodes/Changelog: * microblaze-opc.h: Rename + INST_TYPE_RD_R1_SPECIAL to INST_TYPE_R1_R2_SPECIAL * + microblaze-dis.c (print_insn_microblaze): Same. gas/Changelog * + gas/config/tc-microblaze.c: Rename INST_TYPE_RD_R1_SPECIAL to + INST_TYPE_R1_R2_SPECIAL, don't set RD for wic. + +Upstream-Status: Backport + +diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c +index 5a427a0..e9c7846 100644 +--- a/gas/config/tc-microblaze.c ++++ b/gas/config/tc-microblaze.c +@@ -1358,16 +1358,16 @@ md_assemble (char * str) + output = frag_more (isize); + break; + +- case INST_TYPE_RD_R1_SPECIAL: ++ case INST_TYPE_R1_R2_SPECIAL: + if (strcmp (op_end, "")) +- op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ ++ op_end = parse_reg (op_end + 1, ®1); /* Get r1. */ + else + { + as_fatal (_("Error in statement syntax")); + reg1 = 0; + } + if (strcmp (op_end, "")) +- op_end = parse_reg (op_end + 1, ®2); /* Get r1. */ ++ op_end = parse_reg (op_end + 1, ®2); /* Get r2. */ + else + { + as_fatal (_("Error in statement syntax")); +@@ -1381,7 +1381,6 @@ md_assemble (char * str) + as_fatal (_("Cannot use special register with this instruction")); + + /* insn wic ra, rb => wic ra, ra, rb. */ +- inst |= (reg1 << RD_LOW) & RD_MASK; + inst |= (reg1 << RA_LOW) & RA_MASK; + inst |= (reg2 << RB_LOW) & RB_MASK; + +diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c +index 7e3a546..bf028c4 100644 +--- a/opcodes/microblaze-dis.c ++++ b/opcodes/microblaze-dis.c +@@ -383,8 +383,8 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info) + case INST_TYPE_R1: + print_func (stream, "\t%s", get_field_r1 (inst)); + break; +- case INST_TYPE_RD_R1_SPECIAL: +- print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_r2 (inst)); ++ case INST_TYPE_R1_R2_SPECIAL: ++ print_func (stream, "\t%s, %s", get_field_r1 (inst), get_field_r2 (inst)); + break; + case INST_TYPE_RD_IMM15: + print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_imm15 (inst)); +diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h +index 404985b..e9da12a 100644 +--- a/opcodes/microblaze-opc.h ++++ b/opcodes/microblaze-opc.h +@@ -45,7 +45,7 @@ + #define INST_TYPE_R1_RFSL 15 + + /* New insn type for insn cache. */ +-#define INST_TYPE_RD_R1_SPECIAL 16 ++#define INST_TYPE_R1_R2_SPECIAL 16 + + /* New insn type for msrclr, msrset insns. */ + #define INST_TYPE_RD_IMM15 17 +@@ -171,10 +171,10 @@ struct op_code_struct + {"srl", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000041, OPCODE_MASK_H34, srl, logical_inst }, + {"sext8", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000060, OPCODE_MASK_H34, sext8, logical_inst }, + {"sext16",INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000061, OPCODE_MASK_H34, sext16, logical_inst }, +- {"wic", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst }, +- {"wdc", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst }, +- {"wdc.clear", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000066, OPCODE_MASK_H34B, wdcclear, special_inst }, +- {"wdc.flush", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000074, OPCODE_MASK_H34B, wdcflush, special_inst }, ++ {"wic", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst }, ++ {"wdc", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst }, ++ {"wdc.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000066, OPCODE_MASK_H34B, wdcclear, special_inst }, ++ {"wdc.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000074, OPCODE_MASK_H34B, wdcflush, special_inst }, + {"mts", INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9400C000, OPCODE_MASK_H13S, mts, special_inst }, + {"mfs", INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94008000, OPCODE_MASK_H23S, mfs, special_inst }, + {"br", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98000000, OPCODE_MASK_H124, br, branch_inst }, +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch b/recipes-devtools/binutils/files/0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch new file mode 100644 index 00000000..01f5837d --- /dev/null +++ b/recipes-devtools/binutils/files/0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch @@ -0,0 +1,1371 @@ +From b0ea811a61103f378351c9aa2cb16bd3010b0a31 Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Tue, 11 Dec 2012 16:56:50 +0000 +Subject: Microblaze: Add support for handling TLS symbol suffixes and + generating TLS relocs for General Dynamic and Local Dynamic models. + +bfd/Changelog + * reloc.c: Add new relocations + * bfd-in2.h: Regenerated + * libbfd.h: Regenerated + * elf32-microblaze.c (microblaze_elf_howto_raw): + Add TLS relocations + (microblaze_elf_reloc_type_lookup): Likewise + (elf32_mb_link_hash_entry): define TLS reference types + (elf32_mb_link_hash_table): add TLS Local dynamic GOT entry + #define has_tls_reloc if section has TLS relocs + (dtprel_base), (check_unique_offset): New + (microblaze_elf_output_dynamic_relocation): output simple + dynamic relocation into SRELOC. + (microblaze_elf_relocate_section): Accommodate TLS relocations. + (microblaze_elf_check_relocs): Likewise + (update_local_sym_info): New + (microblaze_elf_copy_indirect_symbol): Add tls_mask. + (allocate_dynrelocs): Handle TLS symbol + (microblaze_elf_size_dynamic_sections): Set size and offset + (microblaze_elf_finish_dynamic_symbol): Use + microblaze_elf_output_dynamic_relocation + +gas/Changelog + * config/tc-microblaze.c: Define TLS offsets + (md_relax_table): Add TLS offsets + (imm_types), (match_imm), (get_imm_otype): New to support + TLS offsets. + (tc_microblaze_fix_adjustable): Add TLS relocs. + (md_convert_frag): Support TLS offsets. + (md_apply_fix), (md_estimate_size_before_relax), (tc_gen_reloc): + Add TLS relocs + +include/Changelog + * elf/microblaze.h: Add TLS relocs to START_RELOC_NUMBERS + +Upstream-Status: Backport + +diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h +index bba8757..82537c1 100644 +--- a/bfd/bfd-in2.h ++++ b/bfd/bfd-in2.h +@@ -5071,6 +5071,37 @@ value in a word. The relocation is relative offset from */ + the dynamic object into the runtime process image. */ + BFD_RELOC_MICROBLAZE_COPY, + ++/* Unused Reloc */ ++ BFD_RELOC_MICROBLAZE_64_TLS, ++ ++/* This is a 64 bit reloc that stores the 32 bit GOT relative value ++of the GOT TLS GD info entry in two words (with an imm instruction). The ++relocation is GOT offset. */ ++ BFD_RELOC_MICROBLAZE_64_TLSGD, ++ ++/* This is a 64 bit reloc that stores the 32 bit GOT relative value ++of the GOT TLS LD info entry in two words (with an imm instruction). The ++relocation is GOT offset. */ ++ BFD_RELOC_MICROBLAZE_64_TLSLD, ++ ++/* This is a 32 bit reloc that stores the Module ID to GOT(n). */ ++ BFD_RELOC_MICROBLAZE_32_TLSDTPMOD, ++ ++/* This is a 32 bit reloc that stores TLS offset to GOT(n+1). */ ++ BFD_RELOC_MICROBLAZE_32_TLSDTPREL, ++ ++/* This is a 32 bit reloc for storing TLS offset to two words (uses imm ++instruction) */ ++ BFD_RELOC_MICROBLAZE_64_TLSDTPREL, ++ ++/* This is a 64 bit reloc that stores 32-bit thread pointer relative offset ++to two words (uses imm instruction). */ ++ BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL, ++ ++/* This is a 64 bit reloc that stores 32-bit thread pointer relative offset ++to two words (uses imm instruction). */ ++ BFD_RELOC_MICROBLAZE_64_TLSTPREL, ++ + /* AArch64 ADD immediate instruction, holding bits 0 to 11 of the address. + Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */ + BFD_RELOC_AARCH64_ADD_LO12, +diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c +index be2de13..9d0a7ca 100644 +--- a/bfd/elf32-microblaze.c ++++ b/bfd/elf32-microblaze.c +@@ -370,6 +370,132 @@ static reloc_howto_type microblaze_elf_howto_raw[] = + 0, /* Source Mask. */ + 0x0000ffff, /* Dest Mask. */ + FALSE), /* PC relative offset? */ ++ ++ /* Marker relocs for TLS. */ ++ HOWTO (R_MICROBLAZE_TLS, ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_MICROBLAZE_TLS", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO (R_MICROBLAZE_TLSGD, ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_MICROBLAZE_TLSGD", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO (R_MICROBLAZE_TLSLD, ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_MICROBLAZE_TLSLD", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Computes the load module index of the load module that contains the ++ definition of its TLS sym. */ ++ HOWTO (R_MICROBLAZE_TLSDTPMOD32, ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_MICROBLAZE_TLSDTPMOD32", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Computes a dtv-relative displacement, the difference between the value ++ of sym+add and the base address of the thread-local storage block that ++ contains the definition of sym, minus 0x8000. Used for initializing GOT */ ++ HOWTO (R_MICROBLAZE_TLSDTPREL32, ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_MICROBLAZE_TLSDTPREL32", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Computes a dtv-relative displacement, the difference between the value ++ of sym+add and the base address of the thread-local storage block that ++ contains the definition of sym, minus 0x8000. */ ++ HOWTO (R_MICROBLAZE_TLSDTPREL64, ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_MICROBLAZE_TLSDTPREL64", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Computes a tp-relative displacement, the difference between the value of ++ sym+add and the value of the thread pointer (r13). */ ++ HOWTO (R_MICROBLAZE_TLSGOTTPREL32, ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_MICROBLAZE_TLSGOTTPREL32", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Computes a tp-relative displacement, the difference between the value of ++ sym+add and the value of the thread pointer (r13). */ ++ HOWTO (R_MICROBLAZE_TLSTPREL32, ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont, /* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_MICROBLAZE_TLSTPREL32", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ + }; + + #ifndef NUM_ELEM +@@ -461,6 +587,27 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, + case BFD_RELOC_MICROBLAZE_32_GOTOFF: + microblaze_reloc = R_MICROBLAZE_GOTOFF_32; + break; ++ case BFD_RELOC_MICROBLAZE_64_TLSGD: ++ microblaze_reloc = R_MICROBLAZE_TLSGD; ++ break; ++ case BFD_RELOC_MICROBLAZE_64_TLSLD: ++ microblaze_reloc = R_MICROBLAZE_TLSLD; ++ break; ++ case BFD_RELOC_MICROBLAZE_32_TLSDTPREL: ++ microblaze_reloc = R_MICROBLAZE_TLSDTPREL32; ++ break; ++ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL: ++ microblaze_reloc = R_MICROBLAZE_TLSDTPREL64; ++ break; ++ case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD: ++ microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32; ++ break; ++ case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL: ++ microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32; ++ break; ++ case BFD_RELOC_MICROBLAZE_64_TLSTPREL: ++ microblaze_reloc = R_MICROBLAZE_TLSTPREL32; ++ break; + case BFD_RELOC_MICROBLAZE_COPY: + microblaze_reloc = R_MICROBLAZE_COPY; + break; +@@ -550,8 +697,21 @@ struct elf32_mb_link_hash_entry + /* Track dynamic relocs copied for this symbol. */ + struct elf32_mb_dyn_relocs *dyn_relocs; + ++ /* TLS Reference Types for the symbol; Updated by check_relocs */ ++#define TLS_GD 1 /* GD reloc. */ ++#define TLS_LD 2 /* LD reloc. */ ++#define TLS_TPREL 4 /* TPREL reloc, => IE. */ ++#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */ ++#define TLS_TLS 16 /* Any TLS reloc. */ ++ unsigned char tls_mask; ++ + }; + ++#define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD)) ++#define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD)) ++#define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL)) ++#define IS_TLS_NONE(x) (x == 0) ++ + #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent)) + + /* ELF linker hash table. */ +@@ -571,8 +731,17 @@ struct elf32_mb_link_hash_table + + /* Small local sym to section mapping cache. */ + struct sym_cache sym_sec; ++ ++ /* TLS Local Dynamic GOT Entry */ ++ union { ++ bfd_signed_vma refcount; ++ bfd_vma offset; ++ } tlsld_got; + }; + ++/* Nonzero if this section has TLS related relocations. */ ++#define has_tls_reloc sec_flg0 ++ + /* Get the ELF linker hash table from a link_info structure. */ + + #define elf32_mb_hash_table(p) \ +@@ -604,6 +773,7 @@ link_hash_newfunc (struct bfd_hash_entry *entry, + + eh = (struct elf32_mb_link_hash_entry *) entry; + eh->dyn_relocs = NULL; ++ eh->tls_mask = 0; + } + + return entry; +@@ -654,6 +824,40 @@ microblaze_elf_final_sdp (struct bfd_link_info *info) + + h->u.def.section->output_offset); + } + ++static bfd_vma ++dtprel_base (struct bfd_link_info *info) ++{ ++ /* If tls_sec is NULL, we should have signalled an error already. */ ++ if (elf_hash_table (info)->tls_sec == NULL) ++ return 0; ++ return elf_hash_table (info)->tls_sec->vma; ++} ++ ++/* The size of the thread control block. */ ++#define TCB_SIZE 8 ++ ++/* Output a simple dynamic relocation into SRELOC. */ ++ ++static void ++microblaze_elf_output_dynamic_relocation (bfd *output_bfd, ++ asection *sreloc, ++ unsigned long reloc_index, ++ unsigned long indx, ++ int r_type, ++ bfd_vma offset, ++ bfd_vma addend) ++{ ++ ++ Elf_Internal_Rela rel; ++ ++ rel.r_info = ELF32_R_INFO (indx, r_type); ++ rel.r_offset = offset; ++ rel.r_addend = addend; ++ ++ bfd_elf32_swap_reloca_out (output_bfd, &rel, ++ (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela))); ++} ++ + /* This code is taken from elf32-m32r.c + There is some attempt to make this function usable for many architectures, + both USE_REL and USE_RELA ['twould be nice if such a critter existed], +@@ -707,6 +911,7 @@ microblaze_elf_relocate_section (bfd *output_bfd, + bfd_boolean ret = TRUE; + asection *sreloc; + bfd_vma *local_got_offsets; ++ unsigned int tls_type; + + if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1]) + microblaze_elf_howto_init (); +@@ -738,6 +943,8 @@ microblaze_elf_relocate_section (bfd *output_bfd, + + h = NULL; + r_type = ELF32_R_TYPE (rel->r_info); ++ tls_type = 0; ++ + if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max) + { + (*_bfd_error_handler) (_("%s: unknown relocation type %d"), +@@ -971,70 +1178,182 @@ microblaze_elf_relocate_section (bfd *output_bfd, + break; + } + ++ case (int) R_MICROBLAZE_TLSGD: ++ tls_type = (TLS_TLS | TLS_GD); ++ goto dogot; ++ case (int) R_MICROBLAZE_TLSLD: ++ tls_type = (TLS_TLS | TLS_LD); ++ dogot: + case (int) R_MICROBLAZE_GOT_64: + { ++ bfd_vma *offp; ++ bfd_vma off, off2; ++ unsigned long indx; ++ bfd_vma static_value; ++ ++ bfd_boolean need_relocs = FALSE; + if (htab->sgot == NULL) + abort (); +- if (h == NULL) ++ ++ indx = 0; ++ offp = NULL; ++ ++ /* 1. Identify GOT Offset; ++ 2. Compute Static Values ++ 3. Process Module Id, Process Offset ++ 4. Fixup Relocation with GOT offset value. */ ++ ++ /* 1. Determine GOT Offset to use : TLS_LD, global, local */ ++ if (IS_TLS_LD (tls_type)) ++ offp = &htab->tlsld_got.offset; ++ else if (h != NULL) ++ { ++ if (htab->sgotplt != NULL && h->got.offset != (bfd_vma) -1) ++ offp = &h->got.offset; ++ else ++ abort (); ++ } ++ else + { +- bfd_vma off; + if (local_got_offsets == NULL) + abort (); +- off = local_got_offsets[r_symndx]; +- /* The LSB indicates whether we've already +- created relocation. */ +- if (off & 1) +- off &= ~1; +- else +- { +- bfd_put_32 (output_bfd, relocation + addend, +- htab->sgot->contents + off); ++ offp = &local_got_offsets[r_symndx]; ++ } ++ ++ if (!offp) ++ abort (); ++ ++ off = (*offp) & ~1; ++ off2 = off; ++ ++ if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type)) ++ off2 = off + 4; ++ ++ /* Symbol index to use for relocs */ ++ if (h != NULL) ++ { ++ bfd_boolean dyn = ++ elf_hash_table (info)->dynamic_sections_created; ++ ++ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) ++ && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, h))) ++ indx = h->dynindx; ++ } + +- if (info->shared) ++ /* Need to generate relocs ? */ ++ if ((info->shared || indx != 0) ++ && (h == NULL ++ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT ++ || h->root.type != bfd_link_hash_undefweak)) ++ need_relocs = TRUE; ++ ++ /* 2. Compute/Emit Static value of r-expression */ ++ static_value = relocation + addend; ++ ++ /* 3. Process module-id and offset */ ++ if (! ((*offp) & 1) ) ++ { ++ bfd_vma got_offset; ++ ++ got_offset = (htab->sgot->output_section->vma ++ + htab->sgot->output_offset ++ + off); ++ ++ /* Process module-id */ ++ if (IS_TLS_LD(tls_type)) ++ { ++ if (! info->shared) + { +- Elf_Internal_Rela outrel; +- bfd_byte *loc; +- if (htab->srelgot == NULL) +- abort (); +- outrel.r_offset = (htab->sgot->output_section->vma +- + htab->sgot->output_offset +- + off); +- outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL); +- outrel.r_addend = relocation + addend; +- loc = htab->srelgot->contents; +- loc += htab->srelgot->reloc_count++ +- * sizeof (Elf32_External_Rela); +- bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); ++ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off); ++ } ++ else ++ { ++ microblaze_elf_output_dynamic_relocation (output_bfd, ++ htab->srelgot, htab->srelgot->reloc_count++, ++ /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32, ++ got_offset, 0); + } +- local_got_offsets[r_symndx] |= 1; + } +- relocation = htab->sgot->output_section->vma +- + htab->sgot->output_offset + off +- - htab->sgotplt->output_section->vma +- - htab->sgotplt->output_offset; +- unresolved_reloc = FALSE; +- } +- else +- { +- if (htab->sgotplt != NULL && h != NULL +- && h->got.offset != (bfd_vma) -1) ++ else if (IS_TLS_GD(tls_type)) ++ { ++ if (! need_relocs) ++ { ++ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off); ++ } ++ else ++ { ++ microblaze_elf_output_dynamic_relocation (output_bfd, ++ htab->srelgot, ++ htab->srelgot->reloc_count++, ++ /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32, ++ got_offset, indx ? 0 : static_value); ++ } ++ } ++ ++ /* Process Offset */ ++ if (htab->srelgot == NULL) ++ abort (); ++ ++ got_offset = (htab->sgot->output_section->vma ++ + htab->sgot->output_offset ++ + off2); ++ if (IS_TLS_LD(tls_type)) ++ { ++ /* For LD, offset should be 0 */ ++ *offp |= 1; ++ bfd_put_32 (output_bfd, 0, htab->sgot->contents + off2); ++ } ++ else if (IS_TLS_GD(tls_type)) + { +- bfd_put_32 (output_bfd, relocation + addend, +- htab->sgot->contents + h->got.offset); +- relocation = htab->sgot->output_section->vma +- + htab->sgot->output_offset +- + h->got.offset +- - htab->sgotplt->output_section->vma +- - htab->sgotplt->output_offset; +- unresolved_reloc = FALSE; ++ *offp |= 1; ++ static_value -= dtprel_base(info); ++ if (need_relocs) ++ { ++ microblaze_elf_output_dynamic_relocation (output_bfd, ++ htab->srelgot, htab->srelgot->reloc_count++, ++ /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32, ++ got_offset, indx ? 0 : static_value); ++ } ++ else ++ { ++ bfd_put_32 (output_bfd, static_value, ++ htab->sgot->contents + off2); ++ } + } + else +- abort (); /* ??? */ ++ { ++ bfd_put_32 (output_bfd, static_value, ++ htab->sgot->contents + off2); ++ ++ /* Relocs for dyn symbols generated by ++ finish_dynamic_symbols */ ++ if (info->shared && h == NULL) ++ { ++ *offp |= 1; ++ microblaze_elf_output_dynamic_relocation (output_bfd, ++ htab->srelgot, htab->srelgot->reloc_count++, ++ /* symindex= */ indx, R_MICROBLAZE_REL, ++ got_offset, static_value); ++ } ++ } + } ++ ++ /* 4. Fixup Relocation with GOT offset value ++ Compute relative address of GOT entry for applying ++ the current relocation */ ++ relocation = htab->sgot->output_section->vma ++ + htab->sgot->output_offset ++ + off ++ - htab->sgotplt->output_section->vma ++ - htab->sgotplt->output_offset; ++ ++ /* Apply Current Relocation */ + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, + contents + offset + endian); + bfd_put_16 (input_bfd, relocation & 0xffff, + contents + offset + endian + INST_WORD_SIZE); ++ ++ unresolved_reloc = FALSE; + break; + } + +@@ -1064,6 +1383,14 @@ microblaze_elf_relocate_section (bfd *output_bfd, + break; + } + ++ case (int) R_MICROBLAZE_TLSDTPREL64: ++ relocation += addend; ++ relocation -= dtprel_base(info); ++ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, ++ contents + offset + 2); ++ bfd_put_16 (input_bfd, relocation & 0xffff, ++ contents + offset + 2 + INST_WORD_SIZE); ++ break; + case (int) R_MICROBLAZE_64_PCREL : + case (int) R_MICROBLAZE_64: + case (int) R_MICROBLAZE_32: +@@ -1941,6 +2268,33 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info) + return TRUE; + } + ++static bfd_boolean ++update_local_sym_info (bfd *abfd, ++ Elf_Internal_Shdr *symtab_hdr, ++ unsigned long r_symndx, ++ unsigned int tls_type) ++{ ++ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd); ++ unsigned char *local_got_tls_masks; ++ ++ if (local_got_refcounts == NULL) ++ { ++ bfd_size_type size = symtab_hdr->sh_info; ++ ++ size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks)); ++ local_got_refcounts = bfd_zalloc (abfd, size); ++ if (local_got_refcounts == NULL) ++ return FALSE; ++ elf_local_got_refcounts (abfd) = local_got_refcounts; ++ } ++ ++ local_got_tls_masks = ++ (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info); ++ local_got_tls_masks[r_symndx] |= tls_type; ++ local_got_refcounts[r_symndx] += 1; ++ ++ return TRUE; ++} + /* Look through the relocs for a section during the first phase. */ + + static bfd_boolean +@@ -1977,6 +2331,7 @@ microblaze_elf_check_relocs (bfd * abfd, + unsigned int r_type; + struct elf_link_hash_entry * h; + unsigned long r_symndx; ++ unsigned char tls_type = 0; + + r_symndx = ELF32_R_SYM (rel->r_info); + r_type = ELF32_R_TYPE (rel->r_info); +@@ -2012,6 +2367,13 @@ microblaze_elf_check_relocs (bfd * abfd, + break; + + /* This relocation requires .got entry. */ ++ case R_MICROBLAZE_TLSGD: ++ tls_type |= (TLS_TLS | TLS_GD); ++ goto dogottls; ++ case R_MICROBLAZE_TLSLD: ++ tls_type |= (TLS_TLS | TLS_LD); ++ dogottls: ++ sec->has_tls_reloc = 1; + case R_MICROBLAZE_GOT_64: + if (htab->sgot == NULL) + { +@@ -2023,25 +2385,12 @@ microblaze_elf_check_relocs (bfd * abfd, + if (h != NULL) + { + h->got.refcount += 1; ++ elf32_mb_hash_entry (h)->tls_mask |= tls_type; + } + else + { +- bfd_signed_vma *local_got_refcounts; +- +- /* This is a global offset table entry for a local symbol. */ +- local_got_refcounts = elf_local_got_refcounts (abfd); +- if (local_got_refcounts == NULL) +- { +- bfd_size_type size; +- +- size = symtab_hdr->sh_info; +- size *= sizeof (bfd_signed_vma); +- local_got_refcounts = bfd_zalloc (abfd, size); +- if (local_got_refcounts == NULL) +- return FALSE; +- elf_local_got_refcounts (abfd) = local_got_refcounts; +- } +- local_got_refcounts[r_symndx] += 1; ++ if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) ) ++ return FALSE; + } + break; + +@@ -2105,45 +2454,16 @@ microblaze_elf_check_relocs (bfd * abfd, + + if (sreloc == NULL) + { +- const char *name; + bfd *dynobj; +- unsigned int strndx = elf_elfheader (abfd)->e_shstrndx; +- unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name; +- +- name = bfd_elf_string_from_elf_section (abfd, strndx, shnam); +- if (name == NULL) +- return FALSE; +- +- if (strncmp (name, ".rela", 5) != 0 +- || strcmp (bfd_get_section_name (abfd, sec), +- name + 5) != 0) +- { +- (*_bfd_error_handler) +- (_("%B: bad relocation section name `%s\'"), +- abfd, name); +- } + + if (htab->elf.dynobj == NULL) + htab->elf.dynobj = abfd; + dynobj = htab->elf.dynobj; + +- sreloc = bfd_get_linker_section (dynobj, name); ++ sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj, ++ 2, abfd, 1); + if (sreloc == NULL) +- { +- flagword flags; +- +- flags = (SEC_HAS_CONTENTS | SEC_READONLY +- | SEC_IN_MEMORY | SEC_LINKER_CREATED); +- if ((sec->flags & SEC_ALLOC) != 0) +- flags |= SEC_ALLOC | SEC_LOAD; +- sreloc = bfd_make_section_anyway_with_flags (dynobj, +- name, +- flags); +- if (sreloc == NULL +- || ! bfd_set_section_alignment (dynobj, sreloc, 2)) +- return FALSE; +- } +- elf_section_data (sec)->sreloc = sreloc; ++ return FALSE; + } + + /* If this is a global symbol, we count the number of +@@ -2274,6 +2594,8 @@ microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info, + eind->dyn_relocs = NULL; + } + ++ edir->tls_mask |= eind->tls_mask; ++ + _bfd_elf_link_hash_copy_indirect (info, dir, ind); + } + +@@ -2492,8 +2814,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat) + h->needs_plt = 0; + } + ++ eh = (struct elf32_mb_link_hash_entry *) h; + if (h->got.refcount > 0) + { ++ unsigned int need; + asection *s; + + /* Make sure this symbol is output as a dynamic symbol. +@@ -2505,15 +2829,43 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat) + return FALSE; + } + +- s = htab->sgot; +- h->got.offset = s->size; +- s->size += 4; +- htab->srelgot->size += sizeof (Elf32_External_Rela); ++ need = 0; ++ if ((eh->tls_mask & TLS_TLS) != 0) ++ { ++ /* Handle TLS Symbol */ ++ if ((eh->tls_mask & TLS_LD) != 0) ++ { ++ if (!eh->elf.def_dynamic) ++ /* We'll just use htab->tlsld_got.offset. This should ++ always be the case. It's a little odd if we have ++ a local dynamic reloc against a non-local symbol. */ ++ htab->tlsld_got.refcount += 1; ++ else ++ need += 8; ++ } ++ if ((eh->tls_mask & TLS_GD) != 0) ++ need += 8; ++ } ++ else ++ { ++ /* Regular (non-TLS) symbol */ ++ need += 4; ++ } ++ if (need == 0) ++ { ++ h->got.offset = (bfd_vma) -1; ++ } ++ else ++ { ++ s = htab->sgot; ++ h->got.offset = s->size; ++ s->size += need; ++ htab->srelgot->size += need * (sizeof (Elf32_External_Rela) / 4); ++ } + } + else + h->got.offset = (bfd_vma) -1; + +- eh = (struct elf32_mb_link_hash_entry *) h; + if (eh->dyn_relocs == NULL) + return TRUE; + +@@ -2611,6 +2963,7 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + bfd_signed_vma *end_local_got; + bfd_size_type locsymcount; + Elf_Internal_Shdr *symtab_hdr; ++ unsigned char *lgot_masks; + asection *srel; + + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) +@@ -2650,17 +3003,36 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; + locsymcount = symtab_hdr->sh_info; + end_local_got = local_got + locsymcount; ++ lgot_masks = (unsigned char *) end_local_got; + s = htab->sgot; + srel = htab->srelgot; + +- for (; local_got < end_local_got; ++local_got) +- { +- if (*local_got > 0) +- { +- *local_got = s->size; +- s->size += 4; +- if (info->shared) +- srel->size += sizeof (Elf32_External_Rela); ++ for (; local_got < end_local_got; ++local_got, ++lgot_masks) ++ { ++ if (*local_got > 0) ++ { ++ unsigned int need = 0; ++ if ((*lgot_masks & TLS_TLS) != 0) ++ { ++ if ((*lgot_masks & TLS_GD) != 0) ++ need += 8; ++ if ((*lgot_masks & TLS_LD) != 0) ++ htab->tlsld_got.refcount += 1; ++ } ++ else ++ need += 4; ++ ++ if (need == 0) ++ { ++ *local_got = (bfd_vma) -1; ++ } ++ else ++ { ++ *local_got = s->size; ++ s->size += need; ++ if (info->shared) ++ srel->size += need * (sizeof (Elf32_External_Rela) / 4); ++ } + } + else + *local_got = (bfd_vma) -1; +@@ -2671,6 +3043,16 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + sym dynamic relocs. */ + elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info); + ++ if (htab->tlsld_got.refcount > 0) ++ { ++ htab->tlsld_got.offset = htab->sgot->size; ++ htab->sgot->size += 8; ++ if (info->shared) ++ htab->srelgot->size += sizeof (Elf32_External_Rela); ++ } ++ else ++ htab->tlsld_got.offset = (bfd_vma) -1; ++ + if (elf_hash_table (info)->dynamic_sections_created) + { + /* Make space for the trailing nop in .plt. */ +@@ -2789,6 +3171,7 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd, + Elf_Internal_Sym *sym) + { + struct elf32_mb_link_hash_table *htab; ++ struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h); + + htab = elf32_mb_hash_table (info); + if (htab == NULL) +@@ -2860,12 +3243,14 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd, + } + } + +- if (h->got.offset != (bfd_vma) -1) ++ /* h->got.refcount to be checked ? */ ++ if (h->got.offset != (bfd_vma) -1 && ++ ! ((h->got.offset & 1) || ++ IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask))) + { + asection *sgot; + asection *srela; +- Elf_Internal_Rela rela; +- bfd_byte *loc; ++ bfd_vma offset; + + /* This symbol has an entry in the global offset table. Set it + up. */ +@@ -2874,8 +3259,7 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd, + srela = htab->srelgot; + BFD_ASSERT (sgot != NULL && srela != NULL); + +- rela.r_offset = (sgot->output_section->vma +- + sgot->output_offset ++ offset = (sgot->output_section->vma + sgot->output_offset + + (h->got.offset &~ (bfd_vma) 1)); + + /* If this is a -Bsymbolic link, and the symbol is defined +@@ -2888,22 +3272,25 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd, + && h->def_regular) + { + asection *sec = h->root.u.def.section; +- rela.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL); +- rela.r_addend = (h->root.u.def.value +- + sec->output_section->vma +- + sec->output_offset); ++ microblaze_elf_output_dynamic_relocation (output_bfd, ++ srela, srela->reloc_count++, ++ /* symindex= */ 0, ++ R_MICROBLAZE_REL, offset, ++ h->root.u.def.value ++ + sec->output_section->vma ++ + sec->output_offset); + } + else + { +- rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_GLOB_DAT); +- rela.r_addend = 0; ++ microblaze_elf_output_dynamic_relocation (output_bfd, ++ srela, srela->reloc_count++, ++ h->dynindx, ++ R_MICROBLAZE_GLOB_DAT, ++ offset, 0); + } + + bfd_put_32 (output_bfd, (bfd_vma) 0, + sgot->contents + (h->got.offset &~ (bfd_vma) 1)); +- loc = srela->contents; +- loc += srela->reloc_count++ * sizeof (Elf32_External_Rela); +- bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); + } + + if (h->needs_copy) +@@ -3073,7 +3460,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd, + #define ELF_TARGET_ID MICROBLAZE_ELF_DATA + #define ELF_MACHINE_CODE EM_MICROBLAZE + #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD +-#define ELF_MAXPAGESIZE 0x4 /* 4k, if we ever have 'em. */ ++#define ELF_MAXPAGESIZE 0x1000 + #define elf_info_to_howto microblaze_elf_info_to_howto + #define elf_info_to_howto_rel NULL + +diff --git a/bfd/libbfd.h b/bfd/libbfd.h +index 0458e39..362e35f 100644 +--- a/bfd/libbfd.h ++++ b/bfd/libbfd.h +@@ -2420,6 +2420,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", + "BFD_RELOC_MICROBLAZE_64_GOTOFF", + "BFD_RELOC_MICROBLAZE_32_GOTOFF", + "BFD_RELOC_MICROBLAZE_COPY", ++ "BFD_RELOC_MICROBLAZE_64_TLS", ++ "BFD_RELOC_MICROBLAZE_64_TLSGD", ++ "BFD_RELOC_MICROBLAZE_64_TLSLD", ++ "BFD_RELOC_MICROBLAZE_32_TLSDTPMOD", ++ "BFD_RELOC_MICROBLAZE_32_TLSDTPREL", ++ "BFD_RELOC_MICROBLAZE_64_TLSDTPREL", ++ "BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL", ++ "BFD_RELOC_MICROBLAZE_64_TLSTPREL", + "BFD_RELOC_AARCH64_ADD_LO12", + "BFD_RELOC_AARCH64_GOT_LD_PREL19", + "BFD_RELOC_AARCH64_ADR_GOT_PAGE", +diff --git a/bfd/reloc.c b/bfd/reloc.c +index e097887..3f88049 100644 +--- a/bfd/reloc.c ++++ b/bfd/reloc.c +@@ -5882,6 +5882,45 @@ ENUM + ENUMDOC + This is used to tell the dynamic linker to copy the value out of + the dynamic object into the runtime process image. ++ENUM ++ BFD_RELOC_MICROBLAZE_64_TLS ++ENUMDOC ++ Unused Reloc ++ENUM ++ BFD_RELOC_MICROBLAZE_64_TLSGD ++ENUMDOC ++ This is a 64 bit reloc that stores the 32 bit GOT relative value ++ of the GOT TLS GD info entry in two words (with an imm instruction). The ++ relocation is GOT offset. ++ENUM ++ BFD_RELOC_MICROBLAZE_64_TLSLD ++ENUMDOC ++ This is a 64 bit reloc that stores the 32 bit GOT relative value ++ of the GOT TLS LD info entry in two words (with an imm instruction). The ++ relocation is GOT offset. ++ENUM ++ BFD_RELOC_MICROBLAZE_32_TLSDTPMOD ++ENUMDOC ++ This is a 32 bit reloc that stores the Module ID to GOT(n). ++ENUM ++ BFD_RELOC_MICROBLAZE_32_TLSDTPREL ++ENUMDOC ++ This is a 32 bit reloc that stores TLS offset to GOT(n+1). ++ENUM ++ BFD_RELOC_MICROBLAZE_64_TLSDTPREL ++ENUMDOC ++ This is a 32 bit reloc for storing TLS offset to two words (uses imm ++ instruction) ++ENUM ++ BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL ++ENUMDOC ++ This is a 64 bit reloc that stores 32-bit thread pointer relative offset ++ to two words (uses imm instruction). ++ENUM ++ BFD_RELOC_MICROBLAZE_64_TLSTPREL ++ENUMDOC ++ This is a 64 bit reloc that stores 32-bit thread pointer relative offset ++ to two words (uses imm instruction). + + ENUM + BFD_RELOC_AARCH64_ADD_LO12 +diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c +index e9c7846..872737b 100644 +--- a/gas/config/tc-microblaze.c ++++ b/gas/config/tc-microblaze.c +@@ -81,7 +81,12 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP"; + #define GOT_OFFSET 8 + #define PLT_OFFSET 9 + #define GOTOFF_OFFSET 10 +- ++#define TLSGD_OFFSET 11 ++#define TLSLD_OFFSET 12 ++#define TLSDTPMOD_OFFSET 13 ++#define TLSDTPREL_OFFSET 14 ++#define TLSGOTTPREL_OFFSET 15 ++#define TLSTPREL_OFFSET 16 + + /* Initialize the relax table. */ + const relax_typeS md_relax_table[] = +@@ -97,6 +102,12 @@ const relax_typeS md_relax_table[] = + { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 8: GOT_OFFSET. */ + { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 9: PLT_OFFSET. */ + { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 10: GOTOFF_OFFSET. */ ++ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 11: TLSGD_OFFSET. */ ++ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 12: TLSLD_OFFSET. */ ++ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */ ++ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 14: TLSDTPREL_OFFSET. */ ++ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */ ++ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */ + }; + + static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */ +@@ -599,9 +610,75 @@ parse_exp (char *s, expressionS *e) + } + + /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */ ++#define IMM_NONE 0 + #define IMM_GOT 1 + #define IMM_PLT 2 + #define IMM_GOTOFF 3 ++#define IMM_TLSGD 4 ++#define IMM_TLSLD 5 ++#define IMM_TLSDTPMOD 6 ++#define IMM_TLSDTPREL 7 ++#define IMM_TLSTPREL 8 ++#define IMM_MAX 9 ++ ++struct imm_type { ++ char *isuffix; /* Suffix String */ ++ int itype; /* Suffix Type */ ++ int otype; /* Offset Type */ ++}; ++ ++/* These are NOT in assending order of type, GOTOFF is ahead to make ++ sure @GOTOFF does not get matched with @GOT */ ++static struct imm_type imm_types[] = { ++ { "NONE", IMM_NONE , 0 }, ++ { "GOTOFF", IMM_GOTOFF , GOTOFF_OFFSET }, ++ { "GOT", IMM_GOT , GOT_OFFSET }, ++ { "PLT", IMM_PLT , PLT_OFFSET }, ++ { "TLSGD", IMM_TLSGD , TLSGD_OFFSET }, ++ { "TLSLDM", IMM_TLSLD, TLSLD_OFFSET }, ++ { "TLSDTPMOD", IMM_TLSDTPMOD, TLSDTPMOD_OFFSET }, ++ { "TLSDTPREL", IMM_TLSDTPREL, TLSDTPREL_OFFSET }, ++ { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET } ++}; ++ ++static int ++match_imm (const char *s, int *ilen) ++{ ++ int i; ++ int slen; ++ ++ /* Check for matching suffix */ ++ for (i = 1; i < IMM_MAX; i++) ++ { ++ slen = strlen (imm_types[i].isuffix); ++ ++ if (strncmp (imm_types[i].isuffix, s, slen) == 0) ++ { ++ *ilen = slen; ++ return imm_types[i].itype; ++ } ++ } /* for */ ++ *ilen = 0; ++ return 0; ++} ++ ++static int ++get_imm_otype (int itype) ++{ ++ int i, otype; ++ ++ otype = 0; ++ /* Check for matching itype */ ++ for (i = 1; i < IMM_MAX; i++) ++ { ++ if (imm_types[i].itype == itype) ++ { ++ otype = imm_types[i].otype; ++ break; ++ } ++ } ++ return otype; ++} + + static symbolS * GOT_symbol; + +@@ -612,6 +689,9 @@ parse_imm (char * s, expressionS * e, int min, int max) + { + char *new_pointer; + char *atp; ++ int itype, ilen; ++ ++ ilen = 0; + + /* Find the start of "@GOT" or "@PLT" suffix (if any) */ + for (atp = s; *atp != '@'; atp++) +@@ -620,26 +700,18 @@ parse_imm (char * s, expressionS * e, int min, int max) + + if (*atp == '@') + { +- if (strncmp (atp + 1, "GOTOFF", 5) == 0) +- { +- *atp = 0; +- e->X_md = IMM_GOTOFF; +- } +- else if (strncmp (atp + 1, "GOT", 3) == 0) +- { +- *atp = 0; +- e->X_md = IMM_GOT; +- } +- else if (strncmp (atp + 1, "PLT", 3) == 0) +- { +- *atp = 0; +- e->X_md = IMM_PLT; +- } ++ itype = match_imm (atp + 1, &ilen); ++ if (itype != 0) ++ { ++ *atp = 0; ++ e->X_md = itype; ++ } + else +- { +- atp = NULL; +- e->X_md = 0; +- } ++ { ++ atp = NULL; ++ e->X_md = 0; ++ ilen = 0; ++ } + *atp = 0; + } + else +@@ -655,6 +727,11 @@ parse_imm (char * s, expressionS * e, int min, int max) + + new_pointer = parse_exp (s, e); + ++ if (!GOT_symbol && ! strncmp (s, GOT_SYMBOL_NAME, 20)) ++ { ++ GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME); ++ } ++ + if (e->X_op == O_absent) + ; /* An error message has already been emitted. */ + else if ((e->X_op != O_constant && e->X_op != O_symbol) ) +@@ -670,9 +747,7 @@ parse_imm (char * s, expressionS * e, int min, int max) + { + *atp = '@'; /* restore back (needed?) */ + if (new_pointer >= atp) +- new_pointer += (e->X_md == IMM_GOTOFF)?7:4; +- /* sizeof("@GOTOFF", "@GOT" or "@PLT") */ +- ++ new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */ + } + return new_pointer; + } +@@ -792,7 +867,14 @@ tc_microblaze_fix_adjustable (struct fix *fixP) + if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF + || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF + || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT +- || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT) ++ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT ++ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGD ++ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSLD ++ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPMOD ++ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPREL ++ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSDTPREL ++ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL ++ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSTPREL) + return 0; + + return 1; +@@ -940,12 +1022,8 @@ md_assemble (char * str) + opc = str_microblaze_rw_anchor; + else + opc = NULL; +- if (exp.X_md == IMM_GOT) +- subtype = GOT_OFFSET; +- else if (exp.X_md == IMM_PLT) +- subtype = PLT_OFFSET; +- else if (exp.X_md == IMM_GOTOFF) +- subtype = GOTOFF_OFFSET; ++ if (exp.X_md != 0) ++ subtype = get_imm_otype(exp.X_md); + else + subtype = opcode->inst_offset_type; + +@@ -1436,12 +1514,11 @@ md_assemble (char * str) + char *opc = NULL; + relax_substateT subtype; + +- if (exp.X_md == IMM_GOT) +- subtype = GOT_OFFSET; +- else if (exp.X_md == IMM_PLT) +- subtype = PLT_OFFSET; ++ if (exp.X_md != 0) ++ subtype = get_imm_otype(exp.X_md); + else + subtype = opcode->inst_offset_type; ++ + output = frag_var (rs_machine_dependent, + isize * 2, /* maxm of 2 words. */ + isize, /* minm of 1 word. */ +@@ -1503,12 +1580,11 @@ md_assemble (char * str) + char *opc = NULL; + relax_substateT subtype; + +- if (exp.X_md == IMM_GOT) +- subtype = GOT_OFFSET; +- else if (exp.X_md == IMM_PLT) +- subtype = PLT_OFFSET; +- else ++ if (exp.X_md != 0) ++ subtype = get_imm_otype(exp.X_md); ++ else + subtype = opcode->inst_offset_type; ++ + output = frag_var (rs_machine_dependent, + isize * 2, /* maxm of 2 words. */ + isize, /* minm of 1 word. */ +@@ -1576,12 +1652,11 @@ md_assemble (char * str) + char *opc = NULL; + relax_substateT subtype; + +- if (exp.X_md == IMM_GOT) +- subtype = GOT_OFFSET; +- else if (exp.X_md == IMM_PLT) +- subtype = PLT_OFFSET; +- else +- subtype = opcode->inst_offset_type; ++ if (exp.X_md != 0) ++ subtype = get_imm_otype(exp.X_md); ++ else ++ subtype = opcode->inst_offset_type; ++ + output = frag_var (rs_machine_dependent, + isize * 2, /* maxm of 2 words. */ + isize, /* minm of 1 word. */ +@@ -1847,6 +1922,24 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, + fragP->fr_fix += INST_WORD_SIZE * 2; + fragP->fr_var = 0; + break; ++ case TLSGD_OFFSET: ++ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, ++ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSGD); ++ fragP->fr_fix += INST_WORD_SIZE * 2; ++ fragP->fr_var = 0; ++ break; ++ case TLSLD_OFFSET: ++ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, ++ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSLD); ++ fragP->fr_fix += INST_WORD_SIZE * 2; ++ fragP->fr_var = 0; ++ break; ++ case TLSDTPREL_OFFSET: ++ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, ++ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSDTPREL); ++ fragP->fr_fix += INST_WORD_SIZE * 2; ++ fragP->fr_var = 0; ++ break; + + default: + abort (); +@@ -2028,6 +2121,11 @@ md_apply_fix (fixS * fixP, + } + break; + ++ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL: ++ case BFD_RELOC_MICROBLAZE_64_TLSGD: ++ case BFD_RELOC_MICROBLAZE_64_TLSLD: ++ S_SET_THREAD_LOCAL (fixP->fx_addsy); ++ + case BFD_RELOC_MICROBLAZE_64_GOTPC: + case BFD_RELOC_MICROBLAZE_64_GOT: + case BFD_RELOC_MICROBLAZE_64_PLT: +@@ -2206,11 +2304,16 @@ md_estimate_size_before_relax (fragS * fragP, + case GOT_OFFSET: + case PLT_OFFSET: + case GOTOFF_OFFSET: ++ case TLSGD_OFFSET: ++ case TLSLD_OFFSET: ++ case TLSTPREL_OFFSET: ++ case TLSDTPREL_OFFSET: + fragP->fr_var = INST_WORD_SIZE*2; + break; + case DEFINED_RO_SEGMENT: + case DEFINED_RW_SEGMENT: + case DEFINED_PC_OFFSET: ++ case TLSDTPMOD_OFFSET: + fragP->fr_var = INST_WORD_SIZE; + break; + default: +@@ -2294,6 +2397,13 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp) + case BFD_RELOC_MICROBLAZE_64_PLT: + case BFD_RELOC_MICROBLAZE_64_GOTOFF: + case BFD_RELOC_MICROBLAZE_32_GOTOFF: ++ case BFD_RELOC_MICROBLAZE_64_TLSGD: ++ case BFD_RELOC_MICROBLAZE_64_TLSLD: ++ case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD: ++ case BFD_RELOC_MICROBLAZE_32_TLSDTPREL: ++ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL: ++ case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL: ++ case BFD_RELOC_MICROBLAZE_64_TLSTPREL: + code = fixp->fx_r_type; + break; + +diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h +index d392231..c4d9821 100644 +--- a/include/elf/microblaze.h ++++ b/include/elf/microblaze.h +@@ -50,6 +50,14 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type) + RELOC_NUMBER (R_MICROBLAZE_GOTOFF_64, 19) /* Offset relative to GOT. */ + RELOC_NUMBER (R_MICROBLAZE_GOTOFF_32, 20) /* Offset relative to GOT. */ + RELOC_NUMBER (R_MICROBLAZE_COPY, 21) /* Runtime copy. */ ++ RELOC_NUMBER (R_MICROBLAZE_TLS, 22) /* TLS Reloc */ ++ RELOC_NUMBER (R_MICROBLAZE_TLSGD, 23) /* TLS General Dynamic */ ++ RELOC_NUMBER (R_MICROBLAZE_TLSLD, 24) /* TLS Local Dynamic */ ++ RELOC_NUMBER (R_MICROBLAZE_TLSDTPMOD32, 25) /* TLS Module ID */ ++ RELOC_NUMBER (R_MICROBLAZE_TLSDTPREL32, 26) /* TLS Offset Within TLS Block */ ++ RELOC_NUMBER (R_MICROBLAZE_TLSDTPREL64, 27) /* TLS Offset Within TLS Block */ ++ RELOC_NUMBER (R_MICROBLAZE_TLSGOTTPREL32, 28) /* TLS Offset From Thread Pointer */ ++ RELOC_NUMBER (R_MICROBLAZE_TLSTPREL32, 29) /* TLS Offset From Thread Pointer */ + + END_RELOC_NUMBERS (R_MICROBLAZE_max) + +-- +1.7.5.4 + diff --git a/recipes-devtools/binutils/files/0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch b/recipes-devtools/binutils/files/0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch new file mode 100644 index 00000000..a2154785 --- /dev/null +++ b/recipes-devtools/binutils/files/0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch @@ -0,0 +1,310 @@ +From 19e05575d97b6dc83dae1b8309624da3102d7a74 Mon Sep 17 00:00:00 2001 +From: Michael Eager +Date: Tue, 18 Dec 2012 16:01:00 +0000 +Subject: PR ld/14736 bfd: * elf32-microblaze.c (calc_fixup): Add end + range. gas/testsuite: * gas/microblaze/relax_size.exp: New file - + test object size after linker relaxation * + gas/microblaze/relax_size.s: Likewise * + gas/microblaze/relax_size.elf: Likewise * + gas/microblaze/relax_size2.s: Likewise * + gas/microblaze/relax_size2.elf: Likewise + +Upstream-Status: Backport + +diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c +index 9d0a7ca..8aafe72 100644 +--- a/bfd/elf32-microblaze.c ++++ b/bfd/elf32-microblaze.c +@@ -1600,8 +1600,9 @@ microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) + /* Calculate fixup value for reference. */ + + static int +-calc_fixup (bfd_vma addr, asection *sec) ++calc_fixup (bfd_vma start, bfd_vma size, asection *sec) + { ++ bfd_vma end = start + size; + int i, fixup = 0; + + if (sec == NULL || sec->relax == NULL) +@@ -1610,11 +1611,12 @@ calc_fixup (bfd_vma addr, asection *sec) + /* Look for addr in relax table, total fixup value. */ + for (i = 0; i < sec->relax_count; i++) + { +- if (addr <= sec->relax[i].addr) ++ if (end <= sec->relax[i].addr) + break; ++ if ((end != start) && (start > sec->relax[i].addr)) ++ continue; + fixup += sec->relax[i].size; + } +- + return fixup; + } + +@@ -1827,7 +1829,7 @@ microblaze_elf_relax_section (bfd *abfd, + bfd_vma nraddr; + + /* Get the new reloc address. */ +- nraddr = irel->r_offset - calc_fixup (irel->r_offset, sec); ++ nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec); + switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info)) + { + default: +@@ -1845,7 +1847,7 @@ microblaze_elf_relax_section (bfd *abfd, + /* Only handle relocs against .text. */ + if (isym->st_shndx == shndx + && ELF32_ST_TYPE (isym->st_info) == STT_SECTION) +- irel->r_addend -= calc_fixup (irel->r_addend, sec); ++ irel->r_addend -= calc_fixup (irel->r_addend, 0, sec); + } + break; + case R_MICROBLAZE_NONE: +@@ -1855,8 +1857,8 @@ microblaze_elf_relax_section (bfd *abfd, + int sfix, efix; + bfd_vma target_address; + target_address = irel->r_addend + irel->r_offset; +- sfix = calc_fixup (irel->r_offset, sec); +- efix = calc_fixup (target_address, sec); ++ sfix = calc_fixup (irel->r_offset, 0, sec); ++ efix = calc_fixup (target_address, 0, sec); + irel->r_addend -= (efix - sfix); + /* Should use HOWTO. */ + microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset, +@@ -1870,8 +1872,8 @@ microblaze_elf_relax_section (bfd *abfd, + int sfix, efix; + bfd_vma target_address; + target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE; +- sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, sec); +- efix = calc_fixup (target_address, sec); ++ sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec); ++ efix = calc_fixup (target_address, 0, sec); + irel->r_addend -= (efix - sfix); + microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset + + INST_WORD_SIZE, irel->r_addend); +@@ -1934,7 +1936,7 @@ microblaze_elf_relax_section (bfd *abfd, + } + + } +- irelscan->r_addend -= calc_fixup (irelscan->r_addend, sec); ++ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec); + } + else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM) + { +@@ -1965,6 +1967,7 @@ microblaze_elf_relax_section (bfd *abfd, + } + irelscan->r_addend -= calc_fixup (irel->r_addend + + isym->st_value, ++ 0, + sec); + } + } +@@ -2005,7 +2008,7 @@ microblaze_elf_relax_section (bfd *abfd, + unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset); + immediate = instr & 0x0000ffff; + target_address = immediate; +- offset = calc_fixup (target_address, sec); ++ offset = calc_fixup (target_address, 0, sec); + immediate -= offset; + irelscan->r_addend -= offset; + microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset, +@@ -2052,7 +2055,7 @@ microblaze_elf_relax_section (bfd *abfd, + + INST_WORD_SIZE); + immediate = (instr_hi & 0x0000ffff) << 16; + immediate |= (instr_lo & 0x0000ffff); +- offset = calc_fixup (irelscan->r_addend, sec); ++ offset = calc_fixup (irelscan->r_addend, 0, sec); + immediate -= offset; + irelscan->r_addend -= offset; + } +@@ -2097,7 +2100,7 @@ microblaze_elf_relax_section (bfd *abfd, + immediate = (instr_hi & 0x0000ffff) << 16; + immediate |= (instr_lo & 0x0000ffff); + target_address = immediate; +- offset = calc_fixup (target_address, sec); ++ offset = calc_fixup (target_address, 0, sec); + immediate -= offset; + irelscan->r_addend -= offset; + microblaze_bfd_write_imm_value_64 (abfd, ocontents +@@ -2112,24 +2115,30 @@ microblaze_elf_relax_section (bfd *abfd, + for (isym = isymbuf; isym < isymend; isym++) + { + if (isym->st_shndx == shndx) +- isym->st_value =- calc_fixup (isym->st_value, sec); ++ { ++ isym->st_value -= calc_fixup (isym->st_value, 0, sec); ++ if (isym->st_size) ++ isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec); ++ } + } + + /* Now adjust the global symbols defined in this section. */ + isym = isymbuf + symtab_hdr->sh_info; +- isymend = isymbuf + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)); +- for (sym_index = 0; isym < isymend; isym++, sym_index++) ++ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info; ++ for (sym_index = 0; sym_index < symcount; sym_index++) + { + sym_hash = elf_sym_hashes (abfd)[sym_index]; +- if (isym->st_shndx == shndx +- && (sym_hash->root.type == bfd_link_hash_defined ++ if ((sym_hash->root.type == bfd_link_hash_defined + || sym_hash->root.type == bfd_link_hash_defweak) + && sym_hash->root.u.def.section == sec) +- { +- sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value, +- sec); +- } +- } ++ { ++ sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value, ++ 0, sec); ++ if (sym_hash->size) ++ sym_hash->size -= calc_fixup (sym_hash->root.u.def.value, ++ sym_hash->size, sec); ++ } ++ } + + /* Physically move the code and change the cooked size. */ + dest = sec->relax[0].addr; +diff --git a/gas/testsuite/gas/microblaze/relax_size.elf b/gas/testsuite/gas/microblaze/relax_size.elf +new file mode 100644 +index 0000000..cf23ea6 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/relax_size.elf +@@ -0,0 +1,32 @@ ++ ++Symbol table '.symtab' contains 29 entries: ++ Num: Value Size Type Bind Vis Ndx Name ++ 0: 00000000 0 NOTYPE LOCAL DEFAULT UND ++ 1: 00000050 0 SECTION LOCAL DEFAULT 1 ++ 2: 00000058 0 SECTION LOCAL DEFAULT 2 ++ 3: 00000000 0 FILE LOCAL DEFAULT ABS relax_size.o ++ 4: 00000050 8 NOTYPE LOCAL DEFAULT 1 func ++ 5: 00000058 0 NOTYPE LOCAL DEFAULT 1 label ++ 6: 00000000 0 FILE LOCAL DEFAULT ABS ++ 7: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _fdata ++ 8: 00000058 0 NOTYPE GLOBAL DEFAULT 1 _etext ++ 9: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _essrw ++ 10: 00000058 0 NOTYPE GLOBAL DEFAULT 1 _heap_end ++ 11: 00000058 0 NOTYPE GLOBAL DEFAULT 1 _heap_start ++ 12: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _ssro_size ++ 13: 00000050 0 NOTYPE GLOBAL DEFAULT 1 _ftext ++ 14: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _essro ++ 15: 00000400 0 NOTYPE GLOBAL DEFAULT ABS _STACK_SIZE ++ 16: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _HEAP_SIZE ++ 17: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _ssrw_size ++ 18: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _stack_end ++ 19: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _edata ++ 20: 00000458 0 NOTYPE GLOBAL DEFAULT 2 _end ++ 21: 00000058 0 NOTYPE GLOBAL DEFAULT 1 _heap ++ 22: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _ssro ++ 23: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _ssrw ++ 24: 00000458 0 NOTYPE GLOBAL DEFAULT 2 _stack ++ 25: 00000050 0 NOTYPE GLOBAL DEFAULT ABS _TEXT_START_ADDR ++ 26: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _frodata ++ 27: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _fbss ++ 28: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _erodata +diff --git a/gas/testsuite/gas/microblaze/relax_size.exp b/gas/testsuite/gas/microblaze/relax_size.exp +new file mode 100644 +index 0000000..a733dc8 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/relax_size.exp +@@ -0,0 +1,25 @@ ++ ++proc ld_run { objects ldflags dest test } { ++ set ld_output [target_link $objects $dest $ldflags] ++} ++ ++proc readelf_run { exec flags dest test } { ++ set readelf [find_binutils_prog readelf] ++ verbose -log "$readelf $flags $exec > $dest" ++ catch "exec $readelf $flags $exec > $dest" readelf_output ++} ++ ++proc regexp_test { file1 file2 test } { ++ if [regexp_diff $file1 $file2] then { fail $test } else { pass $test } ++} ++ ++global srcdir subdir ++if [istarget microblaze*-*-elf] { ++ foreach file [lsort [glob -nocomplain -- $srcdir/$subdir/relax_size*.s]] { ++ set file [file rootname [file tail $file]] ++ gas_run "$file.s" "-o $file.o" "" ++ ld_run "$file.o" "-e 0 -N -relax" "$file.x" "linking $file.x" ++ readelf_run "$file.x" "-s" "$file.elf" "readelf -s $file.x" ++ regexp_test "$file.elf" "$srcdir/$subdir/$file.elf" "matching $file.elf" ++ } ++} +diff --git a/gas/testsuite/gas/microblaze/relax_size.s b/gas/testsuite/gas/microblaze/relax_size.s +new file mode 100644 +index 0000000..6b25977 +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/relax_size.s +@@ -0,0 +1,7 @@ ++ .org 0 ++ .section .text ++func: ++ braid label ++ nop ++label: ++ .size func, . - func +diff --git a/gas/testsuite/gas/microblaze/relax_size2.elf b/gas/testsuite/gas/microblaze/relax_size2.elf +new file mode 100644 +index 0000000..fbdcc0a +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/relax_size2.elf +@@ -0,0 +1,34 @@ ++ ++Symbol table '.symtab' contains 31 entries: ++ Num: Value Size Type Bind Vis Ndx Name ++ 0: 00000000 0 NOTYPE LOCAL DEFAULT UND ++ 1: 00000050 0 SECTION LOCAL DEFAULT 1 ++ 2: 00000060 0 SECTION LOCAL DEFAULT 2 ++ 3: 00000000 0 FILE LOCAL DEFAULT ABS relax_size2.o ++ 4: 00000050 4 NOTYPE LOCAL DEFAULT 1 func ++ 5: 00000054 0 NOTYPE LOCAL DEFAULT 1 label ++ 6: 00000054 8 NOTYPE LOCAL DEFAULT 1 func2 ++ 7: 0000005c 0 NOTYPE LOCAL DEFAULT 1 label2 ++ 8: 00000000 0 FILE LOCAL DEFAULT ABS ++ 9: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _fdata ++ 10: 0000005c 0 NOTYPE GLOBAL DEFAULT 1 _etext ++ 11: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _essrw ++ 12: 00000060 0 NOTYPE GLOBAL DEFAULT 1 _heap_end ++ 13: 00000060 0 NOTYPE GLOBAL DEFAULT 1 _heap_start ++ 14: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _ssro_size ++ 15: 00000050 0 NOTYPE GLOBAL DEFAULT 1 _ftext ++ 16: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _essro ++ 17: 00000400 0 NOTYPE GLOBAL DEFAULT ABS _STACK_SIZE ++ 18: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _HEAP_SIZE ++ 19: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _ssrw_size ++ 20: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _stack_end ++ 21: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _edata ++ 22: 00000460 0 NOTYPE GLOBAL DEFAULT 2 _end ++ 23: 00000060 0 NOTYPE GLOBAL DEFAULT 1 _heap ++ 24: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _ssro ++ 25: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _ssrw ++ 26: 00000460 0 NOTYPE GLOBAL DEFAULT 2 _stack ++ 27: 00000050 0 NOTYPE GLOBAL DEFAULT ABS _TEXT_START_ADDR ++ 28: 0000005c 0 NOTYPE GLOBAL DEFAULT 2 _frodata ++ 29: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _fbss ++ 30: 0000005c 0 NOTYPE GLOBAL DEFAULT 2 _erodata +diff --git a/gas/testsuite/gas/microblaze/relax_size2.s b/gas/testsuite/gas/microblaze/relax_size2.s +new file mode 100644 +index 0000000..dedabfb +--- /dev/null ++++ b/gas/testsuite/gas/microblaze/relax_size2.s +@@ -0,0 +1,11 @@ ++ .org 0 ++ .section .text ++func: ++ nop ++label: ++ .size func, . - func ++func2: ++ braid label2 ++ nop ++label2: ++ .size func2, . - func2 +-- +1.7.5.4 + -- cgit v1.2.3-54-g00ecf