aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils%.bbappend45
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0001-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch (renamed from meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0001-MicroBlaze-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch)14
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0002-Add-mlittle-endian-and-mbig-endian-flags.patch (renamed from meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0002-MicroBlaze-add-mlittle-endian-and-mbig-endian-flags.patch)22
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0003-Disable-the-warning-message-for-eh_frame_hdr.patch47
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0004-Fix-relaxation-of-assembler-resolved-references.patch33
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0005-LOCAL-Fixup-debug_loc-sections-after-linker-relaxati.patch (renamed from meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0005-Fixup-MicroBlaze-debug_loc-sections-after-linker-rel.patch)166
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0006-upstream-change-to-garbage-collection-sweep-causes-m.patch40
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0007-Fix-bug-in-TLSTPREL-Relocation.patch (renamed from meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0006-Fix-bug-in-MicroBlaze-TLSTPREL-Relocation.patch)16
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0008-Added-Address-extension-instructions.patch (renamed from meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0007-Add-MicroBlaze-address-extension-instructions.patch)40
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0009-fixing-the-MAX_OPCODES-to-correct-value.patch26
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0010-Add-new-bit-field-instructions.patch (renamed from meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0008-Add-new-MicroBlaze-bit-field-instructions.patch)48
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0011-fixing-the-imm-bug.patch (renamed from meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0009-Fixing-MicroBlaze-IMM-bug.patch)21
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0012-MicroBlaze-fix-mask-for-barrel-shift-instructions.patch36
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0012-Patch-Microblaze-fixed-bug-in-GCC-so-that-It-will-su.patch (renamed from meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0010-Fixed-bug-in-GCC-so-that-it-will-support-.long-0U-an.patch)17
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0013-fixing-the-constant-range-check-issue.patch (renamed from meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0011-Fixing-MicroBlaze-constant-range-check-issue.patch)21
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch38
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0015-intial-commit-of-MB-64-bit.patch4740
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0016-MB-X-initial-commit.patch694
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch38
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0018-Added-relocations-for-MB-X.patch350
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch375
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0020-Fixing-the-branch-related-issues.patch27
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0021-Fixed-address-computation-issues-with-64bit-address.patch219
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0022-Adding-new-relocation-to-support-64bit-rodata.patch168
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0023-fixing-the-.bss-relocation-issue.patch78
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch46
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch70
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch33
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0027-Patch-Microblaze-PR22471-undefined-reference-to-link.patch363
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0028-Revert-ld-Remove-unused-expression-state.patch97
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0029-Patch-Microblaze-Binutils-security-check-is-causing-.patch35
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0030-fixing-the-long-long-long-mingw-toolchain-issue.patch59
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0031-fixing-the-_STACK_SIZE-issue-with-the-flto-flag.patch57
33 files changed, 7799 insertions, 280 deletions
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils%.bbappend b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils%.bbappend
index 44709727..bf6cf464 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils%.bbappend
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils%.bbappend
@@ -1,15 +1,34 @@
FILESEXTRAPATHS_append_microblaze := "${THISDIR}/binutils-2.31:"
SRC_URI_append_microblaze = " \
- file://0001-MicroBlaze-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch \
- file://0002-MicroBlaze-add-mlittle-endian-and-mbig-endian-flags.patch \
- file://0003-Disable-the-warning-message-for-eh_frame_hdr.patch \
- file://0004-Fix-relaxation-of-assembler-resolved-references.patch \
- file://0005-Fixup-MicroBlaze-debug_loc-sections-after-linker-rel.patch \
- file://0006-Fix-bug-in-MicroBlaze-TLSTPREL-Relocation.patch \
- file://0007-Add-MicroBlaze-address-extension-instructions.patch \
- file://0008-Add-new-MicroBlaze-bit-field-instructions.patch \
- file://0009-Fixing-MicroBlaze-IMM-bug.patch \
- file://0010-Fixed-bug-in-GCC-so-that-it-will-support-.long-0U-an.patch \
- file://0011-Fixing-MicroBlaze-constant-range-check-issue.patch \
- file://0012-MicroBlaze-fix-mask-for-barrel-shift-instructions.patch \
- "
+ file://0001-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch \
+ file://0002-Add-mlittle-endian-and-mbig-endian-flags.patch \
+ file://0003-Disable-the-warning-message-for-eh_frame_hdr.patch \
+ file://0004-Fix-relaxation-of-assembler-resolved-references.patch \
+ file://0005-LOCAL-Fixup-debug_loc-sections-after-linker-relaxati.patch \
+ file://0006-upstream-change-to-garbage-collection-sweep-causes-m.patch \
+ file://0007-Fix-bug-in-TLSTPREL-Relocation.patch \
+ file://0008-Added-Address-extension-instructions.patch \
+ file://0009-fixing-the-MAX_OPCODES-to-correct-value.patch \
+ file://0010-Add-new-bit-field-instructions.patch \
+ file://0011-fixing-the-imm-bug.patch \
+ file://0012-Patch-Microblaze-fixed-bug-in-GCC-so-that-It-will-su.patch \
+ file://0013-fixing-the-constant-range-check-issue.patch \
+ file://0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch \
+ file://0015-intial-commit-of-MB-64-bit.patch \
+ file://0016-MB-X-initial-commit.patch \
+ file://0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch \
+ file://0018-Added-relocations-for-MB-X.patch \
+ file://0019-Fixed-MB-x-relocation-issues.patch \
+ file://0020-Fixing-the-branch-related-issues.patch \
+ file://0021-Fixed-address-computation-issues-with-64bit-address.patch \
+ file://0022-Adding-new-relocation-to-support-64bit-rodata.patch \
+ file://0023-fixing-the-.bss-relocation-issue.patch \
+ file://0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch \
+ file://0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch \
+ file://0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch \
+ file://0027-Patch-Microblaze-PR22471-undefined-reference-to-link.patch \
+ file://0028-Revert-ld-Remove-unused-expression-state.patch \
+ file://0029-Patch-Microblaze-Binutils-security-check-is-causing-.patch \
+ file://0030-fixing-the-long-long-long-mingw-toolchain-issue.patch \
+ file://0031-fixing-the-_STACK_SIZE-issue-with-the-flto-flag.patch \
+ "
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0001-MicroBlaze-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0001-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch
index 878bb321..4ea2f12c 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0001-MicroBlaze-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0001-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch
@@ -1,17 +1,14 @@
-From 91f39b692c48336117c092e4afd80899c97779e6 Mon Sep 17 00:00:00 2001
+From 6958c0c056b1597992d72d4b75e763e65862e1ad Mon Sep 17 00:00:00 2001
From: David Holsgrove <david.holsgrove@xilinx.com>
-Date: Mon, 28 Aug 2017 19:53:52 -0700
-Subject: [PATCH] MicroBlaze Add wdc.ext.clear and wdc.ext.flush insns
+Date: Wed, 8 May 2013 11:03:36 +1000
+Subject: [PATCH 01/31] Add wdc.ext.clear and wdc.ext.flush insns
Added two new instructions, wdc.ext.clear and wdc.ext.flush,
to enable MicroBlaze to flush an external cache, which is
used with the new coherency support for multiprocessing.
-Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Upstream-Status: Pending
-
+Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
---
opcodes/microblaze-opc.h | 5 ++++-
opcodes/microblaze-opcm.h | 4 ++--
@@ -63,3 +60,6 @@ index 92f3f19..7338f6a 100644
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,
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0002-MicroBlaze-add-mlittle-endian-and-mbig-endian-flags.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0002-Add-mlittle-endian-and-mbig-endian-flags.patch
index edeecfd2..12f2f639 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0002-MicroBlaze-add-mlittle-endian-and-mbig-endian-flags.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0002-Add-mlittle-endian-and-mbig-endian-flags.patch
@@ -1,7 +1,7 @@
-From 8b733a61ab54ba4cedb234020562502d20eebcbb Mon Sep 17 00:00:00 2001
-From: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Date: Mon, 28 Aug 2017 19:53:53 -0700
-Subject: [PATCH] MicroBlaze add mlittle-endian and mbig-endian flags
+From a570d7ef1fce2a1e4d4fde5f3ac36a741a01587b Mon Sep 17 00:00:00 2001
+From: nagaraju <nmekala@xilix.com>
+Date: Tue, 19 Mar 2013 17:18:23 +0530
+Subject: [PATCH 02/31] Add mlittle-endian and mbig-endian flags
Added support in gas for mlittle-endian and mbig-endian flags
as options.
@@ -11,15 +11,12 @@ to include new entries.
Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Upstream-Status: Pending
-
---
gas/config/tc-microblaze.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
-index 0194cd9..42dd7ae 100644
+index ba6eabb..360ccba 100644
--- a/gas/config/tc-microblaze.c
+++ b/gas/config/tc-microblaze.c
@@ -37,6 +37,8 @@
@@ -31,7 +28,7 @@ index 0194cd9..42dd7ae 100644
void microblaze_generate_symbol (char *sym);
static bfd_boolean check_spl_reg (unsigned *);
-@@ -1837,6 +1839,8 @@ struct option md_longopts[] =
+@@ -1845,6 +1847,8 @@ struct option md_longopts[] =
{
{"EB", no_argument, NULL, OPTION_EB},
{"EL", no_argument, NULL, OPTION_EL},
@@ -40,7 +37,7 @@ index 0194cd9..42dd7ae 100644
{ NULL, no_argument, NULL, 0}
};
-@@ -2471,9 +2475,11 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
+@@ -2498,9 +2502,11 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
switch (c)
{
case OPTION_EB:
@@ -52,7 +49,7 @@ index 0194cd9..42dd7ae 100644
target_big_endian = 0;
break;
default:
-@@ -2488,6 +2494,9 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
+@@ -2515,6 +2521,9 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
/* fprintf(stream, _("\
MicroBlaze options:\n\
-noSmall Data in the comm and data sections do not go into the small data section\n")); */
@@ -62,3 +59,6 @@ index 0194cd9..42dd7ae 100644
}
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0003-Disable-the-warning-message-for-eh_frame_hdr.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0003-Disable-the-warning-message-for-eh_frame_hdr.patch
index aee0c01e..ec3e2192 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0003-Disable-the-warning-message-for-eh_frame_hdr.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0003-Disable-the-warning-message-for-eh_frame_hdr.patch
@@ -1,39 +1,32 @@
-From dac72d809be9faf9380b181df0c19a2c6d744c54 Mon Sep 17 00:00:00 2001
+From 311a3a3dc3f5b2ab1ee276cb5626a85d0fd1027a Mon Sep 17 00:00:00 2001
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
-Date: Mon, 28 Aug 2017 19:53:54 -0700
-Subject: [PATCH] Disable the warning message for eh_frame_hdr
+Date: Fri, 22 Jun 2012 01:20:20 +0200
+Subject: [PATCH 03/31] Disable the warning message for eh_frame_hdr
-Upstream-Status: Inappropriate [workaround]
-
-Rebased to 2.31
- - Error hanlder changed
-
-Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandr@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
---
- bfd/elf-eh-frame.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
+ bfd/elf-eh-frame.c | 3 +++
+ 1 file changed, 3 insertions(+)
-Index: git/bfd/elf-eh-frame.c
-===================================================================
---- git.orig/bfd/elf-eh-frame.c
-+++ git/bfd/elf-eh-frame.c
-@@ -1042,10 +1042,13 @@ _bfd_elf_parse_eh_frame (bfd *abfd, stru
+diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
+index 12f06ef..e144922 100644
+--- a/bfd/elf-eh-frame.c
++++ b/bfd/elf-eh-frame.c
+@@ -1042,10 +1042,13 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
goto success;
free_no_table:
-- _bfd_error_handler
-+ /* FIXME: Remove the microblaze specifics when relaxing gets fixed. */
-+ if (bfd_get_arch(abfd) != bfd_arch_microblaze) {
++/* FIXME: Remove the microblaze specifics when relaxing gets fixed. */
++if (bfd_get_arch(abfd) != bfd_arch_microblaze) {
+ _bfd_error_handler
/* xgettext:c-format */
-- (_("error in %pB(%pA); no .eh_frame_hdr table will be created"),
-- abfd, sec);
-+ _bfd_error_handler
-+ (_("error in %pB(%pA); no .eh_frame_hdr table will be created"),
-+ abfd, sec);
-+ }
+ (_("error in %pB(%pA); no .eh_frame_hdr table will be created"),
+ abfd, sec);
++}
hdr_info->u.dwarf.table = FALSE;
if (sec_info)
free (sec_info);
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0004-Fix-relaxation-of-assembler-resolved-references.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0004-Fix-relaxation-of-assembler-resolved-references.patch
index b543c54e..d77c6120 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0004-Fix-relaxation-of-assembler-resolved-references.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0004-Fix-relaxation-of-assembler-resolved-references.patch
@@ -1,27 +1,20 @@
-From 927ef228dfedf229dc915b273a308ab2c7bf9e19 Mon Sep 17 00:00:00 2001
+From cafd454afbd2722b9249024332182e3e96b1bcc7 Mon Sep 17 00:00:00 2001
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
-Date: Mon, 28 Aug 2017 19:53:55 -0700
-Subject: [PATCH] Fix relaxation of assembler resolved references
-
-03/2018
-Rebased for binutils 2.30
+Date: Tue, 14 Feb 2012 01:00:22 +0100
+Subject: [PATCH 04/31] Fix relaxation of assembler resolved references
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandr@xilinx.com>
-
-Upstream-Status: Pending
-
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
---
- bfd/elf32-microblaze.c | 39 +++++++++++++++++++++++++++++++++++++++
+ bfd/elf32-microblaze.c | 38 ++++++++++++++++++++++++++++++++++++++
gas/config/tc-microblaze.c | 1 +
- 2 files changed, 40 insertions(+)
+ 2 files changed, 39 insertions(+)
diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
-index f1808bc..a1d810c 100644
+index 3d131bc..56c82ae 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
-@@ -1887,6 +1887,45 @@ microblaze_elf_relax_section (bfd *abfd,
+@@ -1973,6 +1973,44 @@ microblaze_elf_relax_section (bfd *abfd,
irelscanend = irelocs + o->reloc_count;
for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
{
@@ -54,8 +47,7 @@ index f1808bc..a1d810c 100644
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+ }
-+
-+ irelscan->r_addend -= calc_fixup (irelscan->r_addend
++ irelscan->r_addend -= calc_fixup (irelscan->r_addend
+ + isym->st_value, sec);
+ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
@@ -68,10 +60,10 @@ index f1808bc..a1d810c 100644
{
isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
-index 42dd7ae..50dbfc7 100644
+index 360ccba..e3dd1e0 100644
--- a/gas/config/tc-microblaze.c
+++ b/gas/config/tc-microblaze.c
-@@ -2183,6 +2183,7 @@ md_apply_fix (fixS * fixP,
+@@ -2205,6 +2205,7 @@ md_apply_fix (fixS * fixP,
else
fixP->fx_r_type = BFD_RELOC_NONE;
fixP->fx_addsy = section_symbol (absolute_section);
@@ -79,3 +71,6 @@ index 42dd7ae..50dbfc7 100644
}
return;
}
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0005-Fixup-MicroBlaze-debug_loc-sections-after-linker-rel.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0005-LOCAL-Fixup-debug_loc-sections-after-linker-relaxati.patch
index 6cdd2cc2..1b64bff1 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0005-Fixup-MicroBlaze-debug_loc-sections-after-linker-rel.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0005-LOCAL-Fixup-debug_loc-sections-after-linker-relaxati.patch
@@ -1,42 +1,31 @@
-From 5bf68bc39976903929f730b6eed18686c3563c05 Mon Sep 17 00:00:00 2001
-From: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Date: Mon, 28 Aug 2017 19:53:56 -0700
-Subject: [PATCH] Fixup MicroBlaze debug_loc sections after linker relaxation
-
-Fixup debug_loc sections after linker relaxation Adds a new reloctype
-R_MICROBLAZE_32_NONE, used for passing reloc info from the assembler to
-the linker when the linker manages to fully resolve a local symbol
-reference.
+From 9c0639469318b3a88aa7cb5e776eed85b586c5d0 Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Mon, 6 Feb 2017 15:53:08 +0530
+Subject: [PATCH 05/31] [LOCAL]: Fixup debug_loc sections after linker
+ relaxation Adds a new reloctype R_MICROBLAZE_32_NONE, used for passing reloc
+ info from the assembler to the linker when the linker manages to fully
+ resolve a local symbol reference.
This is a workaround for design flaws in the assembler to
linker interface with regards to linker relaxation.
-08/2018
-Rebased for binutils 2.31
- - Some RELOC_NUMBERs were added upstream, rebased to use 33 instead of 30
-
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
-Signed-off-by: Nagaraju Mekala <nmekala@xilinx.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandr@xilinx.com>
-
-Upstream-Status: Pending
-
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
---
- bfd/bfd-in2.h | 9 +++++++--
- bfd/elf32-microblaze.c | 45 ++++++++++++++++++++++++++++++++++++++-------
+ bfd/bfd-in2.h | 9 ++++++--
+ bfd/elf32-microblaze.c | 53 ++++++++++++++++++++++++++++++++++------------
bfd/libbfd.h | 1 +
bfd/reloc.c | 6 ++++++
binutils/readelf.c | 4 ++++
gas/config/tc-microblaze.c | 5 ++++-
- include/elf/microblaze.h | 1 +
- 7 files changed, 61 insertions(+), 10 deletions(-)
+ include/elf/microblaze.h | 2 ++
+ 7 files changed, 64 insertions(+), 16 deletions(-)
-Index: git/bfd/bfd-in2.h
-===================================================================
---- git.orig/bfd/bfd-in2.h
-+++ git/bfd/bfd-in2.h
-@@ -5791,10 +5791,15 @@ value relative to the read-write small d
+diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
+index f53dbb5..5807f70 100644
+--- a/bfd/bfd-in2.h
++++ b/bfd/bfd-in2.h
+@@ -5790,10 +5790,15 @@ value relative to the read-write small data area anchor */
expressions of the form "Symbol Op Symbol" */
BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM,
@@ -54,14 +43,15 @@ Index: git/bfd/bfd-in2.h
/* This is a 64 bit reloc that stores the 32 bit pc relative
value in two words (with an imm instruction). The relocation is
-Index: git/bfd/elf32-microblaze.c
-===================================================================
---- git.orig/bfd/elf32-microblaze.c
-+++ git/bfd/elf32-microblaze.c
-@@ -176,6 +176,20 @@ static reloc_howto_type microblaze_elf_h
+diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
+index 56c82ae..a377790 100644
+--- a/bfd/elf32-microblaze.c
++++ b/bfd/elf32-microblaze.c
+@@ -176,7 +176,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
0x0000ffff, /* Dest Mask. */
FALSE), /* PC relative offset? */
+- /* This reloc does nothing. Used for relaxation. */
+ HOWTO (R_MICROBLAZE_32_NONE, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
@@ -76,10 +66,11 @@ Index: git/bfd/elf32-microblaze.c
+ 0, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
- /* This reloc does nothing. Used for relaxation. */
++ /* This reloc does nothing. Used for relaxation. */
HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
0, /* Rightshift. */
-@@ -562,6 +576,9 @@ microblaze_elf_reloc_type_lookup (bfd *
+ 3, /* Size (0 = byte, 1 = short, 2 = long). */
+@@ -562,6 +576,9 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
case BFD_RELOC_NONE:
microblaze_reloc = R_MICROBLAZE_NONE;
break;
@@ -89,36 +80,41 @@ Index: git/bfd/elf32-microblaze.c
case BFD_RELOC_MICROBLAZE_64_NONE:
microblaze_reloc = R_MICROBLAZE_64_NONE;
break;
-@@ -1918,14 +1935,23 @@ microblaze_elf_relax_section (bfd *abfd,
+@@ -1918,6 +1935,7 @@ microblaze_elf_relax_section (bfd *abfd,
}
break;
case R_MICROBLAZE_NONE:
-+ case R_MICROBLAZE_32_NONE:
++ case R_MICROBLAZE_32_NONE:
{
/* This was a PC-relative instruction that was
completely resolved. */
- int sfix, efix;
-+ unsigned int val;
- bfd_vma target_address;
+@@ -1926,12 +1944,18 @@ microblaze_elf_relax_section (bfd *abfd,
target_address = irel->r_addend + irel->r_offset;
sfix = calc_fixup (irel->r_offset, 0, sec);
efix = calc_fixup (target_address, 0, sec);
+
-+ /* Validate the in-band val. */
-+ val = bfd_get_32 (abfd, contents + irel->r_offset);
-+ if (val != irel->r_addend && ELF32_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
-+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
-+ }
-+
++ /* Validate the in-band val. */
++ val = bfd_get_32 (abfd, contents + irel->r_offset);
++ if (val != irel->r_addend && ELF32_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
++ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
++ }
irel->r_addend -= (efix - sfix);
/* Should use HOWTO. */
microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
-@@ -1973,12 +1999,16 @@ microblaze_elf_relax_section (bfd *abfd,
+ irel->r_addend);
+- }
+- break;
++ }
++ break;
+ case R_MICROBLAZE_64_NONE:
+ {
+ /* This was a PC-relative 64-bit instruction that was
+@@ -1973,12 +1997,16 @@ microblaze_elf_relax_section (bfd *abfd,
irelscanend = irelocs + o->reloc_count;
for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
{
- if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_NONE)
-+ if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
++ if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
{
unsigned int val;
@@ -131,19 +127,23 @@ Index: git/bfd/elf32-microblaze.c
/* This was a PC-relative instruction that was completely resolved. */
if (ocontents == NULL)
{
-@@ -2003,15 +2033,16 @@ microblaze_elf_relax_section (bfd *abfd,
- }
- }
-
-- irelscan->r_addend -= calc_fixup (irelscan->r_addend
+@@ -1999,18 +2027,17 @@ microblaze_elf_relax_section (bfd *abfd,
+ (file_ptr) 0,
+ o->rawsize))
+ goto error_return;
+- elf_section_data (o)->this_hdr.contents = ocontents;
+- }
+- }
+- irelscan->r_addend -= calc_fixup (irelscan->r_addend
- + isym->st_value, sec);
++ elf_section_data (o)->this_hdr.contents = ocontents;
++ }
++ }
val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
-+
+ if (val != irelscan->r_addend) {
+ fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
+ }
+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
-+
microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
irelscan->r_addend);
}
@@ -153,7 +153,7 @@ Index: git/bfd/elf32-microblaze.c
if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
{
isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
-@@ -2071,7 +2102,7 @@ microblaze_elf_relax_section (bfd *abfd,
+@@ -2070,7 +2097,7 @@ microblaze_elf_relax_section (bfd *abfd,
elf_section_data (o)->this_hdr.contents = ocontents;
}
}
@@ -162,11 +162,11 @@ Index: git/bfd/elf32-microblaze.c
+ isym->st_value,
0,
sec);
-Index: git/bfd/libbfd.h
-===================================================================
---- git.orig/bfd/libbfd.h
-+++ git/bfd/libbfd.h
-@@ -2862,6 +2862,7 @@ static const char *const bfd_reloc_code_
+diff --git a/bfd/libbfd.h b/bfd/libbfd.h
+index 85f61b2..261086c 100644
+--- a/bfd/libbfd.h
++++ b/bfd/libbfd.h
+@@ -2862,6 +2862,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_MICROBLAZE_32_ROSDA",
"BFD_RELOC_MICROBLAZE_32_RWSDA",
"BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
@@ -174,10 +174,10 @@ Index: git/bfd/libbfd.h
"BFD_RELOC_MICROBLAZE_64_NONE",
"BFD_RELOC_MICROBLAZE_64_GOTPC",
"BFD_RELOC_MICROBLAZE_64_GOT",
-Index: git/bfd/reloc.c
-===================================================================
---- git.orig/bfd/reloc.c
-+++ git/bfd/reloc.c
+diff --git a/bfd/reloc.c b/bfd/reloc.c
+index 68bc8a8..d89bc5d 100644
+--- a/bfd/reloc.c
++++ b/bfd/reloc.c
@@ -6865,6 +6865,12 @@ ENUMDOC
This is a 32 bit reloc for the microblaze to handle
expressions of the form "Symbol Op Symbol"
@@ -191,25 +191,25 @@ Index: git/bfd/reloc.c
BFD_RELOC_MICROBLAZE_64_NONE
ENUMDOC
This is a 64 bit reloc that stores the 32 bit pc relative
-Index: git/binutils/readelf.c
-===================================================================
---- git.orig/binutils/readelf.c
-+++ git/binutils/readelf.c
-@@ -12908,6 +12908,10 @@ is_none_reloc (Filedata * filedata, unsi
+diff --git a/binutils/readelf.c b/binutils/readelf.c
+index 1b50ba7..13e794d 100644
+--- a/binutils/readelf.c
++++ b/binutils/readelf.c
+@@ -12907,6 +12907,10 @@ is_none_reloc (Filedata * filedata, unsigned int reloc_type)
|| reloc_type == 32 /* R_AVR_DIFF32. */);
case EM_METAG:
return reloc_type == 3; /* R_METAG_NONE. */
+ case EM_MICROBLAZE:
-+ return reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
++ return reloc_type == 30 /* R_MICROBLAZE_32_NONE. */
+ || reloc_type == 0 /* R_MICROBLAZE_NONE. */
+ || reloc_type == 9; /* R_MICROBLAZE_64_NONE. */
case EM_NDS32:
return (reloc_type == 0 /* R_XTENSA_NONE. */
|| reloc_type == 204 /* R_NDS32_DIFF8. */
-Index: git/gas/config/tc-microblaze.c
-===================================================================
---- git.orig/gas/config/tc-microblaze.c
-+++ git/gas/config/tc-microblaze.c
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index e3dd1e0..b34796c 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
@@ -2201,7 +2201,9 @@ md_apply_fix (fixS * fixP,
/* This fixup has been resolved. Create a reloc in case the linker
moves code around due to relaxing. */
@@ -221,7 +221,7 @@ Index: git/gas/config/tc-microblaze.c
else
fixP->fx_r_type = BFD_RELOC_NONE;
fixP->fx_addsy = section_symbol (absolute_section);
-@@ -2426,6 +2428,7 @@ tc_gen_reloc (asection * section ATTRIBU
+@@ -2426,6 +2428,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
switch (fixp->fx_r_type)
{
case BFD_RELOC_NONE:
@@ -229,15 +229,19 @@ Index: git/gas/config/tc-microblaze.c
case BFD_RELOC_MICROBLAZE_64_NONE:
case BFD_RELOC_32:
case BFD_RELOC_MICROBLAZE_32_LO:
-Index: git/include/elf/microblaze.h
-===================================================================
---- git.orig/include/elf/microblaze.h
-+++ git/include/elf/microblaze.h
-@@ -61,6 +61,7 @@ START_RELOC_NUMBERS (elf_microblaze_relo
+diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h
+index dbaa16c..7bdba67 100644
+--- a/include/elf/microblaze.h
++++ b/include/elf/microblaze.h
+@@ -61,6 +61,8 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type)
RELOC_NUMBER (R_MICROBLAZE_TEXTPCREL_64, 30) /* PC-relative TEXT offset. */
RELOC_NUMBER (R_MICROBLAZE_TEXTREL_64, 31) /* TEXT Entry offset 64-bit. */
RELOC_NUMBER (R_MICROBLAZE_TEXTREL_32_LO, 32) /* TEXT Entry offset 32-bit. */
+ RELOC_NUMBER (R_MICROBLAZE_32_NONE, 33)
++
END_RELOC_NUMBERS (R_MICROBLAZE_max)
/* Global base address names. */
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0006-upstream-change-to-garbage-collection-sweep-causes-m.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0006-upstream-change-to-garbage-collection-sweep-causes-m.patch
new file mode 100644
index 00000000..0c7b95b4
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0006-upstream-change-to-garbage-collection-sweep-causes-m.patch
@@ -0,0 +1,40 @@
+From 1bb6a80a2ae3cff3a3cc8526ec09e60f66b7cb96 Mon Sep 17 00:00:00 2001
+From: David Holsgrove <david.holsgrove@xilinx.com>
+Date: Wed, 27 Feb 2013 13:56:11 +1000
+Subject: [PATCH 06/31] upstream change to garbage collection sweep causes mb
+ regression
+
+Upstream change for PR13177 now clears the def_regular during gc_sweep of a
+section. (All other archs in binutils/bfd/elf32-*.c received an update
+to a warning about unresolvable relocations - this warning is not present
+in binutils/bfd/elf32-microblaze.c, but this warning check would not
+prevent the error being seen)
+
+The visible issue with this change is when running a c++ application
+in Petalinux which links libstdc++.so for exception handling it segfaults
+on execution.
+
+This does not occur if static linking libstdc++.a, so its during the
+relocations for a shared lib with garbage collection this occurs
+
+Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elflink.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/bfd/elflink.c b/bfd/elflink.c
+index b24fb95..b316149 100644
+--- a/bfd/elflink.c
++++ b/bfd/elflink.c
+@@ -6172,7 +6172,6 @@ elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
+
+ inf = (struct elf_gc_sweep_symbol_info *) data;
+ (*inf->hide_symbol) (inf->info, h, TRUE);
+- h->def_regular = 0;
+ h->ref_regular = 0;
+ h->ref_regular_nonweak = 0;
+ }
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0006-Fix-bug-in-MicroBlaze-TLSTPREL-Relocation.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0007-Fix-bug-in-TLSTPREL-Relocation.patch
index 8d3d5387..8d880f12 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0006-Fix-bug-in-MicroBlaze-TLSTPREL-Relocation.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0007-Fix-bug-in-TLSTPREL-Relocation.patch
@@ -1,7 +1,7 @@
-From ca0336a49c33ccb78962530f2affff8982027e8e Mon Sep 17 00:00:00 2001
-From: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Date: Mon, 28 Aug 2017 19:53:58 -0700
-Subject: [PATCH] Fix bug in MicroBlaze TLSTPREL Relocation
+From 7bfa31fb09557bc33f4965cd08c865df9c67fbc4 Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Mon, 15 Jun 2015 16:50:30 +0530
+Subject: [PATCH 07/31] Fix bug in TLSTPREL Relocation
Fixed the problem related to the fixup/relocations TLSTPREL.
When the fixup is applied the addend is not added at the correct offset
@@ -10,15 +10,12 @@ and it fails for Little endian. This patch allows support for both
big & little-endian compilers
Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Upstream-Status: Pending
-
---
bfd/elf32-microblaze.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
-index 1dc56f7..d4e53de 100644
+index a377790..474bd0e 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
@@ -1451,9 +1451,9 @@ microblaze_elf_relocate_section (bfd *output_bfd,
@@ -33,3 +30,6 @@ index 1dc56f7..d4e53de 100644
break;
case (int) R_MICROBLAZE_TEXTREL_64:
case (int) R_MICROBLAZE_TEXTREL_32_LO:
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0007-Add-MicroBlaze-address-extension-instructions.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0008-Added-Address-extension-instructions.patch
index 9672c516..b7eaf383 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0007-Add-MicroBlaze-address-extension-instructions.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0008-Added-Address-extension-instructions.patch
@@ -1,38 +1,29 @@
-From 3895968b5c55321d203cadb7630a2baee8699e17 Mon Sep 17 00:00:00 2001
-From: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Date: Mon, 28 Aug 2017 19:53:59 -0700
-Subject: [PATCH] Add MicroBlaze address extension instructions
+From 693a9f95f2fd78b334ed9bb7265ad2f95b536a2d Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Mon, 18 Jan 2016 12:28:21 +0530
+Subject: [PATCH 08/31] Added Address extension instructions
This patch adds the support of new instructions which are required
for supporting Address extension feature.
-2016-01-18 Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+Signed-off-by :Nagaraju Mekala <nmekala@xilix.com>
- * microblaze-opc.h (op_code_struct): Added new instructions
- * microblaze-opcm.h (microblaze_instr): Added new instructions
-
-Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Upstream-Status: Pending
+ChangeLog:
+ 2016-01-18 Nagaraju Mekala <nmekala@xilix.com>
+ *microblaze-opc.h (op_code_struct): Update
+ Added new instructions
+ *microblaze-opcm.h (microblaze_instr): Update
+ Added new instructions
---
- opcodes/microblaze-opc.h | 13 ++++++++++++-
+ opcodes/microblaze-opc.h | 11 +++++++++++
opcodes/microblaze-opcm.h | 10 +++++-----
- 2 files changed, 17 insertions(+), 6 deletions(-)
+ 2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
-index 773dc81..4e69f76 100644
+index 773dc81..292e3a4 100644
--- a/opcodes/microblaze-opc.h
+++ b/opcodes/microblaze-opc.h
-@@ -102,7 +102,7 @@
- #define DELAY_SLOT 1
- #define NO_DELAY_SLOT 0
-
--#define MAX_OPCODES 291
-+#define MAX_OPCODES 299
-
- struct op_code_struct
- {
@@ -178,8 +178,11 @@ struct op_code_struct
{"wdc.ext.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000466, OPCODE_MASK_H35B, wdcextclear, 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 },
@@ -102,3 +93,6 @@ index 7338f6a..c75f10a 100644
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,
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0009-fixing-the-MAX_OPCODES-to-correct-value.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0009-fixing-the-MAX_OPCODES-to-correct-value.patch
new file mode 100644
index 00000000..a8e33af9
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0009-fixing-the-MAX_OPCODES-to-correct-value.patch
@@ -0,0 +1,26 @@
+From c96e1cac59722005484ff5051b03fcc43efd246f Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Thu, 28 Jan 2016 14:07:34 +0530
+Subject: [PATCH 09/31] fixing the MAX_OPCODES to correct value
+
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ opcodes/microblaze-opc.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
+index 292e3a4..4e69f76 100644
+--- a/opcodes/microblaze-opc.h
++++ b/opcodes/microblaze-opc.h
+@@ -102,7 +102,7 @@
+ #define DELAY_SLOT 1
+ #define NO_DELAY_SLOT 0
+
+-#define MAX_OPCODES 291
++#define MAX_OPCODES 299
+
+ struct op_code_struct
+ {
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0008-Add-new-MicroBlaze-bit-field-instructions.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0010-Add-new-bit-field-instructions.patch
index 0bc01177..5410bad9 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0008-Add-new-MicroBlaze-bit-field-instructions.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0010-Add-new-bit-field-instructions.patch
@@ -1,19 +1,17 @@
-From 5c4dacaae2ba93569c1d37cda9859c57d6649dc0 Mon Sep 17 00:00:00 2001
-From: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Date: Mon, 28 Aug 2017 19:54:01 -0700
-Subject: [PATCH] Add new MicroBlaze bit-field instructions
+From bcb1dcdb9349fb2f6863daf9206552916bd4149b Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Mon, 18 Jul 2016 12:24:28 +0530
+Subject: [PATCH 10/31] Add new bit-field instructions
-This patches adds new bsefi and bsifi instructions. BSEFI- The
-instruction shall extract a bit field from a register and place it
-right-adjusted in the destination register. The other bits in the
-destination register shall be set to zero BSIFI- The instruction shall
-insert a right-adjusted bit field from a register at another position in
-the destination register. The rest of the bits in the destination
-register shall be unchanged
+This patches adds new bsefi and bsifi instructions.
+BSEFI- The instruction shall extract a bit field from a
+register and place it right-adjusted in the destination register.
+The other bits in the destination register shall be set to zero
+BSIFI- The instruction shall insert a right-adjusted bit field
+from a register at another position in the destination register.
+The rest of the bits in the destination register shall be unchanged
-Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Upstream-Status: Pending
+Signed-off-by :Nagaraju Mekala <nmekala@xilix.com>
---
gas/config/tc-microblaze.c | 71 +++++++++++++++++++++++++++++++++++++++++++++-
opcodes/microblaze-dis.c | 16 +++++++++++
@@ -22,10 +20,10 @@ Upstream-Status: Pending
4 files changed, 102 insertions(+), 3 deletions(-)
diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
-index e135547e62..34cb80fac2 100644
+index b34796c..7b42c99 100644
--- a/gas/config/tc-microblaze.c
+++ b/gas/config/tc-microblaze.c
-@@ -909,7 +909,7 @@ md_assemble (char * str)
+@@ -917,7 +917,7 @@ md_assemble (char * str)
unsigned reg2;
unsigned reg3;
unsigned isize;
@@ -34,7 +32,7 @@ index e135547e62..34cb80fac2 100644
expressionS exp;
char name[20];
-@@ -1164,7 +1164,76 @@ md_assemble (char * str)
+@@ -1172,7 +1172,76 @@ md_assemble (char * str)
inst |= (reg2 << RA_LOW) & RA_MASK;
inst |= (immed << IMM_LOW) & IMM5_MASK;
break;
@@ -112,14 +110,13 @@ index e135547e62..34cb80fac2 100644
if (strcmp (op_end, ""))
op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
-index 6a174b0eb9..80a47ad2fc 100644
+index 3b676d8..5101ceb 100644
--- a/opcodes/microblaze-dis.c
+++ b/opcodes/microblaze-dis.c
-@@ -73,6 +73,18 @@ get_field_imm5_mbar (long instr)
- return(strdup(tmpstr));
+@@ -74,6 +74,18 @@ get_field_imm5_mbar (long instr)
}
-+static char *
+ static char *
+get_field_imm5width (long instr)
+{
+ char tmpstr[25];
@@ -131,9 +128,10 @@ index 6a174b0eb9..80a47ad2fc 100644
+ return (strdup (tmpstr));
+}
+
- static char *
++static char *
get_field_rfsl (long instr)
{
+ char tmpstr[25];
@@ -396,6 +408,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
/* For mbar 16 or sleep insn. */
case INST_TYPE_NONE:
@@ -146,7 +144,7 @@ index 6a174b0eb9..80a47ad2fc 100644
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 a64f8362da..afb34989d9 100644
+index 4e69f76..4bc400a 100644
--- a/opcodes/microblaze-opc.h
+++ b/opcodes/microblaze-opc.h
@@ -59,6 +59,9 @@
@@ -197,7 +195,7 @@ index a64f8362da..afb34989d9 100644
#endif /* MICROBLAZE_OPC */
diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
-index 21a3dc8d76..dd6be7f65c 100644
+index c75f10a..b69e6a4 100644
--- a/opcodes/microblaze-opcm.h
+++ b/opcodes/microblaze-opcm.h
@@ -29,7 +29,7 @@ enum microblaze_instr
@@ -228,5 +226,5 @@ index 21a3dc8d76..dd6be7f65c 100644
#define RFSL_MASK 0x000000F
--
-2.15.0
+2.7.4
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0009-Fixing-MicroBlaze-IMM-bug.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0011-fixing-the-imm-bug.patch
index bb7e91cc..1b903e64 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0009-Fixing-MicroBlaze-IMM-bug.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0011-fixing-the-imm-bug.patch
@@ -1,23 +1,19 @@
-From f649406ccaea992f3931e0d9ca9fbd6efb0c553b Mon Sep 17 00:00:00 2001
-From: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Date: Mon, 28 Aug 2017 19:54:02 -0700
-Subject: [PATCH] Fixing MicroBlaze IMM bug
-
-Fixing the imm bug. with relax option imm -1 is also getting removed this is corrected now.
+From f61fb7af045c67c8c1c48cabecf568205d6f9637 Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Mon, 10 Jul 2017 16:07:28 +0530
+Subject: [PATCH 11/31] fixing the imm bug. with relax option imm -1 is also
+ getting removed this is corrected now.
Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Upstream-Status: Pending
-
---
bfd/elf32-microblaze.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
-index a94799f..74b00d2 100644
+index 474bd0e..94fa3cf 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
-@@ -1789,8 +1789,7 @@ microblaze_elf_relax_section (bfd *abfd,
+@@ -1869,8 +1869,7 @@ microblaze_elf_relax_section (bfd *abfd,
else
symval += irel->r_addend;
@@ -27,3 +23,6 @@ index a94799f..74b00d2 100644
{
/* We can delete this instruction. */
sec->relax[sec->relax_count].addr = irel->r_offset;
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0012-MicroBlaze-fix-mask-for-barrel-shift-instructions.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0012-MicroBlaze-fix-mask-for-barrel-shift-instructions.patch
deleted file mode 100644
index e340c506..00000000
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0012-MicroBlaze-fix-mask-for-barrel-shift-instructions.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 732b5a44a0a032da5ebb775b5df2ee2a36af988f Mon Sep 17 00:00:00 2001
-From: Nathan Rossi <nathan@nathanrossi.com>
-Date: Sun, 5 Nov 2017 22:17:39 +1000
-Subject: [PATCH] MicroBlaze fix mask for barrel shift instructions
-
-As of v10.0 the bsi (bslli/bsrai/bsrli/bsefi/bsifi) instructions have
-bits 16 and 17 defined as 'Insert' and 'Extract' respectively to support
-bit field insert/extract operations. For the bslli/bsrai/bsrli
-instructions these bits must be 0, as such update the opcode mask so
-that the bslli/bsrai/bsrli instructions do not also match the bsefi and
-bsifi instructions.
-
-Signed-off-by: Nathan Rossi <nathan@nathanrossi.com>
-Upstream-Status: Pending
-
----
- opcodes/microblaze-opc.h | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
-index 4bc400a..9482d81 100644
---- a/opcodes/microblaze-opc.h
-+++ b/opcodes/microblaze-opc.h
-@@ -161,9 +161,9 @@ struct op_code_struct
- {"ncget", INST_TYPE_RD_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C006000, OPCODE_MASK_H32, ncget, anyware_inst },
- {"ncput", INST_TYPE_R1_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00E000, OPCODE_MASK_H32, ncput, anyware_inst },
- {"muli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x60000000, OPCODE_MASK_H, muli, mult_inst },
-- {"bslli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3, bslli, barrel_shift_inst },
-- {"bsrai", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3, bsrai, barrel_shift_inst },
-- {"bsrli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3, bsrli, barrel_shift_inst },
-+ {"bslli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3B, bslli, barrel_shift_inst },
-+ {"bsrai", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3B, bsrai, barrel_shift_inst },
-+ {"bsrli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3B, bsrli, barrel_shift_inst },
- {"bsefi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64004000, OPCODE_MASK_H32B, bsefi, barrel_shift_inst },
- {"bsifi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64008000, OPCODE_MASK_H32B, bsifi, barrel_shift_inst },
- {"or", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H4, microblaze_or, logical_inst },
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0010-Fixed-bug-in-GCC-so-that-it-will-support-.long-0U-an.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0012-Patch-Microblaze-fixed-bug-in-GCC-so-that-It-will-su.patch
index 077343e6..b1eb240d 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0010-Fixed-bug-in-GCC-so-that-it-will-support-.long-0U-an.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0012-Patch-Microblaze-fixed-bug-in-GCC-so-that-It-will-su.patch
@@ -1,19 +1,17 @@
-From e1bacaa7c1aa387f167afff74876c5acdffc39d9 Mon Sep 17 00:00:00 2001
+From ff25d91969293aeddfffc8ae6d87f3f910a69d7b Mon Sep 17 00:00:00 2001
From: Mahesh Bodapati <mbodapat@xilinx.com>
-Date: Wed, 15 Nov 2017 17:45:35 -0800
-Subject: [PATCH] Fixed bug in GCC so that it will support .long 0U and .long
- 0u
+Date: Fri, 29 Sep 2017 18:00:23 +0530
+Subject: [PATCH 12/31] [Patch,Microblaze]: fixed bug in GCC so that It will
+ support .long 0U and .long 0u
Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Upstream-Status: Pending
-
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
---
gas/expr.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/gas/expr.c b/gas/expr.c
-index 3e28af6..0b7cc76 100644
+index 074e0b3..993aaca 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -810,6 +810,15 @@ operand (expressionS *expressionP, enum expr_mode mode)
@@ -32,3 +30,6 @@ index 3e28af6..0b7cc76 100644
c = *input_line_pointer;
switch (c)
{
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0011-Fixing-MicroBlaze-constant-range-check-issue.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0013-fixing-the-constant-range-check-issue.patch
index 244a7ade..03e4c701 100644
--- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0011-Fixing-MicroBlaze-constant-range-check-issue.patch
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0013-fixing-the-constant-range-check-issue.patch
@@ -1,23 +1,19 @@
-From 9393a3e346d2ccbb86761117260c1dd89070a507 Mon Sep 17 00:00:00 2001
-From: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Date: Wed, 15 Nov 2017 17:45:34 -0800
-Subject: [PATCH] Fixing MicroBlaze constant range check issue
-
-Sample error: not in range ffffffff80000000..7fffffff, not ffffffff70000000
+From 85e4d02730d657ddc9ce25f3e7eccf4818bc25eb Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Mon, 16 Oct 2017 15:44:23 +0530
+Subject: [PATCH 13/31] fixing the constant range check issue sample error: not
+ in range ffffffff80000000..7fffffff, not ffffffff70000000
Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
-Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha@xilinx.com>
-Upstream-Status: Pending
-
---
gas/config/tc-microblaze.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
-index 21a5a0c..c614556 100644
+index 7b42c99..f1d97b9 100644
--- a/gas/config/tc-microblaze.c
+++ b/gas/config/tc-microblaze.c
-@@ -749,7 +749,7 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
+@@ -757,7 +757,7 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
if ((e->X_add_number >> 31) == 1)
e->X_add_number |= -((addressT) (1U << 31));
@@ -26,3 +22,6 @@ index 21a5a0c..c614556 100644
{
as_fatal (_("operand must be absolute in range %lx..%lx, not %lx"),
(long) min, (long) max, (long) e->X_add_number);
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch
new file mode 100644
index 00000000..52274e02
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0014-Patch-Microblaze-Compiler-will-give-error-messages-i.patch
@@ -0,0 +1,38 @@
+From 3d1e635a4223f6c0a0b938b94911740b4aa0db8f Mon Sep 17 00:00:00 2001
+From: Mahesh Bodapati <mbodapat@xilinx.com>
+Date: Wed, 21 Feb 2018 12:32:02 +0530
+Subject: [PATCH 14/31] [Patch,Microblaze]: Compiler will give error messages
+ in more detail for mxl-gp-opt flag..
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ ld/ldmain.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/ld/ldmain.c b/ld/ldmain.c
+index f31eeb2..04e96ca 100644
+--- a/ld/ldmain.c
++++ b/ld/ldmain.c
+@@ -1434,6 +1434,18 @@ reloc_overflow (struct bfd_link_info *info,
+ break;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
++
++ if((strcmp(reloc_name,"R_MICROBLAZE_SRW32") == 0) && entry->type == bfd_link_hash_defined)
++ {
++ einfo (_(" relocation truncated to fit: don't enable small data pointer optimizations[mxl-gp-opt] if extern or multiple declarations used: "
++ "%s against symbol `%T' defined in %A section in %B"),
++ reloc_name, entry->root.string,
++ entry->u.def.section,
++ entry->u.def.section == bfd_abs_section_ptr
++ ? info->output_bfd : entry->u.def.section->owner);
++ break;
++ }
++
+ einfo (_(" relocation truncated to fit: "
+ "%s against symbol `%pT' defined in %pA section in %pB"),
+ reloc_name, entry->root.string,
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0015-intial-commit-of-MB-64-bit.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0015-intial-commit-of-MB-64-bit.patch
new file mode 100644
index 00000000..eb4eaf1d
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0015-intial-commit-of-MB-64-bit.patch
@@ -0,0 +1,4740 @@
+From f548b7a7d92d8f06afee253a7faf71f5bb1cb163 Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Sun, 30 Sep 2018 16:28:28 +0530
+Subject: [PATCH 15/31] intial commit of MB 64-bit
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/Makefile.am | 2 +
+ bfd/Makefile.in | 3 +
+ bfd/config.bfd | 4 +
+ bfd/configure | 2 +
+ bfd/configure.ac | 2 +
+ bfd/cpu-microblaze.c | 52 +-
+ bfd/elf64-microblaze.c | 3584 ++++++++++++++++++++++++++++++++++++
+ bfd/targets.c | 6 +
+ gas/config/tc-microblaze.c | 274 ++-
+ gas/config/tc-microblaze.h | 4 +-
+ include/elf/common.h | 1 +
+ ld/Makefile.am | 8 +
+ ld/Makefile.in | 10 +
+ ld/configure.tgt | 3 +
+ ld/emulparams/elf64microblaze.sh | 23 +
+ ld/emulparams/elf64microblazeel.sh | 23 +
+ opcodes/microblaze-dis.c | 39 +-
+ opcodes/microblaze-opc.h | 162 +-
+ opcodes/microblaze-opcm.h | 20 +-
+ 19 files changed, 4181 insertions(+), 41 deletions(-)
+ create mode 100644 bfd/elf64-microblaze.c
+ create mode 100644 ld/emulparams/elf64microblaze.sh
+ create mode 100644 ld/emulparams/elf64microblazeel.sh
+
+diff --git a/bfd/Makefile.am b/bfd/Makefile.am
+index 3f3487f..ae6bf3e 100644
+--- a/bfd/Makefile.am
++++ b/bfd/Makefile.am
+@@ -568,6 +568,7 @@ BFD64_BACKENDS = \
+ elf64-riscv.lo \
+ elfxx-riscv.lo \
+ elf64-s390.lo \
++ elf64-microblaze.lo \
+ elf64-sparc.lo \
+ elf64-tilegx.lo \
+ elf64-x86-64.lo \
+@@ -601,6 +602,7 @@ BFD64_BACKENDS_CFILES = \
+ elf64-nfp.c \
+ elf64-ppc.c \
+ elf64-s390.c \
++ elf64-microblaze.c \
+ elf64-sparc.c \
+ elf64-tilegx.c \
+ elf64-x86-64.c \
+diff --git a/bfd/Makefile.in b/bfd/Makefile.in
+index cc27ef0..3ba6eee 100644
+--- a/bfd/Makefile.in
++++ b/bfd/Makefile.in
+@@ -992,6 +992,7 @@ BFD64_BACKENDS = \
+ elf64-riscv.lo \
+ elfxx-riscv.lo \
+ elf64-s390.lo \
++ elf64-microblaze.lo \
+ elf64-sparc.lo \
+ elf64-tilegx.lo \
+ elf64-x86-64.lo \
+@@ -1025,6 +1026,7 @@ BFD64_BACKENDS_CFILES = \
+ elf64-nfp.c \
+ elf64-ppc.c \
+ elf64-s390.c \
++ elf64-microblaze.c \
+ elf64-sparc.c \
+ elf64-tilegx.c \
+ elf64-x86-64.c \
+@@ -1489,6 +1491,7 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-ppc.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-riscv.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-s390.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-microblaze.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-sparc.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-tilegx.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-x86-64.Plo@am__quote@
+diff --git a/bfd/config.bfd b/bfd/config.bfd
+index 6391f35..cde27b4 100644
+--- a/bfd/config.bfd
++++ b/bfd/config.bfd
+@@ -844,11 +844,15 @@ case "${targ}" in
+ microblazeel*-*)
+ targ_defvec=microblaze_elf32_le_vec
+ targ_selvecs=microblaze_elf32_vec
++ targ64_selvecs=microblaze_elf64_vec
++ targ64_selvecs=microblaze_elf64_le_vec
+ ;;
+
+ microblaze*-*)
+ targ_defvec=microblaze_elf32_vec
+ targ_selvecs=microblaze_elf32_le_vec
++ targ64_selvecs=microblaze_elf64_vec
++ targ64_selvecs=microblaze_elf64_le_vec
+ ;;
+
+ #ifdef BFD64
+diff --git a/bfd/configure b/bfd/configure
+index 3c32a83..5934afd 100755
+--- a/bfd/configure
++++ b/bfd/configure
+@@ -14844,6 +14844,8 @@ do
+ rx_elf32_le_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
+ s390_elf32_vec) tb="$tb elf32-s390.lo elf32.lo $elf" ;;
+ s390_elf64_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
++ microblaze_elf64_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
++ microblaze_elf64_le_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
+ score_elf32_be_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
+ score_elf32_le_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
+ sh_coff_vec) tb="$tb coff-sh.lo $coff" ;;
+diff --git a/bfd/configure.ac b/bfd/configure.ac
+index c6193cd..901977d 100644
+--- a/bfd/configure.ac
++++ b/bfd/configure.ac
+@@ -612,6 +612,8 @@ do
+ rx_elf32_le_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
+ s390_elf32_vec) tb="$tb elf32-s390.lo elf32.lo $elf" ;;
+ s390_elf64_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
++ microblaze_elf64_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
++ microblaze_elf64_le_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
+ score_elf32_be_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
+ score_elf32_le_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
+ sh_coff_vec) tb="$tb coff-sh.lo $coff" ;;
+diff --git a/bfd/cpu-microblaze.c b/bfd/cpu-microblaze.c
+index 2ccf724..dd2d6ab 100644
+--- a/bfd/cpu-microblaze.c
++++ b/bfd/cpu-microblaze.c
+@@ -23,7 +23,24 @@
+ #include "bfd.h"
+ #include "libbfd.h"
+
+-const bfd_arch_info_type bfd_microblaze_arch =
++const bfd_arch_info_type bfd_microblaze_arch[] =
++{
++#if BFD_DEFAULT_TARGET_SIZE == 64
++{
++ 64, /* 32 bits in a word. */
++ 64, /* 32 bits in an address. */
++ 8, /* 8 bits in a byte. */
++ bfd_arch_microblaze, /* Architecture. */
++ 0, /* Machine number - 0 for now. */
++ "microblaze", /* Architecture name. */
++ "MicroBlaze", /* Printable name. */
++ 3, /* Section align power. */
++ FALSE, /* Is this the default architecture ? */
++ bfd_default_compatible, /* Architecture comparison function. */
++ bfd_default_scan, /* String to architecture conversion. */
++ bfd_arch_default_fill, /* Default fill. */
++ &bfd_microblaze_arch[1] /* Next in list. */
++},
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+@@ -38,4 +55,37 @@ const bfd_arch_info_type bfd_microblaze_arch =
+ bfd_default_scan, /* String to architecture conversion. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
++}
++#else
++{
++ 32, /* 32 bits in a word. */
++ 32, /* 32 bits in an address. */
++ 8, /* 8 bits in a byte. */
++ bfd_arch_microblaze, /* Architecture. */
++ 0, /* Machine number - 0 for now. */
++ "microblaze", /* Architecture name. */
++ "MicroBlaze", /* Printable name. */
++ 3, /* Section align power. */
++ TRUE, /* Is this the default architecture ? */
++ bfd_default_compatible, /* Architecture comparison function. */
++ bfd_default_scan, /* String to architecture conversion. */
++ bfd_arch_default_fill, /* Default fill. */
++ &bfd_microblaze_arch[1] /* Next in list. */
++},
++{
++ 64, /* 32 bits in a word. */
++ 64, /* 32 bits in an address. */
++ 8, /* 8 bits in a byte. */
++ bfd_arch_microblaze, /* Architecture. */
++ 0, /* Machine number - 0 for now. */
++ "microblaze", /* Architecture name. */
++ "MicroBlaze", /* Printable name. */
++ 3, /* Section align power. */
++ FALSE, /* Is this the default architecture ? */
++ bfd_default_compatible, /* Architecture comparison function. */
++ bfd_default_scan, /* String to architecture conversion. */
++ bfd_arch_default_fill, /* Default fill. */
++ NULL /* Next in list. */
++}
++#endif
+ };
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+new file mode 100644
+index 0000000..0f43ae6
+--- /dev/null
++++ b/bfd/elf64-microblaze.c
+@@ -0,0 +1,3584 @@
++/* Xilinx MicroBlaze-specific support for 32-bit ELF
++
++ Copyright (C) 2009-2016 Free Software Foundation, Inc.
++
++ This file is part of BFD, the Binary File Descriptor library.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 3 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the
++ Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
++ Boston, MA 02110-1301, USA. */
++
++
++int dbg1 = 0;
++
++#include "sysdep.h"
++#include "bfd.h"
++#include "bfdlink.h"
++#include "libbfd.h"
++#include "elf-bfd.h"
++#include "elf/microblaze.h"
++#include <assert.h>
++
++#define USE_RELA /* Only USE_REL is actually significant, but this is
++ here are a reminder... */
++#define INST_WORD_SIZE 4
++
++static int ro_small_data_pointer = 0;
++static int rw_small_data_pointer = 0;
++
++static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
++
++static reloc_howto_type microblaze_elf_howto_raw[] =
++{
++ /* This reloc does nothing. */
++ HOWTO (R_MICROBLAZE_NONE, /* Type. */
++ 0, /* Rightshift. */
++ 3, /* Size (0 = byte, 1 = short, 2 = long). */
++ 0, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ NULL, /* Special Function. */
++ "R_MICROBLAZE_NONE", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* A standard 32 bit relocation. */
++ HOWTO (R_MICROBLAZE_32, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 32, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_bitfield, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_32", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0xffffffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* A standard PCREL 32 bit relocation. */
++ HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 32, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_bitfield, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_32_PCREL", /* Name. */
++ TRUE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0xffffffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
++ /* A 64 bit PCREL relocation. Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */
++ 0, /* Rightshift. */
++ 4, /* Size (0 = byte, 1 = short, 2 = long). */
++ 64, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_64_PCREL", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
++ /* The low half of a PCREL 32 bit relocation. */
++ HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_signed, /* Complain on overflow. */
++ bfd_elf_generic_reloc, /* Special Function. */
++ "R_MICROBLAZE_32_PCREL_LO", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
++ /* A 64 bit relocation. Table entry not really used. */
++ HOWTO (R_MICROBLAZE_64, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_64", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* The low half of a 32 bit relocation. */
++ HOWTO (R_MICROBLAZE_32_LO, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_signed, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_32_LO", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* Read-only small data section relocation. */
++ HOWTO (R_MICROBLAZE_SRO32, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_bitfield, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_SRO32", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* Read-write small data area relocation. */
++ HOWTO (R_MICROBLAZE_SRW32, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_bitfield, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_SRW32", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ HOWTO (R_MICROBLAZE_32_NONE, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 32, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_bitfield, /* Complain on overflow. */
++ NULL, /* Special Function. */
++ "R_MICROBLAZE_32_NONE",/* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* This reloc does nothing. Used for relaxation. */
++ HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
++ 0, /* Rightshift. */
++ 3, /* Size (0 = byte, 1 = short, 2 = long). */
++ 0, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ NULL, /* Special Function. */
++ "R_MICROBLAZE_64_NONE",/* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* Symbol Op Symbol relocation. */
++ HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 32, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_bitfield, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0xffffffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* GNU extension to record C++ vtable hierarchy. */
++ HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 0, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont,/* Complain on overflow. */
++ NULL, /* Special Function. */
++ "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* GNU extension to record C++ vtable member usage. */
++ HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 0, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont,/* Complain on overflow. */
++ _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */
++ "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* A 64 bit GOTPC relocation. Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc, /* Special Function. */
++ "R_MICROBLAZE_GOTPC_64", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
++ /* A 64 bit GOT relocation. Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_GOT_64",/* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* A 64 bit PLT relocation. Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_PLT_64",/* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
++ /* Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_REL, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_REL", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
++ /* Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_JUMP_SLOT", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
++ /* Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_GLOB_DAT", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
++ /* A 64 bit GOT relative relocation. Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_GOTOFF_64", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* A 32 bit GOT relative relocation. Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc, /* Special Function. */
++ "R_MICROBLAZE_GOTOFF_32", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
++ /* COPY relocation. Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_COPY, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ FALSE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_COPY", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 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
++#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
++#endif
++
++/* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
++
++static void
++microblaze_elf_howto_init (void)
++{
++ unsigned int i;
++
++ for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
++ {
++ unsigned int type;
++
++ type = microblaze_elf_howto_raw[i].type;
++
++ BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
++
++ microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
++ }
++}
++
++static reloc_howto_type *
++microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
++ bfd_reloc_code_real_type code)
++{
++ enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
++
++ switch (code)
++ {
++ case BFD_RELOC_NONE:
++ microblaze_reloc = R_MICROBLAZE_NONE;
++ break;
++ case BFD_RELOC_MICROBLAZE_32_NONE:
++ microblaze_reloc = R_MICROBLAZE_32_NONE;
++ break;
++ case BFD_RELOC_MICROBLAZE_64_NONE:
++ microblaze_reloc = R_MICROBLAZE_64_NONE;
++ break;
++ case BFD_RELOC_32:
++ microblaze_reloc = R_MICROBLAZE_32;
++ break;
++ /* RVA is treated the same as 32 */
++ case BFD_RELOC_RVA:
++ microblaze_reloc = R_MICROBLAZE_32;
++ break;
++ case BFD_RELOC_32_PCREL:
++ microblaze_reloc = R_MICROBLAZE_32_PCREL;
++ break;
++ case BFD_RELOC_64_PCREL:
++ microblaze_reloc = R_MICROBLAZE_64_PCREL;
++ break;
++ case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
++ microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
++ break;
++ case BFD_RELOC_64:
++ microblaze_reloc = R_MICROBLAZE_64;
++ break;
++ case BFD_RELOC_MICROBLAZE_32_LO:
++ microblaze_reloc = R_MICROBLAZE_32_LO;
++ break;
++ case BFD_RELOC_MICROBLAZE_32_ROSDA:
++ microblaze_reloc = R_MICROBLAZE_SRO32;
++ break;
++ case BFD_RELOC_MICROBLAZE_32_RWSDA:
++ microblaze_reloc = R_MICROBLAZE_SRW32;
++ break;
++ case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
++ microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
++ break;
++ case BFD_RELOC_VTABLE_INHERIT:
++ microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
++ break;
++ case BFD_RELOC_VTABLE_ENTRY:
++ microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
++ break;
++ case BFD_RELOC_MICROBLAZE_64_GOTPC:
++ microblaze_reloc = R_MICROBLAZE_GOTPC_64;
++ break;
++ case BFD_RELOC_MICROBLAZE_64_GOT:
++ microblaze_reloc = R_MICROBLAZE_GOT_64;
++ break;
++ case BFD_RELOC_MICROBLAZE_64_PLT:
++ microblaze_reloc = R_MICROBLAZE_PLT_64;
++ break;
++ case BFD_RELOC_MICROBLAZE_64_GOTOFF:
++ microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
++ break;
++ 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;
++ default:
++ return (reloc_howto_type *) NULL;
++ }
++
++ if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
++ /* Initialize howto table if needed. */
++ microblaze_elf_howto_init ();
++
++ return microblaze_elf_howto_table [(int) microblaze_reloc];
++};
++
++static reloc_howto_type *
++microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
++ const char *r_name)
++{
++ unsigned int i;
++
++ for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
++ if (microblaze_elf_howto_raw[i].name != NULL
++ && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
++ return &microblaze_elf_howto_raw[i];
++
++ return NULL;
++}
++
++/* Set the howto pointer for a RCE ELF reloc. */
++
++static void
++microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
++ arelent * cache_ptr,
++ Elf_Internal_Rela * dst)
++{
++ unsigned int r_type;
++
++ if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
++ /* Initialize howto table if needed. */
++ microblaze_elf_howto_init ();
++
++ r_type = ELF64_R_TYPE (dst->r_info);
++ if (r_type >= R_MICROBLAZE_max)
++ {
++ (*_bfd_error_handler) (_("%B: unrecognised MicroBlaze reloc number: %d"),
++ abfd, r_type);
++ bfd_set_error (bfd_error_bad_value);
++ r_type = R_MICROBLAZE_NONE;
++ }
++
++ cache_ptr->howto = microblaze_elf_howto_table [r_type];
++}
++
++/* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
++
++static bfd_boolean
++microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
++{
++ if (name[0] == 'L' && name[1] == '.')
++ return TRUE;
++
++ if (name[0] == '$' && name[1] == 'L')
++ return TRUE;
++
++ /* With gcc, the labels go back to starting with '.', so we accept
++ the generic ELF local label syntax as well. */
++ return _bfd_elf_is_local_label_name (abfd, name);
++}
++
++/* The microblaze linker (like many others) needs to keep track of
++ the number of relocs that it decides to copy as dynamic relocs in
++ check_relocs for each symbol. This is so that it can later discard
++ them if they are found to be unnecessary. We store the information
++ in a field extending the regular ELF linker hash table. */
++
++struct elf64_mb_dyn_relocs
++{
++ struct elf64_mb_dyn_relocs *next;
++
++ /* The input section of the reloc. */
++ asection *sec;
++
++ /* Total number of relocs copied for the input section. */
++ bfd_size_type count;
++
++ /* Number of pc-relative relocs copied for the input section. */
++ bfd_size_type pc_count;
++};
++
++/* ELF linker hash entry. */
++
++struct elf64_mb_link_hash_entry
++{
++ struct elf_link_hash_entry elf;
++
++ /* Track dynamic relocs copied for this symbol. */
++ struct elf64_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 elf64_mb_hash_entry(ent) ((struct elf64_mb_link_hash_entry *)(ent))
++
++/* ELF linker hash table. */
++
++struct elf64_mb_link_hash_table
++{
++ struct elf_link_hash_table elf;
++
++ /* Short-cuts to get to dynamic linker sections. */
++ asection *sgot;
++ asection *sgotplt;
++ asection *srelgot;
++ asection *splt;
++ asection *srelplt;
++ asection *sdynbss;
++ asection *srelbss;
++
++ /* 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 elf64_mb_hash_table(p) \
++ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
++ == MICROBLAZE_ELF_DATA ? ((struct elf64_mb_link_hash_table *) ((p)->hash)) : NULL)
++
++/* Create an entry in a microblaze ELF linker hash table. */
++
++static struct bfd_hash_entry *
++link_hash_newfunc (struct bfd_hash_entry *entry,
++ struct bfd_hash_table *table,
++ const char *string)
++{
++ /* Allocate the structure if it has not already been allocated by a
++ subclass. */
++ if (entry == NULL)
++ {
++ entry = bfd_hash_allocate (table,
++ sizeof (struct elf64_mb_link_hash_entry));
++ if (entry == NULL)
++ return entry;
++ }
++
++ /* Call the allocation method of the superclass. */
++ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
++ if (entry != NULL)
++ {
++ struct elf64_mb_link_hash_entry *eh;
++
++ eh = (struct elf64_mb_link_hash_entry *) entry;
++ eh->dyn_relocs = NULL;
++ eh->tls_mask = 0;
++ }
++
++ return entry;
++}
++
++/* Create a mb ELF linker hash table. */
++
++static struct bfd_link_hash_table *
++microblaze_elf_link_hash_table_create (bfd *abfd)
++{
++ struct elf64_mb_link_hash_table *ret;
++ bfd_size_type amt = sizeof (struct elf64_mb_link_hash_table);
++
++ ret = (struct elf64_mb_link_hash_table *) bfd_zmalloc (amt);
++ if (ret == NULL)
++ return NULL;
++
++ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
++ sizeof (struct elf64_mb_link_hash_entry),
++ MICROBLAZE_ELF_DATA))
++ {
++ free (ret);
++ return NULL;
++ }
++
++ return &ret->elf.root;
++}
++
++/* Set the values of the small data pointers. */
++
++static void
++microblaze_elf_final_sdp (struct bfd_link_info *info)
++{
++ struct bfd_link_hash_entry *h;
++
++ h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
++ if (h != (struct bfd_link_hash_entry *) NULL
++ && h->type == bfd_link_hash_defined)
++ ro_small_data_pointer = (h->u.def.value
++ + h->u.def.section->output_section->vma
++ + h->u.def.section->output_offset);
++
++ h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
++ if (h != (struct bfd_link_hash_entry *) NULL
++ && h->type == bfd_link_hash_defined)
++ rw_small_data_pointer = (h->u.def.value
++ + h->u.def.section->output_section->vma
++ + 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 = ELF64_R_INFO (indx, r_type);
++ rel.r_offset = offset;
++ rel.r_addend = addend;
++
++ bfd_elf64_swap_reloca_out (output_bfd, &rel,
++ (sreloc->contents + reloc_index * sizeof (Elf64_External_Rela)));
++}
++
++/* This code is taken from elf64-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],
++ if only to serve as a learning tool.
++
++ The RELOCATE_SECTION function is called by the new ELF backend linker
++ to handle the relocations for a section.
++
++ The relocs are always passed as Rela structures; if the section
++ actually uses Rel structures, the r_addend field will always be
++ zero.
++
++ This function is responsible for adjust the section contents as
++ necessary, and (if using Rela relocs and generating a
++ relocatable output file) adjusting the reloc addend as
++ necessary.
++
++ This function does not have to worry about setting the reloc
++ address or the reloc symbol index.
++
++ LOCAL_SYMS is a pointer to the swapped in local symbols.
++
++ LOCAL_SECTIONS is an array giving the section in the input file
++ corresponding to the st_shndx field of each local symbol.
++
++ The global hash table entry for the global symbols can be found
++ via elf_sym_hashes (input_bfd).
++
++ When generating relocatable output, this function must handle
++ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
++ going to be the section symbol corresponding to the output
++ section, which means that the addend must be adjusted
++ accordingly. */
++
++static bfd_boolean
++microblaze_elf_relocate_section (bfd *output_bfd,
++ struct bfd_link_info *info,
++ bfd *input_bfd,
++ asection *input_section,
++ bfd_byte *contents,
++ Elf_Internal_Rela *relocs,
++ Elf_Internal_Sym *local_syms,
++ asection **local_sections)
++{
++ struct elf64_mb_link_hash_table *htab;
++ 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;
++ bfd_vma *local_got_offsets;
++ unsigned int tls_type;
++
++ if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
++ microblaze_elf_howto_init ();
++
++ htab = elf64_mb_hash_table (info);
++ if (htab == NULL)
++ return FALSE;
++
++ local_got_offsets = elf_local_got_offsets (input_bfd);
++
++ sreloc = elf_section_data (input_section)->sreloc;
++
++ rel = relocs;
++ relend = relocs + input_section->reloc_count;
++ for (; rel < relend; rel++)
++ {
++ int r_type;
++ reloc_howto_type *howto;
++ unsigned long r_symndx;
++ bfd_vma addend = rel->r_addend;
++ bfd_vma offset = rel->r_offset;
++ struct elf_link_hash_entry *h;
++ Elf_Internal_Sym *sym;
++ asection *sec;
++ const char *sym_name;
++ bfd_reloc_status_type r = bfd_reloc_ok;
++ const char *errmsg = NULL;
++ bfd_boolean unresolved_reloc = FALSE;
++
++ h = NULL;
++ r_type = ELF64_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"),
++ bfd_get_filename (input_bfd), (int) r_type);
++ bfd_set_error (bfd_error_bad_value);
++ ret = FALSE;
++ continue;
++ }
++
++ howto = microblaze_elf_howto_table[r_type];
++ r_symndx = ELF64_R_SYM (rel->r_info);
++
++ if (bfd_link_relocatable (info))
++ {
++ /* This is a relocatable link. We don't have to change
++ anything, unless the reloc is against a section symbol,
++ in which case we have to adjust according to where the
++ section symbol winds up in the output section. */
++ sec = NULL;
++ if (r_symndx >= symtab_hdr->sh_info)
++ /* External symbol. */
++ continue;
++
++ /* Local symbol. */
++ sym = local_syms + r_symndx;
++ sym_name = "<local symbol>";
++ /* STT_SECTION: symbol is associated with a section. */
++ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
++ /* Symbol isn't associated with a section. Nothing to do. */
++ continue;
++
++ sec = local_sections[r_symndx];
++ addend += sec->output_offset + sym->st_value;
++#ifndef USE_REL
++ /* This can't be done for USE_REL because it doesn't mean anything
++ and elf_link_input_bfd asserts this stays zero. */
++ /* rel->r_addend = addend; */
++#endif
++
++#ifndef USE_REL
++ /* Addends are stored with relocs. We're done. */
++ continue;
++#else /* USE_REL */
++ /* If partial_inplace, we need to store any additional addend
++ back in the section. */
++ if (!howto->partial_inplace)
++ continue;
++ /* ??? Here is a nice place to call a special_function like handler. */
++ r = _bfd_relocate_contents (howto, input_bfd, addend,
++ contents + offset);
++#endif /* USE_REL */
++ }
++ else
++ {
++ bfd_vma relocation;
++
++ /* This is a final link. */
++ sym = NULL;
++ sec = NULL;
++ unresolved_reloc = FALSE;
++
++ if (r_symndx < symtab_hdr->sh_info)
++ {
++ /* Local symbol. */
++ sym = local_syms + r_symndx;
++ sec = local_sections[r_symndx];
++ if (sec == 0)
++ continue;
++ sym_name = "<local symbol>";
++ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
++ /* r_addend may have changed if the reference section was
++ a merge section. */
++ addend = rel->r_addend;
++ }
++ else
++ {
++ /* External symbol. */
++ bfd_boolean warned ATTRIBUTE_UNUSED;
++ bfd_boolean ignored ATTRIBUTE_UNUSED;
++
++ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
++ r_symndx, symtab_hdr, sym_hashes,
++ h, sec, relocation,
++ unresolved_reloc, warned, ignored);
++ sym_name = h->root.root.string;
++ }
++
++ /* Sanity check the address. */
++ if (offset > bfd_get_section_limit (input_bfd, input_section))
++ {
++ r = bfd_reloc_outofrange;
++ goto check_reloc;
++ }
++
++ switch ((int) r_type)
++ {
++ case (int) R_MICROBLAZE_SRO32 :
++ {
++ const char *name;
++
++ /* Only relocate if the symbol is defined. */
++ if (sec)
++ {
++ name = bfd_get_section_name (sec->owner, sec);
++
++ if (strcmp (name, ".sdata2") == 0
++ || strcmp (name, ".sbss2") == 0)
++ {
++ if (ro_small_data_pointer == 0)
++ microblaze_elf_final_sdp (info);
++ if (ro_small_data_pointer == 0)
++ {
++ ret = FALSE;
++ r = bfd_reloc_undefined;
++ goto check_reloc;
++ }
++
++ /* At this point `relocation' contains the object's
++ address. */
++ relocation -= ro_small_data_pointer;
++ /* Now it contains the offset from _SDA2_BASE_. */
++ r = _bfd_final_link_relocate (howto, input_bfd,
++ input_section,
++ contents, offset,
++ relocation, addend);
++ }
++ else
++ {
++ (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
++ bfd_get_filename (input_bfd),
++ sym_name,
++ microblaze_elf_howto_table[(int) r_type]->name,
++ bfd_get_section_name (sec->owner, sec));
++ /*bfd_set_error (bfd_error_bad_value); ??? why? */
++ ret = FALSE;
++ continue;
++ }
++ }
++ }
++ break;
++
++ case (int) R_MICROBLAZE_SRW32 :
++ {
++ const char *name;
++
++ /* Only relocate if the symbol is defined. */
++ if (sec)
++ {
++ name = bfd_get_section_name (sec->owner, sec);
++
++ if (strcmp (name, ".sdata") == 0
++ || strcmp (name, ".sbss") == 0)
++ {
++ if (rw_small_data_pointer == 0)
++ microblaze_elf_final_sdp (info);
++ if (rw_small_data_pointer == 0)
++ {
++ ret = FALSE;
++ r = bfd_reloc_undefined;
++ goto check_reloc;
++ }
++
++ /* At this point `relocation' contains the object's
++ address. */
++ relocation -= rw_small_data_pointer;
++ /* Now it contains the offset from _SDA_BASE_. */
++ r = _bfd_final_link_relocate (howto, input_bfd,
++ input_section,
++ contents, offset,
++ relocation, addend);
++ }
++ else
++ {
++ (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
++ bfd_get_filename (input_bfd),
++ sym_name,
++ microblaze_elf_howto_table[(int) r_type]->name,
++ bfd_get_section_name (sec->owner, sec));
++ /*bfd_set_error (bfd_error_bad_value); ??? why? */
++ ret = FALSE;
++ continue;
++ }
++ }
++ }
++ break;
++
++ case (int) R_MICROBLAZE_32_SYM_OP_SYM:
++ break; /* Do nothing. */
++
++ case (int) R_MICROBLAZE_GOTPC_64:
++ relocation = htab->sgotplt->output_section->vma
++ + htab->sgotplt->output_offset;
++ relocation -= (input_section->output_section->vma
++ + input_section->output_offset
++ + offset + INST_WORD_SIZE);
++ relocation += addend;
++ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ contents + offset + endian);
++ bfd_put_16 (input_bfd, relocation & 0xffff,
++ contents + offset + endian + INST_WORD_SIZE);
++ break;
++
++ case (int) R_MICROBLAZE_PLT_64:
++ {
++ bfd_vma immediate;
++ if (htab->splt != NULL && h != NULL
++ && h->plt.offset != (bfd_vma) -1)
++ {
++ relocation = (htab->splt->output_section->vma
++ + htab->splt->output_offset
++ + h->plt.offset);
++ unresolved_reloc = FALSE;
++ immediate = relocation - (input_section->output_section->vma
++ + input_section->output_offset
++ + offset + INST_WORD_SIZE);
++ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
++ contents + offset + endian);
++ bfd_put_16 (input_bfd, immediate & 0xffff,
++ contents + offset + endian + INST_WORD_SIZE);
++ }
++ else
++ {
++ relocation -= (input_section->output_section->vma
++ + input_section->output_offset
++ + offset + INST_WORD_SIZE);
++ immediate = relocation;
++ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
++ contents + offset + endian);
++ bfd_put_16 (input_bfd, immediate & 0xffff,
++ contents + offset + endian + INST_WORD_SIZE);
++ }
++ 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 ();
++
++ 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
++ {
++ if (local_got_offsets == NULL)
++ abort ();
++ 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,
++ bfd_link_pic (info),
++ h)
++ && (!bfd_link_pic (info)
++ || !SYMBOL_REFERENCES_LOCAL (info, h)))
++ indx = h->dynindx;
++ }
++
++ /* Need to generate relocs ? */
++ if ((bfd_link_pic (info) || 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 (! bfd_link_pic (info))
++ {
++ 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);
++ }
++ }
++ 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))
++ {
++ *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
++ {
++ bfd_put_32 (output_bfd, static_value,
++ htab->sgot->contents + off2);
++
++ /* Relocs for dyn symbols generated by
++ finish_dynamic_symbols */
++ if (bfd_link_pic (info) && 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;
++ }
++
++ case (int) R_MICROBLAZE_GOTOFF_64:
++ {
++ bfd_vma immediate;
++ unsigned short lo, high;
++ relocation += addend;
++ relocation -= htab->sgotplt->output_section->vma
++ + htab->sgotplt->output_offset;
++ /* Write this value into correct location. */
++ immediate = relocation;
++ lo = immediate & 0x0000ffff;
++ high = (immediate >> 16) & 0x0000ffff;
++ bfd_put_16 (input_bfd, high, contents + offset + endian);
++ bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian);
++ break;
++ }
++
++ case (int) R_MICROBLAZE_GOTOFF_32:
++ {
++ relocation += addend;
++ relocation -= htab->sgotplt->output_section->vma
++ + htab->sgotplt->output_offset;
++ /* Write this value into correct location. */
++ bfd_put_32 (input_bfd, relocation, contents + offset);
++ break;
++ }
++
++ case (int) R_MICROBLAZE_TLSDTPREL64:
++ relocation += addend;
++ relocation -= dtprel_base(info);
++ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ contents + offset + endian);
++ bfd_put_16 (input_bfd, relocation & 0xffff,
++ contents + offset + endian + INST_WORD_SIZE);
++ break;
++ case (int) R_MICROBLAZE_64_PCREL :
++ case (int) R_MICROBLAZE_64:
++ case (int) R_MICROBLAZE_32:
++ {
++ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
++ from removed linkonce sections, or sections discarded by
++ a linker script. */
++ if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
++ {
++ relocation += addend;
++ if (r_type == R_MICROBLAZE_32)
++ bfd_put_32 (input_bfd, relocation, contents + offset);
++ else
++ {
++ if (r_type == R_MICROBLAZE_64_PCREL)
++ relocation -= (input_section->output_section->vma
++ + input_section->output_offset
++ + offset + INST_WORD_SIZE);
++ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ contents + offset + endian);
++ bfd_put_16 (input_bfd, relocation & 0xffff,
++ contents + offset + endian + INST_WORD_SIZE);
++ }
++ break;
++ }
++
++ if ((bfd_link_pic (info)
++ && (h == NULL
++ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
++ || h->root.type != bfd_link_hash_undefweak)
++ && (!howto->pc_relative
++ || (h != NULL
++ && h->dynindx != -1
++ && (!info->symbolic
++ || !h->def_regular))))
++ || (!bfd_link_pic (info)
++ && h != NULL
++ && h->dynindx != -1
++ && !h->non_got_ref
++ && ((h->def_dynamic
++ && !h->def_regular)
++ || h->root.type == bfd_link_hash_undefweak
++ || h->root.type == bfd_link_hash_undefined)))
++ {
++ Elf_Internal_Rela outrel;
++ bfd_byte *loc;
++ bfd_boolean skip;
++
++ /* When generating a shared object, these relocations
++ are copied into the output file to be resolved at run
++ time. */
++
++ BFD_ASSERT (sreloc != NULL);
++
++ skip = FALSE;
++
++ outrel.r_offset =
++ _bfd_elf_section_offset (output_bfd, info, input_section,
++ rel->r_offset);
++ if (outrel.r_offset == (bfd_vma) -1)
++ skip = TRUE;
++ else if (outrel.r_offset == (bfd_vma) -2)
++ skip = TRUE;
++ outrel.r_offset += (input_section->output_section->vma
++ + input_section->output_offset);
++
++ if (skip)
++ memset (&outrel, 0, sizeof outrel);
++ /* h->dynindx may be -1 if the symbol was marked to
++ become local. */
++ else if (h != NULL
++ && ((! info->symbolic && h->dynindx != -1)
++ || !h->def_regular))
++ {
++ BFD_ASSERT (h->dynindx != -1);
++ outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
++ outrel.r_addend = addend;
++ }
++ else
++ {
++ if (r_type == R_MICROBLAZE_32)
++ {
++ outrel.r_info = ELF64_R_INFO (0, R_MICROBLAZE_REL);
++ outrel.r_addend = relocation + addend;
++ }
++ else
++ {
++ BFD_FAIL ();
++ (*_bfd_error_handler)
++ (_("%B: probably compiled without -fPIC?"),
++ input_bfd);
++ bfd_set_error (bfd_error_bad_value);
++ return FALSE;
++ }
++ }
++
++ loc = sreloc->contents;
++ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
++ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
++ break;
++ }
++ else
++ {
++ relocation += addend;
++ if (r_type == R_MICROBLAZE_32)
++ bfd_put_32 (input_bfd, relocation, contents + offset);
++ else
++ {
++ if (r_type == R_MICROBLAZE_64_PCREL)
++ relocation -= (input_section->output_section->vma
++ + input_section->output_offset
++ + offset + INST_WORD_SIZE);
++ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ contents + offset + endian);
++ bfd_put_16 (input_bfd, relocation & 0xffff,
++ contents + offset + endian + INST_WORD_SIZE);
++ }
++ break;
++ }
++ }
++
++ default :
++ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
++ contents, offset,
++ relocation, addend);
++ break;
++ }
++ }
++
++ check_reloc:
++
++ if (r != bfd_reloc_ok)
++ {
++ /* FIXME: This should be generic enough to go in a utility. */
++ const char *name;
++
++ if (h != NULL)
++ name = h->root.root.string;
++ else
++ {
++ name = (bfd_elf_string_from_elf_section
++ (input_bfd, symtab_hdr->sh_link, sym->st_name));
++ if (name == NULL || *name == '\0')
++ name = bfd_section_name (input_bfd, sec);
++ }
++
++ if (errmsg != NULL)
++ goto common_error;
++
++ switch (r)
++ {
++ case bfd_reloc_overflow:
++ (*info->callbacks->reloc_overflow)
++ (info, (h ? &h->root : NULL), name, howto->name,
++ (bfd_vma) 0, input_bfd, input_section, offset);
++ break;
++
++ case bfd_reloc_undefined:
++ (*info->callbacks->undefined_symbol)
++ (info, name, input_bfd, input_section, offset, TRUE);
++ break;
++
++ case bfd_reloc_outofrange:
++ errmsg = _("internal error: out of range error");
++ goto common_error;
++
++ case bfd_reloc_notsupported:
++ errmsg = _("internal error: unsupported relocation error");
++ goto common_error;
++
++ case bfd_reloc_dangerous:
++ errmsg = _("internal error: dangerous error");
++ goto common_error;
++
++ default:
++ errmsg = _("internal error: unknown error");
++ /* Fall through. */
++ common_error:
++ (*info->callbacks->warning) (info, errmsg, name, input_bfd,
++ input_section, offset);
++ break;
++ }
++ }
++ }
++
++ 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. */
++
++static int
++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)
++ return 0;
++
++ /* Look for addr in relax table, total fixup value. */
++ for (i = 0; i < sec->relax_count; i++)
++ {
++ if (end <= sec->relax[i].addr)
++ break;
++ if ((end != start) && (start > sec->relax[i].addr))
++ continue;
++ fixup += sec->relax[i].size;
++ }
++ 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,
++ struct bfd_link_info *link_info,
++ bfd_boolean *again)
++{
++ Elf_Internal_Shdr *symtab_hdr;
++ Elf_Internal_Rela *internal_relocs;
++ Elf_Internal_Rela *free_relocs = NULL;
++ Elf_Internal_Rela *irel, *irelend;
++ bfd_byte *contents = NULL;
++ bfd_byte *free_contents = NULL;
++ int rel_count;
++ unsigned int shndx;
++ int i, sym_index;
++ asection *o;
++ struct elf_link_hash_entry *sym_hash;
++ Elf_Internal_Sym *isymbuf, *isymend;
++ Elf_Internal_Sym *isym;
++ int symcount;
++ int offset;
++ bfd_vma src, dest;
++
++ /* We only do this once per section. We may be able to delete some code
++ by running multiple passes, but it is not worth it. */
++ *again = FALSE;
++
++ /* Only do this for a text section. */
++ if (bfd_link_relocatable (link_info)
++ || (sec->flags & SEC_RELOC) == 0
++ || (sec->reloc_count == 0)
++ || (sec->flags & SEC_CODE) == 0)
++ return TRUE;
++
++ BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
++
++ /* If this is the first time we have been called for this section,
++ initialize the cooked size. */
++ if (sec->size == 0)
++ sec->size = sec->rawsize;
++
++ /* Get symbols for this section. */
++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
++ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
++ symcount = symtab_hdr->sh_size / sizeof (Elf64_External_Sym);
++ if (isymbuf == NULL)
++ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
++ 0, NULL, NULL, NULL);
++ BFD_ASSERT (isymbuf != NULL);
++
++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
++ if (internal_relocs == NULL)
++ goto error_return;
++ if (! link_info->keep_memory)
++ free_relocs = internal_relocs;
++
++ sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
++ * sizeof (struct relax_table));
++ if (sec->relax == NULL)
++ goto error_return;
++ sec->relax_count = 0;
++
++ irelend = internal_relocs + sec->reloc_count;
++ rel_count = 0;
++ for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
++ {
++ bfd_vma symval;
++ if ((ELF64_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
++ && (ELF64_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 ))
++ continue; /* Can't delete this reloc. */
++
++ /* Get the section contents. */
++ if (contents == NULL)
++ {
++ if (elf_section_data (sec)->this_hdr.contents != NULL)
++ contents = elf_section_data (sec)->this_hdr.contents;
++ else
++ {
++ contents = (bfd_byte *) bfd_malloc (sec->size);
++ if (contents == NULL)
++ goto error_return;
++ free_contents = contents;
++
++ if (!bfd_get_section_contents (abfd, sec, contents,
++ (file_ptr) 0, sec->size))
++ goto error_return;
++ elf_section_data (sec)->this_hdr.contents = contents;
++ }
++ }
++
++ /* Get the value of the symbol referred to by the reloc. */
++ if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
++ {
++ /* A local symbol. */
++ asection *sym_sec;
++
++ isym = isymbuf + ELF64_R_SYM (irel->r_info);
++ if (isym->st_shndx == SHN_UNDEF)
++ sym_sec = bfd_und_section_ptr;
++ else if (isym->st_shndx == SHN_ABS)
++ sym_sec = bfd_abs_section_ptr;
++ else if (isym->st_shndx == SHN_COMMON)
++ sym_sec = bfd_com_section_ptr;
++ else
++ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
++
++ symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
++ }
++ else
++ {
++ unsigned long indx;
++ struct elf_link_hash_entry *h;
++
++ indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
++ h = elf_sym_hashes (abfd)[indx];
++ BFD_ASSERT (h != NULL);
++
++ if (h->root.type != bfd_link_hash_defined
++ && h->root.type != bfd_link_hash_defweak)
++ /* This appears to be a reference to an undefined
++ symbol. Just ignore it--it will be caught by the
++ regular reloc processing. */
++ continue;
++
++ symval = (h->root.u.def.value
++ + h->root.u.def.section->output_section->vma
++ + h->root.u.def.section->output_offset);
++ }
++
++ /* If this is a PC-relative reloc, subtract the instr offset from
++ the symbol value. */
++ if (ELF64_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
++ {
++ symval = symval + irel->r_addend
++ - (irel->r_offset
++ + sec->output_section->vma
++ + sec->output_offset);
++ }
++ else
++ symval += irel->r_addend;
++
++ if ((symval & 0xffff8000) == 0)
++ {
++ /* We can delete this instruction. */
++ sec->relax[sec->relax_count].addr = irel->r_offset;
++ sec->relax[sec->relax_count].size = INST_WORD_SIZE;
++ sec->relax_count++;
++
++ /* Rewrite relocation type. */
++ switch ((enum elf_microblaze_reloc_type) ELF64_R_TYPE (irel->r_info))
++ {
++ case R_MICROBLAZE_64_PCREL:
++ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
++ (int) R_MICROBLAZE_32_PCREL_LO);
++ break;
++ case R_MICROBLAZE_64:
++ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
++ (int) R_MICROBLAZE_32_LO);
++ break;
++ default:
++ /* Cannot happen. */
++ BFD_ASSERT (FALSE);
++ }
++ }
++ } /* Loop through all relocations. */
++
++ /* Loop through the relocs again, and see if anything needs to change. */
++ if (sec->relax_count > 0)
++ {
++ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
++ rel_count = 0;
++ sec->relax[sec->relax_count].addr = sec->size;
++
++ for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
++ {
++ bfd_vma nraddr;
++
++ /* Get the new reloc address. */
++ nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
++ switch ((enum elf_microblaze_reloc_type) ELF64_R_TYPE (irel->r_info))
++ {
++ default:
++ break;
++ case R_MICROBLAZE_64_PCREL:
++ break;
++ case R_MICROBLAZE_64:
++ case R_MICROBLAZE_32_LO:
++ /* If this reloc is against a symbol defined in this
++ section, we must check the addend to see it will put the value in
++ range to be adjusted, and hence must be changed. */
++ if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
++ {
++ isym = isymbuf + ELF64_R_SYM (irel->r_info);
++ /* Only handle relocs against .text. */
++ if (isym->st_shndx == shndx
++ && ELF64_ST_TYPE (isym->st_info) == STT_SECTION)
++ irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
++ }
++ break;
++ case R_MICROBLAZE_NONE:
++ case R_MICROBLAZE_32_NONE:
++ {
++ /* This was a PC-relative instruction that was
++ completely resolved. */
++ int sfix, efix;
++ unsigned int val;
++ bfd_vma target_address;
++ target_address = irel->r_addend + irel->r_offset;
++ sfix = calc_fixup (irel->r_offset, 0, sec);
++ efix = calc_fixup (target_address, 0, sec);
++
++ /* Validate the in-band val. */
++ val = bfd_get_32 (abfd, contents + irel->r_offset);
++ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
++ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
++ }
++ irel->r_addend -= (efix - sfix);
++ /* Should use HOWTO. */
++ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
++ irel->r_addend);
++ }
++ break;
++ case R_MICROBLAZE_64_NONE:
++ {
++ /* This was a PC-relative 64-bit instruction that was
++ completely resolved. */
++ 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, 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);
++ }
++ break;
++ }
++ irel->r_offset = nraddr;
++ } /* Change all relocs in this section. */
++
++ /* Look through all other sections. */
++ for (o = abfd->sections; o != NULL; o = o->next)
++ {
++ Elf_Internal_Rela *irelocs;
++ Elf_Internal_Rela *irelscan, *irelscanend;
++ bfd_byte *ocontents;
++
++ if (o == sec
++ || (o->flags & SEC_RELOC) == 0
++ || o->reloc_count == 0)
++ continue;
++
++ /* We always cache the relocs. Perhaps, if info->keep_memory is
++ FALSE, we should free them, if we are permitted to. */
++
++ irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE);
++ if (irelocs == NULL)
++ goto error_return;
++
++ ocontents = NULL;
++ irelscanend = irelocs + o->reloc_count;
++ for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
++ {
++ if (1 && ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
++ {
++ unsigned int val;
++
++ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
++
++ /* hax: We only do the following fixup for debug location lists. */
++ if (strcmp(".debug_loc", o->name))
++ continue;
++
++ /* This was a PC-relative instruction that was completely resolved. */
++ if (ocontents == NULL)
++ {
++ if (elf_section_data (o)->this_hdr.contents != NULL)
++ ocontents = elf_section_data (o)->this_hdr.contents;
++ else
++ {
++ /* We always cache the section contents.
++ Perhaps, if info->keep_memory is FALSE, we
++ should free them, if we are permitted to. */
++
++ if (o->rawsize == 0)
++ o->rawsize = o->size;
++ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
++ if (ocontents == NULL)
++ goto error_return;
++ if (!bfd_get_section_contents (abfd, o, ocontents,
++ (file_ptr) 0,
++ o->rawsize))
++ goto error_return;
++ elf_section_data (o)->this_hdr.contents = ocontents;
++ }
++ }
++
++ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
++ if (val != irelscan->r_addend) {
++ fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
++ }
++ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
++ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
++ irelscan->r_addend);
++ }
++ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
++ {
++ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
++
++ /* Look at the reloc only if the value has been resolved. */
++ if (isym->st_shndx == shndx
++ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
++ {
++ if (ocontents == NULL)
++ {
++ if (elf_section_data (o)->this_hdr.contents != NULL)
++ ocontents = elf_section_data (o)->this_hdr.contents;
++ else
++ {
++ /* We always cache the section contents.
++ Perhaps, if info->keep_memory is FALSE, we
++ should free them, if we are permitted to. */
++ if (o->rawsize == 0)
++ o->rawsize = o->size;
++ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
++ if (ocontents == NULL)
++ goto error_return;
++ if (!bfd_get_section_contents (abfd, o, ocontents,
++ (file_ptr) 0,
++ o->rawsize))
++ goto error_return;
++ elf_section_data (o)->this_hdr.contents = ocontents;
++ }
++
++ }
++ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
++ }
++ else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
++ {
++ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
++
++ /* Look at the reloc only if the value has been resolved. */
++ if (ocontents == NULL)
++ {
++ if (elf_section_data (o)->this_hdr.contents != NULL)
++ ocontents = elf_section_data (o)->this_hdr.contents;
++ else
++ {
++ /* We always cache the section contents.
++ Perhaps, if info->keep_memory is FALSE, we
++ should free them, if we are permitted to. */
++
++ if (o->rawsize == 0)
++ o->rawsize = o->size;
++ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
++ if (ocontents == NULL)
++ goto error_return;
++ if (!bfd_get_section_contents (abfd, o, ocontents,
++ (file_ptr) 0,
++ o->rawsize))
++ goto error_return;
++ elf_section_data (o)->this_hdr.contents = ocontents;
++ }
++ }
++ irelscan->r_addend -= calc_fixup (irelscan->r_addend
++ + isym->st_value,
++ 0,
++ sec);
++ }
++ }
++ else if ((ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
++ || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO))
++ {
++ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
++
++ /* Look at the reloc only if the value has been resolved. */
++ if (isym->st_shndx == shndx
++ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
++ {
++ bfd_vma immediate;
++ bfd_vma target_address;
++
++ if (ocontents == NULL)
++ {
++ if (elf_section_data (o)->this_hdr.contents != NULL)
++ ocontents = elf_section_data (o)->this_hdr.contents;
++ else
++ {
++ /* We always cache the section contents.
++ Perhaps, if info->keep_memory is FALSE, we
++ should free them, if we are permitted to. */
++ if (o->rawsize == 0)
++ o->rawsize = o->size;
++ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
++ if (ocontents == NULL)
++ goto error_return;
++ if (!bfd_get_section_contents (abfd, o, ocontents,
++ (file_ptr) 0,
++ o->rawsize))
++ goto error_return;
++ elf_section_data (o)->this_hdr.contents = ocontents;
++ }
++ }
++
++ unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
++ immediate = instr & 0x0000ffff;
++ target_address = immediate;
++ offset = calc_fixup (target_address, 0, sec);
++ immediate -= offset;
++ irelscan->r_addend -= offset;
++ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
++ irelscan->r_addend);
++ }
++ }
++
++ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64)
++ {
++ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
++
++ /* Look at the reloc only if the value has been resolved. */
++ if (isym->st_shndx == shndx
++ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
++ {
++ bfd_vma immediate;
++
++ if (ocontents == NULL)
++ {
++ if (elf_section_data (o)->this_hdr.contents != NULL)
++ ocontents = elf_section_data (o)->this_hdr.contents;
++ else
++ {
++ /* We always cache the section contents.
++ Perhaps, if info->keep_memory is FALSE, we
++ should free them, if we are permitted to. */
++
++ if (o->rawsize == 0)
++ o->rawsize = o->size;
++ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
++ if (ocontents == NULL)
++ goto error_return;
++ if (!bfd_get_section_contents (abfd, o, ocontents,
++ (file_ptr) 0,
++ o->rawsize))
++ goto error_return;
++ elf_section_data (o)->this_hdr.contents = ocontents;
++ }
++ }
++ 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, 0, sec);
++ immediate -= offset;
++ irelscan->r_addend -= offset;
++ }
++ }
++ else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
++ {
++ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
++
++ /* Look at the reloc only if the value has been resolved. */
++ if (isym->st_shndx == shndx
++ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
++ {
++ bfd_vma immediate;
++ bfd_vma target_address;
++
++ if (ocontents == NULL)
++ {
++ if (elf_section_data (o)->this_hdr.contents != NULL)
++ ocontents = elf_section_data (o)->this_hdr.contents;
++ else
++ {
++ /* We always cache the section contents.
++ Perhaps, if info->keep_memory is FALSE, we
++ should free them, if we are permitted to. */
++ if (o->rawsize == 0)
++ o->rawsize = o->size;
++ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
++ if (ocontents == NULL)
++ goto error_return;
++ if (!bfd_get_section_contents (abfd, o, ocontents,
++ (file_ptr) 0,
++ o->rawsize))
++ goto error_return;
++ elf_section_data (o)->this_hdr.contents = ocontents;
++ }
++ }
++ 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, 0, sec);
++ immediate -= offset;
++ irelscan->r_addend -= offset;
++ microblaze_bfd_write_imm_value_64 (abfd, ocontents
++ + irelscan->r_offset, immediate);
++ }
++ }
++ }
++ }
++
++ /* Adjust the local symbols defined in this section. */
++ isymend = isymbuf + symtab_hdr->sh_info;
++ for (isym = isymbuf; isym < isymend; isym++)
++ {
++ if (isym->st_shndx == shndx)
++ {
++ 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;
++ symcount = (symtab_hdr->sh_size / sizeof (Elf64_External_Sym)) - symtab_hdr->sh_info;
++ for (sym_index = 0; sym_index < symcount; sym_index++)
++ {
++ sym_hash = elf_sym_hashes (abfd)[sym_index];
++ 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,
++ 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;
++ for (i = 0; i < sec->relax_count; i++)
++ {
++ int len;
++ src = sec->relax[i].addr + sec->relax[i].size;
++ len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size;
++
++ memmove (contents + dest, contents + src, len);
++ sec->size -= sec->relax[i].size;
++ dest += len;
++ }
++
++ elf_section_data (sec)->relocs = internal_relocs;
++ free_relocs = NULL;
++
++ elf_section_data (sec)->this_hdr.contents = contents;
++ free_contents = NULL;
++
++ symtab_hdr->contents = (bfd_byte *) isymbuf;
++ }
++
++ if (free_relocs != NULL)
++ {
++ free (free_relocs);
++ free_relocs = NULL;
++ }
++
++ if (free_contents != NULL)
++ {
++ if (!link_info->keep_memory)
++ free (free_contents);
++ else
++ /* Cache the section contents for elf_link_input_bfd. */
++ elf_section_data (sec)->this_hdr.contents = contents;
++ free_contents = NULL;
++ }
++
++ if (sec->relax_count == 0)
++ {
++ *again = FALSE;
++ free (sec->relax);
++ sec->relax = NULL;
++ }
++ else
++ *again = TRUE;
++ return TRUE;
++
++ error_return:
++ if (free_relocs != NULL)
++ free (free_relocs);
++ if (free_contents != NULL)
++ free (free_contents);
++ if (sec->relax != NULL)
++ {
++ free (sec->relax);
++ sec->relax = NULL;
++ sec->relax_count = 0;
++ }
++ return FALSE;
++}
++
++/* Return the section that should be marked against GC for a given
++ relocation. */
++
++static asection *
++microblaze_elf_gc_mark_hook (asection *sec,
++ struct bfd_link_info * info,
++ Elf_Internal_Rela * rel,
++ struct elf_link_hash_entry * h,
++ Elf_Internal_Sym * sym)
++{
++ if (h != NULL)
++ switch (ELF64_R_TYPE (rel->r_info))
++ {
++ case R_MICROBLAZE_GNU_VTINHERIT:
++ case R_MICROBLAZE_GNU_VTENTRY:
++ return NULL;
++ }
++
++ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
++}
++
++/* Update the got entry reference counts for the section being removed. */
++
++static bfd_boolean
++microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
++ struct bfd_link_info * info ATTRIBUTE_UNUSED,
++ asection * sec ATTRIBUTE_UNUSED,
++ const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
++{
++ return TRUE;
++}
++
++/* PIC support. */
++
++#define PLT_ENTRY_SIZE 16
++
++#define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
++#define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
++#define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
++#define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
++#define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
++
++/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
++ shortcuts to them in our hash table. */
++
++static bfd_boolean
++create_got_section (bfd *dynobj, struct bfd_link_info *info)
++{
++ struct elf64_mb_link_hash_table *htab;
++
++ if (! _bfd_elf_create_got_section (dynobj, info))
++ return FALSE;
++ htab = elf64_mb_hash_table (info);
++ if (htab == NULL)
++ return FALSE;
++
++ htab->sgot = bfd_get_linker_section (dynobj, ".got");
++ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
++ if (!htab->sgot || !htab->sgotplt)
++ return FALSE;
++
++ if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL)
++ htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got");
++ if (htab->srelgot == NULL
++ || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
++ | SEC_LOAD
++ | SEC_HAS_CONTENTS
++ | SEC_IN_MEMORY
++ | SEC_LINKER_CREATED
++ | SEC_READONLY)
++ || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
++ return FALSE;
++ 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
++microblaze_elf_check_relocs (bfd * abfd,
++ struct bfd_link_info * info,
++ asection * sec,
++ const Elf_Internal_Rela * relocs)
++{
++ Elf_Internal_Shdr * symtab_hdr;
++ struct elf_link_hash_entry ** sym_hashes;
++ struct elf_link_hash_entry ** sym_hashes_end;
++ const Elf_Internal_Rela * rel;
++ const Elf_Internal_Rela * rel_end;
++ struct elf64_mb_link_hash_table *htab;
++ asection *sreloc = NULL;
++
++ if (bfd_link_relocatable (info))
++ return TRUE;
++
++ htab = elf64_mb_hash_table (info);
++ if (htab == NULL)
++ return FALSE;
++
++ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
++ sym_hashes = elf_sym_hashes (abfd);
++ sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf64_External_Sym);
++ if (!elf_bad_symtab (abfd))
++ sym_hashes_end -= symtab_hdr->sh_info;
++
++ rel_end = relocs + sec->reloc_count;
++
++ for (rel = relocs; rel < rel_end; rel++)
++ {
++ unsigned int r_type;
++ struct elf_link_hash_entry * h;
++ unsigned long r_symndx;
++ unsigned char tls_type = 0;
++
++ r_symndx = ELF64_R_SYM (rel->r_info);
++ r_type = ELF64_R_TYPE (rel->r_info);
++
++ if (r_symndx < symtab_hdr->sh_info)
++ h = NULL;
++ else
++ {
++ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
++
++ /* PR15323, ref flags aren't set for references in the same
++ object. */
++ h->root.non_ir_ref = 1;
++ }
++
++ switch (r_type)
++ {
++ /* This relocation describes the C++ object vtable hierarchy.
++ Reconstruct it for later use during GC. */
++ case R_MICROBLAZE_GNU_VTINHERIT:
++ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
++ return FALSE;
++ break;
++
++ /* This relocation describes which C++ vtable entries are actually
++ used. Record for later use during GC. */
++ case R_MICROBLAZE_GNU_VTENTRY:
++ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
++ return FALSE;
++ break;
++
++ /* This relocation requires .plt entry. */
++ case R_MICROBLAZE_PLT_64:
++ if (h != NULL)
++ {
++ h->needs_plt = 1;
++ h->plt.refcount += 1;
++ }
++ 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)
++ {
++ if (htab->elf.dynobj == NULL)
++ htab->elf.dynobj = abfd;
++ if (!create_got_section (htab->elf.dynobj, info))
++ return FALSE;
++ }
++ if (h != NULL)
++ {
++ h->got.refcount += 1;
++ elf64_mb_hash_entry (h)->tls_mask |= tls_type;
++ }
++ else
++ {
++ if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
++ return FALSE;
++ }
++ break;
++
++ case R_MICROBLAZE_64:
++ case R_MICROBLAZE_64_PCREL:
++ case R_MICROBLAZE_32:
++ {
++ if (h != NULL && !bfd_link_pic (info))
++ {
++ /* we may need a copy reloc. */
++ h->non_got_ref = 1;
++
++ /* we may also need a .plt entry. */
++ h->plt.refcount += 1;
++ if (ELF64_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
++ h->pointer_equality_needed = 1;
++ }
++
++
++ /* If we are creating a shared library, and this is a reloc
++ against a global symbol, or a non PC relative reloc
++ against a local symbol, then we need to copy the reloc
++ into the shared library. However, if we are linking with
++ -Bsymbolic, we do not need to copy a reloc against a
++ global symbol which is defined in an object we are
++ including in the link (i.e., DEF_REGULAR is set). At
++ this point we have not seen all the input files, so it is
++ possible that DEF_REGULAR is not set now but will be set
++ later (it is never cleared). In case of a weak definition,
++ DEF_REGULAR may be cleared later by a strong definition in
++ a shared library. We account for that possibility below by
++ storing information in the relocs_copied field of the hash
++ table entry. A similar situation occurs when creating
++ shared libraries and symbol visibility changes render the
++ symbol local.
++
++ If on the other hand, we are creating an executable, we
++ may need to keep relocations for symbols satisfied by a
++ dynamic library if we manage to avoid copy relocs for the
++ symbol. */
++
++ if ((bfd_link_pic (info)
++ && (sec->flags & SEC_ALLOC) != 0
++ && (r_type != R_MICROBLAZE_64_PCREL
++ || (h != NULL
++ && (! info->symbolic
++ || h->root.type == bfd_link_hash_defweak
++ || !h->def_regular))))
++ || (!bfd_link_pic (info)
++ && (sec->flags & SEC_ALLOC) != 0
++ && h != NULL
++ && (h->root.type == bfd_link_hash_defweak
++ || !h->def_regular)))
++ {
++ struct elf64_mb_dyn_relocs *p;
++ struct elf64_mb_dyn_relocs **head;
++
++ /* When creating a shared object, we must copy these
++ relocs into the output file. We create a reloc
++ section in dynobj and make room for the reloc. */
++
++ if (sreloc == NULL)
++ {
++ bfd *dynobj;
++
++ if (htab->elf.dynobj == NULL)
++ htab->elf.dynobj = abfd;
++ dynobj = htab->elf.dynobj;
++
++ sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
++ 2, abfd, 1);
++ if (sreloc == NULL)
++ return FALSE;
++ }
++
++ /* If this is a global symbol, we count the number of
++ relocations we need for this symbol. */
++ if (h != NULL)
++ head = &((struct elf64_mb_link_hash_entry *) h)->dyn_relocs;
++ else
++ {
++ /* Track dynamic relocs needed for local syms too.
++ We really need local syms available to do this
++ easily. Oh well. */
++
++ asection *s;
++ Elf_Internal_Sym *isym;
++ void *vpp;
++
++ isym = bfd_sym_from_r_symndx (&htab->sym_sec,
++ abfd, r_symndx);
++ if (isym == NULL)
++ return FALSE;
++
++ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
++ if (s == NULL)
++ return FALSE;
++
++ vpp = &elf_section_data (s)->local_dynrel;
++ head = (struct elf64_mb_dyn_relocs **) vpp;
++ }
++
++ p = *head;
++ if (p == NULL || p->sec != sec)
++ {
++ bfd_size_type amt = sizeof *p;
++ p = ((struct elf64_mb_dyn_relocs *)
++ bfd_alloc (htab->elf.dynobj, amt));
++ if (p == NULL)
++ return FALSE;
++ p->next = *head;
++ *head = p;
++ p->sec = sec;
++ p->count = 0;
++ p->pc_count = 0;
++ }
++
++ p->count += 1;
++ if (r_type == R_MICROBLAZE_64_PCREL)
++ p->pc_count += 1;
++ }
++ }
++ break;
++ }
++ }
++
++ return TRUE;
++}
++
++static bfd_boolean
++microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
++{
++ struct elf64_mb_link_hash_table *htab;
++
++ htab = elf64_mb_hash_table (info);
++ if (htab == NULL)
++ return FALSE;
++
++ if (!htab->sgot && !create_got_section (dynobj, info))
++ return FALSE;
++
++ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
++ return FALSE;
++
++ htab->splt = bfd_get_linker_section (dynobj, ".plt");
++ htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
++ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
++ if (!bfd_link_pic (info))
++ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
++
++ if (!htab->splt || !htab->srelplt || !htab->sdynbss
++ || (!bfd_link_pic (info) && !htab->srelbss))
++ abort ();
++
++ return TRUE;
++}
++
++/* Copy the extra info we tack onto an elf_link_hash_entry. */
++
++static void
++microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
++ struct elf_link_hash_entry *dir,
++ struct elf_link_hash_entry *ind)
++{
++ struct elf64_mb_link_hash_entry *edir, *eind;
++
++ edir = (struct elf64_mb_link_hash_entry *) dir;
++ eind = (struct elf64_mb_link_hash_entry *) ind;
++
++ if (eind->dyn_relocs != NULL)
++ {
++ if (edir->dyn_relocs != NULL)
++ {
++ struct elf64_mb_dyn_relocs **pp;
++ struct elf64_mb_dyn_relocs *p;
++
++ if (ind->root.type == bfd_link_hash_indirect)
++ abort ();
++
++ /* Add reloc counts against the weak sym to the strong sym
++ list. Merge any entries against the same section. */
++ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
++ {
++ struct elf64_mb_dyn_relocs *q;
++
++ for (q = edir->dyn_relocs; q != NULL; q = q->next)
++ if (q->sec == p->sec)
++ {
++ q->pc_count += p->pc_count;
++ q->count += p->count;
++ *pp = p->next;
++ break;
++ }
++ if (q == NULL)
++ pp = &p->next;
++ }
++ *pp = edir->dyn_relocs;
++ }
++
++ edir->dyn_relocs = eind->dyn_relocs;
++ eind->dyn_relocs = NULL;
++ }
++
++ edir->tls_mask |= eind->tls_mask;
++
++ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
++}
++
++static bfd_boolean
++microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
++ struct elf_link_hash_entry *h)
++{
++ struct elf64_mb_link_hash_table *htab;
++ struct elf64_mb_link_hash_entry * eh;
++ struct elf64_mb_dyn_relocs *p;
++ asection *sdynbss, *s;
++ unsigned int power_of_two;
++ bfd *dynobj;
++
++ htab = elf64_mb_hash_table (info);
++ if (htab == NULL)
++ return FALSE;
++
++ /* If this is a function, put it in the procedure linkage table. We
++ will fill in the contents of the procedure linkage table later,
++ when we know the address of the .got section. */
++ if (h->type == STT_FUNC
++ || h->needs_plt)
++ {
++ if (h->plt.refcount <= 0
++ || SYMBOL_CALLS_LOCAL (info, h)
++ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
++ && h->root.type == bfd_link_hash_undefweak))
++ {
++ /* This case can occur if we saw a PLT reloc in an input
++ file, but the symbol was never referred to by a dynamic
++ object, or if all references were garbage collected. In
++ such a case, we don't actually need to build a procedure
++ linkage table, and we can just do a PC32 reloc instead. */
++ h->plt.offset = (bfd_vma) -1;
++ h->needs_plt = 0;
++ }
++
++ return TRUE;
++ }
++ else
++ /* It's possible that we incorrectly decided a .plt reloc was
++ needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
++ check_relocs. We can't decide accurately between function and
++ non-function syms in check-relocs; Objects loaded later in
++ the link may change h->type. So fix it now. */
++ h->plt.offset = (bfd_vma) -1;
++
++ /* If this is a weak symbol, and there is a real definition, the
++ processor independent code will have arranged for us to see the
++ real definition first, and we can just use the same value. */
++ if (h->u.weakdef != NULL)
++ {
++ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
++ || h->u.weakdef->root.type == bfd_link_hash_defweak);
++ h->root.u.def.section = h->u.weakdef->root.u.def.section;
++ h->root.u.def.value = h->u.weakdef->root.u.def.value;
++ return TRUE;
++ }
++
++ /* This is a reference to a symbol defined by a dynamic object which
++ is not a function. */
++
++ /* If we are creating a shared library, we must presume that the
++ only references to the symbol are via the global offset table.
++ For such cases we need not do anything here; the relocations will
++ be handled correctly by relocate_section. */
++ if (bfd_link_pic (info))
++ return TRUE;
++
++ /* If there are no references to this symbol that do not use the
++ GOT, we don't need to generate a copy reloc. */
++ if (!h->non_got_ref)
++ return TRUE;
++
++ /* If -z nocopyreloc was given, we won't generate them either. */
++ if (info->nocopyreloc)
++ {
++ h->non_got_ref = 0;
++ return TRUE;
++ }
++
++ eh = (struct elf64_mb_link_hash_entry *) h;
++ for (p = eh->dyn_relocs; p != NULL; p = p->next)
++ {
++ s = p->sec->output_section;
++ if (s != NULL && (s->flags & SEC_READONLY) != 0)
++ break;
++ }
++
++ /* If we didn't find any dynamic relocs in read-only sections, then
++ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
++ if (p == NULL)
++ {
++ h->non_got_ref = 0;
++ return TRUE;
++ }
++
++ /* We must allocate the symbol in our .dynbss section, which will
++ become part of the .bss section of the executable. There will be
++ an entry for this symbol in the .dynsym section. The dynamic
++ object will contain position independent code, so all references
++ from the dynamic object to this symbol will go through the global
++ offset table. The dynamic linker will use the .dynsym entry to
++ determine the address it must put in the global offset table, so
++ both the dynamic object and the regular object will refer to the
++ same memory location for the variable. */
++
++ /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
++ to copy the initial value out of the dynamic object and into the
++ runtime process image. */
++ dynobj = elf_hash_table (info)->dynobj;
++ BFD_ASSERT (dynobj != NULL);
++ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
++ {
++ htab->srelbss->size += sizeof (Elf64_External_Rela);
++ h->needs_copy = 1;
++ }
++
++ /* We need to figure out the alignment required for this symbol. I
++ have no idea how ELF linkers handle this. */
++ power_of_two = bfd_log2 (h->size);
++ if (power_of_two > 3)
++ power_of_two = 3;
++
++ sdynbss = htab->sdynbss;
++ /* Apply the required alignment. */
++ sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
++ if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss))
++ {
++ if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two))
++ return FALSE;
++ }
++
++ /* Define the symbol as being at this point in the section. */
++ h->root.u.def.section = sdynbss;
++ h->root.u.def.value = sdynbss->size;
++
++ /* Increment the section size to make room for the symbol. */
++ sdynbss->size += h->size;
++ return TRUE;
++}
++
++/* Allocate space in .plt, .got and associated reloc sections for
++ dynamic relocs. */
++
++static bfd_boolean
++allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
++{
++ struct bfd_link_info *info;
++ struct elf64_mb_link_hash_table *htab;
++ struct elf64_mb_link_hash_entry *eh;
++ struct elf64_mb_dyn_relocs *p;
++
++ if (h->root.type == bfd_link_hash_indirect)
++ return TRUE;
++
++ info = (struct bfd_link_info *) dat;
++ htab = elf64_mb_hash_table (info);
++ if (htab == NULL)
++ return FALSE;
++
++ if (htab->elf.dynamic_sections_created
++ && h->plt.refcount > 0)
++ {
++ /* Make sure this symbol is output as a dynamic symbol.
++ Undefined weak syms won't yet be marked as dynamic. */
++ if (h->dynindx == -1
++ && !h->forced_local)
++ {
++ if (! bfd_elf_link_record_dynamic_symbol (info, h))
++ return FALSE;
++ }
++
++ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
++ {
++ asection *s = htab->splt;
++
++ /* The first entry in .plt is reserved. */
++ if (s->size == 0)
++ s->size = PLT_ENTRY_SIZE;
++
++ h->plt.offset = s->size;
++
++ /* If this symbol is not defined in a regular file, and we are
++ not generating a shared library, then set the symbol to this
++ location in the .plt. This is required to make function
++ pointers compare as equal between the normal executable and
++ the shared library. */
++ if (! bfd_link_pic (info)
++ && !h->def_regular)
++ {
++ h->root.u.def.section = s;
++ h->root.u.def.value = h->plt.offset;
++ }
++
++ /* Make room for this entry. */
++ s->size += PLT_ENTRY_SIZE;
++
++ /* We also need to make an entry in the .got.plt section, which
++ will be placed in the .got section by the linker script. */
++ htab->sgotplt->size += 4;
++
++ /* We also need to make an entry in the .rel.plt section. */
++ htab->srelplt->size += sizeof (Elf64_External_Rela);
++ }
++ else
++ {
++ h->plt.offset = (bfd_vma) -1;
++ h->needs_plt = 0;
++ }
++ }
++ else
++ {
++ h->plt.offset = (bfd_vma) -1;
++ h->needs_plt = 0;
++ }
++
++ eh = (struct elf64_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.
++ Undefined weak syms won't yet be marked as dynamic. */
++ if (h->dynindx == -1
++ && !h->forced_local)
++ {
++ if (! bfd_elf_link_record_dynamic_symbol (info, h))
++ return FALSE;
++ }
++
++ 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 (Elf64_External_Rela) / 4);
++ }
++ }
++ else
++ h->got.offset = (bfd_vma) -1;
++
++ if (eh->dyn_relocs == NULL)
++ return TRUE;
++
++ /* In the shared -Bsymbolic case, discard space allocated for
++ dynamic pc-relative relocs against symbols which turn out to be
++ defined in regular objects. For the normal shared case, discard
++ space for pc-relative relocs that have become local due to symbol
++ visibility changes. */
++
++ if (bfd_link_pic (info))
++ {
++ if (h->def_regular
++ && (h->forced_local
++ || info->symbolic))
++ {
++ struct elf64_mb_dyn_relocs **pp;
++
++ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
++ {
++ p->count -= p->pc_count;
++ p->pc_count = 0;
++ if (p->count == 0)
++ *pp = p->next;
++ else
++ pp = &p->next;
++ }
++ }
++ }
++ else
++ {
++ /* For the non-shared case, discard space for relocs against
++ symbols which turn out to need copy relocs or are not
++ dynamic. */
++
++ if (!h->non_got_ref
++ && ((h->def_dynamic
++ && !h->def_regular)
++ || (htab->elf.dynamic_sections_created
++ && (h->root.type == bfd_link_hash_undefweak
++ || h->root.type == bfd_link_hash_undefined))))
++ {
++ /* Make sure this symbol is output as a dynamic symbol.
++ Undefined weak syms won't yet be marked as dynamic. */
++ if (h->dynindx == -1
++ && !h->forced_local)
++ {
++ if (! bfd_elf_link_record_dynamic_symbol (info, h))
++ return FALSE;
++ }
++
++ /* If that succeeded, we know we'll be keeping all the
++ relocs. */
++ if (h->dynindx != -1)
++ goto keep;
++ }
++
++ eh->dyn_relocs = NULL;
++
++ keep: ;
++ }
++
++ /* Finally, allocate space. */
++ for (p = eh->dyn_relocs; p != NULL; p = p->next)
++ {
++ asection *sreloc = elf_section_data (p->sec)->sreloc;
++ sreloc->size += p->count * sizeof (Elf64_External_Rela);
++ }
++
++ return TRUE;
++}
++
++/* Set the sizes of the dynamic sections. */
++
++static bfd_boolean
++microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
++ struct bfd_link_info *info)
++{
++ struct elf64_mb_link_hash_table *htab;
++ bfd *dynobj;
++ asection *s;
++ bfd *ibfd;
++
++ htab = elf64_mb_hash_table (info);
++ if (htab == NULL)
++ return FALSE;
++
++ dynobj = htab->elf.dynobj;
++ BFD_ASSERT (dynobj != NULL);
++
++ /* Set up .got offsets for local syms, and space for local dynamic
++ relocs. */
++ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
++ {
++ bfd_signed_vma *local_got;
++ 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)
++ continue;
++
++ for (s = ibfd->sections; s != NULL; s = s->next)
++ {
++ struct elf64_mb_dyn_relocs *p;
++
++ for (p = ((struct elf64_mb_dyn_relocs *)
++ elf_section_data (s)->local_dynrel);
++ p != NULL;
++ p = p->next)
++ {
++ if (!bfd_is_abs_section (p->sec)
++ && bfd_is_abs_section (p->sec->output_section))
++ {
++ /* Input section has been discarded, either because
++ it is a copy of a linkonce section or due to
++ linker script /DISCARD/, so we'll be discarding
++ the relocs too. */
++ }
++ else if (p->count != 0)
++ {
++ srel = elf_section_data (p->sec)->sreloc;
++ srel->size += p->count * sizeof (Elf64_External_Rela);
++ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
++ info->flags |= DF_TEXTREL;
++ }
++ }
++ }
++
++ local_got = elf_local_got_refcounts (ibfd);
++ if (!local_got)
++ continue;
++
++ 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, ++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 (bfd_link_pic (info))
++ srel->size += need * (sizeof (Elf64_External_Rela) / 4);
++ }
++ }
++ else
++ *local_got = (bfd_vma) -1;
++ }
++ }
++
++ /* Allocate global sym .plt and .got entries, and space for global
++ 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 (bfd_link_pic (info))
++ htab->srelgot->size += sizeof (Elf64_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. */
++ if (htab->splt->size > 0)
++ htab->splt->size += 4;
++ }
++
++ /* The check_relocs and adjust_dynamic_symbol entry points have
++ determined the sizes of the various dynamic sections. Allocate
++ memory for them. */
++ for (s = dynobj->sections; s != NULL; s = s->next)
++ {
++ const char *name;
++ bfd_boolean strip = FALSE;
++
++ if ((s->flags & SEC_LINKER_CREATED) == 0)
++ continue;
++
++ /* It's OK to base decisions on the section name, because none
++ of the dynobj section names depend upon the input files. */
++ name = bfd_get_section_name (dynobj, s);
++
++ if (strncmp (name, ".rela", 5) == 0)
++ {
++ if (s->size == 0)
++ {
++ /* If we don't need this section, strip it from the
++ output file. This is to handle .rela.bss and
++ .rela.plt. We must create it in
++ create_dynamic_sections, because it must be created
++ before the linker maps input sections to output
++ sections. The linker does that before
++ adjust_dynamic_symbol is called, and it is that
++ function which decides whether anything needs to go
++ into these sections. */
++ strip = TRUE;
++ }
++ else
++ {
++ /* We use the reloc_count field as a counter if we need
++ to copy relocs into the output file. */
++ s->reloc_count = 0;
++ }
++ }
++ else if (s != htab->splt && s != htab->sgot && s != htab->sgotplt)
++ {
++ /* It's not one of our sections, so don't allocate space. */
++ continue;
++ }
++
++ if (strip)
++ {
++ s->flags |= SEC_EXCLUDE;
++ continue;
++ }
++
++ /* Allocate memory for the section contents. */
++ /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
++ Unused entries should be reclaimed before the section's contents
++ are written out, but at the moment this does not happen. Thus in
++ order to prevent writing out garbage, we initialise the section's
++ contents to zero. */
++ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
++ if (s->contents == NULL && s->size != 0)
++ return FALSE;
++ }
++
++ if (elf_hash_table (info)->dynamic_sections_created)
++ {
++ /* Add some entries to the .dynamic section. We fill in the
++ values later, in microblaze_elf_finish_dynamic_sections, but we
++ must add the entries now so that we get the correct size for
++ the .dynamic section. The DT_DEBUG entry is filled in by the
++ dynamic linker and used by the debugger. */
++#define add_dynamic_entry(TAG, VAL) \
++ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
++
++ if (bfd_link_executable (info))
++ {
++ if (!add_dynamic_entry (DT_DEBUG, 0))
++ return FALSE;
++ }
++
++ if (!add_dynamic_entry (DT_RELA, 0)
++ || !add_dynamic_entry (DT_RELASZ, 0)
++ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
++ return FALSE;
++
++ if (htab->splt->size != 0)
++ {
++ if (!add_dynamic_entry (DT_PLTGOT, 0)
++ || !add_dynamic_entry (DT_PLTRELSZ, 0)
++ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
++ || !add_dynamic_entry (DT_JMPREL, 0)
++ || !add_dynamic_entry (DT_BIND_NOW, 1))
++ return FALSE;
++ }
++
++ if (info->flags & DF_TEXTREL)
++ {
++ if (!add_dynamic_entry (DT_TEXTREL, 0))
++ return FALSE;
++ }
++ }
++#undef add_dynamic_entry
++ return TRUE;
++}
++
++/* Finish up dynamic symbol handling. We set the contents of various
++ dynamic sections here. */
++
++static bfd_boolean
++microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
++ struct bfd_link_info *info,
++ struct elf_link_hash_entry *h,
++ Elf_Internal_Sym *sym)
++{
++ struct elf64_mb_link_hash_table *htab;
++ struct elf64_mb_link_hash_entry *eh = elf64_mb_hash_entry(h);
++
++ htab = elf64_mb_hash_table (info);
++ if (htab == NULL)
++ return FALSE;
++
++ if (h->plt.offset != (bfd_vma) -1)
++ {
++ asection *splt;
++ asection *srela;
++ asection *sgotplt;
++ Elf_Internal_Rela rela;
++ bfd_byte *loc;
++ bfd_vma plt_index;
++ bfd_vma got_offset;
++ bfd_vma got_addr;
++
++ /* This symbol has an entry in the procedure linkage table. Set
++ it up. */
++ BFD_ASSERT (h->dynindx != -1);
++
++ splt = htab->splt;
++ srela = htab->srelplt;
++ sgotplt = htab->sgotplt;
++ BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
++
++ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
++ got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
++ got_addr = got_offset;
++
++ /* For non-PIC objects we need absolute address of the GOT entry. */
++ if (!bfd_link_pic (info))
++ got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset;
++
++ /* Fill in the entry in the procedure linkage table. */
++ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
++ splt->contents + h->plt.offset);
++ if (bfd_link_pic (info))
++ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
++ splt->contents + h->plt.offset + 4);
++ else
++ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
++ splt->contents + h->plt.offset + 4);
++ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
++ splt->contents + h->plt.offset + 8);
++ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
++ splt->contents + h->plt.offset + 12);
++
++ /* Any additions to the .got section??? */
++ /* bfd_put_32 (output_bfd,
++ splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
++ sgotplt->contents + got_offset); */
++
++ /* Fill in the entry in the .rela.plt section. */
++ rela.r_offset = (sgotplt->output_section->vma
++ + sgotplt->output_offset
++ + got_offset);
++ rela.r_info = ELF64_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
++ rela.r_addend = 0;
++ loc = srela->contents;
++ loc += plt_index * sizeof (Elf64_External_Rela);
++ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
++
++ if (!h->def_regular)
++ {
++ /* Mark the symbol as undefined, rather than as defined in
++ the .plt section. Zero the value. */
++ sym->st_shndx = SHN_UNDEF;
++ sym->st_value = 0;
++ }
++ }
++
++ /* 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;
++ bfd_vma offset;
++
++ /* This symbol has an entry in the global offset table. Set it
++ up. */
++
++ sgot = htab->sgot;
++ srela = htab->srelgot;
++ BFD_ASSERT (sgot != NULL && srela != NULL);
++
++ 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
++ locally, we just want to emit a RELATIVE reloc. Likewise if
++ the symbol was forced to be local because of a version file.
++ The entry in the global offset table will already have been
++ initialized in the relocate_section function. */
++ if (bfd_link_pic (info)
++ && ((info->symbolic && h->def_regular)
++ || h->dynindx == -1))
++ {
++ asection *sec = h->root.u.def.section;
++ 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
++ {
++ 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));
++ }
++
++ if (h->needs_copy)
++ {
++ asection *s;
++ Elf_Internal_Rela rela;
++ bfd_byte *loc;
++
++ /* This symbols needs a copy reloc. Set it up. */
++
++ BFD_ASSERT (h->dynindx != -1);
++
++ s = bfd_get_linker_section (htab->elf.dynobj, ".rela.bss");
++ BFD_ASSERT (s != NULL);
++
++ rela.r_offset = (h->root.u.def.value
++ + h->root.u.def.section->output_section->vma
++ + h->root.u.def.section->output_offset);
++ rela.r_info = ELF64_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
++ rela.r_addend = 0;
++ loc = s->contents + s->reloc_count++ * sizeof (Elf64_External_Rela);
++ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
++ }
++
++ /* Mark some specially defined symbols as absolute. */
++ if (h == htab->elf.hdynamic
++ || h == htab->elf.hgot
++ || h == htab->elf.hplt)
++ sym->st_shndx = SHN_ABS;
++
++ return TRUE;
++}
++
++
++/* Finish up the dynamic sections. */
++
++static bfd_boolean
++microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
++ struct bfd_link_info *info)
++{
++ bfd *dynobj;
++ asection *sdyn, *sgot;
++ struct elf64_mb_link_hash_table *htab;
++
++ htab = elf64_mb_hash_table (info);
++ if (htab == NULL)
++ return FALSE;
++
++ dynobj = htab->elf.dynobj;
++
++ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
++
++ if (htab->elf.dynamic_sections_created)
++ {
++ asection *splt;
++ Elf64_External_Dyn *dyncon, *dynconend;
++
++ splt = bfd_get_linker_section (dynobj, ".plt");
++ BFD_ASSERT (splt != NULL && sdyn != NULL);
++
++ dyncon = (Elf64_External_Dyn *) sdyn->contents;
++ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
++ for (; dyncon < dynconend; dyncon++)
++ {
++ Elf_Internal_Dyn dyn;
++ const char *name;
++ bfd_boolean size;
++
++ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
++
++ switch (dyn.d_tag)
++ {
++ case DT_PLTGOT: name = ".got.plt"; size = FALSE; break;
++ case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
++ case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
++ case DT_RELA: name = ".rela.dyn"; size = FALSE; break;
++ case DT_RELASZ: name = ".rela.dyn"; size = TRUE; break;
++ default: name = NULL; size = FALSE; break;
++ }
++
++ if (name != NULL)
++ {
++ asection *s;
++
++ s = bfd_get_section_by_name (output_bfd, name);
++ if (s == NULL)
++ dyn.d_un.d_val = 0;
++ else
++ {
++ if (! size)
++ dyn.d_un.d_ptr = s->vma;
++ else
++ dyn.d_un.d_val = s->size;
++ }
++ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
++ }
++ }
++
++ /* Clear the first entry in the procedure linkage table,
++ and put a nop in the last four bytes. */
++ if (splt->size > 0)
++ {
++ memset (splt->contents, 0, PLT_ENTRY_SIZE);
++ bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
++ splt->contents + splt->size - 4);
++ }
++
++ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
++ }
++
++ /* Set the first entry in the global offset table to the address of
++ the dynamic section. */
++ sgot = bfd_get_linker_section (dynobj, ".got.plt");
++ if (sgot && sgot->size > 0)
++ {
++ if (sdyn == NULL)
++ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
++ else
++ bfd_put_32 (output_bfd,
++ sdyn->output_section->vma + sdyn->output_offset,
++ sgot->contents);
++ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
++ }
++
++ if (htab->sgot && htab->sgot->size > 0)
++ elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
++
++ return TRUE;
++}
++
++/* Hook called by the linker routine which adds symbols from an object
++ file. We use it to put .comm items in .sbss, and not .bss. */
++
++static bfd_boolean
++microblaze_elf_add_symbol_hook (bfd *abfd,
++ struct bfd_link_info *info,
++ Elf_Internal_Sym *sym,
++ const char **namep ATTRIBUTE_UNUSED,
++ flagword *flagsp ATTRIBUTE_UNUSED,
++ asection **secp,
++ bfd_vma *valp)
++{
++ if (sym->st_shndx == SHN_COMMON
++ && !bfd_link_relocatable (info)
++ && sym->st_size <= elf_gp_size (abfd))
++ {
++ /* Common symbols less than or equal to -G nn bytes are automatically
++ put into .sbss. */
++ *secp = bfd_make_section_old_way (abfd, ".sbss");
++ if (*secp == NULL
++ || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON))
++ return FALSE;
++
++ *valp = sym->st_size;
++ }
++
++ return TRUE;
++}
++
++#define TARGET_LITTLE_SYM microblaze_elf64_le_vec
++#define TARGET_LITTLE_NAME "elf64-microblazeel"
++
++#define TARGET_BIG_SYM microblaze_elf64_vec
++#define TARGET_BIG_NAME "elf64-microblaze"
++
++#define ELF_ARCH bfd_arch_microblaze
++#define ELF_TARGET_ID MICROBLAZE_ELF_DATA
++#define ELF_MACHINE_CODE EM_MICROBLAZE
++#define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
++#define ELF_MAXPAGESIZE 0x1000
++#define elf_info_to_howto microblaze_elf_info_to_howto
++#define elf_info_to_howto_rel NULL
++
++#define bfd_elf64_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
++#define bfd_elf64_bfd_is_local_label_name microblaze_elf_is_local_label_name
++#define elf_backend_relocate_section microblaze_elf_relocate_section
++#define bfd_elf64_bfd_relax_section microblaze_elf_relax_section
++#define bfd_elf64_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data
++#define bfd_elf64_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
++
++#define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
++#define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
++#define elf_backend_check_relocs microblaze_elf_check_relocs
++#define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
++#define bfd_elf64_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
++#define elf_backend_can_gc_sections 1
++#define elf_backend_can_refcount 1
++#define elf_backend_want_got_plt 1
++#define elf_backend_plt_readonly 1
++#define elf_backend_got_header_size 12
++#define elf_backend_rela_normal 1
++
++#define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
++#define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
++#define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
++#define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
++#define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
++#define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
++
++#include "elf64-target.h"
+diff --git a/bfd/targets.c b/bfd/targets.c
+index 531703d..8ddbd39 100644
+--- a/bfd/targets.c
++++ b/bfd/targets.c
+@@ -704,6 +704,8 @@ extern const bfd_target mep_elf32_le_vec;
+ extern const bfd_target metag_elf32_vec;
+ extern const bfd_target microblaze_elf32_vec;
+ extern const bfd_target microblaze_elf32_le_vec;
++extern const bfd_target microblaze_elf64_vec;
++extern const bfd_target microblaze_elf64_le_vec;
+ extern const bfd_target mips_ecoff_be_vec;
+ extern const bfd_target mips_ecoff_le_vec;
+ extern const bfd_target mips_ecoff_bele_vec;
+@@ -1067,6 +1069,10 @@ static const bfd_target * const _bfd_target_vector[] =
+
+ &metag_elf32_vec,
+
++#ifdef BFD64
++ &microblaze_elf64_vec,
++ &microblaze_elf64_le_vec,
++#endif
+ &microblaze_elf32_vec,
+
+ &mips_ecoff_be_vec,
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index f1d97b9..eb7998f 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -35,10 +35,13 @@
+ #define streq(a,b) (strcmp (a, b) == 0)
+ #endif
+
++static int microblaze_arch_size = 0;
++
+ #define OPTION_EB (OPTION_MD_BASE + 0)
+ #define OPTION_EL (OPTION_MD_BASE + 1)
+ #define OPTION_LITTLE (OPTION_MD_BASE + 2)
+ #define OPTION_BIG (OPTION_MD_BASE + 3)
++#define OPTION_M64 (OPTION_MD_BASE + 4)
+
+ void microblaze_generate_symbol (char *sym);
+ static bfd_boolean check_spl_reg (unsigned *);
+@@ -773,6 +776,74 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
+ return new_pointer;
+ }
+
++ static char *
++parse_imml (char * s, expressionS * e, long min, long 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++)
++ if (is_end_of_line[(unsigned char) *atp])
++ break;
++
++ if (*atp == '@')
++ {
++ itype = match_imm (atp + 1, &ilen);
++ if (itype != 0)
++ {
++ *atp = 0;
++ e->X_md = itype;
++ }
++ else
++ {
++ atp = NULL;
++ e->X_md = 0;
++ ilen = 0;
++ }
++ *atp = 0;
++ }
++ else
++ {
++ atp = NULL;
++ e->X_md = 0;
++ }
++
++ if (atp && !GOT_symbol)
++ {
++ GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
++ }
++
++ 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) )
++ as_fatal (_("operand must be a constant or a label"));
++ else if ((e->X_op == O_constant) && ((long) e->X_add_number < min
++ || (long) e->X_add_number > max))
++ {
++ as_fatal (_("operand must be absolute in range %ld..%ld, not %ld"),
++ min, max, (long) e->X_add_number);
++ }
++
++ if (atp)
++ {
++ *atp = '@'; /* restore back (needed?) */
++ if (new_pointer >= atp)
++ new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */
++ }
++ return new_pointer;
++}
++
+ static char *
+ check_got (int * got_type, int * got_len)
+ {
+@@ -920,6 +991,7 @@ md_assemble (char * str)
+ unsigned int immed, immed2, temp;
+ expressionS exp;
+ char name[20];
++ long immedl;
+
+ /* Drop leading whitespace. */
+ while (ISSPACE (* str))
+@@ -1129,7 +1201,7 @@ md_assemble (char * str)
+ }
+ break;
+
+- case INST_TYPE_RD_R1_IMM5:
++ case INST_TYPE_RD_R1_IMMS:
+ if (strcmp (op_end, ""))
+ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
+ else
+@@ -1163,16 +1235,22 @@ md_assemble (char * str)
+ immed = exp.X_add_number;
+ }
+
+- if (immed != (immed % 32))
++ if ((immed != (immed % 32)) &&
++ (opcode->instr == bslli || opcode->instr == bsrai || opcode->instr == bsrli))
+ {
+ as_warn (_("Shift value > 32. using <value %% 32>"));
+ immed = immed % 32;
+ }
++ else if (immed != (immed % 64))
++ {
++ as_warn (_("Shift value > 64. using <value %% 64>"));
++ immed = immed % 64;
++ }
+ inst |= (reg1 << RD_LOW) & RD_MASK;
+ inst |= (reg2 << RA_LOW) & RA_MASK;
+- inst |= (immed << IMM_LOW) & IMM5_MASK;
++ inst |= (immed << IMM_LOW) & IMM6_MASK;
+ break;
+- case INST_TYPE_RD_R1_IMM5_IMM5:
++ case INST_TYPE_RD_R1_IMMW_IMMS:
+ if (strcmp (op_end, ""))
+ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
+ else
+@@ -1196,7 +1274,7 @@ md_assemble (char * str)
+
+ /* Width immediate value. */
+ if (strcmp (op_end, ""))
+- op_end = parse_imm (op_end + 1, &exp, MIN_IMM_WIDTH, MAX_IMM_WIDTH);
++ op_end = parse_imm (op_end + 1, &exp, MIN_IMM, MAX_IMM);
+ else
+ as_fatal (_("Error in statement syntax"));
+ if (exp.X_op != O_constant)
+@@ -1208,6 +1286,8 @@ md_assemble (char * str)
+ immed = exp.X_add_number;
+ if (opcode->instr == bsefi && immed > 31)
+ as_fatal (_("Width value must be less than 32"));
++ else if (opcode->instr == bslefi && immed > 63)
++ as_fatal (_("Width value must be less than 64"));
+
+ /* Shift immediate value. */
+ if (strcmp (op_end, ""))
+@@ -1215,32 +1295,40 @@ md_assemble (char * str)
+ else
+ as_fatal (_("Error in statement syntax"));
+ if (exp.X_op != O_constant)
+- {
++ {
+ as_warn (_("Symbol used as immediate shift value for bit field instruction"));
+ immed2 = 0;
+ }
+ else
+- {
++ {
+ output = frag_more (isize);
+ immed2 = exp.X_add_number;
+- }
+- if (immed2 != (immed2 % 32))
+- {
+- as_warn (_("Shift value greater than 32. using <value %% 32>"));
++ }
++ if ((immed2 != (immed2 % 32)) && (opcode->instr == bsefi || opcode->instr == bsifi))
++ {
++
++ as_warn (_("Shift value greater than 32. using <value %% 32>"));
+ immed2 = immed2 % 32;
+ }
++ else if (immed2 != (immed2 % 64))
++ {
++ as_warn (_("Shift value greater than 64. using <value %% 64>"));
++ immed2 = immed2 % 64;
++ }
+
+ /* Check combined value. */
+- if (immed + immed2 > 32)
++ if ((immed + immed2 > 32) && (opcode->instr == bsefi || opcode->instr == bsifi))
+ as_fatal (_("Width value + shift value must not be greater than 32"));
+
++ else if (immed + immed2 > 64)
++ as_fatal (_("Width value + shift value must not be greater than 64"));
+ inst |= (reg1 << RD_LOW) & RD_MASK;
+ inst |= (reg2 << RA_LOW) & RA_MASK;
+- if (opcode->instr == bsefi)
+- inst |= (immed & IMM5_MASK) << IMM_WIDTH_LOW; /* bsefi */
++ if (opcode->instr == bsefi || opcode->instr == bslefi)
++ inst |= (immed & IMM6_MASK) << IMM_WIDTH_LOW; /* bsefi or bslefi */
+ else
+- inst |= ((immed + immed2 - 1) & IMM5_MASK) << IMM_WIDTH_LOW; /* bsifi */
+- inst |= (immed2 << IMM_LOW) & IMM5_MASK;
++ inst |= ((immed + immed2 - 1) & IMM6_MASK) << IMM_WIDTH_LOW; /* bsifi or bslifi */
++ inst |= (immed2 << IMM_LOW) & IMM6_MASK;
+ break;
+ case INST_TYPE_R1_R2:
+ if (strcmp (op_end, ""))
+@@ -1808,6 +1896,142 @@ md_assemble (char * str)
+ }
+ inst |= (immed << IMM_MBAR);
+ break;
++ /* For 64-bit instructions */
++ case INST_TYPE_RD_R1_IMML:
++ if (strcmp (op_end, ""))
++ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
++ else
++ {
++ as_fatal (_("Error in statement syntax"));
++ reg1 = 0;
++ }
++ if (strcmp (op_end, ""))
++ op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
++ else
++ {
++ as_fatal (_("Error in statement syntax"));
++ reg2 = 0;
++ }
++ if (strcmp (op_end, ""))
++ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
++ else
++ as_fatal (_("Error in statement syntax"));
++
++ /* Check for spl registers. */
++ if (check_spl_reg (& reg1))
++ as_fatal (_("Cannot use special register with this instruction"));
++ if (check_spl_reg (& reg2))
++ as_fatal (_("Cannot use special register with this instruction"));
++
++ if (exp.X_op != O_constant)
++ {
++ char *opc = NULL;
++ relax_substateT subtype;
++
++ 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 * 2, /* minm of 2 words. */
++ subtype, /* PC-relative or not. */
++ exp.X_add_symbol,
++ exp.X_add_number,
++ opc);
++ immedl = 0L;
++ }
++ else
++ {
++ output = frag_more (isize);
++ immedl = exp.X_add_number;
++
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imml");
++ return;
++ }
++
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
++ }
++
++ inst |= (reg1 << RD_LOW) & RD_MASK;
++ inst |= (reg2 << RA_LOW) & RA_MASK;
++ inst |= (immedl << IMM_LOW) & IMM_MASK;
++ break;
++
++ case INST_TYPE_R1_IMML:
++ if (strcmp (op_end, ""))
++ op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
++ else
++ {
++ as_fatal (_("Error in statement syntax"));
++ reg1 = 0;
++ }
++ if (strcmp (op_end, ""))
++ op_end = parse_imml (op_end + 1, & exp, MIN_IMM, MAX_IMM);
++ else
++ as_fatal (_("Error in statement syntax"));
++
++ /* Check for spl registers. */
++ if (check_spl_reg (&reg1))
++ as_fatal (_("Cannot use special register with this instruction"));
++
++ if (exp.X_op != O_constant)
++ {
++ char *opc = NULL;
++ relax_substateT subtype;
++
++ 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 * 2, /* minm of 2 words. */
++ subtype, /* PC-relative or not. */
++ exp.X_add_symbol,
++ exp.X_add_number,
++ opc);
++ immedl = 0L;
++ }
++ else
++ {
++ output = frag_more (isize);
++ immedl = exp.X_add_number;
++
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imml");
++ return;
++ }
++
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
++ }
++
++ inst |= (reg1 << RA_LOW) & RA_MASK;
++ inst |= (immedl << IMM_LOW) & IMM_MASK;
++ break;
++
++ case INST_TYPE_IMML:
++ as_fatal (_("An IMML instruction should not be present in the .s file"));
++ break;
+
+ default:
+ as_fatal (_("unimplemented opcode \"%s\""), name);
+@@ -1918,6 +2142,7 @@ struct option md_longopts[] =
+ {"EL", no_argument, NULL, OPTION_EL},
+ {"mlittle-endian", no_argument, NULL, OPTION_LITTLE},
+ {"mbig-endian", no_argument, NULL, OPTION_BIG},
++ {"m64", no_argument, NULL, OPTION_M64},
+ { NULL, no_argument, NULL, 0}
+ };
+
+@@ -2569,6 +2794,18 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
+ return rel;
+ }
+
++/* Called by TARGET_FORMAT. */
++const char *
++microblaze_target_format (void)
++{
++
++ if (microblaze_arch_size == 64)
++ return "elf64-microblazeel";
++ else
++ return target_big_endian ? "elf32-microblaze" : "elf32-microblazeel";
++}
++
++
+ int
+ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
+ {
+@@ -2582,6 +2819,10 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
+ case OPTION_LITTLE:
+ target_big_endian = 0;
+ break;
++ case OPTION_M64:
++ //if (arg != NULL && strcmp (arg, "64") == 0)
++ microblaze_arch_size = 64;
++ break;
+ default:
+ return 0;
+ }
+@@ -2597,6 +2838,7 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
+ fprintf (stream, _(" MicroBlaze specific assembler options:\n"));
+ fprintf (stream, " -%-23s%s\n", "mbig-endian", N_("assemble for a big endian cpu"));
+ fprintf (stream, " -%-23s%s\n", "mlittle-endian", N_("assemble for a little endian cpu"));
++ fprintf (stream, " -%-23s%s\n", "m64", N_("generate 64-bit elf"));
+ }
+
+
+diff --git a/gas/config/tc-microblaze.h b/gas/config/tc-microblaze.h
+index 1263f57..7a991ae 100644
+--- a/gas/config/tc-microblaze.h
++++ b/gas/config/tc-microblaze.h
+@@ -78,7 +78,9 @@ extern const struct relax_type md_relax_table[];
+
+ #ifdef OBJ_ELF
+
+-#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblazeel")
++#define TARGET_FORMAT microblaze_target_format()
++extern const char *microblaze_target_format (void);
++//#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/include/elf/common.h b/include/elf/common.h
+index 773f378..cd2114e 100644
+--- a/include/elf/common.h
++++ b/include/elf/common.h
+@@ -339,6 +339,7 @@
+ #define EM_RISCV 243 /* RISC-V */
+ #define EM_LANAI 244 /* Lanai 32-bit processor. */
+ #define EM_BPF 247 /* Linux BPF – in-kernel virtual machine. */
++#define EM_MB_64 248 /* Xilinx MicroBlaze 32-bit RISC soft processor core */
+ #define EM_NFP 250 /* Netronome Flow Processor. */
+
+ /* If it is necessary to assign new unofficial EM_* values, please pick large
+diff --git a/ld/Makefile.am b/ld/Makefile.am
+index d86ad09..f531471 100644
+--- a/ld/Makefile.am
++++ b/ld/Makefile.am
+@@ -420,6 +420,8 @@ ALL_64_EMULATION_SOURCES = \
+ eelf32ltsmipn32.c \
+ eelf32ltsmipn32_fbsd.c \
+ eelf32mipswindiss.c \
++ eelf64microblazeel.c \
++ eelf64microblaze.c \
+ eelf64_aix.c \
+ eelf64_ia64.c \
+ eelf64_ia64_fbsd.c \
+@@ -1688,6 +1690,12 @@ eelf32_x86_64_nacl.c: $(srcdir)/emulparams/elf32_x86_64_nacl.sh \
+ $(srcdir)/emulparams/elf_nacl.sh \
+ $(ELF_X86_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
++eelf64microblazeel.c: $(srcdir)/emulparams/elf64microblazeel.sh \
++ $(ELF_DEPS) $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
++
++eelf64microblaze.c: $(srcdir)/emulparams/elf64microblaze.sh \
++ $(ELF_DEPS) $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
++
+ eelf64_aix.c: $(srcdir)/emulparams/elf64_aix.sh \
+ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
+diff --git a/ld/Makefile.in b/ld/Makefile.in
+index 4792b2b..1f75a81 100644
+--- a/ld/Makefile.in
++++ b/ld/Makefile.in
+@@ -905,6 +905,8 @@ ALL_64_EMULATION_SOURCES = \
+ eelf32ltsmipn32.c \
+ eelf32ltsmipn32_fbsd.c \
+ eelf32mipswindiss.c \
++ eelf64microblazeel.c \
++ eelf64microblaze.c \
+ eelf64_aix.c \
+ eelf64_ia64.c \
+ eelf64_ia64_fbsd.c \
+@@ -1350,6 +1352,8 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xc16xs.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xstormy16.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblazeel.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64microblaze.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Po@am__quote@
+@@ -3289,6 +3293,12 @@ eelf32_x86_64_nacl.c: $(srcdir)/emulparams/elf32_x86_64_nacl.sh \
+ $(srcdir)/emulparams/elf_nacl.sh \
+ $(ELF_X86_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
++eelf64microblazeel.c: $(srcdir)/emulparams/elf64microblazeel.sh \
++ $(ELF_DEPS) $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
++
++eelf64microblaze.c: $(srcdir)/emulparams/elf64microblaze.sh \
++ $(ELF_DEPS) $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
++
+ eelf64_aix.c: $(srcdir)/emulparams/elf64_aix.sh \
+ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
+diff --git a/ld/configure.tgt b/ld/configure.tgt
+index fad8b2e..25615ea 100644
+--- a/ld/configure.tgt
++++ b/ld/configure.tgt
+@@ -419,6 +419,9 @@ microblaze*-linux*) targ_emul="elf32mb_linux"
+ microblazeel*) targ_emul=elf32microblazeel
+ targ_extra_emuls=elf32microblaze
+ ;;
++microblazeel64*) targ_emul=elf64microblazeel
++ targ_extra_emuls=elf64microblaze
++ ;;
+ microblaze*) targ_emul=elf32microblaze
+ targ_extra_emuls=elf32microblazeel
+ ;;
+diff --git a/ld/emulparams/elf64microblaze.sh b/ld/emulparams/elf64microblaze.sh
+new file mode 100644
+index 0000000..9c7b0eb
+--- /dev/null
++++ b/ld/emulparams/elf64microblaze.sh
+@@ -0,0 +1,23 @@
++SCRIPT_NAME=elfmicroblaze
++OUTPUT_FORMAT="elf64-microblazeel"
++#BIG_OUTPUT_FORMAT="elf64-microblaze"
++LITTLE_OUTPUT_FORMAT="elf64-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
+diff --git a/ld/emulparams/elf64microblazeel.sh b/ld/emulparams/elf64microblazeel.sh
+new file mode 100644
+index 0000000..9c7b0eb
+--- /dev/null
++++ b/ld/emulparams/elf64microblazeel.sh
+@@ -0,0 +1,23 @@
++SCRIPT_NAME=elfmicroblaze
++OUTPUT_FORMAT="elf64-microblazeel"
++#BIG_OUTPUT_FORMAT="elf64-microblaze"
++LITTLE_OUTPUT_FORMAT="elf64-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
+diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
+index 5101ceb..09757d1 100644
+--- a/opcodes/microblaze-dis.c
++++ b/opcodes/microblaze-dis.c
+@@ -33,6 +33,7 @@
+ #define get_field_r1(instr) get_field (instr, RA_MASK, RA_LOW)
+ #define get_field_r2(instr) get_field (instr, RB_MASK, RB_LOW)
+ #define get_int_field_imm(instr) ((instr & IMM_MASK) >> IMM_LOW)
++#define get_int_field_imml(instr) ((instr & IMML_MASK) >> IMM_LOW)
+ #define get_int_field_r1(instr) ((instr & RA_MASK) >> RA_LOW)
+
+
+@@ -56,11 +57,20 @@ get_field_imm (long instr)
+ }
+
+ static char *
+-get_field_imm5 (long instr)
++get_field_imml (long instr)
+ {
+ char tmpstr[25];
+
+- sprintf (tmpstr, "%d", (short)((instr & IMM5_MASK) >> IMM_LOW));
++ sprintf (tmpstr, "%d", (short)((instr & IMML_MASK) >> IMM_LOW));
++ return (strdup (tmpstr));
++}
++
++static char *
++get_field_imms (long instr)
++{
++ char tmpstr[25];
++
++ sprintf (tmpstr, "%d", (short)((instr & IMM6_MASK) >> IMM_LOW));
+ return (strdup (tmpstr));
+ }
+
+@@ -74,14 +84,14 @@ get_field_imm5_mbar (long instr)
+ }
+
+ static char *
+-get_field_imm5width (long instr)
++get_field_immw (long instr)
+ {
+ char tmpstr[25];
+
+ if (instr & 0x00004000)
+- sprintf (tmpstr, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW))); /* bsefi */
++ sprintf (tmpstr, "%d", (short)(((instr & IMM6_WIDTH_MASK) >> IMM_WIDTH_LOW))); /* bsefi */
+ else
+- sprintf (tmpstr, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW) - ((instr & IMM5_MASK) >> IMM_LOW) + 1)); /* bsifi */
++ sprintf (tmpstr, "%d", (short)(((instr & IMM6_WIDTH_MASK) >> IMM_WIDTH_LOW) - ((instr & IMM6_MASK) >> IMM_LOW) + 1)); /* bsifi */
+ return (strdup (tmpstr));
+ }
+
+@@ -286,9 +296,13 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
+ }
+ }
+ break;
+- case INST_TYPE_RD_R1_IMM5:
++ case INST_TYPE_RD_R1_IMML:
++ print_func (stream, "\t%s, %s, %s", get_field_rd (inst),
++ get_field_r1(inst), get_field_imm (inst));
++ /* TODO: Also print symbol */
++ case INST_TYPE_RD_R1_IMMS:
+ print_func (stream, "\t%s, %s, %s", get_field_rd (inst),
+- get_field_r1(inst), get_field_imm5 (inst));
++ get_field_r1(inst), get_field_imms (inst));
+ break;
+ case INST_TYPE_RD_RFSL:
+ print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_rfsl (inst));
+@@ -386,6 +400,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
+ }
+ }
+ break;
++ case INST_TYPE_IMML:
++ print_func (stream, "\t%s", get_field_imml (inst));
++ /* TODO: Also print symbol */
++ break;
+ case INST_TYPE_RD_R2:
+ print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_r2 (inst));
+ break;
+@@ -409,9 +427,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
+ case INST_TYPE_NONE:
+ break;
+ /* For bit field insns. */
+- case INST_TYPE_RD_R1_IMM5_IMM5:
+- print_func (stream, "\t%s, %s, %s, %s", get_field_rd (inst),get_field_r1(inst),get_field_imm5width (inst), get_field_imm5 (inst));
+- break;
++ case INST_TYPE_RD_R1_IMMW_IMMS:
++ print_func (stream, "\t%s, %s, %s, %s", get_field_rd (inst), get_field_r1(inst),
++ get_field_immw (inst), get_field_imms (inst));
++ 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 4bc400a..c88092d 100644
+--- a/opcodes/microblaze-opc.h
++++ b/opcodes/microblaze-opc.h
+@@ -40,7 +40,7 @@
+ #define INST_TYPE_RD_SPECIAL 11
+ #define INST_TYPE_R1 12
+ /* New instn type for barrel shift imms. */
+-#define INST_TYPE_RD_R1_IMM5 13
++#define INST_TYPE_RD_R1_IMMS 13
+ #define INST_TYPE_RD_RFSL 14
+ #define INST_TYPE_R1_RFSL 15
+
+@@ -60,7 +60,13 @@
+ #define INST_TYPE_IMM5 20
+
+ /* For bsefi and bsifi */
+-#define INST_TYPE_RD_R1_IMM5_IMM5 21
++#define INST_TYPE_RD_R1_IMMW_IMMS 21
++
++/* For 64-bit instructions */
++#define INST_TYPE_IMML 22
++#define INST_TYPE_RD_R1_IMML 23
++#define INST_TYPE_R1_IMML 24
++#define INST_TYPE_RD_R1_IMMW_IMMS 21
+
+ #define INST_TYPE_NONE 25
+
+@@ -91,13 +97,14 @@
+ #define OPCODE_MASK_H24 0xFC1F07FF /* High 6, bits 20-16 and low 11 bits. */
+ #define OPCODE_MASK_H124 0xFFFF07FF /* High 16, and low 11 bits. */
+ #define OPCODE_MASK_H1234 0xFFFFFFFF /* All 32 bits. */
+-#define OPCODE_MASK_H3 0xFC000600 /* High 6 bits and bits 21, 22. */
+-#define OPCODE_MASK_H3B 0xFC00C600 /* High 6 bits and bits 16, 17, 21, 22. */
++#define OPCODE_MASK_H3 0xFC000700 /* High 6 bits and bits 21, 22, 23. */
++#define OPCODE_MASK_H3B 0xFC00E600 /* High 6 bits and bits 16, 17, 18, 21, 22. */
+ #define OPCODE_MASK_H32 0xFC00FC00 /* High 6 bits and bit 16-21. */
+-#define OPCODE_MASK_H32B 0xFC00C000 /* High 6 bits and bit 16, 17. */
++#define OPCODE_MASK_H32B 0xFC00E000 /* High 6 bits and bit 16, 17, 18. */
+ #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits. */
+ #define OPCODE_MASK_H35B 0xFC0004FF /* High 6 bits and low 9 bits. */
+ #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */
++#define OPCODE_MASK_H8 0xFF000000 /* High 8 bits only. */
+
+ /* New Mask for msrset, msrclr insns. */
+ #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */
+@@ -107,7 +114,7 @@
+ #define DELAY_SLOT 1
+ #define NO_DELAY_SLOT 0
+
+-#define MAX_OPCODES 301
++#define MAX_OPCODES 412
+
+ struct op_code_struct
+ {
+@@ -125,6 +132,7 @@ struct op_code_struct
+ /* More info about output format here. */
+ } opcodes[MAX_OPCODES] =
+ {
++ /* 32-bit instructions */
+ {"add", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000000, OPCODE_MASK_H4, add, arithmetic_inst },
+ {"rsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H4, rsub, arithmetic_inst },
+ {"addc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000000, OPCODE_MASK_H4, addc, arithmetic_inst },
+@@ -161,11 +169,11 @@ struct op_code_struct
+ {"ncget", INST_TYPE_RD_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C006000, OPCODE_MASK_H32, ncget, anyware_inst },
+ {"ncput", INST_TYPE_R1_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00E000, OPCODE_MASK_H32, ncput, anyware_inst },
+ {"muli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x60000000, OPCODE_MASK_H, muli, mult_inst },
+- {"bslli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3, bslli, barrel_shift_inst },
+- {"bsrai", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3, bsrai, barrel_shift_inst },
+- {"bsrli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3, bsrli, barrel_shift_inst },
+- {"bsefi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64004000, OPCODE_MASK_H32B, bsefi, barrel_shift_inst },
+- {"bsifi", INST_TYPE_RD_R1_IMM5_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64008000, OPCODE_MASK_H32B, bsifi, barrel_shift_inst },
++ {"bslli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3B, bslli, barrel_shift_inst },
++ {"bsrai", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3B, bsrai, barrel_shift_inst },
++ {"bsrli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3B, bsrli, barrel_shift_inst },
++ {"bsefi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64004000, OPCODE_MASK_H32B, bsefi, barrel_shift_inst },
++ {"bsifi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64008000, OPCODE_MASK_H32B, bsifi, barrel_shift_inst },
+ {"or", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H4, microblaze_or, logical_inst },
+ {"and", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000000, OPCODE_MASK_H4, microblaze_and, logical_inst },
+ {"xor", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000000, OPCODE_MASK_H4, microblaze_xor, logical_inst },
+@@ -425,6 +433,129 @@ struct op_code_struct
+ {"suspend", INST_TYPE_NONE, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBB020004, OPCODE_MASK_HN, invalid_inst, special_inst }, /* translates to mbar 24. */
+ {"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 },
++
++ /* 64-bit instructions */
++ {"addl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000100, OPCODE_MASK_H4, addl, arithmetic_inst },
++ {"rsubl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000100, OPCODE_MASK_H4, rsubl, arithmetic_inst },
++ {"addlc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000100, OPCODE_MASK_H4, addlc, arithmetic_inst },
++ {"rsublc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x0C000100, OPCODE_MASK_H4, rsublc, arithmetic_inst },
++ {"addlk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x10000100, OPCODE_MASK_H4, addlk, arithmetic_inst },
++ {"rsublk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000100, OPCODE_MASK_H4, rsublk, arithmetic_inst },
++ {"addlkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x18000100, OPCODE_MASK_H4, addlkc, arithmetic_inst },
++ {"rsublkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x1C000100, OPCODE_MASK_H4, rsublkc, arithmetic_inst },
++ {"cmpl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000101, OPCODE_MASK_H4, cmpl, arithmetic_inst },
++ {"cmplu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000103, OPCODE_MASK_H4, cmplu, arithmetic_inst },
++ {"addli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x20000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"rsubli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x24000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"addlic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x28000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"rsublic", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x2C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"addlik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"rsublik", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x34000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"addlikc", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x38000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"rsublikc",INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3C000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* Identical to 32-bit */
++ {"mull", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x40000100, OPCODE_MASK_H4, mull, mult_inst },
++ {"bslll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000500, OPCODE_MASK_H3, bslll, barrel_shift_inst },
++ {"bslra", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000300, OPCODE_MASK_H3, bslra, barrel_shift_inst },
++ {"bslrl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000100, OPCODE_MASK_H3, bslrl, barrel_shift_inst },
++ {"bsllli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002400, OPCODE_MASK_H3B, bsllli, barrel_shift_inst },
++ {"bslrai", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002200, OPCODE_MASK_H3B, bslrai, barrel_shift_inst },
++ {"bslrli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002000, OPCODE_MASK_H3B, bslrli, barrel_shift_inst },
++ {"bslefi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64006000, OPCODE_MASK_H32B, bslefi, barrel_shift_inst },
++ {"bslifi", INST_TYPE_RD_R1_IMMW_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6400a000, OPCODE_MASK_H32B, bslifi, barrel_shift_inst },
++ {"orl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000100, OPCODE_MASK_H4, orl, logical_inst },
++ {"andl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000100, OPCODE_MASK_H4, andl, logical_inst },
++ {"xorl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000100, OPCODE_MASK_H4, xorl, logical_inst },
++ {"andnl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000100, OPCODE_MASK_H4, andnl, logical_inst },
++ {"pcmplbf", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000500, OPCODE_MASK_H4, pcmplbf, logical_inst },
++ {"pcmpleq", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000500, OPCODE_MASK_H4, pcmpleq, logical_inst },
++ {"pcmplne", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000500, OPCODE_MASK_H4, pcmplne, logical_inst },
++ {"srla", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000101, OPCODE_MASK_H34, srla, logical_inst },
++ {"srlc", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000121, OPCODE_MASK_H34, srlc, logical_inst },
++ {"srll", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000141, OPCODE_MASK_H34, srll, logical_inst },
++ {"sextl8", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000160, OPCODE_MASK_H34, sextl8, logical_inst },
++ {"sextl16", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000161, OPCODE_MASK_H34, sextl16, logical_inst },
++ {"sextl32", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000162, OPCODE_MASK_H34, sextl32, logical_inst },
++ {"brea", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98010000, OPCODE_MASK_H124, brea, branch_inst },
++ {"bread", INST_TYPE_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98110000, OPCODE_MASK_H124, bread, branch_inst },
++ {"breald", INST_TYPE_RD_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98150000, OPCODE_MASK_H24, breald, branch_inst },
++ {"beaeq", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D000000, OPCODE_MASK_H14, beaeq, branch_inst },
++ {"bealeq", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D000100, OPCODE_MASK_H14, bealeq, branch_inst },
++ {"beaeqd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F000000, OPCODE_MASK_H14, beaeqd, branch_inst },
++ {"bealeqd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F000100, OPCODE_MASK_H14, bealeqd, branch_inst },
++ {"beane", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D200000, OPCODE_MASK_H14, beane, branch_inst },
++ {"bealne", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D200100, OPCODE_MASK_H14, bealne, branch_inst },
++ {"beaned", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F200000, OPCODE_MASK_H14, beaned, branch_inst },
++ {"bealned", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F200100, OPCODE_MASK_H14, bealned, branch_inst },
++ {"bealt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D400000, OPCODE_MASK_H14, bealt, branch_inst },
++ {"beallt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D400100, OPCODE_MASK_H14, beallt, branch_inst },
++ {"bealtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F400000, OPCODE_MASK_H14, bealtd, branch_inst },
++ {"bealltd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F400100, OPCODE_MASK_H14, bealltd, branch_inst },
++ {"beale", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D600000, OPCODE_MASK_H14, beale, branch_inst },
++ {"bealle", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D600100, OPCODE_MASK_H14, bealle, branch_inst },
++ {"bealed", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F600000, OPCODE_MASK_H14, bealed, branch_inst },
++ {"bealled", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F600100, OPCODE_MASK_H14, bealled, branch_inst },
++ {"beagt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D800000, OPCODE_MASK_H14, beagt, branch_inst },
++ {"bealgt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D800100, OPCODE_MASK_H14, bealgt, branch_inst },
++ {"beagtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F800000, OPCODE_MASK_H14, beagtd, branch_inst },
++ {"bealgtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F800100, OPCODE_MASK_H14, bealgtd, branch_inst },
++ {"beage", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9DA00000, OPCODE_MASK_H14, beage, branch_inst },
++ {"bealge", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9DA00100, OPCODE_MASK_H14, bealge, branch_inst },
++ {"beaged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00000, OPCODE_MASK_H14, beaged, branch_inst },
++ {"bealged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00100, OPCODE_MASK_H14, bealged, branch_inst },
++ {"orli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA0000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
++ {"andli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA4000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
++ {"xorli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA8000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
++ {"andnli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xAC000000, OPCODE_MASK_H, invalid_inst, logical_inst }, /* Identical to 32-bit */
++ {"imml", INST_TYPE_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB2000000, OPCODE_MASK_H8, imml, immediate_inst },
++ {"breai", INST_TYPE_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8010000, OPCODE_MASK_H12, breai, branch_inst },
++ {"breaid", INST_TYPE_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8110000, OPCODE_MASK_H12, breaid, branch_inst },
++ {"brealid", INST_TYPE_RD_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8150000, OPCODE_MASK_H2, brealid, branch_inst },
++ {"beaeqi", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD000000, OPCODE_MASK_H1, beaeqi, branch_inst },
++ {"bealeqi", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD000000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beaeqi */
++ {"beaeqid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF000000, OPCODE_MASK_H1, beaeqid, branch_inst },
++ {"bealeqid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF000000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beaeqid */
++ {"beanei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD200000, OPCODE_MASK_H1, beanei, branch_inst },
++ {"bealnei", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD200000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beanei */
++ {"beaneid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF200000, OPCODE_MASK_H1, beaneid, branch_inst },
++ {"bealneid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF200000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beaneid */
++ {"bealti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD400000, OPCODE_MASK_H1, bealti, branch_inst },
++ {"beallti", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD400000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealti */
++ {"bealtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF400000, OPCODE_MASK_H1, bealtid, branch_inst },
++ {"bealltid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF400000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealtid */
++ {"bealei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD600000, OPCODE_MASK_H1, bealei, branch_inst },
++ {"beallei", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD600000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealei */
++ {"bealeid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF600000, OPCODE_MASK_H1, bealeid, branch_inst },
++ {"bealleid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF600000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to bealeid */
++ {"beagti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD800000, OPCODE_MASK_H1, beagti, branch_inst },
++ {"bealgti", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD800000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beagti */
++ {"beagtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF800000, OPCODE_MASK_H1, beagtid, branch_inst },
++ {"bealgtid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF800000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beagtid */
++ {"beagei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBDA00000, OPCODE_MASK_H1, beagei, branch_inst },
++ {"bealgei", INST_TYPE_R1_IMML, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBDA00000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beagei */
++ {"beageid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBFA00000, OPCODE_MASK_H1, beageid, branch_inst },
++ {"bealgeid",INST_TYPE_R1_IMML, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBFA00000, OPCODE_MASK_H1, invalid_inst, branch_inst }, /* Identical to beageid */
++ {"ll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000100, OPCODE_MASK_H4, ll, memory_load_inst },
++ {"llr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000300, OPCODE_MASK_H4, llr, memory_load_inst },
++ {"sl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000100, OPCODE_MASK_H4, sl, memory_store_inst },
++ {"slr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000300, OPCODE_MASK_H4, slr, memory_store_inst },
++ {"lli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, invalid_inst, memory_load_inst }, /* Identical to 32-bit */
++ {"sli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, invalid_inst, memory_store_inst }, /* Identical to 32-bit */
++ {"lla", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* lla translates to addlik */
++ {"dadd", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000400, OPCODE_MASK_H4, dadd, arithmetic_inst },
++ {"drsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000480, OPCODE_MASK_H4, drsub, arithmetic_inst },
++ {"dmul", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000500, OPCODE_MASK_H4, dmul, arithmetic_inst },
++ {"ddiv", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000580, OPCODE_MASK_H4, ddiv, arithmetic_inst },
++ {"dcmp.lt", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000610, OPCODE_MASK_H4, dcmp_lt, arithmetic_inst },
++ {"dcmp.eq", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000620, OPCODE_MASK_H4, dcmp_eq, arithmetic_inst },
++ {"dcmp.le", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000630, OPCODE_MASK_H4, dcmp_le, arithmetic_inst },
++ {"dcmp.gt", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000640, OPCODE_MASK_H4, dcmp_gt, arithmetic_inst },
++ {"dcmp.ne", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000650, OPCODE_MASK_H4, dcmp_ne, arithmetic_inst },
++ {"dcmp.ge", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000660, OPCODE_MASK_H4, dcmp_ge, arithmetic_inst },
++ {"dcmp.un", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000600, OPCODE_MASK_H4, dcmp_un, arithmetic_inst },
++ {"dbl", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000680, OPCODE_MASK_H4, dbl, arithmetic_inst },
++ {"dlong", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000700, OPCODE_MASK_H4, dlong, arithmetic_inst },
++ {"dsqrt", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000780, OPCODE_MASK_H4, dsqrt, arithmetic_inst },
++
+ {"", 0, 0, 0, 0, 0, 0, 0, 0},
+ };
+
+@@ -445,8 +576,17 @@ char pvr_register_prefix[] = "rpvr";
+ #define MIN_IMM5 ((int) 0x00000000)
+ #define MAX_IMM5 ((int) 0x0000001f)
+
++#define MIN_IMM6 ((int) 0x00000000)
++#define MAX_IMM6 ((int) 0x0000003f)
++
+ #define MIN_IMM_WIDTH ((int) 0x00000001)
+ #define MAX_IMM_WIDTH ((int) 0x00000020)
+
++#define MIN_IMM6_WIDTH ((int) 0x00000001)
++#define MAX_IMM6_WIDTH ((int) 0x00000040)
++
++#define MIN_IMML ((long) 0xffffff8000000000L)
++#define MAX_IMML ((long) 0x0000007fffffffffL)
++
+ #endif /* MICROBLAZE_OPC */
+
+diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
+index b69e6a4..265cea8 100644
+--- a/opcodes/microblaze-opcm.h
++++ b/opcodes/microblaze-opcm.h
+@@ -25,6 +25,7 @@
+
+ enum microblaze_instr
+ {
++ /* 32-bit instructions */
+ add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, clz, cmp, cmpu,
+ addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul,
+ mulh, mulhu, mulhsu,swapb,swaph,
+@@ -58,6 +59,18 @@ enum microblaze_instr
+ aputd, taputd, caputd, tcaputd, naputd, tnaputd, ncaputd, tncaputd,
+ eagetd, teagetd, ecagetd, tecagetd, neagetd, tneagetd, necagetd, tnecagetd,
+ eaputd, teaputd, ecaputd, tecaputd, neaputd, tneaputd, necaputd, tnecaputd,
++
++ /* 64-bit instructions */
++ addl, rsubl, addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull,
++ bslll, bslra, bslrl, bsllli, bslrai, bslrli, bslefi, bslifi, orl, andl, xorl,
++ andnl, pcmplbf, pcmpleq, pcmplne, srla, srlc, srll, sextl8, sextl16, sextl32,
++ brea, bread, breald, beaeq, bealeq, beaeqd, bealeqd, beane, bealne, beaned,
++ bealned, bealt, beallt, bealtd, bealltd, beale, bealle, bealed, bealled, beagt,
++ bealgt, beagtd, bealgtd, beage, bealge, beaged, bealged, breai, breaid, brealid,
++ beaeqi, beaeqid, beanei, beaneid, bealti, bealtid, bealei, bealeid, beagti,
++ beagtid, beagei, beageid, imml, ll, llr, sl, slr,
++ dadd, drsub, dmul, ddiv, dcmp_lt, dcmp_eq, dcmp_le, dcmp_gt, dcmp_ne, dcmp_ge,
++ dcmp_un, dbl, dlong, dsqrt,
+ invalid_inst
+ };
+
+@@ -135,15 +148,18 @@ enum microblaze_instr_type
+ #define RA_MASK 0x001F0000
+ #define RB_MASK 0x0000F800
+ #define IMM_MASK 0x0000FFFF
++#define IMML_MASK 0x00FFFFFF
+
+-/* Imm mask for barrel shifts. */
++/* Imm masks for barrel shifts. */
+ #define IMM5_MASK 0x0000001F
++#define IMM6_MASK 0x0000003F
+
+ /* Imm mask for mbar. */
+ #define IMM5_MBAR_MASK 0x03E00000
+
+-/* Imm mask for extract/insert width. */
++/* Imm masks for extract/insert width. */
+ #define IMM5_WIDTH_MASK 0x000007C0
++#define IMM6_WIDTH_MASK 0x00000FC0
+
+ /* FSL imm mask for get, put instructions. */
+ #define RFSL_MASK 0x000000F
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0016-MB-X-initial-commit.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0016-MB-X-initial-commit.patch
new file mode 100644
index 00000000..6239e214
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0016-MB-X-initial-commit.patch
@@ -0,0 +1,694 @@
+From 05240f6bdb5e3789efdc03b90c073b78785268e4 Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Sun, 30 Sep 2018 16:31:26 +0530
+Subject: [PATCH 16/31] MB-X initial commit code cleanup is needed.
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/bfd-in2.h | 10 +++
+ bfd/elf32-microblaze.c | 65 +++++++++++++++++--
+ bfd/elf64-microblaze.c | 61 +++++++++++++++++-
+ bfd/libbfd.h | 2 +
+ bfd/reloc.c | 12 ++++
+ gas/config/tc-microblaze.c | 152 +++++++++++++++++++++++++++++++++++++--------
+ include/elf/microblaze.h | 2 +
+ opcodes/microblaze-opc.h | 4 +-
+ opcodes/microblaze-opcm.h | 4 +-
+ 9 files changed, 277 insertions(+), 35 deletions(-)
+
+diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
+index 5807f70..44cddc2 100644
+--- a/bfd/bfd-in2.h
++++ b/bfd/bfd-in2.h
+@@ -5801,11 +5801,21 @@ done here - only used for relaxing */
+ BFD_RELOC_MICROBLAZE_64_NONE,
+
+ /* This is a 64 bit reloc that stores the 32 bit pc relative
++ * +value in two words (with an imml instruction). No relocation is
++ * +done here - only used for relaxing */
++ BFD_RELOC_MICROBLAZE_64,
++
++/* This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). The relocation is
+ PC-relative GOT offset */
+ BFD_RELOC_MICROBLAZE_64_GOTPC,
+
+ /* This is a 64 bit reloc that stores the 32 bit pc relative
++value in two words (with an imml instruction). The relocation is
++PC-relative GOT offset */
++ BFD_RELOC_MICROBLAZE_64_GPC,
++
++/* This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). The relocation is
+ GOT offset */
+ BFD_RELOC_MICROBLAZE_64_GOT,
+diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
+index 94fa3cf..b632dd1 100644
+--- a/bfd/elf32-microblaze.c
++++ b/bfd/elf32-microblaze.c
+@@ -116,6 +116,20 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
++ HOWTO (R_MICROBLAZE_IMML_64, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_IMML_64", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
++
+ /* A 64 bit relocation. Table entry not really used. */
+ HOWTO (R_MICROBLAZE_64, /* Type. */
+ 0, /* Rightshift. */
+@@ -280,6 +294,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
++ /* A 64 bit GOTPC relocation. Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_GPC_64, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc, /* Special Function. */
++ "R_MICROBLAZE_GPC_64", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
+ /* A 64 bit GOT relocation. Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
+ 0, /* Rightshift. */
+@@ -619,9 +648,15 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ case BFD_RELOC_VTABLE_ENTRY:
+ microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
+ break;
++ case BFD_RELOC_MICROBLAZE_64:
++ microblaze_reloc = R_MICROBLAZE_IMML_64;
++ break;
+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
+ microblaze_reloc = R_MICROBLAZE_GOTPC_64;
+ break;
++ case BFD_RELOC_MICROBLAZE_64_GPC:
++ microblaze_reloc = R_MICROBLAZE_GPC_64;
++ break;
+ case BFD_RELOC_MICROBLAZE_64_GOT:
+ microblaze_reloc = R_MICROBLAZE_GOT_64;
+ break;
+@@ -1467,7 +1502,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
+ {
+ relocation += addend;
+- if (r_type == R_MICROBLAZE_32)
++ if (r_type == R_MICROBLAZE_32)// || r_type == R_MICROBLAZE_IMML_64)
+ bfd_put_32 (input_bfd, relocation, contents + offset);
+ else
+ {
+@@ -1933,6 +1968,28 @@ microblaze_elf_relax_section (bfd *abfd,
+ irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
+ }
+ break;
++ case R_MICROBLAZE_IMML_64:
++ {
++ /* This was a PC-relative instruction that was
++ completely resolved. */
++ int sfix, efix;
++ unsigned int val;
++ bfd_vma target_address;
++ target_address = irel->r_addend + irel->r_offset;
++ sfix = calc_fixup (irel->r_offset, 0, sec);
++ efix = calc_fixup (target_address, 0, sec);
++
++ /* Validate the in-band val. */
++ val = bfd_get_32 (abfd, contents + irel->r_offset);
++ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
++ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
++ }
++ irel->r_addend -= (efix - sfix);
++ /* Should use HOWTO. */
++ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
++ irel->r_addend);
++ }
++ break;
+ case R_MICROBLAZE_NONE:
+ case R_MICROBLAZE_32_NONE:
+ {
+@@ -2037,9 +2094,9 @@ microblaze_elf_relax_section (bfd *abfd,
+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
+ irelscan->r_addend);
+ }
+- if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
+- {
+- isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
++ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)// || ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
++ {
++ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
+
+ /* Look at the reloc only if the value has been resolved. */
+ if (isym->st_shndx == shndx
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+index 0f43ae6..56a45f2 100644
+--- a/bfd/elf64-microblaze.c
++++ b/bfd/elf64-microblaze.c
+@@ -117,6 +117,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
+ TRUE), /* PC relative offset? */
+
+ /* A 64 bit relocation. Table entry not really used. */
++ HOWTO (R_MICROBLAZE_IMML_64, /* Type. */
++ 0, /* Rightshift. */
++ 4, /* Size (0 = byte, 1 = short, 2 = long). */
++ 64, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc,/* Special Function. */
++ "R_MICROBLAZE_IMML_64", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
++ /* A 64 bit relocation. Table entry not really used. */
+ HOWTO (R_MICROBLAZE_64, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+@@ -265,6 +280,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
++ /* A 64 bit GOTPC relocation. Table-entry not really used. */
++ HOWTO (R_MICROBLAZE_GPC_64, /* Type. */
++ 0, /* Rightshift. */
++ 2, /* Size (0 = byte, 1 = short, 2 = long). */
++ 16, /* Bitsize. */
++ TRUE, /* PC_relative. */
++ 0, /* Bitpos. */
++ complain_overflow_dont, /* Complain on overflow. */
++ bfd_elf_generic_reloc, /* Special Function. */
++ "R_MICROBLAZE_GPC_64", /* Name. */
++ FALSE, /* Partial Inplace. */
++ 0, /* Source Mask. */
++ 0x0000ffff, /* Dest Mask. */
++ TRUE), /* PC relative offset? */
++
+ /* A 64 bit GOT relocation. Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
+ 0, /* Rightshift. */
+@@ -589,9 +619,15 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ case BFD_RELOC_VTABLE_ENTRY:
+ microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
+ break;
++ case BFD_RELOC_MICROBLAZE_64:
++ microblaze_reloc = R_MICROBLAZE_IMML_64;
++ break;
+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
+ microblaze_reloc = R_MICROBLAZE_GOTPC_64;
+ break;
++ case BFD_RELOC_MICROBLAZE_64_GPC:
++ microblaze_reloc = R_MICROBLAZE_GPC_64;
++ break;
+ case BFD_RELOC_MICROBLAZE_64_GOT:
+ microblaze_reloc = R_MICROBLAZE_GOT_64;
+ break;
+@@ -1161,6 +1197,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ break; /* Do nothing. */
+
+ case (int) R_MICROBLAZE_GOTPC_64:
++ case (int) R_MICROBLAZE_GPC_64:
+ relocation = htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset;
+ relocation -= (input_section->output_section->vma
+@@ -1431,7 +1468,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
+ {
+ relocation += addend;
+- if (r_type == R_MICROBLAZE_32)
++ if (r_type == R_MICROBLAZE_32)// || r_type == R_MICROBLAZE_IMML_64)
+ bfd_put_32 (input_bfd, relocation, contents + offset);
+ else
+ {
+@@ -1876,6 +1913,28 @@ microblaze_elf_relax_section (bfd *abfd,
+ irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
+ }
+ break;
++ case R_MICROBLAZE_IMML_64:
++ {
++ /* This was a PC-relative instruction that was
++ completely resolved. */
++ int sfix, efix;
++ unsigned int val;
++ bfd_vma target_address;
++ target_address = irel->r_addend + irel->r_offset;
++ sfix = calc_fixup (irel->r_offset, 0, sec);
++ efix = calc_fixup (target_address, 0, sec);
++
++ /* Validate the in-band val. */
++ val = bfd_get_32 (abfd, contents + irel->r_offset);
++ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
++ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
++ }
++ irel->r_addend -= (efix - sfix);
++ /* Should use HOWTO. */
++ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
++ irel->r_addend);
++ }
++ break;
+ case R_MICROBLAZE_NONE:
+ case R_MICROBLAZE_32_NONE:
+ {
+diff --git a/bfd/libbfd.h b/bfd/libbfd.h
+index 261086c..d7892a6 100644
+--- a/bfd/libbfd.h
++++ b/bfd/libbfd.h
+@@ -2864,7 +2864,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
+ "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
+ "BFD_RELOC_MICROBLAZE_32_NONE",
+ "BFD_RELOC_MICROBLAZE_64_NONE",
++ "BFD_RELOC_MICROBLAZE_64",
+ "BFD_RELOC_MICROBLAZE_64_GOTPC",
++ "BFD_RELOC_MICROBLAZE_64_GPC",
+ "BFD_RELOC_MICROBLAZE_64_GOT",
+ "BFD_RELOC_MICROBLAZE_64_PLT",
+ "BFD_RELOC_MICROBLAZE_64_GOTOFF",
+diff --git a/bfd/reloc.c b/bfd/reloc.c
+index d89bc5d..60eac77 100644
+--- a/bfd/reloc.c
++++ b/bfd/reloc.c
+@@ -6873,6 +6873,12 @@ ENUMDOC
+ ENUM
+ BFD_RELOC_MICROBLAZE_64_NONE
+ ENUMDOC
++ This is a 32 bit reloc that stores the 32 bit pc relative
++ value in two words (with an imml instruction). No relocation is
++ done here - only used for relaxing
++ENUM
++ BFD_RELOC_MICROBLAZE_64
++ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). No relocation is
+ done here - only used for relaxing
+@@ -6880,6 +6886,12 @@ ENUM
+ BFD_RELOC_MICROBLAZE_64_GOTPC
+ ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit pc relative
++ value in two words (with an imml instruction). No relocation is
++ done here - only used for relaxing
++ENUM
++ BFD_RELOC_MICROBLAZE_64_GPC
++ENUMDOC
++ This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). The relocation is
+ PC-relative GOT offset
+ ENUM
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index eb7998f..680a794 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -94,6 +94,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
+ #define TLSTPREL_OFFSET 16
+ #define TEXT_OFFSET 17
+ #define TEXT_PC_OFFSET 18
++#define DEFINED_64_OFFSET 19
+
+ /* Initialize the relax table. */
+ const relax_typeS md_relax_table[] =
+@@ -117,6 +118,8 @@ const relax_typeS md_relax_table[] =
+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 16: TLSTPREL_OFFSET. */
+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
++// { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
++ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 17: DEFINED_64_OFFSET. */
+ };
+
+ static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
+@@ -396,7 +399,8 @@ const pseudo_typeS md_pseudo_table[] =
+ {"data32", cons, 4}, /* Same as word. */
+ {"ent", s_func, 0}, /* Treat ent as function entry point. */
+ {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
+- {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
++ {"gpword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
++ {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
+ {"weakext", microblaze_s_weakext, 0},
+ {"rodata", microblaze_s_rdata, 0},
+ {"sdata2", microblaze_s_rdata, 1},
+@@ -405,6 +409,7 @@ const pseudo_typeS md_pseudo_table[] =
+ {"sbss", microblaze_s_bss, 1},
+ {"text", microblaze_s_text, 0},
+ {"word", cons, 4},
++ {"dword", cons, 8},
+ {"frame", s_ignore, 0},
+ {"mask", s_ignore, 0}, /* Emitted by gcc. */
+ {NULL, NULL, 0}
+@@ -898,7 +903,7 @@ check_got (int * got_type, int * got_len)
+ extern bfd_reloc_code_real_type
+ parse_cons_expression_microblaze (expressionS *exp, int size)
+ {
+- if (size == 4)
++ if (size == 4 || (microblaze_arch_size == 64 && size == 8))
+ {
+ /* Handle @GOTOFF et.al. */
+ char *save, *gotfree_copy;
+@@ -930,6 +935,7 @@ parse_cons_expression_microblaze (expressionS *exp, int size)
+
+ static const char * str_microblaze_ro_anchor = "RO";
+ static const char * str_microblaze_rw_anchor = "RW";
++static const char * str_microblaze_64 = "64";
+
+ static bfd_boolean
+ check_spl_reg (unsigned * reg)
+@@ -1174,6 +1180,33 @@ md_assemble (char * str)
+ inst |= (immed << IMM_LOW) & IMM_MASK;
+ }
+ }
++#if 0 //revisit
++ else if (streq (name, "lli") || streq (name, "sli"))
++ {
++ temp = immed & 0xFFFFFFFFFFFF8000;
++ if ((temp != 0) && (temp != 0xFFFFFFFFFFFF8000))
++ {
++ /* Needs an immediate inst. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imml");
++ return;
++ }
++
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
++ }
++ inst |= (reg1 << RD_LOW) & RD_MASK;
++ inst |= (reg2 << RA_LOW) & RA_MASK;
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
++#endif
+ else
+ {
+ temp = immed & 0xFFFF8000;
+@@ -1926,6 +1959,7 @@ md_assemble (char * str)
+ if (exp.X_op != O_constant)
+ {
+ char *opc = NULL;
++ //char *opc = str_microblaze_64;
+ relax_substateT subtype;
+
+ if (exp.X_md != 0)
+@@ -1939,7 +1973,7 @@ md_assemble (char * str)
+ subtype, /* PC-relative or not. */
+ exp.X_add_symbol,
+ exp.X_add_number,
+- opc);
++ (char *) opc);
+ immedl = 0L;
+ }
+ else
+@@ -1977,7 +2011,7 @@ md_assemble (char * str)
+ reg1 = 0;
+ }
+ if (strcmp (op_end, ""))
+- op_end = parse_imml (op_end + 1, & exp, MIN_IMM, MAX_IMM);
++ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
+ else
+ as_fatal (_("Error in statement syntax"));
+
+@@ -1987,7 +2021,8 @@ md_assemble (char * str)
+
+ if (exp.X_op != O_constant)
+ {
+- char *opc = NULL;
++ //char *opc = NULL;
++ char *opc = str_microblaze_64;
+ relax_substateT subtype;
+
+ if (exp.X_md != 0)
+@@ -2001,14 +2036,13 @@ md_assemble (char * str)
+ subtype, /* PC-relative or not. */
+ exp.X_add_symbol,
+ exp.X_add_number,
+- opc);
++ (char *) opc);
+ immedl = 0L;
+ }
+ else
+ {
+ output = frag_more (isize);
+ immedl = exp.X_add_number;
+-
+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
+ if (opcode1 == NULL)
+ {
+@@ -2187,13 +2221,23 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
+ fragP->fr_fix += INST_WORD_SIZE * 2;
+ fragP->fr_var = 0;
+ break;
++ case DEFINED_64_OFFSET:
++ if (fragP->fr_symbol == GOT_symbol)
++ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
++ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GPC);
++ else
++ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
++ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64);
++ fragP->fr_fix += INST_WORD_SIZE * 2;
++ fragP->fr_var = 0;
++ break;
+ case DEFINED_ABS_SEGMENT:
+ if (fragP->fr_symbol == GOT_symbol)
+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
+ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
+ else
+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
+- fragP->fr_offset, FALSE, BFD_RELOC_64);
++ fragP->fr_offset, TRUE, BFD_RELOC_64);
+ fragP->fr_fix += INST_WORD_SIZE * 2;
+ fragP->fr_var = 0;
+ break;
+@@ -2416,22 +2460,38 @@ md_apply_fix (fixS * fixP,
+ case BFD_RELOC_64_PCREL:
+ case BFD_RELOC_64:
+ case BFD_RELOC_MICROBLAZE_64_TEXTREL:
++ case BFD_RELOC_MICROBLAZE_64:
+ /* Add an imm instruction. First save the current instruction. */
+ for (i = 0; i < INST_WORD_SIZE; i++)
+ buf[i + INST_WORD_SIZE] = buf[i];
++ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
++ {
++ /* Generate the imm instruction. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imml");
++ return;
++ }
+
+- /* Generate the imm instruction. */
+- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
+- if (opcode1 == NULL)
+- {
+- as_bad (_("unknown opcode \"%s\""), "imm");
+- return;
+- }
+-
+- inst1 = opcode1->bit_sequence;
+- if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
+- inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
+-
++ inst1 = opcode1->bit_sequence;
++ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
++ inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ }
++ else
++ {
++ /* Generate the imm instruction. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imm");
++ return;
++ }
++
++ inst1 = opcode1->bit_sequence;
++ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
++ inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
++ }
+ buf[0] = INST_BYTE0 (inst1);
+ buf[1] = INST_BYTE1 (inst1);
+ buf[2] = INST_BYTE2 (inst1);
+@@ -2460,6 +2520,7 @@ md_apply_fix (fixS * fixP,
+ /* Fall through. */
+
+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
++ case BFD_RELOC_MICROBLAZE_64_GPC:
+ case BFD_RELOC_MICROBLAZE_64_GOT:
+ case BFD_RELOC_MICROBLAZE_64_PLT:
+ case BFD_RELOC_MICROBLAZE_64_GOTOFF:
+@@ -2467,12 +2528,16 @@ md_apply_fix (fixS * fixP,
+ /* Add an imm instruction. First save the current instruction. */
+ for (i = 0; i < INST_WORD_SIZE; i++)
+ buf[i + INST_WORD_SIZE] = buf[i];
+-
+- /* Generate the imm instruction. */
+- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
++ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
++ else
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
+ if (opcode1 == NULL)
+ {
+- as_bad (_("unknown opcode \"%s\""), "imm");
++ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
++ as_bad (_("unknown opcode \"%s\""), "imml");
++ else
++ as_bad (_("unknown opcode \"%s\""), "imm");
+ return;
+ }
+
+@@ -2496,6 +2561,8 @@ md_apply_fix (fixS * fixP,
+ moves code around due to relaxing. */
+ if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
++ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
++ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
+ else if (fixP->fx_r_type == BFD_RELOC_32)
+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
+ else
+@@ -2539,6 +2606,32 @@ 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
++ && !S_IS_WEAK (fragP->fr_symbol))
++ {
++ if (fragP->fr_opcode != NULL) {
++ if(streq (fragP->fr_opcode, str_microblaze_64))
++ {
++ /* Used as an absolute value. */
++ fragP->fr_subtype = DEFINED_64_OFFSET;
++ /* Variable part does not change. */
++ fragP->fr_var = INST_WORD_SIZE;
++ }
++ else
++ {
++ fragP->fr_subtype = DEFINED_PC_OFFSET;
++ /* Don't know now whether we need an imm instruction. */
++ fragP->fr_var = INST_WORD_SIZE;
++ }
++ }
++ else
++ {
++ fragP->fr_subtype = DEFINED_PC_OFFSET;
++ /* Don't know now whether we need an imm instruction. */
++ fragP->fr_var = INST_WORD_SIZE;
++ }
++ }
++ #if 0
+ else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
+ !S_IS_WEAK (fragP->fr_symbol))
+ {
+@@ -2546,6 +2639,7 @@ md_estimate_size_before_relax (fragS * fragP,
+ /* Don't know now whether we need an imm instruction. */
+ fragP->fr_var = INST_WORD_SIZE;
+ }
++#endif
+ else if (S_IS_DEFINED (fragP->fr_symbol)
+ && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
+ {
+@@ -2648,6 +2742,7 @@ md_estimate_size_before_relax (fragS * fragP,
+ case TLSLD_OFFSET:
+ case TLSTPREL_OFFSET:
+ case TLSDTPREL_OFFSET:
++ case DEFINED_64_OFFSET:
+ fragP->fr_var = INST_WORD_SIZE*2;
+ break;
+ case DEFINED_RO_SEGMENT:
+@@ -2701,7 +2796,7 @@ md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
+ else
+ {
+ /* The case where we are going to resolve things... */
+- if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
++ if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64)
+ return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
+ else
+ return fixp->fx_where + fixp->fx_frag->fr_address;
+@@ -2734,6 +2829,8 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
+ case BFD_RELOC_MICROBLAZE_32_RWSDA:
+ case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
++ case BFD_RELOC_MICROBLAZE_64_GPC:
++ case BFD_RELOC_MICROBLAZE_64:
+ case BFD_RELOC_MICROBLAZE_64_GOT:
+ case BFD_RELOC_MICROBLAZE_64_PLT:
+ case BFD_RELOC_MICROBLAZE_64_GOTOFF:
+@@ -2876,7 +2973,10 @@ cons_fix_new_microblaze (fragS * frag,
+ r = BFD_RELOC_32;
+ break;
+ case 8:
+- r = BFD_RELOC_64;
++ if (microblaze_arch_size == 64)
++ r = BFD_RELOC_32;
++ else
++ r = BFD_RELOC_64;
+ break;
+ default:
+ as_bad (_("unsupported BFD relocation size %u"), size);
+diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h
+index 7bdba67..454e2b4 100644
+--- a/include/elf/microblaze.h
++++ b/include/elf/microblaze.h
+@@ -62,6 +62,8 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type)
+ RELOC_NUMBER (R_MICROBLAZE_TEXTREL_64, 31) /* TEXT Entry offset 64-bit. */
+ RELOC_NUMBER (R_MICROBLAZE_TEXTREL_32_LO, 32) /* TEXT Entry offset 32-bit. */
+ RELOC_NUMBER (R_MICROBLAZE_32_NONE, 33)
++ RELOC_NUMBER (R_MICROBLAZE_IMML_64, 34)
++ RELOC_NUMBER (R_MICROBLAZE_GPC_64, 35) /* GOT entry offset. */
+
+ END_RELOC_NUMBERS (R_MICROBLAZE_max)
+
+diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
+index c88092d..8d43af0 100644
+--- a/opcodes/microblaze-opc.h
++++ b/opcodes/microblaze-opc.h
+@@ -538,8 +538,8 @@ struct op_code_struct
+ {"llr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000300, OPCODE_MASK_H4, llr, memory_load_inst },
+ {"sl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000100, OPCODE_MASK_H4, sl, memory_store_inst },
+ {"slr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000300, OPCODE_MASK_H4, slr, memory_store_inst },
+- {"lli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, invalid_inst, memory_load_inst }, /* Identical to 32-bit */
+- {"sli", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, invalid_inst, memory_store_inst }, /* Identical to 32-bit */
++ {"lli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xEC000000, OPCODE_MASK_H, invalid_inst, memory_load_inst }, /* Identical to 32-bit */
++ {"sli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xFC000000, OPCODE_MASK_H, invalid_inst, memory_store_inst }, /* Identical to 32-bit */
+ {"lla", INST_TYPE_RD_R1_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* lla translates to addlik */
+ {"dadd", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000400, OPCODE_MASK_H4, dadd, arithmetic_inst },
+ {"drsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000480, OPCODE_MASK_H4, drsub, arithmetic_inst },
+diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
+index 265cea8..abb5c9f 100644
+--- a/opcodes/microblaze-opcm.h
++++ b/opcodes/microblaze-opcm.h
+@@ -40,8 +40,8 @@ enum microblaze_instr
+ 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, lbuea, lbur, lhu, lhuea, lhur, lw, lwea, lwr, lwx,
+- sb, sbea, sbr, sh, shea, shr, sw, swea, swr, swx, lbui, lhui, lwi,
+- sbi, shi, swi, msrset, msrclr, tuqula, fadd, frsub, fmul, fdiv,
++ sb, sbea, sbr, sh, shea, shr, sw, swea, swr, swx, lbui, lhui, lwi, lli,
++ sbi, shi, sli, 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,
+ tget, tcget, tnget, tncget, tput, tcput, tnput, tncput,
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch
new file mode 100644
index 00000000..9cc96fae
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0017-Patch-Microblaze-negl-instruction-is-overriding-rsub.patch
@@ -0,0 +1,38 @@
+From 7df271f0025a39dc7b9f21e122d69a6f81a44af2 Mon Sep 17 00:00:00 2001
+From: Mahesh Bodapati <mbodapat@xilinx.com>
+Date: Tue, 11 Sep 2018 13:48:33 +0530
+Subject: [PATCH 17/31] [Patch,Microblaze] : negl instruction is overriding
+ rsubl,fixed it by changing the instruction order...
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ opcodes/microblaze-opc.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
+index 8d43af0..2096269 100644
+--- a/opcodes/microblaze-opc.h
++++ b/opcodes/microblaze-opc.h
+@@ -275,9 +275,7 @@ struct op_code_struct
+ {"la", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* la translates to addik. */
+ {"tuqula",INST_TYPE_RD, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3000002A, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* tuqula rd translates to addik rd, r0, 42. */
+ {"not", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA800FFFF, OPCODE_MASK_H34, invalid_inst, logical_inst }, /* not translates to xori rd,ra,-1. */
+- {"neg", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* neg translates to rsub rd, ra, r0. */
+ {"rtb", INST_TYPE_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6000004, OPCODE_MASK_H1, invalid_inst, return_inst }, /* rtb translates to rts rd, 4. */
+- {"sub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* sub translates to rsub rd, rb, ra. */
+ {"lmi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, invalid_inst, memory_load_inst },
+ {"smi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, invalid_inst, memory_store_inst },
+ {"msrset",INST_TYPE_RD_IMM15, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x94100000, OPCODE_MASK_H23N, msrset, special_inst },
+@@ -555,6 +553,8 @@ struct op_code_struct
+ {"dbl", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000680, OPCODE_MASK_H4, dbl, arithmetic_inst },
+ {"dlong", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000700, OPCODE_MASK_H4, dlong, arithmetic_inst },
+ {"dsqrt", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000780, OPCODE_MASK_H4, dsqrt, arithmetic_inst },
++ {"neg", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* neg translates to rsub rd, ra, r0. */
++ {"sub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* sub translates to rsub rd, rb, ra. */
+
+ {"", 0, 0, 0, 0, 0, 0, 0, 0},
+ };
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0018-Added-relocations-for-MB-X.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0018-Added-relocations-for-MB-X.patch
new file mode 100644
index 00000000..d401cdd3
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0018-Added-relocations-for-MB-X.patch
@@ -0,0 +1,350 @@
+From a1961dbfa4324335116f84494396ce9801688f18 Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Tue, 11 Sep 2018 17:30:17 +0530
+Subject: [PATCH 18/31] Added relocations for MB-X
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/bfd-in2.h | 11 ++++--
+ bfd/libbfd.h | 4 +--
+ bfd/reloc.c | 26 +++++++-------
+ gas/config/tc-microblaze.c | 90 ++++++++++++++++++++--------------------------
+ 4 files changed, 62 insertions(+), 69 deletions(-)
+
+diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
+index 44cddc2..44e719b 100644
+--- a/bfd/bfd-in2.h
++++ b/bfd/bfd-in2.h
+@@ -5796,16 +5796,21 @@ done here - only used for relaxing */
+ BFD_RELOC_MICROBLAZE_32_NONE,
+
+ /* This is a 64 bit reloc that stores the 32 bit pc relative
+- * +value in two words (with an imm instruction). No relocation is
++ * +value in two words (with an imml instruction). No relocation is
+ * +done here - only used for relaxing */
+- BFD_RELOC_MICROBLAZE_64_NONE,
++ BFD_RELOC_MICROBLAZE_64_PCREL,
+
+-/* This is a 64 bit reloc that stores the 32 bit pc relative
++/* This is a 64 bit reloc that stores the 32 bit relative
+ * +value in two words (with an imml instruction). No relocation is
+ * +done here - only used for relaxing */
+ BFD_RELOC_MICROBLAZE_64,
+
+ /* This is a 64 bit reloc that stores the 32 bit pc relative
++ * +value in two words (with an imm instruction). No relocation is
++ * +done here - only used for relaxing */
++ BFD_RELOC_MICROBLAZE_64_NONE,
++
++/* This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). The relocation is
+ PC-relative GOT offset */
+ BFD_RELOC_MICROBLAZE_64_GOTPC,
+diff --git a/bfd/libbfd.h b/bfd/libbfd.h
+index d7892a6..bb8fb42 100644
+--- a/bfd/libbfd.h
++++ b/bfd/libbfd.h
+@@ -2864,14 +2864,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
+ "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
+ "BFD_RELOC_MICROBLAZE_32_NONE",
+ "BFD_RELOC_MICROBLAZE_64_NONE",
+- "BFD_RELOC_MICROBLAZE_64",
+ "BFD_RELOC_MICROBLAZE_64_GOTPC",
+- "BFD_RELOC_MICROBLAZE_64_GPC",
+ "BFD_RELOC_MICROBLAZE_64_GOT",
+ "BFD_RELOC_MICROBLAZE_64_PLT",
+ "BFD_RELOC_MICROBLAZE_64_GOTOFF",
+ "BFD_RELOC_MICROBLAZE_32_GOTOFF",
+ "BFD_RELOC_MICROBLAZE_COPY",
++ "BFD_RELOC_MICROBLAZE_64",
++ "BFD_RELOC_MICROBLAZE_64_PCREL",
+ "BFD_RELOC_MICROBLAZE_64_TLS",
+ "BFD_RELOC_MICROBLAZE_64_TLSGD",
+ "BFD_RELOC_MICROBLAZE_64_TLSLD",
+diff --git a/bfd/reloc.c b/bfd/reloc.c
+index 60eac77..2d73154 100644
+--- a/bfd/reloc.c
++++ b/bfd/reloc.c
+@@ -6873,12 +6873,6 @@ ENUMDOC
+ ENUM
+ BFD_RELOC_MICROBLAZE_64_NONE
+ ENUMDOC
+- This is a 32 bit reloc that stores the 32 bit pc relative
+- value in two words (with an imml instruction). No relocation is
+- done here - only used for relaxing
+-ENUM
+- BFD_RELOC_MICROBLAZE_64
+-ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). No relocation is
+ done here - only used for relaxing
+@@ -6886,12 +6880,6 @@ ENUM
+ BFD_RELOC_MICROBLAZE_64_GOTPC
+ ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit pc relative
+- value in two words (with an imml instruction). No relocation is
+- done here - only used for relaxing
+-ENUM
+- BFD_RELOC_MICROBLAZE_64_GPC
+-ENUMDOC
+- This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). The relocation is
+ PC-relative GOT offset
+ ENUM
+@@ -6975,6 +6963,20 @@ ENUMDOC
+ value in two words (with an imm instruction). The relocation is
+ relative offset from start of TEXT.
+
++ This is a 64 bit reloc that stores 64-bit thread pointer relative offset
++ to two words (uses imml instruction).
++ENUM
++BFD_RELOC_MICROBLAZE_64,
++ENUMDOC
++ This is a 64 bit reloc that stores the 64 bit pc relative
++ value in two words (with an imml instruction). No relocation is
++ done here - only used for relaxing
++ENUM
++BFD_RELOC_MICROBLAZE_64_PCREL,
++ENUMDOC
++ This is a 32 bit reloc that stores the 32 bit pc relative
++ value in two words (with an imml instruction). No relocation is
++ done here - only used for relaxing
+ ENUM
+ BFD_RELOC_AARCH64_RELOC_START
+ ENUMDOC
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index 680a794..663e1a6 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -95,6 +95,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
+ #define TEXT_OFFSET 17
+ #define TEXT_PC_OFFSET 18
+ #define DEFINED_64_OFFSET 19
++#define DEFINED_64_PC_OFFSET 20
+
+ /* Initialize the relax table. */
+ const relax_typeS md_relax_table[] =
+@@ -119,7 +120,8 @@ const relax_typeS md_relax_table[] =
+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
+ // { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
+- { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 17: DEFINED_64_OFFSET. */
++ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 19: DEFINED_64_OFFSET. */
++ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE*2, 0 } /* 20: DEFINED_64_PC_OFFSET. */
+ };
+
+ static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
+@@ -1180,33 +1182,6 @@ md_assemble (char * str)
+ inst |= (immed << IMM_LOW) & IMM_MASK;
+ }
+ }
+-#if 0 //revisit
+- else if (streq (name, "lli") || streq (name, "sli"))
+- {
+- temp = immed & 0xFFFFFFFFFFFF8000;
+- if ((temp != 0) && (temp != 0xFFFFFFFFFFFF8000))
+- {
+- /* Needs an immediate inst. */
+- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
+- if (opcode1 == NULL)
+- {
+- as_bad (_("unknown opcode \"%s\""), "imml");
+- return;
+- }
+-
+- inst1 = opcode1->bit_sequence;
+- inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
+- output[0] = INST_BYTE0 (inst1);
+- output[1] = INST_BYTE1 (inst1);
+- output[2] = INST_BYTE2 (inst1);
+- output[3] = INST_BYTE3 (inst1);
+- output = frag_more (isize);
+- }
+- inst |= (reg1 << RD_LOW) & RD_MASK;
+- inst |= (reg2 << RA_LOW) & RA_MASK;
+- inst |= (immed << IMM_LOW) & IMM_MASK;
+- }
+-#endif
+ else
+ {
+ temp = immed & 0xFFFF8000;
+@@ -1958,8 +1933,8 @@ md_assemble (char * str)
+
+ if (exp.X_op != O_constant)
+ {
+- char *opc = NULL;
+- //char *opc = str_microblaze_64;
++ //char *opc = NULL;
++ char *opc = str_microblaze_64;
+ relax_substateT subtype;
+
+ if (exp.X_md != 0)
+@@ -2221,13 +2196,19 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
+ fragP->fr_fix += INST_WORD_SIZE * 2;
+ fragP->fr_var = 0;
+ break;
++ case DEFINED_64_PC_OFFSET:
++ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
++ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PCREL);
++ fragP->fr_fix += INST_WORD_SIZE * 2;
++ fragP->fr_var = 0;
++ break;
+ case DEFINED_64_OFFSET:
+ if (fragP->fr_symbol == GOT_symbol)
+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
+- fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GPC);
++ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GPC);
+ else
+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
+- fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64);
++ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64);
+ fragP->fr_fix += INST_WORD_SIZE * 2;
+ fragP->fr_var = 0;
+ break;
+@@ -2237,7 +2218,7 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
+ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
+ else
+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
+- fragP->fr_offset, TRUE, BFD_RELOC_64);
++ fragP->fr_offset, FALSE, BFD_RELOC_64);
+ fragP->fr_fix += INST_WORD_SIZE * 2;
+ fragP->fr_var = 0;
+ break;
+@@ -2457,14 +2438,17 @@ md_apply_fix (fixS * fixP,
+ }
+ }
+ break;
++
+ case BFD_RELOC_64_PCREL:
+ case BFD_RELOC_64:
+ case BFD_RELOC_MICROBLAZE_64_TEXTREL:
+ case BFD_RELOC_MICROBLAZE_64:
++ case BFD_RELOC_MICROBLAZE_64_PCREL:
+ /* Add an imm instruction. First save the current instruction. */
+ for (i = 0; i < INST_WORD_SIZE; i++)
+ buf[i + INST_WORD_SIZE] = buf[i];
+- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
++ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64
++ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
+ {
+ /* Generate the imm instruction. */
+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
+@@ -2477,6 +2461,10 @@ md_apply_fix (fixS * fixP,
+ inst1 = opcode1->bit_sequence;
+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
+ inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
++ fixP->fx_r_type = BFD_RELOC_64;
++ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
++ fixP->fx_r_type = BFD_RELOC_64_PCREL;
+ }
+ else
+ {
+@@ -2487,7 +2475,7 @@ md_apply_fix (fixS * fixP,
+ as_bad (_("unknown opcode \"%s\""), "imm");
+ return;
+ }
+-
++
+ inst1 = opcode1->bit_sequence;
+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
+ inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
+@@ -2534,7 +2522,7 @@ md_apply_fix (fixS * fixP,
+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
+ if (opcode1 == NULL)
+ {
+- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
++ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
+ as_bad (_("unknown opcode \"%s\""), "imml");
+ else
+ as_bad (_("unknown opcode \"%s\""), "imm");
+@@ -2561,8 +2549,6 @@ md_apply_fix (fixS * fixP,
+ moves code around due to relaxing. */
+ if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
+- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
+- fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
+ else if (fixP->fx_r_type == BFD_RELOC_32)
+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
+ else
+@@ -2613,33 +2599,24 @@ md_estimate_size_before_relax (fragS * fragP,
+ if(streq (fragP->fr_opcode, str_microblaze_64))
+ {
+ /* Used as an absolute value. */
+- fragP->fr_subtype = DEFINED_64_OFFSET;
++ fragP->fr_subtype = DEFINED_64_PC_OFFSET;
+ /* Variable part does not change. */
+- fragP->fr_var = INST_WORD_SIZE;
++ fragP->fr_var = INST_WORD_SIZE*2;
+ }
+ else
+ {
+ fragP->fr_subtype = DEFINED_PC_OFFSET;
+- /* Don't know now whether we need an imm instruction. */
++ /* Don't know now whether we need an imm instruction. */
+ fragP->fr_var = INST_WORD_SIZE;
+ }
+ }
+ else
+ {
+ fragP->fr_subtype = DEFINED_PC_OFFSET;
+- /* Don't know now whether we need an imm instruction. */
++ /* Don't know now whether we need an imm instruction. */
+ fragP->fr_var = INST_WORD_SIZE;
+ }
+ }
+- #if 0
+- 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. */
+- fragP->fr_var = INST_WORD_SIZE;
+- }
+-#endif
+ else if (S_IS_DEFINED (fragP->fr_symbol)
+ && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
+ {
+@@ -2669,6 +2646,13 @@ md_estimate_size_before_relax (fragS * fragP,
+ /* Variable part does not change. */
+ fragP->fr_var = INST_WORD_SIZE*2;
+ }
++ else if (streq (fragP->fr_opcode, str_microblaze_64))
++ {
++ /* Used as an absolute value. */
++ fragP->fr_subtype = DEFINED_64_OFFSET;
++ /* Variable part does not change. */
++ fragP->fr_var = INST_WORD_SIZE;
++ }
+ else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
+ {
+ /* It is accessed using the small data read only anchor. */
+@@ -2743,6 +2727,7 @@ md_estimate_size_before_relax (fragS * fragP,
+ case TLSTPREL_OFFSET:
+ case TLSDTPREL_OFFSET:
+ case DEFINED_64_OFFSET:
++ case DEFINED_64_PC_OFFSET:
+ fragP->fr_var = INST_WORD_SIZE*2;
+ break;
+ case DEFINED_RO_SEGMENT:
+@@ -2796,7 +2781,7 @@ md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
+ else
+ {
+ /* The case where we are going to resolve things... */
+- if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64)
++ if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
+ return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
+ else
+ return fixp->fx_where + fixp->fx_frag->fr_address;
+@@ -2831,6 +2816,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
+ case BFD_RELOC_MICROBLAZE_64_GPC:
+ case BFD_RELOC_MICROBLAZE_64:
++ case BFD_RELOC_MICROBLAZE_64_PCREL:
+ case BFD_RELOC_MICROBLAZE_64_GOT:
+ case BFD_RELOC_MICROBLAZE_64_PLT:
+ case BFD_RELOC_MICROBLAZE_64_GOTOFF:
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch
new file mode 100644
index 00000000..814672d2
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch
@@ -0,0 +1,375 @@
+From b63b8ae83cc538808e06d84143df6b7150fb4037 Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Fri, 28 Sep 2018 12:04:55 +0530
+Subject: [PATCH 19/31] -Fixed MB-x relocation issues -Added imml for required
+ MB-x instructions
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elf64-microblaze.c | 68 ++++++++++++++++----
+ gas/config/tc-microblaze.c | 152 ++++++++++++++++++++++++++++++++-------------
+ gas/tc.h | 2 +-
+ 3 files changed, 167 insertions(+), 55 deletions(-)
+
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+index 56a45f2..54a2461 100644
+--- a/bfd/elf64-microblaze.c
++++ b/bfd/elf64-microblaze.c
+@@ -1476,8 +1476,17 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset + INST_WORD_SIZE);
+- bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
++ if (insn == 0xb2000000 || insn == 0xb2ffffff)
++ {
++ insn &= ~0x00ffffff;
++ insn |= (relocation >> 16) & 0xffffff;
++ bfd_put_32 (input_bfd, insn,
+ contents + offset + endian);
++ }
++ else
++ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ contents + offset + endian);
+ bfd_put_16 (input_bfd, relocation & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+ }
+@@ -1567,11 +1576,28 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ else
+ {
+ if (r_type == R_MICROBLAZE_64_PCREL)
+- relocation -= (input_section->output_section->vma
+- + input_section->output_offset
+- + offset + INST_WORD_SIZE);
+- bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ {
++ if (!input_section->output_section->vma &&
++ !input_section->output_offset && !offset)
++ relocation -= (input_section->output_section->vma
++ + input_section->output_offset
++ + offset);
++ else
++ relocation -= (input_section->output_section->vma
++ + input_section->output_offset
++ + offset + INST_WORD_SIZE);
++ }
++ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
++ if (insn == 0xb2000000 || insn == 0xb2ffffff)
++ {
++ insn &= ~0x00ffffff;
++ insn |= (relocation >> 16) & 0xffffff;
++ bfd_put_32 (input_bfd, insn,
+ contents + offset + endian);
++ }
++ else
++ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ contents + offset + endian);
+ bfd_put_16 (input_bfd, relocation & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+ }
+@@ -1690,9 +1716,19 @@ 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);
++
++ if (instr == 0xb2000000 || instr == 0xb2ffffff)
++ {
++ instr &= ~0x00ffffff;
++ instr |= (val & 0xffffff);
++ bfd_put_32 (abfd, instr, bfd_addr);
++ }
++ else
++ {
++ 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
+@@ -1704,10 +1740,18 @@ microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
+ 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);
+-
++ if (instr_hi == 0xb2000000 || instr_hi == 0xb2ffffff)
++ {
++ instr_hi &= ~0x00ffffff;
++ instr_hi |= (val >> 16) & 0xffffff;
++ bfd_put_32 (abfd, instr_hi,bfd_addr);
++ }
++ else
++ {
++ 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);
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index 663e1a6..8d2980a 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -392,7 +392,7 @@ microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
+ Integer arg to pass to the function. */
+ /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
+ and then in the read.c table. */
+-const pseudo_typeS md_pseudo_table[] =
++pseudo_typeS md_pseudo_table[] =
+ {
+ {"lcomm", microblaze_s_lcomm, 1},
+ {"data", microblaze_s_data, 0},
+@@ -401,7 +401,7 @@ const pseudo_typeS md_pseudo_table[] =
+ {"data32", cons, 4}, /* Same as word. */
+ {"ent", s_func, 0}, /* Treat ent as function entry point. */
+ {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
+- {"gpword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
++ {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
+ {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
+ {"weakext", microblaze_s_weakext, 0},
+ {"rodata", microblaze_s_rdata, 0},
+@@ -996,7 +996,7 @@ md_assemble (char * str)
+ unsigned reg2;
+ unsigned reg3;
+ unsigned isize;
+- unsigned int immed, immed2, temp;
++ unsigned long immed, immed2, temp;
+ expressionS exp;
+ char name[20];
+ long immedl;
+@@ -1118,8 +1118,9 @@ md_assemble (char * str)
+ as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
+ else if (streq (name, "smi"))
+ as_fatal (_("smi pseudo instruction should not use a label in imm field"));
+-
+- if (reg2 == REG_ROSDP)
++ if(streq (name, "lli") || streq (name, "sli"))
++ opc = str_microblaze_64;
++ else if (reg2 == REG_ROSDP)
+ opc = str_microblaze_ro_anchor;
+ else if (reg2 == REG_RWSDP)
+ opc = str_microblaze_rw_anchor;
+@@ -1182,31 +1183,55 @@ md_assemble (char * str)
+ inst |= (immed << IMM_LOW) & IMM_MASK;
+ }
+ }
+- else
+- {
+- temp = immed & 0xFFFF8000;
+- if ((temp != 0) && (temp != 0xFFFF8000))
+- {
++ else if (streq (name, "lli") || streq (name, "sli"))
++ {
++ temp = immed & 0xFFFFFF8000;
++ if (temp != 0 && temp != 0xFFFFFF8000)
++ {
+ /* Needs an immediate inst. */
+- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
+ if (opcode1 == NULL)
+ {
+- as_bad (_("unknown opcode \"%s\""), "imm");
++ as_bad (_("unknown opcode \"%s\""), "imml");
+ return;
+ }
+-
+ inst1 = opcode1->bit_sequence;
+- inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
++ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
+ output[0] = INST_BYTE0 (inst1);
+ output[1] = INST_BYTE1 (inst1);
+ output[2] = INST_BYTE2 (inst1);
+ output[3] = INST_BYTE3 (inst1);
+ output = frag_more (isize);
+- }
+- inst |= (reg1 << RD_LOW) & RD_MASK;
+- inst |= (reg2 << RA_LOW) & RA_MASK;
+- inst |= (immed << IMM_LOW) & IMM_MASK;
+- }
++ }
++ inst |= (reg1 << RD_LOW) & RD_MASK;
++ inst |= (reg2 << RA_LOW) & RA_MASK;
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
++ else
++ {
++ temp = immed & 0xFFFF8000;
++ if ((temp != 0) && (temp != 0xFFFF8000))
++ {
++ /* Needs an immediate inst. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imm");
++ return;
++ }
++
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
++ }
++ inst |= (reg1 << RD_LOW) & RD_MASK;
++ inst |= (reg2 << RA_LOW) & RA_MASK;
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
+ break;
+
+ case INST_TYPE_RD_R1_IMMS:
+@@ -1832,12 +1857,20 @@ md_assemble (char * str)
+ case INST_TYPE_IMM:
+ if (streq (name, "imm"))
+ as_fatal (_("An IMM instruction should not be present in the .s file"));
+-
+- op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
++ if (microblaze_arch_size == 64)
++ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
++ else
++ op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
+
+ if (exp.X_op != O_constant)
+ {
+- char *opc = NULL;
++ char *opc;
++ if (microblaze_arch_size == 64 && (streq (name, "breai") ||
++ streq (name, "breaid") ||
++ streq (name, "brai") || streq (name, "braid")))
++ opc = str_microblaze_64;
++ else
++ opc = NULL;
+ relax_substateT subtype;
+
+ if (exp.X_md != 0)
+@@ -1860,27 +1893,54 @@ md_assemble (char * str)
+ immed = exp.X_add_number;
+ }
+
++ if (microblaze_arch_size == 64 && (streq (name, "breai") ||
++ streq (name, "breaid") ||
++ streq (name, "brai") || streq (name, "braid")))
++ {
++ temp = immed & 0xFFFFFF8000;
++ if (temp != 0)
++ {
++ /* Needs an immediate inst. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imml");
++ return;
++ }
+
+- temp = immed & 0xFFFF8000;
+- if ((temp != 0) && (temp != 0xFFFF8000))
+- {
+- /* Needs an immediate inst. */
+- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
+- if (opcode1 == NULL)
+- {
+- as_bad (_("unknown opcode \"%s\""), "imm");
+- return;
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
+ }
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
++ else
++ {
++ temp = immed & 0xFFFF8000;
++ if ((temp != 0) && (temp != 0xFFFF8000))
++ {
++ /* Needs an immediate inst. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imm");
++ return;
++ }
+
+- inst1 = opcode1->bit_sequence;
+- inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
+- output[0] = INST_BYTE0 (inst1);
+- output[1] = INST_BYTE1 (inst1);
+- output[2] = INST_BYTE2 (inst1);
+- output[3] = INST_BYTE3 (inst1);
+- output = frag_more (isize);
+- }
+- inst |= (immed << IMM_LOW) & IMM_MASK;
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
++ }
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
+ break;
+
+ case INST_TYPE_NONE:
+@@ -2460,7 +2520,7 @@ md_apply_fix (fixS * fixP,
+
+ inst1 = opcode1->bit_sequence;
+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
+- inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ inst1 |= ((val & 0xFFFFFF0000L) >> 16) & IMML_MASK;
+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
+ fixP->fx_r_type = BFD_RELOC_64;
+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
+@@ -2628,7 +2688,14 @@ md_estimate_size_before_relax (fragS * fragP,
+ }
+ else
+ {
+- fragP->fr_subtype = UNDEFINED_PC_OFFSET;
++ if (fragP->fr_opcode != NULL) {
++ if (streq (fragP->fr_opcode, str_microblaze_64))
++ fragP->fr_subtype = DEFINED_64_PC_OFFSET;
++ else
++ fragP->fr_subtype = UNDEFINED_PC_OFFSET;
++ }
++ else
++ fragP->fr_subtype = UNDEFINED_PC_OFFSET;
+ fragP->fr_var = INST_WORD_SIZE*2;
+ }
+ break;
+@@ -2905,6 +2972,7 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
+ case OPTION_M64:
+ //if (arg != NULL && strcmp (arg, "64") == 0)
+ microblaze_arch_size = 64;
++ md_pseudo_table[7].poc_val = 8;
+ break;
+ default:
+ return 0;
+diff --git a/gas/tc.h b/gas/tc.h
+index beddb48..96c7559 100644
+--- a/gas/tc.h
++++ b/gas/tc.h
+@@ -22,7 +22,7 @@
+ /* In theory (mine, at least!) the machine dependent part of the assembler
+ should only have to include one file. This one. -- JF */
+
+-extern const pseudo_typeS md_pseudo_table[];
++extern pseudo_typeS md_pseudo_table[];
+
+ const char * md_atof (int, char *, int *);
+ int md_parse_option (int, const char *);
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0020-Fixing-the-branch-related-issues.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0020-Fixing-the-branch-related-issues.patch
new file mode 100644
index 00000000..0fbb6362
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0020-Fixing-the-branch-related-issues.patch
@@ -0,0 +1,27 @@
+From fc9704bdb0c74f34a77346c0283f2e05440d68ec Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Sun, 30 Sep 2018 17:06:58 +0530
+Subject: [PATCH 20/31] Fixing the branch related issues
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elf64-microblaze.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+index 54a2461..e9b3cf3 100644
+--- a/bfd/elf64-microblaze.c
++++ b/bfd/elf64-microblaze.c
+@@ -2532,7 +2532,7 @@ microblaze_elf_check_relocs (bfd * abfd,
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+- h->root.non_ir_ref = 1;
++ h->root.non_ir_ref_regular = 1;
+ }
+
+ switch (r_type)
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0021-Fixed-address-computation-issues-with-64bit-address.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0021-Fixed-address-computation-issues-with-64bit-address.patch
new file mode 100644
index 00000000..612f706d
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0021-Fixed-address-computation-issues-with-64bit-address.patch
@@ -0,0 +1,219 @@
+From 380ad65a2bdb42749c22783f53f4b2263721a2ca Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Tue, 9 Oct 2018 10:14:22 +0530
+Subject: [PATCH 21/31] - Fixed address computation issues with 64bit address -
+ Fixed imml dissassamble issue
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/bfd-in2.h | 5 ++++
+ bfd/elf64-microblaze.c | 14 ++++-----
+ gas/config/tc-microblaze.c | 74 +++++++++++++++++++++++++++++++++++++++++-----
+ opcodes/microblaze-dis.c | 2 +-
+ 4 files changed, 79 insertions(+), 16 deletions(-)
+
+diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
+index 44e719b..a35e51d 100644
+--- a/bfd/bfd-in2.h
++++ b/bfd/bfd-in2.h
+@@ -5805,6 +5805,11 @@ done here - only used for relaxing */
+ * +done here - only used for relaxing */
+ BFD_RELOC_MICROBLAZE_64,
+
++/* This is a 64 bit reloc that stores the 32 bit relative
++ * +value in two words (with an imml instruction). No relocation is
++ * +done here - only used for relaxing */
++ BFD_RELOC_MICROBLAZE_EA64,
++
+ /* This is a 64 bit reloc that stores the 32 bit pc relative
+ * +value in two words (with an imm instruction). No relocation is
+ * +done here - only used for relaxing */
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+index e9b3cf3..40f10aa 100644
+--- a/bfd/elf64-microblaze.c
++++ b/bfd/elf64-microblaze.c
+@@ -121,15 +121,15 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
+ 0, /* Rightshift. */
+ 4, /* Size (0 = byte, 1 = short, 2 = long). */
+ 64, /* Bitsize. */
+- TRUE, /* PC_relative. */
++ FALSE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc,/* Special Function. */
+ "R_MICROBLAZE_IMML_64", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+- 0x0000ffff, /* Dest Mask. */
+- TRUE), /* PC relative offset? */
++ 0xffffffffffffff, /* Dest Mask. */
++ FALSE), /* PC relative offset? */
+
+ /* A 64 bit relocation. Table entry not really used. */
+ HOWTO (R_MICROBLAZE_64, /* Type. */
+@@ -585,9 +585,9 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ case BFD_RELOC_32:
+ microblaze_reloc = R_MICROBLAZE_32;
+ break;
+- /* RVA is treated the same as 32 */
++ /* RVA is treated the same as 64 */
+ case BFD_RELOC_RVA:
+- microblaze_reloc = R_MICROBLAZE_32;
++ microblaze_reloc = R_MICROBLAZE_IMML_64;
+ break;
+ case BFD_RELOC_32_PCREL:
+ microblaze_reloc = R_MICROBLAZE_32_PCREL;
+@@ -619,7 +619,7 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ case BFD_RELOC_VTABLE_ENTRY:
+ microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
+ break;
+- case BFD_RELOC_MICROBLAZE_64:
++ case BFD_RELOC_MICROBLAZE_EA64:
+ microblaze_reloc = R_MICROBLAZE_IMML_64;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
+@@ -1969,7 +1969,7 @@ microblaze_elf_relax_section (bfd *abfd,
+ efix = calc_fixup (target_address, 0, sec);
+
+ /* Validate the in-band val. */
+- val = bfd_get_32 (abfd, contents + irel->r_offset);
++ val = bfd_get_64 (abfd, contents + irel->r_offset);
+ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
+ }
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index 8d2980a..7ff93a1 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -402,7 +402,6 @@ pseudo_typeS md_pseudo_table[] =
+ {"ent", s_func, 0}, /* Treat ent as function entry point. */
+ {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
+ {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
+- {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
+ {"weakext", microblaze_s_weakext, 0},
+ {"rodata", microblaze_s_rdata, 0},
+ {"sdata2", microblaze_s_rdata, 1},
+@@ -2482,15 +2481,71 @@ md_apply_fix (fixS * fixP,
+ /* Don't do anything if the symbol is not defined. */
+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
+ {
++ if ((fixP->fx_r_type == BFD_RELOC_RVA) && (microblaze_arch_size == 64))
++ {
++ if (target_big_endian)
++ {
++ buf[0] |= ((val >> 56) & 0xff);
++ buf[1] |= ((val >> 48) & 0xff);
++ buf[2] |= ((val >> 40) & 0xff);
++ buf[3] |= ((val >> 32) & 0xff);
++ buf[4] |= ((val >> 24) & 0xff);
++ buf[5] |= ((val >> 16) & 0xff);
++ buf[6] |= ((val >> 8) & 0xff);
++ buf[7] |= (val & 0xff);
++ }
++ else
++ {
++ buf[7] |= ((val >> 56) & 0xff);
++ buf[6] |= ((val >> 48) & 0xff);
++ buf[5] |= ((val >> 40) & 0xff);
++ buf[4] |= ((val >> 32) & 0xff);
++ buf[3] |= ((val >> 24) & 0xff);
++ buf[2] |= ((val >> 16) & 0xff);
++ buf[1] |= ((val >> 8) & 0xff);
++ buf[0] |= (val & 0xff);
++ }
++ }
++ else {
++ if (target_big_endian)
++ {
++ buf[0] |= ((val >> 24) & 0xff);
++ buf[1] |= ((val >> 16) & 0xff);
++ buf[2] |= ((val >> 8) & 0xff);
++ buf[3] |= (val & 0xff);
++ }
++ else
++ {
++ buf[3] |= ((val >> 24) & 0xff);
++ buf[2] |= ((val >> 16) & 0xff);
++ buf[1] |= ((val >> 8) & 0xff);
++ buf[0] |= (val & 0xff);
++ }
++ }
++ }
++ break;
++
++ case BFD_RELOC_MICROBLAZE_EA64:
++ /* Don't do anything if the symbol is not defined. */
++ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
++ {
+ if (target_big_endian)
+ {
+- buf[0] |= ((val >> 24) & 0xff);
+- buf[1] |= ((val >> 16) & 0xff);
+- buf[2] |= ((val >> 8) & 0xff);
+- buf[3] |= (val & 0xff);
++ buf[0] |= ((val >> 56) & 0xff);
++ buf[1] |= ((val >> 48) & 0xff);
++ buf[2] |= ((val >> 40) & 0xff);
++ buf[3] |= ((val >> 32) & 0xff);
++ buf[4] |= ((val >> 24) & 0xff);
++ buf[5] |= ((val >> 16) & 0xff);
++ buf[6] |= ((val >> 8) & 0xff);
++ buf[7] |= (val & 0xff);
+ }
+ else
+ {
++ buf[7] |= ((val >> 56) & 0xff);
++ buf[6] |= ((val >> 48) & 0xff);
++ buf[5] |= ((val >> 40) & 0xff);
++ buf[4] |= ((val >> 32) & 0xff);
+ buf[3] |= ((val >> 24) & 0xff);
+ buf[2] |= ((val >> 16) & 0xff);
+ buf[1] |= ((val >> 8) & 0xff);
+@@ -2611,6 +2666,8 @@ md_apply_fix (fixS * fixP,
+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
+ else if (fixP->fx_r_type == BFD_RELOC_32)
+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
++ else if(fixP->fx_r_type == BFD_RELOC_MICROBLAZE_EA64)
++ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_EA64;
+ else
+ fixP->fx_r_type = BFD_RELOC_NONE;
+ fixP->fx_addsy = section_symbol (absolute_section);
+@@ -2882,6 +2939,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
+ case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
+ case BFD_RELOC_MICROBLAZE_64_GPC:
++ case BFD_RELOC_MICROBLAZE_EA64:
+ case BFD_RELOC_MICROBLAZE_64:
+ case BFD_RELOC_MICROBLAZE_64_PCREL:
+ case BFD_RELOC_MICROBLAZE_64_GOT:
+@@ -3027,10 +3085,10 @@ cons_fix_new_microblaze (fragS * frag,
+ r = BFD_RELOC_32;
+ break;
+ case 8:
+- if (microblaze_arch_size == 64)
++ /*if (microblaze_arch_size == 64)
+ r = BFD_RELOC_32;
+- else
+- r = BFD_RELOC_64;
++ else*/
++ r = BFD_RELOC_MICROBLAZE_EA64;
+ break;
+ default:
+ as_bad (_("unsupported BFD relocation size %u"), size);
+diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
+index 09757d1..69e11e6 100644
+--- a/opcodes/microblaze-dis.c
++++ b/opcodes/microblaze-dis.c
+@@ -61,7 +61,7 @@ get_field_imml (long instr)
+ {
+ char tmpstr[25];
+
+- sprintf (tmpstr, "%d", (short)((instr & IMML_MASK) >> IMM_LOW));
++ sprintf (tmpstr, "%d", (int)((instr & IMML_MASK) >> IMM_LOW));
+ return (strdup (tmpstr));
+ }
+
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0022-Adding-new-relocation-to-support-64bit-rodata.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0022-Adding-new-relocation-to-support-64bit-rodata.patch
new file mode 100644
index 00000000..4e54b0d3
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0022-Adding-new-relocation-to-support-64bit-rodata.patch
@@ -0,0 +1,168 @@
+From e2c399e62b6b0f1940e73024a8076c8787602b9c Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Sat, 13 Oct 2018 21:17:01 +0530
+Subject: [PATCH 22/31] Adding new relocation to support 64bit rodata
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elf64-microblaze.c | 11 +++++++++--
+ gas/config/tc-microblaze.c | 49 ++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 54 insertions(+), 6 deletions(-)
+
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+index 40f10aa..4d9b906 100644
+--- a/bfd/elf64-microblaze.c
++++ b/bfd/elf64-microblaze.c
+@@ -1461,6 +1461,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ case (int) R_MICROBLAZE_64_PCREL :
+ case (int) R_MICROBLAZE_64:
+ case (int) R_MICROBLAZE_32:
++ case (int) R_MICROBLAZE_IMML_64:
+ {
+ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
+ from removed linkonce sections, or sections discarded by
+@@ -1470,6 +1471,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ relocation += addend;
+ if (r_type == R_MICROBLAZE_32)// || r_type == R_MICROBLAZE_IMML_64)
+ bfd_put_32 (input_bfd, relocation, contents + offset);
++ else if (r_type == R_MICROBLAZE_IMML_64)
++ bfd_put_64 (input_bfd, relocation, contents + offset);
+ else
+ {
+ if (r_type == R_MICROBLAZE_64_PCREL)
+@@ -1547,7 +1550,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ }
+ else
+ {
+- if (r_type == R_MICROBLAZE_32)
++ if (r_type == R_MICROBLAZE_32 || r_type == R_MICROBLAZE_IMML_64)
+ {
+ outrel.r_info = ELF64_R_INFO (0, R_MICROBLAZE_REL);
+ outrel.r_addend = relocation + addend;
+@@ -1573,6 +1576,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ relocation += addend;
+ if (r_type == R_MICROBLAZE_32)
+ bfd_put_32 (input_bfd, relocation, contents + offset);
++ else if (r_type == R_MICROBLAZE_IMML_64)
++ bfd_put_64 (input_bfd, relocation, contents + offset + endian);
+ else
+ {
+ if (r_type == R_MICROBLAZE_64_PCREL)
+@@ -2085,7 +2090,8 @@ microblaze_elf_relax_section (bfd *abfd,
+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
+ irelscan->r_addend);
+ }
+- if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
++ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32
++ || ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
+ {
+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
+
+@@ -2591,6 +2597,7 @@ microblaze_elf_check_relocs (bfd * abfd,
+ case R_MICROBLAZE_64:
+ case R_MICROBLAZE_64_PCREL:
+ case R_MICROBLAZE_32:
++ case R_MICROBLAZE_IMML_64:
+ {
+ if (h != NULL && !bfd_link_pic (info))
+ {
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index 7ff93a1..442f72c 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -1119,6 +1119,13 @@ md_assemble (char * str)
+ as_fatal (_("smi pseudo instruction should not use a label in imm field"));
+ if(streq (name, "lli") || streq (name, "sli"))
+ opc = str_microblaze_64;
++ else if ((microblaze_arch_size == 64) && ((streq (name, "lbui")
++ || streq (name, "lhui") || streq (name, "lwi") || streq (name, "sbi")
++ || streq (name, "shi") || streq (name, "swi"))))
++ {
++ opc = str_microblaze_64;
++ subtype = opcode->inst_offset_type;
++ }
+ else if (reg2 == REG_ROSDP)
+ opc = str_microblaze_ro_anchor;
+ else if (reg2 == REG_RWSDP)
+@@ -1182,7 +1189,10 @@ md_assemble (char * str)
+ inst |= (immed << IMM_LOW) & IMM_MASK;
+ }
+ }
+- else if (streq (name, "lli") || streq (name, "sli"))
++ else if (streq (name, "lli") || streq (name, "sli") || ((microblaze_arch_size == 64)
++ && ((streq (name, "lbui")) || streq (name, "lhui")
++ || streq (name, "lwi") || streq (name, "sbi")
++ || streq (name, "shi") || streq (name, "swi"))))
+ {
+ temp = immed & 0xFFFFFF8000;
+ if (temp != 0 && temp != 0xFFFFFF8000)
+@@ -1794,6 +1804,11 @@ md_assemble (char * str)
+
+ if (exp.X_md != 0)
+ subtype = get_imm_otype(exp.X_md);
++ else if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
++ {
++ opc = str_microblaze_64;
++ subtype = opcode->inst_offset_type;
++ }
+ else
+ subtype = opcode->inst_offset_type;
+
+@@ -1811,6 +1826,31 @@ md_assemble (char * str)
+ output = frag_more (isize);
+ immed = exp.X_add_number;
+ }
++ if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
++ {
++ temp = immed & 0xFFFFFF8000;
++ if (temp != 0 && temp != 0xFFFFFF8000)
++ {
++ /* Needs an immediate inst. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imml");
++ return;
++ }
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
++ }
++ inst |= (reg1 << RD_LOW) & RD_MASK;
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
++ else
++ {
+
+ temp = immed & 0xFFFF8000;
+ if ((temp != 0) && (temp != 0xFFFF8000))
+@@ -1834,6 +1874,7 @@ md_assemble (char * str)
+
+ inst |= (reg1 << RD_LOW) & RD_MASK;
+ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
+ break;
+
+ case INST_TYPE_R2:
+@@ -3085,10 +3126,10 @@ cons_fix_new_microblaze (fragS * frag,
+ r = BFD_RELOC_32;
+ break;
+ case 8:
+- /*if (microblaze_arch_size == 64)
+- r = BFD_RELOC_32;
+- else*/
++ if (microblaze_arch_size == 64)
+ r = BFD_RELOC_MICROBLAZE_EA64;
++ else
++ r = BFD_RELOC_64;
+ break;
+ default:
+ as_bad (_("unsupported BFD relocation size %u"), size);
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0023-fixing-the-.bss-relocation-issue.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0023-fixing-the-.bss-relocation-issue.patch
new file mode 100644
index 00000000..fc42ca58
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0023-fixing-the-.bss-relocation-issue.patch
@@ -0,0 +1,78 @@
+From 2a2298c9f32e96a71d6295e7ef52b37d834e5224 Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Wed, 24 Oct 2018 12:34:37 +0530
+Subject: [PATCH 23/31] fixing the .bss relocation issue
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elf64-microblaze.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+index 4d9b906..184b7d5 100644
+--- a/bfd/elf64-microblaze.c
++++ b/bfd/elf64-microblaze.c
+@@ -1480,7 +1480,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ + input_section->output_offset
+ + offset + INST_WORD_SIZE);
+ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
+- if (insn == 0xb2000000 || insn == 0xb2ffffff)
++ if ((insn & 0xff000000) == 0xb2000000)
+ {
+ insn &= ~0x00ffffff;
+ insn |= (relocation >> 16) & 0xffffff;
+@@ -1593,7 +1593,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ + offset + INST_WORD_SIZE);
+ }
+ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
+- if (insn == 0xb2000000 || insn == 0xb2ffffff)
++ if ((insn & 0xff000000) == 0xb2000000)
+ {
+ insn &= ~0x00ffffff;
+ insn |= (relocation >> 16) & 0xffffff;
+@@ -1722,7 +1722,7 @@ microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
+ {
+ unsigned long instr = bfd_get_32 (abfd, bfd_addr);
+
+- if (instr == 0xb2000000 || instr == 0xb2ffffff)
++ if ((instr & 0xff000000) == 0xb2000000)
+ {
+ instr &= ~0x00ffffff;
+ instr |= (val & 0xffffff);
+@@ -1745,7 +1745,7 @@ microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
+ unsigned long instr_lo;
+
+ instr_hi = bfd_get_32 (abfd, bfd_addr);
+- if (instr_hi == 0xb2000000 || instr_hi == 0xb2ffffff)
++ if ((instr_hi & 0xff000000) == 0xb2000000)
+ {
+ instr_hi &= ~0x00ffffff;
+ instr_hi |= (val >> 16) & 0xffffff;
+@@ -2238,7 +2238,10 @@ microblaze_elf_relax_section (bfd *abfd,
+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
+ + irelscan->r_offset
+ + INST_WORD_SIZE);
+- immediate = (instr_hi & 0x0000ffff) << 16;
++ if ((instr_hi & 0xff000000) == 0xb2000000)
++ immediate = (instr_hi & 0x00ffffff) << 24;
++ else
++ immediate = (instr_hi & 0x0000ffff) << 16;
+ immediate |= (instr_lo & 0x0000ffff);
+ offset = calc_fixup (irelscan->r_addend, 0, sec);
+ immediate -= offset;
+@@ -2282,7 +2285,10 @@ microblaze_elf_relax_section (bfd *abfd,
+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
+ + irelscan->r_offset
+ + INST_WORD_SIZE);
+- immediate = (instr_hi & 0x0000ffff) << 16;
++ if ((instr_hi & 0xff000000) == 0xb2000000)
++ immediate = (instr_hi & 0x00ffffff) << 24;
++ else
++ immediate = (instr_hi & 0x0000ffff) << 16;
+ immediate |= (instr_lo & 0x0000ffff);
+ target_address = immediate;
+ offset = calc_fixup (target_address, 0, sec);
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch
new file mode 100644
index 00000000..5c327d2d
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0024-Fixed-the-bug-in-the-R_MICROBLAZE_64_NONE-relocation.patch
@@ -0,0 +1,46 @@
+From 198f2ccd054613f39bbad49b3f0dbad23036b4fc Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Wed, 28 Nov 2018 14:00:29 +0530
+Subject: [PATCH 24/31] Fixed the bug in the R_MICROBLAZE_64_NONE relocation.
+ It was adjusting only lower 16bits.
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elf32-microblaze.c | 4 ++--
+ bfd/elf64-microblaze.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
+index b632dd1..ffb23d8 100644
+--- a/bfd/elf32-microblaze.c
++++ b/bfd/elf32-microblaze.c
+@@ -2022,8 +2022,8 @@ microblaze_elf_relax_section (bfd *abfd,
+ 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);
++ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
++ irel->r_addend);
+ }
+ break;
+ }
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+index 184b7d5..ef6a870 100644
+--- a/bfd/elf64-microblaze.c
++++ b/bfd/elf64-microblaze.c
+@@ -2017,8 +2017,8 @@ microblaze_elf_relax_section (bfd *abfd,
+ 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);
++ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
++ irel->r_addend);
+ }
+ break;
+ }
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch
new file mode 100644
index 00000000..f035a8da
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0025-Patch-MicroBlaze-fixed-Build-issue-which-are-due-to-.patch
@@ -0,0 +1,70 @@
+From 597ab75895c106c673db0e7a2adfac2f2350c2ec Mon Sep 17 00:00:00 2001
+From: Mahesh Bodapati <mbodapat@xilinx.com>
+Date: Sun, 2 Dec 2018 14:49:14 +0530
+Subject: [PATCH 25/31] [Patch,MicroBlaze]: fixed Build issue which are due to
+ conflicts in patches.
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elf32-microblaze.c | 1 +
+ bfd/elf64-microblaze.c | 12 ++++++------
+ gas/config/tc-microblaze.c | 4 ++--
+ 3 files changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
+index ffb23d8..53924f6 100644
+--- a/bfd/elf32-microblaze.c
++++ b/bfd/elf32-microblaze.c
+@@ -1996,6 +1996,7 @@ microblaze_elf_relax_section (bfd *abfd,
+ /* This was a PC-relative instruction that was
+ completely resolved. */
+ int sfix, efix;
++ unsigned int val;
+ bfd_vma target_address;
+ target_address = irel->r_addend + irel->r_offset;
+ sfix = calc_fixup (irel->r_offset, 0, sec);
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+index ef6a870..bed534e 100644
+--- a/bfd/elf64-microblaze.c
++++ b/bfd/elf64-microblaze.c
+@@ -2854,14 +2854,14 @@ microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+- if (h->u.weakdef != NULL)
++ if (h->is_weakalias)
+ {
+- BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+- || h->u.weakdef->root.type == bfd_link_hash_defweak);
+- h->root.u.def.section = h->u.weakdef->root.u.def.section;
+- h->root.u.def.value = h->u.weakdef->root.u.def.value;
++ struct elf_link_hash_entry *def = weakdef (h);
++ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
++ h->root.u.def.section = def->root.u.def.section;
++ h->root.u.def.value = def->root.u.def.value;
+ return TRUE;
+- }
++ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index 442f72c..edc7985 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -118,9 +118,9 @@ const relax_typeS md_relax_table[] =
+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 16: TLSTPREL_OFFSET. */
+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
+- { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
++ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 18: TEXT_PC_OFFSET. */
+ // { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
+- { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 19: DEFINED_64_OFFSET. */
++ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 }, /* 19: DEFINED_64_OFFSET. */
+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE*2, 0 } /* 20: DEFINED_64_PC_OFFSET. */
+ };
+
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch
new file mode 100644
index 00000000..a7ecec15
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0026-Patch-Microblaze-changes-of-PR22458-failure-to-choos.patch
@@ -0,0 +1,33 @@
+From c0be3d2a8f0ac0c1a2ba82253c9eea99071da0a9 Mon Sep 17 00:00:00 2001
+From: Mahesh Bodapati <mbodapat@xilinx.com>
+Date: Tue, 26 Feb 2019 17:31:41 +0530
+Subject: [PATCH 26/31] [Patch,Microblaze] : changes of "PR22458, failure to
+ choose a matching ELF target" is causing "Multiple Prevailing definition
+ errors",added check for best_match elf.
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/format.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/bfd/format.c b/bfd/format.c
+index c4afd97..4f7367d 100644
+--- a/bfd/format.c
++++ b/bfd/format.c
+@@ -292,7 +292,12 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
+
+ /* Don't check the default target twice. */
+ if (*target == &binary_vec
++#if !BFD_SUPPORTS_PLUGINS
+ || (!abfd->target_defaulted && *target == save_targ))
++#else
++ || (!abfd->target_defaulted && *target == save_targ)
++ || (*target)->match_priority > best_match)
++#endif
+ continue;
+
+ /* If we already tried a match, the bfd is modified and may
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0027-Patch-Microblaze-PR22471-undefined-reference-to-link.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0027-Patch-Microblaze-PR22471-undefined-reference-to-link.patch
new file mode 100644
index 00000000..002b3794
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0027-Patch-Microblaze-PR22471-undefined-reference-to-link.patch
@@ -0,0 +1,363 @@
+From 059fc6d823a81602d951275ba99430550b84f8a3 Mon Sep 17 00:00:00 2001
+From: Mahesh Bodapati <mbodapat@xilinx.com>
+Date: Tue, 26 Feb 2019 17:46:36 +0530
+Subject: [PATCH 27/31] [Patch,Microblaze] : "PR22471, undefined reference to
+ linker-defined symbols" is causing runtime loops.reverting for now.
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elflink.c | 7 +---
+ bfd/linker.c | 9 +----
+ ld/ldexp.c | 64 +++++++++++++++++++------------
+ ld/ldlang.c | 6 +--
+ ld/testsuite/ld-mips-elf/tlsdyn-o32-1.d | 4 +-
+ ld/testsuite/ld-mips-elf/tlsdyn-o32-1.got | 2 +-
+ ld/testsuite/ld-mips-elf/tlsdyn-o32-2.d | 4 +-
+ ld/testsuite/ld-mips-elf/tlsdyn-o32-2.got | 2 +-
+ ld/testsuite/ld-mips-elf/tlsdyn-o32-3.d | 4 +-
+ ld/testsuite/ld-mips-elf/tlsdyn-o32-3.got | 2 +-
+ 10 files changed, 53 insertions(+), 51 deletions(-)
+
+diff --git a/bfd/elflink.c b/bfd/elflink.c
+index b316149..3860891 100644
+--- a/bfd/elflink.c
++++ b/bfd/elflink.c
+@@ -1496,15 +1496,10 @@ _bfd_elf_merge_symbol (bfd *abfd,
+ treated as strong if the new symbol is from a dynamic library.
+ This reflects the way glibc's ld.so works.
+
+- Also allow a weak symbol to override a linker script symbol
+- defined by an early pass over the script. This is done so the
+- linker knows the symbol is defined in an object file, for the
+- DEFINED script function.
+-
+ Do this before setting *type_change_ok or *size_change_ok so that
+ we warn properly when dynamic library symbols are overridden. */
+
+- if (newdef && !newdyn && (olddyn || h->root.ldscript_def))
++ if (newdef && !newdyn && olddyn)
+ newweak = FALSE;
+ if (olddef && newdyn)
+ oldweak = FALSE;
+diff --git a/bfd/linker.c b/bfd/linker.c
+index 6b4c8e5..8d51c2a 100644
+--- a/bfd/linker.c
++++ b/bfd/linker.c
+@@ -1449,14 +1449,9 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
+ do
+ {
+ enum link_action action;
+- int prev;
+
+- prev = h->type;
+- /* Treat symbols defined by early linker script pass as undefined. */
+- if (h->ldscript_def)
+- prev = bfd_link_hash_undefined;
+ cycle = FALSE;
+- action = link_action[(int) row][prev];
++ action = link_action[(int) row][(int) h->type];
+ switch (action)
+ {
+ case FAIL:
+@@ -1500,7 +1495,6 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
+ h->u.def.section = section;
+ h->u.def.value = value;
+ h->linker_def = 0;
+- h->ldscript_def = 0;
+
+ /* If we have been asked to, we act like collect2 and
+ identify all functions that might be global
+@@ -1600,7 +1594,6 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
+ else
+ h->u.c.p->section = section;
+ h->linker_def = 0;
+- h->ldscript_def = 0;
+ break;
+
+ case REF:
+diff --git a/ld/ldexp.c b/ld/ldexp.c
+index 6fa251e..d46a06f 100644
+--- a/ld/ldexp.c
++++ b/ld/ldexp.c
+@@ -60,12 +60,15 @@ struct definedness_hash_entry
+ section statement, the section we'd like it relative to. */
+ asection *final_sec;
+
+- /* Low bits of iteration count. Symbols with matching iteration have
+- been defined in this pass over the script. */
+- unsigned int iteration : 8;
+-
+ /* Symbol was defined by an object file. */
+ unsigned int by_object : 1;
++
++ /* Symbols was defined by a script. */
++ unsigned int by_script : 1;
++
++ /* Low bit of iteration count. Symbols with matching iteration have
++ been defined in this pass over the script. */
++ unsigned int iteration : 1;
+ };
+
+ static struct bfd_hash_table definedness_table;
+@@ -283,6 +286,7 @@ definedness_newfunc (struct bfd_hash_entry *entry,
+ einfo (_("%F%P: bfd_hash_allocate failed creating symbol %s\n"), name);
+
+ ret->by_object = 0;
++ ret->by_script = 0;
+ ret->iteration = 0;
+ return &ret->root;
+ }
+@@ -316,7 +320,7 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h)
+ /* If the symbol was already defined, and not by a script, then it
+ must be defined by an object file or by the linker target code. */
+ ret = TRUE;
+- if (!h->ldscript_def
++ if (!defentry->by_script
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak
+ || h->type == bfd_link_hash_common))
+@@ -328,6 +332,7 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h)
+ ret = FALSE;
+ }
+
++ defentry->by_script = 1;
+ defentry->iteration = lang_statement_iteration;
+ defentry->final_sec = bfd_abs_section_ptr;
+ if (expld.phase == lang_final_phase_enum
+@@ -681,9 +686,6 @@ fold_trinary (etree_type *tree)
+ static void
+ fold_name (etree_type *tree)
+ {
+- struct bfd_link_hash_entry *h;
+- struct definedness_hash_entry *def;
+-
+ memset (&expld.result, 0, sizeof (expld.result));
+
+ switch (tree->type.node_code)
+@@ -701,18 +703,23 @@ fold_name (etree_type *tree)
+ break;
+
+ case DEFINED:
+- h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
+- &link_info,
+- tree->name.name,
+- FALSE, FALSE, TRUE);
+- new_number (h != NULL
+- && (h->type == bfd_link_hash_defined
+- || h->type == bfd_link_hash_defweak
+- || h->type == bfd_link_hash_common)
+- && (!h->ldscript_def
+- || (def = symbol_defined (tree->name.name)) == NULL
+- || def->by_object
+- || def->iteration == (lang_statement_iteration & 255)));
++ if (expld.phase != lang_first_phase_enum)
++ {
++ struct bfd_link_hash_entry *h;
++ struct definedness_hash_entry *def;
++
++ h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
++ &link_info,
++ tree->name.name,
++ FALSE, FALSE, TRUE);
++ new_number (h != NULL
++ && (h->type == bfd_link_hash_defined
++ || h->type == bfd_link_hash_defweak
++ || h->type == bfd_link_hash_common)
++ && ((def = symbol_defined (tree->name.name)) == NULL
++ || def->by_object
++ || def->iteration == (lang_statement_iteration & 1)));
++ }
+ break;
+
+ case NAME:
+@@ -721,6 +728,9 @@ fold_name (etree_type *tree)
+ {
+ /* Self-assignment is only allowed for absolute symbols
+ defined in a linker script. */
++ struct bfd_link_hash_entry *h;
++ struct definedness_hash_entry *def;
++
+ h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
+ &link_info,
+ tree->name.name,
+@@ -730,13 +740,17 @@ fold_name (etree_type *tree)
+ || h->type == bfd_link_hash_defweak)
+ && h->u.def.section == bfd_abs_section_ptr
+ && (def = symbol_defined (tree->name.name)) != NULL
+- && def->iteration == (lang_statement_iteration & 255)))
++ && def->iteration == (lang_statement_iteration & 1)))
+ expld.assign_name = NULL;
+ }
+- if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
++ if (expld.phase == lang_first_phase_enum)
++ ;
++ else if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
+ new_rel_from_abs (expld.dot);
+ else
+ {
++ struct bfd_link_hash_entry *h;
++
+ h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
+ &link_info,
+ tree->name.name,
+@@ -751,7 +765,7 @@ fold_name (etree_type *tree)
+ output_section = h->u.def.section->output_section;
+ if (output_section == NULL)
+ {
+- if (expld.phase <= lang_mark_phase_enum)
++ if (expld.phase == lang_mark_phase_enum)
+ new_rel (h->u.def.value, h->u.def.section);
+ else
+ einfo (_("%X%P:%pS: unresolvable symbol `%s'"
+@@ -943,12 +957,12 @@ is_sym_value (const etree_type *tree, bfd_vma val)
+ return (tree->type.node_class == etree_name
+ && tree->type.node_code == NAME
+ && (def = symbol_defined (tree->name.name)) != NULL
+- && def->iteration == (lang_statement_iteration & 255)
++ && def->by_script
++ && def->iteration == (lang_statement_iteration & 1)
+ && (h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
+ &link_info,
+ tree->name.name,
+ FALSE, FALSE, TRUE)) != NULL
+- && h->ldscript_def
+ && h->type == bfd_link_hash_defined
+ && h->u.def.section == bfd_abs_section_ptr
+ && h->u.def.value == val);
+diff --git a/ld/ldlang.c b/ld/ldlang.c
+index 350baf2..7e12480 100644
+--- a/ld/ldlang.c
++++ b/ld/ldlang.c
+@@ -3360,7 +3360,9 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
+ #endif
+ break;
+ case lang_assignment_statement_enum:
+- if (s->assignment_statement.exp->type.node_class != etree_assert)
++ if (s->assignment_statement.exp->type.node_class != etree_assert
++ && s->assignment_statement.exp->assign.defsym)
++ /* This is from a --defsym on the command line. */
+ exp_fold_tree_no_dot (s->assignment_statement.exp);
+ break;
+ default:
+@@ -7176,7 +7178,6 @@ lang_process (void)
+
+ /* Create a bfd for each input file. */
+ current_target = default_target;
+- lang_statement_iteration++;
+ open_input_bfds (statement_list.head, OPEN_BFD_NORMAL);
+
+ #ifdef ENABLE_PLUGINS
+@@ -7232,7 +7233,6 @@ lang_process (void)
+
+ /* Rescan archives in case new undefined symbols have appeared. */
+ files = file_chain;
+- lang_statement_iteration++;
+ open_input_bfds (statement_list.head, OPEN_BFD_RESCAN);
+ lang_list_remove_tail (&file_chain, &files);
+ while (files.head != NULL)
+diff --git a/ld/testsuite/ld-mips-elf/tlsdyn-o32-1.d b/ld/testsuite/ld-mips-elf/tlsdyn-o32-1.d
+index 17e42d0..011df6c 100644
+--- a/ld/testsuite/ld-mips-elf/tlsdyn-o32-1.d
++++ b/ld/testsuite/ld-mips-elf/tlsdyn-o32-1.d
+@@ -5,7 +5,7 @@ Disassembly of section .text:
+
+ .* <__start>:
+ .*: 3c1c0fc0 lui gp,0xfc0
+- .*: 279c7b80 addiu gp,gp,31616
++ .*: 279c7c30 addiu gp,gp,31792
+ .*: 0399e021 addu gp,gp,t9
+ .*: 27bdfff0 addiu sp,sp,-16
+ .*: afbe0008 sw s8,8\(sp\)
+@@ -55,7 +55,7 @@ Disassembly of section .text:
+
+ .* <other>:
+ .*: 3c1c0fc0 lui gp,0xfc0
+- .*: 279c7ac0 addiu gp,gp,31424
++ .*: 279c7b70 addiu gp,gp,31600
+ .*: 0399e021 addu gp,gp,t9
+ .*: 27bdfff0 addiu sp,sp,-16
+ .*: afbe0008 sw s8,8\(sp\)
+diff --git a/ld/testsuite/ld-mips-elf/tlsdyn-o32-1.got b/ld/testsuite/ld-mips-elf/tlsdyn-o32-1.got
+index 508fed2..1dbcab4 100644
+--- a/ld/testsuite/ld-mips-elf/tlsdyn-o32-1.got
++++ b/ld/testsuite/ld-mips-elf/tlsdyn-o32-1.got
+@@ -13,6 +13,6 @@ OFFSET TYPE VALUE
+
+
+ Contents of section .got:
+- 10000020 00000000 80000000 0040053c 00000000 .........@......
++ 10000020 00000000 80000000 0040048c 00000000 .........@......
+ 10000030 00000000 00000000 00000000 00000000 ................
+ 10000040 00000000 00000001 00000000 ............
+diff --git a/ld/testsuite/ld-mips-elf/tlsdyn-o32-2.d b/ld/testsuite/ld-mips-elf/tlsdyn-o32-2.d
+index 17e42d0..011df6c 100644
+--- a/ld/testsuite/ld-mips-elf/tlsdyn-o32-2.d
++++ b/ld/testsuite/ld-mips-elf/tlsdyn-o32-2.d
+@@ -5,7 +5,7 @@ Disassembly of section .text:
+
+ .* <__start>:
+ .*: 3c1c0fc0 lui gp,0xfc0
+- .*: 279c7b80 addiu gp,gp,31616
++ .*: 279c7c30 addiu gp,gp,31792
+ .*: 0399e021 addu gp,gp,t9
+ .*: 27bdfff0 addiu sp,sp,-16
+ .*: afbe0008 sw s8,8\(sp\)
+@@ -55,7 +55,7 @@ Disassembly of section .text:
+
+ .* <other>:
+ .*: 3c1c0fc0 lui gp,0xfc0
+- .*: 279c7ac0 addiu gp,gp,31424
++ .*: 279c7b70 addiu gp,gp,31600
+ .*: 0399e021 addu gp,gp,t9
+ .*: 27bdfff0 addiu sp,sp,-16
+ .*: afbe0008 sw s8,8\(sp\)
+diff --git a/ld/testsuite/ld-mips-elf/tlsdyn-o32-2.got b/ld/testsuite/ld-mips-elf/tlsdyn-o32-2.got
+index 4a97099..fb50635 100644
+--- a/ld/testsuite/ld-mips-elf/tlsdyn-o32-2.got
++++ b/ld/testsuite/ld-mips-elf/tlsdyn-o32-2.got
+@@ -13,6 +13,6 @@ OFFSET TYPE VALUE
+
+
+ Contents of section .got:
+- 10000020 00000000 80000000 0040053c 00000000 .*
++ 10000020 00000000 80000000 0040048c 00000000 .*
+ 10000030 00000000 00000000 00000000 00000000 .*
+ 10000040 00000000 00000001 00000000 .*
+diff --git a/ld/testsuite/ld-mips-elf/tlsdyn-o32-3.d b/ld/testsuite/ld-mips-elf/tlsdyn-o32-3.d
+index fb3750a..3828aca 100644
+--- a/ld/testsuite/ld-mips-elf/tlsdyn-o32-3.d
++++ b/ld/testsuite/ld-mips-elf/tlsdyn-o32-3.d
+@@ -5,7 +5,7 @@ Disassembly of section .text:
+
+ .* <other>:
+ .*: 3c1c0fc0 lui gp,0xfc0
+- .*: 279c7b80 addiu gp,gp,31616
++ .*: 279c7c30 addiu gp,gp,31792
+ .*: 0399e021 addu gp,gp,t9
+ .*: 27bdfff0 addiu sp,sp,-16
+ .*: afbe0008 sw s8,8\(sp\)
+@@ -51,7 +51,7 @@ Disassembly of section .text:
+
+ .* <__start>:
+ .*: 3c1c0fc0 lui gp,0xfc0
+- .*: 279c7ad0 addiu gp,gp,31440
++ .*: 279c7b80 addiu gp,gp,31616
+ .*: 0399e021 addu gp,gp,t9
+ .*: 27bdfff0 addiu sp,sp,-16
+ .*: afbe0008 sw s8,8\(sp\)
+diff --git a/ld/testsuite/ld-mips-elf/tlsdyn-o32-3.got b/ld/testsuite/ld-mips-elf/tlsdyn-o32-3.got
+index d96375c..4a97099 100644
+--- a/ld/testsuite/ld-mips-elf/tlsdyn-o32-3.got
++++ b/ld/testsuite/ld-mips-elf/tlsdyn-o32-3.got
+@@ -13,6 +13,6 @@ OFFSET TYPE VALUE
+
+
+ Contents of section .got:
+- 10000020 00000000 80000000 004005ec 00000000 .*
++ 10000020 00000000 80000000 0040053c 00000000 .*
+ 10000030 00000000 00000000 00000000 00000000 .*
+ 10000040 00000000 00000001 00000000 .*
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0028-Revert-ld-Remove-unused-expression-state.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0028-Revert-ld-Remove-unused-expression-state.patch
new file mode 100644
index 00000000..c574470e
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0028-Revert-ld-Remove-unused-expression-state.patch
@@ -0,0 +1,97 @@
+From a9bcbddf77662f8c12e83360809a697196a55281 Mon Sep 17 00:00:00 2001
+From: Mahesh Bodapati <mbodapat@xilinx.com>
+Date: Wed, 27 Feb 2019 15:12:32 +0530
+Subject: [PATCH 28/31] Revert "ld: Remove unused expression state"
+
+This reverts commit 65f14869fd3fbee8ed4c4ca49de8aaa86dbc66cb.
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ ld/ChangeLog | 9 ---------
+ ld/ldexp.c | 8 +++++---
+ ld/ldexp.h | 1 +
+ 3 files changed, 6 insertions(+), 12 deletions(-)
+
+diff --git a/ld/ChangeLog b/ld/ChangeLog
+index 4827678..ce3d2d5 100644
+--- a/ld/ChangeLog
++++ b/ld/ChangeLog
+@@ -2972,15 +2972,6 @@
+
+ 2018-01-11 Andrew Burgess <andrew.burgess@embecosm.com>
+
+- * ldexp.h (union etree_union): Remove defsym field.
+- * ldexp.c (exp_assop): Remove defsym parameter, and use of defsym
+- parameter.
+- (exp_assign): Remove passing of defsym parameter.
+- (exp_defsym): Likewise.
+- (exp_provide): Likewise.
+-
+-2018-01-11 Andrew Burgess <andrew.burgess@embecosm.com>
+-
+ * ldexp.c (exp_fold_tree_1): Rework condition underwhich provide
+ nodes are ignored in the tree walk, and move the location at which
+ we change provide nodes into provided nodes.
+diff --git a/ld/ldexp.c b/ld/ldexp.c
+index d46a06f..a84bf63 100644
+--- a/ld/ldexp.c
++++ b/ld/ldexp.c
+@@ -1355,6 +1355,7 @@ static etree_type *
+ exp_assop (const char *dst,
+ etree_type *src,
+ enum node_tree_enum class,
++ bfd_boolean defsym,
+ bfd_boolean hidden)
+ {
+ etree_type *n;
+@@ -1366,6 +1367,7 @@ exp_assop (const char *dst,
+ n->assign.type.node_class = class;
+ n->assign.src = src;
+ n->assign.dst = dst;
++ n->assign.defsym = defsym;
+ n->assign.hidden = hidden;
+ return n;
+ }
+@@ -1375,7 +1377,7 @@ exp_assop (const char *dst,
+ etree_type *
+ exp_assign (const char *dst, etree_type *src, bfd_boolean hidden)
+ {
+- return exp_assop (dst, src, etree_assign, hidden);
++ return exp_assop (dst, src, etree_assign, FALSE, hidden);
+ }
+
+ /* Handle --defsym command-line option. */
+@@ -1383,7 +1385,7 @@ exp_assign (const char *dst, etree_type *src, bfd_boolean hidden)
+ etree_type *
+ exp_defsym (const char *dst, etree_type *src)
+ {
+- return exp_assop (dst, src, etree_assign, FALSE);
++ return exp_assop (dst, src, etree_assign, TRUE, FALSE);
+ }
+
+ /* Handle PROVIDE. */
+@@ -1391,7 +1393,7 @@ exp_defsym (const char *dst, etree_type *src)
+ etree_type *
+ exp_provide (const char *dst, etree_type *src, bfd_boolean hidden)
+ {
+- return exp_assop (dst, src, etree_provide, hidden);
++ return exp_assop (dst, src, etree_provide, FALSE, hidden);
+ }
+
+ /* Handle ASSERT. */
+diff --git a/ld/ldexp.h b/ld/ldexp.h
+index d58cacb..572b703 100644
+--- a/ld/ldexp.h
++++ b/ld/ldexp.h
+@@ -66,6 +66,7 @@ typedef union etree_union {
+ node_type type;
+ const char *dst;
+ union etree_union *src;
++ bfd_boolean defsym;
+ bfd_boolean hidden;
+ } assign;
+ struct {
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0029-Patch-Microblaze-Binutils-security-check-is-causing-.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0029-Patch-Microblaze-Binutils-security-check-is-causing-.patch
new file mode 100644
index 00000000..dd7bf088
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0029-Patch-Microblaze-Binutils-security-check-is-causing-.patch
@@ -0,0 +1,35 @@
+From e267384901f94566300114b91fa251de43f7ec34 Mon Sep 17 00:00:00 2001
+From: Mahesh Bodapati <mbodapat@xilinx.com>
+Date: Mon, 11 Mar 2019 14:23:58 +0530
+Subject: [PATCH 29/31] [Patch,Microblaze] : Binutils security check is causing
+ build error for windows builds.commenting for now.
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elf-attrs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c
+index 5c1b960..5285db2 100644
+--- a/bfd/elf-attrs.c
++++ b/bfd/elf-attrs.c
+@@ -440,6 +440,7 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
+ /* PR 17512: file: 2844a11d. */
+ if (hdr->sh_size == 0)
+ return;
++ #if 0
+ if (hdr->sh_size > bfd_get_file_size (abfd))
+ {
+ /* xgettext:c-format */
+@@ -448,6 +449,7 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
+ bfd_set_error (bfd_error_invalid_operation);
+ return;
+ }
++ #endif
+
+ contents = (bfd_byte *) bfd_malloc (hdr->sh_size + 1);
+ if (!contents)
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0030-fixing-the-long-long-long-mingw-toolchain-issue.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0030-fixing-the-long-long-long-mingw-toolchain-issue.patch
new file mode 100644
index 00000000..fea12b0b
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0030-fixing-the-long-long-long-mingw-toolchain-issue.patch
@@ -0,0 +1,59 @@
+From 0e918ef176cf14073abca83c61d3978f3fa2551e Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Thu, 29 Nov 2018 17:59:25 +0530
+Subject: [PATCH 30/31] fixing the long & long long mingw toolchain issue
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ gas/config/tc-microblaze.c | 10 +++++-----
+ opcodes/microblaze-opc.h | 4 ++--
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index edc7985..9db9a7f 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -783,7 +783,7 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
+ }
+
+ static char *
+-parse_imml (char * s, expressionS * e, long min, long max)
++parse_imml (char * s, expressionS * e, long long min, long long max)
+ {
+ char *new_pointer;
+ char *atp;
+@@ -834,11 +834,11 @@ parse_imml (char * s, expressionS * e, long min, long max)
+ ; /* An error message has already been emitted. */
+ else if ((e->X_op != O_constant && e->X_op != O_symbol) )
+ as_fatal (_("operand must be a constant or a label"));
+- else if ((e->X_op == O_constant) && ((long) e->X_add_number < min
+- || (long) e->X_add_number > max))
++ else if ((e->X_op == O_constant) && ((long long) e->X_add_number < min
++ || (long long) e->X_add_number > max))
+ {
+- as_fatal (_("operand must be absolute in range %ld..%ld, not %ld"),
+- min, max, (long) e->X_add_number);
++ as_fatal (_("operand must be absolute in range %lld..%lld, not %lld"),
++ min, max, (long long) e->X_add_number);
+ }
+
+ if (atp)
+diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
+index 2096269..7df80d4 100644
+--- a/opcodes/microblaze-opc.h
++++ b/opcodes/microblaze-opc.h
+@@ -585,8 +585,8 @@ char pvr_register_prefix[] = "rpvr";
+ #define MIN_IMM6_WIDTH ((int) 0x00000001)
+ #define MAX_IMM6_WIDTH ((int) 0x00000040)
+
+-#define MIN_IMML ((long) 0xffffff8000000000L)
+-#define MAX_IMML ((long) 0x0000007fffffffffL)
++#define MIN_IMML ((long long) 0xffffff8000000000L)
++#define MAX_IMML ((long long) 0x0000007fffffffffL)
+
+ #endif /* MICROBLAZE_OPC */
+
+--
+2.7.4
+
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0031-fixing-the-_STACK_SIZE-issue-with-the-flto-flag.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0031-fixing-the-_STACK_SIZE-issue-with-the-flto-flag.patch
new file mode 100644
index 00000000..d47b59a9
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0031-fixing-the-_STACK_SIZE-issue-with-the-flto-flag.patch
@@ -0,0 +1,57 @@
+From 8c08e0dfcfcb6c56576b68f235b0006c4c67fafb Mon Sep 17 00:00:00 2001
+From: Nagaraju <nmekala@xilinx.com>
+Date: Wed, 20 Mar 2019 11:42:07 +0530
+Subject: [PATCH 31/31] fixing the _STACK_SIZE issue with the flto flag
+
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ ld/scripttempl/elfmicroblaze.sc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/ld/scripttempl/elfmicroblaze.sc b/ld/scripttempl/elfmicroblaze.sc
+index d8f7569..1316901 100644
+--- a/ld/scripttempl/elfmicroblaze.sc
++++ b/ld/scripttempl/elfmicroblaze.sc
+@@ -63,9 +63,9 @@ ${RELOCATING+${LIB_SEARCH_DIRS}}
+
+ ${RELOCATING+ENTRY (${ENTRY})}
+
+-_TEXT_START_ADDR = DEFINED(_TEXT_START_ADDR) ? _TEXT_START_ADDR : 0x50;
+-_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x0;
+-_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
++_DEF_TEXT_START_ADDR = DEFINED(_TEXT_START_ADDR) ? _TEXT_START_ADDR : 0x50;
++_DEF_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x0;
++_DEF_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
+
+ SECTIONS
+ {
+@@ -75,7 +75,7 @@ SECTIONS
+ .vectors.debug_sw_break 0x18 : { KEEP (*(.vectors.debug_sw_break)) } = 0
+ .vectors.hw_exception 0x20 : { KEEP (*(.vectors.hw_exception)) } = 0
+
+- ${RELOCATING+. = _TEXT_START_ADDR;}
++ ${RELOCATING+. = _DEF_TEXT_START_ADDR;}
+
+ ${RELOCATING+ _ftext = .;}
+ .text : {
+@@ -208,7 +208,7 @@ SECTIONS
+ .heap : {
+ ${RELOCATING+ _heap = .;}
+ ${RELOCATING+ _heap_start = .;}
+- ${RELOCATING+ . += _HEAP_SIZE;}
++ ${RELOCATING+ . += _DEF_HEAP_SIZE;}
+ ${RELOCATING+ _heap_end = .;}
+ }
+
+@@ -216,7 +216,7 @@ SECTIONS
+
+ .stack : {
+ ${RELOCATING+ _stack_end = .;}
+- ${RELOCATING+ . += _STACK_SIZE;}
++ ${RELOCATING+ . += _DEF_STACK_SIZE;}
+ ${RELOCATING+ . = ALIGN(. != 0 ? 8 : 1);}
+ ${RELOCATING+ _stack = .;}
+ ${RELOCATING+ _end = .;}
+--
+2.7.4
+