summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Hatle <mark.hatle@amd.com>2024-07-23 15:43:00 -0600
committerMark Hatle <mark.hatle@amd.com>2024-07-24 11:52:53 -0600
commitc5b5967008a48fcf4e988189db0830db7bfc00c6 (patch)
tree1da50fc507b8907e8d3997a18f394c51f70df1e5
parent50801e15753588919571def325fc054595acbb85 (diff)
downloadmeta-xilinx-c5b5967008a48fcf4e988189db0830db7bfc00c6.tar.gz
meta-microblaze: binutils: Add local patches, including 64-bit support
Signed-off-by: Mark Hatle <mark.hatle@amd.com>
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc59
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0001-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch42
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0002-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch639
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0003-Initial-port-of-core-reading-support-Added-support-f.patch301
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0004-Fix-debug-message-when-register-is-unavailable.patch45
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0005-MicroBlaze-native-gdb-port.patch834
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0006-Adding-64-bit-MB-support-Added-new-architecture-to-M.patch1841
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0007-these-changes-will-make-64-bit-vectors-as-default-ta.patch35
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0008-Added-m64-abi-for-64-bit-target-descriptions.-set-m6.patch4104
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0009-Depth-Total-number-of-inline-functions-refer-inline-.patch74
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0010-Fix-gdb-14-build-errors-for-microblaze-xilinx-elf-20.patch133
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0011-fix-gdb-microblaze-xilinx-elf-crash-issue-on-invocat.patch28
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0012-Add-mlittle-endian-and-mbig-endian-flags.patch46
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0013-Disable-the-warning-message-for-eh_frame_hdr.patch35
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0014-Fix-relaxation-of-assembler-resolved-references-Fixu.patch48
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0015-upstream-change-to-garbage-collection-sweep-causes-m.patch43
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0016-Add-new-bit-field-instructions.patch219
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0017-fixed-bug-in-GCC-so-that-It-will-support-.long-0U-an.patch34
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0018-Compiler-will-give-error-messages-in-more-detail-for.patch37
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0019-initial-support-for-MicroBlaze-64-bit-m64.patch202
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0020-initial-support-for-MicroBlaze-64-bit-m64.patch82
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0021-Added-relocations-for-MB-X.patch108
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0022-initial-support-for-MicroBlaze-64-bit-m64.patch958
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0023-Added-relocations-for-MB-X.patch246
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0024-Fixed-MB-x-relocation-issues-Added-imml-for-required.patch52
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0025-Fixed-address-computation-issues-with-64bit-address-.patch160
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0026-Patch-MicroBlaze-Adding-new-relocation-to-support-64.patch110
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0027-Revert-ld-Remove-unused-expression-state-defsym-symb.patch84
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0028-fixing-the-long-long-long-mingw-toolchain-issue.patch58
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0029-Added-support-to-new-arithmetic-single-register-inst.patch371
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0030-double-imml-generation-for-64-bit-values.patch545
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0031-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch88
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0032-This-patch-will-remove-imml-0-and-imml-1-instruction.patch38
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0033-Changing-the-long-to-long-long-as-in-Windows-long-is.patch32
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0034-gas-revert-moving-of-md_pseudo_table-from-const.patch62
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0035-ld-emulparams-elf64microblaze-Fix-emulation-generati.patch44
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0036-Invalid-data-offsets-pointer-after-relaxation.-Propo.patch79
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0037-Double-free-with-ld-no-keep-memory.-Proposed-patches.patch107
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0038-MB-binutils-Upstream-port-issues.patch99
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0039-Initial-port-of-core-reading-support-Added-support-f.patch89
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0040-Fix-build-issues-after-Xilinx-2023.2-binutils-merge.patch185
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0041-disable-truncated-register-warning-gdb-remote.c.patch26
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0042-Fix-unresolved-conflicts-from-binutils_2_42_merge.patch42
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0043-microblaze_gdbarch_init-set-microblaze_abi-based-on-.patch177
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0044-Start-bfd_mach_microblaze-values-from-0-0-1-instead-.patch32
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0045-Fix-build-issues-bfd-reloc.c-add-missing-relocs-used.patch61
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0046-Regenerate-bfd-bfd-in2.h-bfd-libbfd.h.patch116
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0047-gdb-remote.c-revert-earlier-change-to-process_g_pack.patch32
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0048-Fix-build-issues-after-Xilinx-2023.2-binutils-patch-.patch465
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0049-When-unwinding-pc-value-adjust-return-pc-value.patch92
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0050-info-reg-pc-does-not-print-symbolic-value.patch116
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0051-Wrong-target-description-accepted-by-microblaze-arch.patch51
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0052-Merge-gdb-microblaze-linux-tdep.c-to-gdb-14-and-fix-.patch42
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0053-Roll-back-an-improvement-which-inlines-target_gdbarc.patch29
-rw-r--r--meta-vitis-tc/conf/machine/microblaze-tc.conf32
55 files changed, 13693 insertions, 16 deletions
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc b/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc
index 3701d245..014729a5 100644
--- a/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc
+++ b/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc
@@ -2,3 +2,62 @@ FILESEXTRAPATHS:append := ":${THISDIR}/binutils"
2 2
3LDGOLD_ALTS:microblaze = "" 3LDGOLD_ALTS:microblaze = ""
4USE_ALTERNATIVES_FOR:remove:microblaze = "gprof" 4USE_ALTERNATIVES_FOR:remove:microblaze = "gprof"
5
6# Our changes are all local, no real patch-status
7ERROR_QA:remove = "patch-status"
8
9SRC_URI += " \
10 file://0001-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch \
11 file://0002-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch \
12 file://0003-Initial-port-of-core-reading-support-Added-support-f.patch \
13 file://0004-Fix-debug-message-when-register-is-unavailable.patch \
14 file://0005-MicroBlaze-native-gdb-port.patch \
15 file://0006-Adding-64-bit-MB-support-Added-new-architecture-to-M.patch \
16 file://0007-these-changes-will-make-64-bit-vectors-as-default-ta.patch \
17 file://0008-Added-m64-abi-for-64-bit-target-descriptions.-set-m6.patch \
18 file://0009-Depth-Total-number-of-inline-functions-refer-inline-.patch \
19 file://0010-Fix-gdb-14-build-errors-for-microblaze-xilinx-elf-20.patch \
20 file://0011-fix-gdb-microblaze-xilinx-elf-crash-issue-on-invocat.patch \
21 file://0012-Add-mlittle-endian-and-mbig-endian-flags.patch \
22 file://0013-Disable-the-warning-message-for-eh_frame_hdr.patch \
23 file://0014-Fix-relaxation-of-assembler-resolved-references-Fixu.patch \
24 file://0015-upstream-change-to-garbage-collection-sweep-causes-m.patch \
25 file://0016-Add-new-bit-field-instructions.patch \
26 file://0017-fixed-bug-in-GCC-so-that-It-will-support-.long-0U-an.patch \
27 file://0018-Compiler-will-give-error-messages-in-more-detail-for.patch \
28 file://0019-initial-support-for-MicroBlaze-64-bit-m64.patch \
29 file://0020-initial-support-for-MicroBlaze-64-bit-m64.patch \
30 file://0021-Added-relocations-for-MB-X.patch \
31 file://0022-initial-support-for-MicroBlaze-64-bit-m64.patch \
32 file://0023-Added-relocations-for-MB-X.patch \
33 file://0024-Fixed-MB-x-relocation-issues-Added-imml-for-required.patch \
34 file://0025-Fixed-address-computation-issues-with-64bit-address-.patch \
35 file://0026-Patch-MicroBlaze-Adding-new-relocation-to-support-64.patch \
36 file://0027-Revert-ld-Remove-unused-expression-state-defsym-symb.patch \
37 file://0028-fixing-the-long-long-long-mingw-toolchain-issue.patch \
38 file://0029-Added-support-to-new-arithmetic-single-register-inst.patch \
39 file://0030-double-imml-generation-for-64-bit-values.patch \
40 file://0031-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch \
41 file://0032-This-patch-will-remove-imml-0-and-imml-1-instruction.patch \
42 file://0033-Changing-the-long-to-long-long-as-in-Windows-long-is.patch \
43 file://0034-gas-revert-moving-of-md_pseudo_table-from-const.patch \
44 file://0035-ld-emulparams-elf64microblaze-Fix-emulation-generati.patch \
45 file://0036-Invalid-data-offsets-pointer-after-relaxation.-Propo.patch \
46 file://0037-Double-free-with-ld-no-keep-memory.-Proposed-patches.patch \
47 file://0038-MB-binutils-Upstream-port-issues.patch \
48 file://0039-Initial-port-of-core-reading-support-Added-support-f.patch \
49 file://0040-Fix-build-issues-after-Xilinx-2023.2-binutils-merge.patch \
50 file://0041-disable-truncated-register-warning-gdb-remote.c.patch \
51 file://0042-Fix-unresolved-conflicts-from-binutils_2_42_merge.patch \
52 file://0043-microblaze_gdbarch_init-set-microblaze_abi-based-on-.patch \
53 file://0044-Start-bfd_mach_microblaze-values-from-0-0-1-instead-.patch \
54 file://0045-Fix-build-issues-bfd-reloc.c-add-missing-relocs-used.patch \
55 file://0046-Regenerate-bfd-bfd-in2.h-bfd-libbfd.h.patch \
56 file://0047-gdb-remote.c-revert-earlier-change-to-process_g_pack.patch \
57 file://0048-Fix-build-issues-after-Xilinx-2023.2-binutils-patch-.patch \
58 file://0049-When-unwinding-pc-value-adjust-return-pc-value.patch \
59 file://0050-info-reg-pc-does-not-print-symbolic-value.patch \
60 file://0051-Wrong-target-description-accepted-by-microblaze-arch.patch \
61 file://0052-Merge-gdb-microblaze-linux-tdep.c-to-gdb-14-and-fix-.patch \
62 file://0053-Roll-back-an-improvement-which-inlines-target_gdbarc.patch \
63"
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0001-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0001-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch
new file mode 100644
index 00000000..fd8a96c9
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0001-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch
@@ -0,0 +1,42 @@
1From add4545f804219232f16f96e3a83af2fadf41463 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 10 Oct 2022 15:07:22 +0530
4Subject: [PATCH 01/53] Add initial port of linux gdbserver add
5 gdb_proc_service_h to gdbserver microblaze-linux
6
7gdbserver needs to initialise the microblaze registers
8
9other archs use this step to run a *_arch_setup() to carry out all
10architecture specific setup - may need to add in future
11
12 * add linux-ptrace.o to gdbserver configure
13 * Update breakpoint opcode
14 * fix segfault on connecting gdbserver
15 * add microblaze_linux_memory_remove_breakpoint
16 * add set_solib_svr4_fetch_link_map_offsets
17 * add set_gdbarch_fetch_tls_load_module_address
18 * Force reading of r0 as 0, prevent stores
19
20Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com>
21Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com>
22Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
23Signed-off-by: Aayush Misra <aayushm@amd.com>
24---
25 gdbserver/Makefile.in | 1 +
26 1 file changed, 1 insertion(+)
27
28diff --git a/gdbserver/Makefile.in b/gdbserver/Makefile.in
29index d12f8746611..ee606908bae 100644
30--- a/gdbserver/Makefile.in
31+++ b/gdbserver/Makefile.in
32@@ -180,6 +180,7 @@ SFILES = \
33 $(srcdir)/linux-loongarch-low.cc \
34 $(srcdir)/linux-low.cc \
35 $(srcdir)/linux-m68k-low.cc \
36+ $(srcdir)/linux-microblaze-low.cc \
37 $(srcdir)/linux-mips-low.cc \
38 $(srcdir)/linux-nios2-low.cc \
39 $(srcdir)/linux-or1k-low.cc \
40--
412.34.1
42
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0002-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0002-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch
new file mode 100644
index 00000000..ea6689fe
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0002-Add-initial-port-of-linux-gdbserver-add-gdb_proc_ser.patch
@@ -0,0 +1,639 @@
1From aebe2fdb45467fe4a07874cc310e441a38c23f84 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 10 Oct 2022 15:07:22 +0530
4Subject: [PATCH 02/53] Add initial port of linux gdbserver add
5 gdb_proc_service_h to gdbserver microblaze-linux
6
7gdbserver needs to initialise the microblaze registers
8
9other archs use this step to run a *_arch_setup() to carry out all
10architecture specific setup - may need to add in future
11
12 * add linux-ptrace.o to gdbserver configure
13 * Update breakpoint opcode
14 * fix segfault on connecting gdbserver
15 * add microblaze_linux_memory_remove_breakpoint
16 * add set_solib_svr4_fetch_link_map_offsets
17 * add set_gdbarch_fetch_tls_load_module_address
18 * Force reading of r0 as 0, prevent stores
19
20Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com>
21Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com>
22Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
23Signed-off-by: Aayush Misra <aayushm@amd.com>
24---
25 gdb/configure.host | 2 +
26 gdb/features/Makefile | 1 +
27 gdb/features/microblaze-linux.xml | 13 ++
28 gdb/microblaze-linux-tdep.c | 29 ++-
29 gdb/microblaze-tdep.c | 35 +++-
30 gdb/microblaze-tdep.h | 4 +-
31 gdb/regformats/microblaze-linux.dat | 64 +++++++
32 gdb/regformats/reg-microblaze.dat | 41 +++++
33 gdbserver/configure.srv | 10 ++
34 gdbserver/linux-microblaze-low.cc | 269 ++++++++++++++++++++++++++++
35 10 files changed, 465 insertions(+), 3 deletions(-)
36 create mode 100644 gdb/features/microblaze-linux.xml
37 create mode 100644 gdb/regformats/microblaze-linux.dat
38 create mode 100644 gdb/regformats/reg-microblaze.dat
39 create mode 100644 gdbserver/linux-microblaze-low.cc
40
41diff --git a/gdb/configure.host b/gdb/configure.host
42index da71675b201..877537d06ef 100644
43--- a/gdb/configure.host
44+++ b/gdb/configure.host
45@@ -61,6 +61,7 @@ i[34567]86*) gdb_host_cpu=i386 ;;
46 loongarch*) gdb_host_cpu=loongarch ;;
47 m68*) gdb_host_cpu=m68k ;;
48 mips*) gdb_host_cpu=mips ;;
49+microblaze*) gdb_host_cpu=microblaze ;;
50 powerpc* | rs6000) gdb_host_cpu=powerpc ;;
51 sparcv9 | sparc64) gdb_host_cpu=sparc ;;
52 s390*) gdb_host_cpu=s390 ;;
53@@ -127,6 +128,7 @@ m68*-*-openbsd*) gdb_host=obsd ;;
54
55 m88*-*-openbsd*) gdb_host=obsd ;;
56
57+microblaze*-*linux*) gdb_host=linux ;;
58 mips*-*-linux*) gdb_host=linux ;;
59 mips*-*-netbsdaout* | mips*-*-knetbsd*-gnu)
60 gdb_host=nbsd ;;
61diff --git a/gdb/features/Makefile b/gdb/features/Makefile
62index cda6a49d563..8ac30d8cea3 100644
63--- a/gdb/features/Makefile
64+++ b/gdb/features/Makefile
65@@ -46,6 +46,7 @@
66 # List of .dat files to create in ../regformats/
67 WHICH = mips-linux mips-dsp-linux \
68 mips64-linux mips64-dsp-linux \
69+ microblaze-linux \
70 nios2-linux \
71 or1k-linux \
72 rs6000/powerpc-32 \
73diff --git a/gdb/features/microblaze-linux.xml b/gdb/features/microblaze-linux.xml
74new file mode 100644
75index 00000000000..688a3f83d1e
76--- /dev/null
77+++ b/gdb/features/microblaze-linux.xml
78@@ -0,0 +1,13 @@
79+<?xml version="1.0"?>
80+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
81+
82+ Copying and distribution of this file, with or without modification,
83+ are permitted in any medium without royalty provided the copyright
84+ notice and this notice are preserved. -->
85+
86+<!DOCTYPE target SYSTEM "gdb-target.dtd">
87+<target>
88+ <architecture>microblaze</architecture>
89+ <osabi>GNU/Linux</osabi>
90+ <xi:include href="microblaze-core.xml"/>
91+</target>
92diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
93index 7d620a3688b..d25100ef867 100644
94--- a/gdb/microblaze-linux-tdep.c
95+++ b/gdb/microblaze-linux-tdep.c
96@@ -37,6 +37,22 @@
97 #include "tramp-frame.h"
98 #include "linux-tdep.h"
99
100+static int microblaze_debug_flag = 0;
101+
102+static void
103+microblaze_debug (const char *fmt, ...)
104+{
105+ if (microblaze_debug_flag)
106+ {
107+ va_list args;
108+
109+ va_start (args, fmt);
110+ printf_unfiltered ("MICROBLAZE LINUX: ");
111+ vprintf_unfiltered (fmt, args);
112+ va_end (args);
113+ }
114+}
115+
116 static int
117 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
118 struct bp_target_info *bp_tgt)
119@@ -50,13 +66,20 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
120 /* Determine appropriate breakpoint contents and size for this address. */
121 bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
122
123+ /* Make sure we see the memory breakpoints. */
124+ scoped_restore restore_memory
125+ = make_scoped_restore_show_memory_breakpoints (1);
126+
127 val = target_read_memory (addr, old_contents, bplen);
128
129 /* If our breakpoint is no longer at the address, this means that the
130 program modified the code on us, so it is wrong to put back the
131 old value. */
132 if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
133- val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
134+ {
135+ val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
136+ microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
137+ }
138
139 return val;
140 }
141@@ -129,6 +152,10 @@ microblaze_linux_init_abi (struct gdbarch_info info,
142 /* Trampolines. */
143 tramp_frame_prepend_unwinder (gdbarch,
144 &microblaze_linux_sighandler_tramp_frame);
145+
146+ /* Enable TLS support. */
147+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
148+ svr4_fetch_objfile_link_map);
149 }
150
151 void _initialize_microblaze_linux_tdep ();
152diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
153index fc83634d1e6..3ff7ec644b6 100644
154--- a/gdb/microblaze-tdep.c
155+++ b/gdb/microblaze-tdep.c
156@@ -128,7 +128,38 @@ microblaze_fetch_instruction (CORE_ADDR pc)
157 constexpr gdb_byte microblaze_break_insn[] = MICROBLAZE_BREAKPOINT;
158
159 typedef BP_MANIPULATION (microblaze_break_insn) microblaze_breakpoint;
160-
161+static int
162+microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
163+ struct bp_target_info *bp_tgt)
164+{
165+ CORE_ADDR addr = bp_tgt->placed_address;
166+ const unsigned char *bp;
167+ int val;
168+ int bplen;
169+ gdb_byte old_contents[BREAKPOINT_MAX];
170+
171+ /* Determine appropriate breakpoint contents and size for this address. */
172+ bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
173+ if (bp == NULL)
174+ error (_("Software breakpoints not implemented for this target."));
175+
176+ /* Make sure we see the memory breakpoints. */
177+ scoped_restore restore_memory
178+ = make_scoped_restore_show_memory_breakpoints (1);
179+
180+ val = target_read_memory (addr, old_contents, bplen);
181+
182+ /* If our breakpoint is no longer at the address, this means that the
183+ program modified the code on us, so it is wrong to put back the
184+ old value. */
185+ if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
186+ {
187+ val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
188+ microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
189+ }
190+
191+ return val;
192+}
193
194 /* Allocate and initialize a frame cache. */
195
196@@ -714,6 +745,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
197 microblaze_breakpoint::kind_from_pc);
198 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
199 microblaze_breakpoint::bp_from_kind);
200+ set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
201
202 set_gdbarch_frame_args_skip (gdbarch, 8);
203
204@@ -754,4 +786,5 @@ When non-zero, microblaze specific debugging is enabled."),
205 NULL,
206 &setdebuglist, &showdebuglist);
207
208+
209 }
210diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
211index 0b4a5a3f472..56736b9b0c9 100644
212--- a/gdb/microblaze-tdep.h
213+++ b/gdb/microblaze-tdep.h
214@@ -118,6 +118,8 @@ struct microblaze_frame_cache
215
216 /* MICROBLAZE_BREAKPOINT defines the breakpoint that should be used.
217 Only used for native debugging. */
218-#define MICROBLAZE_BREAKPOINT {0xb9, 0xcc, 0x00, 0x60}
219+#define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18}
220+#define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba}
221+
222
223 #endif /* microblaze-tdep.h */
224diff --git a/gdb/regformats/microblaze-linux.dat b/gdb/regformats/microblaze-linux.dat
225new file mode 100644
226index 00000000000..b5b49f485cd
227--- /dev/null
228+++ b/gdb/regformats/microblaze-linux.dat
229@@ -0,0 +1,64 @@
230+# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
231+# Generated from: microblaze-linux.xml
232+name:microblaze_linux
233+xmltarget:microblaze-linux.xml
234+expedite:r1,rpc
235+32:r0
236+32:r1
237+32:r2
238+32:r3
239+32:r4
240+32:r5
241+32:r6
242+32:r7
243+32:r8
244+32:r9
245+32:r10
246+32:r11
247+32:r12
248+32:r13
249+32:r14
250+32:r15
251+32:r16
252+32:r17
253+32:r18
254+32:r19
255+32:r20
256+32:r21
257+32:r22
258+32:r23
259+32:r24
260+32:r25
261+32:r26
262+32:r27
263+32:r28
264+32:r29
265+32:r30
266+32:r31
267+32:rpc
268+32:rmsr
269+32:rear
270+32:resr
271+32:rfsr
272+32:rbtr
273+32:rpvr0
274+32:rpvr1
275+32:rpvr2
276+32:rpvr3
277+32:rpvr4
278+32:rpvr5
279+32:rpvr6
280+32:rpvr7
281+32:rpvr8
282+32:rpvr9
283+32:rpvr10
284+32:rpvr11
285+32:redr
286+32:rpid
287+32:rzpr
288+32:rtlbx
289+32:rtlbsx
290+32:rtlblo
291+32:rtlbhi
292+32:slr
293+32:shr
294diff --git a/gdb/regformats/reg-microblaze.dat b/gdb/regformats/reg-microblaze.dat
295new file mode 100644
296index 00000000000..bd8a4384424
297--- /dev/null
298+++ b/gdb/regformats/reg-microblaze.dat
299@@ -0,0 +1,41 @@
300+name:microblaze
301+expedite:r1,pc
302+32:r0
303+32:r1
304+32:r2
305+32:r3
306+32:r4
307+32:r5
308+32:r6
309+32:r7
310+32:r8
311+32:r9
312+32:r10
313+32:r11
314+32:r12
315+32:r13
316+32:r14
317+32:r15
318+32:r16
319+32:r17
320+32:r18
321+32:r19
322+32:r20
323+32:r21
324+32:r22
325+32:r23
326+32:r24
327+32:r25
328+32:r26
329+32:r27
330+32:r28
331+32:r29
332+32:r30
333+32:r31
334+32:pc
335+32:msr
336+32:ear
337+32:esr
338+32:fsr
339+32:slr
340+32:shr
341diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv
342index 9e861a75088..11ce617e72f 100644
343--- a/gdbserver/configure.srv
344+++ b/gdbserver/configure.srv
345@@ -159,6 +159,16 @@ case "${gdbserver_host}" in
346 srv_linux_regsets=yes
347 srv_linux_thread_db=yes
348 ;;
349+
350+microblaze*-*-linux*) srv_regobj="microblaze-linux.o"
351+ srv_tgtobj="$srv_linux_obj linux-microblaze-low.o"
352+ srv_xmlfiles="microblaze-linux.xml"
353+ srv_xmlfiles="${srv_xmlfiles} microblaze-core.xml"
354+ srv_linux_usrregs=yes
355+ srv_linux_regsets=yes
356+ srv_linux_thread_db=yes
357+ ;;
358+
359 mips*-*-linux*) srv_regobj="mips-linux.o"
360 srv_regobj="${srv_regobj} mips-dsp-linux.o"
361 srv_regobj="${srv_regobj} mips64-linux.o"
362diff --git a/gdbserver/linux-microblaze-low.cc b/gdbserver/linux-microblaze-low.cc
363new file mode 100644
364index 00000000000..bf9eecc41ab
365--- /dev/null
366+++ b/gdbserver/linux-microblaze-low.cc
367@@ -0,0 +1,269 @@
368+/* GNU/Linux/Microblaze specific low level interface, for the remote server for
369+ GDB.
370+ Copyright (C) 1995-2013 Free Software Foundation, Inc.
371+
372+ This file is part of GDB.
373+
374+ This program is free software; you can redistribute it and/or modify
375+ it under the terms of the GNU General Public License as published by
376+ the Free Software Foundation; either version 3 of the License, or
377+ (at your option) any later version.
378+
379+ This program is distributed in the hope that it will be useful,
380+ but WITHOUT ANY WARRANTY; without even the implied warranty of
381+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
382+ GNU General Public License for more details.
383+
384+ You should have received a copy of the GNU General Public License
385+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
386+
387+#include "server.h"
388+#include "linux-low.h"
389+
390+#include "elf/common.h"
391+#include "nat/gdb_ptrace.h"
392+#include <endian.h>
393+
394+#include <asm/ptrace.h>
395+#include <sys/procfs.h>
396+#include <sys/ptrace.h>
397+
398+#include "gdb_proc_service.h"
399+
400+
401+static int microblaze_regmap[] =
402+ {PT_GPR(0), PT_GPR(1), PT_GPR(2), PT_GPR(3),
403+ PT_GPR(4), PT_GPR(5), PT_GPR(6), PT_GPR(7),
404+ PT_GPR(8), PT_GPR(9), PT_GPR(10), PT_GPR(11),
405+ PT_GPR(12), PT_GPR(13), PT_GPR(14), PT_GPR(15),
406+ PT_GPR(16), PT_GPR(17), PT_GPR(18), PT_GPR(19),
407+ PT_GPR(20), PT_GPR(21), PT_GPR(22), PT_GPR(23),
408+ PT_GPR(24), PT_GPR(25), PT_GPR(26), PT_GPR(27),
409+ PT_GPR(28), PT_GPR(29), PT_GPR(30), PT_GPR(31),
410+ PT_PC, PT_MSR, PT_EAR, PT_ESR,
411+ PT_FSR
412+ };
413+
414+
415+
416+class microblaze_target : public linux_process_target
417+{
418+public:
419+
420+ const regs_info *get_regs_info () override;
421+
422+ const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
423+ // CORE_ADDR microblaze_reinsert_addr (regcache *regcache);
424+
425+protected:
426+
427+ void low_arch_setup () override;
428+
429+ bool low_cannot_fetch_register (int regno) override;
430+
431+ bool low_cannot_store_register (int regno) override;
432+
433+ // bool low_supports_breakpoints () override;
434+
435+ CORE_ADDR low_get_pc (regcache *regcache) override;
436+
437+ void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
438+
439+ bool low_breakpoint_at (CORE_ADDR pc) override;
440+};
441+
442+/* The singleton target ops object. */
443+
444+static microblaze_target the_microblaze_target;
445+
446+#define microblaze_num_regs (sizeof (microblaze_regmap) / sizeof (microblaze_regmap[0]))
447+
448+/* Defined in auto-generated file microblaze-linux.c. */
449+void init_registers_microblaze_linux (void);
450+extern const struct target_desc *tdesc_microblaze_linux;
451+
452+bool
453+microblaze_target::low_cannot_store_register (int regno)
454+{
455+ if (microblaze_regmap[regno] == -1 || regno == 0)
456+ return 1;
457+
458+ return 0;
459+}
460+
461+bool
462+microblaze_target::low_cannot_fetch_register (int regno)
463+{
464+ return 0;
465+}
466+
467+CORE_ADDR
468+microblaze_target::low_get_pc (struct regcache *regcache)
469+{
470+ unsigned long pc;
471+
472+ collect_register_by_name (regcache, "pc", &pc);
473+ return (CORE_ADDR) pc;
474+}
475+
476+void
477+microblaze_target::low_set_pc (struct regcache *regcache, CORE_ADDR pc)
478+{
479+ unsigned long newpc = pc;
480+
481+ supply_register_by_name (regcache, "pc", &newpc);
482+}
483+
484+/* dbtrap insn */
485+/* brki r16, 0x18; */
486+static const unsigned long microblaze_breakpoint = 0xba0c0018;
487+#define microblaze_breakpoint_len 4
488+
489+/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
490+
491+const gdb_byte *
492+microblaze_target::sw_breakpoint_from_kind (int kind, int *size)
493+{
494+ *size = microblaze_breakpoint_len;
495+ return (const gdb_byte *) &microblaze_breakpoint;
496+}
497+
498+bool
499+microblaze_target::low_breakpoint_at (CORE_ADDR where)
500+{
501+ unsigned long insn;
502+
503+ read_memory (where, (unsigned char *) &insn, 4);
504+ if (insn == microblaze_breakpoint)
505+ return 1;
506+ /* If necessary, recognize more trap instructions here. GDB only uses the
507+ one. */
508+ return 0;
509+}
510+#if 0
511+CORE_ADDR
512+microblaze_target::microblaze_reinsert_addr (struct regcache *regcache)
513+{
514+ unsigned long pc;
515+ collect_register_by_name (regcache, "r15", &pc);
516+ return pc;
517+}
518+#endif
519+#if 0
520+#ifdef HAVE_PTRACE_GETREGS
521+
522+static void
523+microblaze_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
524+{
525+ int size = register_size (regcache->tdesc, regno);
526+
527+ memset (buf, 0, sizeof (long));
528+
529+ if (size < sizeof (long))
530+ collect_register (regcache, regno, buf + sizeof (long) - size);
531+ else
532+ collect_register (regcache, regno, buf);
533+}
534+
535+static void
536+microblaze_supply_ptrace_register (struct regcache *regcache,
537+ int regno, const char *buf)
538+{
539+ int size = register_size (regcache->tdesc, regno);
540+
541+ if (regno == 0) {
542+ unsigned long regbuf_0 = 0;
543+ /* clobbering r0 so that it is always 0 as enforced by hardware */
544+ supply_register (regcache, regno, (const char*)&regbuf_0);
545+ } else {
546+ if (size < sizeof (long))
547+ supply_register (regcache, regno, buf + sizeof (long) - size);
548+ else
549+ supply_register (regcache, regno, buf);
550+ }
551+}
552+
553+/* Provide only a fill function for the general register set. ps_lgetregs
554+ will use this for NPTL support. */
555+
556+static void microblaze_fill_gregset (struct regcache *regcache, void *buf)
557+{
558+ int i;
559+
560+ for (i = 0; i < 32; i++)
561+ microblaze_collect_ptrace_register (regcache, i, (char *) buf + microblaze_regmap[i]);
562+}
563+
564+static void
565+microblaze_store_gregset (struct regcache *regcache, const void *buf)
566+{
567+ int i;
568+
569+ for (i = 0; i < 32; i++)
570+ supply_register (regcache, i, (char *) buf + microblaze_regmap[i]);
571+}
572+
573+#endif /* HAVE_PTRACE_GETREGS */
574+#endif
575+
576+static struct regset_info microblaze_regsets[] = {
577+#if 0
578+#ifdef HAVE_PTRACE_GETREGS
579+ { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, microblaze_fill_gregset, microblaze_store_gregset },
580+ { 0, 0, 0, -1, GENERAL_REGS, NULL, NULL },
581+#endif /* HAVE_PTRACE_GETREGS */
582+#endif
583+ { 0, 0, 0, -1, GENERAL_REGS, NULL, NULL },
584+ NULL_REGSET
585+};
586+
587+static struct usrregs_info microblaze_usrregs_info =
588+ {
589+ microblaze_num_regs,
590+ microblaze_regmap,
591+ };
592+
593+static struct regsets_info microblaze_regsets_info =
594+ {
595+ microblaze_regsets, /* regsets */
596+ 0, /* num_regsets */
597+ NULL, /* disabled_regsets */
598+ };
599+
600+static struct regs_info microblaze_regs_info =
601+ {
602+ NULL, /* regset_bitmap */
603+ &microblaze_usrregs_info,
604+ &microblaze_regsets_info
605+ };
606+
607+const regs_info *
608+microblaze_target::get_regs_info (void)
609+{
610+ return &microblaze_regs_info;
611+}
612+
613+/* Support for hardware single step. */
614+
615+static int
616+microblaze_supports_hardware_single_step (void)
617+{
618+ return 1;
619+}
620+
621+
622+void
623+microblaze_target::low_arch_setup (void)
624+{
625+ current_process ()->tdesc = tdesc_microblaze_linux;
626+}
627+
628+linux_process_target *the_linux_target = &the_microblaze_target;
629+
630+void
631+initialize_low_arch (void)
632+{
633+ init_registers_microblaze_linux ();
634+ initialize_regsets_info (&microblaze_regsets_info);
635+}
636+
637--
6382.34.1
639
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0003-Initial-port-of-core-reading-support-Added-support-f.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0003-Initial-port-of-core-reading-support-Added-support-f.patch
new file mode 100644
index 00000000..c0515aa6
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0003-Initial-port-of-core-reading-support-Added-support-f.patch
@@ -0,0 +1,301 @@
1From 67943e124abc6b1228d84399fbde5b129015ac7f Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 10 Oct 2022 16:37:53 +0530
4Subject: [PATCH 03/53] Initial port of core reading support Added support for
5 reading notes in linux core dumps Support for reading of PRSTATUS and PSINFO
6 information for rebuilding ".reg" sections of core dumps at run time.
7
8Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com>
9Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com>
10Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
11Signed-off-by: Aayush Misra <aayushm@amd.com>
12---
13 bfd/elf32-microblaze.c | 84 +++++++++++++++++++++++++++++++++++++
14 gdb/configure.tgt | 2 +-
15 gdb/microblaze-linux-tdep.c | 17 +++++++-
16 gdb/microblaze-tdep.c | 48 +++++++++++++++++++++
17 gdb/microblaze-tdep.h | 28 +++++++++++++
18 5 files changed, 177 insertions(+), 2 deletions(-)
19
20diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
21index 64198b8f1a6..022ce365c59 100644
22--- a/bfd/elf32-microblaze.c
23+++ b/bfd/elf32-microblaze.c
24@@ -772,6 +772,87 @@ microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
25 return _bfd_elf_is_local_label_name (abfd, name);
26 }
27
28+/* Support for core dump NOTE sections. */
29+static bool
30+microblaze_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
31+{
32+ int offset;
33+ unsigned int size;
34+
35+ switch (note->descsz)
36+ {
37+ default:
38+ return false;
39+
40+ case 228: /* Linux/MicroBlaze */
41+ /* pr_cursig */
42+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
43+
44+ /* pr_pid */
45+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
46+
47+ /* pr_reg */
48+ offset = 72;
49+ size = 50 * 4;
50+
51+ break;
52+ }
53+
54+ /* Make a ".reg/999" section. */
55+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
56+ size, note->descpos + offset);
57+}
58+
59+static bool
60+microblaze_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
61+{
62+ switch (note->descsz)
63+ {
64+ default:
65+ return false;
66+
67+ case 128: /* Linux/MicroBlaze elf_prpsinfo */
68+ elf_tdata (abfd)->core->program
69+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
70+ elf_tdata (abfd)->core->command
71+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
72+ }
73+
74+ /* Note that for some reason, a spurious space is tacked
75+ onto the end of the args in some (at least one anyway)
76+ implementations, so strip it off if it exists. */
77+
78+ {
79+ char *command = elf_tdata (abfd)->core->command;
80+ int n = strlen (command);
81+
82+ if (0 < n && command[n - 1] == ' ')
83+ command[n - 1] = '\0';
84+ }
85+
86+ return true;
87+}
88+
89+/* The microblaze linker (like many others) needs to keep track of
90+ the number of relocs that it decides to copy as dynamic relocs in
91+ check_relocs for each symbol. This is so that it can later discard
92+ them if they are found to be unnecessary. We store the information
93+ in a field extending the regular ELF linker hash table. */
94+
95+struct elf32_mb_dyn_relocs
96+{
97+ struct elf32_mb_dyn_relocs *next;
98+
99+ /* The input section of the reloc. */
100+ asection *sec;
101+
102+ /* Total number of relocs copied for the input section. */
103+ bfd_size_type count;
104+
105+ /* Number of pc-relative relocs copied for the input section. */
106+ bfd_size_type pc_count;
107+};
108+
109 /* ELF linker hash entry. */
110
111 struct elf32_mb_link_hash_entry
112@@ -3500,4 +3581,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd,
113 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
114 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
115
116+#define elf_backend_grok_prstatus microblaze_elf_grok_prstatus
117+#define elf_backend_grok_psinfo microblaze_elf_grok_psinfo
118+
119 #include "elf32-target.h"
120diff --git a/gdb/configure.tgt b/gdb/configure.tgt
121index 47a674201f9..d0673abd2b8 100644
122--- a/gdb/configure.tgt
123+++ b/gdb/configure.tgt
124@@ -415,7 +415,7 @@ mep-*-*)
125
126 microblaze*-linux-*|microblaze*-*-linux*)
127 # Target: Xilinx MicroBlaze running Linux
128- gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o solib-svr4.o \
129+ gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o solib-svr4.o glibc-tdep.o \
130 symfile-mem.o linux-tdep.o"
131 ;;
132 microblaze*-*-*)
133diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
134index d25100ef867..eef09bacec0 100644
135--- a/gdb/microblaze-linux-tdep.c
136+++ b/gdb/microblaze-linux-tdep.c
137@@ -36,6 +36,7 @@
138 #include "frame-unwind.h"
139 #include "tramp-frame.h"
140 #include "linux-tdep.h"
141+#include "glibc-tdep.h"
142
143 static int microblaze_debug_flag = 0;
144
145@@ -135,11 +136,14 @@ static struct tramp_frame microblaze_linux_sighandler_tramp_frame =
146 microblaze_linux_sighandler_cache_init
147 };
148
149-
150 static void
151 microblaze_linux_init_abi (struct gdbarch_info info,
152 struct gdbarch *gdbarch)
153 {
154+ struct microblaze_gdbarch_tdep *tdep =(microblaze_gdbarch_tdep *) gdbarch_tdep (gdbarch);
155+
156+ tdep->sizeof_gregset = 200;
157+
158 linux_init_abi (info, gdbarch, 0);
159
160 set_gdbarch_memory_remove_breakpoint (gdbarch,
161@@ -153,6 +157,17 @@ microblaze_linux_init_abi (struct gdbarch_info info,
162 tramp_frame_prepend_unwinder (gdbarch,
163 &microblaze_linux_sighandler_tramp_frame);
164
165+ /* BFD target for core files. */
166+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
167+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze");
168+ else
169+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel");
170+
171+
172+ /* Shared library handling. */
173+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
174+ set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
175+
176 /* Enable TLS support. */
177 set_gdbarch_fetch_tls_load_module_address (gdbarch,
178 svr4_fetch_objfile_link_map);
179diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
180index 3ff7ec644b6..7c98331f8a9 100644
181--- a/gdb/microblaze-tdep.c
182+++ b/gdb/microblaze-tdep.c
183@@ -665,6 +665,43 @@ microblaze_register_g_packet_guesses (struct gdbarch *gdbarch)
184 tdesc_microblaze_with_stack_protect);
185 }
186
187+void
188+microblaze_supply_gregset (const struct regset *regset,
189+ struct regcache *regcache,
190+ int regnum, const void *gregs)
191+{
192+ const unsigned int *regs = (const unsigned int *)gregs;
193+ if (regnum >= 0)
194+ regcache->raw_supply (regnum, regs + regnum);
195+
196+ if (regnum == -1) {
197+ int i;
198+
199+ for (i = 0; i < 50; i++) {
200+ regcache->raw_supply (i, regs + i);
201+ }
202+ }
203+}
204+
205+
206+/* Return the appropriate register set for the core section identified
207+ by SECT_NAME and SECT_SIZE. */
208+
209+static void
210+microblaze_iterate_over_regset_sections (struct gdbarch *gdbarch,
211+ iterate_over_regset_sections_cb *cb,
212+ void *cb_data,
213+ const struct regcache *regcache)
214+{
215+ struct microblaze_gdbarch_tdep *tdep =(microblaze_gdbarch_tdep *) gdbarch_tdep (gdbarch);
216+
217+ cb(".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, tdep->gregset, NULL, cb_data);
218+
219+ cb(".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, tdep->fpregset, NULL, cb_data);
220+}
221+
222+
223+
224 static struct gdbarch *
225 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
226 {
227@@ -716,6 +753,10 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
228 gdbarch *gdbarch
229 = gdbarch_alloc (&info, gdbarch_tdep_up (new microblaze_gdbarch_tdep));
230
231+ tdep->gregset = NULL;
232+ tdep->sizeof_gregset = 0;
233+ tdep->fpregset = NULL;
234+ tdep->sizeof_fpregset = 0;
235 set_gdbarch_long_double_bit (gdbarch, 128);
236
237 set_gdbarch_num_regs (gdbarch, MICROBLAZE_NUM_REGS);
238@@ -764,6 +805,13 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
239 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
240 if (tdesc_data != NULL)
241 tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
242+ //frame_base_append_sniffer (gdbarch, microblaze_frame_sniffer);
243+
244+ /* If we have register sets, enable the generic core file support. */
245+ if (tdep->gregset) {
246+ set_gdbarch_iterate_over_regset_sections (gdbarch,
247+ microblaze_iterate_over_regset_sections);
248+ }
249
250 return gdbarch;
251 }
252diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
253index 56736b9b0c9..07a160a463c 100644
254--- a/gdb/microblaze-tdep.h
255+++ b/gdb/microblaze-tdep.h
256@@ -23,8 +23,23 @@
257 #include "gdbarch.h"
258
259 /* Microblaze architecture-specific information. */
260+struct microblaze_gregset
261+{
262+ microblaze_gregset() {}
263+ unsigned int gregs[32];
264+ unsigned int fpregs[32];
265+ unsigned int pregs[16];
266+};
267+
268 struct microblaze_gdbarch_tdep : gdbarch_tdep_base
269 {
270+ int dummy; // declare something.
271+
272+ /* Register sets. */
273+ struct regset *gregset;
274+ size_t sizeof_gregset;
275+ struct regset *fpregset;
276+ size_t sizeof_fpregset;
277 };
278
279 /* Register numbers. */
280@@ -121,5 +136,18 @@ struct microblaze_frame_cache
281 #define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18}
282 #define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba}
283
284+extern void microblaze_supply_gregset (const struct regset *regset,
285+ struct regcache *regcache,
286+ int regnum, const void *gregs);
287+extern void microblaze_collect_gregset (const struct regset *regset,
288+ const struct regcache *regcache,
289+ int regnum, void *gregs);
290+extern void microblaze_supply_fpregset (struct regcache *regcache,
291+ int regnum, const void *fpregs);
292+extern void microblaze_collect_fpregset (const struct regcache *regcache,
293+ int regnum, void *fpregs);
294+
295+extern const struct regset * microblaze_regset_from_core_section (struct gdbarch *gdbarch,
296+ const char *sect_name, size_t sect_size);
297
298 #endif /* microblaze-tdep.h */
299--
3002.34.1
301
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0004-Fix-debug-message-when-register-is-unavailable.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0004-Fix-debug-message-when-register-is-unavailable.patch
new file mode 100644
index 00000000..1383efd8
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0004-Fix-debug-message-when-register-is-unavailable.patch
@@ -0,0 +1,45 @@
1From 087f77ebdbdf5b9b5d199ba92b31c6503cb66b37 Mon Sep 17 00:00:00 2001
2From: Nathan Rossi <nathan.rossi@petalogix.com>
3Date: Tue, 8 May 2012 18:11:17 +1000
4Subject: [PATCH 04/53] Fix debug message when register is unavailable
5
6Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com>
7
8Conflicts:
9 gdb/frame.c
10Signed-off-by: Aayush Misra <aayushm@amd.com>
11---
12 gdb/frame.c | 14 +++++++++++---
13 1 file changed, 11 insertions(+), 3 deletions(-)
14
15diff --git a/gdb/frame.c b/gdb/frame.c
16index d95d63eb0f6..859e1a6553d 100644
17--- a/gdb/frame.c
18+++ b/gdb/frame.c
19@@ -1317,12 +1317,20 @@ frame_unwind_register_value (frame_info_ptr next_frame, int regnum)
20 else
21 {
22 int i;
23- gdb::array_view<const gdb_byte> buf = value->contents ();
24+
25+ const gdb_byte *buf = NULL;
26+ if (value_entirely_available(value)) {
27+ gdb::array_view<const gdb_byte> buf = value->contents ();
28+ }
29
30 gdb_printf (&debug_file, " bytes=");
31 gdb_printf (&debug_file, "[");
32- for (i = 0; i < register_size (gdbarch, regnum); i++)
33- gdb_printf (&debug_file, "%02x", buf[i]);
34+ if (buf != NULL) {
35+ for (i = 0; i < register_size (gdbarch, regnum); i++)
36+ gdb_printf (&debug_file, "%02x", buf[i]);
37+ } else {
38+ gdb_printf (&debug_file, "unavailable");
39+ }
40 gdb_printf (&debug_file, "]");
41 }
42 }
43--
442.34.1
45
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0005-MicroBlaze-native-gdb-port.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0005-MicroBlaze-native-gdb-port.patch
new file mode 100644
index 00000000..75c06b62
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0005-MicroBlaze-native-gdb-port.patch
@@ -0,0 +1,834 @@
1From 5b633480eb0b45dc15b6416c54535c54c062d23c Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 10 Oct 2022 18:53:46 +0530
4Subject: [PATCH 05/53] MicroBlaze native gdb port.
5
6signed-off-by : Mahesh Bodapati <mbodapat@amd.com>
7
8Signed-off-by: Aayush Misra <aayushm@amd.com>
9---
10 gdb/Makefile.in | 2 +
11 gdb/configure.nat | 4 +
12 gdb/features/microblaze-linux.c | 79 +++++++
13 gdb/microblaze-linux-nat.c | 366 ++++++++++++++++++++++++++++++++
14 gdb/microblaze-linux-tdep.c | 2 +
15 gdb/microblaze-linux-tdep.h | 24 +++
16 gdb/microblaze-tdep.c | 151 ++++++++++++-
17 gdb/microblaze-tdep.h | 15 +-
18 8 files changed, 629 insertions(+), 14 deletions(-)
19 create mode 100755 gdb/features/microblaze-linux.c
20 create mode 100755 gdb/microblaze-linux-nat.c
21 create mode 100644 gdb/microblaze-linux-tdep.h
22
23diff --git a/gdb/Makefile.in b/gdb/Makefile.in
24index 0e0f19c40c9..056588d88d0 100644
25--- a/gdb/Makefile.in
26+++ b/gdb/Makefile.in
27@@ -1409,6 +1409,7 @@ HFILES_NO_SRCDIR = \
28 memory-map.h \
29 memrange.h \
30 microblaze-tdep.h \
31+ microblaze-linux-tdep.h \
32 mips-linux-tdep.h \
33 mips-netbsd-tdep.h \
34 mips-tdep.h \
35@@ -1757,6 +1758,7 @@ ALLDEPFILES = \
36 m68k-linux-nat.c \
37 m68k-linux-tdep.c \
38 m68k-tdep.c \
39+ microblaze-linux-nat.c \
40 microblaze-linux-tdep.c \
41 microblaze-tdep.c \
42 mingw-hdep.c \
43diff --git a/gdb/configure.nat b/gdb/configure.nat
44index 8b98511cef7..c9f0fb25010 100644
45--- a/gdb/configure.nat
46+++ b/gdb/configure.nat
47@@ -274,6 +274,10 @@ case ${gdb_host} in
48 # Host: Motorola m68k running GNU/Linux.
49 NATDEPFILES="${NATDEPFILES} m68k-linux-nat.o"
50 ;;
51+ microblaze)
52+ # Host: Microblaze running GNU/Linux.
53+ NATDEPFILES="${NATDEPFILES} microblaze-linux-nat.o"
54+ ;;
55 mips)
56 # Host: Linux/MIPS
57 NATDEPFILES="${NATDEPFILES} linux-nat-trad.o \
58diff --git a/gdb/features/microblaze-linux.c b/gdb/features/microblaze-linux.c
59new file mode 100755
60index 00000000000..267e12f6d59
61--- /dev/null
62+++ b/gdb/features/microblaze-linux.c
63@@ -0,0 +1,79 @@
64+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
65+ Original: microblaze.xml */
66+
67+#include "defs.h"
68+#include "osabi.h"
69+#include "target-descriptions.h"
70+
71+struct target_desc *tdesc_microblaze_linux;
72+static void
73+initialize_tdesc_microblaze_linux (void)
74+{
75+ target_desc_up result = allocate_target_description ();
76+ struct tdesc_feature *feature;
77+ set_tdesc_architecture (result.get(), bfd_scan_arch ("microblaze"));
78+ set_tdesc_osabi (result.get(), osabi_from_tdesc_string ("GNU/Linux"));
79+
80+ feature = tdesc_create_feature (result.get(), "org.gnu.gdb.microblaze.core");
81+ tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
82+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
83+ tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
84+ tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
85+ tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
86+ tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "int");
87+ tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "int");
88+ tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "int");
89+ tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "int");
90+ tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "int");
91+ tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "int");
92+ tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "int");
93+ tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "int");
94+ tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "int");
95+ tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "int");
96+ tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "int");
97+ tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "int");
98+ tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "int");
99+ tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "int");
100+ tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "int");
101+ tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "int");
102+ tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "int");
103+ tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "int");
104+ tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "int");
105+ tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "int");
106+ tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "int");
107+ tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "int");
108+ tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "int");
109+ tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "int");
110+ tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "int");
111+ tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "int");
112+ tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "int");
113+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "int");
114+ tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
115+ tdesc_create_reg (feature, "rear", 34, 1, NULL, 32, "int");
116+ tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
117+ tdesc_create_reg (feature, "rfsr", 36, 1, NULL, 32, "int");
118+ tdesc_create_reg (feature, "rbtr", 37, 1, NULL, 32, "int");
119+ tdesc_create_reg (feature, "rpvr0", 38, 1, NULL, 32, "int");
120+ tdesc_create_reg (feature, "rpvr1", 39, 1, NULL, 32, "int");
121+ tdesc_create_reg (feature, "rpvr2", 40, 1, NULL, 32, "int");
122+ tdesc_create_reg (feature, "rpvr3", 41, 1, NULL, 32, "int");
123+ tdesc_create_reg (feature, "rpvr4", 42, 1, NULL, 32, "int");
124+ tdesc_create_reg (feature, "rpvr5", 43, 1, NULL, 32, "int");
125+ tdesc_create_reg (feature, "rpvr6", 44, 1, NULL, 32, "int");
126+ tdesc_create_reg (feature, "rpvr7", 45, 1, NULL, 32, "int");
127+ tdesc_create_reg (feature, "rpvr8", 46, 1, NULL, 32, "int");
128+ tdesc_create_reg (feature, "rpvr9", 47, 1, NULL, 32, "int");
129+ tdesc_create_reg (feature, "rpvr10", 48, 1, NULL, 32, "int");
130+ tdesc_create_reg (feature, "rpvr11", 49, 1, NULL, 32, "int");
131+ tdesc_create_reg (feature, "redr", 50, 1, NULL, 32, "int");
132+ tdesc_create_reg (feature, "rpid", 51, 1, NULL, 32, "int");
133+ tdesc_create_reg (feature, "rzpr", 52, 1, NULL, 32, "int");
134+ tdesc_create_reg (feature, "rtlbx", 53, 1, NULL, 32, "int");
135+ tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
136+ tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
137+ tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
138+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
139+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
140+
141+ tdesc_microblaze_linux = result.release();
142+}
143diff --git a/gdb/microblaze-linux-nat.c b/gdb/microblaze-linux-nat.c
144new file mode 100755
145index 00000000000..a348001a3e2
146--- /dev/null
147+++ b/gdb/microblaze-linux-nat.c
148@@ -0,0 +1,366 @@
149+/* Native-dependent code for GNU/Linux MicroBlaze.
150+ Copyright (C) 2021 Free Software Foundation, Inc.
151+
152+ This file is part of GDB.
153+
154+ This program is free software; you can redistribute it and/or modify
155+ it under the terms of the GNU General Public License as published by
156+ the Free Software Foundation; either version 3 of the License, or
157+ (at your option) any later version.
158+
159+ This program is distributed in the hope that it will be useful,
160+ but WITHOUT ANY WARRANTY; without even the implied warranty of
161+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
162+ GNU General Public License for more details.
163+
164+ You should have received a copy of the GNU General Public License
165+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
166+
167+#include "defs.h"
168+#include "arch-utils.h"
169+#include "dis-asm.h"
170+#include "frame.h"
171+#include "trad-frame.h"
172+#include "symtab.h"
173+#include "value.h"
174+#include "gdbcmd.h"
175+#include "breakpoint.h"
176+#include "inferior.h"
177+#include "gdbthread.h"
178+#include "gdbcore.h"
179+#include "regcache.h"
180+#include "regset.h"
181+#include "target.h"
182+#include "frame.h"
183+#include "frame-base.h"
184+#include "frame-unwind.h"
185+#include "osabi.h"
186+#include "gdbsupport/gdb_assert.h"
187+#include <string.h>
188+#include "target-descriptions.h"
189+#include "opcodes/microblaze-opcm.h"
190+#include "opcodes/microblaze-dis.h"
191+#include "gregset.h"
192+
193+#include "linux-nat.h"
194+#include "linux-tdep.h"
195+#include "target-descriptions.h"
196+
197+#include <sys/user.h>
198+#include <sys/ioctl.h>
199+#include <sys/uio.h>
200+#include "gdbsupport/gdb_wait.h"
201+#include <fcntl.h>
202+#include <sys/procfs.h>
203+#include "nat/gdb_ptrace.h"
204+#include "nat/linux-ptrace.h"
205+#include "inf-ptrace.h"
206+#include <algorithm>
207+#include <unordered_map>
208+#include <list>
209+#include <sys/ptrace.h>
210+
211+/* Prototypes for supply_gregset etc. */
212+#include "gregset.h"
213+
214+#include "microblaze-tdep.h"
215+#include "microblaze-linux-tdep.h"
216+#include "inferior.h"
217+
218+#include "elf/common.h"
219+
220+#include "auxv.h"
221+#include "linux-tdep.h"
222+
223+#include <sys/ptrace.h>
224+
225+
226+//int have_ptrace_getsetregs=1;
227+
228+/* MicroBlaze Linux native additions to the default linux support. */
229+
230+class microblaze_linux_nat_target final : public linux_nat_target
231+{
232+public:
233+ /* Add our register access methods. */
234+ void fetch_registers (struct regcache *regcache, int regnum) override;
235+ void store_registers (struct regcache *regcache, int regnum) override;
236+
237+ /* Read suitable target description. */
238+ const struct target_desc *read_description () override;
239+};
240+
241+static microblaze_linux_nat_target the_microblaze_linux_nat_target;
242+
243+static int
244+microblaze_register_u_addr (struct gdbarch *gdbarch, int regno)
245+{
246+ int u_addr = -1;
247+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
248+ /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
249+ * interface, and not the wordsize of the program's ABI. */
250+ int wordsize = sizeof (long);
251+
252+ /* General purpose registers occupy 1 slot each in the buffer. */
253+ if (regno >= MICROBLAZE_R0_REGNUM
254+ && regno <= MICROBLAZE_FSR_REGNUM)
255+ u_addr = ((regno - MICROBLAZE_R0_REGNUM)* wordsize);
256+
257+ return u_addr;
258+}
259+
260+/* Copy general purpose register REGNUM (or all gp regs if REGNUM == -1)
261+ from regset GREGS into REGCACHE. */
262+
263+static void
264+supply_gregset_regnum (struct regcache *regcache, const prgregset_t *gregs,
265+ int regnum)
266+{
267+ int i;
268+ const elf_greg_t *regp = *gregs;
269+ /* Access all registers */
270+ if (regnum == -1)
271+ {
272+ /* We fill the general purpose registers. */
273+ for (i = MICROBLAZE_R0_REGNUM + 1; i < MICROBLAZE_FSR_REGNUM; i++)
274+ regcache->raw_supply (i, regp + i);
275+
276+ /* Supply MICROBLAZE_PC_REGNUM from index 32. */
277+ regcache->raw_supply (MICROBLAZE_PC_REGNUM, regp + 32);
278+
279+ /* Fill the inaccessible zero register with zero. */
280+ regcache->raw_supply_zeroed (0);
281+ }
282+ else if (regnum == MICROBLAZE_R0_REGNUM)
283+ regcache->raw_supply_zeroed (0);
284+ else if (regnum == MICROBLAZE_PC_REGNUM)
285+ regcache->raw_supply (MICROBLAZE_PC_REGNUM, regp + 32);
286+ else if (regnum > MICROBLAZE_R0_REGNUM && regnum < MICROBLAZE_FSR_REGNUM)
287+ regcache->raw_supply (regnum, regp + regnum);
288+}
289+
290+/* Copy all general purpose registers from regset GREGS into REGCACHE. */
291+
292+void
293+supply_gregset (struct regcache *regcache, const prgregset_t *gregs)
294+{
295+ supply_gregset_regnum (regcache, gregs, -1);
296+}
297+
298+/* Copy general purpose register REGNUM (or all gp regs if REGNUM == -1)
299+ from REGCACHE into regset GREGS. */
300+
301+void
302+fill_gregset (const struct regcache *regcache, prgregset_t *gregs, int regnum)
303+{
304+ elf_greg_t *regp = *gregs;
305+ if (regnum == -1)
306+ {
307+ /* We fill the general purpose registers. */
308+ for (int i = MICROBLAZE_R0_REGNUM + 1; i < MICROBLAZE_FSR_REGNUM; i++)
309+ regcache->raw_collect (i, regp + i);
310+
311+ regcache->raw_collect (MICROBLAZE_PC_REGNUM, regp + 32);
312+ }
313+ else if (regnum == MICROBLAZE_R0_REGNUM)
314+ /* Nothing to do here. */
315+ ;
316+ else if (regnum > MICROBLAZE_R0_REGNUM && regnum < MICROBLAZE_FSR_REGNUM)
317+ regcache->raw_collect (regnum, regp + regnum);
318+ else if (regnum == MICROBLAZE_PC_REGNUM)
319+ regcache->raw_collect (MICROBLAZE_PC_REGNUM, regp + 32);
320+}
321+
322+/* Transfering floating-point registers between GDB, inferiors and cores.
323+ Since MicroBlaze floating-point registers are the same as GPRs these do
324+ nothing. */
325+
326+void
327+supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
328+{
329+}
330+
331+void
332+fill_fpregset (const struct regcache *regcache,
333+ gdb_fpregset_t *fpregs, int regno)
334+{
335+}
336+
337+
338+static void
339+fetch_register (struct regcache *regcache, int tid, int regno)
340+{
341+ struct gdbarch *gdbarch = regcache->arch ();
342+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
343+ /* This isn't really an address. But ptrace thinks of it as one. */
344+ CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
345+ int bytes_transferred;
346+ char buf[MICROBLAZE_MAX_REGISTER_SIZE];
347+
348+ if (regaddr == -1)
349+ {
350+ memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */
351+ regcache->raw_supply (regno, buf);
352+ return;
353+ }
354+
355+ /* Read the raw register using sizeof(long) sized chunks. On a
356+ * 32-bit platform, 64-bit floating-point registers will require two
357+ * transfers. */
358+ for (bytes_transferred = 0;
359+ bytes_transferred < register_size (gdbarch, regno);
360+ bytes_transferred += sizeof (long))
361+ {
362+ long l;
363+
364+ errno = 0;
365+ l = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0);
366+ if (errno == EIO)
367+ {
368+ printf("ptrace io error\n");
369+ }
370+ regaddr += sizeof (long);
371+ if (errno != 0)
372+ {
373+ char message[128];
374+ sprintf (message, "reading register %s (#%d)",
375+ gdbarch_register_name (gdbarch, regno), regno);
376+ perror_with_name (message);
377+ }
378+ memcpy (&buf[bytes_transferred], &l, sizeof (l));
379+ }
380+
381+ /* Now supply the register. Keep in mind that the regcache's idea
382+ * of the register's size may not be a multiple of sizeof
383+ * (long). */
384+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
385+ {
386+ /* Little-endian values are always found at the left end of the
387+ * bytes transferred. */
388+ regcache->raw_supply (regno, buf);
389+ }
390+ else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
391+ {
392+ /* Big-endian values are found at the right end of the bytes
393+ * transferred. */
394+ size_t padding = (bytes_transferred - register_size (gdbarch, regno));
395+ regcache->raw_supply (regno, buf + padding);
396+ }
397+ else
398+ internal_error (__FILE__, __LINE__,
399+ _("fetch_register: unexpected byte order: %d"),
400+ gdbarch_byte_order (gdbarch));
401+}
402+
403+
404+/* This is a wrapper for the fetch_all_gp_regs function. It is
405+ * responsible for verifying if this target has the ptrace request
406+ * that can be used to fetch all general-purpose registers at one
407+ * shot. If it doesn't, then we should fetch them using the
408+ * old-fashioned way, which is to iterate over the registers and
409+ * request them one by one. */
410+static void
411+fetch_gp_regs (struct regcache *regcache, int tid)
412+{
413+ int i;
414+/* If we've hit this point, it doesn't really matter which
415+ architecture we are using. We just need to read the
416+ registers in the "old-fashioned way". */
417+ for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++)
418+ fetch_register (regcache, tid, i);
419+}
420+
421+/* Return a target description for the current target. */
422+
423+const struct target_desc *
424+microblaze_linux_nat_target::read_description ()
425+{
426+ return tdesc_microblaze_linux;
427+}
428+
429+/* Fetch REGNUM (or all registers if REGNUM == -1) from the target
430+ into REGCACHE using PTRACE_GETREGSET. */
431+
432+void
433+microblaze_linux_nat_target::fetch_registers (struct regcache * regcache,
434+ int regno)
435+{
436+ /* Get the thread id for the ptrace call. */
437+ int tid = regcache->ptid ().lwp ();
438+//int tid = get_ptrace_pid (regcache->ptid());
439+#if 1
440+ if (regno == -1)
441+#endif
442+ fetch_gp_regs (regcache, tid);
443+#if 1
444+ else
445+ fetch_register (regcache, tid, regno);
446+#endif
447+}
448+
449+
450+/* Store REGNUM (or all registers if REGNUM == -1) to the target
451+ from REGCACHE using PTRACE_SETREGSET. */
452+
453+void
454+microblaze_linux_nat_target::store_registers (struct regcache *regcache, int regno)
455+{
456+ int tid;
457+
458+ tid = get_ptrace_pid (regcache->ptid ());
459+
460+ struct gdbarch *gdbarch = regcache->arch ();
461+ /* This isn't really an address. But ptrace thinks of it as one. */
462+ CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
463+ int i;
464+ size_t bytes_to_transfer;
465+ char buf[MICROBLAZE_MAX_REGISTER_SIZE];
466+
467+ if (regaddr == -1)
468+ return;
469+
470+ /* First collect the register. Keep in mind that the regcache's
471+ * idea of the register's size may not be a multiple of sizeof
472+ * (long). */
473+ memset (buf, 0, sizeof buf);
474+ bytes_to_transfer = align_up (register_size (gdbarch, regno), sizeof (long));
475+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
476+ {
477+ /* Little-endian values always sit at the left end of the buffer. */
478+ regcache->raw_collect (regno, buf);
479+ }
480+ else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
481+ {
482+ /* Big-endian values sit at the right end of the buffer. */
483+ size_t padding = (bytes_to_transfer - register_size (gdbarch, regno));
484+ regcache->raw_collect (regno, buf + padding);
485+ }
486+
487+ for (i = 0; i < bytes_to_transfer; i += sizeof (long))
488+ {
489+ long l;
490+
491+ memcpy (&l, &buf[i], sizeof (l));
492+ errno = 0;
493+ ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, l);
494+ regaddr += sizeof (long);
495+
496+ if (errno != 0)
497+ {
498+ char message[128];
499+ sprintf (message, "writing register %s (#%d)",
500+ gdbarch_register_name (gdbarch, regno), regno);
501+ perror_with_name (message);
502+ }
503+ }
504+}
505+
506+void _initialize_microblaze_linux_nat (void);
507+
508+void
509+_initialize_microblaze_linux_nat (void)
510+{
511+ /* Register the target. */
512+ linux_target = &the_microblaze_linux_nat_target;
513+ add_inf_child_target (linux_target);
514+}
515diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
516index eef09bacec0..d086debc4f8 100644
517--- a/gdb/microblaze-linux-tdep.c
518+++ b/gdb/microblaze-linux-tdep.c
519@@ -37,6 +37,7 @@
520 #include "tramp-frame.h"
521 #include "linux-tdep.h"
522 #include "glibc-tdep.h"
523+#include "features/microblaze-linux.c"
524
525 static int microblaze_debug_flag = 0;
526
527@@ -179,4 +180,5 @@ _initialize_microblaze_linux_tdep ()
528 {
529 gdbarch_register_osabi (bfd_arch_microblaze, 0, GDB_OSABI_LINUX,
530 microblaze_linux_init_abi);
531+ initialize_tdesc_microblaze_linux ();
532 }
533diff --git a/gdb/microblaze-linux-tdep.h b/gdb/microblaze-linux-tdep.h
534new file mode 100644
535index 00000000000..a2c744e2961
536--- /dev/null
537+++ b/gdb/microblaze-linux-tdep.h
538@@ -0,0 +1,24 @@
539+/* Target-dependent code for GNU/Linux on OpenRISC.
540+
541+ Copyright (C) 2021 Free Software Foundation, Inc.
542+
543+ This file is part of GDB.
544+
545+ This program is free software; you can redistribute it and/or modify
546+ it under the terms of the GNU General Public License as published by
547+ the Free Software Foundation; either version 3 of the License, or
548+ (at your option) any later version.
549+
550+ This program is distributed in the hope that it will be useful,
551+ but WITHOUT ANY WARRANTY; without even the implied warranty of
552+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
553+ GNU General Public License for more details.
554+
555+ You should have received a copy of the GNU General Public License
556+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
557+#ifndef MICROBLAZE_LINUX_TDEP_H
558+#define MICROBLAZE_LINUX_TDEP_H
559+ /* Target descriptions. */
560+ extern struct target_desc *tdesc_microblaze_linux;
561+
562+#endif /* MICROBLAZE_LINUX_TDEP_H */
563diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
564index 7c98331f8a9..b0b4c1b2614 100644
565--- a/gdb/microblaze-tdep.c
566+++ b/gdb/microblaze-tdep.c
567@@ -285,6 +285,7 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
568 cache->frameless_p = 0; /* Frame found. */
569 save_hidden_pointer_found = 0;
570 non_stack_instruction_found = 0;
571+ cache->register_offsets[rd] = -imm;
572 continue;
573 }
574 else if (IS_SPILL_SP(op, rd, ra))
575@@ -431,15 +432,17 @@ microblaze_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
576 if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
577 {
578 sal = find_pc_line (func_start, 0);
579-
580- if (sal.end < func_end
581- && start_pc <= sal.end)
582+
583+ if (sal.line !=0 && sal.end <= func_end && start_pc <= sal.end) {
584 start_pc = sal.end;
585+ microblaze_debug("start_pc is %d\t sal.end is %d\t func_end is %d\t",start_pc,sal.end,func_end);
586+ }
587 }
588
589 ostart_pc = microblaze_analyze_prologue (gdbarch, func_start, 0xffffffffUL,
590 &cache);
591
592+
593 if (ostart_pc > start_pc)
594 return ostart_pc;
595 return start_pc;
596@@ -453,6 +456,7 @@ microblaze_frame_cache (frame_info_ptr next_frame, void **this_cache)
597 struct microblaze_frame_cache *cache;
598 struct gdbarch *gdbarch = get_frame_arch (next_frame);
599 int rn;
600+ CORE_ADDR current_pc;
601
602 if (*this_cache)
603 return (struct microblaze_frame_cache *) *this_cache;
604@@ -466,10 +470,17 @@ microblaze_frame_cache (frame_info_ptr next_frame, void **this_cache)
605 cache->register_offsets[rn] = -1;
606
607 /* Call for side effects. */
608- get_frame_func (next_frame);
609-
610- cache->pc = get_frame_address_in_block (next_frame);
611-
612+ cache->pc = get_frame_func (next_frame);
613+
614+// cache->pc = get_frame_address_in_block (next_frame);
615+ current_pc = get_frame_pc (next_frame);
616+ if (cache->pc)
617+ microblaze_analyze_prologue (gdbarch, cache->pc, current_pc, cache);
618+
619+ cache->saved_sp = cache->base + cache->framesize;
620+ cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM] = cache->base;
621+ cache->register_offsets[MICROBLAZE_SP_REGNUM] = cache->saved_sp;
622+
623 return cache;
624 }
625
626@@ -494,6 +505,25 @@ microblaze_frame_prev_register (frame_info_ptr this_frame,
627 struct microblaze_frame_cache *cache =
628 microblaze_frame_cache (this_frame, this_cache);
629
630+if ((regnum == MICROBLAZE_SP_REGNUM &&
631+ cache->register_offsets[MICROBLAZE_SP_REGNUM])
632+ || (regnum == MICROBLAZE_FP_REGNUM &&
633+ cache->register_offsets[MICROBLAZE_SP_REGNUM]))
634+
635+ return frame_unwind_got_constant (this_frame, regnum,
636+ cache->register_offsets[MICROBLAZE_SP_REGNUM]);
637+
638+if (regnum == MICROBLAZE_PC_REGNUM)
639+{
640+ regnum = 15;
641+ return frame_unwind_got_memory (this_frame, regnum,
642+ cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM]);
643+
644+}
645+if (regnum == MICROBLAZE_SP_REGNUM)
646+ regnum = 1;
647+#if 0
648+
649 if (cache->frameless_p)
650 {
651 if (regnum == MICROBLAZE_PC_REGNUM)
652@@ -506,7 +536,9 @@ microblaze_frame_prev_register (frame_info_ptr this_frame,
653 else
654 return trad_frame_get_prev_register (this_frame, cache->saved_regs,
655 regnum);
656-
657+#endif
658+ return trad_frame_get_prev_register (this_frame, cache->saved_regs,
659+ regnum);
660 }
661
662 static const struct frame_unwind microblaze_frame_unwind =
663@@ -621,7 +653,106 @@ microblaze_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
664 return (type->length () == 16);
665 }
666
667-
668+#if 1
669+static std::vector<CORE_ADDR>
670+microblaze_software_single_step (struct regcache *regcache)
671+{
672+ struct gdbarch *arch = regcache->arch ();
673+ //struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
674+ static int le_breakp[] = MICROBLAZE_BREAKPOINT_LE;
675+ static int be_breakp[] = MICROBLAZE_BREAKPOINT;
676+ enum bfd_endian byte_order = gdbarch_byte_order (arch);
677+ int *breakp = byte_order == BFD_ENDIAN_BIG ? be_breakp : le_breakp;
678+// std::vector<CORE_ADDR> ret = NULL;
679+
680+ /* Save the address and the values of the next_pc and the target */
681+ static struct sstep_breaks
682+ {
683+ CORE_ADDR address;
684+ bfd_boolean valid;
685+ /* Shadow contents. */
686+ char data[INST_WORD_SIZE];
687+ } stepbreaks[2];
688+ int ii;
689+
690+ CORE_ADDR pc;
691+ std::vector<CORE_ADDR> next_pcs;
692+ long insn;
693+ enum microblaze_instr minstr;
694+ bfd_boolean isunsignednum;
695+ enum microblaze_instr_type insn_type;
696+ short delay_slots;
697+ int imm;
698+ bfd_boolean immfound = FALSE;
699+
700+ /* Set a breakpoint at the next instruction */
701+ /* If the current instruction is an imm, set it at the inst after */
702+ /* If the instruction has a delay slot, skip the delay slot */
703+ pc = regcache_read_pc (regcache);
704+ insn = microblaze_fetch_instruction (pc);
705+ minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
706+ if (insn_type == immediate_inst)
707+ {
708+ int rd, ra, rb;
709+ immfound = TRUE;
710+ minstr = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
711+ pc = pc + INST_WORD_SIZE;
712+ insn = microblaze_fetch_instruction (pc);
713+ minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
714+ }
715+ stepbreaks[0].address = pc + (delay_slots * INST_WORD_SIZE) + INST_WORD_SIZE;
716+ if (insn_type != return_inst) {
717+ stepbreaks[0].valid = TRUE;
718+ } else {
719+ stepbreaks[0].valid = FALSE;
720+ }
721+
722+ microblaze_debug ("single-step insn_type=%x insn=%x\n", insn_type, insn);
723+ /* Now check for branch or return instructions */
724+ if (insn_type == branch_inst || insn_type == return_inst) {
725+ int limm;
726+ int lrd, lra, lrb;
727+ int ra, rb;
728+ bfd_boolean targetvalid;
729+ bfd_boolean unconditionalbranch;
730+ microblaze_decode_insn(insn, &lrd, &lra, &lrb, &limm);
731+ if (lra >= 0 && lra < MICROBLAZE_NUM_REGS)
732+ ra = regcache_raw_get_unsigned(regcache, lra);
733+ else
734+ ra = 0;
735+ if (lrb >= 0 && lrb < MICROBLAZE_NUM_REGS)
736+ rb = regcache_raw_get_unsigned(regcache, lrb);
737+ else
738+ rb = 0;
739+ stepbreaks[1].address = microblaze_get_target_address (insn, immfound, imm, pc, ra, rb, &targetvalid, &unconditionalbranch);
740+ microblaze_debug ("single-step uncondbr=%d targetvalid=%d target=%x\n", unconditionalbranch, targetvalid, stepbreaks[1].address);
741+ if (unconditionalbranch)
742+ stepbreaks[0].valid = FALSE; /* This is a unconditional branch: will not come to the next address */
743+ if (targetvalid && (stepbreaks[0].valid == FALSE ||
744+ (stepbreaks[0].address != stepbreaks[1].address))
745+ && (stepbreaks[1].address != pc)) {
746+ stepbreaks[1].valid = TRUE;
747+ } else {
748+ stepbreaks[1].valid = FALSE;
749+ }
750+ } else {
751+ stepbreaks[1].valid = FALSE;
752+ }
753+
754+ /* Insert the breakpoints */
755+ for (ii = 0; ii < 2; ++ii)
756+ {
757+
758+ /* ignore invalid breakpoint. */
759+ if (stepbreaks[ii].valid) {
760+ // VEC_safe_push (CORE_ADDR, next_pcs, stepbreaks[ii].address);;
761+ next_pcs.push_back (stepbreaks[ii].address);
762+ }
763+ }
764+ return next_pcs;
765+}
766+#endif
767+
768 static int dwarf2_to_reg_map[78] =
769 { 0 /* r0 */, 1 /* r1 */, 2 /* r2 */, 3 /* r3 */, /* 0- 3 */
770 4 /* r4 */, 5 /* r5 */, 6 /* r6 */, 7 /* r7 */, /* 4- 7 */
771@@ -788,6 +919,8 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
772 microblaze_breakpoint::bp_from_kind);
773 set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
774
775+ set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step);
776+
777 set_gdbarch_frame_args_skip (gdbarch, 8);
778
779 set_gdbarch_unwind_pc (gdbarch, microblaze_unwind_pc);
780diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
781index 07a160a463c..c4c8098308f 100644
782--- a/gdb/microblaze-tdep.h
783+++ b/gdb/microblaze-tdep.h
784@@ -60,11 +60,11 @@ enum microblaze_regnum
785 MICROBLAZE_R12_REGNUM,
786 MICROBLAZE_R13_REGNUM,
787 MICROBLAZE_R14_REGNUM,
788- MICROBLAZE_R15_REGNUM,
789+ MICROBLAZE_R15_REGNUM,MICROBLAZE_PREV_PC_REGNUM = MICROBLAZE_R15_REGNUM,
790 MICROBLAZE_R16_REGNUM,
791 MICROBLAZE_R17_REGNUM,
792 MICROBLAZE_R18_REGNUM,
793- MICROBLAZE_R19_REGNUM,
794+ MICROBLAZE_R19_REGNUM,MICROBLAZE_FP_REGNUM = MICROBLAZE_R19_REGNUM,
795 MICROBLAZE_R20_REGNUM,
796 MICROBLAZE_R21_REGNUM,
797 MICROBLAZE_R22_REGNUM,
798@@ -77,7 +77,8 @@ enum microblaze_regnum
799 MICROBLAZE_R29_REGNUM,
800 MICROBLAZE_R30_REGNUM,
801 MICROBLAZE_R31_REGNUM,
802- MICROBLAZE_PC_REGNUM,
803+ MICROBLAZE_MAX_GPR_REGS,
804+ MICROBLAZE_PC_REGNUM=32,
805 MICROBLAZE_MSR_REGNUM,
806 MICROBLAZE_EAR_REGNUM,
807 MICROBLAZE_ESR_REGNUM,
808@@ -102,17 +103,21 @@ enum microblaze_regnum
809 MICROBLAZE_RTLBSX_REGNUM,
810 MICROBLAZE_RTLBLO_REGNUM,
811 MICROBLAZE_RTLBHI_REGNUM,
812- MICROBLAZE_SLR_REGNUM, MICROBLAZE_NUM_CORE_REGS = MICROBLAZE_SLR_REGNUM,
813+ MICROBLAZE_SLR_REGNUM,
814 MICROBLAZE_SHR_REGNUM,
815- MICROBLAZE_NUM_REGS
816+ MICROBLAZE_NUM_REGS, MICROBLAZE_NUM_CORE_REGS = MICROBLAZE_NUM_REGS
817 };
818
819+/* Big enough to hold the size of the largest register in bytes. */
820+#define MICROBLAZE_MAX_REGISTER_SIZE 64
821+
822 struct microblaze_frame_cache
823 {
824 /* Base address. */
825 CORE_ADDR base;
826 CORE_ADDR pc;
827
828+ CORE_ADDR saved_sp;
829 /* Do we have a frame? */
830 int frameless_p;
831
832--
8332.34.1
834
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0006-Adding-64-bit-MB-support-Added-new-architecture-to-M.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0006-Adding-64-bit-MB-support-Added-new-architecture-to-M.patch
new file mode 100644
index 00000000..a61c17d9
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0006-Adding-64-bit-MB-support-Added-new-architecture-to-M.patch
@@ -0,0 +1,1841 @@
1From ff4596845becf48fa17f06ea30a59658e9722e06 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Thu, 31 Jan 2019 14:36:00 +0530
4Subject: [PATCH 06/53] Adding 64 bit MB support Added new architecture to
5 Microblaze 64-bit support to GDB Signed-off-by :Nagaraju Mekala
6 <nmekala@xilix.com> Signed-off-by :Mahesh Bodapati <mbodapat@xilinx.com>
7
8Conflicts:
9 gdb/Makefile.in
10
11Conflicts:
12 bfd/cpu-microblaze.c
13 gdb/microblaze-tdep.c
14 ld/Makefile.am
15 ld/Makefile.in
16 opcodes/microblaze-dis.c
17
18Conflicts:
19 bfd/configure
20 gas/config/tc-microblaze.c
21 ld/Makefile.in
22 opcodes/microblaze-opcm.h
23
24Conflicts:
25 gdb/microblaze-tdep.c
26
27Conflicts:
28 bfd/elf32-microblaze.c
29 gas/config/tc-microblaze.c
30 gdb/features/Makefile
31 gdb/features/microblaze-with-stack-protect.c
32 gdb/microblaze-tdep.c
33 gdb/regformats/microblaze-with-stack-protect.dat
34 gdbserver/linux-microblaze-low.c
35 include/elf/common.h
36
37Signed-off-by: Aayush Misra <aayushm@amd.com>
38---
39 bfd/Makefile.am | 2 +
40 bfd/Makefile.in | 3 +
41 bfd/archures.c | 2 +
42 bfd/bfd-in2.h | 41 ++++-
43 bfd/config.bfd | 4 +
44 bfd/configure | 2 +
45 bfd/cpu-microblaze.c | 55 +++++-
46 bfd/elf32-microblaze.c | 133 ++++++++++++--
47 bfd/libbfd.h | 2 +
48 bfd/reloc.c | 20 +++
49 bfd/targets.c | 6 +
50 gdb/features/Makefile | 2 +
51 gdb/features/microblaze-core.xml | 6 +-
52 gdb/features/microblaze-stack-protect.xml | 4 +-
53 gdb/features/microblaze-with-stack-protect.c | 8 +-
54 gdb/features/microblaze.c | 6 +-
55 gdb/features/microblaze64-core.xml | 69 ++++++++
56 gdb/features/microblaze64-stack-protect.xml | 12 ++
57 .../microblaze64-with-stack-protect.c | 79 +++++++++
58 .../microblaze64-with-stack-protect.xml | 12 ++
59 gdb/features/microblaze64.c | 77 +++++++++
60 gdb/features/microblaze64.xml | 11 ++
61 gdb/microblaze-linux-tdep.c | 36 +++-
62 gdb/microblaze-tdep.c | 125 ++++++++++----
63 gdb/microblaze-tdep.h | 4 +-
64 include/elf/common.h | 1 +
65 include/elf/microblaze.h | 2 +
66 opcodes/microblaze-dis.c | 52 +++---
67 opcodes/microblaze-opc.h | 162 ++++++++++++++++--
68 opcodes/microblaze-opcm.h | 24 ++-
69 30 files changed, 853 insertions(+), 109 deletions(-)
70 create mode 100644 gdb/features/microblaze64-core.xml
71 create mode 100644 gdb/features/microblaze64-stack-protect.xml
72 create mode 100644 gdb/features/microblaze64-with-stack-protect.c
73 create mode 100644 gdb/features/microblaze64-with-stack-protect.xml
74 create mode 100644 gdb/features/microblaze64.c
75 create mode 100644 gdb/features/microblaze64.xml
76
77diff --git a/bfd/Makefile.am b/bfd/Makefile.am
78index 4f67b59585d..510f96439b7 100644
79--- a/bfd/Makefile.am
80+++ b/bfd/Makefile.am
81@@ -568,6 +568,7 @@ BFD64_BACKENDS = \
82 elf64-ppc.lo \
83 elf64-riscv.lo \
84 elf64-s390.lo \
85+ elf64-microblaze.lo \
86 elf64-sparc.lo \
87 elf64-tilegx.lo \
88 elf64-x86-64.lo \
89@@ -617,6 +618,7 @@ BFD64_BACKENDS_CFILES = \
90 elf64-nfp.c \
91 elf64-ppc.c \
92 elf64-s390.c \
93+ elf64-microblaze.c \
94 elf64-sparc.c \
95 elf64-tilegx.c \
96 elf64-x86-64.c \
97diff --git a/bfd/Makefile.in b/bfd/Makefile.in
98index faaa0c424b8..71982d9f729 100644
99--- a/bfd/Makefile.in
100+++ b/bfd/Makefile.in
101@@ -1036,6 +1036,7 @@ BFD64_BACKENDS = \
102 elf64-ppc.lo \
103 elf64-riscv.lo \
104 elf64-s390.lo \
105+ elf64-microblaze.lo \
106 elf64-sparc.lo \
107 elf64-tilegx.lo \
108 elf64-x86-64.lo \
109@@ -1085,6 +1086,7 @@ BFD64_BACKENDS_CFILES = \
110 elf64-nfp.c \
111 elf64-ppc.c \
112 elf64-s390.c \
113+ elf64-microblaze.c \
114 elf64-sparc.c \
115 elf64-tilegx.c \
116 elf64-x86-64.c \
117@@ -1661,6 +1663,7 @@ distclean-compile:
118 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-ppc.Plo@am__quote@
119 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-riscv.Plo@am__quote@
120 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-s390.Plo@am__quote@
121+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-microblaze.Plo@am__quote@
122 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-sparc.Plo@am__quote@
123 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-tilegx.Plo@am__quote@
124 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-x86-64.Plo@am__quote@
125diff --git a/bfd/archures.c b/bfd/archures.c
126index 94118b8d2cf..b9db26627ea 100644
127--- a/bfd/archures.c
128+++ b/bfd/archures.c
129@@ -515,6 +515,8 @@ DESCRIPTION
130 . bfd_arch_lm32, {* Lattice Mico32. *}
131 .#define bfd_mach_lm32 1
132 . bfd_arch_microblaze,{* Xilinx MicroBlaze. *}
133+.#define bfd_mach_microblaze 1
134+.#define bfd_mach_microblaze64 2
135 . bfd_arch_kvx, {* Kalray VLIW core of the MPPA processor family *}
136 .#define bfd_mach_kv3_unknown 0
137 .#define bfd_mach_kv3_1 1
138diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
139index 581d8fe0b3e..7ccc155394d 100644
140--- a/bfd/bfd-in2.h
141+++ b/bfd/bfd-in2.h
142@@ -1771,6 +1771,8 @@ enum bfd_architecture
143 bfd_arch_lm32, /* Lattice Mico32. */
144 #define bfd_mach_lm32 1
145 bfd_arch_microblaze,/* Xilinx MicroBlaze. */
146+#define bfd_mach_microblaze 1
147+#define bfd_mach_microblaze64 2
148 bfd_arch_kvx, /* Kalray VLIW core of the MPPA processor family */
149 #define bfd_mach_kv3_unknown 0
150 #define bfd_mach_kv3_1 1
151@@ -6444,23 +6446,44 @@ enum bfd_reloc_code_real
152 the form "Symbol Op Symbol". */
153 BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM,
154
155- /* This is a 32 bit reloc that stores the 32 bit pc relative value in
156- two words (with an imm instruction). No relocation is done here -
157- only used for relaxing. */
158+/* This is a 32 bit reloc that stores the 32 bit pc relative
159+value in two words (with an imm instruction). No relocation is
160+done here - only used for relaxing */
161 BFD_RELOC_MICROBLAZE_32_NONE,
162
163- /* This is a 64 bit reloc that stores the 32 bit pc relative value in
164- two words (with an imm instruction). No relocation is done here -
165- only used for relaxing. */
166- BFD_RELOC_MICROBLAZE_64_NONE,
167+/* This is a 64 bit reloc that stores the 32 bit pc relative
168+ * +value in two words (with an imml instruction). No relocation is
169+ * +done here - only used for relaxing */
170+ BFD_RELOC_MICROBLAZE_64_PCREL,
171+
172+/* This is a 64 bit reloc that stores the 32 bit relative
173+ * +value in two words (with an imml instruction). No relocation is
174+ * +done here - only used for relaxing */
175+ BFD_RELOC_MICROBLAZE_64,
176+
177+/* This is a 64 bit reloc that stores the 32 bit relative
178+ * +value in two words (with an imml instruction). No relocation is
179+ * +done here - only used for relaxing */
180+ BFD_RELOC_MICROBLAZE_EA64,
181+
182+/* This is a 64 bit reloc that stores the 32 bit pc relative
183+ * +value in two words (with an imm instruction). No relocation is
184+ * +done here - only used for relaxing */
185+ BFD_RELOC_MICROBLAZE_64_NONE,
186
187 /* This is a 64 bit reloc that stores the 32 bit pc relative value in
188 two words (with an imm instruction). The relocation is PC-relative
189 GOT offset. */
190 BFD_RELOC_MICROBLAZE_64_GOTPC,
191
192- /* This is a 64 bit reloc that stores the 32 bit pc relative value in
193- two words (with an imm instruction). The relocation is GOT offset. */
194+/* This is a 64 bit reloc that stores the 32 bit pc relative
195+value in two words (with an imml instruction). The relocation is
196+PC-relative GOT offset */
197+ BFD_RELOC_MICROBLAZE_64_GPC,
198+
199+/* This is a 64 bit reloc that stores the 32 bit pc relative
200+value in two words (with an imm instruction). The relocation is
201+GOT offset */
202 BFD_RELOC_MICROBLAZE_64_GOT,
203
204 /* This is a 64 bit reloc that stores the 32 bit pc relative value in
205diff --git a/bfd/config.bfd b/bfd/config.bfd
206index bbf12447517..cbba305354f 100644
207--- a/bfd/config.bfd
208+++ b/bfd/config.bfd
209@@ -884,11 +884,15 @@ case "${targ}" in
210 microblazeel*-*)
211 targ_defvec=microblaze_elf32_le_vec
212 targ_selvecs=microblaze_elf32_vec
213+ targ64_selvecs=microblaze_elf64_vec
214+ targ64_selvecs=microblaze_elf64_le_vec
215 ;;
216
217 microblaze*-*)
218 targ_defvec=microblaze_elf32_vec
219 targ_selvecs=microblaze_elf32_le_vec
220+ targ64_selvecs=microblaze_elf64_vec
221+ targ64_selvecs=microblaze_elf64_le_vec
222 ;;
223
224 #ifdef BFD64
225diff --git a/bfd/configure b/bfd/configure
226index 5618c5d3217..3c5b58c33b4 100755
227--- a/bfd/configure
228+++ b/bfd/configure
229@@ -16016,6 +16016,8 @@ do
230 rx_elf32_linux_le_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
231 s390_elf32_vec) tb="$tb elf32-s390.lo elf32.lo $elf" ;;
232 s390_elf64_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
233+ microblaze_elf64_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
234+ microblaze_elf64_le_vec) tb="$tb elf64-microblaze.lo elf64.lo $elf"; target_size=64 ;;
235 score_elf32_be_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo elf64.lo $elf"; want64=true; target_size=64 ;;
236 score_elf32_le_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo elf64.lo $elf"; want64=true; target_size=64 ;;
237 sh_coff_vec) tb="$tb coff-sh.lo $coff" ;;
238diff --git a/bfd/cpu-microblaze.c b/bfd/cpu-microblaze.c
239index a7af3a17237..caf4fb66826 100644
240--- a/bfd/cpu-microblaze.c
241+++ b/bfd/cpu-microblaze.c
242@@ -23,13 +23,30 @@
243 #include "bfd.h"
244 #include "libbfd.h"
245
246-const bfd_arch_info_type bfd_microblaze_arch =
247+const bfd_arch_info_type bfd_microblaze_arch[] =
248+{
249+#if BFD_DEFAULT_TARGET_SIZE == 64
250+{
251+ 64, /* 32 bits in a word. */
252+ 64, /* 32 bits in an address. */
253+ 8, /* 8 bits in a byte. */
254+ bfd_arch_microblaze, /* Architecture. */
255+ bfd_mach_microblaze64, /* 64 bit Machine */
256+ "microblaze", /* Architecture name. */
257+ "MicroBlaze", /* Printable name. */
258+ 3, /* Section align power. */
259+ false, /* Is this the default architecture ? */
260+ bfd_default_compatible, /* Architecture comparison function. */
261+ bfd_default_scan, /* String to architecture conversion. */
262+ bfd_arch_default_fill, /* Default fill. */
263+ &bfd_microblaze_arch[1] /* Next in list. */
264+},
265 {
266 32, /* Bits in a word. */
267 32, /* Bits in an address. */
268 8, /* Bits in a byte. */
269 bfd_arch_microblaze, /* Architecture number. */
270- 0, /* Machine number - 0 for now. */
271+ bfd_mach_microblaze, /* Machine number - 0 for now. */
272 "microblaze", /* Architecture name. */
273 "MicroBlaze", /* Printable name. */
274 3, /* Section align power. */
275@@ -39,4 +56,38 @@ const bfd_arch_info_type bfd_microblaze_arch =
276 bfd_arch_default_fill, /* Default fill. */
277 NULL, /* Next in list. */
278 0 /* Maximum offset of a reloc from the start of an insn. */
279+}
280+#else
281+{
282+ 32, /* 32 bits in a word. */
283+ 32, /* 32 bits in an address. */
284+ 8, /* 8 bits in a byte. */
285+ bfd_arch_microblaze, /* Architecture. */
286+ bfd_mach_microblaze, /* 32 bit Machine */
287+ "microblaze", /* Architecture name. */
288+ "MicroBlaze", /* Printable name. */
289+ 3, /* Section align power. */
290+ true, /* Is this the default architecture ? */
291+ bfd_default_compatible, /* Architecture comparison function. */
292+ bfd_default_scan, /* String to architecture conversion. */
293+ bfd_arch_default_fill, /* Default fill. */
294+ &bfd_microblaze_arch[1] /* Next in list. */
295+},
296+{
297+ 64, /* 32 bits in a word. */
298+ 64, /* 32 bits in an address. */
299+ 8, /* 8 bits in a byte. */
300+ bfd_arch_microblaze, /* Architecture. */
301+ bfd_mach_microblaze64, /* 64 bit Machine */
302+ "microblaze", /* Architecture name. */
303+ "MicroBlaze", /* Printable name. */
304+ 3, /* Section align power. */
305+ false, /* Is this the default architecture ? */
306+ bfd_default_compatible, /* Architecture comparison function. */
307+ bfd_default_scan, /* String to architecture conversion. */
308+ bfd_arch_default_fill, /* Default fill. */
309+ NULL, /* Next in list. */
310+ 0
311+}
312+#endif
313 };
314diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
315index 022ce365c59..7e7c4bf471d 100644
316--- a/bfd/elf32-microblaze.c
317+++ b/bfd/elf32-microblaze.c
318@@ -114,6 +114,20 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
319 0x0000ffff, /* Dest Mask. */
320 true), /* PC relative offset? */
321
322+ HOWTO (R_MICROBLAZE_IMML_64, /* Type. */
323+ 0, /* Rightshift. */
324+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
325+ 16, /* Bitsize. */
326+ true, /* PC_relative. */
327+ 0, /* Bitpos. */
328+ complain_overflow_dont, /* Complain on overflow. */
329+ bfd_elf_generic_reloc,/* Special Function. */
330+ "R_MICROBLAZE_IMML_64", /* Name. */
331+ false, /* Partial Inplace. */
332+ 0, /* Source Mask. */
333+ 0x0000ffff, /* Dest Mask. */
334+ false), /* PC relative offset? */
335+
336 /* A 64 bit relocation. Table entry not really used. */
337 HOWTO (R_MICROBLAZE_64, /* Type. */
338 0, /* Rightshift. */
339@@ -279,6 +293,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
340 0x0000ffff, /* Dest Mask. */
341 true), /* PC relative offset? */
342
343+ /* A 64 bit GOTPC relocation. Table-entry not really used. */
344+ HOWTO (R_MICROBLAZE_GPC_64, /* Type. */
345+ 0, /* Rightshift. */
346+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
347+ 16, /* Bitsize. */
348+ true, /* PC_relative. */
349+ 0, /* Bitpos. */
350+ complain_overflow_dont, /* Complain on overflow. */
351+ bfd_elf_generic_reloc, /* Special Function. */
352+ "R_MICROBLAZE_GPC_64", /* Name. */
353+ false, /* Partial Inplace. */
354+ 0, /* Source Mask. */
355+ 0x0000ffff, /* Dest Mask. */
356+ true), /* PC relative offset? */
357+
358 /* A 64 bit GOT relocation. Table-entry not really used. */
359 HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
360 0, /* Rightshift. */
361@@ -618,9 +647,15 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
362 case BFD_RELOC_VTABLE_ENTRY:
363 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
364 break;
365+ case BFD_RELOC_MICROBLAZE_64:
366+ microblaze_reloc = R_MICROBLAZE_IMML_64;
367+ break;
368 case BFD_RELOC_MICROBLAZE_64_GOTPC:
369 microblaze_reloc = R_MICROBLAZE_GOTPC_64;
370 break;
371+ case BFD_RELOC_MICROBLAZE_64_GPC:
372+ microblaze_reloc = R_MICROBLAZE_GPC_64;
373+ break;
374 case BFD_RELOC_MICROBLAZE_64_GOT:
375 microblaze_reloc = R_MICROBLAZE_GOT_64;
376 break;
377@@ -1582,7 +1617,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
378 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
379 {
380 relocation += addend;
381- if (r_type == R_MICROBLAZE_32)
382+ if (r_type == R_MICROBLAZE_32)// || r_type == R_MICROBLAZE_IMML_64)
383 bfd_put_32 (input_bfd, relocation, contents + offset);
384 else
385 {
386@@ -1987,8 +2022,7 @@ microblaze_elf_relax_section (bfd *abfd,
387 else
388 symval += irel->r_addend;
389
390- if ((symval & 0xffff8000) == 0
391- || (symval & 0xffff8000) == 0xffff8000)
392+ if ((symval & 0xffff8000) == 0)
393 {
394 /* We can delete this instruction. */
395 sdata->relax[sdata->relax_count].addr = irel->r_offset;
396@@ -2052,16 +2086,45 @@ microblaze_elf_relax_section (bfd *abfd,
397 irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
398 }
399 break;
400+ case R_MICROBLAZE_IMML_64:
401+ {
402+ /* This was a PC-relative instruction that was
403+ completely resolved. */
404+ int sfix, efix;
405+ unsigned int val;
406+ bfd_vma target_address;
407+ target_address = irel->r_addend + irel->r_offset;
408+ sfix = calc_fixup (irel->r_offset, 0, sec);
409+ efix = calc_fixup (target_address, 0, sec);
410+
411+ /* Validate the in-band val. */
412+ val = bfd_get_32 (abfd, contents + irel->r_offset);
413+ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
414+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
415+ }
416+ irel->r_addend -= (efix - sfix);
417+ /* Should use HOWTO. */
418+ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
419+ irel->r_addend);
420+ }
421+ break;
422 case R_MICROBLAZE_NONE:
423 case R_MICROBLAZE_32_NONE:
424 {
425 /* This was a PC-relative instruction that was
426 completely resolved. */
427 size_t sfix, efix;
428+ unsigned int val;
429 bfd_vma target_address;
430 target_address = irel->r_addend + irel->r_offset;
431 sfix = calc_fixup (irel->r_offset, 0, sec);
432 efix = calc_fixup (target_address, 0, sec);
433+
434+ /* Validate the in-band val. */
435+ val = bfd_get_32 (abfd, contents + irel->r_offset);
436+ if (val != irel->r_addend && ELF32_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
437+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
438+ }
439 irel->r_addend -= (efix - sfix);
440 /* Should use HOWTO. */
441 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
442@@ -2078,8 +2141,8 @@ microblaze_elf_relax_section (bfd *abfd,
443 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
444 efix = calc_fixup (target_address, 0, sec);
445 irel->r_addend -= (efix - sfix);
446- microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
447- + INST_WORD_SIZE, irel->r_addend);
448+ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
449+ irel->r_addend);
450 }
451 break;
452 }
453@@ -2109,10 +2172,50 @@ microblaze_elf_relax_section (bfd *abfd,
454 irelscanend = irelocs + o->reloc_count;
455 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
456 {
457- if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
458- || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE))
459- {
460- isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
461+ if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
462+ {
463+ unsigned int val;
464+
465+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
466+
467+ /* hax: We only do the following fixup for debug location lists. */
468+ if (strcmp(".debug_loc", o->name))
469+ continue;
470+
471+ /* This was a PC-relative instruction that was completely resolved. */
472+ if (ocontents == NULL)
473+ {
474+ if (elf_section_data (o)->this_hdr.contents != NULL)
475+ ocontents = elf_section_data (o)->this_hdr.contents;
476+ else
477+ {
478+ /* We always cache the section contents.
479+ Perhaps, if info->keep_memory is FALSE, we
480+ should free them, if we are permitted to. */
481+
482+ if (o->rawsize == 0)
483+ o->rawsize = o->size;
484+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
485+ if (ocontents == NULL)
486+ goto error_return;
487+ if (!bfd_get_section_contents (abfd, o, ocontents,
488+ (file_ptr) 0,
489+ o->rawsize))
490+ goto error_return;
491+ elf_section_data (o)->this_hdr.contents = ocontents;
492+ }
493+ }
494+ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
495+ if (val != irelscan->r_addend) {
496+ fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
497+ }
498+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
499+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
500+ irelscan->r_addend);
501+ }
502+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)// || ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
503+ {
504+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
505
506 /* Look at the reloc only if the value has been resolved. */
507 if (isym->st_shndx == shndx
508@@ -3510,6 +3613,14 @@ microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
509 return true;
510 }
511
512+
513+static bool
514+elf_microblaze_object_p (bfd *abfd)
515+{
516+ /* Set the right machine number for an s390 elf32 file. */
517+ return bfd_default_set_arch_mach (abfd, bfd_arch_microblaze, bfd_mach_microblaze);
518+}
519+
520 /* Hook called by the linker routine which adds symbols from an object
521 file. We use it to put .comm items in .sbss, and not .bss. */
522
523@@ -3580,8 +3691,6 @@ microblaze_elf_add_symbol_hook (bfd *abfd,
524 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
525 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
526 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
527-
528-#define elf_backend_grok_prstatus microblaze_elf_grok_prstatus
529-#define elf_backend_grok_psinfo microblaze_elf_grok_psinfo
530+#define elf_backend_object_p elf_microblaze_object_p
531
532 #include "elf32-target.h"
533diff --git a/bfd/libbfd.h b/bfd/libbfd.h
534index ebd4f24149b..7a3e558d70a 100644
535--- a/bfd/libbfd.h
536+++ b/bfd/libbfd.h
537@@ -3011,6 +3011,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
538 "BFD_RELOC_MICROBLAZE_64_GOTOFF",
539 "BFD_RELOC_MICROBLAZE_32_GOTOFF",
540 "BFD_RELOC_MICROBLAZE_COPY",
541+ "BFD_RELOC_MICROBLAZE_64",
542+ "BFD_RELOC_MICROBLAZE_64_PCREL",
543 "BFD_RELOC_MICROBLAZE_64_TLS",
544 "BFD_RELOC_MICROBLAZE_64_TLSGD",
545 "BFD_RELOC_MICROBLAZE_64_TLSLD",
546diff --git a/bfd/reloc.c b/bfd/reloc.c
547index e74cbd75e96..fda67e5ffda 100644
548--- a/bfd/reloc.c
549+++ b/bfd/reloc.c
550@@ -6665,6 +6665,12 @@ ENUMDOC
551 This is a 32 bit reloc that stores the 32 bit pc relative value in
552 two words (with an imm instruction). No relocation is done here -
553 only used for relaxing.
554+ENUM
555+ BFD_RELOC_MICROBLAZE_32_NONE
556+ENUMDOC
557+ This is a 32 bit reloc that stores the 32 bit pc relative
558+ value in two words (with an imm instruction). No relocation is
559+ done here - only used for relaxing
560 ENUM
561 BFD_RELOC_MICROBLAZE_64_NONE
562 ENUMDOC
563@@ -7886,6 +7892,20 @@ ENUMX
564 ENUMDOC
565 Tilera TILE-Gx Relocations.
566
567+ This is a 64 bit reloc that stores 64-bit thread pointer relative offset
568+ to two words (uses imml instruction).
569+ENUM
570+BFD_RELOC_MICROBLAZE_64,
571+ENUMDOC
572+ This is a 64 bit reloc that stores the 64 bit pc relative
573+ value in two words (with an imml instruction). No relocation is
574+ done here - only used for relaxing
575+ENUM
576+BFD_RELOC_MICROBLAZE_64_PCREL,
577+ENUMDOC
578+ This is a 32 bit reloc that stores the 32 bit pc relative
579+ value in two words (with an imml instruction). No relocation is
580+ done here - only used for relaxing
581 ENUM
582 BFD_RELOC_BPF_64
583 ENUMX
584diff --git a/bfd/targets.c b/bfd/targets.c
585index 3addf2fe373..a9a9b975c82 100644
586--- a/bfd/targets.c
587+++ b/bfd/targets.c
588@@ -799,6 +799,8 @@ extern const bfd_target mep_elf32_le_vec;
589 extern const bfd_target metag_elf32_vec;
590 extern const bfd_target microblaze_elf32_vec;
591 extern const bfd_target microblaze_elf32_le_vec;
592+extern const bfd_target microblaze_elf64_vec;
593+extern const bfd_target microblaze_elf64_le_vec;
594 extern const bfd_target mips_ecoff_be_vec;
595 extern const bfd_target mips_ecoff_le_vec;
596 extern const bfd_target mips_ecoff_bele_vec;
597@@ -1167,6 +1169,10 @@ static const bfd_target * const _bfd_target_vector[] =
598
599 &metag_elf32_vec,
600
601+#ifdef BFD64
602+ &microblaze_elf64_vec,
603+ &microblaze_elf64_le_vec,
604+#endif
605 &microblaze_elf32_vec,
606
607 &mips_ecoff_be_vec,
608diff --git a/gdb/features/Makefile b/gdb/features/Makefile
609index 8ac30d8cea3..690f1e94570 100644
610--- a/gdb/features/Makefile
611+++ b/gdb/features/Makefile
612@@ -102,7 +102,9 @@ OUTPUTS = $(patsubst %,$(outdir)/%.dat,$(WHICH))
613 # to make on the command line.
614 XMLTOC = \
615 microblaze-with-stack-protect.xml \
616+ microblaze64-with-stack-protect.xml \
617 microblaze.xml \
618+ microblaze64.xml \
619 mips-dsp-linux.xml \
620 mips-linux.xml \
621 mips64-dsp-linux.xml \
622diff --git a/gdb/features/microblaze-core.xml b/gdb/features/microblaze-core.xml
623index d1d7d538461..4d77d9d898f 100644
624--- a/gdb/features/microblaze-core.xml
625+++ b/gdb/features/microblaze-core.xml
626@@ -8,7 +8,7 @@
627 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
628 <feature name="org.gnu.gdb.microblaze.core">
629 <reg name="r0" bitsize="32" regnum="0"/>
630- <reg name="r1" bitsize="32" type="data_ptr"/>
631+ <reg name="r1" bitsize="32"/>
632 <reg name="r2" bitsize="32"/>
633 <reg name="r3" bitsize="32"/>
634 <reg name="r4" bitsize="32"/>
635@@ -39,7 +39,7 @@
636 <reg name="r29" bitsize="32"/>
637 <reg name="r30" bitsize="32"/>
638 <reg name="r31" bitsize="32"/>
639- <reg name="rpc" bitsize="32" type="code_ptr"/>
640+ <reg name="rpc" bitsize="32"/>
641 <reg name="rmsr" bitsize="32"/>
642 <reg name="rear" bitsize="32"/>
643 <reg name="resr" bitsize="32"/>
644@@ -64,4 +64,6 @@
645 <reg name="rtlbsx" bitsize="32"/>
646 <reg name="rtlblo" bitsize="32"/>
647 <reg name="rtlbhi" bitsize="32"/>
648+ <reg name="slr" bitsize="32"/>
649+ <reg name="shr" bitsize="32"/>
650 </feature>
651diff --git a/gdb/features/microblaze-stack-protect.xml b/gdb/features/microblaze-stack-protect.xml
652index b5f68403bd5..013240ce798 100644
653--- a/gdb/features/microblaze-stack-protect.xml
654+++ b/gdb/features/microblaze-stack-protect.xml
655@@ -7,6 +7,6 @@
656
657 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
658 <feature name="org.gnu.gdb.microblaze.stack-protect">
659- <reg name="rslr" bitsize="32"/>
660- <reg name="rshr" bitsize="32"/>
661+ <reg name="slr" bitsize="32"/>
662+ <reg name="shr" bitsize="32"/>
663 </feature>
664diff --git a/gdb/features/microblaze-with-stack-protect.c b/gdb/features/microblaze-with-stack-protect.c
665index 574dc02db67..8ab9565a047 100644
666--- a/gdb/features/microblaze-with-stack-protect.c
667+++ b/gdb/features/microblaze-with-stack-protect.c
668@@ -14,7 +14,7 @@ initialize_tdesc_microblaze_with_stack_protect (void)
669
670 feature = tdesc_create_feature (result.get (), "org.gnu.gdb.microblaze.core");
671 tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
672- tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "data_ptr");
673+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
674 tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
675 tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
676 tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
677@@ -45,7 +45,7 @@ initialize_tdesc_microblaze_with_stack_protect (void)
678 tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "int");
679 tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "int");
680 tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "int");
681- tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "code_ptr");
682+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "int");
683 tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
684 tdesc_create_reg (feature, "rear", 34, 1, NULL, 32, "int");
685 tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
686@@ -72,8 +72,8 @@ initialize_tdesc_microblaze_with_stack_protect (void)
687 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
688
689 feature = tdesc_create_feature (result.get (), "org.gnu.gdb.microblaze.stack-protect");
690- tdesc_create_reg (feature, "rslr", 57, 1, NULL, 32, "int");
691- tdesc_create_reg (feature, "rshr", 58, 1, NULL, 32, "int");
692+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 32, "int");
693+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 32, "int");
694
695 tdesc_microblaze_with_stack_protect = result.release ();
696 }
697diff --git a/gdb/features/microblaze.c b/gdb/features/microblaze.c
698index 8f1fb0a142f..ed12e5bcfd2 100644
699--- a/gdb/features/microblaze.c
700+++ b/gdb/features/microblaze.c
701@@ -14,7 +14,7 @@ initialize_tdesc_microblaze (void)
702
703 feature = tdesc_create_feature (result.get (), "org.gnu.gdb.microblaze.core");
704 tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
705- tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "data_ptr");
706+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
707 tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
708 tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
709 tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
710@@ -45,7 +45,7 @@ initialize_tdesc_microblaze (void)
711 tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "int");
712 tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "int");
713 tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "int");
714- tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "code_ptr");
715+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "int");
716 tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
717 tdesc_create_reg (feature, "rear", 34, 1, NULL, 32, "int");
718 tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
719@@ -70,6 +70,8 @@ initialize_tdesc_microblaze (void)
720 tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
721 tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
722 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
723+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
724+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
725
726 tdesc_microblaze = result.release ();
727 }
728diff --git a/gdb/features/microblaze64-core.xml b/gdb/features/microblaze64-core.xml
729new file mode 100644
730index 00000000000..96e99e2fb24
731--- /dev/null
732+++ b/gdb/features/microblaze64-core.xml
733@@ -0,0 +1,69 @@
734+<?xml version="1.0"?>
735+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
736+
737+ Copying and distribution of this file, with or without modification,
738+ are permitted in any medium without royalty provided the copyright
739+ notice and this notice are preserved. -->
740+
741+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
742+<feature name="org.gnu.gdb.microblaze64.core">
743+ <reg name="r0" bitsize="64" regnum="0"/>
744+ <reg name="r1" bitsize="64"/>
745+ <reg name="r2" bitsize="64"/>
746+ <reg name="r3" bitsize="64"/>
747+ <reg name="r4" bitsize="64"/>
748+ <reg name="r5" bitsize="64"/>
749+ <reg name="r6" bitsize="64"/>
750+ <reg name="r7" bitsize="64"/>
751+ <reg name="r8" bitsize="64"/>
752+ <reg name="r9" bitsize="64"/>
753+ <reg name="r10" bitsize="64"/>
754+ <reg name="r11" bitsize="64"/>
755+ <reg name="r12" bitsize="64"/>
756+ <reg name="r13" bitsize="64"/>
757+ <reg name="r14" bitsize="64"/>
758+ <reg name="r15" bitsize="64"/>
759+ <reg name="r16" bitsize="64"/>
760+ <reg name="r17" bitsize="64"/>
761+ <reg name="r18" bitsize="64"/>
762+ <reg name="r19" bitsize="64"/>
763+ <reg name="r20" bitsize="64"/>
764+ <reg name="r21" bitsize="64"/>
765+ <reg name="r22" bitsize="64"/>
766+ <reg name="r23" bitsize="64"/>
767+ <reg name="r24" bitsize="64"/>
768+ <reg name="r25" bitsize="64"/>
769+ <reg name="r26" bitsize="64"/>
770+ <reg name="r27" bitsize="64"/>
771+ <reg name="r28" bitsize="64"/>
772+ <reg name="r29" bitsize="64"/>
773+ <reg name="r30" bitsize="64"/>
774+ <reg name="r31" bitsize="64"/>
775+ <reg name="rpc" bitsize="64"/>
776+ <reg name="rmsr" bitsize="32"/>
777+ <reg name="rear" bitsize="64"/>
778+ <reg name="resr" bitsize="32"/>
779+ <reg name="rfsr" bitsize="32"/>
780+ <reg name="rbtr" bitsize="64"/>
781+ <reg name="rpvr0" bitsize="32"/>
782+ <reg name="rpvr1" bitsize="32"/>
783+ <reg name="rpvr2" bitsize="32"/>
784+ <reg name="rpvr3" bitsize="32"/>
785+ <reg name="rpvr4" bitsize="32"/>
786+ <reg name="rpvr5" bitsize="32"/>
787+ <reg name="rpvr6" bitsize="32"/>
788+ <reg name="rpvr7" bitsize="32"/>
789+ <reg name="rpvr8" bitsize="64"/>
790+ <reg name="rpvr9" bitsize="64"/>
791+ <reg name="rpvr10" bitsize="32"/>
792+ <reg name="rpvr11" bitsize="32"/>
793+ <reg name="redr" bitsize="32"/>
794+ <reg name="rpid" bitsize="32"/>
795+ <reg name="rzpr" bitsize="32"/>
796+ <reg name="rtlbx" bitsize="32"/>
797+ <reg name="rtlbsx" bitsize="32"/>
798+ <reg name="rtlblo" bitsize="32"/>
799+ <reg name="rtlbhi" bitsize="32"/>
800+ <reg name="slr" bitsize="64"/>
801+ <reg name="shr" bitsize="64"/>
802+</feature>
803diff --git a/gdb/features/microblaze64-stack-protect.xml b/gdb/features/microblaze64-stack-protect.xml
804new file mode 100644
805index 00000000000..1bbf5fc3cea
806--- /dev/null
807+++ b/gdb/features/microblaze64-stack-protect.xml
808@@ -0,0 +1,12 @@
809+<?xml version="1.0"?>
810+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
811+
812+ Copying and distribution of this file, with or without modification,
813+ are permitted in any medium without royalty provided the copyright
814+ notice and this notice are preserved. -->
815+
816+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
817+<feature name="org.gnu.gdb.microblaze64.stack-protect">
818+ <reg name="slr" bitsize="64"/>
819+ <reg name="shr" bitsize="64"/>
820+</feature>
821diff --git a/gdb/features/microblaze64-with-stack-protect.c b/gdb/features/microblaze64-with-stack-protect.c
822new file mode 100644
823index 00000000000..a4de4666c76
824--- /dev/null
825+++ b/gdb/features/microblaze64-with-stack-protect.c
826@@ -0,0 +1,79 @@
827+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
828+ Original: microblaze-with-stack-protect.xml */
829+
830+#include "defs.h"
831+#include "osabi.h"
832+#include "target-descriptions.h"
833+
834+struct target_desc *tdesc_microblaze64_with_stack_protect;
835+static void
836+initialize_tdesc_microblaze64_with_stack_protect (void)
837+{
838+ target_desc_up result = allocate_target_description ();
839+ struct tdesc_feature *feature;
840+
841+ feature = tdesc_create_feature (result.get() , "org.gnu.gdb.microblaze64.core");
842+ tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64");
843+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64");
844+ tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64");
845+ tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64");
846+ tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64");
847+ tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64");
848+ tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64");
849+ tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64");
850+ tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64");
851+ tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64");
852+ tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64");
853+ tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64");
854+ tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64");
855+ tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64");
856+ tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64");
857+ tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64");
858+ tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64");
859+ tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64");
860+ tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64");
861+ tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64");
862+ tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64");
863+ tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64");
864+ tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64");
865+ tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64");
866+ tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64");
867+ tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64");
868+ tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64");
869+ tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64");
870+ tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64");
871+ tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64");
872+ tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64");
873+ tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64");
874+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 64, "uint64");
875+ tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
876+ tdesc_create_reg (feature, "rear", 34, 1, NULL, 64, "int");
877+ tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
878+ tdesc_create_reg (feature, "rfsr", 36, 1, NULL, 32, "int");
879+ tdesc_create_reg (feature, "rbtr", 37, 1, NULL, 64, "uint64");
880+ tdesc_create_reg (feature, "rpvr0", 38, 1, NULL, 32, "int");
881+ tdesc_create_reg (feature, "rpvr1", 39, 1, NULL, 32, "int");
882+ tdesc_create_reg (feature, "rpvr2", 40, 1, NULL, 32, "int");
883+ tdesc_create_reg (feature, "rpvr3", 41, 1, NULL, 32, "int");
884+ tdesc_create_reg (feature, "rpvr4", 42, 1, NULL, 32, "int");
885+ tdesc_create_reg (feature, "rpvr5", 43, 1, NULL, 32, "int");
886+ tdesc_create_reg (feature, "rpvr6", 44, 1, NULL, 32, "int");
887+ tdesc_create_reg (feature, "rpvr7", 45, 1, NULL, 32, "int");
888+ tdesc_create_reg (feature, "rpvr8", 46, 1, NULL, 64, "uint64");
889+ tdesc_create_reg (feature, "rpvr9", 47, 1, NULL, 64, "uint64");
890+ tdesc_create_reg (feature, "rpvr10", 48, 1, NULL, 32, "int");
891+ tdesc_create_reg (feature, "rpvr11", 49, 1, NULL, 32, "int");
892+ tdesc_create_reg (feature, "redr", 50, 1, NULL, 32, "int");
893+ tdesc_create_reg (feature, "rpid", 51, 1, NULL, 32, "int");
894+ tdesc_create_reg (feature, "rzpr", 52, 1, NULL, 32, "int");
895+ tdesc_create_reg (feature, "rtlbx", 53, 1, NULL, 32, "int");
896+ tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
897+ tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
898+ tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
899+
900+ feature = tdesc_create_feature (result.get(), "org.gnu.gdb.microblaze64.stack-protect");
901+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
902+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
903+
904+ tdesc_microblaze64_with_stack_protect = result.release();
905+}
906diff --git a/gdb/features/microblaze64-with-stack-protect.xml b/gdb/features/microblaze64-with-stack-protect.xml
907new file mode 100644
908index 00000000000..0e9f01611f3
909--- /dev/null
910+++ b/gdb/features/microblaze64-with-stack-protect.xml
911@@ -0,0 +1,12 @@
912+<?xml version="1.0"?>
913+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
914+
915+ Copying and distribution of this file, with or without modification,
916+ are permitted in any medium without royalty provided the copyright
917+ notice and this notice are preserved. -->
918+
919+<!DOCTYPE target SYSTEM "gdb-target.dtd">
920+<target>
921+ <xi:include href="microblaze64-core.xml"/>
922+ <xi:include href="microblaze64-stack-protect.xml"/>
923+</target>
924diff --git a/gdb/features/microblaze64.c b/gdb/features/microblaze64.c
925new file mode 100644
926index 00000000000..8ab7a90dd95
927--- /dev/null
928+++ b/gdb/features/microblaze64.c
929@@ -0,0 +1,77 @@
930+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
931+ Original: microblaze.xml */
932+
933+#include "defs.h"
934+#include "osabi.h"
935+#include "target-descriptions.h"
936+
937+struct target_desc *tdesc_microblaze64;
938+static void
939+initialize_tdesc_microblaze64 (void)
940+{
941+ target_desc_up result = allocate_target_description ();
942+ struct tdesc_feature *feature;
943+
944+ feature = tdesc_create_feature (result.get(), "org.gnu.gdb.microblaze64.core");
945+ tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64");
946+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64");
947+ tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64");
948+ tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64");
949+ tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64");
950+ tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64");
951+ tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64");
952+ tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64");
953+ tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64");
954+ tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64");
955+ tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64");
956+ tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64");
957+ tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64");
958+ tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64");
959+ tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64");
960+ tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64");
961+ tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64");
962+ tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64");
963+ tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64");
964+ tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64");
965+ tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64");
966+ tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64");
967+ tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64");
968+ tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64");
969+ tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64");
970+ tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64");
971+ tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64");
972+ tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64");
973+ tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64");
974+ tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64");
975+ tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64");
976+ tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64");
977+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 64, "uint64");
978+ tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
979+ tdesc_create_reg (feature, "rear", 34, 1, NULL, 64, "uint64");
980+ tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
981+ tdesc_create_reg (feature, "rfsr", 36, 1, NULL, 32, "int");
982+ tdesc_create_reg (feature, "rbtr", 37, 1, NULL, 64, "uint64");
983+ tdesc_create_reg (feature, "rpvr0", 38, 1, NULL, 32, "int");
984+ tdesc_create_reg (feature, "rpvr1", 39, 1, NULL, 32, "int");
985+ tdesc_create_reg (feature, "rpvr2", 40, 1, NULL, 32, "int");
986+ tdesc_create_reg (feature, "rpvr3", 41, 1, NULL, 32, "int");
987+ tdesc_create_reg (feature, "rpvr4", 42, 1, NULL, 32, "int");
988+ tdesc_create_reg (feature, "rpvr5", 43, 1, NULL, 32, "int");
989+ tdesc_create_reg (feature, "rpvr6", 44, 1, NULL, 32, "int");
990+ tdesc_create_reg (feature, "rpvr7", 45, 1, NULL, 32, "int");
991+ tdesc_create_reg (feature, "rpvr8", 46, 1, NULL, 64, "uint64");
992+ tdesc_create_reg (feature, "rpvr9", 47, 1, NULL, 64, "uint64");
993+ tdesc_create_reg (feature, "rpvr10", 48, 1, NULL, 32, "int");
994+ tdesc_create_reg (feature, "rpvr11", 49, 1, NULL, 32, "int");
995+ tdesc_create_reg (feature, "redr", 50, 1, NULL, 32, "int");
996+ tdesc_create_reg (feature, "rpid", 51, 1, NULL, 32, "int");
997+ tdesc_create_reg (feature, "rzpr", 52, 1, NULL, 32, "int");
998+ tdesc_create_reg (feature, "rtlbx", 53, 1, NULL, 32, "int");
999+ tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
1000+ tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
1001+ tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
1002+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
1003+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
1004+
1005+ tdesc_microblaze64 = result.release();
1006+}
1007diff --git a/gdb/features/microblaze64.xml b/gdb/features/microblaze64.xml
1008new file mode 100644
1009index 00000000000..515d18e65cf
1010--- /dev/null
1011+++ b/gdb/features/microblaze64.xml
1012@@ -0,0 +1,11 @@
1013+<?xml version="1.0"?>
1014+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
1015+
1016+ Copying and distribution of this file, with or without modification,
1017+ are permitted in any medium without royalty provided the copyright
1018+ notice and this notice are preserved. -->
1019+
1020+<!DOCTYPE target SYSTEM "gdb-target.dtd">
1021+<target>
1022+ <xi:include href="microblaze64-core.xml"/>
1023+</target>
1024diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
1025index d086debc4f8..f34b0fa9fd4 100644
1026--- a/gdb/microblaze-linux-tdep.c
1027+++ b/gdb/microblaze-linux-tdep.c
1028@@ -40,6 +40,7 @@
1029 #include "features/microblaze-linux.c"
1030
1031 static int microblaze_debug_flag = 0;
1032+int MICROBLAZE_REGISTER_SIZE=4;
1033
1034 static void
1035 microblaze_debug (const char *fmt, ...)
1036@@ -55,6 +56,7 @@ microblaze_debug (const char *fmt, ...)
1037 }
1038 }
1039
1040+#if 0
1041 static int
1042 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
1043 struct bp_target_info *bp_tgt)
1044@@ -86,6 +88,8 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
1045 return val;
1046 }
1047
1048+#endif
1049+
1050 static void
1051 microblaze_linux_sigtramp_cache (frame_info_ptr next_frame,
1052 struct trad_frame_cache *this_cache,
1053@@ -147,8 +151,8 @@ microblaze_linux_init_abi (struct gdbarch_info info,
1054
1055 linux_init_abi (info, gdbarch, 0);
1056
1057- set_gdbarch_memory_remove_breakpoint (gdbarch,
1058- microblaze_linux_memory_remove_breakpoint);
1059+ // set_gdbarch_memory_remove_breakpoint (gdbarch,
1060+ // microblaze_linux_memory_remove_breakpoint);
1061
1062 /* Shared library handling. */
1063 set_solib_svr4_fetch_link_map_offsets (gdbarch,
1064@@ -160,10 +164,30 @@ microblaze_linux_init_abi (struct gdbarch_info info,
1065
1066 /* BFD target for core files. */
1067 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
1068- set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze");
1069+ {
1070+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64) {
1071+ set_gdbarch_gcore_bfd_target (gdbarch, "elf64-microblaze");
1072+ MICROBLAZE_REGISTER_SIZE=8;
1073+ }
1074+ else
1075+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze");
1076+ }
1077 else
1078- set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel");
1079+ {
1080+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64) {
1081+ set_gdbarch_gcore_bfd_target (gdbarch, "elf64-microblazeel");
1082+ MICROBLAZE_REGISTER_SIZE=8;
1083+ }
1084+ else
1085+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel");
1086+ }
1087
1088+ switch (info.bfd_arch_info->mach)
1089+ {
1090+ case bfd_mach_microblaze64:
1091+ set_gdbarch_ptr_bit (gdbarch, 64);
1092+ break;
1093+ }
1094
1095 /* Shared library handling. */
1096 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
1097@@ -178,7 +202,9 @@ void _initialize_microblaze_linux_tdep ();
1098 void
1099 _initialize_microblaze_linux_tdep ()
1100 {
1101- gdbarch_register_osabi (bfd_arch_microblaze, 0, GDB_OSABI_LINUX,
1102+ gdbarch_register_osabi (bfd_arch_microblaze, bfd_mach_microblaze, GDB_OSABI_LINUX,
1103+ microblaze_linux_init_abi);
1104+ gdbarch_register_osabi (bfd_arch_microblaze, bfd_mach_microblaze64, GDB_OSABI_LINUX,
1105 microblaze_linux_init_abi);
1106 initialize_tdesc_microblaze_linux ();
1107 }
1108diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
1109index b0b4c1b2614..7cbbc8986a1 100644
1110--- a/gdb/microblaze-tdep.c
1111+++ b/gdb/microblaze-tdep.c
1112@@ -40,7 +40,9 @@
1113 #include "remote.h"
1114
1115 #include "features/microblaze-with-stack-protect.c"
1116+#include "features/microblaze64-with-stack-protect.c"
1117 #include "features/microblaze.c"
1118+#include "features/microblaze64.c"
1119
1120 /* Instruction macros used for analyzing the prologue. */
1121 /* This set of instruction macros need to be changed whenever the
1122@@ -75,12 +77,13 @@ static const char * const microblaze_register_names[] =
1123 "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6",
1124 "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11",
1125 "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi",
1126- "rslr", "rshr"
1127+ "slr", "shr"
1128 };
1129
1130 #define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names)
1131
1132 static unsigned int microblaze_debug_flag = 0;
1133+int reg_size = 4;
1134
1135 #define microblaze_debug(fmt, ...) \
1136 debug_prefixed_printf_cond_nofunc (microblaze_debug_flag, "MICROBLAZE", \
1137@@ -128,6 +131,15 @@ microblaze_fetch_instruction (CORE_ADDR pc)
1138 constexpr gdb_byte microblaze_break_insn[] = MICROBLAZE_BREAKPOINT;
1139
1140 typedef BP_MANIPULATION (microblaze_break_insn) microblaze_breakpoint;
1141+static CORE_ADDR
1142+microblaze_store_arguments (struct regcache *regcache, int nargs,
1143+ struct value **args, CORE_ADDR sp,
1144+ int struct_return, CORE_ADDR struct_addr)
1145+{
1146+ error (_("store_arguments not implemented"));
1147+ return sp;
1148+}
1149+#if 0
1150 static int
1151 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
1152 struct bp_target_info *bp_tgt)
1153@@ -146,7 +158,6 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
1154 /* Make sure we see the memory breakpoints. */
1155 scoped_restore restore_memory
1156 = make_scoped_restore_show_memory_breakpoints (1);
1157-
1158 val = target_read_memory (addr, old_contents, bplen);
1159
1160 /* If our breakpoint is no longer at the address, this means that the
1161@@ -161,6 +172,7 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
1162 return val;
1163 }
1164
1165+#endif
1166 /* Allocate and initialize a frame cache. */
1167
1168 static struct microblaze_frame_cache *
1169@@ -583,11 +595,11 @@ microblaze_extract_return_value (struct type *type, struct regcache *regcache,
1170 {
1171 case 1: /* return last byte in the register. */
1172 regcache->cooked_read (MICROBLAZE_RETVAL_REGNUM, buf);
1173- memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 1, 1);
1174+ memcpy(valbuf, buf + reg_size - 1, 1);
1175 return;
1176 case 2: /* return last 2 bytes in register. */
1177 regcache->cooked_read (MICROBLAZE_RETVAL_REGNUM, buf);
1178- memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 2, 2);
1179+ memcpy(valbuf, buf + reg_size - 2, 2);
1180 return;
1181 case 4: /* for sizes 4 or 8, copy the required length. */
1182 case 8:
1183@@ -753,6 +765,12 @@ microblaze_software_single_step (struct regcache *regcache)
1184 }
1185 #endif
1186
1187+static void
1188+microblaze_write_pc (struct regcache *regcache, CORE_ADDR pc)
1189+{
1190+ regcache_cooked_write_unsigned (regcache, MICROBLAZE_PC_REGNUM, pc);
1191+}
1192+
1193 static int dwarf2_to_reg_map[78] =
1194 { 0 /* r0 */, 1 /* r1 */, 2 /* r2 */, 3 /* r3 */, /* 0- 3 */
1195 4 /* r4 */, 5 /* r5 */, 6 /* r6 */, 7 /* r7 */, /* 4- 7 */
1196@@ -787,13 +805,14 @@ microblaze_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
1197 static void
1198 microblaze_register_g_packet_guesses (struct gdbarch *gdbarch)
1199 {
1200+
1201 register_remote_g_packet_guess (gdbarch,
1202 4 * MICROBLAZE_NUM_CORE_REGS,
1203- tdesc_microblaze);
1204+ tdesc_microblaze64);
1205
1206 register_remote_g_packet_guess (gdbarch,
1207 4 * MICROBLAZE_NUM_REGS,
1208- tdesc_microblaze_with_stack_protect);
1209+ tdesc_microblaze64_with_stack_protect);
1210 }
1211
1212 void
1213@@ -801,7 +820,7 @@ microblaze_supply_gregset (const struct regset *regset,
1214 struct regcache *regcache,
1215 int regnum, const void *gregs)
1216 {
1217- const unsigned int *regs = (const unsigned int *)gregs;
1218+ const gdb_byte *regs = (const gdb_byte *) gregs;
1219 if (regnum >= 0)
1220 regcache->raw_supply (regnum, regs + regnum);
1221
1222@@ -809,7 +828,7 @@ microblaze_supply_gregset (const struct regset *regset,
1223 int i;
1224
1225 for (i = 0; i < 50; i++) {
1226- regcache->raw_supply (i, regs + i);
1227+ regcache->raw_supply (regnum, regs + i);
1228 }
1229 }
1230 }
1231@@ -832,6 +851,17 @@ microblaze_iterate_over_regset_sections (struct gdbarch *gdbarch,
1232 }
1233
1234
1235+static void
1236+make_regs (struct gdbarch *arch)
1237+{
1238+ struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
1239+ int mach = gdbarch_bfd_arch_info (arch)->mach;
1240+
1241+ if (mach == bfd_mach_microblaze64)
1242+ {
1243+ set_gdbarch_ptr_bit (arch, 64);
1244+ }
1245+}
1246
1247 static struct gdbarch *
1248 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1249@@ -844,8 +874,15 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1250 if (arches != NULL)
1251 return arches->gdbarch;
1252 if (tdesc == NULL)
1253- tdesc = tdesc_microblaze;
1254-
1255+ {
1256+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
1257+ {
1258+ tdesc = tdesc_microblaze64;
1259+ reg_size = 8;
1260+ }
1261+ else
1262+ tdesc = tdesc_microblaze;
1263+ }
1264 /* Check any target description for validity. */
1265 if (tdesc_has_registers (tdesc))
1266 {
1267@@ -853,31 +890,42 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1268 int valid_p;
1269 int i;
1270
1271- feature = tdesc_find_feature (tdesc,
1272- "org.gnu.gdb.microblaze.core");
1273+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
1274+ feature = tdesc_find_feature (tdesc,
1275+ "org.gnu.gdb.microblaze64.core");
1276+ else
1277+ feature = tdesc_find_feature (tdesc,
1278+ "org.gnu.gdb.microblaze.core");
1279 if (feature == NULL)
1280 return NULL;
1281 tdesc_data = tdesc_data_alloc ();
1282
1283 valid_p = 1;
1284- for (i = 0; i < MICROBLAZE_NUM_CORE_REGS; i++)
1285- valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
1286- microblaze_register_names[i]);
1287- feature = tdesc_find_feature (tdesc,
1288- "org.gnu.gdb.microblaze.stack-protect");
1289+ for (i = 0; i < MICROBLAZE_NUM_REGS; i++)
1290+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get(), i,
1291+ microblaze_register_names[i]);
1292+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
1293+ feature = tdesc_find_feature (tdesc,
1294+ "org.gnu.gdb.microblaze64.stack-protect");
1295+ else
1296+ feature = tdesc_find_feature (tdesc,
1297+ "org.gnu.gdb.microblaze.stack-protect");
1298 if (feature != NULL)
1299- {
1300- valid_p = 1;
1301- valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
1302- MICROBLAZE_SLR_REGNUM,
1303- "rslr");
1304- valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
1305- MICROBLAZE_SHR_REGNUM,
1306- "rshr");
1307- }
1308+ {
1309+ valid_p = 1;
1310+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get(),
1311+ MICROBLAZE_SLR_REGNUM,
1312+ "slr");
1313+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get(),
1314+ MICROBLAZE_SHR_REGNUM,
1315+ "shr");
1316+ }
1317
1318 if (!valid_p)
1319- return NULL;
1320+ {
1321+ // tdesc_data_cleanup (tdesc_data.get ());
1322+ return NULL;
1323+ }
1324 }
1325
1326 /* Allocate space for the new architecture. */
1327@@ -897,7 +945,17 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1328 /* Register numbers of various important registers. */
1329 set_gdbarch_sp_regnum (gdbarch, MICROBLAZE_SP_REGNUM);
1330 set_gdbarch_pc_regnum (gdbarch, MICROBLAZE_PC_REGNUM);
1331+
1332+ /* Register set.
1333+ make_regs (gdbarch); */
1334+ switch (info.bfd_arch_info->mach)
1335+ {
1336+ case bfd_mach_microblaze64:
1337+ set_gdbarch_ptr_bit (gdbarch, 64);
1338+ break;
1339+ }
1340
1341+
1342 /* Map Dwarf2 registers to GDB registers. */
1343 set_gdbarch_dwarf2_reg_to_regnum (gdbarch, microblaze_dwarf2_reg_to_regnum);
1344
1345@@ -917,7 +975,9 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1346 microblaze_breakpoint::kind_from_pc);
1347 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
1348 microblaze_breakpoint::bp_from_kind);
1349- set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
1350+// set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
1351+
1352+// set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step);
1353
1354 set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step);
1355
1356@@ -925,7 +985,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1357
1358 set_gdbarch_unwind_pc (gdbarch, microblaze_unwind_pc);
1359
1360- microblaze_register_g_packet_guesses (gdbarch);
1361+ //microblaze_register_g_packet_guesses (gdbarch);
1362
1363 frame_base_set_default (gdbarch, &microblaze_frame_base);
1364
1365@@ -940,12 +1000,11 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1366 tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
1367 //frame_base_append_sniffer (gdbarch, microblaze_frame_sniffer);
1368
1369- /* If we have register sets, enable the generic core file support. */
1370+ /* If we have register sets, enable the generic core file support.
1371 if (tdep->gregset) {
1372 set_gdbarch_iterate_over_regset_sections (gdbarch,
1373 microblaze_iterate_over_regset_sections);
1374- }
1375-
1376+ }*/
1377 return gdbarch;
1378 }
1379
1380@@ -957,6 +1016,8 @@ _initialize_microblaze_tdep ()
1381
1382 initialize_tdesc_microblaze_with_stack_protect ();
1383 initialize_tdesc_microblaze ();
1384+ initialize_tdesc_microblaze64_with_stack_protect ();
1385+ initialize_tdesc_microblaze64 ();
1386 /* Debug this files internals. */
1387 add_setshow_zuinteger_cmd ("microblaze", class_maintenance,
1388 &microblaze_debug_flag, _("\
1389diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
1390index c4c8098308f..81f7f30cb8e 100644
1391--- a/gdb/microblaze-tdep.h
1392+++ b/gdb/microblaze-tdep.h
1393@@ -28,7 +28,7 @@ struct microblaze_gregset
1394 microblaze_gregset() {}
1395 unsigned int gregs[32];
1396 unsigned int fpregs[32];
1397- unsigned int pregs[16];
1398+ unsigned int pregs[18];
1399 };
1400
1401 struct microblaze_gdbarch_tdep : gdbarch_tdep_base
1402@@ -134,7 +134,7 @@ struct microblaze_frame_cache
1403 struct trad_frame_saved_reg *saved_regs;
1404 };
1405 /* All registers are 32 bits. */
1406-#define MICROBLAZE_REGISTER_SIZE 4
1407+//#define MICROBLAZE_REGISTER_SIZE 8
1408
1409 /* MICROBLAZE_BREAKPOINT defines the breakpoint that should be used.
1410 Only used for native debugging. */
1411diff --git a/include/elf/common.h b/include/elf/common.h
1412index 6a66456cd22..11f5d1a3cc9 100644
1413--- a/include/elf/common.h
1414+++ b/include/elf/common.h
1415@@ -360,6 +360,7 @@
1416 #define EM_U16_U8CORE 260 /* LAPIS nX-U16/U8 */
1417 #define EM_TACHYUM 261 /* Tachyum */
1418 #define EM_56800EF 262 /* NXP 56800EF Digital Signal Controller (DSC) */
1419+#define EM_MB_64 263 /* Xilinx MicroBlaze 32-bit RISC soft processor core */
1420
1421 /* If it is necessary to assign new unofficial EM_* values, please pick large
1422 random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
1423diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h
1424index a48b1358efd..c515f15bfb8 100644
1425--- a/include/elf/microblaze.h
1426+++ b/include/elf/microblaze.h
1427@@ -62,6 +62,8 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type)
1428 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_64, 31) /* TEXT Entry offset 64-bit. */
1429 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_32_LO, 32) /* TEXT Entry offset 32-bit. */
1430 RELOC_NUMBER (R_MICROBLAZE_32_NONE, 33)
1431+ RELOC_NUMBER (R_MICROBLAZE_IMML_64, 34)
1432+ RELOC_NUMBER (R_MICROBLAZE_GPC_64, 35) /* GOT entry offset. */
1433 END_RELOC_NUMBERS (R_MICROBLAZE_max)
1434
1435 /* Global base address names. */
1436diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
1437index 3d696325803..ee447cecc3f 100644
1438--- a/opcodes/microblaze-dis.c
1439+++ b/opcodes/microblaze-dis.c
1440@@ -33,6 +33,7 @@
1441 #define get_field_r1(buf, instr) get_field (buf, instr, RA_MASK, RA_LOW)
1442 #define get_field_r2(buf, instr) get_field (buf, instr, RB_MASK, RB_LOW)
1443 #define get_int_field_imm(instr) ((instr & IMM_MASK) >> IMM_LOW)
1444+#define get_int_field_imml(instr) ((instr & IMML_MASK) >> IMM_LOW)
1445 #define get_int_field_r1(instr) ((instr & RA_MASK) >> RA_LOW)
1446
1447 #define NUM_STRBUFS 4
1448@@ -73,11 +74,20 @@ get_field_imm (struct string_buf *buf, long instr)
1449 }
1450
1451 static char *
1452-get_field_imm5 (struct string_buf *buf, long instr)
1453+get_field_imml (struct string_buf *buf, long instr)
1454 {
1455 char *p = strbuf (buf);
1456
1457- sprintf (p, "%d", (short)((instr & IMM5_MASK) >> IMM_LOW));
1458+ sprintf (p, "%d", (int)((instr & IMML_MASK) >> IMM_LOW));
1459+ return p;
1460+}
1461+
1462+static char *
1463+get_field_imms (struct string_buf *buf, long instr)
1464+{
1465+ char *p = strbuf (buf);
1466+
1467+ sprintf (p, "%d", (short)((instr & IMM6_MASK) >> IMM_LOW));
1468 return p;
1469 }
1470
1471@@ -96,12 +106,9 @@ get_field_immw (struct string_buf *buf, long instr)
1472 char *p = strbuf (buf);
1473
1474 if (instr & 0x00004000)
1475- sprintf (p, "%d", (short)(((instr & IMM5_WIDTH_MASK)
1476- >> IMM_WIDTH_LOW))); /* bsefi */
1477- else
1478- sprintf (p, "%d", (short)(((instr & IMM5_WIDTH_MASK) >>
1479- IMM_WIDTH_LOW) - ((instr & IMM5_MASK) >>
1480- IMM_LOW) + 1)); /* bsifi */
1481+ sprintf (p, "%d", (short)(((instr & IMM6_WIDTH_MASK) >> IMM_WIDTH_LOW))); /* bsefi */
1482+ else
1483+ sprintf (p, "%d", (short)(((instr & IMM6_WIDTH_MASK) >> IMM_WIDTH_LOW) - ((instr & IMM6_MASK) >> IMM_LOW) + 1)); /* bsifi */
1484 return p;
1485 }
1486
1487@@ -311,9 +318,14 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
1488 }
1489 }
1490 break;
1491- case INST_TYPE_RD_R1_IMM5:
1492+ case INST_TYPE_RD_R1_IMML:
1493+ print_func (stream, "\t%s, %s, %s", get_field_rd (&buf, inst),
1494+ get_field_r1(&buf, inst), get_field_imm (&buf, inst));
1495+ /* TODO: Also print symbol */
1496+ break;
1497+ case INST_TYPE_RD_R1_IMMS:
1498 print_func (stream, "\t%s, %s, %s", get_field_rd (&buf, inst),
1499- get_field_r1 (&buf, inst), get_field_imm5 (&buf, inst));
1500+ get_field_r1(&buf, inst), get_field_imms (&buf, inst));
1501 break;
1502 case INST_TYPE_RD_RFSL:
1503 print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
1504@@ -417,9 +429,12 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
1505 }
1506 }
1507 break;
1508- case INST_TYPE_RD_R2:
1509- print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
1510- get_field_r2 (&buf, inst));
1511+ case INST_TYPE_IMML:
1512+ print_func (stream, "\t%s", get_field_imml (&buf, inst));
1513+ /* TODO: Also print symbol */
1514+ break;
1515+ case INST_TYPE_RD_R2:
1516+ print_func (stream, "\t%s, %s", get_field_rd (&buf, inst), get_field_r2 (&buf, inst));
1517 break;
1518 case INST_TYPE_R2:
1519 print_func (stream, "\t%s", get_field_r2 (&buf, inst));
1520@@ -442,15 +457,12 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
1521 /* For mbar 16 or sleep insn. */
1522 case INST_TYPE_NONE:
1523 break;
1524- /* For bit field insns. */
1525+ /* For bit field insns. */
1526 case INST_TYPE_RD_R1_IMMW_IMMS:
1527- print_func (stream, "\t%s, %s, %s, %s",
1528- get_field_rd (&buf, inst),
1529- get_field_r1 (&buf, inst),
1530- get_field_immw (&buf, inst),
1531- get_field_imm5 (&buf, inst));
1532+ print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst), get_field_r1(&buf, inst),
1533+ get_field_immw (&buf, inst), get_field_imms (&buf, inst));
1534 break;
1535- /* For tuqula instruction */
1536+ /* For tuqula instruction */
1537 case INST_TYPE_RD:
1538 print_func (stream, "\t%s", get_field_rd (&buf, inst));
1539 break;
1540diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
1541index fe23b0af56a..afc1220e357 100644
1542--- a/opcodes/microblaze-opc.h
1543+++ b/opcodes/microblaze-opc.h
1544@@ -40,7 +40,7 @@
1545 #define INST_TYPE_RD_SPECIAL 11
1546 #define INST_TYPE_R1 12
1547 /* New instn type for barrel shift imms. */
1548-#define INST_TYPE_RD_R1_IMM5 13
1549+#define INST_TYPE_RD_R1_IMMS 13
1550 #define INST_TYPE_RD_RFSL 14
1551 #define INST_TYPE_R1_RFSL 15
1552
1553@@ -62,6 +62,11 @@
1554 /* For bsefi and bsifi */
1555 #define INST_TYPE_RD_R1_IMMW_IMMS 21
1556
1557+/* For 64-bit instructions */
1558+#define INST_TYPE_IMML 22
1559+#define INST_TYPE_RD_R1_IMML 23
1560+#define INST_TYPE_R1_IMML 24
1561+
1562 #define INST_TYPE_NONE 25
1563
1564
1565@@ -91,15 +96,14 @@
1566 #define OPCODE_MASK_H24 0xFC1F07FF /* High 6, bits 20-16 and low 11 bits. */
1567 #define OPCODE_MASK_H124 0xFFFF07FF /* High 16, and low 11 bits. */
1568 #define OPCODE_MASK_H1234 0xFFFFFFFF /* All 32 bits. */
1569-#define OPCODE_MASK_H3 0xFC000600 /* High 6 bits and bits 21, 22. */
1570-#define OPCODE_MASK_H3B 0xFC00F9E0 /* High 6 bits and bits 16:20 and
1571- bits 23:26. */
1572+#define OPCODE_MASK_H3 0xFC000700 /* High 6 bits and bits 21, 22, 23. */
1573+#define OPCODE_MASK_H3B 0xFC00E600 /* High 6 bits and bits 16, 17, 18, 21, 22. */
1574 #define OPCODE_MASK_H32 0xFC00FC00 /* High 6 bits and bit 16-21. */
1575-#define OPCODE_MASK_H32B 0xFC00F820 /* High 6 bits and bits 16:20 and
1576- bit 26 */
1577+#define OPCODE_MASK_H32B 0xFC00E000 /* High 6 bits and bit 16, 17, 18. */
1578 #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits. */
1579 #define OPCODE_MASK_H35B 0xFC0004FF /* High 6 bits and low 9 bits. */
1580 #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */
1581+#define OPCODE_MASK_H8 0xFF000000 /* High 8 bits only. */
1582
1583 /* New Mask for msrset, msrclr insns. */
1584 #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */
1585@@ -109,7 +113,7 @@
1586 #define DELAY_SLOT 1
1587 #define NO_DELAY_SLOT 0
1588
1589-#define MAX_OPCODES 291
1590+#define MAX_OPCODES 412
1591
1592 const struct op_code_struct
1593 {
1594@@ -127,6 +131,7 @@ const struct op_code_struct
1595 /* More info about output format here. */
1596 } microblaze_opcodes[MAX_OPCODES] =
1597 {
1598+ /* 32-bit instructions */
1599 {"add", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000000, OPCODE_MASK_H4, add, arithmetic_inst },
1600 {"rsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H4, rsub, arithmetic_inst },
1601 {"addc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000000, OPCODE_MASK_H4, addc, arithmetic_inst },
1602@@ -163,9 +168,9 @@ const struct op_code_struct
1603 {"ncget", INST_TYPE_RD_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C006000, OPCODE_MASK_H32, ncget, anyware_inst },
1604 {"ncput", INST_TYPE_R1_RFSL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00E000, OPCODE_MASK_H32, ncput, anyware_inst },
1605 {"muli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x60000000, OPCODE_MASK_H, muli, mult_inst },
1606- {"bslli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3B, bslli, barrel_shift_inst },
1607- {"bsrai", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3B, bsrai, barrel_shift_inst },
1608- {"bsrli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3B, bsrli, barrel_shift_inst },
1609+ {"bslli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3B, bslli, barrel_shift_inst },
1610+ {"bsrai", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3B, bsrai, barrel_shift_inst },
1611+ {"bsrli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3B, bsrli, barrel_shift_inst },
1612 {"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 },
1613 {"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 },
1614 {"or", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H4, microblaze_or, logical_inst },
1615@@ -269,9 +274,7 @@ const struct op_code_struct
1616 {"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. */
1617 {"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. */
1618 {"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. */
1619- {"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. */
1620 {"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. */
1621- {"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. */
1622 {"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 },
1623 {"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 },
1624 {"msrset",INST_TYPE_RD_IMM15, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x94100000, OPCODE_MASK_H23N, msrset, special_inst },
1625@@ -427,7 +430,131 @@ const struct op_code_struct
1626 {"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. */
1627 {"swapb", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E0, OPCODE_MASK_H4, swapb, arithmetic_inst },
1628 {"swaph", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E2, OPCODE_MASK_H4, swaph, arithmetic_inst },
1629- {NULL, 0, 0, 0, 0, 0, 0, 0, 0},
1630+ /* 64-bit instructions */
1631+ {"addl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000100, OPCODE_MASK_H4, addl, arithmetic_inst },
1632+ {"rsubl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000100, OPCODE_MASK_H4, rsubl, arithmetic_inst },
1633+ {"addlc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000100, OPCODE_MASK_H4, addlc, arithmetic_inst },
1634+ {"rsublc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x0C000100, OPCODE_MASK_H4, rsublc, arithmetic_inst },
1635+ {"addlk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x10000100, OPCODE_MASK_H4, addlk, arithmetic_inst },
1636+ {"rsublk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000100, OPCODE_MASK_H4, rsublk, arithmetic_inst },
1637+ {"addlkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x18000100, OPCODE_MASK_H4, addlkc, arithmetic_inst },
1638+ {"rsublkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x1C000100, OPCODE_MASK_H4, rsublkc, arithmetic_inst },
1639+ {"cmpl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000101, OPCODE_MASK_H4, cmpl, arithmetic_inst },
1640+ {"cmplu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000103, OPCODE_MASK_H4, cmplu, arithmetic_inst },
1641+ {"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 */
1642+ {"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 */
1643+ {"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 */
1644+ {"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 */
1645+ {"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 */
1646+ {"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 */
1647+ {"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 */
1648+ {"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 */
1649+ {"mull", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x40000100, OPCODE_MASK_H4, mull, mult_inst },
1650+ {"bslll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000500, OPCODE_MASK_H3, bslll, barrel_shift_inst },
1651+ {"bslra", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000300, OPCODE_MASK_H3, bslra, barrel_shift_inst },
1652+ {"bslrl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000100, OPCODE_MASK_H3, bslrl, barrel_shift_inst },
1653+ {"bsllli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002400, OPCODE_MASK_H3B, bsllli, barrel_shift_inst },
1654+ {"bslrai", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002200, OPCODE_MASK_H3B, bslrai, barrel_shift_inst },
1655+ {"bslrli", INST_TYPE_RD_R1_IMMS, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64002000, OPCODE_MASK_H3B, bslrli, barrel_shift_inst },
1656+ {"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 },
1657+ {"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 },
1658+ {"orl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000100, OPCODE_MASK_H4, orl, logical_inst },
1659+ {"andl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000100, OPCODE_MASK_H4, andl, logical_inst },
1660+ {"xorl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000100, OPCODE_MASK_H4, xorl, logical_inst },
1661+ {"andnl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000100, OPCODE_MASK_H4, andnl, logical_inst },
1662+ {"pcmplbf", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000500, OPCODE_MASK_H4, pcmplbf, logical_inst },
1663+ {"pcmpleq", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000500, OPCODE_MASK_H4, pcmpleq, logical_inst },
1664+ {"pcmplne", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000500, OPCODE_MASK_H4, pcmplne, logical_inst },
1665+ {"srla", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000101, OPCODE_MASK_H34, srla, logical_inst },
1666+ {"srlc", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000121, OPCODE_MASK_H34, srlc, logical_inst },
1667+ {"srll", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000141, OPCODE_MASK_H34, srll, logical_inst },
1668+ {"sextl8", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000160, OPCODE_MASK_H34, sextl8, logical_inst },
1669+ {"sextl16", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000161, OPCODE_MASK_H34, sextl16, logical_inst },
1670+ {"sextl32", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000162, OPCODE_MASK_H34, sextl32, logical_inst },
1671+ {"brea", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98010000, OPCODE_MASK_H124, brea, branch_inst },
1672+ {"bread", INST_TYPE_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98110000, OPCODE_MASK_H124, bread, branch_inst },
1673+ {"breald", INST_TYPE_RD_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98150000, OPCODE_MASK_H24, breald, branch_inst },
1674+ {"beaeq", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D000000, OPCODE_MASK_H14, beaeq, branch_inst },
1675+ {"bealeq", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D000100, OPCODE_MASK_H14, bealeq, branch_inst },
1676+ {"beaeqd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F000000, OPCODE_MASK_H14, beaeqd, branch_inst },
1677+ {"bealeqd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F000100, OPCODE_MASK_H14, bealeqd, branch_inst },
1678+ {"beane", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D200000, OPCODE_MASK_H14, beane, branch_inst },
1679+ {"bealne", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D200100, OPCODE_MASK_H14, bealne, branch_inst },
1680+ {"beaned", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F200000, OPCODE_MASK_H14, beaned, branch_inst },
1681+ {"bealned", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F200100, OPCODE_MASK_H14, bealned, branch_inst },
1682+ {"bealt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D400000, OPCODE_MASK_H14, bealt, branch_inst },
1683+ {"beallt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D400100, OPCODE_MASK_H14, beallt, branch_inst },
1684+ {"bealtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F400000, OPCODE_MASK_H14, bealtd, branch_inst },
1685+ {"bealltd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F400100, OPCODE_MASK_H14, bealltd, branch_inst },
1686+ {"beale", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D600000, OPCODE_MASK_H14, beale, branch_inst },
1687+ {"bealle", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D600100, OPCODE_MASK_H14, bealle, branch_inst },
1688+ {"bealed", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F600000, OPCODE_MASK_H14, bealed, branch_inst },
1689+ {"bealled", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F600100, OPCODE_MASK_H14, bealled, branch_inst },
1690+ {"beagt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D800000, OPCODE_MASK_H14, beagt, branch_inst },
1691+ {"bealgt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9D800100, OPCODE_MASK_H14, bealgt, branch_inst },
1692+ {"beagtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F800000, OPCODE_MASK_H14, beagtd, branch_inst },
1693+ {"bealgtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9F800100, OPCODE_MASK_H14, bealgtd, branch_inst },
1694+ {"beage", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9DA00000, OPCODE_MASK_H14, beage, branch_inst },
1695+ {"bealge", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9DA00100, OPCODE_MASK_H14, bealge, branch_inst },
1696+ {"beaged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00000, OPCODE_MASK_H14, beaged, branch_inst },
1697+ {"bealged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00100, OPCODE_MASK_H14, bealged, branch_inst },
1698+ {"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 */
1699+ {"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 */
1700+ {"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 */
1701+ {"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 */
1702+ {"imml", INST_TYPE_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB2000000, OPCODE_MASK_H8, imml, immediate_inst },
1703+ {"breai", INST_TYPE_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8010000, OPCODE_MASK_H12, breai, branch_inst },
1704+ {"breaid", INST_TYPE_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8110000, OPCODE_MASK_H12, breaid, branch_inst },
1705+ {"brealid", INST_TYPE_RD_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8150000, OPCODE_MASK_H2, brealid, branch_inst },
1706+ {"beaeqi", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD000000, OPCODE_MASK_H1, beaeqi, branch_inst },
1707+ {"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 */
1708+ {"beaeqid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF000000, OPCODE_MASK_H1, beaeqid, branch_inst },
1709+ {"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 */
1710+ {"beanei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD200000, OPCODE_MASK_H1, beanei, branch_inst },
1711+ {"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 */
1712+ {"beaneid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF200000, OPCODE_MASK_H1, beaneid, branch_inst },
1713+ {"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 */
1714+ {"bealti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD400000, OPCODE_MASK_H1, bealti, branch_inst },
1715+ {"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 */
1716+ {"bealtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF400000, OPCODE_MASK_H1, bealtid, branch_inst },
1717+ {"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 */
1718+ {"bealei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD600000, OPCODE_MASK_H1, bealei, branch_inst },
1719+ {"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 */
1720+ {"bealeid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF600000, OPCODE_MASK_H1, bealeid, branch_inst },
1721+ {"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 */
1722+ {"beagti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBD800000, OPCODE_MASK_H1, beagti, branch_inst },
1723+ {"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 */
1724+ {"beagtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBF800000, OPCODE_MASK_H1, beagtid, branch_inst },
1725+ {"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 */
1726+ {"beagei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBDA00000, OPCODE_MASK_H1, beagei, branch_inst },
1727+ {"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 */
1728+ {"beageid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBFA00000, OPCODE_MASK_H1, beageid, branch_inst },
1729+ {"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 */
1730+ {"ll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000100, OPCODE_MASK_H4, ll, memory_load_inst },
1731+ {"llr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000300, OPCODE_MASK_H4, llr, memory_load_inst },
1732+ {"sl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000100, OPCODE_MASK_H4, sl, memory_store_inst },
1733+ {"slr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000300, OPCODE_MASK_H4, slr, memory_store_inst },
1734+ {"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 */
1735+ {"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 */
1736+ {"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 */
1737+ {"dadd", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000400, OPCODE_MASK_H4, dadd, arithmetic_inst },
1738+ {"drsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000480, OPCODE_MASK_H4, drsub, arithmetic_inst },
1739+ {"dmul", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000500, OPCODE_MASK_H4, dmul, arithmetic_inst },
1740+ {"ddiv", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000580, OPCODE_MASK_H4, ddiv, arithmetic_inst },
1741+ {"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 },
1742+ {"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 },
1743+ {"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 },
1744+ {"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 },
1745+ {"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 },
1746+ {"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 },
1747+ {"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 },
1748+ {"dbl", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000680, OPCODE_MASK_H4, dbl, arithmetic_inst },
1749+ {"dlong", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000700, OPCODE_MASK_H4, dlong, arithmetic_inst },
1750+ {"dsqrt", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000780, OPCODE_MASK_H4, dsqrt, arithmetic_inst },
1751+ {"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. */
1752+ {"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. */
1753+
1754+ {"", 0, 0, 0, 0, 0, 0, 0, 0},
1755 };
1756
1757 /* Prefix for register names. */
1758@@ -447,8 +574,17 @@ char pvr_register_prefix[] = "rpvr";
1759 #define MIN_IMM5 ((int) 0x00000000)
1760 #define MAX_IMM5 ((int) 0x0000001f)
1761
1762+#define MIN_IMM6 ((int) 0x00000000)
1763+#define MAX_IMM6 ((int) 0x0000003f)
1764+
1765 #define MIN_IMM_WIDTH ((int) 0x00000001)
1766 #define MAX_IMM_WIDTH ((int) 0x00000020)
1767
1768+#define MIN_IMM6_WIDTH ((int) 0x00000001)
1769+#define MAX_IMM6_WIDTH ((int) 0x00000040)
1770+
1771+#define MIN_IMML ((long) 0xffffff8000000000L)
1772+#define MAX_IMML ((long) 0x0000007fffffffffL)
1773+
1774 #endif /* MICROBLAZE_OPC */
1775
1776diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
1777index cb8d3a59949..08ed44352ee 100644
1778--- a/opcodes/microblaze-opcm.h
1779+++ b/opcodes/microblaze-opcm.h
1780@@ -25,6 +25,7 @@
1781
1782 enum microblaze_instr
1783 {
1784+ /* 32-bit instructions */
1785 add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, clz, cmp, cmpu,
1786 addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul,
1787 mulh, mulhu, mulhsu, swapb, swaph,
1788@@ -39,8 +40,8 @@ enum microblaze_instr
1789 imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
1790 brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti,
1791 bgtid, bgei, bgeid, lbu, lbuea, lbur, lhu, lhuea, lhur, lw, lwea, lwr, lwx,
1792- sb, sbea, sbr, sh, shea, shr, sw, swea, swr, swx, lbui, lhui, lwi,
1793- sbi, shi, swi, msrset, msrclr, tuqula, mbi_fadd, frsub, mbi_fmul, mbi_fdiv,
1794+ sb, sbea, sbr, sh, shea, shr, sw, swea, swr, swx, lbui, lhui, lwi, lli,
1795+ sbi, shi, sli, swi, msrset, msrclr, tuqula, mbi_fadd, frsub, mbi_fmul, mbi_fdiv,
1796 fcmp_lt, fcmp_eq, fcmp_le, fcmp_gt, fcmp_ne, fcmp_ge, fcmp_un, flt,
1797 /* 'fsqrt' is a glibc:math.h symbol. */
1798 fint, microblaze_fsqrt,
1799@@ -59,6 +60,18 @@ enum microblaze_instr
1800 aputd, taputd, caputd, tcaputd, naputd, tnaputd, ncaputd, tncaputd,
1801 eagetd, teagetd, ecagetd, tecagetd, neagetd, tneagetd, necagetd, tnecagetd,
1802 eaputd, teaputd, ecaputd, tecaputd, neaputd, tneaputd, necaputd, tnecaputd,
1803+
1804+ /* 64-bit instructions */
1805+ addl, rsubl, addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull,
1806+ bslll, bslra, bslrl, bsllli, bslrai, bslrli, bslefi, bslifi, orl, andl, xorl,
1807+ andnl, pcmplbf, pcmpleq, pcmplne, srla, srlc, srll, sextl8, sextl16, sextl32,
1808+ brea, bread, breald, beaeq, bealeq, beaeqd, bealeqd, beane, bealne, beaned,
1809+ bealned, bealt, beallt, bealtd, bealltd, beale, bealle, bealed, bealled, beagt,
1810+ bealgt, beagtd, bealgtd, beage, bealge, beaged, bealged, breai, breaid, brealid,
1811+ beaeqi, beaeqid, beanei, beaneid, bealti, bealtid, bealei, bealeid, beagti,
1812+ beagtid, beagei, beageid, imml, ll, llr, sl, slr,
1813+ dadd, drsub, dmul, ddiv, dcmp_lt, dcmp_eq, dcmp_le, dcmp_gt, dcmp_ne, dcmp_ge,
1814+ dcmp_un, dbl, dlong, dsqrt,
1815 invalid_inst
1816 };
1817
1818@@ -136,15 +149,18 @@ enum microblaze_instr_type
1819 #define RA_MASK 0x001F0000
1820 #define RB_MASK 0x0000F800
1821 #define IMM_MASK 0x0000FFFF
1822+#define IMML_MASK 0x00FFFFFF
1823
1824-/* Imm mask for barrel shifts. */
1825+/* Imm masks for barrel shifts. */
1826 #define IMM5_MASK 0x0000001F
1827+#define IMM6_MASK 0x0000003F
1828
1829 /* Imm mask for mbar. */
1830 #define IMM5_MBAR_MASK 0x03E00000
1831
1832-/* Imm mask for extract/insert width. */
1833+/* Imm masks for extract/insert width. */
1834 #define IMM5_WIDTH_MASK 0x000007C0
1835+#define IMM6_WIDTH_MASK 0x00000FC0
1836
1837 /* FSL imm mask for get, put instructions. */
1838 #define RFSL_MASK 0x000000F
1839--
18402.34.1
1841
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0007-these-changes-will-make-64-bit-vectors-as-default-ta.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0007-these-changes-will-make-64-bit-vectors-as-default-ta.patch
new file mode 100644
index 00000000..a744bcb4
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0007-these-changes-will-make-64-bit-vectors-as-default-ta.patch
@@ -0,0 +1,35 @@
1From 6c699df5c33f13ea3226d144f544d5a295edcf17 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 19 Apr 2021 14:33:27 +0530
4Subject: [PATCH 07/53] these changes will make 64 bit vectors as default
5 target types when we built gdb with microblaze 64 bit type targets,for
6 instance microblaze-xilinx-elf64/microblazeel-xilinx-elf64
7
8Signed-off-by: Aayush Misra <aayushm@amd.com>
9---
10 bfd/config.bfd | 8 ++++++++
11 1 file changed, 8 insertions(+)
12
13diff --git a/bfd/config.bfd b/bfd/config.bfd
14index cbba305354f..f7134608693 100644
15--- a/bfd/config.bfd
16+++ b/bfd/config.bfd
17@@ -880,7 +880,15 @@ case "${targ}" in
18 targ_defvec=metag_elf32_vec
19 targ_underscore=yes
20 ;;
21+ microblazeel*-*64)
22+ targ_defvec=microblaze_elf64_le_vec
23+ targ_selvecs=microblaze_elf64_vec
24+ ;;
25
26+ microblaze*-*64)
27+ targ_defvec=microblaze_elf64_vec
28+ targ_selvecs=microblaze_elf64_le_vec
29+ ;;
30 microblazeel*-*)
31 targ_defvec=microblaze_elf32_le_vec
32 targ_selvecs=microblaze_elf32_vec
33--
342.34.1
35
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0008-Added-m64-abi-for-64-bit-target-descriptions.-set-m6.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0008-Added-m64-abi-for-64-bit-target-descriptions.-set-m6.patch
new file mode 100644
index 00000000..10517953
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0008-Added-m64-abi-for-64-bit-target-descriptions.-set-m6.patch
@@ -0,0 +1,4104 @@
1From 815e641399628fcde8e13f925e4a6d3bc565a762 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 9 Nov 2021 16:19:17 +0530
4Subject: [PATCH 08/53] Added m64 abi for 64 bit target descriptions. set m64
5 abi for 64 bit elf.
6
7Conflicts:
8 gdb/microblaze-tdep.c
9 gdb/microblaze-tdep.h
10
11Signed-off-by: Aayush Misra <aayushm@amd.com>
12---
13 bfd/elf64-microblaze.c | 3810 ++++++++++++++++++++++++++++++++++++++++
14 gdb/microblaze-tdep.c | 160 +-
15 gdb/microblaze-tdep.h | 13 +-
16 3 files changed, 3975 insertions(+), 8 deletions(-)
17 create mode 100755 bfd/elf64-microblaze.c
18
19diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
20new file mode 100755
21index 00000000000..6cd9753a592
22--- /dev/null
23+++ b/bfd/elf64-microblaze.c
24@@ -0,0 +1,3810 @@
25+/* Xilinx MicroBlaze-specific support for 32-bit ELF
26+
27+ Copyright (C) 2009-2021 Free Software Foundation, Inc.
28+
29+ This file is part of BFD, the Binary File Descriptor library.
30+
31+ This program is free software; you can redistribute it and/or modify
32+ it under the terms of the GNU General Public License as published by
33+ the Free Software Foundation; either version 3 of the License, or
34+ (at your option) any later version.
35+
36+ This program is distributed in the hope that it will be useful,
37+ but WITHOUT ANY WARRANTY; without even the implied warranty of
38+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39+ GNU General Public License for more details.
40+
41+ You should have received a copy of the GNU General Public License
42+ along with this program; if not, write to the
43+ Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
44+ Boston, MA 02110-1301, USA. */
45+
46+
47+#include "sysdep.h"
48+#include "bfd.h"
49+#include "bfdlink.h"
50+#include "libbfd.h"
51+#include "elf-bfd.h"
52+#include "elf/microblaze.h"
53+#include <assert.h>
54+
55+#define USE_RELA /* Only USE_REL is actually significant, but this is
56+ here are a reminder... */
57+#define INST_WORD_SIZE 4
58+
59+static int ro_small_data_pointer = 0;
60+static int rw_small_data_pointer = 0;
61+
62+static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
63+
64+static reloc_howto_type microblaze_elf_howto_raw[] =
65+{
66+ /* This reloc does nothing. */
67+ HOWTO (R_MICROBLAZE_NONE, /* Type. */
68+ 0, /* Rightshift. */
69+ 0, /* Size. */
70+ 0, /* Bitsize. */
71+ false, /* PC_relative. */
72+ 0, /* Bitpos. */
73+ complain_overflow_dont, /* Complain on overflow. */
74+ NULL, /* Special Function. */
75+ "R_MICROBLAZE_NONE", /* Name. */
76+ false, /* Partial Inplace. */
77+ 0, /* Source Mask. */
78+ 0, /* Dest Mask. */
79+ false), /* PC relative offset? */
80+
81+ /* A standard 32 bit relocation. */
82+ HOWTO (R_MICROBLAZE_32, /* Type. */
83+ 0, /* Rightshift. */
84+ 4, /* Size. */
85+ 32, /* Bitsize. */
86+ false, /* PC_relative. */
87+ 0, /* Bitpos. */
88+ complain_overflow_bitfield, /* Complain on overflow. */
89+ bfd_elf_generic_reloc,/* Special Function. */
90+ "R_MICROBLAZE_32", /* Name. */
91+ false, /* Partial Inplace. */
92+ 0, /* Source Mask. */
93+ 0xffffffff, /* Dest Mask. */
94+ false), /* PC relative offset? */
95+
96+ /* A standard PCREL 32 bit relocation. */
97+ HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */
98+ 0, /* Rightshift. */
99+ 4, /* Size. */
100+ 32, /* Bitsize. */
101+ true, /* PC_relative. */
102+ 0, /* Bitpos. */
103+ complain_overflow_bitfield, /* Complain on overflow. */
104+ bfd_elf_generic_reloc,/* Special Function. */
105+ "R_MICROBLAZE_32_PCREL", /* Name. */
106+ true, /* Partial Inplace. */
107+ 0, /* Source Mask. */
108+ 0xffffffff, /* Dest Mask. */
109+ true), /* PC relative offset? */
110+
111+ /* A 64 bit PCREL relocation. Table-entry not really used. */
112+ HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */
113+ 0, /* Rightshift. */
114+ 4, /* Size. */
115+ 16, /* Bitsize. */
116+ true, /* PC_relative. */
117+ 0, /* Bitpos. */
118+ complain_overflow_dont, /* Complain on overflow. */
119+ bfd_elf_generic_reloc,/* Special Function. */
120+ "R_MICROBLAZE_64_PCREL", /* Name. */
121+ false, /* Partial Inplace. */
122+ 0, /* Source Mask. */
123+ 0x0000ffff, /* Dest Mask. */
124+ true), /* PC relative offset? */
125+
126+ /* The low half of a PCREL 32 bit relocation. */
127+ HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */
128+ 0, /* Rightshift. */
129+ 4, /* Size. */
130+ 16, /* Bitsize. */
131+ true, /* PC_relative. */
132+ 0, /* Bitpos. */
133+ complain_overflow_signed, /* Complain on overflow. */
134+ bfd_elf_generic_reloc, /* Special Function. */
135+ "R_MICROBLAZE_32_PCREL_LO", /* Name. */
136+ false, /* Partial Inplace. */
137+ 0, /* Source Mask. */
138+ 0x0000ffff, /* Dest Mask. */
139+ true), /* PC relative offset? */
140+
141+ HOWTO (R_MICROBLAZE_IMML_64, /* Type. */
142+ 0, /* Rightshift. */
143+ 4, /* Size (0 = byte, 1 = short, 2 = long). */
144+ 64, /* Bitsize. */
145+ false, /* PC_relative. */
146+ 0, /* Bitpos. */
147+ complain_overflow_dont, /* Complain on overflow. */
148+ bfd_elf_generic_reloc,/* Special Function. */
149+ "R_MICROBLAZE_IMML_64", /* Name. */
150+ false, /* Partial Inplace. */
151+ 0, /* Source Mask. */
152+ 0xffffffffffffff, /* Dest Mask. */
153+ false), /* PC relative offset? */
154+
155+ /* A 64 bit relocation. Table entry not really used. */
156+ HOWTO (R_MICROBLAZE_64, /* Type. */
157+ 0, /* Rightshift. */
158+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
159+ 16, /* Bitsize. */
160+ false, /* PC_relative. */
161+ 0, /* Bitpos. */
162+ complain_overflow_dont, /* Complain on overflow. */
163+ bfd_elf_generic_reloc,/* Special Function. */
164+ "R_MICROBLAZE_64", /* Name. */
165+ false, /* Partial Inplace. */
166+ 0, /* Source Mask. */
167+ 0x0000ffff, /* Dest Mask. */
168+ false), /* PC relative offset? */
169+
170+ /* The low half of a 32 bit relocation. */
171+ HOWTO (R_MICROBLAZE_32_LO, /* Type. */
172+ 0, /* Rightshift. */
173+ 4, /* Size. */
174+ 16, /* Bitsize. */
175+ false, /* PC_relative. */
176+ 0, /* Bitpos. */
177+ complain_overflow_signed, /* Complain on overflow. */
178+ bfd_elf_generic_reloc,/* Special Function. */
179+ "R_MICROBLAZE_32_LO", /* Name. */
180+ false, /* Partial Inplace. */
181+ 0, /* Source Mask. */
182+ 0x0000ffff, /* Dest Mask. */
183+ false), /* PC relative offset? */
184+
185+ /* Read-only small data section relocation. */
186+ HOWTO (R_MICROBLAZE_SRO32, /* Type. */
187+ 0, /* Rightshift. */
188+ 4, /* Size. */
189+ 16, /* Bitsize. */
190+ false, /* PC_relative. */
191+ 0, /* Bitpos. */
192+ complain_overflow_bitfield, /* Complain on overflow. */
193+ bfd_elf_generic_reloc,/* Special Function. */
194+ "R_MICROBLAZE_SRO32", /* Name. */
195+ false, /* Partial Inplace. */
196+ 0, /* Source Mask. */
197+ 0x0000ffff, /* Dest Mask. */
198+ false), /* PC relative offset? */
199+
200+ /* Read-write small data area relocation. */
201+ HOWTO (R_MICROBLAZE_SRW32, /* Type. */
202+ 0, /* Rightshift. */
203+ 4, /* Size. */
204+ 16, /* Bitsize. */
205+ false, /* PC_relative. */
206+ 0, /* Bitpos. */
207+ complain_overflow_bitfield, /* Complain on overflow. */
208+ bfd_elf_generic_reloc,/* Special Function. */
209+ "R_MICROBLAZE_SRW32", /* Name. */
210+ false, /* Partial Inplace. */
211+ 0, /* Source Mask. */
212+ 0x0000ffff, /* Dest Mask. */
213+ false), /* PC relative offset? */
214+
215+ /* This reloc does nothing. Used for relaxation. */
216+ HOWTO (R_MICROBLAZE_32_NONE, /* Type. */
217+ 0, /* Rightshift. */
218+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
219+ 32, /* Bitsize. */
220+ true, /* PC_relative. */
221+ 0, /* Bitpos. */
222+ complain_overflow_bitfield, /* Complain on overflow. */
223+ NULL, /* Special Function. */
224+ "R_MICROBLAZE_32_NONE",/* Name. */
225+ false, /* Partial Inplace. */
226+ 0, /* Source Mask. */
227+ 0, /* Dest Mask. */
228+ false), /* PC relative offset? */
229+
230+ /* This reloc does nothing. Used for relaxation. */
231+ HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
232+ 0, /* Rightshift. */
233+ 0, /* Size. */
234+ 0, /* Bitsize. */
235+ true, /* PC_relative. */
236+ 0, /* Bitpos. */
237+ complain_overflow_dont, /* Complain on overflow. */
238+ NULL, /* Special Function. */
239+ "R_MICROBLAZE_64_NONE",/* Name. */
240+ false, /* Partial Inplace. */
241+ 0, /* Source Mask. */
242+ 0, /* Dest Mask. */
243+ false), /* PC relative offset? */
244+
245+ /* Symbol Op Symbol relocation. */
246+ HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */
247+ 0, /* Rightshift. */
248+ 4, /* Size. */
249+ 32, /* Bitsize. */
250+ false, /* PC_relative. */
251+ 0, /* Bitpos. */
252+ complain_overflow_bitfield, /* Complain on overflow. */
253+ bfd_elf_generic_reloc,/* Special Function. */
254+ "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
255+ false, /* Partial Inplace. */
256+ 0, /* Source Mask. */
257+ 0xffffffff, /* Dest Mask. */
258+ false), /* PC relative offset? */
259+
260+ /* GNU extension to record C++ vtable hierarchy. */
261+ HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */
262+ 0, /* Rightshift. */
263+ 4, /* Size. */
264+ 0, /* Bitsize. */
265+ false, /* PC_relative. */
266+ 0, /* Bitpos. */
267+ complain_overflow_dont,/* Complain on overflow. */
268+ NULL, /* Special Function. */
269+ "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
270+ false, /* Partial Inplace. */
271+ 0, /* Source Mask. */
272+ 0, /* Dest Mask. */
273+ false), /* PC relative offset? */
274+
275+ /* GNU extension to record C++ vtable member usage. */
276+ HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */
277+ 0, /* Rightshift. */
278+ 4, /* Size. */
279+ 0, /* Bitsize. */
280+ false, /* PC_relative. */
281+ 0, /* Bitpos. */
282+ complain_overflow_dont,/* Complain on overflow. */
283+ _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */
284+ "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
285+ false, /* Partial Inplace. */
286+ 0, /* Source Mask. */
287+ 0, /* Dest Mask. */
288+ false), /* PC relative offset? */
289+
290+ /* A 64 bit GOTPC relocation. Table-entry not really used. */
291+ HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */
292+ 0, /* Rightshift. */
293+ 4, /* Size. */
294+ 16, /* Bitsize. */
295+ true, /* PC_relative. */
296+ 0, /* Bitpos. */
297+ complain_overflow_dont, /* Complain on overflow. */
298+ bfd_elf_generic_reloc, /* Special Function. */
299+ "R_MICROBLAZE_GOTPC_64", /* Name. */
300+ false, /* Partial Inplace. */
301+ 0, /* Source Mask. */
302+ 0x0000ffff, /* Dest Mask. */
303+ true), /* PC relative offset? */
304+
305+ /* A 64 bit TEXTPCREL relocation. Table-entry not really used. */
306+ HOWTO (R_MICROBLAZE_TEXTPCREL_64, /* Type. */
307+ 0, /* Rightshift. */
308+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
309+ 16, /* Bitsize. */
310+ true, /* PC_relative. */
311+ 0, /* Bitpos. */
312+ complain_overflow_dont, /* Complain on overflow. */
313+ bfd_elf_generic_reloc, /* Special Function. */
314+ "R_MICROBLAZE_TEXTPCREL_64", /* Name. */
315+ false, /* Partial Inplace. */
316+ 0, /* Source Mask. */
317+ 0x0000ffff, /* Dest Mask. */
318+ true), /* PC relative offset? */
319+
320+ /* A 64 bit GOTPC relocation. Table-entry not really used. */
321+ HOWTO (R_MICROBLAZE_GPC_64, /* Type. */
322+ 0, /* Rightshift. */
323+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
324+ 16, /* Bitsize. */
325+ true, /* PC_relative. */
326+ 0, /* Bitpos. */
327+ complain_overflow_dont, /* Complain on overflow. */
328+ bfd_elf_generic_reloc, /* Special Function. */
329+ "R_MICROBLAZE_GPC_64", /* Name. */
330+ false, /* Partial Inplace. */
331+ 0, /* Source Mask. */
332+ 0x0000ffff, /* Dest Mask. */
333+ true), /* PC relative offset? */
334+
335+ /* A 64 bit GOT relocation. Table-entry not really used. */
336+ HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
337+ 0, /* Rightshift. */
338+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
339+ 16, /* Bitsize. */
340+ false, /* PC_relative. */
341+ 0, /* Bitpos. */
342+ complain_overflow_dont, /* Complain on overflow. */
343+ bfd_elf_generic_reloc,/* Special Function. */
344+ "R_MICROBLAZE_GOT_64",/* Name. */
345+ false, /* Partial Inplace. */
346+ 0, /* Source Mask. */
347+ 0x0000ffff, /* Dest Mask. */
348+ false), /* PC relative offset? */
349+
350+ /* A 64 bit TEXTREL relocation. Table-entry not really used. */
351+ HOWTO (R_MICROBLAZE_TEXTREL_64, /* Type. */
352+ 0, /* Rightshift. */
353+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
354+ 16, /* Bitsize. */
355+ false, /* PC_relative. */
356+ 0, /* Bitpos. */
357+ complain_overflow_dont, /* Complain on overflow. */
358+ bfd_elf_generic_reloc,/* Special Function. */
359+ "R_MICROBLAZE_TEXTREL_64",/* Name. */
360+ false, /* Partial Inplace. */
361+ 0, /* Source Mask. */
362+ 0x0000ffff, /* Dest Mask. */
363+ false), /* PC relative offset? */
364+
365+ /* A 64 bit PLT relocation. Table-entry not really used. */
366+ HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
367+ 0, /* Rightshift. */
368+ 4, /* Size. */
369+ 16, /* Bitsize. */
370+ true, /* PC_relative. */
371+ 0, /* Bitpos. */
372+ complain_overflow_dont, /* Complain on overflow. */
373+ bfd_elf_generic_reloc,/* Special Function. */
374+ "R_MICROBLAZE_PLT_64",/* Name. */
375+ false, /* Partial Inplace. */
376+ 0, /* Source Mask. */
377+ 0x0000ffff, /* Dest Mask. */
378+ true), /* PC relative offset? */
379+
380+ /* Table-entry not really used. */
381+ HOWTO (R_MICROBLAZE_REL, /* Type. */
382+ 0, /* Rightshift. */
383+ 4, /* Size. */
384+ 16, /* Bitsize. */
385+ true, /* PC_relative. */
386+ 0, /* Bitpos. */
387+ complain_overflow_dont, /* Complain on overflow. */
388+ bfd_elf_generic_reloc,/* Special Function. */
389+ "R_MICROBLAZE_REL", /* Name. */
390+ false, /* Partial Inplace. */
391+ 0, /* Source Mask. */
392+ 0x0000ffff, /* Dest Mask. */
393+ true), /* PC relative offset? */
394+
395+ /* Table-entry not really used. */
396+ HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
397+ 0, /* Rightshift. */
398+ 4, /* Size. */
399+ 16, /* Bitsize. */
400+ true, /* PC_relative. */
401+ 0, /* Bitpos. */
402+ complain_overflow_dont, /* Complain on overflow. */
403+ bfd_elf_generic_reloc,/* Special Function. */
404+ "R_MICROBLAZE_JUMP_SLOT", /* Name. */
405+ false, /* Partial Inplace. */
406+ 0, /* Source Mask. */
407+ 0x0000ffff, /* Dest Mask. */
408+ true), /* PC relative offset? */
409+
410+ /* Table-entry not really used. */
411+ HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
412+ 0, /* Rightshift. */
413+ 4, /* Size. */
414+ 16, /* Bitsize. */
415+ true, /* PC_relative. */
416+ 0, /* Bitpos. */
417+ complain_overflow_dont, /* Complain on overflow. */
418+ bfd_elf_generic_reloc,/* Special Function. */
419+ "R_MICROBLAZE_GLOB_DAT", /* Name. */
420+ false, /* Partial Inplace. */
421+ 0, /* Source Mask. */
422+ 0x0000ffff, /* Dest Mask. */
423+ true), /* PC relative offset? */
424+
425+ /* A 64 bit GOT relative relocation. Table-entry not really used. */
426+ HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */
427+ 0, /* Rightshift. */
428+ 4, /* Size. */
429+ 16, /* Bitsize. */
430+ false, /* PC_relative. */
431+ 0, /* Bitpos. */
432+ complain_overflow_dont, /* Complain on overflow. */
433+ bfd_elf_generic_reloc,/* Special Function. */
434+ "R_MICROBLAZE_GOTOFF_64", /* Name. */
435+ false, /* Partial Inplace. */
436+ 0, /* Source Mask. */
437+ 0x0000ffff, /* Dest Mask. */
438+ false), /* PC relative offset? */
439+
440+ /* A 32 bit GOT relative relocation. Table-entry not really used. */
441+ HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */
442+ 0, /* Rightshift. */
443+ 4, /* Size. */
444+ 16, /* Bitsize. */
445+ false, /* PC_relative. */
446+ 0, /* Bitpos. */
447+ complain_overflow_dont, /* Complain on overflow. */
448+ bfd_elf_generic_reloc, /* Special Function. */
449+ "R_MICROBLAZE_GOTOFF_32", /* Name. */
450+ false, /* Partial Inplace. */
451+ 0, /* Source Mask. */
452+ 0x0000ffff, /* Dest Mask. */
453+ false), /* PC relative offset? */
454+
455+ /* COPY relocation. Table-entry not really used. */
456+ HOWTO (R_MICROBLAZE_COPY, /* Type. */
457+ 0, /* Rightshift. */
458+ 4, /* Size. */
459+ 16, /* Bitsize. */
460+ false, /* PC_relative. */
461+ 0, /* Bitpos. */
462+ complain_overflow_dont, /* Complain on overflow. */
463+ bfd_elf_generic_reloc,/* Special Function. */
464+ "R_MICROBLAZE_COPY", /* Name. */
465+ false, /* Partial Inplace. */
466+ 0, /* Source Mask. */
467+ 0x0000ffff, /* Dest Mask. */
468+ false), /* PC relative offset? */
469+
470+ /* Marker relocs for TLS. */
471+ HOWTO (R_MICROBLAZE_TLS,
472+ 0, /* rightshift */
473+ 2, /* size (0 = byte, 1 = short, 2 = long) */
474+ 32, /* bitsize */
475+ false, /* pc_relative */
476+ 0, /* bitpos */
477+ complain_overflow_dont, /* complain_on_overflow */
478+ bfd_elf_generic_reloc, /* special_function */
479+ "R_MICROBLAZE_TLS", /* name */
480+ false, /* partial_inplace */
481+ 0, /* src_mask */
482+ 0x0000ffff, /* dst_mask */
483+ false), /* pcrel_offset */
484+
485+ HOWTO (R_MICROBLAZE_TLSGD,
486+ 0, /* rightshift */
487+ 4, /* size */
488+ 32, /* bitsize */
489+ false, /* pc_relative */
490+ 0, /* bitpos */
491+ complain_overflow_dont, /* complain_on_overflow */
492+ bfd_elf_generic_reloc, /* special_function */
493+ "R_MICROBLAZE_TLSGD", /* name */
494+ false, /* partial_inplace */
495+ 0, /* src_mask */
496+ 0x0000ffff, /* dst_mask */
497+ false), /* pcrel_offset */
498+
499+ HOWTO (R_MICROBLAZE_TLSLD,
500+ 0, /* rightshift */
501+ 2, /* size (0 = byte, 1 = short, 2 = long) */
502+ 32, /* bitsize */
503+ false, /* pc_relative */
504+ 0, /* bitpos */
505+ complain_overflow_dont, /* complain_on_overflow */
506+ bfd_elf_generic_reloc, /* special_function */
507+ "R_MICROBLAZE_TLSLD", /* name */
508+ false, /* partial_inplace */
509+ 0, /* src_mask */
510+ 0x0000ffff, /* dst_mask */
511+ false), /* pcrel_offset */
512+
513+ /* Computes the load module index of the load module that contains the
514+ definition of its TLS sym. */
515+ HOWTO (R_MICROBLAZE_TLSDTPMOD32,
516+ 0, /* rightshift */
517+ 2, /* size (0 = byte, 1 = short, 2 = long) */
518+ 32, /* bitsize */
519+ false, /* pc_relative */
520+ 0, /* bitpos */
521+ complain_overflow_dont, /* complain_on_overflow */
522+ bfd_elf_generic_reloc, /* special_function */
523+ "R_MICROBLAZE_TLSDTPMOD32", /* name */
524+ false, /* partial_inplace */
525+ 0, /* src_mask */
526+ 0x0000ffff, /* dst_mask */
527+ false), /* pcrel_offset */
528+
529+ /* Computes a dtv-relative displacement, the difference between the value
530+ of sym+add and the base address of the thread-local storage block that
531+ contains the definition of sym, minus 0x8000. Used for initializing GOT */
532+ HOWTO (R_MICROBLAZE_TLSDTPREL32,
533+ 0, /* rightshift */
534+ 4, /* size */
535+ 32, /* bitsize */
536+ false, /* pc_relative */
537+ 0, /* bitpos */
538+ complain_overflow_dont, /* complain_on_overflow */
539+ bfd_elf_generic_reloc, /* special_function */
540+ "R_MICROBLAZE_TLSDTPREL32", /* name */
541+ false, /* partial_inplace */
542+ 0, /* src_mask */
543+ 0x0000ffff, /* dst_mask */
544+ false), /* pcrel_offset */
545+
546+ /* Computes a dtv-relative displacement, the difference between the value
547+ of sym+add and the base address of the thread-local storage block that
548+ contains the definition of sym, minus 0x8000. */
549+ HOWTO (R_MICROBLAZE_TLSDTPREL64,
550+ 0, /* rightshift */
551+ 4, /* size */
552+ 32, /* bitsize */
553+ false, /* pc_relative */
554+ 0, /* bitpos */
555+ complain_overflow_dont, /* complain_on_overflow */
556+ bfd_elf_generic_reloc, /* special_function */
557+ "R_MICROBLAZE_TLSDTPREL64", /* name */
558+ false, /* partial_inplace */
559+ 0, /* src_mask */
560+ 0x0000ffff, /* dst_mask */
561+ false), /* pcrel_offset */
562+
563+ /* Computes a tp-relative displacement, the difference between the value of
564+ sym+add and the value of the thread pointer (r13). */
565+ HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
566+ 0, /* rightshift */
567+ 4, /* size */
568+ 32, /* bitsize */
569+ false, /* pc_relative */
570+ 0, /* bitpos */
571+ complain_overflow_dont, /* complain_on_overflow */
572+ bfd_elf_generic_reloc, /* special_function */
573+ "R_MICROBLAZE_TLSGOTTPREL32", /* name */
574+ false, /* partial_inplace */
575+ 0, /* src_mask */
576+ 0x0000ffff, /* dst_mask */
577+ false), /* pcrel_offset */
578+
579+ /* Computes a tp-relative displacement, the difference between the value of
580+ sym+add and the value of the thread pointer (r13). */
581+ HOWTO (R_MICROBLAZE_TLSTPREL32,
582+ 0, /* rightshift */
583+ 4, /* size */
584+ 32, /* bitsize */
585+ false, /* pc_relative */
586+ 0, /* bitpos */
587+ complain_overflow_dont, /* complain_on_overflow */
588+ bfd_elf_generic_reloc, /* special_function */
589+ "R_MICROBLAZE_TLSTPREL32", /* name */
590+ false, /* partial_inplace */
591+ 0, /* src_mask */
592+ 0x0000ffff, /* dst_mask */
593+ false), /* pcrel_offset */
594+
595+};
596+
597+#ifndef NUM_ELEM
598+#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
599+#endif
600+
601+/* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
602+
603+static void
604+microblaze_elf_howto_init (void)
605+{
606+ unsigned int i;
607+
608+ for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
609+ {
610+ unsigned int type;
611+
612+ type = microblaze_elf_howto_raw[i].type;
613+
614+ BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
615+
616+ microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
617+ }
618+}
619+
620+static reloc_howto_type *
621+microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
622+ bfd_reloc_code_real_type code)
623+{
624+ enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
625+
626+ switch (code)
627+ {
628+ case BFD_RELOC_NONE:
629+ microblaze_reloc = R_MICROBLAZE_NONE;
630+ break;
631+ case BFD_RELOC_MICROBLAZE_32_NONE:
632+ microblaze_reloc = R_MICROBLAZE_32_NONE;
633+ break;
634+ case BFD_RELOC_MICROBLAZE_64_NONE:
635+ microblaze_reloc = R_MICROBLAZE_64_NONE;
636+ break;
637+ case BFD_RELOC_32:
638+ microblaze_reloc = R_MICROBLAZE_32;
639+ break;
640+ /* RVA is treated the same as 64 */
641+ case BFD_RELOC_RVA:
642+ microblaze_reloc = R_MICROBLAZE_IMML_64;
643+ break;
644+ case BFD_RELOC_32_PCREL:
645+ microblaze_reloc = R_MICROBLAZE_32_PCREL;
646+ break;
647+ case BFD_RELOC_64_PCREL:
648+ microblaze_reloc = R_MICROBLAZE_64_PCREL;
649+ break;
650+ case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
651+ microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
652+ break;
653+ case BFD_RELOC_64:
654+ microblaze_reloc = R_MICROBLAZE_64;
655+ break;
656+ case BFD_RELOC_MICROBLAZE_32_LO:
657+ microblaze_reloc = R_MICROBLAZE_32_LO;
658+ break;
659+ case BFD_RELOC_MICROBLAZE_32_ROSDA:
660+ microblaze_reloc = R_MICROBLAZE_SRO32;
661+ break;
662+ case BFD_RELOC_MICROBLAZE_32_RWSDA:
663+ microblaze_reloc = R_MICROBLAZE_SRW32;
664+ break;
665+ case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
666+ microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
667+ break;
668+ case BFD_RELOC_VTABLE_INHERIT:
669+ microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
670+ break;
671+ case BFD_RELOC_VTABLE_ENTRY:
672+ microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
673+ break;
674+ case BFD_RELOC_MICROBLAZE_EA64:
675+ microblaze_reloc = R_MICROBLAZE_IMML_64;
676+ break;
677+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
678+ microblaze_reloc = R_MICROBLAZE_GOTPC_64;
679+ break;
680+ case BFD_RELOC_MICROBLAZE_64_GPC:
681+ microblaze_reloc = R_MICROBLAZE_GPC_64;
682+ break;
683+ case BFD_RELOC_MICROBLAZE_64_GOT:
684+ microblaze_reloc = R_MICROBLAZE_GOT_64;
685+ break;
686+ case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
687+ microblaze_reloc = R_MICROBLAZE_TEXTPCREL_64;
688+ break;
689+ case BFD_RELOC_MICROBLAZE_64_TEXTREL:
690+ microblaze_reloc = R_MICROBLAZE_TEXTREL_64;
691+ break;
692+ case BFD_RELOC_MICROBLAZE_64_PLT:
693+ microblaze_reloc = R_MICROBLAZE_PLT_64;
694+ break;
695+ case BFD_RELOC_MICROBLAZE_64_GOTOFF:
696+ microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
697+ break;
698+ case BFD_RELOC_MICROBLAZE_32_GOTOFF:
699+ microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
700+ break;
701+ case BFD_RELOC_MICROBLAZE_64_TLSGD:
702+ microblaze_reloc = R_MICROBLAZE_TLSGD;
703+ break;
704+ case BFD_RELOC_MICROBLAZE_64_TLSLD:
705+ microblaze_reloc = R_MICROBLAZE_TLSLD;
706+ break;
707+ case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
708+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
709+ break;
710+ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
711+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
712+ break;
713+ case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
714+ microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
715+ break;
716+ case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
717+ microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
718+ break;
719+ case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
720+ microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
721+ break;
722+ case BFD_RELOC_MICROBLAZE_COPY:
723+ microblaze_reloc = R_MICROBLAZE_COPY;
724+ break;
725+ default:
726+ return (reloc_howto_type *) NULL;
727+ }
728+
729+ if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
730+ /* Initialize howto table if needed. */
731+ microblaze_elf_howto_init ();
732+
733+ return microblaze_elf_howto_table [(int) microblaze_reloc];
734+};
735+
736+static reloc_howto_type *
737+microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
738+ const char *r_name)
739+{
740+ unsigned int i;
741+
742+ for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
743+ if (microblaze_elf_howto_raw[i].name != NULL
744+ && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
745+ return &microblaze_elf_howto_raw[i];
746+
747+ return NULL;
748+}
749+
750+/* Set the howto pointer for a RCE ELF reloc. */
751+
752+static bool
753+microblaze_elf_info_to_howto (bfd * abfd,
754+ arelent * cache_ptr,
755+ Elf_Internal_Rela * dst)
756+{
757+ unsigned int r_type;
758+
759+ if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
760+ /* Initialize howto table if needed. */
761+ microblaze_elf_howto_init ();
762+
763+ r_type = ELF64_R_TYPE (dst->r_info);
764+ if (r_type >= R_MICROBLAZE_max)
765+ {
766+ /* xgettext:c-format */
767+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
768+ abfd, r_type);
769+ bfd_set_error (bfd_error_bad_value);
770+ return false;
771+ }
772+
773+ cache_ptr->howto = microblaze_elf_howto_table [r_type];
774+ return true;
775+}
776+
777+struct _microblaze_elf_section_data
778+{
779+ struct bfd_elf_section_data elf;
780+ /* Count of used relaxation table entries. */
781+ size_t relax_count;
782+ /* Relaxation table. */
783+ struct relax_table *relax;
784+};
785+
786+#define microblaze_elf_section_data(sec) \
787+ ((struct _microblaze_elf_section_data *) elf_section_data (sec))
788+
789+static bool
790+microblaze_elf_new_section_hook (bfd *abfd, asection *sec)
791+{
792+ if (!sec->used_by_bfd)
793+ {
794+ struct _microblaze_elf_section_data *sdata;
795+ size_t amt = sizeof (*sdata);
796+
797+ sdata = bfd_zalloc (abfd, amt);
798+ if (sdata == NULL)
799+ return false;
800+ sec->used_by_bfd = sdata;
801+ }
802+
803+ return _bfd_elf_new_section_hook (abfd, sec);
804+}
805+
806+/* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
807+
808+static bool
809+microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
810+{
811+ if (name[0] == 'L' && name[1] == '.')
812+ return true;
813+
814+ if (name[0] == '$' && name[1] == 'L')
815+ return true;
816+
817+ /* With gcc, the labels go back to starting with '.', so we accept
818+ the generic ELF local label syntax as well. */
819+ return _bfd_elf_is_local_label_name (abfd, name);
820+}
821+
822+/* The microblaze linker (like many others) needs to keep track of
823+ the number of relocs that it decides to copy as dynamic relocs in
824+ check_relocs for each symbol. This is so that it can later discard
825+ them if they are found to be unnecessary. We store the information
826+ in a field extending the regular ELF linker hash table. */
827+
828+struct elf64_mb_dyn_relocs
829+{
830+ struct elf64_mb_dyn_relocs *next;
831+
832+ /* The input section of the reloc. */
833+ asection *sec;
834+
835+ /* Total number of relocs copied for the input section. */
836+ bfd_size_type count;
837+
838+ /* Number of pc-relative relocs copied for the input section. */
839+ bfd_size_type pc_count;
840+};
841+
842+/* ELF linker hash entry. */
843+
844+struct elf64_mb_link_hash_entry
845+{
846+ struct elf_link_hash_entry elf;
847+
848+ /* Track dynamic relocs copied for this symbol. */
849+ struct elf64_mb_dyn_relocs *dyn_relocs;
850+
851+ /* TLS Reference Types for the symbol; Updated by check_relocs */
852+#define TLS_GD 1 /* GD reloc. */
853+#define TLS_LD 2 /* LD reloc. */
854+#define TLS_TPREL 4 /* TPREL reloc, => IE. */
855+#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
856+#define TLS_TLS 16 /* Any TLS reloc. */
857+ unsigned char tls_mask;
858+
859+};
860+
861+#define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
862+#define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
863+#define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
864+#define IS_TLS_NONE(x) (x == 0)
865+
866+#define elf64_mb_hash_entry(ent) ((struct elf64_mb_link_hash_entry *)(ent))
867+
868+/* ELF linker hash table. */
869+
870+struct elf64_mb_link_hash_table
871+{
872+ struct elf_link_hash_table elf;
873+
874+ /* Short-cuts to get to dynamic linker sections. */
875+ asection *sgot;
876+ asection *sgotplt;
877+ asection *srelgot;
878+ asection *splt;
879+ asection *srelplt;
880+ asection *sdynbss;
881+ asection *srelbss;
882+
883+ /* Small local sym to section mapping cache. */
884+ struct sym_cache sym_sec;
885+
886+ /* TLS Local Dynamic GOT Entry */
887+ union {
888+ bfd_signed_vma refcount;
889+ bfd_vma offset;
890+ } tlsld_got;
891+};
892+
893+/* Nonzero if this section has TLS related relocations. */
894+#define has_tls_reloc sec_flg0
895+
896+/* Get the ELF linker hash table from a link_info structure. */
897+
898+#define elf64_mb_hash_table(p) \
899+ ((is_elf_hash_table ((p)->hash) \
900+ && elf_hash_table_id (elf_hash_table (p)) == MICROBLAZE_ELF_DATA) \
901+ ? (struct elf64_mb_link_hash_table *) (p)->hash : NULL)
902+
903+/* Create an entry in a microblaze ELF linker hash table. */
904+
905+static struct bfd_hash_entry *
906+link_hash_newfunc (struct bfd_hash_entry *entry,
907+ struct bfd_hash_table *table,
908+ const char *string)
909+{
910+ /* Allocate the structure if it has not already been allocated by a
911+ subclass. */
912+ if (entry == NULL)
913+ {
914+ entry = bfd_hash_allocate (table,
915+ sizeof (struct elf64_mb_link_hash_entry));
916+ if (entry == NULL)
917+ return entry;
918+ }
919+
920+ /* Call the allocation method of the superclass. */
921+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
922+ if (entry != NULL)
923+ {
924+ struct elf64_mb_link_hash_entry *eh;
925+
926+ eh = (struct elf64_mb_link_hash_entry *) entry;
927+ eh->tls_mask = 0;
928+ }
929+
930+ return entry;
931+}
932+
933+/* Create a mb ELF linker hash table. */
934+
935+static struct bfd_link_hash_table *
936+microblaze_elf_link_hash_table_create (bfd *abfd)
937+{
938+ struct elf64_mb_link_hash_table *ret;
939+ size_t amt = sizeof (struct elf64_mb_link_hash_table);
940+
941+ ret = (struct elf64_mb_link_hash_table *) bfd_zmalloc (amt);
942+ if (ret == NULL)
943+ return NULL;
944+
945+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
946+ sizeof (struct elf64_mb_link_hash_entry),
947+ MICROBLAZE_ELF_DATA))
948+ {
949+ free (ret);
950+ return NULL;
951+ }
952+
953+ return &ret->elf.root;
954+}
955+
956+/* Set the values of the small data pointers. */
957+
958+static void
959+microblaze_elf_final_sdp (struct bfd_link_info *info)
960+{
961+ struct bfd_link_hash_entry *h;
962+
963+ h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, false, false, true);
964+ if (h != (struct bfd_link_hash_entry *) NULL
965+ && h->type == bfd_link_hash_defined)
966+ ro_small_data_pointer = (h->u.def.value
967+ + h->u.def.section->output_section->vma
968+ + h->u.def.section->output_offset);
969+
970+ h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, false, false, true);
971+ if (h != (struct bfd_link_hash_entry *) NULL
972+ && h->type == bfd_link_hash_defined)
973+ rw_small_data_pointer = (h->u.def.value
974+ + h->u.def.section->output_section->vma
975+ + h->u.def.section->output_offset);
976+}
977+
978+static bfd_vma
979+dtprel_base (struct bfd_link_info *info)
980+{
981+ /* If tls_sec is NULL, we should have signalled an error already. */
982+ if (elf_hash_table (info)->tls_sec == NULL)
983+ return 0;
984+ return elf_hash_table (info)->tls_sec->vma;
985+}
986+
987+/* The size of the thread control block. */
988+#define TCB_SIZE 8
989+
990+/* Output a simple dynamic relocation into SRELOC. */
991+
992+static void
993+microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
994+ asection *sreloc,
995+ unsigned long reloc_index,
996+ unsigned long indx,
997+ int r_type,
998+ bfd_vma offset,
999+ bfd_vma addend)
1000+{
1001+
1002+ Elf_Internal_Rela rel;
1003+
1004+ rel.r_info = ELF64_R_INFO (indx, r_type);
1005+ rel.r_offset = offset;
1006+ rel.r_addend = addend;
1007+
1008+ bfd_elf64_swap_reloca_out (output_bfd, &rel,
1009+ (sreloc->contents + reloc_index * sizeof (Elf64_External_Rela)));
1010+}
1011+
1012+/* This code is taken from elf64-m32r.c
1013+ There is some attempt to make this function usable for many architectures,
1014+ both USE_REL and USE_RELA ['twould be nice if such a critter existed],
1015+ if only to serve as a learning tool.
1016+
1017+ The RELOCATE_SECTION function is called by the new ELF backend linker
1018+ to handle the relocations for a section.
1019+
1020+ The relocs are always passed as Rela structures; if the section
1021+ actually uses Rel structures, the r_addend field will always be
1022+ zero.
1023+
1024+ This function is responsible for adjust the section contents as
1025+ necessary, and (if using Rela relocs and generating a
1026+ relocatable output file) adjusting the reloc addend as
1027+ necessary.
1028+
1029+ This function does not have to worry about setting the reloc
1030+ address or the reloc symbol index.
1031+
1032+ LOCAL_SYMS is a pointer to the swapped in local symbols.
1033+
1034+ LOCAL_SECTIONS is an array giving the section in the input file
1035+ corresponding to the st_shndx field of each local symbol.
1036+
1037+ The global hash table entry for the global symbols can be found
1038+ via elf_sym_hashes (input_bfd).
1039+
1040+ When generating relocatable output, this function must handle
1041+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
1042+ going to be the section symbol corresponding to the output
1043+ section, which means that the addend must be adjusted
1044+ accordingly. */
1045+
1046+static int
1047+microblaze_elf_relocate_section (bfd *output_bfd,
1048+ struct bfd_link_info *info,
1049+ bfd *input_bfd,
1050+ asection *input_section,
1051+ bfd_byte *contents,
1052+ Elf_Internal_Rela *relocs,
1053+ Elf_Internal_Sym *local_syms,
1054+ asection **local_sections)
1055+{
1056+ struct elf64_mb_link_hash_table *htab;
1057+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1058+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
1059+ Elf_Internal_Rela *rel, *relend;
1060+ int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
1061+ /* Assume success. */
1062+ bool ret = true;
1063+ asection *sreloc;
1064+ bfd_vma *local_got_offsets;
1065+ unsigned int tls_type;
1066+
1067+ if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
1068+ microblaze_elf_howto_init ();
1069+
1070+ htab = elf64_mb_hash_table (info);
1071+ if (htab == NULL)
1072+ return false;
1073+
1074+ local_got_offsets = elf_local_got_offsets (input_bfd);
1075+
1076+ sreloc = elf_section_data (input_section)->sreloc;
1077+
1078+ rel = relocs;
1079+ relend = relocs + input_section->reloc_count;
1080+ for (; rel < relend; rel++)
1081+ {
1082+ int r_type;
1083+ reloc_howto_type *howto;
1084+ unsigned long r_symndx;
1085+ bfd_vma addend = rel->r_addend;
1086+ bfd_vma offset = rel->r_offset;
1087+ struct elf_link_hash_entry *h;
1088+ Elf_Internal_Sym *sym;
1089+ asection *sec;
1090+ const char *sym_name;
1091+ bfd_reloc_status_type r = bfd_reloc_ok;
1092+ const char *errmsg = NULL;
1093+ bool unresolved_reloc = false;
1094+
1095+ h = NULL;
1096+ r_type = ELF64_R_TYPE (rel->r_info);
1097+ tls_type = 0;
1098+
1099+ if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
1100+ {
1101+ /* xgettext:c-format */
1102+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1103+ input_bfd, (int) r_type);
1104+ bfd_set_error (bfd_error_bad_value);
1105+ ret = false;
1106+ continue;
1107+ }
1108+
1109+ howto = microblaze_elf_howto_table[r_type];
1110+ r_symndx = ELF64_R_SYM (rel->r_info);
1111+
1112+ if (bfd_link_relocatable (info))
1113+ {
1114+ /* This is a relocatable link. We don't have to change
1115+ anything, unless the reloc is against a section symbol,
1116+ in which case we have to adjust according to where the
1117+ section symbol winds up in the output section. */
1118+ sec = NULL;
1119+ if (r_symndx >= symtab_hdr->sh_info)
1120+ /* External symbol. */
1121+ continue;
1122+
1123+ /* Local symbol. */
1124+ sym = local_syms + r_symndx;
1125+ sym_name = "<local symbol>";
1126+ /* STT_SECTION: symbol is associated with a section. */
1127+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
1128+ /* Symbol isn't associated with a section. Nothing to do. */
1129+ continue;
1130+
1131+ sec = local_sections[r_symndx];
1132+ addend += sec->output_offset + sym->st_value;
1133+#ifndef USE_REL
1134+ /* This can't be done for USE_REL because it doesn't mean anything
1135+ and elf_link_input_bfd asserts this stays zero. */
1136+ /* rel->r_addend = addend; */
1137+#endif
1138+
1139+#ifndef USE_REL
1140+ /* Addends are stored with relocs. We're done. */
1141+ continue;
1142+#else /* USE_REL */
1143+ /* If partial_inplace, we need to store any additional addend
1144+ back in the section. */
1145+ if (!howto->partial_inplace)
1146+ continue;
1147+ /* ??? Here is a nice place to call a special_function like handler. */
1148+ r = _bfd_relocate_contents (howto, input_bfd, addend,
1149+ contents + offset);
1150+#endif /* USE_REL */
1151+ }
1152+ else
1153+ {
1154+ bfd_vma relocation;
1155+ bool resolved_to_zero;
1156+
1157+ /* This is a final link. */
1158+ sym = NULL;
1159+ sec = NULL;
1160+ unresolved_reloc = false;
1161+
1162+ if (r_symndx < symtab_hdr->sh_info)
1163+ {
1164+ /* Local symbol. */
1165+ sym = local_syms + r_symndx;
1166+ sec = local_sections[r_symndx];
1167+ if (sec == 0)
1168+ continue;
1169+ sym_name = "<local symbol>";
1170+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1171+ /* r_addend may have changed if the reference section was
1172+ a merge section. */
1173+ addend = rel->r_addend;
1174+ }
1175+ else
1176+ {
1177+ /* External symbol. */
1178+ bool warned ATTRIBUTE_UNUSED;
1179+ bool ignored ATTRIBUTE_UNUSED;
1180+
1181+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1182+ r_symndx, symtab_hdr, sym_hashes,
1183+ h, sec, relocation,
1184+ unresolved_reloc, warned, ignored);
1185+ sym_name = h->root.root.string;
1186+ }
1187+
1188+ /* Sanity check the address. */
1189+ if (offset > bfd_get_section_limit (input_bfd, input_section))
1190+ {
1191+ r = bfd_reloc_outofrange;
1192+ goto check_reloc;
1193+ }
1194+
1195+ resolved_to_zero = (h != NULL
1196+ && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
1197+
1198+ switch ((int) r_type)
1199+ {
1200+ case (int) R_MICROBLAZE_SRO32 :
1201+ {
1202+ const char *name;
1203+
1204+ /* Only relocate if the symbol is defined. */
1205+ if (sec)
1206+ {
1207+ name = bfd_section_name (sec);
1208+
1209+ if (strcmp (name, ".sdata2") == 0
1210+ || strcmp (name, ".sbss2") == 0)
1211+ {
1212+ if (ro_small_data_pointer == 0)
1213+ microblaze_elf_final_sdp (info);
1214+ if (ro_small_data_pointer == 0)
1215+ {
1216+ ret = false;
1217+ r = bfd_reloc_undefined;
1218+ goto check_reloc;
1219+ }
1220+
1221+ /* At this point `relocation' contains the object's
1222+ address. */
1223+ relocation -= ro_small_data_pointer;
1224+ /* Now it contains the offset from _SDA2_BASE_. */
1225+ r = _bfd_final_link_relocate (howto, input_bfd,
1226+ input_section,
1227+ contents, offset,
1228+ relocation, addend);
1229+ }
1230+ else
1231+ {
1232+ _bfd_error_handler
1233+ /* xgettext:c-format */
1234+ (_("%pB: the target (%s) of an %s relocation"
1235+ " is in the wrong section (%pA)"),
1236+ input_bfd,
1237+ sym_name,
1238+ microblaze_elf_howto_table[(int) r_type]->name,
1239+ sec);
1240+ /*bfd_set_error (bfd_error_bad_value); ??? why? */
1241+ ret = false;
1242+ continue;
1243+ }
1244+ }
1245+ }
1246+ break;
1247+
1248+ case (int) R_MICROBLAZE_SRW32 :
1249+ {
1250+ const char *name;
1251+
1252+ /* Only relocate if the symbol is defined. */
1253+ if (sec)
1254+ {
1255+ name = bfd_section_name (sec);
1256+
1257+ if (strcmp (name, ".sdata") == 0
1258+ || strcmp (name, ".sbss") == 0)
1259+ {
1260+ if (rw_small_data_pointer == 0)
1261+ microblaze_elf_final_sdp (info);
1262+ if (rw_small_data_pointer == 0)
1263+ {
1264+ ret = false;
1265+ r = bfd_reloc_undefined;
1266+ goto check_reloc;
1267+ }
1268+
1269+ /* At this point `relocation' contains the object's
1270+ address. */
1271+ relocation -= rw_small_data_pointer;
1272+ /* Now it contains the offset from _SDA_BASE_. */
1273+ r = _bfd_final_link_relocate (howto, input_bfd,
1274+ input_section,
1275+ contents, offset,
1276+ relocation, addend);
1277+ }
1278+ else
1279+ {
1280+ _bfd_error_handler
1281+ /* xgettext:c-format */
1282+ (_("%pB: the target (%s) of an %s relocation"
1283+ " is in the wrong section (%pA)"),
1284+ input_bfd,
1285+ sym_name,
1286+ microblaze_elf_howto_table[(int) r_type]->name,
1287+ sec);
1288+ /*bfd_set_error (bfd_error_bad_value); ??? why? */
1289+ ret = false;
1290+ continue;
1291+ }
1292+ }
1293+ }
1294+ break;
1295+
1296+ case (int) R_MICROBLAZE_32_SYM_OP_SYM:
1297+ break; /* Do nothing. */
1298+
1299+ case (int) R_MICROBLAZE_GOTPC_64:
1300+ relocation = (htab->elf.sgotplt->output_section->vma
1301+ + htab->elf.sgotplt->output_offset);
1302+ relocation -= (input_section->output_section->vma
1303+ + input_section->output_offset
1304+ + offset + INST_WORD_SIZE);
1305+ relocation += addend;
1306+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1307+ contents + offset + endian);
1308+ bfd_put_16 (input_bfd, relocation & 0xffff,
1309+ contents + offset + endian + INST_WORD_SIZE);
1310+ break;
1311+
1312+ case (int) R_MICROBLAZE_TEXTPCREL_64:
1313+ relocation = input_section->output_section->vma;
1314+ relocation -= (input_section->output_section->vma
1315+ + input_section->output_offset
1316+ + offset + INST_WORD_SIZE);
1317+ relocation += addend;
1318+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1319+ contents + offset + endian);
1320+ bfd_put_16 (input_bfd, relocation & 0xffff,
1321+ contents + offset + endian + INST_WORD_SIZE);
1322+ break;
1323+
1324+ case (int) R_MICROBLAZE_PLT_64:
1325+ {
1326+ bfd_vma immediate;
1327+ if (htab->elf.splt != NULL && h != NULL
1328+ && h->plt.offset != (bfd_vma) -1)
1329+ {
1330+ relocation = (htab->elf.splt->output_section->vma
1331+ + htab->elf.splt->output_offset
1332+ + h->plt.offset);
1333+ unresolved_reloc = false;
1334+ immediate = relocation - (input_section->output_section->vma
1335+ + input_section->output_offset
1336+ + offset + INST_WORD_SIZE);
1337+ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1338+ contents + offset + endian);
1339+ bfd_put_16 (input_bfd, immediate & 0xffff,
1340+ contents + offset + endian + INST_WORD_SIZE);
1341+ }
1342+ else
1343+ {
1344+ relocation -= (input_section->output_section->vma
1345+ + input_section->output_offset
1346+ + offset + INST_WORD_SIZE);
1347+ immediate = relocation;
1348+ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1349+ contents + offset + endian);
1350+ bfd_put_16 (input_bfd, immediate & 0xffff,
1351+ contents + offset + endian + INST_WORD_SIZE);
1352+ }
1353+ break;
1354+ }
1355+
1356+ case (int) R_MICROBLAZE_TLSGD:
1357+ tls_type = (TLS_TLS | TLS_GD);
1358+ goto dogot;
1359+ case (int) R_MICROBLAZE_TLSLD:
1360+ tls_type = (TLS_TLS | TLS_LD);
1361+ /* Fall through. */
1362+ dogot:
1363+ case (int) R_MICROBLAZE_GOT_64:
1364+ {
1365+ bfd_vma *offp;
1366+ bfd_vma off, off2;
1367+ unsigned long indx;
1368+ bfd_vma static_value;
1369+
1370+ bool need_relocs = false;
1371+ if (htab->elf.sgot == NULL)
1372+ abort ();
1373+
1374+ indx = 0;
1375+ offp = NULL;
1376+
1377+ /* 1. Identify GOT Offset;
1378+ 2. Compute Static Values
1379+ 3. Process Module Id, Process Offset
1380+ 4. Fixup Relocation with GOT offset value. */
1381+
1382+ /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1383+ if (IS_TLS_LD (tls_type))
1384+ offp = &htab->tlsld_got.offset;
1385+ else if (h != NULL)
1386+ {
1387+ if (htab->elf.sgotplt != NULL
1388+ && h->got.offset != (bfd_vma) -1)
1389+ offp = &h->got.offset;
1390+ else
1391+ abort ();
1392+ }
1393+ else
1394+ {
1395+ if (local_got_offsets == NULL)
1396+ abort ();
1397+ offp = &local_got_offsets[r_symndx];
1398+ }
1399+
1400+ if (!offp)
1401+ abort ();
1402+
1403+ off = (*offp) & ~1;
1404+ off2 = off;
1405+
1406+ if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
1407+ off2 = off + 4;
1408+
1409+ /* Symbol index to use for relocs */
1410+ if (h != NULL)
1411+ {
1412+ bool dyn =
1413+ elf_hash_table (info)->dynamic_sections_created;
1414+
1415+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
1416+ bfd_link_pic (info),
1417+ h)
1418+ && (!bfd_link_pic (info)
1419+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
1420+ indx = h->dynindx;
1421+ }
1422+
1423+ /* Need to generate relocs ? */
1424+ if ((bfd_link_pic (info) || indx != 0)
1425+ && (h == NULL
1426+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1427+ || h->root.type != bfd_link_hash_undefweak))
1428+ need_relocs = true;
1429+
1430+ /* 2. Compute/Emit Static value of r-expression */
1431+ static_value = relocation + addend;
1432+
1433+ /* 3. Process module-id and offset */
1434+ if (! ((*offp) & 1) )
1435+ {
1436+ bfd_vma got_offset;
1437+
1438+ got_offset = (htab->elf.sgot->output_section->vma
1439+ + htab->elf.sgot->output_offset
1440+ + off);
1441+
1442+ /* Process module-id */
1443+ if (IS_TLS_LD(tls_type))
1444+ {
1445+ if (! bfd_link_pic (info))
1446+ bfd_put_32 (output_bfd, 1,
1447+ htab->elf.sgot->contents + off);
1448+ else
1449+ microblaze_elf_output_dynamic_relocation
1450+ (output_bfd,
1451+ htab->elf.srelgot,
1452+ htab->elf.srelgot->reloc_count++,
1453+ /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
1454+ got_offset, 0);
1455+ }
1456+ else if (IS_TLS_GD(tls_type))
1457+ {
1458+ if (! need_relocs)
1459+ bfd_put_32 (output_bfd, 1,
1460+ htab->elf.sgot->contents + off);
1461+ else
1462+ microblaze_elf_output_dynamic_relocation
1463+ (output_bfd,
1464+ htab->elf.srelgot,
1465+ htab->elf.srelgot->reloc_count++,
1466+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
1467+ got_offset, indx ? 0 : static_value);
1468+ }
1469+
1470+ /* Process Offset */
1471+ if (htab->elf.srelgot == NULL)
1472+ abort ();
1473+
1474+ got_offset = (htab->elf.sgot->output_section->vma
1475+ + htab->elf.sgot->output_offset
1476+ + off2);
1477+ if (IS_TLS_LD(tls_type))
1478+ {
1479+ /* For LD, offset should be 0 */
1480+ *offp |= 1;
1481+ bfd_put_32 (output_bfd, 0,
1482+ htab->elf.sgot->contents + off2);
1483+ }
1484+ else if (IS_TLS_GD(tls_type))
1485+ {
1486+ *offp |= 1;
1487+ static_value -= dtprel_base(info);
1488+ if (need_relocs)
1489+ microblaze_elf_output_dynamic_relocation
1490+ (output_bfd,
1491+ htab->elf.srelgot,
1492+ htab->elf.srelgot->reloc_count++,
1493+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
1494+ got_offset, indx ? 0 : static_value);
1495+ else
1496+ bfd_put_32 (output_bfd, static_value,
1497+ htab->elf.sgot->contents + off2);
1498+ }
1499+ else
1500+ {
1501+ bfd_put_32 (output_bfd, static_value,
1502+ htab->elf.sgot->contents + off2);
1503+
1504+ /* Relocs for dyn symbols generated by
1505+ finish_dynamic_symbols */
1506+ if (bfd_link_pic (info) && h == NULL)
1507+ {
1508+ *offp |= 1;
1509+ microblaze_elf_output_dynamic_relocation
1510+ (output_bfd,
1511+ htab->elf.srelgot,
1512+ htab->elf.srelgot->reloc_count++,
1513+ /* symindex= */ indx, R_MICROBLAZE_REL,
1514+ got_offset, static_value);
1515+ }
1516+ }
1517+ }
1518+
1519+ /* 4. Fixup Relocation with GOT offset value
1520+ Compute relative address of GOT entry for applying
1521+ the current relocation */
1522+ relocation = htab->elf.sgot->output_section->vma
1523+ + htab->elf.sgot->output_offset
1524+ + off
1525+ - htab->elf.sgotplt->output_section->vma
1526+ - htab->elf.sgotplt->output_offset;
1527+
1528+ /* Apply Current Relocation */
1529+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1530+ contents + offset + endian);
1531+ bfd_put_16 (input_bfd, relocation & 0xffff,
1532+ contents + offset + endian + INST_WORD_SIZE);
1533+
1534+ unresolved_reloc = false;
1535+ break;
1536+ }
1537+
1538+ case (int) R_MICROBLAZE_GOTOFF_64:
1539+ {
1540+ bfd_vma immediate;
1541+ unsigned short lo, high;
1542+ relocation += addend;
1543+ relocation -= (htab->elf.sgotplt->output_section->vma
1544+ + htab->elf.sgotplt->output_offset);
1545+ /* Write this value into correct location. */
1546+ immediate = relocation;
1547+ lo = immediate & 0x0000ffff;
1548+ high = (immediate >> 16) & 0x0000ffff;
1549+ bfd_put_16 (input_bfd, high, contents + offset + endian);
1550+ bfd_put_16 (input_bfd, lo,
1551+ contents + offset + INST_WORD_SIZE + endian);
1552+ break;
1553+ }
1554+
1555+ case (int) R_MICROBLAZE_GOTOFF_32:
1556+ {
1557+ relocation += addend;
1558+ relocation -= (htab->elf.sgotplt->output_section->vma
1559+ + htab->elf.sgotplt->output_offset);
1560+ /* Write this value into correct location. */
1561+ bfd_put_32 (input_bfd, relocation, contents + offset);
1562+ break;
1563+ }
1564+
1565+ case (int) R_MICROBLAZE_TLSDTPREL64:
1566+ relocation += addend;
1567+ relocation -= dtprel_base(info);
1568+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1569+ contents + offset + endian);
1570+ bfd_put_16 (input_bfd, relocation & 0xffff,
1571+ contents + offset + endian + INST_WORD_SIZE);
1572+ break;
1573+ case (int) R_MICROBLAZE_TEXTREL_64:
1574+ case (int) R_MICROBLAZE_TEXTREL_32_LO:
1575+ case (int) R_MICROBLAZE_64_PCREL :
1576+ case (int) R_MICROBLAZE_64:
1577+ case (int) R_MICROBLAZE_32:
1578+ case (int) R_MICROBLAZE_IMML_64:
1579+ {
1580+ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1581+ from removed linkonce sections, or sections discarded by
1582+ a linker script. */
1583+ if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
1584+ {
1585+ relocation += addend;
1586+ if (r_type == R_MICROBLAZE_32)// || r_type == R_MICROBLAZE_IMML_64)
1587+ bfd_put_32 (input_bfd, relocation, contents + offset);
1588+ else if (r_type == R_MICROBLAZE_IMML_64)
1589+ bfd_put_64 (input_bfd, relocation, contents + offset);
1590+ else
1591+ {
1592+ if (r_type == R_MICROBLAZE_64_PCREL)
1593+ relocation -= (input_section->output_section->vma
1594+ + input_section->output_offset
1595+ + offset + INST_WORD_SIZE);
1596+ else if (r_type == R_MICROBLAZE_TEXTREL_64
1597+ || r_type == R_MICROBLAZE_TEXTREL_32_LO)
1598+ relocation -= input_section->output_section->vma;
1599+
1600+ if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
1601+ bfd_put_16 (input_bfd, relocation & 0xffff,
1602+ contents + offset + endian);
1603+
1604+ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
1605+ if ((insn & 0xff000000) == 0xb2000000)
1606+ {
1607+ insn &= ~0x00ffffff;
1608+ insn |= (relocation >> 16) & 0xffffff;
1609+ bfd_put_32 (input_bfd, insn,
1610+ contents + offset + endian);
1611+ }
1612+ else
1613+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1614+ contents + offset + endian);
1615+ bfd_put_16 (input_bfd, relocation & 0xffff,
1616+ contents + offset + endian + INST_WORD_SIZE);
1617+ }
1618+ break;
1619+ }
1620+
1621+ if ((bfd_link_pic (info)
1622+ && (h == NULL
1623+ || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1624+ && !resolved_to_zero)
1625+ || h->root.type != bfd_link_hash_undefweak)
1626+ && (!howto->pc_relative
1627+ || (h != NULL
1628+ && h->dynindx != -1
1629+ && (!info->symbolic
1630+ || !h->def_regular))))
1631+ || (!bfd_link_pic (info)
1632+ && h != NULL
1633+ && h->dynindx != -1
1634+ && !h->non_got_ref
1635+ && ((h->def_dynamic
1636+ && !h->def_regular)
1637+ || h->root.type == bfd_link_hash_undefweak
1638+ || h->root.type == bfd_link_hash_undefined)))
1639+ {
1640+ Elf_Internal_Rela outrel;
1641+ bfd_byte *loc;
1642+ bool skip;
1643+
1644+ /* When generating a shared object, these relocations
1645+ are copied into the output file to be resolved at run
1646+ time. */
1647+
1648+ BFD_ASSERT (sreloc != NULL);
1649+
1650+ skip = false;
1651+
1652+ outrel.r_offset =
1653+ _bfd_elf_section_offset (output_bfd, info, input_section,
1654+ rel->r_offset);
1655+ if (outrel.r_offset == (bfd_vma) -1)
1656+ skip = true;
1657+ else if (outrel.r_offset == (bfd_vma) -2)
1658+ skip = true;
1659+ outrel.r_offset += (input_section->output_section->vma
1660+ + input_section->output_offset);
1661+
1662+ if (skip)
1663+ memset (&outrel, 0, sizeof outrel);
1664+ /* h->dynindx may be -1 if the symbol was marked to
1665+ become local. */
1666+ else if (h != NULL
1667+ && ((! info->symbolic && h->dynindx != -1)
1668+ || !h->def_regular))
1669+ {
1670+ BFD_ASSERT (h->dynindx != -1);
1671+ outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
1672+ outrel.r_addend = addend;
1673+ }
1674+ else
1675+ {
1676+ if (r_type == R_MICROBLAZE_32 || r_type == R_MICROBLAZE_IMML_64)
1677+ {
1678+ outrel.r_info = ELF64_R_INFO (0, R_MICROBLAZE_REL);
1679+ outrel.r_addend = relocation + addend;
1680+ }
1681+ else
1682+ {
1683+ BFD_FAIL ();
1684+ _bfd_error_handler
1685+ (_("%pB: probably compiled without -fPIC?"),
1686+ input_bfd);
1687+ bfd_set_error (bfd_error_bad_value);
1688+ return false;
1689+ }
1690+ }
1691+
1692+ loc = sreloc->contents;
1693+ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
1694+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
1695+ break;
1696+ }
1697+ else
1698+ {
1699+ relocation += addend;
1700+ if (r_type == R_MICROBLAZE_32)
1701+ bfd_put_32 (input_bfd, relocation, contents + offset);
1702+ else if (r_type == R_MICROBLAZE_IMML_64)
1703+ bfd_put_64 (input_bfd, relocation, contents + offset + endian);
1704+ else
1705+ {
1706+ if (r_type == R_MICROBLAZE_64_PCREL)
1707+ {
1708+ if (!input_section->output_section->vma &&
1709+ !input_section->output_offset && !offset)
1710+ relocation -= (input_section->output_section->vma
1711+ + input_section->output_offset
1712+ + offset);
1713+ else
1714+ relocation -= (input_section->output_section->vma
1715+ + input_section->output_offset + offset + INST_WORD_SIZE);
1716+ }
1717+ else if (r_type == R_MICROBLAZE_TEXTREL_64
1718+ || r_type == R_MICROBLAZE_TEXTREL_32_LO)
1719+ relocation -= input_section->output_section->vma;
1720+
1721+ if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
1722+ {
1723+ bfd_put_16 (input_bfd, relocation & 0xffff,
1724+ contents + offset + endian);
1725+ }
1726+ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
1727+ if ((insn & 0xff000000) == 0xb2000000)
1728+ {
1729+ insn &= ~0x00ffffff;
1730+ insn |= (relocation >> 16) & 0xffffff;
1731+ bfd_put_32 (input_bfd, insn,
1732+ contents + offset + endian);
1733+ }
1734+ else
1735+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1736+ contents + offset + endian);
1737+ bfd_put_16 (input_bfd, relocation & 0xffff,
1738+ contents + offset + endian + INST_WORD_SIZE);
1739+ }
1740+ break;
1741+ }
1742+ }
1743+
1744+ default :
1745+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1746+ contents, offset,
1747+ relocation, addend);
1748+ break;
1749+ }
1750+ }
1751+
1752+ check_reloc:
1753+
1754+ if (r != bfd_reloc_ok)
1755+ {
1756+ /* FIXME: This should be generic enough to go in a utility. */
1757+ const char *name;
1758+
1759+ if (h != NULL)
1760+ name = h->root.root.string;
1761+ else
1762+ {
1763+ name = (bfd_elf_string_from_elf_section
1764+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
1765+ if (name == NULL || *name == '\0')
1766+ name = bfd_section_name (sec);
1767+ }
1768+
1769+ if (errmsg != NULL)
1770+ goto common_error;
1771+
1772+ switch (r)
1773+ {
1774+ case bfd_reloc_overflow:
1775+ (*info->callbacks->reloc_overflow)
1776+ (info, (h ? &h->root : NULL), name, howto->name,
1777+ (bfd_vma) 0, input_bfd, input_section, offset);
1778+ break;
1779+
1780+ case bfd_reloc_undefined:
1781+ (*info->callbacks->undefined_symbol)
1782+ (info, name, input_bfd, input_section, offset, true);
1783+ break;
1784+
1785+ case bfd_reloc_outofrange:
1786+ errmsg = _("internal error: out of range error");
1787+ goto common_error;
1788+
1789+ case bfd_reloc_notsupported:
1790+ errmsg = _("internal error: unsupported relocation error");
1791+ goto common_error;
1792+
1793+ case bfd_reloc_dangerous:
1794+ errmsg = _("internal error: dangerous error");
1795+ goto common_error;
1796+
1797+ default:
1798+ errmsg = _("internal error: unknown error");
1799+ /* Fall through. */
1800+ common_error:
1801+ (*info->callbacks->warning) (info, errmsg, name, input_bfd,
1802+ input_section, offset);
1803+ break;
1804+ }
1805+ }
1806+ }
1807+
1808+ return ret;
1809+}
1810+
1811+/* Merge backend specific data from an object file to the output
1812+ object file when linking.
1813+
1814+ Note: We only use this hook to catch endian mismatches. */
1815+static bool
1816+microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
1817+{
1818+ /* Check if we have the same endianess. */
1819+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
1820+ return false;
1821+
1822+ return true;
1823+}
1824+
1825+
1826+/* Calculate fixup value for reference. */
1827+
1828+static size_t
1829+calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
1830+{
1831+ bfd_vma end = start + size;
1832+ size_t i, fixup = 0;
1833+ struct _microblaze_elf_section_data *sdata;
1834+
1835+ if (sec == NULL || (sdata = microblaze_elf_section_data (sec)) == NULL)
1836+ return 0;
1837+
1838+ /* Look for addr in relax table, total fixup value. */
1839+ for (i = 0; i < sdata->relax_count; i++)
1840+ {
1841+ if (end <= sdata->relax[i].addr)
1842+ break;
1843+ if (end != start && start > sdata->relax[i].addr)
1844+ continue;
1845+ fixup += sdata->relax[i].size;
1846+ }
1847+ return fixup;
1848+}
1849+
1850+/* Read-modify-write into the bfd, an immediate value into appropriate fields of
1851+ a 32-bit instruction. */
1852+static void
1853+microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1854+{
1855+ unsigned long instr = bfd_get_32 (abfd, bfd_addr);
1856+
1857+ if ((instr & 0xff000000) == 0xb2000000)
1858+ {
1859+ instr &= ~0x00ffffff;
1860+ instr |= (val & 0xffffff);
1861+ bfd_put_32 (abfd, instr, bfd_addr);
1862+ }
1863+ else
1864+ {
1865+ instr &= ~0x0000ffff;
1866+ instr |= (val & 0x0000ffff);
1867+ bfd_put_32 (abfd, instr, bfd_addr);
1868+ }
1869+}
1870+
1871+/* Read-modify-write into the bfd, an immediate value into appropriate fields of
1872+ two consecutive 32-bit instructions. */
1873+static void
1874+microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1875+{
1876+ unsigned long instr_hi;
1877+ unsigned long instr_lo;
1878+
1879+ instr_hi = bfd_get_32 (abfd, bfd_addr);
1880+ if ((instr_hi & 0xff000000) == 0xb2000000)
1881+ {
1882+ instr_hi &= ~0x00ffffff;
1883+ instr_hi |= (val >> 16) & 0xffffff;
1884+ bfd_put_32 (abfd, instr_hi,bfd_addr);
1885+ }
1886+ else
1887+ {
1888+ instr_hi &= ~0x0000ffff;
1889+ instr_hi |= ((val >> 16) & 0x0000ffff);
1890+ bfd_put_32 (abfd, instr_hi, bfd_addr);
1891+ }
1892+ instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
1893+ instr_lo &= ~0x0000ffff;
1894+ instr_lo |= (val & 0x0000ffff);
1895+ bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
1896+}
1897+
1898+static bool
1899+microblaze_elf_relax_section (bfd *abfd,
1900+ asection *sec,
1901+ struct bfd_link_info *link_info,
1902+ bool *again)
1903+{
1904+ Elf_Internal_Shdr *symtab_hdr;
1905+ Elf_Internal_Rela *internal_relocs;
1906+ Elf_Internal_Rela *irel, *irelend;
1907+ bfd_byte *contents = NULL;
1908+ int rel_count;
1909+ unsigned int shndx;
1910+ size_t i, sym_index;
1911+ asection *o;
1912+ struct elf_link_hash_entry *sym_hash;
1913+ Elf_Internal_Sym *isymbuf, *isymend;
1914+ Elf_Internal_Sym *isym;
1915+ size_t symcount;
1916+ size_t offset;
1917+ bfd_vma src, dest;
1918+ struct _microblaze_elf_section_data *sdata;
1919+
1920+ /* We only do this once per section. We may be able to delete some code
1921+ by running multiple passes, but it is not worth it. */
1922+ *again = false;
1923+
1924+ /* Only do this for a text section. */
1925+ if (bfd_link_relocatable (link_info)
1926+ || (sec->flags & SEC_RELOC) == 0
1927+ || (sec->flags & SEC_CODE) == 0
1928+ || sec->reloc_count == 0
1929+ || (sdata = microblaze_elf_section_data (sec)) == NULL)
1930+ return true;
1931+
1932+ BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1933+
1934+ /* If this is the first time we have been called for this section,
1935+ initialize the cooked size. */
1936+ if (sec->size == 0)
1937+ sec->size = sec->rawsize;
1938+
1939+ /* Get symbols for this section. */
1940+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1941+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1942+ symcount = symtab_hdr->sh_size / sizeof (Elf64_External_Sym);
1943+ if (isymbuf == NULL)
1944+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1945+ 0, NULL, NULL, NULL);
1946+ BFD_ASSERT (isymbuf != NULL);
1947+
1948+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1949+ if (internal_relocs == NULL)
1950+ goto error_return;
1951+
1952+ sdata->relax_count = 0;
1953+ sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1954+ * sizeof (*sdata->relax));
1955+ if (sdata->relax == NULL)
1956+ goto error_return;
1957+
1958+ irelend = internal_relocs + sec->reloc_count;
1959+ rel_count = 0;
1960+ for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1961+ {
1962+ bfd_vma symval;
1963+ if ((ELF64_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1964+ && (ELF64_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 )
1965+&& (ELF64_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_TEXTREL_64))
1966+ continue; /* Can't delete this reloc. */
1967+
1968+ /* Get the section contents. */
1969+ if (contents == NULL)
1970+ {
1971+ if (elf_section_data (sec)->this_hdr.contents != NULL)
1972+ contents = elf_section_data (sec)->this_hdr.contents;
1973+ else
1974+ {
1975+ contents = (bfd_byte *) bfd_malloc (sec->size);
1976+ if (contents == NULL)
1977+ goto error_return;
1978+ if (!bfd_get_section_contents (abfd, sec, contents,
1979+ (file_ptr) 0, sec->size))
1980+ goto error_return;
1981+ elf_section_data (sec)->this_hdr.contents = contents;
1982+ }
1983+ }
1984+
1985+ /* Get the value of the symbol referred to by the reloc. */
1986+ if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1987+ {
1988+ /* A local symbol. */
1989+ asection *sym_sec;
1990+
1991+ isym = isymbuf + ELF64_R_SYM (irel->r_info);
1992+ if (isym->st_shndx == SHN_UNDEF)
1993+ sym_sec = bfd_und_section_ptr;
1994+ else if (isym->st_shndx == SHN_ABS)
1995+ sym_sec = bfd_abs_section_ptr;
1996+ else if (isym->st_shndx == SHN_COMMON)
1997+ sym_sec = bfd_com_section_ptr;
1998+ else
1999+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2000+
2001+ symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
2002+ }
2003+ else
2004+ {
2005+ unsigned long indx;
2006+ struct elf_link_hash_entry *h;
2007+
2008+ indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2009+ h = elf_sym_hashes (abfd)[indx];
2010+ BFD_ASSERT (h != NULL);
2011+
2012+ if (h->root.type != bfd_link_hash_defined
2013+ && h->root.type != bfd_link_hash_defweak)
2014+ /* This appears to be a reference to an undefined
2015+ symbol. Just ignore it--it will be caught by the
2016+ regular reloc processing. */
2017+ continue;
2018+
2019+ symval = (h->root.u.def.value
2020+ + h->root.u.def.section->output_section->vma
2021+ + h->root.u.def.section->output_offset);
2022+ }
2023+
2024+ /* If this is a PC-relative reloc, subtract the instr offset from
2025+ the symbol value. */
2026+ if (ELF64_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
2027+ {
2028+ symval = symval + irel->r_addend
2029+ - (irel->r_offset
2030+ + sec->output_section->vma
2031+ + sec->output_offset);
2032+ }
2033+ else if (ELF64_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_TEXTREL_64)
2034+ {
2035+ symval = symval + irel->r_addend - (sec->output_section->vma);
2036+ }
2037+ else
2038+ symval += irel->r_addend;
2039+
2040+ if ((symval & 0xffff8000) == 0
2041+ || (symval & 0xffff8000) == 0xffff8000)
2042+ {
2043+ /* We can delete this instruction. */
2044+ sdata->relax[sdata->relax_count].addr = irel->r_offset;
2045+ sdata->relax[sdata->relax_count].size = INST_WORD_SIZE;
2046+ sdata->relax_count++;
2047+
2048+ /* Rewrite relocation type. */
2049+ switch ((enum elf_microblaze_reloc_type) ELF64_R_TYPE (irel->r_info))
2050+ {
2051+ case R_MICROBLAZE_64_PCREL:
2052+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
2053+ (int) R_MICROBLAZE_32_PCREL_LO);
2054+ break;
2055+ case R_MICROBLAZE_64:
2056+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
2057+ (int) R_MICROBLAZE_32_LO);
2058+ break;
2059+ case R_MICROBLAZE_TEXTREL_64:
2060+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
2061+ (int) R_MICROBLAZE_TEXTREL_32_LO);
2062+ break;
2063+ default:
2064+ /* Cannot happen. */
2065+ BFD_ASSERT (false);
2066+ }
2067+ }
2068+ } /* Loop through all relocations. */
2069+
2070+ /* Loop through the relocs again, and see if anything needs to change. */
2071+ if (sdata->relax_count > 0)
2072+ {
2073+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
2074+ rel_count = 0;
2075+ sdata->relax[sdata->relax_count].addr = sec->size;
2076+
2077+ for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
2078+ {
2079+ bfd_vma nraddr;
2080+
2081+ /* Get the new reloc address. */
2082+ nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
2083+ switch ((enum elf_microblaze_reloc_type) ELF64_R_TYPE (irel->r_info))
2084+ {
2085+ default:
2086+ break;
2087+ case R_MICROBLAZE_64_PCREL:
2088+ break;
2089+ case R_MICROBLAZE_64:
2090+ case R_MICROBLAZE_32_LO:
2091+ /* If this reloc is against a symbol defined in this
2092+ section, we must check the addend to see it will put the value in
2093+ range to be adjusted, and hence must be changed. */
2094+ if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2095+ {
2096+ isym = isymbuf + ELF64_R_SYM (irel->r_info);
2097+ /* Only handle relocs against .text. */
2098+ if (isym->st_shndx == shndx
2099+ && ELF64_ST_TYPE (isym->st_info) == STT_SECTION)
2100+ irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
2101+ }
2102+ break;
2103+ case R_MICROBLAZE_IMML_64:
2104+ {
2105+ /* This was a PC-relative instruction that was
2106+ completely resolved. */
2107+ int sfix, efix;
2108+ unsigned int val;
2109+ bfd_vma target_address;
2110+ target_address = irel->r_addend + irel->r_offset;
2111+ sfix = calc_fixup (irel->r_offset, 0, sec);
2112+ efix = calc_fixup (target_address, 0, sec);
2113+
2114+ /* Validate the in-band val. */
2115+ val = bfd_get_64 (abfd, contents + irel->r_offset);
2116+ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
2117+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
2118+ }
2119+ irel->r_addend -= (efix - sfix);
2120+ /* Should use HOWTO. */
2121+ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
2122+ irel->r_addend);
2123+ }
2124+ break;
2125+ case R_MICROBLAZE_NONE:
2126+ case R_MICROBLAZE_32_NONE:
2127+ {
2128+ /* This was a PC-relative instruction that was
2129+ completely resolved. */
2130+ size_t sfix, efix;
2131+ unsigned int val;
2132+ bfd_vma target_address;
2133+ target_address = irel->r_addend + irel->r_offset;
2134+ sfix = calc_fixup (irel->r_offset, 0, sec);
2135+ efix = calc_fixup (target_address, 0, sec);
2136+
2137+ /* Validate the in-band val. */
2138+ val = bfd_get_32 (abfd, contents + irel->r_offset);
2139+ if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
2140+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
2141+ }
2142+ irel->r_addend -= (efix - sfix);
2143+ /* Should use HOWTO. */
2144+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
2145+ irel->r_addend);
2146+ }
2147+ break;
2148+ case R_MICROBLAZE_64_NONE:
2149+ {
2150+ /* This was a PC-relative 64-bit instruction that was
2151+ completely resolved. */
2152+ size_t sfix, efix;
2153+ bfd_vma target_address;
2154+ target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
2155+ sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
2156+ efix = calc_fixup (target_address, 0, sec);
2157+ irel->r_addend -= (efix - sfix);
2158+ microblaze_bfd_write_imm_value_64 (abfd, contents + irel->r_offset,
2159+ irel->r_addend);
2160+ }
2161+ break;
2162+ }
2163+ irel->r_offset = nraddr;
2164+ } /* Change all relocs in this section. */
2165+
2166+ /* Look through all other sections. */
2167+ for (o = abfd->sections; o != NULL; o = o->next)
2168+ {
2169+ Elf_Internal_Rela *irelocs;
2170+ Elf_Internal_Rela *irelscan, *irelscanend;
2171+ bfd_byte *ocontents;
2172+
2173+ if (o == sec
2174+ || (o->flags & SEC_RELOC) == 0
2175+ || o->reloc_count == 0)
2176+ continue;
2177+
2178+ /* We always cache the relocs. Perhaps, if info->keep_memory is
2179+ false, we should free them, if we are permitted to. */
2180+
2181+ irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, true);
2182+ if (irelocs == NULL)
2183+ goto error_return;
2184+
2185+ ocontents = NULL;
2186+ irelscanend = irelocs + o->reloc_count;
2187+ for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
2188+ {
2189+ if (1 && ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
2190+ {
2191+ unsigned int val;
2192+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
2193+ continue;
2194+
2195+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2196+
2197+ /* hax: We only do the following fixup for debug location lists. */
2198+ if (strcmp(".debug_loc", o->name))
2199+ continue;
2200+
2201+ /* This was a PC-relative instruction that was completely resolved. */
2202+ if (ocontents == NULL)
2203+ {
2204+ if (elf_section_data (o)->this_hdr.contents != NULL)
2205+ ocontents = elf_section_data (o)->this_hdr.contents;
2206+ else
2207+ {
2208+ /* We always cache the section contents.
2209+ Perhaps, if info->keep_memory is false, we
2210+ should free them, if we are permitted to. */
2211+
2212+ if (o->rawsize == 0)
2213+ o->rawsize = o->size;
2214+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2215+ if (ocontents == NULL)
2216+ goto error_return;
2217+ if (!bfd_get_section_contents (abfd, o, ocontents,
2218+ (file_ptr) 0,
2219+ o->rawsize))
2220+ goto error_return;
2221+ elf_section_data (o)->this_hdr.contents = ocontents;
2222+ }
2223+ }
2224+
2225+ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2226+ if (val != irelscan->r_addend) {
2227+ fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
2228+ }
2229+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
2230+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2231+ irelscan->r_addend);
2232+ }
2233+ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32
2234+ || ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
2235+ {
2236+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
2237+ continue;
2238+
2239+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2240+
2241+ /* Look at the reloc only if the value has been resolved. */
2242+ if (isym->st_shndx == shndx
2243+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
2244+ {
2245+ if (ocontents == NULL)
2246+ {
2247+ if (elf_section_data (o)->this_hdr.contents != NULL)
2248+ ocontents = elf_section_data (o)->this_hdr.contents;
2249+ else
2250+ {
2251+ /* We always cache the section contents.
2252+ Perhaps, if info->keep_memory is false, we
2253+ should free them, if we are permitted to. */
2254+ if (o->rawsize == 0)
2255+ o->rawsize = o->size;
2256+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2257+ if (ocontents == NULL)
2258+ goto error_return;
2259+ if (!bfd_get_section_contents (abfd, o, ocontents,
2260+ (file_ptr) 0,
2261+ o->rawsize))
2262+ goto error_return;
2263+ elf_section_data (o)->this_hdr.contents = ocontents;
2264+ }
2265+
2266+ }
2267+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
2268+ }
2269+ else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
2270+ {
2271+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
2272+ continue;
2273+
2274+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2275+
2276+ /* Look at the reloc only if the value has been resolved. */
2277+ if (ocontents == NULL)
2278+ {
2279+ if (elf_section_data (o)->this_hdr.contents != NULL)
2280+ ocontents = elf_section_data (o)->this_hdr.contents;
2281+ else
2282+ {
2283+ /* We always cache the section contents.
2284+ Perhaps, if info->keep_memory is false, we
2285+ should free them, if we are permitted to. */
2286+
2287+ if (o->rawsize == 0)
2288+ o->rawsize = o->size;
2289+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2290+ if (ocontents == NULL)
2291+ goto error_return;
2292+ if (!bfd_get_section_contents (abfd, o, ocontents,
2293+ (file_ptr) 0,
2294+ o->rawsize))
2295+ goto error_return;
2296+ elf_section_data (o)->this_hdr.contents = ocontents;
2297+ }
2298+ }
2299+ irelscan->r_addend -= calc_fixup (irelscan->r_addend
2300+ + isym->st_value,
2301+ 0,
2302+ sec);
2303+ }
2304+ }
2305+ else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
2306+ || (ELF32_R_TYPE (irelscan->r_info)
2307+ == (int) R_MICROBLAZE_32_LO)
2308+ || (ELF32_R_TYPE (irelscan->r_info)
2309+ == (int) R_MICROBLAZE_TEXTREL_32_LO))
2310+ {
2311+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
2312+ continue;
2313+
2314+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2315+
2316+ /* Look at the reloc only if the value has been resolved. */
2317+ if (isym->st_shndx == shndx
2318+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
2319+ {
2320+ bfd_vma immediate;
2321+ bfd_vma target_address;
2322+
2323+ if (ocontents == NULL)
2324+ {
2325+ if (elf_section_data (o)->this_hdr.contents != NULL)
2326+ ocontents = elf_section_data (o)->this_hdr.contents;
2327+ else
2328+ {
2329+ /* We always cache the section contents.
2330+ Perhaps, if info->keep_memory is false, we
2331+ should free them, if we are permitted to. */
2332+ if (o->rawsize == 0)
2333+ o->rawsize = o->size;
2334+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2335+ if (ocontents == NULL)
2336+ goto error_return;
2337+ if (!bfd_get_section_contents (abfd, o, ocontents,
2338+ (file_ptr) 0,
2339+ o->rawsize))
2340+ goto error_return;
2341+ elf_section_data (o)->this_hdr.contents = ocontents;
2342+ }
2343+ }
2344+
2345+ unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2346+ immediate = instr & 0x0000ffff;
2347+ target_address = immediate;
2348+ offset = calc_fixup (target_address, 0, sec);
2349+ immediate -= offset;
2350+ irelscan->r_addend -= offset;
2351+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2352+ irelscan->r_addend);
2353+ }
2354+ }
2355+
2356+ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64
2357+ || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_TEXTREL_64))
2358+ {
2359+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
2360+ continue;
2361+
2362+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2363+
2364+ /* Look at the reloc only if the value has been resolved. */
2365+ if (isym->st_shndx == shndx
2366+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
2367+ {
2368+ bfd_vma immediate;
2369+
2370+ if (ocontents == NULL)
2371+ {
2372+ if (elf_section_data (o)->this_hdr.contents != NULL)
2373+ ocontents = elf_section_data (o)->this_hdr.contents;
2374+ else
2375+ {
2376+ /* We always cache the section contents.
2377+ Perhaps, if info->keep_memory is false, we
2378+ should free them, if we are permitted to. */
2379+
2380+ if (o->rawsize == 0)
2381+ o->rawsize = o->size;
2382+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2383+ if (ocontents == NULL)
2384+ goto error_return;
2385+ if (!bfd_get_section_contents (abfd, o, ocontents,
2386+ (file_ptr) 0,
2387+ o->rawsize))
2388+ goto error_return;
2389+ elf_section_data (o)->this_hdr.contents = ocontents;
2390+ }
2391+ }
2392+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2393+ + irelscan->r_offset);
2394+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2395+ + irelscan->r_offset
2396+ + INST_WORD_SIZE);
2397+ if ((instr_hi & 0xff000000) == 0xb2000000)
2398+ immediate = (instr_hi & 0x00ffffff) << 24;
2399+ else
2400+ immediate = (instr_hi & 0x0000ffff) << 16;
2401+ immediate |= (instr_lo & 0x0000ffff);
2402+ offset = calc_fixup (irelscan->r_addend, 0, sec);
2403+ immediate -= offset;
2404+ irelscan->r_addend -= offset;
2405+
2406+ }
2407+ }
2408+ else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
2409+ {
2410+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
2411+ continue;
2412+
2413+ isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
2414+
2415+ /* Look at the reloc only if the value has been resolved. */
2416+ if (isym->st_shndx == shndx
2417+ && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
2418+ {
2419+ bfd_vma immediate;
2420+ bfd_vma target_address;
2421+
2422+ if (ocontents == NULL)
2423+ {
2424+ if (elf_section_data (o)->this_hdr.contents != NULL)
2425+ ocontents = elf_section_data (o)->this_hdr.contents;
2426+ else
2427+ {
2428+ /* We always cache the section contents.
2429+ Perhaps, if info->keep_memory is false, we
2430+ should free them, if we are permitted to. */
2431+ if (o->rawsize == 0)
2432+ o->rawsize = o->size;
2433+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2434+ if (ocontents == NULL)
2435+ goto error_return;
2436+ if (!bfd_get_section_contents (abfd, o, ocontents,
2437+ (file_ptr) 0,
2438+ o->rawsize))
2439+ goto error_return;
2440+ elf_section_data (o)->this_hdr.contents = ocontents;
2441+ }
2442+ }
2443+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2444+ + irelscan->r_offset);
2445+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2446+ + irelscan->r_offset
2447+ + INST_WORD_SIZE);
2448+ if ((instr_hi & 0xff000000) == 0xb2000000)
2449+ immediate = (instr_hi & 0x00ffffff) << 24;
2450+ else
2451+ immediate = (instr_hi & 0x0000ffff) << 16;
2452+ immediate |= (instr_lo & 0x0000ffff);
2453+ target_address = immediate;
2454+ offset = calc_fixup (target_address, 0, sec);
2455+ immediate -= offset;
2456+ irelscan->r_addend -= offset;
2457+ microblaze_bfd_write_imm_value_64 (abfd, ocontents
2458+ + irelscan->r_offset, immediate);
2459+ }
2460+ }
2461+ }
2462+ }
2463+
2464+ /* Adjust the local symbols defined in this section. */
2465+ isymend = isymbuf + symtab_hdr->sh_info;
2466+ for (isym = isymbuf; isym < isymend; isym++)
2467+ {
2468+ if (isym->st_shndx == shndx)
2469+ {
2470+ isym->st_value -= calc_fixup (isym->st_value, 0, sec);
2471+ if (isym->st_size)
2472+ isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
2473+ }
2474+ }
2475+
2476+ /* Now adjust the global symbols defined in this section. */
2477+ isym = isymbuf + symtab_hdr->sh_info;
2478+ symcount = (symtab_hdr->sh_size / sizeof (Elf64_External_Sym)) - symtab_hdr->sh_info;
2479+ for (sym_index = 0; sym_index < symcount; sym_index++)
2480+ {
2481+ sym_hash = elf_sym_hashes (abfd)[sym_index];
2482+ if ((sym_hash->root.type == bfd_link_hash_defined
2483+ || sym_hash->root.type == bfd_link_hash_defweak)
2484+ && sym_hash->root.u.def.section == sec)
2485+ {
2486+ sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
2487+ 0, sec);
2488+ if (sym_hash->size)
2489+ sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
2490+ sym_hash->size, sec);
2491+ }
2492+ }
2493+
2494+ /* Physically move the code and change the cooked size. */
2495+ dest = sdata->relax[0].addr;
2496+ for (i = 0; i < sdata->relax_count; i++)
2497+ {
2498+ size_t len;
2499+ src = sdata->relax[i].addr + sdata->relax[i].size;
2500+ len = (sdata->relax[i+1].addr - sdata->relax[i].addr
2501+ - sdata->relax[i].size);
2502+
2503+ memmove (contents + dest, contents + src, len);
2504+ sec->size -= sdata->relax[i].size;
2505+ dest += len;
2506+ }
2507+
2508+ elf_section_data (sec)->relocs = internal_relocs;
2509+
2510+ elf_section_data (sec)->this_hdr.contents = contents;
2511+
2512+ symtab_hdr->contents = (bfd_byte *) isymbuf;
2513+ }
2514+
2515+ if (internal_relocs != NULL
2516+ && elf_section_data (sec)->relocs != internal_relocs)
2517+ free (internal_relocs);
2518+
2519+ if (contents != NULL
2520+ && elf_section_data (sec)->this_hdr.contents != contents)
2521+ {
2522+ if (! link_info->keep_memory)
2523+ free (contents);
2524+ else
2525+ {
2526+ /* Cache the section contents for elf_link_input_bfd. */
2527+ elf_section_data (sec)->this_hdr.contents = contents;
2528+ }
2529+ }
2530+
2531+ if (sdata->relax_count == 0)
2532+ {
2533+ *again = false;
2534+ free (sdata->relax);
2535+ sdata->relax = NULL;
2536+ }
2537+ else
2538+ *again = true;
2539+ return true;
2540+
2541+ error_return:
2542+ if (isymbuf != NULL
2543+ && symtab_hdr->contents != (unsigned char *) isymbuf)
2544+ free (isymbuf);
2545+ if (internal_relocs != NULL
2546+ && elf_section_data (sec)->relocs != internal_relocs)
2547+ free (internal_relocs);
2548+ if (contents != NULL
2549+ && elf_section_data (sec)->this_hdr.contents != contents)
2550+ free (contents);
2551+ free (sdata->relax);
2552+ sdata->relax = NULL;
2553+ sdata->relax_count = 0;
2554+ return false;
2555+}
2556+
2557+/* Return the section that should be marked against GC for a given
2558+ relocation. */
2559+
2560+static asection *
2561+microblaze_elf_gc_mark_hook (asection *sec,
2562+ struct bfd_link_info * info,
2563+ Elf_Internal_Rela * rel,
2564+ struct elf_link_hash_entry * h,
2565+ Elf_Internal_Sym * sym)
2566+{
2567+ if (h != NULL)
2568+ switch (ELF64_R_TYPE (rel->r_info))
2569+ {
2570+ case R_MICROBLAZE_GNU_VTINHERIT:
2571+ case R_MICROBLAZE_GNU_VTENTRY:
2572+ return NULL;
2573+ }
2574+
2575+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2576+}
2577+
2578+/* Update the got entry reference counts for the section being removed. */
2579+
2580+static bool
2581+microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
2582+ struct bfd_link_info * info ATTRIBUTE_UNUSED,
2583+ asection * sec ATTRIBUTE_UNUSED,
2584+ const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
2585+{
2586+ return true;
2587+}
2588+
2589+/* PIC support. */
2590+
2591+#define PLT_ENTRY_SIZE 16
2592+
2593+#define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2594+#define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2595+#define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2596+#define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2597+#define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2598+
2599+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
2600+ shortcuts to them in our hash table. */
2601+
2602+static bool
2603+update_local_sym_info (bfd *abfd,
2604+ Elf_Internal_Shdr *symtab_hdr,
2605+ unsigned long r_symndx,
2606+ unsigned int tls_type)
2607+{
2608+ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
2609+ unsigned char *local_got_tls_masks;
2610+
2611+ if (local_got_refcounts == NULL)
2612+ {
2613+ bfd_size_type size = symtab_hdr->sh_info;
2614+
2615+ size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
2616+ local_got_refcounts = bfd_zalloc (abfd, size);
2617+ if (local_got_refcounts == NULL)
2618+ return false;
2619+ elf_local_got_refcounts (abfd) = local_got_refcounts;
2620+ }
2621+
2622+ local_got_tls_masks =
2623+ (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
2624+ local_got_tls_masks[r_symndx] |= tls_type;
2625+ local_got_refcounts[r_symndx] += 1;
2626+
2627+ return true;
2628+}
2629+/* Look through the relocs for a section during the first phase. */
2630+
2631+static bool
2632+microblaze_elf_check_relocs (bfd * abfd,
2633+ struct bfd_link_info * info,
2634+ asection * sec,
2635+ const Elf_Internal_Rela * relocs)
2636+{
2637+ Elf_Internal_Shdr * symtab_hdr;
2638+ struct elf_link_hash_entry ** sym_hashes;
2639+ struct elf_link_hash_entry ** sym_hashes_end;
2640+ const Elf_Internal_Rela * rel;
2641+ const Elf_Internal_Rela * rel_end;
2642+ struct elf64_mb_link_hash_table *htab;
2643+ asection *sreloc = NULL;
2644+
2645+ if (bfd_link_relocatable (info))
2646+ return true;
2647+
2648+ htab = elf64_mb_hash_table (info);
2649+ if (htab == NULL)
2650+ return false;
2651+
2652+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2653+ sym_hashes = elf_sym_hashes (abfd);
2654+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf64_External_Sym);
2655+ if (!elf_bad_symtab (abfd))
2656+ sym_hashes_end -= symtab_hdr->sh_info;
2657+
2658+ rel_end = relocs + sec->reloc_count;
2659+
2660+ for (rel = relocs; rel < rel_end; rel++)
2661+ {
2662+ unsigned int r_type;
2663+ struct elf_link_hash_entry * h;
2664+ unsigned long r_symndx;
2665+ unsigned char tls_type = 0;
2666+
2667+ r_symndx = ELF64_R_SYM (rel->r_info);
2668+ r_type = ELF64_R_TYPE (rel->r_info);
2669+
2670+ if (r_symndx < symtab_hdr->sh_info)
2671+ h = NULL;
2672+ else
2673+ {
2674+ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
2675+ while (h->root.type == bfd_link_hash_indirect
2676+ || h->root.type == bfd_link_hash_warning)
2677+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
2678+ /* PR15323, ref flags aren't set for references in the same
2679+ object. */
2680+ h->root.non_ir_ref_regular = 1;
2681+ }
2682+
2683+ switch (r_type)
2684+ {
2685+ /* This relocation describes the C++ object vtable hierarchy.
2686+ Reconstruct it for later use during GC. */
2687+ case R_MICROBLAZE_GNU_VTINHERIT:
2688+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2689+ return false;
2690+ break;
2691+
2692+ /* This relocation describes which C++ vtable entries are actually
2693+ used. Record for later use during GC. */
2694+ case R_MICROBLAZE_GNU_VTENTRY:
2695+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2696+ return false;
2697+ break;
2698+
2699+ /* This relocation requires .plt entry. */
2700+ case R_MICROBLAZE_PLT_64:
2701+ if (h != NULL)
2702+ {
2703+ h->needs_plt = 1;
2704+ h->plt.refcount += 1;
2705+ }
2706+ break;
2707+
2708+ /* This relocation requires .got entry. */
2709+ case R_MICROBLAZE_TLSGD:
2710+ tls_type |= (TLS_TLS | TLS_GD);
2711+ goto dogottls;
2712+ case R_MICROBLAZE_TLSLD:
2713+ tls_type |= (TLS_TLS | TLS_LD);
2714+ /* Fall through. */
2715+ dogottls:
2716+ sec->has_tls_reloc = 1;
2717+ /* Fall through. */
2718+ case R_MICROBLAZE_GOT_64:
2719+ if (htab->elf.sgot == NULL)
2720+ {
2721+ if (htab->elf.dynobj == NULL)
2722+ htab->elf.dynobj = abfd;
2723+ if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2724+ return false;
2725+ }
2726+ if (h != NULL)
2727+ {
2728+ h->got.refcount += 1;
2729+ elf64_mb_hash_entry (h)->tls_mask |= tls_type;
2730+ }
2731+ else
2732+ {
2733+ if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
2734+ return false;
2735+ }
2736+ break;
2737+
2738+ case R_MICROBLAZE_GOTOFF_64:
2739+ case R_MICROBLAZE_GOTOFF_32:
2740+ if (htab->elf.sgot == NULL)
2741+ {
2742+ if (htab->elf.dynobj == NULL)
2743+ htab->elf.dynobj = abfd;
2744+ if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2745+ return false;
2746+ }
2747+ break;
2748+
2749+ case R_MICROBLAZE_64:
2750+ case R_MICROBLAZE_64_PCREL:
2751+ case R_MICROBLAZE_32:
2752+ case R_MICROBLAZE_IMML_64:
2753+ {
2754+ if (h != NULL && !bfd_link_pic (info))
2755+ {
2756+ /* we may need a copy reloc. */
2757+ h->non_got_ref = 1;
2758+
2759+ /* we may also need a .plt entry. */
2760+ h->plt.refcount += 1;
2761+ if (ELF64_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2762+ h->pointer_equality_needed = 1;
2763+ }
2764+
2765+
2766+ /* If we are creating a shared library, and this is a reloc
2767+ against a global symbol, or a non PC relative reloc
2768+ against a local symbol, then we need to copy the reloc
2769+ into the shared library. However, if we are linking with
2770+ -Bsymbolic, we do not need to copy a reloc against a
2771+ global symbol which is defined in an object we are
2772+ including in the link (i.e., DEF_REGULAR is set). At
2773+ this point we have not seen all the input files, so it is
2774+ possible that DEF_REGULAR is not set now but will be set
2775+ later (it is never cleared). In case of a weak definition,
2776+ DEF_REGULAR may be cleared later by a strong definition in
2777+ a shared library. We account for that possibility below by
2778+ storing information in the relocs_copied field of the hash
2779+ table entry. A similar situation occurs when creating
2780+ shared libraries and symbol visibility changes render the
2781+ symbol local.
2782+
2783+ If on the other hand, we are creating an executable, we
2784+ may need to keep relocations for symbols satisfied by a
2785+ dynamic library if we manage to avoid copy relocs for the
2786+ symbol. */
2787+
2788+ if ((bfd_link_pic (info)
2789+ && (sec->flags & SEC_ALLOC) != 0
2790+ && (r_type != R_MICROBLAZE_64_PCREL
2791+ || (h != NULL
2792+ && (! info->symbolic
2793+ || h->root.type == bfd_link_hash_defweak
2794+ || !h->def_regular))))
2795+ || (!bfd_link_pic (info)
2796+ && (sec->flags & SEC_ALLOC) != 0
2797+ && h != NULL
2798+ && (h->root.type == bfd_link_hash_defweak
2799+ || !h->def_regular)))
2800+ {
2801+ struct elf64_mb_dyn_relocs *p;
2802+ struct elf64_mb_dyn_relocs **head;
2803+
2804+ /* When creating a shared object, we must copy these
2805+ relocs into the output file. We create a reloc
2806+ section in dynobj and make room for the reloc. */
2807+
2808+ if (sreloc == NULL)
2809+ {
2810+ bfd *dynobj;
2811+
2812+ if (htab->elf.dynobj == NULL)
2813+ htab->elf.dynobj = abfd;
2814+ dynobj = htab->elf.dynobj;
2815+
2816+ sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2817+ 2, abfd, 1);
2818+ if (sreloc == NULL)
2819+ return false;
2820+ }
2821+
2822+ /* If this is a global symbol, we count the number of
2823+ relocations we need for this symbol. */
2824+ if (h != NULL)
2825+ head = &h->dyn_relocs;
2826+ else
2827+ {
2828+ /* Track dynamic relocs needed for local syms too.
2829+ We really need local syms available to do this
2830+ easily. Oh well. */
2831+
2832+ asection *s;
2833+ Elf_Internal_Sym *isym;
2834+ void *vpp;
2835+
2836+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
2837+ abfd, r_symndx);
2838+ if (isym == NULL)
2839+ return false;
2840+
2841+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2842+ if (s == NULL)
2843+ return false;
2844+
2845+ vpp = &elf_section_data (s)->local_dynrel;
2846+ head = (struct elf64_mb_dyn_relocs **) vpp;
2847+ }
2848+
2849+ p = *head;
2850+ if (p == NULL || p->sec != sec)
2851+ {
2852+ size_t amt = sizeof *p;
2853+ p = ((struct elf64_mb_dyn_relocs *)
2854+ bfd_alloc (htab->elf.dynobj, amt));
2855+ if (p == NULL)
2856+ return false;
2857+ p->next = *head;
2858+ *head = p;
2859+ p->sec = sec;
2860+ p->count = 0;
2861+ p->pc_count = 0;
2862+ }
2863+
2864+ p->count += 1;
2865+ if (r_type == R_MICROBLAZE_64_PCREL)
2866+ p->pc_count += 1;
2867+ }
2868+ }
2869+ break;
2870+ }
2871+ }
2872+
2873+ return true;
2874+}
2875+
2876+static bool
2877+microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
2878+{
2879+ struct elf64_mb_link_hash_table *htab;
2880+
2881+ htab = elf64_mb_hash_table (info);
2882+ if (htab == NULL)
2883+ return false;
2884+
2885+ if (!htab->sgot && !_bfd_elf_create_got_section (dynobj, info))
2886+ return false;
2887+
2888+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
2889+ return false;
2890+
2891+ htab->splt = bfd_get_linker_section (dynobj, ".plt");
2892+ htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
2893+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
2894+ if (!bfd_link_pic (info))
2895+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
2896+
2897+ if (!htab->splt || !htab->srelplt || !htab->sdynbss
2898+ || (!bfd_link_pic (info) && !htab->srelbss))
2899+ abort ();
2900+
2901+ return true;
2902+}
2903+
2904+/* Copy the extra info we tack onto an elf_link_hash_entry. */
2905+
2906+static void
2907+microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2908+ struct elf_link_hash_entry *dir,
2909+ struct elf_link_hash_entry *ind)
2910+{
2911+ struct elf64_mb_link_hash_entry *edir, *eind;
2912+
2913+ edir = (struct elf64_mb_link_hash_entry *) dir;
2914+ eind = (struct elf64_mb_link_hash_entry *) ind;
2915+
2916+ if (eind->dyn_relocs != NULL)
2917+ {
2918+ if (edir->dyn_relocs != NULL)
2919+ {
2920+ struct elf64_mb_dyn_relocs **pp;
2921+ struct elf64_mb_dyn_relocs *p;
2922+
2923+ if (ind->root.type == bfd_link_hash_indirect)
2924+ abort ();
2925+
2926+ /* Add reloc counts against the weak sym to the strong sym
2927+ list. Merge any entries against the same section. */
2928+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
2929+ {
2930+ struct elf64_mb_dyn_relocs *q;
2931+
2932+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
2933+ if (q->sec == p->sec)
2934+ {
2935+ q->pc_count += p->pc_count;
2936+ q->count += p->count;
2937+ *pp = p->next;
2938+ break;
2939+ }
2940+ if (q == NULL)
2941+ pp = &p->next;
2942+ }
2943+ *pp = edir->dyn_relocs;
2944+ }
2945+
2946+ edir->dyn_relocs = eind->dyn_relocs;
2947+ eind->dyn_relocs = NULL;
2948+ }
2949+
2950+ edir->tls_mask |= eind->tls_mask;
2951+
2952+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2953+}
2954+
2955+static bool
2956+microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2957+ struct elf_link_hash_entry *h)
2958+{
2959+ struct elf64_mb_link_hash_table *htab;
2960+ struct elf64_mb_link_hash_entry * eh;
2961+ struct elf64_mb_dyn_relocs *p;
2962+ asection *sdynbss;
2963+ asection *s, *srel;
2964+ unsigned int power_of_two;
2965+ bfd *dynobj;
2966+
2967+ htab = elf64_mb_hash_table (info);
2968+ if (htab == NULL)
2969+ return false;
2970+
2971+ /* If this is a function, put it in the procedure linkage table. We
2972+ will fill in the contents of the procedure linkage table later,
2973+ when we know the address of the .got section. */
2974+ if (h->type == STT_FUNC
2975+ || h->needs_plt)
2976+ {
2977+ if (h->plt.refcount <= 0
2978+ || SYMBOL_CALLS_LOCAL (info, h)
2979+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2980+ && h->root.type == bfd_link_hash_undefweak))
2981+ {
2982+ /* This case can occur if we saw a PLT reloc in an input
2983+ file, but the symbol was never referred to by a dynamic
2984+ object, or if all references were garbage collected. In
2985+ such a case, we don't actually need to build a procedure
2986+ linkage table, and we can just do a PC32 reloc instead. */
2987+ h->plt.offset = (bfd_vma) -1;
2988+ h->needs_plt = 0;
2989+ }
2990+
2991+ return true;
2992+ }
2993+ else
2994+ /* It's possible that we incorrectly decided a .plt reloc was
2995+ needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2996+ check_relocs. We can't decide accurately between function and
2997+ non-function syms in check-relocs; Objects loaded later in
2998+ the link may change h->type. So fix it now. */
2999+ h->plt.offset = (bfd_vma) -1;
3000+
3001+ /* If this is a weak symbol, and there is a real definition, the
3002+ processor independent code will have arranged for us to see the
3003+ real definition first, and we can just use the same value. */
3004+ if (h->is_weakalias)
3005+ {
3006+ struct elf_link_hash_entry *def = weakdef (h);
3007+ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
3008+ h->root.u.def.section = def->root.u.def.section;
3009+ h->root.u.def.value = def->root.u.def.value;
3010+ return true;
3011+ }
3012+
3013+ /* This is a reference to a symbol defined by a dynamic object which
3014+ is not a function. */
3015+
3016+ /* If we are creating a shared library, we must presume that the
3017+ only references to the symbol are via the global offset table.
3018+ For such cases we need not do anything here; the relocations will
3019+ be handled correctly by relocate_section. */
3020+ if (bfd_link_pic (info))
3021+ return true;
3022+
3023+ /* If there are no references to this symbol that do not use the
3024+ GOT, we don't need to generate a copy reloc. */
3025+ if (!h->non_got_ref)
3026+ return true;
3027+
3028+ /* If -z nocopyreloc was given, we won't generate them either. */
3029+ if (info->nocopyreloc)
3030+ {
3031+ h->non_got_ref = 0;
3032+ return true;
3033+ }
3034+
3035+ eh = (struct elf64_mb_link_hash_entry *) h;
3036+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
3037+ {
3038+ s = p->sec->output_section;
3039+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
3040+ break;
3041+ }
3042+
3043+ /* If we didn't find any dynamic relocs in read-only sections, then
3044+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
3045+ if (p == NULL)
3046+ {
3047+ h->non_got_ref = 0;
3048+ return true;
3049+ }
3050+
3051+ /* We must allocate the symbol in our .dynbss section, which will
3052+ become part of the .bss section of the executable. There will be
3053+ an entry for this symbol in the .dynsym section. The dynamic
3054+ object will contain position independent code, so all references
3055+ from the dynamic object to this symbol will go through the global
3056+ offset table. The dynamic linker will use the .dynsym entry to
3057+ determine the address it must put in the global offset table, so
3058+ both the dynamic object and the regular object will refer to the
3059+ same memory location for the variable. */
3060+
3061+ /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
3062+ to copy the initial value out of the dynamic object and into the
3063+ runtime process image. */
3064+ dynobj = elf_hash_table (info)->dynobj;
3065+ BFD_ASSERT (dynobj != NULL);
3066+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
3067+ {
3068+ htab->srelbss->size += sizeof (Elf64_External_Rela);
3069+ h->needs_copy = 1;
3070+ }
3071+
3072+ /* We need to figure out the alignment required for this symbol. I
3073+ have no idea how ELF linkers handle this. */
3074+ power_of_two = bfd_log2 (h->size);
3075+ if (power_of_two > 3)
3076+ power_of_two = 3;
3077+
3078+ sdynbss = htab->sdynbss;
3079+ /* Apply the required alignment. */
3080+ sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
3081+ if (power_of_two > sdynbss->alignment_power)
3082+ {
3083+ if (! bfd_set_section_alignment (sdynbss, power_of_two))
3084+ return false;
3085+ }
3086+
3087+ /* Define the symbol as being at this point in the section. */
3088+ h->root.u.def.section = s;
3089+ h->root.u.def.value = s->size;
3090+
3091+ /* Increment the section size to make room for the symbol. */
3092+ s->size += h->size;
3093+ return true;
3094+}
3095+
3096+/* Allocate space in .plt, .got and associated reloc sections for
3097+ dynamic relocs. */
3098+
3099+static bool
3100+allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
3101+{
3102+ struct bfd_link_info *info;
3103+ struct elf64_mb_link_hash_table *htab;
3104+ struct elf64_mb_link_hash_entry *eh;
3105+ struct elf64_mb_dyn_relocs *p;
3106+
3107+ if (h->root.type == bfd_link_hash_indirect)
3108+ return true;
3109+
3110+ info = (struct bfd_link_info *) dat;
3111+ htab = elf64_mb_hash_table (info);
3112+ if (htab == NULL)
3113+ return false;
3114+
3115+ if (htab->elf.dynamic_sections_created
3116+ && h->plt.refcount > 0)
3117+ {
3118+ /* Make sure this symbol is output as a dynamic symbol.
3119+ Undefined weak syms won't yet be marked as dynamic. */
3120+ if (h->dynindx == -1
3121+ && !h->forced_local)
3122+ {
3123+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
3124+ return false;
3125+ }
3126+
3127+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
3128+ {
3129+ asection *s = htab->elf.splt;
3130+
3131+ /* The first entry in .plt is reserved. */
3132+ if (s->size == 0)
3133+ s->size = PLT_ENTRY_SIZE;
3134+
3135+ h->plt.offset = s->size;
3136+
3137+ /* If this symbol is not defined in a regular file, and we are
3138+ not generating a shared library, then set the symbol to this
3139+ location in the .plt. This is required to make function
3140+ pointers compare as equal between the normal executable and
3141+ the shared library. */
3142+ if (! bfd_link_pic (info)
3143+ && !h->def_regular)
3144+ {
3145+ h->root.u.def.section = s;
3146+ h->root.u.def.value = h->plt.offset;
3147+ }
3148+
3149+ /* Make room for this entry. */
3150+ s->size += PLT_ENTRY_SIZE;
3151+
3152+ /* We also need to make an entry in the .got.plt section, which
3153+ will be placed in the .got section by the linker script. */
3154+ htab->elf.sgotplt->size += 4;
3155+
3156+ /* We also need to make an entry in the .rel.plt section. */
3157+ htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
3158+ }
3159+ else
3160+ {
3161+ h->plt.offset = (bfd_vma) -1;
3162+ h->needs_plt = 0;
3163+ }
3164+ }
3165+ else
3166+ {
3167+ h->plt.offset = (bfd_vma) -1;
3168+ h->needs_plt = 0;
3169+ }
3170+
3171+ eh = (struct elf64_mb_link_hash_entry *) h;
3172+ if (h->got.refcount > 0)
3173+ {
3174+ unsigned int need;
3175+ asection *s;
3176+
3177+ /* Make sure this symbol is output as a dynamic symbol.
3178+ Undefined weak syms won't yet be marked as dynamic. */
3179+ if (h->dynindx == -1
3180+ && !h->forced_local)
3181+ {
3182+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
3183+ return false;
3184+ }
3185+
3186+ need = 0;
3187+ if ((eh->tls_mask & TLS_TLS) != 0)
3188+ {
3189+ /* Handle TLS Symbol */
3190+ if ((eh->tls_mask & TLS_LD) != 0)
3191+ {
3192+ if (!eh->elf.def_dynamic)
3193+ /* We'll just use htab->tlsld_got.offset. This should
3194+ always be the case. It's a little odd if we have
3195+ a local dynamic reloc against a non-local symbol. */
3196+ htab->tlsld_got.refcount += 1;
3197+ else
3198+ need += 8;
3199+ }
3200+ if ((eh->tls_mask & TLS_GD) != 0)
3201+ need += 8;
3202+ }
3203+ else
3204+ {
3205+ /* Regular (non-TLS) symbol */
3206+ need += 4;
3207+ }
3208+ if (need == 0)
3209+ {
3210+ h->got.offset = (bfd_vma) -1;
3211+ }
3212+ else
3213+ {
3214+ s = htab->elf.sgot;
3215+ h->got.offset = s->size;
3216+ s->size += need;
3217+ htab->elf.srelgot->size += need * (sizeof (Elf64_External_Rela) / 4);
3218+ }
3219+ }
3220+ else
3221+ h->got.offset = (bfd_vma) -1;
3222+
3223+ if (eh->dyn_relocs == NULL)
3224+ return true;
3225+
3226+ /* In the shared -Bsymbolic case, discard space allocated for
3227+ dynamic pc-relative relocs against symbols which turn out to be
3228+ defined in regular objects. For the normal shared case, discard
3229+ space for pc-relative relocs that have become local due to symbol
3230+ visibility changes. */
3231+
3232+ if (bfd_link_pic (info))
3233+ {
3234+ if (h->def_regular
3235+ && (h->forced_local
3236+ || info->symbolic))
3237+ {
3238+ struct elf64_mb_dyn_relocs **pp;
3239+
3240+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
3241+ {
3242+ p->count -= p->pc_count;
3243+ p->pc_count = 0;
3244+ if (p->count == 0)
3245+ *pp = p->next;
3246+ else
3247+ pp = &p->next;
3248+ }
3249+ }
3250+ else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
3251+ h->dyn_relocs = NULL;
3252+ }
3253+ else
3254+ {
3255+ /* For the non-shared case, discard space for relocs against
3256+ symbols which turn out to need copy relocs or are not
3257+ dynamic. */
3258+
3259+ if (!h->non_got_ref
3260+ && ((h->def_dynamic
3261+ && !h->def_regular)
3262+ || (htab->elf.dynamic_sections_created
3263+ && (h->root.type == bfd_link_hash_undefweak
3264+ || h->root.type == bfd_link_hash_undefined))))
3265+ {
3266+ /* Make sure this symbol is output as a dynamic symbol.
3267+ Undefined weak syms won't yet be marked as dynamic. */
3268+ if (h->dynindx == -1
3269+ && !h->forced_local)
3270+ {
3271+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
3272+ return false;
3273+ }
3274+
3275+ /* If that succeeded, we know we'll be keeping all the
3276+ relocs. */
3277+ if (h->dynindx != -1)
3278+ goto keep;
3279+ }
3280+
3281+ h->dyn_relocs = NULL;
3282+
3283+ keep: ;
3284+ }
3285+
3286+ /* Finally, allocate space. */
3287+ for (p = h->dyn_relocs; p != NULL; p = p->next)
3288+ {
3289+ asection *sreloc = elf_section_data (p->sec)->sreloc;
3290+ sreloc->size += p->count * sizeof (Elf64_External_Rela);
3291+ }
3292+
3293+ return true;
3294+}
3295+
3296+/* Set the sizes of the dynamic sections. */
3297+
3298+static bool
3299+microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
3300+ struct bfd_link_info *info)
3301+{
3302+ struct elf64_mb_link_hash_table *htab;
3303+ bfd *dynobj;
3304+ asection *s;
3305+ bfd *ibfd;
3306+
3307+ htab = elf64_mb_hash_table (info);
3308+ if (htab == NULL)
3309+ return false;
3310+
3311+ dynobj = htab->elf.dynobj;
3312+ BFD_ASSERT (dynobj != NULL);
3313+
3314+ /* Set up .got offsets for local syms, and space for local dynamic
3315+ relocs. */
3316+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
3317+ {
3318+ bfd_signed_vma *local_got;
3319+ bfd_signed_vma *end_local_got;
3320+ bfd_size_type locsymcount;
3321+ Elf_Internal_Shdr *symtab_hdr;
3322+ unsigned char *lgot_masks;
3323+ asection *srel;
3324+
3325+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
3326+ continue;
3327+
3328+ for (s = ibfd->sections; s != NULL; s = s->next)
3329+ {
3330+ struct elf_dyn_relocs *p;
3331+
3332+ for (p = ((struct elf64_mb_dyn_relocs *)
3333+ elf_section_data (s)->local_dynrel);
3334+ p != NULL;
3335+ p = p->next)
3336+ {
3337+ if (!bfd_is_abs_section (p->sec)
3338+ && bfd_is_abs_section (p->sec->output_section))
3339+ {
3340+ /* Input section has been discarded, either because
3341+ it is a copy of a linkonce section or due to
3342+ linker script /DISCARD/, so we'll be discarding
3343+ the relocs too. */
3344+ }
3345+ else if (p->count != 0)
3346+ {
3347+ srel = elf_section_data (p->sec)->sreloc;
3348+ srel->size += p->count * sizeof (Elf64_External_Rela);
3349+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
3350+ info->flags |= DF_TEXTREL;
3351+ }
3352+ }
3353+ }
3354+
3355+ local_got = elf_local_got_refcounts (ibfd);
3356+ if (!local_got)
3357+ continue;
3358+
3359+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3360+ locsymcount = symtab_hdr->sh_info;
3361+ end_local_got = local_got + locsymcount;
3362+ lgot_masks = (unsigned char *) end_local_got;
3363+ s = htab->elf.sgot;
3364+ srel = htab->elf.srelgot;
3365+
3366+ for (; local_got < end_local_got; ++local_got, ++lgot_masks)
3367+ {
3368+ if (*local_got > 0)
3369+ {
3370+ unsigned int need = 0;
3371+ if ((*lgot_masks & TLS_TLS) != 0)
3372+ {
3373+ if ((*lgot_masks & TLS_GD) != 0)
3374+ need += 8;
3375+ if ((*lgot_masks & TLS_LD) != 0)
3376+ htab->tlsld_got.refcount += 1;
3377+ }
3378+ else
3379+ need += 4;
3380+
3381+ if (need == 0)
3382+ {
3383+ *local_got = (bfd_vma) -1;
3384+ }
3385+ else
3386+ {
3387+ *local_got = s->size;
3388+ s->size += need;
3389+ if (bfd_link_pic (info))
3390+ srel->size += need * (sizeof (Elf64_External_Rela) / 4);
3391+ }
3392+ }
3393+ else
3394+ *local_got = (bfd_vma) -1;
3395+ }
3396+ }
3397+
3398+ /* Allocate global sym .plt and .got entries, and space for global
3399+ sym dynamic relocs. */
3400+ elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
3401+
3402+ if (htab->tlsld_got.refcount > 0)
3403+ {
3404+ htab->tlsld_got.offset = htab->elf.sgot->size;
3405+ htab->elf.sgot->size += 8;
3406+ if (bfd_link_pic (info))
3407+ htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
3408+ }
3409+ else
3410+ htab->tlsld_got.offset = (bfd_vma) -1;
3411+
3412+ if (elf_hash_table (info)->dynamic_sections_created)
3413+ {
3414+ /* Make space for the trailing nop in .plt. */
3415+ if (htab->elf.splt->size > 0)
3416+ htab->elf.splt->size += 4;
3417+ }
3418+
3419+ /* The check_relocs and adjust_dynamic_symbol entry points have
3420+ determined the sizes of the various dynamic sections. Allocate
3421+ memory for them. */
3422+ for (s = dynobj->sections; s != NULL; s = s->next)
3423+ {
3424+ const char *name;
3425+ bool strip = false;
3426+
3427+ if ((s->flags & SEC_LINKER_CREATED) == 0)
3428+ continue;
3429+
3430+ /* It's OK to base decisions on the section name, because none
3431+ of the dynobj section names depend upon the input files. */
3432+ name = bfd_section_name (s);
3433+
3434+ if (startswith (name, ".rela"))
3435+ {
3436+ if (s->size == 0)
3437+ {
3438+ /* If we don't need this section, strip it from the
3439+ output file. This is to handle .rela.bss and
3440+ .rela.plt. We must create it in
3441+ create_dynamic_sections, because it must be created
3442+ before the linker maps input sections to output
3443+ sections. The linker does that before
3444+ adjust_dynamic_symbol is called, and it is that
3445+ function which decides whether anything needs to go
3446+ into these sections. */
3447+ strip = true;
3448+ }
3449+ else
3450+ {
3451+ /* We use the reloc_count field as a counter if we need
3452+ to copy relocs into the output file. */
3453+ s->reloc_count = 0;
3454+ }
3455+ }
3456+ else if (s != htab->elf.splt
3457+ && s != htab->elf.sgot
3458+ && s != htab->elf.sgotplt
3459+ && s != htab->elf.sdynbss
3460+ && s != htab->elf.sdynrelro)
3461+ {
3462+ /* It's not one of our sections, so don't allocate space. */
3463+ continue;
3464+ }
3465+
3466+ if (strip)
3467+ {
3468+ s->flags |= SEC_EXCLUDE;
3469+ continue;
3470+ }
3471+
3472+ /* Allocate memory for the section contents. */
3473+ /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3474+ Unused entries should be reclaimed before the section's contents
3475+ are written out, but at the moment this does not happen. Thus in
3476+ order to prevent writing out garbage, we initialise the section's
3477+ contents to zero. */
3478+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3479+ if (s->contents == NULL && s->size != 0)
3480+ return false;
3481+ }
3482+
3483+ /* ??? Force DF_BIND_NOW? */
3484+ info->flags |= DF_BIND_NOW;
3485+ return _bfd_elf_add_dynamic_tags (output_bfd, info, true);
3486+}
3487+
3488+/* Finish up dynamic symbol handling. We set the contents of various
3489+ dynamic sections here. */
3490+
3491+static bool
3492+microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
3493+ struct bfd_link_info *info,
3494+ struct elf_link_hash_entry *h,
3495+ Elf_Internal_Sym *sym)
3496+{
3497+ struct elf64_mb_link_hash_table *htab;
3498+ struct elf64_mb_link_hash_entry *eh = elf64_mb_hash_entry(h);
3499+
3500+ htab = elf64_mb_hash_table (info);
3501+ if (htab == NULL)
3502+ return false;
3503+
3504+ if (h->plt.offset != (bfd_vma) -1)
3505+ {
3506+ asection *splt;
3507+ asection *srela;
3508+ asection *sgotplt;
3509+ Elf_Internal_Rela rela;
3510+ bfd_byte *loc;
3511+ bfd_vma plt_index;
3512+ bfd_vma got_offset;
3513+ bfd_vma got_addr;
3514+
3515+ /* This symbol has an entry in the procedure linkage table. Set
3516+ it up. */
3517+ BFD_ASSERT (h->dynindx != -1);
3518+
3519+ splt = htab->elf.splt;
3520+ srela = htab->elf.srelplt;
3521+ sgotplt = htab->elf.sgotplt;
3522+ BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
3523+
3524+ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
3525+ got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
3526+ got_addr = got_offset;
3527+
3528+ /* For non-PIC objects we need absolute address of the GOT entry. */
3529+ if (!bfd_link_pic (info))
3530+ got_addr += sgotplt->output_section->vma + sgotplt->output_offset;
3531+
3532+ /* Fill in the entry in the procedure linkage table. */
3533+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
3534+ splt->contents + h->plt.offset);
3535+ if (bfd_link_pic (info))
3536+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
3537+ splt->contents + h->plt.offset + 4);
3538+ else
3539+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
3540+ splt->contents + h->plt.offset + 4);
3541+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
3542+ splt->contents + h->plt.offset + 8);
3543+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
3544+ splt->contents + h->plt.offset + 12);
3545+
3546+ /* Any additions to the .got section??? */
3547+ /* bfd_put_32 (output_bfd,
3548+ splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3549+ sgotplt->contents + got_offset); */
3550+
3551+ /* Fill in the entry in the .rela.plt section. */
3552+ rela.r_offset = (sgotplt->output_section->vma
3553+ + sgotplt->output_offset
3554+ + got_offset);
3555+ rela.r_info = ELF64_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
3556+ rela.r_addend = 0;
3557+ loc = srela->contents;
3558+ loc += plt_index * sizeof (Elf64_External_Rela);
3559+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
3560+
3561+ if (!h->def_regular)
3562+ {
3563+ /* Mark the symbol as undefined, rather than as defined in
3564+ the .plt section. Zero the value. */
3565+ sym->st_shndx = SHN_UNDEF;
3566+ sym->st_value = 0;
3567+ }
3568+ }
3569+
3570+ /* h->got.refcount to be checked ? */
3571+ if (h->got.offset != (bfd_vma) -1 &&
3572+ ! ((h->got.offset & 1) ||
3573+ IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
3574+ {
3575+ asection *sgot;
3576+ asection *srela;
3577+ bfd_vma offset;
3578+
3579+ /* This symbol has an entry in the global offset table. Set it
3580+ up. */
3581+
3582+ sgot = htab->elf.sgot;
3583+ srela = htab->elf.srelgot;
3584+ BFD_ASSERT (sgot != NULL && srela != NULL);
3585+
3586+ offset = (sgot->output_section->vma + sgot->output_offset
3587+ + (h->got.offset &~ (bfd_vma) 1));
3588+
3589+ /* If this is a -Bsymbolic link, and the symbol is defined
3590+ locally, we just want to emit a RELATIVE reloc. Likewise if
3591+ the symbol was forced to be local because of a version file.
3592+ The entry in the global offset table will already have been
3593+ initialized in the relocate_section function. */
3594+ if (bfd_link_pic (info)
3595+ && ((info->symbolic && h->def_regular)
3596+ || h->dynindx == -1))
3597+ {
3598+ asection *sec = h->root.u.def.section;
3599+ bfd_vma value;
3600+
3601+ value = h->root.u.def.value;
3602+ if (sec->output_section != NULL)
3603+ /* PR 21180: If the output section is NULL, then the symbol is no
3604+ longer needed, and in theory the GOT entry is redundant. But
3605+ it is too late to change our minds now... */
3606+ value += sec->output_section->vma + sec->output_offset;
3607+
3608+ microblaze_elf_output_dynamic_relocation (output_bfd,
3609+ srela, srela->reloc_count++,
3610+ /* symindex= */ 0,
3611+ R_MICROBLAZE_REL, offset,
3612+ value);
3613+ }
3614+ else
3615+ {
3616+ microblaze_elf_output_dynamic_relocation (output_bfd,
3617+ srela, srela->reloc_count++,
3618+ h->dynindx,
3619+ R_MICROBLAZE_GLOB_DAT,
3620+ offset, 0);
3621+ }
3622+
3623+ bfd_put_32 (output_bfd, (bfd_vma) 0,
3624+ sgot->contents + (h->got.offset &~ (bfd_vma) 1));
3625+ }
3626+
3627+ if (h->needs_copy)
3628+ {
3629+ asection *s;
3630+ Elf_Internal_Rela rela;
3631+ bfd_byte *loc;
3632+
3633+ /* This symbols needs a copy reloc. Set it up. */
3634+
3635+ BFD_ASSERT (h->dynindx != -1);
3636+
3637+ rela.r_offset = (h->root.u.def.value
3638+ + h->root.u.def.section->output_section->vma
3639+ + h->root.u.def.section->output_offset);
3640+ rela.r_info = ELF64_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
3641+ rela.r_addend = 0;
3642+ if (h->root.u.def.section == htab->elf.sdynrelro)
3643+ s = htab->elf.sreldynrelro;
3644+ else
3645+ s = htab->elf.srelbss;
3646+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
3647+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3648+ }
3649+
3650+ /* Mark some specially defined symbols as absolute. */
3651+ if (h == htab->elf.hdynamic
3652+ || h == htab->elf.hgot
3653+ || h == htab->elf.hplt)
3654+ sym->st_shndx = SHN_ABS;
3655+
3656+ return true;
3657+}
3658+
3659+
3660+/* Finish up the dynamic sections. */
3661+
3662+static bool
3663+microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
3664+ struct bfd_link_info *info)
3665+{
3666+ bfd *dynobj;
3667+ asection *sdyn, *sgot;
3668+ struct elf64_mb_link_hash_table *htab;
3669+
3670+ htab = elf64_mb_hash_table (info);
3671+ if (htab == NULL)
3672+ return false;
3673+
3674+ dynobj = htab->elf.dynobj;
3675+
3676+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3677+
3678+ if (htab->elf.dynamic_sections_created)
3679+ {
3680+ asection *splt;
3681+ Elf64_External_Dyn *dyncon, *dynconend;
3682+
3683+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
3684+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
3685+ for (; dyncon < dynconend; dyncon++)
3686+ {
3687+ Elf_Internal_Dyn dyn;
3688+ asection *s;
3689+ bool size;
3690+
3691+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
3692+
3693+ switch (dyn.d_tag)
3694+ {
3695+ case DT_PLTGOT:
3696+ s = htab->elf.sgotplt;
3697+ size = false;
3698+ break;
3699+
3700+ case DT_PLTRELSZ:
3701+ s = htab->elf.srelplt;
3702+ size = true;
3703+ break;
3704+
3705+ case DT_JMPREL:
3706+ s = htab->elf.srelplt;
3707+ size = false;
3708+ break;
3709+
3710+ default:
3711+ continue;
3712+ }
3713+
3714+ if (s == NULL)
3715+ dyn.d_un.d_val = 0;
3716+ else
3717+ {
3718+ if (!size)
3719+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3720+ else
3721+ dyn.d_un.d_val = s->size;
3722+ }
3723+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
3724+ }
3725+
3726+ splt = htab->elf.splt;
3727+ BFD_ASSERT (splt != NULL && sdyn != NULL);
3728+
3729+ /* Clear the first entry in the procedure linkage table,
3730+ and put a nop in the last four bytes. */
3731+ if (splt->size > 0)
3732+ {
3733+ memset (splt->contents, 0, PLT_ENTRY_SIZE);
3734+ bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
3735+ splt->contents + splt->size - 4);
3736+
3737+ if (splt->output_section != bfd_abs_section_ptr)
3738+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
3739+ }
3740+ }
3741+
3742+ /* Set the first entry in the global offset table to the address of
3743+ the dynamic section. */
3744+ sgot = htab->elf.sgotplt;
3745+ if (sgot && sgot->size > 0)
3746+ {
3747+ if (sdyn == NULL)
3748+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3749+ else
3750+ bfd_put_32 (output_bfd,
3751+ sdyn->output_section->vma + sdyn->output_offset,
3752+ sgot->contents);
3753+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3754+ }
3755+
3756+ if (htab->elf.sgot && htab->elf.sgot->size > 0)
3757+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
3758+
3759+ return true;
3760+}
3761+
3762+/* Hook called by the linker routine which adds symbols from an object
3763+ file. We use it to put .comm items in .sbss, and not .bss. */
3764+
3765+static bool
3766+microblaze_elf_add_symbol_hook (bfd *abfd,
3767+ struct bfd_link_info *info,
3768+ Elf_Internal_Sym *sym,
3769+ const char **namep ATTRIBUTE_UNUSED,
3770+ flagword *flagsp ATTRIBUTE_UNUSED,
3771+ asection **secp,
3772+ bfd_vma *valp)
3773+{
3774+ if (sym->st_shndx == SHN_COMMON
3775+ && !bfd_link_relocatable (info)
3776+ && sym->st_size <= elf_gp_size (abfd))
3777+ {
3778+ /* Common symbols less than or equal to -G nn bytes are automatically
3779+ put into .sbss. */
3780+ *secp = bfd_make_section_old_way (abfd, ".sbss");
3781+ if (*secp == NULL
3782+ || !bfd_set_section_flags (*secp, SEC_IS_COMMON | SEC_SMALL_DATA))
3783+ return false;
3784+
3785+ *valp = sym->st_size;
3786+ }
3787+
3788+ return true;
3789+}
3790+
3791+#define TARGET_LITTLE_SYM microblaze_elf64_le_vec
3792+#define TARGET_LITTLE_NAME "elf64-microblazeel"
3793+
3794+#define TARGET_BIG_SYM microblaze_elf64_vec
3795+#define TARGET_BIG_NAME "elf64-microblaze"
3796+
3797+#define ELF_ARCH bfd_arch_microblaze
3798+#define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3799+#define ELF_MACHINE_CODE EM_MICROBLAZE
3800+#define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3801+#define ELF_MAXPAGESIZE 0x1000
3802+#define elf_info_to_howto microblaze_elf_info_to_howto
3803+#define elf_info_to_howto_rel NULL
3804+
3805+#define bfd_elf64_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3806+#define bfd_elf64_bfd_is_local_label_name microblaze_elf_is_local_label_name
3807+#define bfd_elf64_new_section_hook microblaze_elf_new_section_hook
3808+#define elf_backend_relocate_section microblaze_elf_relocate_section
3809+#define bfd_elf64_bfd_relax_section microblaze_elf_relax_section
3810+#define bfd_elf64_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data
3811+#define bfd_elf64_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3812+
3813+#define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3814+#define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
3815+#define elf_backend_check_relocs microblaze_elf_check_relocs
3816+#define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3817+#define bfd_elf64_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3818+#define elf_backend_can_gc_sections 1
3819+#define elf_backend_can_refcount 1
3820+#define elf_backend_want_got_plt 1
3821+#define elf_backend_plt_readonly 1
3822+#define elf_backend_got_header_size 12
3823+#define elf_backend_want_dynrelro 1
3824+#define elf_backend_rela_normal 1
3825+#define elf_backend_dtrel_excludes_plt 1
3826+
3827+#define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3828+#define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
3829+#define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3830+#define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3831+#define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3832+#define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3833+
3834+#include "elf64-target.h"
3835diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
3836index 7cbbc8986a1..597507e53cd 100644
3837--- a/gdb/microblaze-tdep.c
3838+++ b/gdb/microblaze-tdep.c
3839@@ -65,8 +65,95 @@
3840 #define IS_SAVE_HIDDEN_PTR(op, rd, ra, rb) \
3841 ((op == add || op == addik) && ra == MICROBLAZE_FIRST_ARGREG && rb == 0)
3842
3843+static const char *microblaze_abi_string;
3844+
3845+static const char *const microblaze_abi_strings[] = {
3846+ "auto",
3847+ "m64",
3848+};
3849+
3850+enum microblaze_abi
3851+microblaze_abi (struct gdbarch *gdbarch)
3852+{
3853+ microblaze_gdbarch_tdep *tdep = (microblaze_gdbarch_tdep *) gdbarch_tdep (gdbarch);
3854+ return tdep->microblaze_abi;
3855+}
3856 /* The registers of the Xilinx microblaze processor. */
3857
3858+ static struct cmd_list_element *setmicroblazecmdlist = NULL;
3859+ static struct cmd_list_element *showmicroblazecmdlist = NULL;
3860+
3861+static void
3862+microblaze_abi_update (const char *ignore_args,
3863+ int from_tty, struct cmd_list_element *c)
3864+{
3865+ struct gdbarch_info info;
3866+
3867+ /* Force the architecture to update, and (if it's a microblaze architecture)
3868+ * microblaze_gdbarch_init will take care of the rest. */
3869+// gdbarch_info_init (&info);
3870+ gdbarch_update_p (info);
3871+}
3872+
3873+
3874+static enum microblaze_abi
3875+global_microblaze_abi (void)
3876+{
3877+ int i;
3878+
3879+ for (i = 0; microblaze_abi_strings[i] != NULL; i++)
3880+ if (microblaze_abi_strings[i] == microblaze_abi_string)
3881+ return (enum microblaze_abi) i;
3882+
3883+// internal_error (__FILE__, __LINE__, _("unknown ABI string"));
3884+}
3885+
3886+static void
3887+show_microblaze_abi (struct ui_file *file,
3888+ int from_tty,
3889+ struct cmd_list_element *ignored_cmd,
3890+ const char *ignored_value)
3891+{
3892+ enum microblaze_abi global_abi = global_microblaze_abi ();
3893+ enum microblaze_abi actual_abi = microblaze_abi (target_gdbarch ());
3894+ const char *actual_abi_str = microblaze_abi_strings[actual_abi];
3895+
3896+#if 1
3897+ if (global_abi == MICROBLAZE_ABI_AUTO)
3898+ fprintf_filtered
3899+ (file,
3900+ "The microblaze ABI is set automatically (currently \"%s\").\n",
3901+ actual_abi_str);
3902+ else if (global_abi == actual_abi)
3903+ fprintf_filtered
3904+ (file,
3905+ "The microblaze ABI is assumed to be \"%s\" (due to user setting).\n",
3906+ actual_abi_str);
3907+ else
3908+ {
3909+#endif
3910+ /* Probably shouldn't happen... */
3911+ fprintf_filtered (file,
3912+ "The (auto detected) microblaze ABI \"%s\" is in use "
3913+ "even though the user setting was \"%s\".\n",
3914+ actual_abi_str, microblaze_abi_strings[global_abi]);
3915+ }
3916+}
3917+
3918+static void
3919+show_microblaze_command (const char *args, int from_tty)
3920+{
3921+ help_list (showmicroblazecmdlist, "show microblaze ", all_commands, gdb_stdout);
3922+}
3923+
3924+static void
3925+set_microblaze_command (const char *args, int from_tty)
3926+{
3927+ printf_unfiltered
3928+ ("\"set microblaze\" must be followed by an appropriate subcommand.\n");
3929+ help_list (setmicroblazecmdlist, "set microblaze ", all_commands, gdb_stdout);
3930+}
3931+
3932 static const char * const microblaze_register_names[] =
3933 {
3934 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3935@@ -85,9 +172,21 @@ static const char * const microblaze_register_names[] =
3936 static unsigned int microblaze_debug_flag = 0;
3937 int reg_size = 4;
3938
3939+unsigned int
3940+microblaze_abi_regsize (struct gdbarch *gdbarch)
3941+{
3942+ switch (microblaze_abi (gdbarch))
3943+ {
3944+ case MICROBLAZE_ABI_M64:
3945+ return 8;
3946+ default:
3947+ return 4;
3948+ }
3949+}
3950+
3951 #define microblaze_debug(fmt, ...) \
3952 debug_prefixed_printf_cond_nofunc (microblaze_debug_flag, "MICROBLAZE", \
3953- fmt, ## __VA_ARGS__)
3954+ fmt, ## __VA_ARGS__)
3955
3956
3957 /* Return the name of register REGNUM. */
3958@@ -867,15 +966,30 @@ static struct gdbarch *
3959 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
3960 {
3961 tdesc_arch_data_up tdesc_data;
3962+ enum microblaze_abi microblaze_abi, found_abi, wanted_abi;
3963 const struct target_desc *tdesc = info.target_desc;
3964
3965+ /* What has the user specified from the command line? */
3966+ wanted_abi = global_microblaze_abi ();
3967+ if (gdbarch_debug)
3968+ fprintf_unfiltered (gdb_stdlog, "microblaze_gdbarch_init: wanted_abi = %d\n",
3969+ wanted_abi);
3970+ if (wanted_abi != MICROBLAZE_ABI_AUTO)
3971+ microblaze_abi = wanted_abi;
3972+
3973 /* If there is already a candidate, use it. */
3974 arches = gdbarch_list_lookup_by_info (arches, &info);
3975- if (arches != NULL)
3976+ if ((arches != NULL) && (microblaze_abi != MICROBLAZE_ABI_M64))
3977 return arches->gdbarch;
3978+
3979+ if (microblaze_abi == MICROBLAZE_ABI_M64)
3980+ {
3981+ tdesc = tdesc_microblaze64;
3982+ reg_size = 8;
3983+ }
3984 if (tdesc == NULL)
3985 {
3986- if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
3987+ if ((info.bfd_arch_info->mach == bfd_mach_microblaze64) || (microblaze_abi == MICROBLAZE_ABI_M64))
3988 {
3989 tdesc = tdesc_microblaze64;
3990 reg_size = 8;
3991@@ -890,7 +1004,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
3992 int valid_p;
3993 int i;
3994
3995- if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
3996+ if ((info.bfd_arch_info->mach == bfd_mach_microblaze64) || (microblaze_abi == MICROBLAZE_ABI_M64))
3997 feature = tdesc_find_feature (tdesc,
3998 "org.gnu.gdb.microblaze64.core");
3999 else
4000@@ -904,7 +1018,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
4001 for (i = 0; i < MICROBLAZE_NUM_REGS; i++)
4002 valid_p &= tdesc_numbered_register (feature, tdesc_data.get(), i,
4003 microblaze_register_names[i]);
4004- if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
4005+ if ((info.bfd_arch_info->mach == bfd_mach_microblaze64) || (microblaze_abi == MICROBLAZE_ABI_M64))
4006 feature = tdesc_find_feature (tdesc,
4007 "org.gnu.gdb.microblaze64.stack-protect");
4008 else
4009@@ -954,7 +1068,8 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
4010 set_gdbarch_ptr_bit (gdbarch, 64);
4011 break;
4012 }
4013-
4014+ if(microblaze_abi == MICROBLAZE_ABI_M64)
4015+ set_gdbarch_ptr_bit (gdbarch, 64);
4016
4017 /* Map Dwarf2 registers to GDB registers. */
4018 set_gdbarch_dwarf2_reg_to_regnum (gdbarch, microblaze_dwarf2_reg_to_regnum);
4019@@ -1014,6 +1129,38 @@ _initialize_microblaze_tdep ()
4020 {
4021 gdbarch_register (bfd_arch_microblaze, microblaze_gdbarch_init);
4022
4023+// static struct cmd_list_element *setmicroblazecmdlist = NULL;
4024+// static struct cmd_list_element *showmicroblazecmdlist = NULL;
4025+
4026+ /* Add root prefix command for all "set microblaze"/"show microblaze" commands. */
4027+
4028+ add_setshow_prefix_cmd ("microblaze", no_class,
4029+ _("Various microblaze specific commands."),
4030+ _("Various microblaze specific commands."),
4031+ &setmicroblazecmdlist,&showmicroblazecmdlist,
4032+ &setlist,&showlist);
4033+#if 0
4034+ add_prefix_cmd ("microblaze", no_class, set_microblaze_command,
4035+ _("Various microblaze specific commands."),
4036+ &setmicroblazecmdlist, "set microblaze ", 0, &setlist);
4037+
4038+ add_prefix_cmd ("microblaze", no_class, show_microblaze_command,
4039+ _("Various microblaze specific commands."),
4040+ &showmicroblazecmdlist, "show microblaze ", 0, &showlist);
4041+#endif
4042+
4043+ /* Allow the user to override the ABI. */
4044+ add_setshow_enum_cmd ("abi", class_obscure, microblaze_abi_strings,
4045+ &microblaze_abi_string, _("\
4046+Set the microblaze ABI used by this program."), _("\
4047+Show the microblaze ABI used by this program."), _("\
4048+This option can be set to one of:\n\
4049+ auto - the default ABI associated with the current binary\n\
4050+ m64"),
4051+ microblaze_abi_update,
4052+ show_microblaze_abi,
4053+ &setmicroblazecmdlist, &showmicroblazecmdlist);
4054+
4055 initialize_tdesc_microblaze_with_stack_protect ();
4056 initialize_tdesc_microblaze ();
4057 initialize_tdesc_microblaze64_with_stack_protect ();
4058@@ -1028,5 +1175,4 @@ When non-zero, microblaze specific debugging is enabled."),
4059 NULL,
4060 &setdebuglist, &showdebuglist);
4061
4062-
4063 }
4064diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
4065index 81f7f30cb8e..f6cef7c9a33 100644
4066--- a/gdb/microblaze-tdep.h
4067+++ b/gdb/microblaze-tdep.h
4068@@ -19,9 +19,17 @@
4069
4070 #ifndef MICROBLAZE_TDEP_H
4071 #define MICROBLAZE_TDEP_H 1
4072-
4073+#include "objfiles.h"
4074 #include "gdbarch.h"
4075
4076+struct gdbarch;
4077+enum microblaze_abi
4078+ {
4079+ MICROBLAZE_ABI_AUTO = 0,
4080+ MICROBLAZE_ABI_M64,
4081+ };
4082+
4083+enum microblaze_abi microblaze_abi (struct gdbarch *gdbarch);
4084 /* Microblaze architecture-specific information. */
4085 struct microblaze_gregset
4086 {
4087@@ -35,11 +43,14 @@ struct microblaze_gdbarch_tdep : gdbarch_tdep_base
4088 {
4089 int dummy; // declare something.
4090
4091+ enum microblaze_abi microblaze_abi {};
4092+ enum microblaze_abi found_abi {};
4093 /* Register sets. */
4094 struct regset *gregset;
4095 size_t sizeof_gregset;
4096 struct regset *fpregset;
4097 size_t sizeof_fpregset;
4098+ int register_size;
4099 };
4100
4101 /* Register numbers. */
4102--
41032.34.1
4104
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0009-Depth-Total-number-of-inline-functions-refer-inline-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0009-Depth-Total-number-of-inline-functions-refer-inline-.patch
new file mode 100644
index 00000000..6ec184d0
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0009-Depth-Total-number-of-inline-functions-refer-inline-.patch
@@ -0,0 +1,74 @@
1From bd2d24cf21943babe2e0a73cf68da273a38d7058 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Thu, 21 Jul 2022 11:45:01 +0530
4Subject: [PATCH 09/53] =?UTF-8?q?Depth:=20Total=20number=20of=20inline=20f?=
5 =?UTF-8?q?unctions=20[refer=20inline-frame.c]=20state->skipped=5Fframes?=
6 =?UTF-8?q?=20:=20Number=20of=20inline=20functions=20skipped.=20the=20curr?=
7 =?UTF-8?q?ent=20unwind=5Fpc=20is=20causing=20an=20issue=20when=20we=20try?=
8 =?UTF-8?q?=20to=20step=20into=20inline=20functions[Depth=20is=20becoming?=
9 =?UTF-8?q?=200].=20It=E2=80=99s=20incrementing=20pc=20by=208=20even=20wit?=
10 =?UTF-8?q?h=20si=20instruction.?=
11MIME-Version: 1.0
12Content-Type: text/plain; charset=UTF-8
13Content-Transfer-Encoding: 8bit
14
15Signed-off-by: Aayush Misra <aayushm@amd.com>
16---
17 gdb/features/microblaze64.xml | 1 +
18 gdb/microblaze-tdep.c | 14 +++-----------
19 2 files changed, 4 insertions(+), 11 deletions(-)
20
21diff --git a/gdb/features/microblaze64.xml b/gdb/features/microblaze64.xml
22index 515d18e65cf..9c1b7d22003 100644
23--- a/gdb/features/microblaze64.xml
24+++ b/gdb/features/microblaze64.xml
25@@ -7,5 +7,6 @@
26
27 <!DOCTYPE target SYSTEM "gdb-target.dtd">
28 <target>
29+ <architecture>microblaze64</architecture>
30 <xi:include href="microblaze64-core.xml"/>
31 </target>
32diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
33index 597507e53cd..aed5f2ec30c 100644
34--- a/gdb/microblaze-tdep.c
35+++ b/gdb/microblaze-tdep.c
36@@ -513,16 +513,8 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
37 static CORE_ADDR
38 microblaze_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
39 {
40- gdb_byte buf[4];
41 CORE_ADDR pc;
42-
43- frame_unwind_register (next_frame, MICROBLAZE_PC_REGNUM, buf);
44- pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
45- /* For sentinel frame, return address is actual PC. For other frames,
46- return address is pc+8. This is a workaround because gcc does not
47- generate correct return address in CIE. */
48- if (frame_relative_level (next_frame) >= 0)
49- pc += 8;
50+ pc=frame_unwind_register_unsigned (next_frame, MICROBLAZE_PC_REGNUM);
51 return pc;
52 }
53
54@@ -553,7 +545,6 @@ microblaze_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
55 ostart_pc = microblaze_analyze_prologue (gdbarch, func_start, 0xffffffffUL,
56 &cache);
57
58-
59 if (ostart_pc > start_pc)
60 return ostart_pc;
61 return start_pc;
62@@ -660,7 +651,8 @@ static const struct frame_unwind microblaze_frame_unwind =
63 microblaze_frame_this_id,
64 microblaze_frame_prev_register,
65 NULL,
66- default_frame_sniffer
67+ default_frame_sniffer,
68+ NULL,
69 };
70
71 static CORE_ADDR
72--
732.34.1
74
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0010-Fix-gdb-14-build-errors-for-microblaze-xilinx-elf-20.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0010-Fix-gdb-14-build-errors-for-microblaze-xilinx-elf-20.patch
new file mode 100644
index 00000000..78e4970b
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0010-Fix-gdb-14-build-errors-for-microblaze-xilinx-elf-20.patch
@@ -0,0 +1,133 @@
1From 3616ef25911d9fa8b5c0e4883f19131da48896d5 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 29 Feb 2024 10:53:04 +0530
4Subject: [PATCH 10/53] Fix gdb-14 build errors for microblaze-xilinx-elf
5 2023.2 merge
6
7Signed-off-by: Aayush Misra <aayushm@amd.com>
8---
9 bfd/elf64-microblaze.c | 12 ++++++++++++
10 gdb/frame.c | 2 +-
11 gdb/microblaze-tdep.c | 17 +++++++++++------
12 3 files changed, 24 insertions(+), 7 deletions(-)
13
14diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
15index 6cd9753a592..119d266f95a 100755
16--- a/bfd/elf64-microblaze.c
17+++ b/bfd/elf64-microblaze.c
18@@ -750,6 +750,18 @@ microblaze_elf_info_to_howto (bfd * abfd,
19 return true;
20 }
21
22+/* Relax table contains information about instructions which can
23+ be removed by relaxation -- replacing a long address with a
24+ short address. */
25+struct relax_table
26+{
27+ /* Address where bytes may be deleted. */
28+ bfd_vma addr;
29+
30+ /* Number of bytes to be deleted. */
31+ size_t size;
32+};
33+
34 struct _microblaze_elf_section_data
35 {
36 struct bfd_elf_section_data elf;
37diff --git a/gdb/frame.c b/gdb/frame.c
38index 859e1a6553d..94bb026c4d9 100644
39--- a/gdb/frame.c
40+++ b/gdb/frame.c
41@@ -1319,7 +1319,7 @@ frame_unwind_register_value (frame_info_ptr next_frame, int regnum)
42 int i;
43
44 const gdb_byte *buf = NULL;
45- if (value_entirely_available(value)) {
46+ if (value->entirely_available()) {
47 gdb::array_view<const gdb_byte> buf = value->contents ();
48 }
49
50diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
51index aed5f2ec30c..e1a7a49eb84 100644
52--- a/gdb/microblaze-tdep.c
53+++ b/gdb/microblaze-tdep.c
54@@ -75,7 +75,7 @@ static const char *const microblaze_abi_strings[] = {
55 enum microblaze_abi
56 microblaze_abi (struct gdbarch *gdbarch)
57 {
58- microblaze_gdbarch_tdep *tdep = (microblaze_gdbarch_tdep *) gdbarch_tdep (gdbarch);
59+ microblaze_gdbarch_tdep *tdep = gdbarch_tdep<microblaze_gdbarch_tdep> (gdbarch);
60 return tdep->microblaze_abi;
61 }
62 /* The registers of the Xilinx microblaze processor. */
63@@ -120,12 +120,12 @@ show_microblaze_abi (struct ui_file *file,
64
65 #if 1
66 if (global_abi == MICROBLAZE_ABI_AUTO)
67- fprintf_filtered
68+ gdb_printf
69 (file,
70 "The microblaze ABI is set automatically (currently \"%s\").\n",
71 actual_abi_str);
72 else if (global_abi == actual_abi)
73- fprintf_filtered
74+ gdb_printf
75 (file,
76 "The microblaze ABI is assumed to be \"%s\" (due to user setting).\n",
77 actual_abi_str);
78@@ -133,7 +133,7 @@ show_microblaze_abi (struct ui_file *file,
79 {
80 #endif
81 /* Probably shouldn't happen... */
82- fprintf_filtered (file,
83+ gdb_printf (file,
84 "The (auto detected) microblaze ABI \"%s\" is in use "
85 "even though the user setting was \"%s\".\n",
86 actual_abi_str, microblaze_abi_strings[global_abi]);
87@@ -934,7 +934,7 @@ microblaze_iterate_over_regset_sections (struct gdbarch *gdbarch,
88 void *cb_data,
89 const struct regcache *regcache)
90 {
91- struct microblaze_gdbarch_tdep *tdep =(microblaze_gdbarch_tdep *) gdbarch_tdep (gdbarch);
92+ microblaze_gdbarch_tdep *tdep = gdbarch_tdep<microblaze_gdbarch_tdep> (gdbarch);
93
94 cb(".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, tdep->gregset, NULL, cb_data);
95
96@@ -942,6 +942,8 @@ microblaze_iterate_over_regset_sections (struct gdbarch *gdbarch,
97 }
98
99
100+#if 0
101+// compilation errors - function is not actually used ?
102 static void
103 make_regs (struct gdbarch *arch)
104 {
105@@ -953,6 +955,7 @@ make_regs (struct gdbarch *arch)
106 set_gdbarch_ptr_bit (arch, 64);
107 }
108 }
109+#endif
110
111 static struct gdbarch *
112 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
113@@ -964,7 +967,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
114 /* What has the user specified from the command line? */
115 wanted_abi = global_microblaze_abi ();
116 if (gdbarch_debug)
117- fprintf_unfiltered (gdb_stdlog, "microblaze_gdbarch_init: wanted_abi = %d\n",
118+ gdb_printf (gdb_stdlog, "microblaze_gdbarch_init: wanted_abi = %d\n",
119 wanted_abi);
120 if (wanted_abi != MICROBLAZE_ABI_AUTO)
121 microblaze_abi = wanted_abi;
122@@ -1038,6 +1041,8 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
123 gdbarch *gdbarch
124 = gdbarch_alloc (&info, gdbarch_tdep_up (new microblaze_gdbarch_tdep));
125
126+ microblaze_gdbarch_tdep *tdep = gdbarch_tdep<microblaze_gdbarch_tdep> (gdbarch);
127+
128 tdep->gregset = NULL;
129 tdep->sizeof_gregset = 0;
130 tdep->fpregset = NULL;
131--
1322.34.1
133
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0011-fix-gdb-microblaze-xilinx-elf-crash-issue-on-invocat.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0011-fix-gdb-microblaze-xilinx-elf-crash-issue-on-invocat.patch
new file mode 100644
index 00000000..d3da41d5
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0011-fix-gdb-microblaze-xilinx-elf-crash-issue-on-invocat.patch
@@ -0,0 +1,28 @@
1From 9037b1a9e862263ba935314e8604a922d14c8dd4 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 29 Feb 2024 10:55:16 +0530
4Subject: [PATCH 11/53] fix gdb microblaze-xilinx-elf crash issue on invocation
5 Regression from merging microblaze 64-bit support
6
7Signed-off-by: Aayush Misra <aayushm@amd.com>
8---
9 gdb/microblaze-tdep.c | 3 +++
10 1 file changed, 3 insertions(+)
11
12diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
13index e1a7a49eb84..f9cb3dfda33 100644
14--- a/gdb/microblaze-tdep.c
15+++ b/gdb/microblaze-tdep.c
16@@ -1124,6 +1124,9 @@ void _initialize_microblaze_tdep ();
17 void
18 _initialize_microblaze_tdep ()
19 {
20+ //Setting abi to auto manually, should be able to modify in 'arch'_gdbarch_init function
21+ microblaze_abi_string = microblaze_abi_strings[0];
22+
23 gdbarch_register (bfd_arch_microblaze, microblaze_gdbarch_init);
24
25 // static struct cmd_list_element *setmicroblazecmdlist = NULL;
26--
272.34.1
28
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0012-Add-mlittle-endian-and-mbig-endian-flags.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0012-Add-mlittle-endian-and-mbig-endian-flags.patch
new file mode 100644
index 00000000..e1074c85
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0012-Add-mlittle-endian-and-mbig-endian-flags.patch
@@ -0,0 +1,46 @@
1From 05a5677c1b5cd7f109c49e6697b6716f7ac0fb97 Mon Sep 17 00:00:00 2001
2From: nagaraju <nmekala@xilix.com>
3Date: Tue, 19 Mar 2013 17:18:23 +0530
4Subject: [PATCH 12/53] Add mlittle-endian and mbig-endian flags
5
6Added support in gas for mlittle-endian and mbig-endian flags
7as options.
8
9Updated show usage for MicroBlaze specific assembler options
10to include new entries.
11
12Signed-off-by:nagaraju <nmekala@xilix.com>
13Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
14Signed-off-by: Aayush Misra <aayushm@amd.com>
15---
16 gas/config/tc-microblaze.c | 4 ++++
17 1 file changed, 4 insertions(+)
18
19diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
20index c971d187095..62238646a52 100644
21--- a/gas/config/tc-microblaze.c
22+++ b/gas/config/tc-microblaze.c
23@@ -37,6 +37,8 @@
24
25 #define OPTION_EB (OPTION_MD_BASE + 0)
26 #define OPTION_EL (OPTION_MD_BASE + 1)
27+#define OPTION_LITTLE (OPTION_MD_BASE + 2)
28+#define OPTION_BIG (OPTION_MD_BASE + 3)
29
30 void microblaze_generate_symbol (char *sym);
31 static bool check_spl_reg (unsigned *);
32@@ -2565,9 +2567,11 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
33 switch (c)
34 {
35 case OPTION_EB:
36+ case OPTION_BIG:
37 target_big_endian = 1;
38 break;
39 case OPTION_EL:
40+ case OPTION_LITTLE:
41 target_big_endian = 0;
42 break;
43 default:
44--
452.34.1
46
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0013-Disable-the-warning-message-for-eh_frame_hdr.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0013-Disable-the-warning-message-for-eh_frame_hdr.patch
new file mode 100644
index 00000000..31529d0d
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0013-Disable-the-warning-message-for-eh_frame_hdr.patch
@@ -0,0 +1,35 @@
1From a622ee3ff40515edf05a61a77fbcd8999ecf0905 Mon Sep 17 00:00:00 2001
2From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
3Date: Fri, 22 Jun 2012 01:20:20 +0200
4Subject: [PATCH 13/53] Disable the warning message for eh_frame_hdr
5
6Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
7
8Conflicts:
9 bfd/elf-eh-frame.c
10Signed-off-by: Aayush Misra <aayushm@amd.com>
11---
12 bfd/elf-eh-frame.c | 3 +++
13 1 file changed, 3 insertions(+)
14
15diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
16index 9a504234163..5e393558293 100644
17--- a/bfd/elf-eh-frame.c
18+++ b/bfd/elf-eh-frame.c
19@@ -1045,10 +1045,13 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
20 goto success;
21
22 free_no_table:
23+/* FIXME: Remove the microblaze specifics when relaxing gets fixed. */
24+if (bfd_get_arch(abfd) != bfd_arch_microblaze) {
25 _bfd_error_handler
26 /* xgettext:c-format */
27 (_("error in %pB(%pA); no .eh_frame_hdr table will be created"),
28 abfd, sec);
29+}
30 hdr_info->u.dwarf.table = false;
31 free (sec_info);
32 success:
33--
342.34.1
35
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0014-Fix-relaxation-of-assembler-resolved-references-Fixu.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0014-Fix-relaxation-of-assembler-resolved-references-Fixu.patch
new file mode 100644
index 00000000..7574067d
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0014-Fix-relaxation-of-assembler-resolved-references-Fixu.patch
@@ -0,0 +1,48 @@
1From 965a464418e8c8968453206f27763043fb38dc64 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 8 Nov 2016 11:54:08 +0530
4Subject: [PATCH 14/53] Fix relaxation of assembler resolved references,Fixup
5 debug_loc sections after linker relaxation Adds a new reloctype
6 R_MICROBLAZE_32_NONE, used for passing reloc info from the assembler to the
7 linker when the linker manages to fully resolve a local symbol reference.
8
9This is a workaround for design flaws in the assembler to
10linker interface with regards to linker relaxation.
11
12Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
13Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
14
15Conflicts:
16 bfd/elf32-microblaze.c
17 binutils/readelf.c
18 include/elf/microblaze.h
19
20Conflicts:
21 binutils/readelf.c
22
23Conflicts:
24 bfd/elf32-microblaze.c
25Signed-off-by: Aayush Misra <aayushm@amd.com>
26---
27 binutils/readelf.c | 5 +++++
28 1 file changed, 5 insertions(+)
29
30diff --git a/binutils/readelf.c b/binutils/readelf.c
31index 5e4ad6ea6ad..3ca9f3697d1 100644
32--- a/binutils/readelf.c
33+++ b/binutils/readelf.c
34@@ -15288,6 +15288,11 @@ is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
35 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
36 default:
37 return false;
38+ /* REVISIT microblaze-binutils-merge */
39+ case EM_MICROBLAZE:
40+ return reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
41+ || reloc_type == 0 /* R_MICROBLAZE_NONE. */
42+ || reloc_type == 9; /* R_MICROBLAZE_64_NONE. */
43 }
44 }
45
46--
472.34.1
48
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0015-upstream-change-to-garbage-collection-sweep-causes-m.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0015-upstream-change-to-garbage-collection-sweep-causes-m.patch
new file mode 100644
index 00000000..c46af2e7
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0015-upstream-change-to-garbage-collection-sweep-causes-m.patch
@@ -0,0 +1,43 @@
1From 07743ed9395bfea466cdbdf0bbe9566fa93165de Mon Sep 17 00:00:00 2001
2From: David Holsgrove <david.holsgrove@xilinx.com>
3Date: Wed, 27 Feb 2013 13:56:11 +1000
4Subject: [PATCH 15/53] upstream change to garbage collection sweep causes mb
5 regression
6
7Upstream change for PR13177 now clears the def_regular during gc_sweep of a
8section. (All other archs in binutils/bfd/elf32-*.c received an update
9to a warning about unresolvable relocations - this warning is not present
10in binutils/bfd/elf32-microblaze.c, but this warning check would not
11prevent the error being seen)
12
13The visible issue with this change is when running a c++ application
14in Petalinux which links libstdc++.so for exception handling it segfaults
15on execution.
16
17This does not occur if static linking libstdc++.a, so its during the
18relocations for a shared lib with garbage collection this occurs
19
20Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
21
22Conflicts:
23 bfd/elflink.c
24Signed-off-by: Aayush Misra <aayushm@amd.com>
25---
26 bfd/elflink.c | 1 -
27 1 file changed, 1 deletion(-)
28
29diff --git a/bfd/elflink.c b/bfd/elflink.c
30index c2494b3e12e..1f8f54cd4e6 100644
31--- a/bfd/elflink.c
32+++ b/bfd/elflink.c
33@@ -6633,7 +6633,6 @@ elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
34
35 inf = (struct elf_gc_sweep_symbol_info *) data;
36 (*inf->hide_symbol) (inf->info, h, true);
37- h->def_regular = 0;
38 h->ref_regular = 0;
39 h->ref_regular_nonweak = 0;
40 }
41--
422.34.1
43
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0016-Add-new-bit-field-instructions.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0016-Add-new-bit-field-instructions.patch
new file mode 100644
index 00000000..aab6c5d1
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0016-Add-new-bit-field-instructions.patch
@@ -0,0 +1,219 @@
1From 39ef5af3dd4551b24a47c8e48af67478183a7149 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Mon, 18 Jul 2016 12:24:28 +0530
4Subject: [PATCH 16/53] Add new bit-field instructions
5
6This patches adds new bsefi and bsifi instructions.
7BSEFI- The instruction shall extract a bit field from a
8register and place it right-adjusted in the destination register.
9The other bits in the destination register shall be set to zero
10BSIFI- The instruction shall insert a right-adjusted bit field
11from a register at another position in the destination register.
12The rest of the bits in the destination register shall be unchanged
13
14Signed-off-by :Nagaraju Mekala <nmekala@xilix.com>
15
16Conflicts:
17 opcodes/microblaze-dis.c
18
19Conflicts:
20 gas/config/tc-microblaze.c
21 opcodes/microblaze-opc.h
22
23Signed-off-by: Aayush Misra <aayushm@amd.com>
24---
25 gas/config/tc-microblaze.c | 82 ++++++++++++++++----------------------
26 opcodes/microblaze-dis.c | 18 ++++++++-
27 opcodes/microblaze-opc.h | 6 +++
28 3 files changed, 58 insertions(+), 48 deletions(-)
29
30diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
31index 62238646a52..f13efcae979 100644
32--- a/gas/config/tc-microblaze.c
33+++ b/gas/config/tc-microblaze.c
34@@ -1150,88 +1150,76 @@ md_assemble (char * str)
35 inst |= (reg2 << RA_LOW) & RA_MASK;
36 inst |= (immed << IMM_LOW) & IMM5_MASK;
37 break;
38-
39- case INST_TYPE_RD_R1_IMMW_IMMS:
40+ case INST_TYPE_RD_R1_IMM5_IMM5:
41 if (strcmp (op_end, ""))
42- op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
43+ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
44 else
45 {
46- as_fatal (_("Error in statement syntax"));
47- reg1 = 0;
48- }
49-
50+ as_fatal (_("Error in statement syntax"));
51+ reg1 = 0;
52+ }
53 if (strcmp (op_end, ""))
54- op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
55+ op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
56 else
57 {
58- as_fatal (_("Error in statement syntax"));
59- reg2 = 0;
60- }
61+ as_fatal (_("Error in statement syntax"));
62+ reg2 = 0;
63+ }
64
65 /* Check for spl registers. */
66 if (check_spl_reg (&reg1))
67- as_fatal (_("Cannot use special register with this instruction"));
68+ as_fatal (_("Cannot use special register with this instruction"));
69 if (check_spl_reg (&reg2))
70- as_fatal (_("Cannot use special register with this instruction"));
71+ as_fatal (_("Cannot use special register with this instruction"));
72
73 /* Width immediate value. */
74 if (strcmp (op_end, ""))
75- op_end = parse_imm (op_end + 1, &exp, MIN_IMM_WIDTH, MAX_IMM_WIDTH);
76+ op_end = parse_imm (op_end + 1, &exp, MIN_IMM_WIDTH, MAX_IMM_WIDTH);
77 else
78- as_fatal (_("Error in statement syntax"));
79-
80+ as_fatal (_("Error in statement syntax"));
81 if (exp.X_op != O_constant)
82 {
83- as_warn (_(
84- "Symbol used as immediate width value for bit field instruction"));
85- immed = 1;
86- }
87+ as_warn (_("Symbol used as immediate width value for bit field instruction"));
88+ immed = 1;
89+ }
90 else
91- immed = exp.X_add_number;
92-
93+ immed = exp.X_add_number;
94 if (opcode->instr == bsefi && immed > 31)
95- as_fatal (_("Width value must be less than 32"));
96+ as_fatal (_("Width value must be less than 32"));
97
98 /* Shift immediate value. */
99 if (strcmp (op_end, ""))
100- op_end = parse_imm (op_end + 1, &exp, MIN_IMM, MAX_IMM);
101+ op_end = parse_imm (op_end + 1, &exp, MIN_IMM, MAX_IMM);
102 else
103- as_fatal (_("Error in statement syntax"));
104-
105+ as_fatal (_("Error in statement syntax"));
106 if (exp.X_op != O_constant)
107- {
108- as_warn (_(
109- "Symbol used as immediate shift value for bit field instruction"));
110- immed2 = 0;
111- }
112+ {
113+ as_warn (_("Symbol used as immediate shift value for bit field instruction"));
114+ immed2 = 0;
115+ }
116 else
117- {
118- output = frag_more (isize);
119- immed2 = exp.X_add_number;
120- }
121-
122+ {
123+ output = frag_more (isize);
124+ immed2 = exp.X_add_number;
125+ }
126 if (immed2 != (immed2 % 32))
127- {
128- as_warn (_("Shift value greater than 32. using <value %% 32>"));
129- immed2 = immed2 % 32;
130- }
131+ {
132+ as_warn (_("Shift value greater than 32. using <value %% 32>"));
133+ immed2 = immed2 % 32;
134+ }
135
136 /* Check combined value. */
137 if (immed + immed2 > 32)
138- as_fatal (_("Width value + shift value must not be greater than 32"));
139+ as_fatal (_("Width value + shift value must not be greater than 32"));
140
141 inst |= (reg1 << RD_LOW) & RD_MASK;
142 inst |= (reg2 << RA_LOW) & RA_MASK;
143-
144 if (opcode->instr == bsefi)
145- inst |= (immed & IMM5_MASK) << IMM_WIDTH_LOW; /* bsefi */
146+ inst |= (immed & IMM5_MASK) << IMM_WIDTH_LOW; /* bsefi */
147 else
148- inst |= ((immed + immed2 - 1) & IMM5_MASK)
149- << IMM_WIDTH_LOW; /* bsifi */
150-
151+ inst |= ((immed + immed2 - 1) & IMM5_MASK) << IMM_WIDTH_LOW; /* bsifi */
152 inst |= (immed2 << IMM_LOW) & IMM5_MASK;
153 break;
154-
155 case INST_TYPE_R1_R2:
156 if (strcmp (op_end, ""))
157 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
158diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
159index ee447cecc3f..45135f9d264 100644
160--- a/opcodes/microblaze-dis.c
161+++ b/opcodes/microblaze-dis.c
162@@ -113,7 +113,19 @@ get_field_immw (struct string_buf *buf, long instr)
163 }
164
165 static char *
166-get_field_rfsl (struct string_buf *buf, long instr)
167+get_field_imm5width (struct string_buf *buf, long instr)
168+{
169+ char *p = strbuf (buf);
170+
171+ if (instr & 0x00004000)
172+ sprintf (p, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW))); /* bsefi */
173+ else
174+ sprintf (p, "%d", (short)(((instr & IMM5_WIDTH_MASK) >> IMM_WIDTH_LOW) - ((instr & IMM5_MASK) >> IMM_LOW) + 1)); /* bsifi */
175+ return p;
176+}
177+
178+static char *
179+get_field_rfsl (struct string_buf *buf,long instr)
180 {
181 char *p = strbuf (buf);
182
183@@ -462,6 +474,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
184 print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst), get_field_r1(&buf, inst),
185 get_field_immw (&buf, inst), get_field_imms (&buf, inst));
186 break;
187+ /* For bit field insns. */
188+ case INST_TYPE_RD_R1_IMM5_IMM5:
189+ print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst),get_field_r1(&buf, inst),get_field_imm5width (&buf, inst), get_field_imm5 (&buf, inst));
190+ break;
191 /* For tuqula instruction */
192 case INST_TYPE_RD:
193 print_func (stream, "\t%s", get_field_rd (&buf, inst));
194diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
195index afc1220e357..a952b9ac3c2 100644
196--- a/opcodes/microblaze-opc.h
197+++ b/opcodes/microblaze-opc.h
198@@ -67,6 +67,9 @@
199 #define INST_TYPE_RD_R1_IMML 23
200 #define INST_TYPE_R1_IMML 24
201
202+/* For bsefi and bsifi */
203+#define INST_TYPE_RD_R1_IMM5_IMM5 21
204+
205 #define INST_TYPE_NONE 25
206
207
208@@ -586,5 +589,8 @@ char pvr_register_prefix[] = "rpvr";
209 #define MIN_IMML ((long) 0xffffff8000000000L)
210 #define MAX_IMML ((long) 0x0000007fffffffffL)
211
212+#define MIN_IMM_WIDTH ((int) 0x00000001)
213+#define MAX_IMM_WIDTH ((int) 0x00000020)
214+
215 #endif /* MICROBLAZE_OPC */
216
217--
2182.34.1
219
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0017-fixed-bug-in-GCC-so-that-It-will-support-.long-0U-an.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0017-fixed-bug-in-GCC-so-that-It-will-support-.long-0U-an.patch
new file mode 100644
index 00000000..f679971d
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0017-fixed-bug-in-GCC-so-that-It-will-support-.long-0U-an.patch
@@ -0,0 +1,34 @@
1From ea27bc6ec052b20f4c193054ecdef9bd4ecbcde7 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Fri, 29 Sep 2017 18:00:23 +0530
4Subject: [PATCH 17/53] fixed bug in GCC so that It will support .long 0U and
5 .long 0u
6
7Signed-off-by: Aayush Misra <aayushm@amd.com>
8---
9 gas/expr.c | 9 +++++++++
10 1 file changed, 9 insertions(+)
11
12diff --git a/gas/expr.c b/gas/expr.c
13index 3a01b88e310..8214bdf3263 100644
14--- a/gas/expr.c
15+++ b/gas/expr.c
16@@ -833,6 +833,15 @@ operand (expressionS *expressionP, enum expr_mode mode)
17 break;
18 }
19 }
20+ if ((*input_line_pointer == 'U') || (*input_line_pointer == 'u'))
21+ {
22+ input_line_pointer--;
23+
24+ integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
25+ ? 0 : 10,
26+ expressionP);
27+ break;
28+ }
29 c = *input_line_pointer;
30 switch (c)
31 {
32--
332.34.1
34
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0018-Compiler-will-give-error-messages-in-more-detail-for.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0018-Compiler-will-give-error-messages-in-more-detail-for.patch
new file mode 100644
index 00000000..c63f4566
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0018-Compiler-will-give-error-messages-in-more-detail-for.patch
@@ -0,0 +1,37 @@
1From 3056650d65b5bfa34bf16cd1ee7829a64dfb19ac Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Wed, 21 Feb 2018 12:32:02 +0530
4Subject: [PATCH 18/53] Compiler will give error messages in more detail for
5 mxl-gp-opt flag..
6
7Signed-off-by: Aayush Misra <aayushm@amd.com>
8---
9 ld/ldmain.c | 12 ++++++++++++
10 1 file changed, 12 insertions(+)
11
12diff --git a/ld/ldmain.c b/ld/ldmain.c
13index e90c2021b33..e135939fade 100644
14--- a/ld/ldmain.c
15+++ b/ld/ldmain.c
16@@ -1575,6 +1575,18 @@ reloc_overflow (struct bfd_link_info *info,
17 break;
18 case bfd_link_hash_defined:
19 case bfd_link_hash_defweak:
20+
21+ if((strcmp(reloc_name,"R_MICROBLAZE_SRW32") == 0) && entry->type == bfd_link_hash_defined)
22+ {
23+ einfo (_(" relocation truncated to fit: don't enable small data pointer optimizations[mxl-gp-opt] if extern or multiple declarations used: "
24+ "%s against symbol `%T' defined in %A section in %B"),
25+ reloc_name, entry->root.string,
26+ entry->u.def.section,
27+ entry->u.def.section == bfd_abs_section_ptr
28+ ? info->output_bfd : entry->u.def.section->owner);
29+ break;
30+ }
31+
32 einfo (_(" relocation truncated to fit: "
33 "%s against symbol `%pT' defined in %pA section in %pB"),
34 reloc_name, entry->root.string,
35--
362.34.1
37
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0019-initial-support-for-MicroBlaze-64-bit-m64.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0019-initial-support-for-MicroBlaze-64-bit-m64.patch
new file mode 100644
index 00000000..452c1418
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0019-initial-support-for-MicroBlaze-64-bit-m64.patch
@@ -0,0 +1,202 @@
1From 06c3e8ef9bdea329af1099e14abbde3d76a114a9 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 1 Nov 2021 19:06:53 +0530
4Subject: [PATCH 19/53] initial support for MicroBlaze 64 bit [-m64]
5
6Conflicts:
7 bfd/elf32-microblaze.c
8 include/elf/common.h
9 ld/Makefile.am
10 ld/Makefile.in
11signed-off-by:Nagaraju Mekala<nmekala@xilinx.com>
12 Mahesh Bodapati<mbodapat@xilinx.com>
13
14Signed-off-by: Aayush Misra <aayushm@amd.com>
15---
16 bfd/bfd-in2.h | 14 ++++++++++++--
17 bfd/libbfd.h | 2 ++
18 bfd/reloc.c | 18 +++++++++++++++---
19 gas/config/tc-microblaze.h | 4 +++-
20 ld/Makefile.am | 2 ++
21 ld/configure.tgt | 3 +++
22 opcodes/microblaze-dis.c | 8 ++++++--
23 opcodes/microblaze-opc.h | 11 +++++++----
24 8 files changed, 50 insertions(+), 12 deletions(-)
25
26diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
27index 7ccc155394d..8b2815d7303 100644
28--- a/bfd/bfd-in2.h
29+++ b/bfd/bfd-in2.h
30@@ -6472,8 +6472,13 @@ done here - only used for relaxing */
31 BFD_RELOC_MICROBLAZE_64_NONE,
32
33 /* This is a 64 bit reloc that stores the 32 bit pc relative value in
34- two words (with an imm instruction). The relocation is PC-relative
35- GOT offset. */
36+ two words (with an imm instruction). No relocation is done here
37+ only used for relaxing */
38+ BFD_RELOC_MICROBLAZE_64,
39+
40+/* This is a 64 bit reloc that stores the 32 bit pc relative
41+value in two words (with an imm instruction). The relocation is
42+PC-relative GOT offset */
43 BFD_RELOC_MICROBLAZE_64_GOTPC,
44
45 /* This is a 64 bit reloc that stores the 32 bit pc relative
46@@ -6481,6 +6486,11 @@ value in two words (with an imml instruction). The relocation is
47 PC-relative GOT offset */
48 BFD_RELOC_MICROBLAZE_64_GPC,
49
50+/* This is a 64 bit reloc that stores the 32 bit pc relative
51+value in two words (with an imml instruction). The relocation is
52+PC-relative GOT offset */
53+ BFD_RELOC_MICROBLAZE_64_GPC,
54+
55 /* This is a 64 bit reloc that stores the 32 bit pc relative
56 value in two words (with an imm instruction). The relocation is
57 GOT offset */
58diff --git a/bfd/libbfd.h b/bfd/libbfd.h
59index 7a3e558d70a..603ed8260cb 100644
60--- a/bfd/libbfd.h
61+++ b/bfd/libbfd.h
62@@ -3005,7 +3005,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
63 "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
64 "BFD_RELOC_MICROBLAZE_32_NONE",
65 "BFD_RELOC_MICROBLAZE_64_NONE",
66+ "BFD_RELOC_MICROBLAZE_64",
67 "BFD_RELOC_MICROBLAZE_64_GOTPC",
68+ "BFD_RELOC_MICROBLAZE_64_GPC",
69 "BFD_RELOC_MICROBLAZE_64_GOT",
70 "BFD_RELOC_MICROBLAZE_64_PLT",
71 "BFD_RELOC_MICROBLAZE_64_GOTOFF",
72diff --git a/bfd/reloc.c b/bfd/reloc.c
73index fda67e5ffda..3e8647f601e 100644
74--- a/bfd/reloc.c
75+++ b/bfd/reloc.c
76@@ -6677,12 +6677,24 @@ ENUMDOC
77 This is a 64 bit reloc that stores the 32 bit pc relative value in
78 two words (with an imm instruction). No relocation is done here -
79 only used for relaxing.
80+ENUM
81+ BFD_RELOC_MICROBLAZE_64
82+ENUMDOC
83+ This is a 64 bit reloc that stores the 32 bit pc relative
84+ value in two words (with an imm instruction). No relocation is
85+ done here - only used for relaxing
86 ENUM
87 BFD_RELOC_MICROBLAZE_64_GOTPC
88 ENUMDOC
89- This is a 64 bit reloc that stores the 32 bit pc relative value in
90- two words (with an imm instruction). The relocation is PC-relative
91- GOT offset.
92+ This is a 64 bit reloc that stores the 32 bit pc relative
93+ value in two words (with an imml instruction). No relocation is
94+ done here - only used for relaxing
95+ENUM
96+ BFD_RELOC_MICROBLAZE_64_GPC
97+ENUMDOC
98+ This is a 64 bit reloc that stores the 32 bit pc relative
99+ value in two words (with an imm instruction). The relocation is
100+ PC-relative GOT offset
101 ENUM
102 BFD_RELOC_MICROBLAZE_64_GOT
103 ENUMDOC
104diff --git a/gas/config/tc-microblaze.h b/gas/config/tc-microblaze.h
105index 20d0da5496d..f0f861c3373 100644
106--- a/gas/config/tc-microblaze.h
107+++ b/gas/config/tc-microblaze.h
108@@ -81,7 +81,9 @@ extern const struct relax_type md_relax_table[];
109
110 #ifdef OBJ_ELF
111
112-#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblazeel")
113+#define TARGET_FORMAT microblaze_target_format()
114+extern const char *microblaze_target_format (void);
115+//#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblazeel")
116
117 #define ELF_TC_SPECIAL_SECTIONS \
118 { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
119diff --git a/ld/Makefile.am b/ld/Makefile.am
120index f9ee05b1400..c1daf842444 100644
121--- a/ld/Makefile.am
122+++ b/ld/Makefile.am
123@@ -424,6 +424,8 @@ ALL_64_EMULATION_SOURCES = \
124 eelf32ltsmipn32.c \
125 eelf32ltsmipn32_fbsd.c \
126 eelf32mipswindiss.c \
127+ eelf64microblazeel.c \
128+ eelf64microblaze.c \
129 eelf64_aix.c \
130 eelf64_ia64.c \
131 eelf64_ia64_fbsd.c \
132diff --git a/ld/configure.tgt b/ld/configure.tgt
133index f937f78b876..a9d3004e445 100644
134--- a/ld/configure.tgt
135+++ b/ld/configure.tgt
136@@ -527,6 +527,9 @@ microblaze*-linux*) targ_emul="elf32mb_linux"
137 microblazeel*) targ_emul=elf32microblazeel
138 targ_extra_emuls=elf32microblaze
139 ;;
140+microblazeel64*) targ_emul=elf64microblazeel
141+ targ_extra_emuls=elf64microblaze
142+ ;;
143 microblaze*) targ_emul=elf32microblaze
144 targ_extra_emuls=elf32microblazeel
145 ;;
146diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
147index 45135f9d264..45262aef909 100644
148--- a/opcodes/microblaze-dis.c
149+++ b/opcodes/microblaze-dis.c
150@@ -457,6 +457,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
151 case INST_TYPE_R1_R2_SPECIAL:
152 print_func (stream, "\t%s, %s", get_field_r1 (&buf, inst),
153 get_field_r2 (&buf, inst));
154+ break;
155+ case INST_TYPE_IMML:
156+ print_func (stream, "\t%s", get_field_imml (&buf, inst));
157+ /* TODO: Also print symbol */
158 break;
159 case INST_TYPE_RD_IMM15:
160 print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
161@@ -475,8 +479,8 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
162 get_field_immw (&buf, inst), get_field_imms (&buf, inst));
163 break;
164 /* For bit field insns. */
165- case INST_TYPE_RD_R1_IMM5_IMM5:
166- print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst),get_field_r1(&buf, inst),get_field_imm5width (&buf, inst), get_field_imm5 (&buf, inst));
167+ case INST_TYPE_RD_R1_IMMW_IMMS:
168+ print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst),get_field_r1(&buf, inst),get_field_immw (&buf, inst), get_field_imms (&buf, inst));
169 break;
170 /* For tuqula instruction */
171 case INST_TYPE_RD:
172diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
173index a952b9ac3c2..d9d05721dae 100644
174--- a/opcodes/microblaze-opc.h
175+++ b/opcodes/microblaze-opc.h
176@@ -68,7 +68,13 @@
177 #define INST_TYPE_R1_IMML 24
178
179 /* For bsefi and bsifi */
180-#define INST_TYPE_RD_R1_IMM5_IMM5 21
181+#define INST_TYPE_RD_R1_IMMW_IMMS 21
182+
183+/* For 64-bit instructions */
184+#define INST_TYPE_IMML 22
185+#define INST_TYPE_RD_R1_IMML 23
186+#define INST_TYPE_R1_IMML 24
187+#define INST_TYPE_RD_R1_IMMW_IMMS 21
188
189 #define INST_TYPE_NONE 25
190
191@@ -589,8 +595,5 @@ char pvr_register_prefix[] = "rpvr";
192 #define MIN_IMML ((long) 0xffffff8000000000L)
193 #define MAX_IMML ((long) 0x0000007fffffffffL)
194
195-#define MIN_IMM_WIDTH ((int) 0x00000001)
196-#define MAX_IMM_WIDTH ((int) 0x00000020)
197-
198 #endif /* MICROBLAZE_OPC */
199
200--
2012.34.1
202
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0020-initial-support-for-MicroBlaze-64-bit-m64.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0020-initial-support-for-MicroBlaze-64-bit-m64.patch
new file mode 100644
index 00000000..f3073f1e
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0020-initial-support-for-MicroBlaze-64-bit-m64.patch
@@ -0,0 +1,82 @@
1From f46a81a4ffa73453403a5e99e7005a8f1d974ecf Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 1 Nov 2021 19:06:53 +0530
4Subject: [PATCH 20/53] initial support for MicroBlaze 64 bit [-m64]
5
6Conflicts:
7 bfd/elf32-microblaze.c
8 include/elf/common.h
9 ld/Makefile.am
10 ld/Makefile.in
11signed-off-by:Nagaraju Mekala<nmekala@xilinx.com>
12 Mahesh Bodapati<mbodapat@xilinx.com>
13
14Signed-off-by: Aayush Misra <aayushm@amd.com>
15---
16 ld/emulparams/elf64microblaze.sh | 23 +++++++++++++++++++++++
17 ld/emulparams/elf64microblazeel.sh | 23 +++++++++++++++++++++++
18 2 files changed, 46 insertions(+)
19 create mode 100644 ld/emulparams/elf64microblaze.sh
20 create mode 100644 ld/emulparams/elf64microblazeel.sh
21
22diff --git a/ld/emulparams/elf64microblaze.sh b/ld/emulparams/elf64microblaze.sh
23new file mode 100644
24index 00000000000..9c7b0eb7080
25--- /dev/null
26+++ b/ld/emulparams/elf64microblaze.sh
27@@ -0,0 +1,23 @@
28+SCRIPT_NAME=elfmicroblaze
29+OUTPUT_FORMAT="elf64-microblazeel"
30+#BIG_OUTPUT_FORMAT="elf64-microblaze"
31+LITTLE_OUTPUT_FORMAT="elf64-microblazeel"
32+#TEXT_START_ADDR=0
33+NONPAGED_TEXT_START_ADDR=0x28
34+ALIGNMENT=4
35+MAXPAGESIZE=4
36+ARCH=microblaze
37+EMBEDDED=yes
38+
39+NOP=0x80000000
40+
41+# Hmmm, there's got to be a better way. This sets the stack to the
42+# top of the simulator memory (2^19 bytes).
43+#PAGE_SIZE=0x1000
44+#DATA_ADDR=0x10000
45+#OTHER_RELOCATING_SECTIONS='.stack 0x7000 : { _stack = .; *(.stack) }'
46+#$@{RELOCATING+ PROVIDE (__stack = 0x7000);@}
47+#OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);'
48+
49+TEMPLATE_NAME=elf32
50+#GENERATE_SHLIB_SCRIPT=yes
51diff --git a/ld/emulparams/elf64microblazeel.sh b/ld/emulparams/elf64microblazeel.sh
52new file mode 100644
53index 00000000000..9c7b0eb7080
54--- /dev/null
55+++ b/ld/emulparams/elf64microblazeel.sh
56@@ -0,0 +1,23 @@
57+SCRIPT_NAME=elfmicroblaze
58+OUTPUT_FORMAT="elf64-microblazeel"
59+#BIG_OUTPUT_FORMAT="elf64-microblaze"
60+LITTLE_OUTPUT_FORMAT="elf64-microblazeel"
61+#TEXT_START_ADDR=0
62+NONPAGED_TEXT_START_ADDR=0x28
63+ALIGNMENT=4
64+MAXPAGESIZE=4
65+ARCH=microblaze
66+EMBEDDED=yes
67+
68+NOP=0x80000000
69+
70+# Hmmm, there's got to be a better way. This sets the stack to the
71+# top of the simulator memory (2^19 bytes).
72+#PAGE_SIZE=0x1000
73+#DATA_ADDR=0x10000
74+#OTHER_RELOCATING_SECTIONS='.stack 0x7000 : { _stack = .; *(.stack) }'
75+#$@{RELOCATING+ PROVIDE (__stack = 0x7000);@}
76+#OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);'
77+
78+TEMPLATE_NAME=elf32
79+#GENERATE_SHLIB_SCRIPT=yes
80--
812.34.1
82
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0021-Added-relocations-for-MB-X.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0021-Added-relocations-for-MB-X.patch
new file mode 100644
index 00000000..24e0894d
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0021-Added-relocations-for-MB-X.patch
@@ -0,0 +1,108 @@
1From 39ba1e8a13828ac3c860a72b95c3abae024044b5 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Tue, 11 Sep 2018 17:30:17 +0530
4Subject: [PATCH 21/53] Added relocations for MB-X
5
6Conflicts:
7 bfd/bfd-in2.h
8 gas/config/tc-microblaze.c
9
10Conflicts:
11 gas/config/tc-microblaze.c
12
13Signed-off-by: Aayush Misra <aayushm@amd.com>
14---
15 bfd/reloc.c | 26 ++++++++++++++------------
16 gas/config/tc-microblaze.c | 11 +++++++++++
17 2 files changed, 25 insertions(+), 12 deletions(-)
18
19diff --git a/bfd/reloc.c b/bfd/reloc.c
20index 3e8647f601e..c5c0ce5d060 100644
21--- a/bfd/reloc.c
22+++ b/bfd/reloc.c
23@@ -6661,12 +6661,6 @@ ENUMDOC
24 the form "Symbol Op Symbol".
25 ENUM
26 BFD_RELOC_MICROBLAZE_32_NONE
27-ENUMDOC
28- This is a 32 bit reloc that stores the 32 bit pc relative value in
29- two words (with an imm instruction). No relocation is done here -
30- only used for relaxing.
31-ENUM
32- BFD_RELOC_MICROBLAZE_32_NONE
33 ENUMDOC
34 This is a 32 bit reloc that stores the 32 bit pc relative
35 value in two words (with an imm instruction). No relocation is
36@@ -6685,12 +6679,6 @@ ENUMDOC
37 done here - only used for relaxing
38 ENUM
39 BFD_RELOC_MICROBLAZE_64_GOTPC
40-ENUMDOC
41- This is a 64 bit reloc that stores the 32 bit pc relative
42- value in two words (with an imml instruction). No relocation is
43- done here - only used for relaxing
44-ENUM
45- BFD_RELOC_MICROBLAZE_64_GPC
46 ENUMDOC
47 This is a 64 bit reloc that stores the 32 bit pc relative
48 value in two words (with an imm instruction). The relocation is
49@@ -7929,6 +7917,20 @@ ENUMX
50 ENUMDOC
51 Linux eBPF relocations.
52
53+ This is a 64 bit reloc that stores 64-bit thread pointer relative offset
54+ to two words (uses imml instruction).
55+ENUM
56+BFD_RELOC_MICROBLAZE_64,
57+ENUMDOC
58+ This is a 64 bit reloc that stores the 64 bit pc relative
59+ value in two words (with an imml instruction). No relocation is
60+ done here - only used for relaxing
61+ENUM
62+BFD_RELOC_MICROBLAZE_64_PCREL,
63+ENUMDOC
64+ This is a 32 bit reloc that stores the 32 bit pc relative
65+ value in two words (with an imml instruction). No relocation is
66+ done here - only used for relaxing
67 ENUM
68 BFD_RELOC_EPIPHANY_SIMM8
69 ENUMDOC
70diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
71index f13efcae979..9b8b129e309 100644
72--- a/gas/config/tc-microblaze.c
73+++ b/gas/config/tc-microblaze.c
74@@ -91,6 +91,8 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
75 #define TLSTPREL_OFFSET 16
76 #define TEXT_OFFSET 17
77 #define TEXT_PC_OFFSET 18
78+#define DEFINED_64_OFFSET 19
79+#define DEFINED_64_PC_OFFSET 20
80
81 /* Initialize the relax table. */
82 const relax_typeS md_relax_table[] =
83@@ -114,6 +116,8 @@ const relax_typeS md_relax_table[] =
84 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 16: TLSTPREL_OFFSET. */
85 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
86 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
87+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 }, /* 19: DEFINED_64_OFFSET. */
88+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE*2, 0 } /* 20: DEFINED_64_PC_OFFSET. */
89 };
90
91 static htab_t opcode_hash_control; /* Opcode mnemonics. */
92@@ -2330,6 +2334,13 @@ md_estimate_size_before_relax (fragS * fragP,
93 /* Variable part does not change. */
94 fragP->fr_var = INST_WORD_SIZE*2;
95 }
96+ else if (streq (fragP->fr_opcode, str_microblaze_64))
97+ {
98+ /* Used as an absolute value. */
99+ fragP->fr_subtype = DEFINED_64_OFFSET;
100+ /* Variable part does not change. */
101+ fragP->fr_var = INST_WORD_SIZE;
102+ }
103 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
104 {
105 /* It is accessed using the small data read only anchor. */
106--
1072.34.1
108
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0022-initial-support-for-MicroBlaze-64-bit-m64.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0022-initial-support-for-MicroBlaze-64-bit-m64.patch
new file mode 100644
index 00000000..5ef086bd
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0022-initial-support-for-MicroBlaze-64-bit-m64.patch
@@ -0,0 +1,958 @@
1From 6e30e2ce72e9257daae0633a6b57e7a5c4c918f2 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 1 Nov 2021 19:06:53 +0530
4Subject: [PATCH 22/53] initial support for MicroBlaze 64 bit [-m64]
5
6Conflicts:
7 bfd/elf32-microblaze.c
8 include/elf/common.h
9 ld/Makefile.am
10 ld/Makefile.in
11signed-off-by:Nagaraju Mekala<nmekala@xilinx.com>
12 Mahesh Bodapati<mbodapat@xilinx.com>
13
14Signed-off-by: Aayush Misra <aayushm@amd.com>
15---
16 bfd/elf64-microblaze.c | 8 +
17 bfd/reloc.c | 36 +--
18 gas/config/tc-microblaze.c | 556 ++++++++++++++++++++++++++++++++-----
19 3 files changed, 499 insertions(+), 101 deletions(-)
20
21diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
22index 119d266f95a..ca92df647c9 100755
23--- a/bfd/elf64-microblaze.c
24+++ b/bfd/elf64-microblaze.c
25@@ -1666,6 +1666,14 @@ microblaze_elf_relocate_section (bfd *output_bfd,
26 outrel.r_info = ELF64_R_INFO (0, R_MICROBLAZE_REL);
27 outrel.r_addend = relocation + addend;
28 }
29+ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
30+ if (insn == 0xb2000000 || insn == 0xb2ffffff)
31+ {
32+ insn &= ~0x00ffffff;
33+ insn |= (relocation >> 16) & 0xffffff;
34+ bfd_put_32 (input_bfd, insn,
35+ contents + offset + endian);
36+ }
37 else
38 {
39 BFD_FAIL ();
40diff --git a/bfd/reloc.c b/bfd/reloc.c
41index c5c0ce5d060..6eb93e993f0 100644
42--- a/bfd/reloc.c
43+++ b/bfd/reloc.c
44@@ -6677,8 +6677,20 @@ ENUMDOC
45 This is a 64 bit reloc that stores the 32 bit pc relative
46 value in two words (with an imm instruction). No relocation is
47 done here - only used for relaxing
48+ENUM
49+BFD_RELOC_MICROBLAZE_64_PCREL,
50+ENUMDOC
51+ This is a 32 bit reloc that stores the 32 bit pc relative
52+ value in two words (with an imml instruction). No relocation is
53+ done here - only used for relaxing
54 ENUM
55 BFD_RELOC_MICROBLAZE_64_GOTPC
56+ENUMDOC
57+ This is a 64 bit reloc that stores the 32 bit pc relative
58+ value in two words (with an imml instruction). No relocation is
59+ done here - only used for relaxing
60+ENUM
61+ BFD_RELOC_MICROBLAZE_64_GPC
62 ENUMDOC
63 This is a 64 bit reloc that stores the 32 bit pc relative
64 value in two words (with an imm instruction). The relocation is
65@@ -7894,18 +7906,6 @@ ENUMDOC
66
67 This is a 64 bit reloc that stores 64-bit thread pointer relative offset
68 to two words (uses imml instruction).
69-ENUM
70-BFD_RELOC_MICROBLAZE_64,
71-ENUMDOC
72- This is a 64 bit reloc that stores the 64 bit pc relative
73- value in two words (with an imml instruction). No relocation is
74- done here - only used for relaxing
75-ENUM
76-BFD_RELOC_MICROBLAZE_64_PCREL,
77-ENUMDOC
78- This is a 32 bit reloc that stores the 32 bit pc relative
79- value in two words (with an imml instruction). No relocation is
80- done here - only used for relaxing
81 ENUM
82 BFD_RELOC_BPF_64
83 ENUMX
84@@ -7919,18 +7919,6 @@ ENUMDOC
85
86 This is a 64 bit reloc that stores 64-bit thread pointer relative offset
87 to two words (uses imml instruction).
88-ENUM
89-BFD_RELOC_MICROBLAZE_64,
90-ENUMDOC
91- This is a 64 bit reloc that stores the 64 bit pc relative
92- value in two words (with an imml instruction). No relocation is
93- done here - only used for relaxing
94-ENUM
95-BFD_RELOC_MICROBLAZE_64_PCREL,
96-ENUMDOC
97- This is a 32 bit reloc that stores the 32 bit pc relative
98- value in two words (with an imml instruction). No relocation is
99- done here - only used for relaxing
100 ENUM
101 BFD_RELOC_EPIPHANY_SIMM8
102 ENUMDOC
103diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
104index 9b8b129e309..6640266cc47 100644
105--- a/gas/config/tc-microblaze.c
106+++ b/gas/config/tc-microblaze.c
107@@ -35,10 +35,13 @@
108 #define streq(a,b) (strcmp (a, b) == 0)
109 #endif
110
111+static int microblaze_arch_size = 0;
112+
113 #define OPTION_EB (OPTION_MD_BASE + 0)
114 #define OPTION_EL (OPTION_MD_BASE + 1)
115 #define OPTION_LITTLE (OPTION_MD_BASE + 2)
116 #define OPTION_BIG (OPTION_MD_BASE + 3)
117+#define OPTION_M64 (OPTION_MD_BASE + 4)
118
119 void microblaze_generate_symbol (char *sym);
120 static bool check_spl_reg (unsigned *);
121@@ -360,7 +363,7 @@ microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
122 Integer arg to pass to the function. */
123 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
124 and then in the read.c table. */
125-const pseudo_typeS md_pseudo_table[] =
126+pseudo_typeS md_pseudo_table[] =
127 {
128 {"lcomm", microblaze_s_lcomm, 1},
129 {"data8", cons, 1}, /* Same as byte. */
130@@ -369,6 +372,7 @@ const pseudo_typeS md_pseudo_table[] =
131 {"ent", s_func, 0}, /* Treat ent as function entry point. */
132 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
133 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
134+ {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
135 {"weakext", microblaze_s_weakext, 0},
136 {"rodata", microblaze_s_rdata, 0},
137 {"sdata2", microblaze_s_rdata, 1},
138@@ -378,6 +382,7 @@ const pseudo_typeS md_pseudo_table[] =
139 #endif
140 {"sbss", microblaze_s_sbss, 0},
141 {"word", cons, 4},
142+ {"dword", cons, 8},
143 {"frame", s_ignore, 0},
144 {"mask", s_ignore, 0}, /* Emitted by gcc. */
145 {NULL, NULL, 0}
146@@ -749,6 +754,74 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
147 return new_pointer;
148 }
149
150+ static char *
151+parse_imml (char * s, expressionS * e, long min, long max)
152+{
153+ char *new_pointer;
154+ char *atp;
155+ int itype, ilen;
156+
157+ ilen = 0;
158+
159+ /* Find the start of "@GOT" or "@PLT" suffix (if any) */
160+ for (atp = s; *atp != '@'; atp++)
161+ if (is_end_of_line[(unsigned char) *atp])
162+ break;
163+
164+ if (*atp == '@')
165+ {
166+ itype = match_imm (atp + 1, &ilen);
167+ if (itype != 0)
168+ {
169+ *atp = 0;
170+ e->X_md = itype;
171+ }
172+ else
173+ {
174+ atp = NULL;
175+ e->X_md = 0;
176+ ilen = 0;
177+ }
178+ *atp = 0;
179+ }
180+ else
181+ {
182+ atp = NULL;
183+ e->X_md = 0;
184+ }
185+
186+ if (atp && !GOT_symbol)
187+ {
188+ GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
189+ }
190+
191+ new_pointer = parse_exp (s, e);
192+
193+ if (!GOT_symbol && ! strncmp (s, GOT_SYMBOL_NAME, 20))
194+ {
195+ GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
196+ }
197+
198+ if (e->X_op == O_absent)
199+ ; /* An error message has already been emitted. */
200+ else if ((e->X_op != O_constant && e->X_op != O_symbol) )
201+ as_fatal (_("operand must be a constant or a label"));
202+ else if ((e->X_op == O_constant) && ((long) e->X_add_number < min
203+ || (long) e->X_add_number > max))
204+ {
205+ as_fatal (_("operand must be absolute in range %ld..%ld, not %ld"),
206+ min, max, (long) e->X_add_number);
207+ }
208+
209+ if (atp)
210+ {
211+ *atp = '@'; /* restore back (needed?) */
212+ if (new_pointer >= atp)
213+ new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */
214+ }
215+ return new_pointer;
216+}
217+
218 static char *
219 check_got (int * got_type, int * got_len)
220 {
221@@ -803,7 +876,7 @@ check_got (int * got_type, int * got_len)
222 extern bfd_reloc_code_real_type
223 parse_cons_expression_microblaze (expressionS *exp, int size)
224 {
225- if (size == 4)
226+ if (size == 4 || (microblaze_arch_size == 64 && size == 8))
227 {
228 /* Handle @GOTOFF et.al. */
229 char *save, *gotfree_copy;
230@@ -835,6 +908,7 @@ parse_cons_expression_microblaze (expressionS *exp, int size)
231
232 static const char * str_microblaze_ro_anchor = "RO";
233 static const char * str_microblaze_rw_anchor = "RW";
234+static const char * str_microblaze_64 = "64";
235
236 static bool
237 check_spl_reg (unsigned * reg)
238@@ -893,9 +967,10 @@ md_assemble (char * str)
239 unsigned reg2;
240 unsigned reg3;
241 unsigned isize;
242- unsigned int immed = 0, immed2 = 0, temp;
243+ unsigned long immed = 0, immed2 = 0, temp;
244 expressionS exp;
245 char name[20];
246+ long immedl;
247
248 /* Drop leading whitespace. */
249 while (ISSPACE (* str))
250@@ -1014,8 +1089,9 @@ md_assemble (char * str)
251 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
252 else if (streq (name, "smi"))
253 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
254-
255- if (reg2 == REG_ROSDP)
256+ if(streq (name, "lli") || streq (name, "sli"))
257+ opc = str_microblaze_64;
258+ else if (reg2 == REG_ROSDP)
259 opc = str_microblaze_ro_anchor;
260 else if (reg2 == REG_RWSDP)
261 opc = str_microblaze_rw_anchor;
262@@ -1082,36 +1158,60 @@ md_assemble (char * str)
263 inst |= (immed << IMM_LOW) & IMM_MASK;
264 }
265 }
266- else
267- {
268- temp = immed & 0xFFFF8000;
269- if ((temp != 0) && (temp != 0xFFFF8000))
270- {
271+ else if (streq (name, "lli") || streq (name, "sli"))
272+ {
273+ temp = immed & 0xFFFFFF8000;
274+ if (temp != 0 && temp != 0xFFFFFF8000)
275+ {
276 /* Needs an immediate inst. */
277 opcode1
278 = (struct op_code_struct *) str_hash_find (opcode_hash_control,
279- "imm");
280+ "imml");
281 if (opcode1 == NULL)
282 {
283- as_bad (_("unknown opcode \"%s\""), "imm");
284+ as_bad (_("unknown opcode \"%s\""), "imml");
285 return;
286 }
287-
288 inst1 = opcode1->bit_sequence;
289- inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
290+ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
291 output[0] = INST_BYTE0 (inst1);
292 output[1] = INST_BYTE1 (inst1);
293 output[2] = INST_BYTE2 (inst1);
294 output[3] = INST_BYTE3 (inst1);
295 output = frag_more (isize);
296- }
297- inst |= (reg1 << RD_LOW) & RD_MASK;
298- inst |= (reg2 << RA_LOW) & RA_MASK;
299- inst |= (immed << IMM_LOW) & IMM_MASK;
300- }
301+ }
302+ inst |= (reg1 << RD_LOW) & RD_MASK;
303+ inst |= (reg2 << RA_LOW) & RA_MASK;
304+ inst |= (immed << IMM_LOW) & IMM_MASK;
305+ }
306+ else
307+ {
308+ temp = immed & 0xFFFF8000;
309+ if ((temp != 0) && (temp != 0xFFFF8000))
310+ {
311+ /* Needs an immediate inst. */
312+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
313+ if (opcode1 == NULL)
314+ {
315+ as_bad (_("unknown opcode \"%s\""), "imm");
316+ return;
317+ }
318+
319+ inst1 = opcode1->bit_sequence;
320+ inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
321+ output[0] = INST_BYTE0 (inst1);
322+ output[1] = INST_BYTE1 (inst1);
323+ output[2] = INST_BYTE2 (inst1);
324+ output[3] = INST_BYTE3 (inst1);
325+ output = frag_more (isize);
326+ }
327+ inst |= (reg1 << RD_LOW) & RD_MASK;
328+ inst |= (reg2 << RA_LOW) & RA_MASK;
329+ inst |= (immed << IMM_LOW) & IMM_MASK;
330+ }
331 break;
332
333- case INST_TYPE_RD_R1_IMM5:
334+ case INST_TYPE_RD_R1_IMMS:
335 if (strcmp (op_end, ""))
336 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
337 else
338@@ -1145,16 +1245,22 @@ md_assemble (char * str)
339 immed = exp.X_add_number;
340 }
341
342- if (immed != (immed % 32))
343+ if ((immed != (immed % 32)) &&
344+ (opcode->instr == bslli || opcode->instr == bsrai || opcode->instr == bsrli))
345 {
346 as_warn (_("Shift value > 32. using <value %% 32>"));
347 immed = immed % 32;
348 }
349+ else if (immed != (immed % 64))
350+ {
351+ as_warn (_("Shift value > 64. using <value %% 64>"));
352+ immed = immed % 64;
353+ }
354 inst |= (reg1 << RD_LOW) & RD_MASK;
355 inst |= (reg2 << RA_LOW) & RA_MASK;
356- inst |= (immed << IMM_LOW) & IMM5_MASK;
357+ inst |= (immed << IMM_LOW) & IMM6_MASK;
358 break;
359- case INST_TYPE_RD_R1_IMM5_IMM5:
360+ case INST_TYPE_RD_R1_IMMW_IMMS:
361 if (strcmp (op_end, ""))
362 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
363 else
364@@ -1178,7 +1284,7 @@ md_assemble (char * str)
365
366 /* Width immediate value. */
367 if (strcmp (op_end, ""))
368- op_end = parse_imm (op_end + 1, &exp, MIN_IMM_WIDTH, MAX_IMM_WIDTH);
369+ op_end = parse_imm (op_end + 1, &exp, MIN_IMM, MAX_IMM);
370 else
371 as_fatal (_("Error in statement syntax"));
372 if (exp.X_op != O_constant)
373@@ -1190,6 +1296,8 @@ md_assemble (char * str)
374 immed = exp.X_add_number;
375 if (opcode->instr == bsefi && immed > 31)
376 as_fatal (_("Width value must be less than 32"));
377+ else if (opcode->instr == bslefi && immed > 63)
378+ as_fatal (_("Width value must be less than 64"));
379
380 /* Shift immediate value. */
381 if (strcmp (op_end, ""))
382@@ -1206,23 +1314,31 @@ md_assemble (char * str)
383 output = frag_more (isize);
384 immed2 = exp.X_add_number;
385 }
386- if (immed2 != (immed2 % 32))
387- {
388- as_warn (_("Shift value greater than 32. using <value %% 32>"));
389+ if ((immed2 != (immed2 % 32)) && (opcode->instr == bsefi || opcode->instr == bsifi))
390+ {
391+
392+ as_warn (_("Shift value greater than 32. using <value %% 32>"));
393 immed2 = immed2 % 32;
394 }
395+ else if (immed2 != (immed2 % 64))
396+ {
397+ as_warn (_("Shift value greater than 64. using <value %% 64>"));
398+ immed2 = immed2 % 64;
399+ }
400
401 /* Check combined value. */
402- if (immed + immed2 > 32)
403+ if ((immed + immed2 > 32) && (opcode->instr == bsefi || opcode->instr == bsifi))
404 as_fatal (_("Width value + shift value must not be greater than 32"));
405+ else if (immed + immed2 > 64)
406+ as_fatal (_("Width value + shift value must not be greater than 64"));
407
408 inst |= (reg1 << RD_LOW) & RD_MASK;
409 inst |= (reg2 << RA_LOW) & RA_MASK;
410- if (opcode->instr == bsefi)
411- inst |= (immed & IMM5_MASK) << IMM_WIDTH_LOW; /* bsefi */
412+ if (opcode->instr == bsefi || opcode->instr == bslefi)
413+ inst |= (immed & IMM6_MASK) << IMM_WIDTH_LOW; /* bsefi or bslefi */
414 else
415- inst |= ((immed + immed2 - 1) & IMM5_MASK) << IMM_WIDTH_LOW; /* bsifi */
416- inst |= (immed2 << IMM_LOW) & IMM5_MASK;
417+ inst |= ((immed + immed2 - 1) & IMM6_MASK) << IMM_WIDTH_LOW; /* bsifi or bslifi */
418+ inst |= (immed2 << IMM_LOW) & IMM6_MASK;
419 break;
420 case INST_TYPE_R1_R2:
421 if (strcmp (op_end, ""))
422@@ -1722,12 +1838,20 @@ md_assemble (char * str)
423 case INST_TYPE_IMM:
424 if (streq (name, "imm"))
425 as_fatal (_("An IMM instruction should not be present in the .s file"));
426-
427- op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
428+ if (microblaze_arch_size == 64)
429+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
430+ else
431+ op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
432
433 if (exp.X_op != O_constant)
434 {
435- char *opc = NULL;
436+ char *opc;
437+ if (microblaze_arch_size == 64 && (streq (name, "breai") ||
438+ streq (name, "breaid") ||
439+ streq (name, "brai") || streq (name, "braid")))
440+ opc = str_microblaze_64;
441+ else
442+ opc = NULL;
443 relax_substateT subtype;
444
445 if (exp.X_md != 0)
446@@ -1750,29 +1874,53 @@ md_assemble (char * str)
447 immed = exp.X_add_number;
448 }
449
450-
451- temp = immed & 0xFFFF8000;
452- if ((temp != 0) && (temp != 0xFFFF8000))
453- {
454- /* Needs an immediate inst. */
455- opcode1
456- = (struct op_code_struct *) str_hash_find (opcode_hash_control,
457- "imm");
458- if (opcode1 == NULL)
459- {
460- as_bad (_("unknown opcode \"%s\""), "imm");
461- return;
462+ if (microblaze_arch_size == 64 && (streq (name, "breai") ||
463+ streq (name, "breaid") ||
464+ streq (name, "brai") || streq (name, "braid")))
465+ {
466+ temp = immed & 0xFFFFFF8000;
467+ if (temp != 0)
468+ {
469+ /* Needs an immediate inst. */
470+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
471+ if (opcode1 == NULL)
472+ {
473+ as_bad (_("unknown opcode \"%s\""), "imml");
474+ return;
475+ }
476+ inst1 = opcode1->bit_sequence;
477+ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
478+ output[0] = INST_BYTE0 (inst1);
479+ output[1] = INST_BYTE1 (inst1);
480+ output[2] = INST_BYTE2 (inst1);
481+ output[3] = INST_BYTE3 (inst1);
482+ output = frag_more (isize);
483 }
484+ inst |= (immed << IMM_LOW) & IMM_MASK;
485+ }
486+ else
487+ {
488+ temp = immed & 0xFFFF8000;
489+ if ((temp != 0) && (temp != 0xFFFF8000))
490+ {
491+ /* Needs an immediate inst. */
492+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
493+ if (opcode1 == NULL)
494+ {
495+ as_bad (_("unknown opcode \"%s\""), "imm");
496+ return;
497+ }
498
499- inst1 = opcode1->bit_sequence;
500- inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
501- output[0] = INST_BYTE0 (inst1);
502- output[1] = INST_BYTE1 (inst1);
503- output[2] = INST_BYTE2 (inst1);
504- output[3] = INST_BYTE3 (inst1);
505- output = frag_more (isize);
506- }
507- inst |= (immed << IMM_LOW) & IMM_MASK;
508+ inst1 = opcode1->bit_sequence;
509+ inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
510+ output[0] = INST_BYTE0 (inst1);
511+ output[1] = INST_BYTE1 (inst1);
512+ output[2] = INST_BYTE2 (inst1);
513+ output[3] = INST_BYTE3 (inst1);
514+ output = frag_more (isize);
515+ }
516+ inst |= (immed << IMM_LOW) & IMM_MASK;
517+ }
518 break;
519
520 case INST_TYPE_NONE:
521@@ -1903,6 +2051,7 @@ struct option md_longopts[] =
522 {"EL", no_argument, NULL, OPTION_EL},
523 {"mlittle-endian", no_argument, NULL, OPTION_EL},
524 {"mbig-endian", no_argument, NULL, OPTION_EB},
525+ {"m64", no_argument, NULL, OPTION_M64},
526 { NULL, no_argument, NULL, 0}
527 };
528
529@@ -1947,13 +2096,23 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
530 fragP->fr_fix += INST_WORD_SIZE * 2;
531 fragP->fr_var = 0;
532 break;
533+ case DEFINED_64_OFFSET:
534+ if (fragP->fr_symbol == GOT_symbol)
535+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
536+ fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64_GPC);
537+ else
538+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
539+ fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64);
540+ fragP->fr_fix += INST_WORD_SIZE * 2;
541+ fragP->fr_var = 0;
542+ break;
543 case DEFINED_ABS_SEGMENT:
544 if (fragP->fr_symbol == GOT_symbol)
545 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
546 fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64_GOTPC);
547 else
548 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
549- fragP->fr_offset, false, BFD_RELOC_64);
550+ fragP->fr_offset, true, BFD_RELOC_64);
551 fragP->fr_fix += INST_WORD_SIZE * 2;
552 fragP->fr_var = 0;
553 break;
554@@ -2174,23 +2333,38 @@ md_apply_fix (fixS * fixP,
555 case BFD_RELOC_64_PCREL:
556 case BFD_RELOC_64:
557 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
558+ case BFD_RELOC_MICROBLAZE_64:
559 /* Add an imm instruction. First save the current instruction. */
560 for (i = 0; i < INST_WORD_SIZE; i++)
561 buf[i + INST_WORD_SIZE] = buf[i];
562+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
563+ {
564+ /* Generate the imm instruction. */
565+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
566+ if (opcode1 == NULL)
567+ {
568+ as_bad (_("unknown opcode \"%s\""), "imml");
569+ return;
570+ }
571
572- /* Generate the imm instruction. */
573- opcode1
574- = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
575- if (opcode1 == NULL)
576- {
577- as_bad (_("unknown opcode \"%s\""), "imm");
578- return;
579- }
580-
581- inst1 = opcode1->bit_sequence;
582- if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
583- inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
584-
585+ inst1 = opcode1->bit_sequence;
586+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
587+ inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
588+ }
589+ else
590+ {
591+ /* Generate the imm instruction. */
592+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
593+ if (opcode1 == NULL)
594+ {
595+ as_bad (_("unknown opcode \"%s\""), "imm");
596+ return;
597+ }
598+
599+ inst1 = opcode1->bit_sequence;
600+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
601+ inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
602+ }
603 buf[0] = INST_BYTE0 (inst1);
604 buf[1] = INST_BYTE1 (inst1);
605 buf[2] = INST_BYTE2 (inst1);
606@@ -2219,6 +2393,7 @@ md_apply_fix (fixS * fixP,
607 /* Fall through. */
608
609 case BFD_RELOC_MICROBLAZE_64_GOTPC:
610+ case BFD_RELOC_MICROBLAZE_64_GPC:
611 case BFD_RELOC_MICROBLAZE_64_GOT:
612 case BFD_RELOC_MICROBLAZE_64_PLT:
613 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
614@@ -2226,13 +2401,17 @@ md_apply_fix (fixS * fixP,
615 /* Add an imm instruction. First save the current instruction. */
616 for (i = 0; i < INST_WORD_SIZE; i++)
617 buf[i + INST_WORD_SIZE] = buf[i];
618-
619 /* Generate the imm instruction. */
620- opcode1
621- = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
622+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
623+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
624+ else
625+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
626 if (opcode1 == NULL)
627 {
628- as_bad (_("unknown opcode \"%s\""), "imm");
629+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
630+ as_bad (_("unknown opcode \"%s\""), "imml");
631+ else
632+ as_bad (_("unknown opcode \"%s\""), "imm");
633 return;
634 }
635
636@@ -2256,6 +2435,8 @@ md_apply_fix (fixS * fixP,
637 moves code around due to relaxing. */
638 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
639 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
640+ else if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
641+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
642 else if (fixP->fx_r_type == BFD_RELOC_32)
643 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
644 else
645@@ -2298,6 +2479,32 @@ md_estimate_size_before_relax (fragS * fragP,
646 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
647 abort ();
648 }
649+ else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type
650+ && !S_IS_WEAK (fragP->fr_symbol))
651+ {
652+ if (fragP->fr_opcode != NULL) {
653+ if(streq (fragP->fr_opcode, str_microblaze_64))
654+ {
655+ /* Used as an absolute value. */
656+ fragP->fr_subtype = DEFINED_64_OFFSET;
657+ /* Variable part does not change. */
658+ fragP->fr_var = INST_WORD_SIZE;
659+ }
660+ else
661+ {
662+ fragP->fr_subtype = DEFINED_PC_OFFSET;
663+ /* Don't know now whether we need an imm instruction. */
664+ fragP->fr_var = INST_WORD_SIZE;
665+ }
666+ }
667+ else
668+ {
669+ fragP->fr_subtype = DEFINED_PC_OFFSET;
670+ /* Don't know now whether we need an imm instruction. */
671+ fragP->fr_var = INST_WORD_SIZE;
672+ }
673+ }
674+#if 0
675 else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
676 !S_IS_WEAK (fragP->fr_symbol))
677 {
678@@ -2305,6 +2512,7 @@ md_estimate_size_before_relax (fragS * fragP,
679 /* Don't know now whether we need an imm instruction. */
680 fragP->fr_var = INST_WORD_SIZE;
681 }
682+#endif
683 else if (S_IS_DEFINED (fragP->fr_symbol)
684 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
685 {
686@@ -2316,7 +2524,14 @@ md_estimate_size_before_relax (fragS * fragP,
687 }
688 else
689 {
690- fragP->fr_subtype = UNDEFINED_PC_OFFSET;
691+ if (fragP->fr_opcode != NULL) {
692+ if (streq (fragP->fr_opcode, str_microblaze_64))
693+ fragP->fr_subtype = DEFINED_64_PC_OFFSET;
694+ else
695+ fragP->fr_subtype = UNDEFINED_PC_OFFSET;
696+ }
697+ else
698+ fragP->fr_subtype = UNDEFINED_PC_OFFSET;
699 fragP->fr_var = INST_WORD_SIZE*2;
700 }
701 break;
702@@ -2395,6 +2610,33 @@ md_estimate_size_before_relax (fragS * fragP,
703 abort ();
704 }
705 }
706+#if 0 //revisit
707+ else if (streq (name, "lli") || streq (name, "sli"))
708+ {
709+ temp = immed & 0xFFFFFFFFFFFF8000;
710+ if ((temp != 0) && (temp != 0xFFFFFFFFFFFF8000))
711+ {
712+ /* Needs an immediate inst. */
713+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
714+ if (opcode1 == NULL)
715+ {
716+ as_bad (_("unknown opcode \"%s\""), "imml");
717+ return;
718+ }
719+
720+ inst1 = opcode1->bit_sequence;
721+ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
722+ output[0] = INST_BYTE0 (inst1);
723+ output[1] = INST_BYTE1 (inst1);
724+ output[2] = INST_BYTE2 (inst1);
725+ output[3] = INST_BYTE3 (inst1);
726+ output = frag_more (isize);
727+ }
728+ inst |= (reg1 << RD_LOW) & RD_MASK;
729+ inst |= (reg2 << RA_LOW) & RA_MASK;
730+ inst |= (immed << IMM_LOW) & IMM_MASK;
731+ }
732+#endif
733 else
734 {
735 /* We know the abs value: Should never happen. */
736@@ -2414,6 +2656,7 @@ md_estimate_size_before_relax (fragS * fragP,
737 case TLSLD_OFFSET:
738 case TLSTPREL_OFFSET:
739 case TLSDTPREL_OFFSET:
740+ case DEFINED_64_OFFSET:
741 fragP->fr_var = INST_WORD_SIZE*2;
742 break;
743 case DEFINED_RO_SEGMENT:
744@@ -2467,7 +2710,7 @@ md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
745 else
746 {
747 /* The case where we are going to resolve things... */
748- if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
749+ if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64)
750 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
751 else
752 return fixp->fx_where + fixp->fx_frag->fr_address;
753@@ -2500,6 +2743,8 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
754 case BFD_RELOC_MICROBLAZE_32_RWSDA:
755 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
756 case BFD_RELOC_MICROBLAZE_64_GOTPC:
757+ case BFD_RELOC_MICROBLAZE_64_GPC:
758+ case BFD_RELOC_MICROBLAZE_64:
759 case BFD_RELOC_MICROBLAZE_64_GOT:
760 case BFD_RELOC_MICROBLAZE_64_PLT:
761 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
762@@ -2515,6 +2760,143 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
763 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
764 code = fixp->fx_r_type;
765 break;
766+ /* For 64-bit instructions */
767+ case INST_TYPE_RD_R1_IMML:
768+ if (strcmp (op_end, ""))
769+ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
770+ else
771+ {
772+ as_fatal (_("Error in statement syntax"));
773+ reg1 = 0;
774+ }
775+ if (strcmp (op_end, ""))
776+ op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
777+ else
778+ {
779+ as_fatal (_("Error in statement syntax"));
780+ reg2 = 0;
781+ }
782+ if (strcmp (op_end, ""))
783+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
784+ else
785+ as_fatal (_("Error in statement syntax"));
786+
787+ /* Check for spl registers. */
788+ if (check_spl_reg (& reg1))
789+ as_fatal (_("Cannot use special register with this instruction"));
790+ if (check_spl_reg (& reg2))
791+ as_fatal (_("Cannot use special register with this instruction"));
792+
793+ if (exp.X_op != O_constant)
794+ {
795+ char *opc = NULL;
796+ //char *opc = str_microblaze_64;
797+ relax_substateT subtype;
798+
799+ if (exp.X_md != 0)
800+ subtype = get_imm_otype(exp.X_md);
801+ else
802+ subtype = opcode->inst_offset_type;
803+
804+ output = frag_var (rs_machine_dependent,
805+ isize * 2, /* maxm of 2 words. */
806+ isize * 2, /* minm of 2 words. */
807+ subtype, /* PC-relative or not. */
808+ exp.X_add_symbol,
809+ exp.X_add_number,
810+ (char *) opc);
811+ immedl = 0L;
812+ }
813+ else
814+ {
815+ output = frag_more (isize);
816+ immedl = exp.X_add_number;
817+
818+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
819+ if (opcode1 == NULL)
820+ {
821+ as_bad (_("unknown opcode \"%s\""), "imml");
822+ return;
823+ }
824+
825+ inst1 = opcode1->bit_sequence;
826+ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
827+ output[0] = INST_BYTE0 (inst1);
828+ output[1] = INST_BYTE1 (inst1);
829+ output[2] = INST_BYTE2 (inst1);
830+ output[3] = INST_BYTE3 (inst1);
831+ output = frag_more (isize);
832+ }
833+
834+ inst |= (reg1 << RD_LOW) & RD_MASK;
835+ inst |= (reg2 << RA_LOW) & RA_MASK;
836+ inst |= (immedl << IMM_LOW) & IMM_MASK;
837+ break;
838+
839+ case INST_TYPE_R1_IMML:
840+ if (strcmp (op_end, ""))
841+ op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
842+ else
843+ {
844+ as_fatal (_("Error in statement syntax"));
845+ reg1 = 0;
846+ }
847+ if (strcmp (op_end, ""))
848+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
849+ else
850+ as_fatal (_("Error in statement syntax"));
851+
852+ /* Check for spl registers. */
853+ if (check_spl_reg (&reg1))
854+ as_fatal (_("Cannot use special register with this instruction"));
855+
856+ if (exp.X_op != O_constant)
857+ {
858+ //char *opc = NULL;
859+ char *opc = str_microblaze_64;
860+ relax_substateT subtype;
861+
862+ if (exp.X_md != 0)
863+ subtype = get_imm_otype(exp.X_md);
864+ else
865+ subtype = opcode->inst_offset_type;
866+
867+ output = frag_var (rs_machine_dependent,
868+ isize * 2, /* maxm of 2 words. */
869+ isize * 2, /* minm of 2 words. */
870+ subtype, /* PC-relative or not. */
871+ exp.X_add_symbol,
872+ exp.X_add_number,
873+ (char *) opc);
874+ immedl = 0L;
875+ }
876+ else
877+ {
878+ output = frag_more (isize);
879+ immedl = exp.X_add_number;
880+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
881+ if (opcode1 == NULL)
882+ {
883+ as_bad (_("unknown opcode \"%s\""), "imml");
884+ return;
885+ }
886+
887+ inst1 = opcode1->bit_sequence;
888+ inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
889+ output[0] = INST_BYTE0 (inst1);
890+ output[1] = INST_BYTE1 (inst1);
891+ output[2] = INST_BYTE2 (inst1);
892+ output[3] = INST_BYTE3 (inst1);
893+ output = frag_more (isize);
894+ }
895+
896+ inst |= (reg1 << RA_LOW) & RA_MASK;
897+ inst |= (immedl << IMM_LOW) & IMM_MASK;
898+ break;
899+
900+ case INST_TYPE_IMML:
901+ as_fatal (_("An IMML instruction should not be present in the .s file"));
902+ break;
903
904 default:
905 switch (F (fixp->fx_size, fixp->fx_pcrel))
906@@ -2560,6 +2942,18 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
907 return rel;
908 }
909
910+/* Called by TARGET_FORMAT. */
911+const char *
912+microblaze_target_format (void)
913+{
914+
915+ if (microblaze_arch_size == 64)
916+ return "elf64-microblazeel";
917+ else
918+ return target_big_endian ? "elf32-microblaze" : "elf32-microblazeel";
919+}
920+
921+
922 int
923 md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
924 {
925@@ -2573,6 +2967,10 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
926 case OPTION_LITTLE:
927 target_big_endian = 0;
928 break;
929+ case OPTION_M64:
930+ //if (arg != NULL && strcmp (arg, "64") == 0)
931+ microblaze_arch_size = 64;
932+ break;
933 default:
934 return 0;
935 }
936@@ -2588,6 +2986,7 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
937 fprintf (stream, _(" MicroBlaze specific assembler options:\n"));
938 fprintf (stream, " -%-23s%s\n", "mbig-endian", N_("assemble for a big endian cpu"));
939 fprintf (stream, " -%-23s%s\n", "mlittle-endian", N_("assemble for a little endian cpu"));
940+ fprintf (stream, " -%-23s%s\n", "m64", N_("generate 64-bit elf"));
941 }
942
943
944@@ -2625,7 +3024,10 @@ cons_fix_new_microblaze (fragS * frag,
945 r = BFD_RELOC_32;
946 break;
947 case 8:
948- r = BFD_RELOC_64;
949+ if (microblaze_arch_size == 64)
950+ r = BFD_RELOC_32;
951+ else
952+ r = BFD_RELOC_64;
953 break;
954 default:
955 as_bad (_("unsupported BFD relocation size %u"), size);
956--
9572.34.1
958
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0023-Added-relocations-for-MB-X.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0023-Added-relocations-for-MB-X.patch
new file mode 100644
index 00000000..f92dd068
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0023-Added-relocations-for-MB-X.patch
@@ -0,0 +1,246 @@
1From fb4a4d6855092f5b0b201e40234782822cd63a66 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Tue, 11 Sep 2018 17:30:17 +0530
4Subject: [PATCH 23/53] Added relocations for MB-X
5
6Conflicts:
7 bfd/bfd-in2.h
8 gas/config/tc-microblaze.c
9
10Conflicts:
11 gas/config/tc-microblaze.c
12
13Signed-off-by: Aayush Misra <aayushm@amd.com>
14---
15 bfd/libbfd.h | 2 --
16 bfd/reloc.c | 26 ++++++++-------
17 gas/config/tc-microblaze.c | 68 ++++++++++++--------------------------
18 3 files changed, 36 insertions(+), 60 deletions(-)
19
20diff --git a/bfd/libbfd.h b/bfd/libbfd.h
21index 603ed8260cb..7a3e558d70a 100644
22--- a/bfd/libbfd.h
23+++ b/bfd/libbfd.h
24@@ -3005,9 +3005,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
25 "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
26 "BFD_RELOC_MICROBLAZE_32_NONE",
27 "BFD_RELOC_MICROBLAZE_64_NONE",
28- "BFD_RELOC_MICROBLAZE_64",
29 "BFD_RELOC_MICROBLAZE_64_GOTPC",
30- "BFD_RELOC_MICROBLAZE_64_GPC",
31 "BFD_RELOC_MICROBLAZE_64_GOT",
32 "BFD_RELOC_MICROBLAZE_64_PLT",
33 "BFD_RELOC_MICROBLAZE_64_GOTOFF",
34diff --git a/bfd/reloc.c b/bfd/reloc.c
35index 6eb93e993f0..b6c9c22a0be 100644
36--- a/bfd/reloc.c
37+++ b/bfd/reloc.c
38@@ -6634,6 +6634,20 @@ ENUM
39 ENUMDOC
40 Address of a GOT entry.
41
42+ This is a 64 bit reloc that stores 64-bit thread pointer relative offset
43+ to two words (uses imml instruction).
44+ENUM
45+BFD_RELOC_MICROBLAZE_64,
46+ENUMDOC
47+ This is a 64 bit reloc that stores the 64 bit pc relative
48+ value in two words (with an imml instruction). No relocation is
49+ done here - only used for relaxing
50+ENUM
51+BFD_RELOC_MICROBLAZE_64_PCREL,
52+ENUMDOC
53+ This is a 32 bit reloc that stores the 32 bit pc relative
54+ value in two words (with an imml instruction). No relocation is
55+ done here - only used for relaxing
56 ENUM
57 BFD_RELOC_MICROBLAZE_32_LO
58 ENUMDOC
59@@ -6671,12 +6685,6 @@ ENUMDOC
60 This is a 64 bit reloc that stores the 32 bit pc relative value in
61 two words (with an imm instruction). No relocation is done here -
62 only used for relaxing.
63-ENUM
64- BFD_RELOC_MICROBLAZE_64
65-ENUMDOC
66- This is a 64 bit reloc that stores the 32 bit pc relative
67- value in two words (with an imm instruction). No relocation is
68- done here - only used for relaxing
69 ENUM
70 BFD_RELOC_MICROBLAZE_64_PCREL,
71 ENUMDOC
72@@ -6689,12 +6697,6 @@ ENUMDOC
73 This is a 64 bit reloc that stores the 32 bit pc relative
74 value in two words (with an imml instruction). No relocation is
75 done here - only used for relaxing
76-ENUM
77- BFD_RELOC_MICROBLAZE_64_GPC
78-ENUMDOC
79- This is a 64 bit reloc that stores the 32 bit pc relative
80- value in two words (with an imm instruction). The relocation is
81- PC-relative GOT offset
82 ENUM
83 BFD_RELOC_MICROBLAZE_64_GOT
84 ENUMDOC
85diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
86index 6640266cc47..29fb6360169 100644
87--- a/gas/config/tc-microblaze.c
88+++ b/gas/config/tc-microblaze.c
89@@ -2096,23 +2096,29 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
90 fragP->fr_fix += INST_WORD_SIZE * 2;
91 fragP->fr_var = 0;
92 break;
93+ case DEFINED_64_PC_OFFSET:
94+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
95+ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PCREL);
96+ fragP->fr_fix += INST_WORD_SIZE * 2;
97+ fragP->fr_var = 0;
98+ break;
99 case DEFINED_64_OFFSET:
100 if (fragP->fr_symbol == GOT_symbol)
101 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
102- fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64_GPC);
103+ fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_GPC);
104 else
105 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
106- fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64);
107+ fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64);
108 fragP->fr_fix += INST_WORD_SIZE * 2;
109 fragP->fr_var = 0;
110 break;
111 case DEFINED_ABS_SEGMENT:
112 if (fragP->fr_symbol == GOT_symbol)
113 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
114- fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64_GOTPC);
115+ fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64_GOTPC);
116 else
117 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
118- fragP->fr_offset, true, BFD_RELOC_64);
119+ fragP->fr_offset, false, BFD_RELOC_64);
120 fragP->fr_fix += INST_WORD_SIZE * 2;
121 fragP->fr_var = 0;
122 break;
123@@ -2334,10 +2340,12 @@ md_apply_fix (fixS * fixP,
124 case BFD_RELOC_64:
125 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
126 case BFD_RELOC_MICROBLAZE_64:
127+ case BFD_RELOC_MICROBLAZE_64_PCREL:
128 /* Add an imm instruction. First save the current instruction. */
129 for (i = 0; i < INST_WORD_SIZE; i++)
130 buf[i + INST_WORD_SIZE] = buf[i];
131- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
132+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64
133+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
134 {
135 /* Generate the imm instruction. */
136 opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
137@@ -2350,6 +2358,10 @@ md_apply_fix (fixS * fixP,
138 inst1 = opcode1->bit_sequence;
139 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
140 inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
141+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
142+ fixP->fx_r_type = BFD_RELOC_64;
143+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
144+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
145 }
146 else
147 {
148@@ -2435,8 +2447,6 @@ md_apply_fix (fixS * fixP,
149 moves code around due to relaxing. */
150 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
151 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
152- else if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
153- fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
154 else if (fixP->fx_r_type == BFD_RELOC_32)
155 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
156 else
157@@ -2486,9 +2496,9 @@ md_estimate_size_before_relax (fragS * fragP,
158 if(streq (fragP->fr_opcode, str_microblaze_64))
159 {
160 /* Used as an absolute value. */
161- fragP->fr_subtype = DEFINED_64_OFFSET;
162+ fragP->fr_subtype = DEFINED_64_PC_OFFSET;
163 /* Variable part does not change. */
164- fragP->fr_var = INST_WORD_SIZE;
165+ fragP->fr_var = INST_WORD_SIZE*2;
166 }
167 else
168 {
169@@ -2504,15 +2514,6 @@ md_estimate_size_before_relax (fragS * fragP,
170 fragP->fr_var = INST_WORD_SIZE;
171 }
172 }
173-#if 0
174- else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
175- !S_IS_WEAK (fragP->fr_symbol))
176- {
177- fragP->fr_subtype = DEFINED_PC_OFFSET;
178- /* Don't know now whether we need an imm instruction. */
179- fragP->fr_var = INST_WORD_SIZE;
180- }
181-#endif
182 else if (S_IS_DEFINED (fragP->fr_symbol)
183 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
184 {
185@@ -2610,33 +2611,6 @@ md_estimate_size_before_relax (fragS * fragP,
186 abort ();
187 }
188 }
189-#if 0 //revisit
190- else if (streq (name, "lli") || streq (name, "sli"))
191- {
192- temp = immed & 0xFFFFFFFFFFFF8000;
193- if ((temp != 0) && (temp != 0xFFFFFFFFFFFF8000))
194- {
195- /* Needs an immediate inst. */
196- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
197- if (opcode1 == NULL)
198- {
199- as_bad (_("unknown opcode \"%s\""), "imml");
200- return;
201- }
202-
203- inst1 = opcode1->bit_sequence;
204- inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
205- output[0] = INST_BYTE0 (inst1);
206- output[1] = INST_BYTE1 (inst1);
207- output[2] = INST_BYTE2 (inst1);
208- output[3] = INST_BYTE3 (inst1);
209- output = frag_more (isize);
210- }
211- inst |= (reg1 << RD_LOW) & RD_MASK;
212- inst |= (reg2 << RA_LOW) & RA_MASK;
213- inst |= (immed << IMM_LOW) & IMM_MASK;
214- }
215-#endif
216 else
217 {
218 /* We know the abs value: Should never happen. */
219@@ -2657,6 +2631,7 @@ md_estimate_size_before_relax (fragS * fragP,
220 case TLSTPREL_OFFSET:
221 case TLSDTPREL_OFFSET:
222 case DEFINED_64_OFFSET:
223+ case DEFINED_64_PC_OFFSET:
224 fragP->fr_var = INST_WORD_SIZE*2;
225 break;
226 case DEFINED_RO_SEGMENT:
227@@ -2710,7 +2685,7 @@ md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
228 else
229 {
230 /* The case where we are going to resolve things... */
231- if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64)
232+ if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
233 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
234 else
235 return fixp->fx_where + fixp->fx_frag->fr_address;
236@@ -2745,6 +2720,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
237 case BFD_RELOC_MICROBLAZE_64_GOTPC:
238 case BFD_RELOC_MICROBLAZE_64_GPC:
239 case BFD_RELOC_MICROBLAZE_64:
240+ case BFD_RELOC_MICROBLAZE_64_PCREL:
241 case BFD_RELOC_MICROBLAZE_64_GOT:
242 case BFD_RELOC_MICROBLAZE_64_PLT:
243 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
244--
2452.34.1
246
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0024-Fixed-MB-x-relocation-issues-Added-imml-for-required.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0024-Fixed-MB-x-relocation-issues-Added-imml-for-required.patch
new file mode 100644
index 00000000..18698b02
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0024-Fixed-MB-x-relocation-issues-Added-imml-for-required.patch
@@ -0,0 +1,52 @@
1From 88f7a313f8e21021dacfc8da2c490a433f596fd8 Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Fri, 28 Sep 2018 12:04:55 +0530
4Subject: [PATCH 24/53] -Fixed MB-x relocation issues -Added imml for required
5 MB-x instructions
6
7Conflicts:
8 bfd/elf64-microblaze.c
9 gas/config/tc-microblaze.c
10
11Conflicts:
12 gas/config/tc-microblaze.c
13
14Signed-off-by: Aayush Misra <aayushm@amd.com>
15---
16 gas/config/tc-microblaze.c | 6 ++++--
17 1 file changed, 4 insertions(+), 2 deletions(-)
18
19diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
20index 29fb6360169..e43ea82a2cc 100644
21--- a/gas/config/tc-microblaze.c
22+++ b/gas/config/tc-microblaze.c
23@@ -363,7 +363,7 @@ microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
24 Integer arg to pass to the function. */
25 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
26 and then in the read.c table. */
27-pseudo_typeS md_pseudo_table[] =
28+const pseudo_typeS md_pseudo_table[] =
29 {
30 {"lcomm", microblaze_s_lcomm, 1},
31 {"data8", cons, 1}, /* Same as byte. */
32@@ -2357,7 +2357,7 @@ md_apply_fix (fixS * fixP,
33
34 inst1 = opcode1->bit_sequence;
35 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
36- inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
37+ inst1 |= ((val & 0xFFFFFF0000L) >> 16) & IMML_MASK;
38 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
39 fixP->fx_r_type = BFD_RELOC_64;
40 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
41@@ -2946,6 +2946,8 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
42 case OPTION_M64:
43 //if (arg != NULL && strcmp (arg, "64") == 0)
44 microblaze_arch_size = 64;
45+ // UPSTREAM/REVISIT - md_pseudo_table is const
46+ // md_pseudo_table[7].poc_val = 8;
47 break;
48 default:
49 return 0;
50--
512.34.1
52
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0025-Fixed-address-computation-issues-with-64bit-address-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0025-Fixed-address-computation-issues-with-64bit-address-.patch
new file mode 100644
index 00000000..d480388c
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0025-Fixed-address-computation-issues-with-64bit-address-.patch
@@ -0,0 +1,160 @@
1From 585f95d1510385ed3f67e76e2ad8f9a27b3ee32a Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Tue, 9 Oct 2018 10:14:22 +0530
4Subject: [PATCH 25/53] - Fixed address computation issues with 64bit address -
5 Fixed imml dissassamble issue
6
7Conflicts:
8 gas/config/tc-microblaze.c
9 opcodes/microblaze-dis.c
10
11Conflicts:
12 bfd/elf64-microblaze.c
13
14Conflicts:
15 bfd/elf64-microblaze.c
16
17Signed-off-by: Aayush Misra <aayushm@amd.com>
18---
19 bfd/elf64-microblaze.c | 2 +-
20 gas/config/tc-microblaze.c | 74 +++++++++++++++++++++++++++++++++-----
21 2 files changed, 67 insertions(+), 9 deletions(-)
22
23diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
24index ca92df647c9..9f542f55ebd 100755
25--- a/bfd/elf64-microblaze.c
26+++ b/bfd/elf64-microblaze.c
27@@ -2131,7 +2131,7 @@ microblaze_elf_relax_section (bfd *abfd,
28 efix = calc_fixup (target_address, 0, sec);
29
30 /* Validate the in-band val. */
31- val = bfd_get_32 (abfd, contents + irel->r_offset);
32+ val = bfd_get_64 (abfd, contents + irel->r_offset);
33 if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
34 fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
35 }
36diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
37index e43ea82a2cc..544732649a5 100644
38--- a/gas/config/tc-microblaze.c
39+++ b/gas/config/tc-microblaze.c
40@@ -372,7 +372,6 @@ const pseudo_typeS md_pseudo_table[] =
41 {"ent", s_func, 0}, /* Treat ent as function entry point. */
42 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
43 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
44- {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
45 {"weakext", microblaze_s_weakext, 0},
46 {"rodata", microblaze_s_rdata, 0},
47 {"sdata2", microblaze_s_rdata, 1},
48@@ -2317,18 +2316,74 @@ md_apply_fix (fixS * fixP,
49 case BFD_RELOC_RVA:
50 case BFD_RELOC_32_PCREL:
51 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
52+ /* Don't do anything if the symbol is not defined. */
53+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
54+ {
55+ if ((fixP->fx_r_type == BFD_RELOC_RVA) && (microblaze_arch_size == 64))
56+ {
57+ if (target_big_endian)
58+ {
59+ buf[0] |= ((val >> 56) & 0xff);
60+ buf[1] |= ((val >> 48) & 0xff);
61+ buf[2] |= ((val >> 40) & 0xff);
62+ buf[3] |= ((val >> 32) & 0xff);
63+ buf[4] |= ((val >> 24) & 0xff);
64+ buf[5] |= ((val >> 16) & 0xff);
65+ buf[6] |= ((val >> 8) & 0xff);
66+ buf[7] |= (val & 0xff);
67+ }
68+ else
69+ {
70+ buf[7] |= ((val >> 56) & 0xff);
71+ buf[6] |= ((val >> 48) & 0xff);
72+ buf[5] |= ((val >> 40) & 0xff);
73+ buf[4] |= ((val >> 32) & 0xff);
74+ buf[3] |= ((val >> 24) & 0xff);
75+ buf[2] |= ((val >> 16) & 0xff);
76+ buf[1] |= ((val >> 8) & 0xff);
77+ buf[0] |= (val & 0xff);
78+ }
79+ }
80+ else {
81+ if (target_big_endian)
82+ {
83+ buf[0] |= ((val >> 24) & 0xff);
84+ buf[1] |= ((val >> 16) & 0xff);
85+ buf[2] |= ((val >> 8) & 0xff);
86+ buf[3] |= (val & 0xff);
87+ }
88+ else
89+ {
90+ buf[3] |= ((val >> 24) & 0xff);
91+ buf[2] |= ((val >> 16) & 0xff);
92+ buf[1] |= ((val >> 8) & 0xff);
93+ buf[0] |= (val & 0xff);
94+ }
95+ }
96+ }
97+ break;
98+
99+ case BFD_RELOC_MICROBLAZE_EA64:
100 /* Don't do anything if the symbol is not defined. */
101 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
102 {
103 if (target_big_endian)
104 {
105- buf[0] |= ((val >> 24) & 0xff);
106- buf[1] |= ((val >> 16) & 0xff);
107- buf[2] |= ((val >> 8) & 0xff);
108- buf[3] |= (val & 0xff);
109+ buf[0] |= ((val >> 56) & 0xff);
110+ buf[1] |= ((val >> 48) & 0xff);
111+ buf[2] |= ((val >> 40) & 0xff);
112+ buf[3] |= ((val >> 32) & 0xff);
113+ buf[4] |= ((val >> 24) & 0xff);
114+ buf[5] |= ((val >> 16) & 0xff);
115+ buf[6] |= ((val >> 8) & 0xff);
116+ buf[7] |= (val & 0xff);
117 }
118 else
119 {
120+ buf[7] |= ((val >> 56) & 0xff);
121+ buf[6] |= ((val >> 48) & 0xff);
122+ buf[5] |= ((val >> 40) & 0xff);
123+ buf[4] |= ((val >> 32) & 0xff);
124 buf[3] |= ((val >> 24) & 0xff);
125 buf[2] |= ((val >> 16) & 0xff);
126 buf[1] |= ((val >> 8) & 0xff);
127@@ -2449,6 +2504,8 @@ md_apply_fix (fixS * fixP,
128 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
129 else if (fixP->fx_r_type == BFD_RELOC_32)
130 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
131+ else if(fixP->fx_r_type == BFD_RELOC_MICROBLAZE_EA64)
132+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_EA64;
133 else
134 fixP->fx_r_type = BFD_RELOC_NONE;
135 fixP->fx_addsy = section_symbol (absolute_section);
136@@ -2719,6 +2776,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
137 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
138 case BFD_RELOC_MICROBLAZE_64_GOTPC:
139 case BFD_RELOC_MICROBLAZE_64_GPC:
140+ case BFD_RELOC_MICROBLAZE_EA64:
141 case BFD_RELOC_MICROBLAZE_64:
142 case BFD_RELOC_MICROBLAZE_64_PCREL:
143 case BFD_RELOC_MICROBLAZE_64_GOT:
144@@ -3002,10 +3060,10 @@ cons_fix_new_microblaze (fragS * frag,
145 r = BFD_RELOC_32;
146 break;
147 case 8:
148- if (microblaze_arch_size == 64)
149+ /*if (microblaze_arch_size == 64)
150 r = BFD_RELOC_32;
151- else
152- r = BFD_RELOC_64;
153+ else*/
154+ r = BFD_RELOC_MICROBLAZE_EA64;
155 break;
156 default:
157 as_bad (_("unsupported BFD relocation size %u"), size);
158--
1592.34.1
160
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0026-Patch-MicroBlaze-Adding-new-relocation-to-support-64.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0026-Patch-MicroBlaze-Adding-new-relocation-to-support-64.patch
new file mode 100644
index 00000000..03d8e0b8
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0026-Patch-MicroBlaze-Adding-new-relocation-to-support-64.patch
@@ -0,0 +1,110 @@
1From d3fd5a77fa218f8f6c296337758d45cab61483fe Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 2 Nov 2021 17:28:24 +0530
4Subject: [PATCH 26/53] [Patch,MicroBlaze : Adding new relocation to support
5 64bit rodata.
6
7Signed-off-by: Aayush Misra <aayushm@amd.com>
8---
9 gas/config/tc-microblaze.c | 49 ++++++++++++++++++++++++++++++++++----
10 1 file changed, 45 insertions(+), 4 deletions(-)
11
12diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
13index 544732649a5..c9757796ae8 100644
14--- a/gas/config/tc-microblaze.c
15+++ b/gas/config/tc-microblaze.c
16@@ -1090,6 +1090,13 @@ md_assemble (char * str)
17 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
18 if(streq (name, "lli") || streq (name, "sli"))
19 opc = str_microblaze_64;
20+ else if ((microblaze_arch_size == 64) && ((streq (name, "lbui")
21+ || streq (name, "lhui") || streq (name, "lwi") || streq (name, "sbi")
22+ || streq (name, "shi") || streq (name, "swi"))))
23+ {
24+ opc = str_microblaze_64;
25+ subtype = opcode->inst_offset_type;
26+ }
27 else if (reg2 == REG_ROSDP)
28 opc = str_microblaze_ro_anchor;
29 else if (reg2 == REG_RWSDP)
30@@ -1157,7 +1164,10 @@ md_assemble (char * str)
31 inst |= (immed << IMM_LOW) & IMM_MASK;
32 }
33 }
34- else if (streq (name, "lli") || streq (name, "sli"))
35+ else if (streq (name, "lli") || streq (name, "sli") || ((microblaze_arch_size == 64)
36+ && ((streq (name, "lbui")) || streq (name, "lhui")
37+ || streq (name, "lwi") || streq (name, "sbi")
38+ || streq (name, "shi") || streq (name, "swi"))))
39 {
40 temp = immed & 0xFFFFFF8000;
41 if (temp != 0 && temp != 0xFFFFFF8000)
42@@ -1773,6 +1783,11 @@ md_assemble (char * str)
43
44 if (exp.X_md != 0)
45 subtype = get_imm_otype(exp.X_md);
46+ else if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
47+ {
48+ opc = str_microblaze_64;
49+ subtype = opcode->inst_offset_type;
50+ }
51 else
52 subtype = opcode->inst_offset_type;
53
54@@ -1790,6 +1805,31 @@ md_assemble (char * str)
55 output = frag_more (isize);
56 immed = exp.X_add_number;
57 }
58+ if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
59+ {
60+ temp = immed & 0xFFFFFF8000;
61+ if (temp != 0 && temp != 0xFFFFFF8000)
62+ {
63+ /* Needs an immediate inst. */
64+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
65+ if (opcode1 == NULL)
66+ {
67+ as_bad (_("unknown opcode \"%s\""), "imml");
68+ return;
69+ }
70+ inst1 = opcode1->bit_sequence;
71+ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
72+ output[0] = INST_BYTE0 (inst1);
73+ output[1] = INST_BYTE1 (inst1);
74+ output[2] = INST_BYTE2 (inst1);
75+ output[3] = INST_BYTE3 (inst1);
76+ output = frag_more (isize);
77+ }
78+ inst |= (reg1 << RD_LOW) & RD_MASK;
79+ inst |= (immed << IMM_LOW) & IMM_MASK;
80+ }
81+ else
82+ {
83
84 temp = immed & 0xFFFF8000;
85 if ((temp != 0) && (temp != 0xFFFF8000))
86@@ -1815,6 +1855,7 @@ md_assemble (char * str)
87
88 inst |= (reg1 << RD_LOW) & RD_MASK;
89 inst |= (immed << IMM_LOW) & IMM_MASK;
90+ }
91 break;
92
93 case INST_TYPE_R2:
94@@ -3060,10 +3101,10 @@ cons_fix_new_microblaze (fragS * frag,
95 r = BFD_RELOC_32;
96 break;
97 case 8:
98- /*if (microblaze_arch_size == 64)
99- r = BFD_RELOC_32;
100- else*/
101+ if (microblaze_arch_size == 64)
102 r = BFD_RELOC_MICROBLAZE_EA64;
103+ else
104+ r = BFD_RELOC_64;
105 break;
106 default:
107 as_bad (_("unsupported BFD relocation size %u"), size);
108--
1092.34.1
110
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0027-Revert-ld-Remove-unused-expression-state-defsym-symb.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0027-Revert-ld-Remove-unused-expression-state-defsym-symb.patch
new file mode 100644
index 00000000..5a8992df
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0027-Revert-ld-Remove-unused-expression-state-defsym-symb.patch
@@ -0,0 +1,84 @@
1From e89c2729322ce147e8a5a5e7842944593b4dd474 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Wed, 27 Feb 2019 15:12:32 +0530
4Subject: [PATCH 27/53] Revert "ld: Remove unused expression state" --defsym
5 symbol=expression Create a global symbol in the output file, containing the
6 absolute address given by expression.
7
8This reverts commit 65f14869fd3fbee8ed4c4ca49de8aaa86dbc66cb.
9
10Conflicts:
11 ld/ChangeLog
12
13Conflicts:
14 ld/ldexp.c
15 ld/ldexp.h
16
17Signed-off-by: Aayush Misra <aayushm@amd.com>
18---
19 ld/ldexp.c | 8 +++++---
20 ld/ldexp.h | 1 +
21 2 files changed, 6 insertions(+), 3 deletions(-)
22
23diff --git a/ld/ldexp.c b/ld/ldexp.c
24index 3c8ab2d3589..525f3e4262c 100644
25--- a/ld/ldexp.c
26+++ b/ld/ldexp.c
27@@ -1402,6 +1402,7 @@ static etree_type *
28 exp_assop (const char *dst,
29 etree_type *src,
30 enum node_tree_enum class,
31+ bool defsym,
32 bool hidden)
33 {
34 etree_type *n;
35@@ -1413,6 +1414,7 @@ exp_assop (const char *dst,
36 n->assign.type.node_class = class;
37 n->assign.src = src;
38 n->assign.dst = dst;
39+ n->assign.defsym = defsym;
40 n->assign.hidden = hidden;
41 return n;
42 }
43@@ -1422,7 +1424,7 @@ exp_assop (const char *dst,
44 etree_type *
45 exp_assign (const char *dst, etree_type *src, bool hidden)
46 {
47- return exp_assop (dst, src, etree_assign, hidden);
48+ return exp_assop (dst, src, etree_assign, false, hidden);
49 }
50
51 /* Handle --defsym command-line option. */
52@@ -1430,7 +1432,7 @@ exp_assign (const char *dst, etree_type *src, bool hidden)
53 etree_type *
54 exp_defsym (const char *dst, etree_type *src)
55 {
56- return exp_assop (dst, src, etree_assign, false);
57+ return exp_assop (dst, src, etree_assign, true, false);
58 }
59
60 /* Handle PROVIDE. */
61@@ -1438,7 +1440,7 @@ exp_defsym (const char *dst, etree_type *src)
62 etree_type *
63 exp_provide (const char *dst, etree_type *src, bool hidden)
64 {
65- return exp_assop (dst, src, etree_provide, hidden);
66+ return exp_assop (dst, src, etree_provide, false, hidden);
67 }
68
69 /* Handle ASSERT. */
70diff --git a/ld/ldexp.h b/ld/ldexp.h
71index c779729e900..6d583e1b15a 100644
72--- a/ld/ldexp.h
73+++ b/ld/ldexp.h
74@@ -66,6 +66,7 @@ typedef union etree_union {
75 node_type type;
76 const char *dst;
77 union etree_union *src;
78+ bool defsym;
79 bool hidden;
80 } assign;
81 struct {
82--
832.34.1
84
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0028-fixing-the-long-long-long-mingw-toolchain-issue.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0028-fixing-the-long-long-long-mingw-toolchain-issue.patch
new file mode 100644
index 00000000..675ce3ee
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0028-fixing-the-long-long-long-mingw-toolchain-issue.patch
@@ -0,0 +1,58 @@
1From 21eacbba925e2aaceaf3d3400030ae61a1aa4fef Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Thu, 29 Nov 2018 17:59:25 +0530
4Subject: [PATCH 28/53] fixing the long & long long mingw toolchain issue
5
6Signed-off-by: Aayush Misra <aayushm@amd.com>
7---
8 gas/config/tc-microblaze.c | 10 +++++-----
9 opcodes/microblaze-opc.h | 4 ++--
10 2 files changed, 7 insertions(+), 7 deletions(-)
11
12diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
13index c9757796ae8..a8194d175e1 100644
14--- a/gas/config/tc-microblaze.c
15+++ b/gas/config/tc-microblaze.c
16@@ -754,7 +754,7 @@ parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
17 }
18
19 static char *
20-parse_imml (char * s, expressionS * e, long min, long max)
21+parse_imml (char * s, expressionS * e, long long min, long long max)
22 {
23 char *new_pointer;
24 char *atp;
25@@ -805,11 +805,11 @@ parse_imml (char * s, expressionS * e, long min, long max)
26 ; /* An error message has already been emitted. */
27 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
28 as_fatal (_("operand must be a constant or a label"));
29- else if ((e->X_op == O_constant) && ((long) e->X_add_number < min
30- || (long) e->X_add_number > max))
31+ else if ((e->X_op == O_constant) && ((long long) e->X_add_number < min
32+ || (long long) e->X_add_number > max))
33 {
34- as_fatal (_("operand must be absolute in range %ld..%ld, not %ld"),
35- min, max, (long) e->X_add_number);
36+ as_fatal (_("operand must be absolute in range %lld..%lld, not %lld"),
37+ min, max, (long long) e->X_add_number);
38 }
39
40 if (atp)
41diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
42index d9d05721dae..f85f5a600cc 100644
43--- a/opcodes/microblaze-opc.h
44+++ b/opcodes/microblaze-opc.h
45@@ -592,8 +592,8 @@ char pvr_register_prefix[] = "rpvr";
46 #define MIN_IMM6_WIDTH ((int) 0x00000001)
47 #define MAX_IMM6_WIDTH ((int) 0x00000040)
48
49-#define MIN_IMML ((long) 0xffffff8000000000L)
50-#define MAX_IMML ((long) 0x0000007fffffffffL)
51+#define MIN_IMML ((long long) 0xffffff8000000000L)
52+#define MAX_IMML ((long long) 0x0000007fffffffffL)
53
54 #endif /* MICROBLAZE_OPC */
55
56--
572.34.1
58
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0029-Added-support-to-new-arithmetic-single-register-inst.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0029-Added-support-to-new-arithmetic-single-register-inst.patch
new file mode 100644
index 00000000..6199a4e5
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0029-Added-support-to-new-arithmetic-single-register-inst.patch
@@ -0,0 +1,371 @@
1From c0cff55375899b12045eef8f5755e68a598ee4ff Mon Sep 17 00:00:00 2001
2From: Nagaraju <nmekala@xilinx.com>
3Date: Fri, 23 Aug 2019 16:18:43 +0530
4Subject: [PATCH 29/53] Added support to new arithmetic single register
5 instructions
6
7Conflicts:
8 opcodes/microblaze-dis.c
9
10Conflicts:
11 gas/config/tc-microblaze.c
12 opcodes/microblaze-dis.c
13
14Conflicts:
15 gas/config/tc-microblaze.c
16signed-off-by:Nagaraju <nmekala@xilinx.com>
17 Mahesh <mbodapat@xilinx.com>
18
19Signed-off-by: Aayush Misra <aayushm@amd.com>
20---
21 gas/config/tc-microblaze.c | 147 ++++++++++++++++++++++++++++++++++++-
22 opcodes/microblaze-dis.c | 11 +++
23 opcodes/microblaze-opc.h | 43 ++++++++++-
24 opcodes/microblaze-opcm.h | 5 +-
25 4 files changed, 200 insertions(+), 6 deletions(-)
26
27diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
28index a8194d175e1..3c9aec4c1f9 100644
29--- a/gas/config/tc-microblaze.c
30+++ b/gas/config/tc-microblaze.c
31@@ -394,12 +394,33 @@ void
32 md_begin (void)
33 {
34 const struct op_code_struct * opcode;
35+ const char *prev_name = "";
36
37 opcode_hash_control = str_htab_create ();
38
39 /* Insert unique names into hash table. */
40- for (opcode = microblaze_opcodes; opcode->name; opcode ++)
41- str_hash_insert (opcode_hash_control, opcode->name, opcode, 0);
42+ for (opcode = (struct microblaze_opcodes *)microblaze_opcodes; opcode->name; opcode ++)
43+ {
44+ if (strcmp (prev_name, opcode->name))
45+ {
46+ prev_name = (char *) opcode->name;
47+ str_hash_insert (opcode_hash_control, opcode->name, opcode, 0);
48+ }
49+ }
50+}
51+
52+static int
53+is_reg (char * s)
54+{
55+ int is_reg = 0;
56+ /* Strip leading whitespace. */
57+ while (ISSPACE (* s))
58+ ++ s;
59+ if (TOLOWER (s[0]) == 'r')
60+ {
61+ is_reg =1;
62+ }
63+ return is_reg;
64 }
65
66 /* Try to parse a reg name. */
67@@ -957,6 +978,7 @@ md_assemble (char * str)
68 {
69 char * op_start;
70 char * op_end;
71+ char * temp_op_end;
72 struct op_code_struct * opcode, *opcode1;
73 char * output = NULL;
74 int nlen = 0;
75@@ -967,9 +989,10 @@ md_assemble (char * str)
76 unsigned reg3;
77 unsigned isize;
78 unsigned long immed = 0, immed2 = 0, temp;
79- expressionS exp;
80+ expressionS exp,exp1;
81 char name[20];
82 long immedl;
83+ int reg=0;
84
85 /* Drop leading whitespace. */
86 while (ISSPACE (* str))
87@@ -1000,7 +1023,78 @@ md_assemble (char * str)
88 as_bad (_("unknown opcode \"%s\""), name);
89 return;
90 }
91-
92+
93+ if ((microblaze_arch_size == 64) && (streq (name, "addli") || streq (name, "addlic") ||
94+ streq (name, "addlik") || streq (name, "addlikc") || streq (name, "rsubli")
95+ || streq (name, "rsublic") || streq (name, "rsublik") || streq (name, "rsublikc")
96+ || streq (name, "andli") || streq (name, "andnli") || streq (name, "orli")
97+ || streq (name, "xorli")))
98+ {
99+ temp_op_end = op_end;
100+ if (strcmp (temp_op_end, ""))
101+ temp_op_end = parse_reg (temp_op_end + 1, &reg1); /* Get rd. */
102+ if (strcmp (temp_op_end, ""))
103+ reg = is_reg (temp_op_end + 1);
104+ if (reg)
105+ {
106+
107+ opcode->inst_type=INST_TYPE_RD_R1_IMML;
108+ opcode->inst_offset_type = OPCODE_MASK_H;
109+ if (streq (name, "addli"))
110+ opcode->bit_sequence = ADDLI_MASK;
111+ else if (streq (name, "addlic"))
112+ opcode->bit_sequence = ADDLIC_MASK;
113+ else if (streq (name, "addlik"))
114+ opcode->bit_sequence = ADDLIK_MASK;
115+ else if (streq (name, "addlikc"))
116+ opcode->bit_sequence = ADDLIKC_MASK;
117+ else if (streq (name, "rsubli"))
118+ opcode->bit_sequence = RSUBLI_MASK;
119+ else if (streq (name, "rsublic"))
120+ opcode->bit_sequence = RSUBLIC_MASK;
121+ else if (streq (name, "rsublik"))
122+ opcode->bit_sequence = RSUBLIK_MASK;
123+ else if (streq (name, "rsublikc"))
124+ opcode->bit_sequence = RSUBLIKC_MASK;
125+ else if (streq (name, "andli"))
126+ opcode->bit_sequence = ANDLI_MASK;
127+ else if (streq (name, "andnli"))
128+ opcode->bit_sequence = ANDLNI_MASK;
129+ else if (streq (name, "orli"))
130+ opcode->bit_sequence = ORLI_MASK;
131+ else if (streq (name, "xorli"))
132+ opcode->bit_sequence = XORLI_MASK;
133+ }
134+ else
135+ {
136+ opcode->inst_type=INST_TYPE_RD_IMML;
137+ opcode->inst_offset_type = OPCODE_MASK_LIMM;
138+ if (streq (name, "addli"))
139+ opcode->bit_sequence = ADDLI_ONE_REG_MASK;
140+ else if (streq (name, "addlic"))
141+ opcode->bit_sequence = ADDLIC_ONE_REG_MASK;
142+ else if (streq (name, "addlik"))
143+ opcode->bit_sequence = ADDLIK_ONE_REG_MASK;
144+ else if (streq (name, "addlikc"))
145+ opcode->bit_sequence = ADDLIKC_ONE_REG_MASK;
146+ else if (streq (name, "rsubli"))
147+ opcode->bit_sequence = RSUBLI_ONE_REG_MASK;
148+ else if (streq (name, "rsublic"))
149+ opcode->bit_sequence = RSUBLIC_ONE_REG_MASK;
150+ else if (streq (name, "rsublik"))
151+ opcode->bit_sequence = RSUBLIK_ONE_REG_MASK;
152+ else if (streq (name, "rsublikc"))
153+ opcode->bit_sequence = RSUBLIKC_ONE_REG_MASK;
154+ else if (streq (name, "andli"))
155+ opcode->bit_sequence = ANDLI_ONE_REG_MASK;
156+ else if (streq (name, "andnli"))
157+ opcode->bit_sequence = ANDLNI_ONE_REG_MASK;
158+ else if (streq (name, "orli"))
159+ opcode->bit_sequence = ORLI_ONE_REG_MASK;
160+ else if (streq (name, "xorli"))
161+ opcode->bit_sequence = XORLI_ONE_REG_MASK;
162+ }
163+ }
164 inst = opcode->bit_sequence;
165 isize = 4;
166
167@@ -1457,6 +1551,51 @@ md_assemble (char * str)
168 inst |= (immed << IMM_LOW) & IMM15_MASK;
169 break;
170
171+ case INST_TYPE_RD_IMML:
172+ if (strcmp (op_end, ""))
173+ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
174+ else
175+ {
176+ as_fatal (_("Error in statement syntax"));
177+ reg1 = 0;
178+ }
179+
180+ if (strcmp (op_end, ""))
181+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
182+ else
183+ as_fatal (_("Error in statement syntax"));
184+
185+ /* Check for spl registers. */
186+ if (check_spl_reg (&reg1))
187+ as_fatal (_("Cannot use special register with this instruction"));
188+ if (exp.X_op != O_constant)
189+ {
190+ char *opc = NULL;
191+ relax_substateT subtype;
192+
193+ if (exp.X_md != 0)
194+ subtype = get_imm_otype(exp.X_md);
195+ else
196+ subtype = opcode->inst_offset_type;
197+
198+ output = frag_var (rs_machine_dependent,
199+ isize * 2,
200+ isize * 2,
201+ subtype,
202+ exp.X_add_symbol,
203+ exp.X_add_number,
204+ (char *) opc);
205+ immedl = 0L;
206+ }
207+ else
208+ {
209+ output = frag_more (isize);
210+ immed = exp.X_add_number;
211+ }
212+ inst |= (reg1 << RD_LOW) & RD_MASK;
213+ inst |= (immed << IMM_LOW) & IMM16_MASK;
214+ break;
215+
216 case INST_TYPE_R1_RFSL:
217 if (strcmp (op_end, ""))
218 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
219diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
220index 45262aef909..bdc6db79726 100644
221--- a/opcodes/microblaze-dis.c
222+++ b/opcodes/microblaze-dis.c
223@@ -143,6 +143,14 @@ get_field_imm15 (struct string_buf *buf, long instr)
224 return p;
225 }
226
227+get_field_imm16 (struct string_buf *buf, long instr)
228+{
229+ char *p = strbuf (buf);
230+
231+ sprintf (p, "%d", (short)((instr & IMM16_MASK) >> IMM_LOW));
232+ return p;
233+}
234+
235 static char *
236 get_field_special (struct string_buf *buf, long instr,
237 const struct op_code_struct *op)
238@@ -473,6 +481,9 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
239 /* For mbar 16 or sleep insn. */
240 case INST_TYPE_NONE:
241 break;
242+ case INST_TYPE_RD_IMML:
243+ print_func (stream, "\t%s, %s", get_field_rd (&buf, inst), get_field_imm16 (&buf, inst));
244+ break;
245 /* For bit field insns. */
246 case INST_TYPE_RD_R1_IMMW_IMMS:
247 print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst), get_field_r1(&buf, inst),
248diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
249index f85f5a600cc..6228114698b 100644
250--- a/opcodes/microblaze-opc.h
251+++ b/opcodes/microblaze-opc.h
252@@ -77,6 +77,7 @@
253 #define INST_TYPE_RD_R1_IMMW_IMMS 21
254
255 #define INST_TYPE_NONE 25
256+#define INST_TYPE_RD_IMML 26
257
258
259
260@@ -92,6 +93,7 @@
261 #define IMMVAL_MASK_MFS 0x0000
262
263 #define OPCODE_MASK_H 0xFC000000 /* High 6 bits only. */
264+#define OPCODE_MASK_LIMM 0xFC1F0000 /* High 6 bits and 12-16 bits */
265 #define OPCODE_MASK_H1 0xFFE00000 /* High 11 bits. */
266 #define OPCODE_MASK_H2 0xFC1F0000 /* High 6 and bits 20-16. */
267 #define OPCODE_MASK_H12 0xFFFF0000 /* High 16. */
268@@ -114,6 +116,33 @@
269 #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */
270 #define OPCODE_MASK_H8 0xFF000000 /* High 8 bits only. */
271
272+/*Defines to identify 64-bit single reg instructions */
273+#define ADDLI_ONE_REG_MASK 0x68000000
274+#define ADDLIC_ONE_REG_MASK 0x68020000
275+#define ADDLIK_ONE_REG_MASK 0x68040000
276+#define ADDLIKC_ONE_REG_MASK 0x68060000
277+#define RSUBLI_ONE_REG_MASK 0x68010000
278+#define RSUBLIC_ONE_REG_MASK 0x68030000
279+#define RSUBLIK_ONE_REG_MASK 0x68050000
280+#define RSUBLIKC_ONE_REG_MASK 0x68070000
281+#define ORLI_ONE_REG_MASK 0x68100000
282+#define ANDLI_ONE_REG_MASK 0x68110000
283+#define XORLI_ONE_REG_MASK 0x68120000
284+#define ANDLNI_ONE_REG_MASK 0x68130000
285+#define ADDLI_MASK 0x20000000
286+#define ADDLIC_MASK 0x28000000
287+#define ADDLIK_MASK 0x30000000
288+#define ADDLIKC_MASK 0x38000000
289+#define RSUBLI_MASK 0x24000000
290+#define RSUBLIC_MASK 0x2C000000
291+#define RSUBLIK_MASK 0x34000000
292+#define RSUBLIKC_MASK 0x3C000000
293+#define ANDLI_MASK 0xA4000000
294+#define ANDLNI_MASK 0xAC000000
295+#define ORLI_MASK 0xA0000000
296+#define XORLI_MASK 0xA8000000
297+
298+
299 /* New Mask for msrset, msrclr insns. */
300 #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */
301 /* Mask for mbar insn. */
302@@ -122,7 +151,7 @@
303 #define DELAY_SLOT 1
304 #define NO_DELAY_SLOT 0
305
306-#define MAX_OPCODES 412
307+#define MAX_OPCODES 424
308
309 const struct op_code_struct
310 {
311@@ -451,13 +480,21 @@ const struct op_code_struct
312 {"cmpl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000101, OPCODE_MASK_H4, cmpl, arithmetic_inst },
313 {"cmplu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000103, OPCODE_MASK_H4, cmplu, arithmetic_inst },
314 {"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 */
315+ {"addli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68000000, OPCODE_MASK_LIMM, addli, arithmetic_inst },
316 {"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 */
317+ {"rsubli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68010000, OPCODE_MASK_LIMM, rsubli, arithmetic_inst },
318 {"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 */
319+ {"addlic", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68020000, OPCODE_MASK_LIMM, addlic, arithmetic_inst },
320 {"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 */
321+ {"rsublic", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68030000, OPCODE_MASK_LIMM, rsublic, arithmetic_inst },
322 {"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 */
323+ {"addlik", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68040000, OPCODE_MASK_LIMM, addlik, arithmetic_inst },
324 {"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 */
325+ {"rsublik", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68050000, OPCODE_MASK_LIMM, rsublik, arithmetic_inst },
326 {"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 */
327+ {"addlikc", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68060000, OPCODE_MASK_LIMM, addlikc, arithmetic_inst },
328 {"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 */
329+ {"rsublikc", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68070000, OPCODE_MASK_LIMM, rsublikc, arithmetic_inst },
330 {"mull", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x40000100, OPCODE_MASK_H4, mull, mult_inst },
331 {"bslll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000500, OPCODE_MASK_H3, bslll, barrel_shift_inst },
332 {"bslra", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000300, OPCODE_MASK_H3, bslra, barrel_shift_inst },
333@@ -508,9 +545,13 @@ const struct op_code_struct
334 {"beaged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00000, OPCODE_MASK_H14, beaged, branch_inst },
335 {"bealged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9FA00100, OPCODE_MASK_H14, bealged, branch_inst },
336 {"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 */
337+ {"orli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68100000, OPCODE_MASK_LIMM, orli, arithmetic_inst },
338 {"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 */
339+ {"andli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68110000, OPCODE_MASK_LIMM, andli, arithmetic_inst },
340 {"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 */
341+ {"xorli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68120000, OPCODE_MASK_LIMM, xorli, arithmetic_inst },
342 {"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 */
343+ {"andnli", INST_TYPE_RD_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL,0x68130000, OPCODE_MASK_LIMM, andnli, arithmetic_inst },
344 {"imml", INST_TYPE_IMML, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB2000000, OPCODE_MASK_H8, imml, immediate_inst },
345 {"breai", INST_TYPE_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8010000, OPCODE_MASK_H12, breai, branch_inst },
346 {"breaid", INST_TYPE_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8110000, OPCODE_MASK_H12, breaid, branch_inst },
347diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
348index 08ed44352ee..a57cabf905f 100644
349--- a/opcodes/microblaze-opcm.h
350+++ b/opcodes/microblaze-opcm.h
351@@ -62,7 +62,9 @@ enum microblaze_instr
352 eaputd, teaputd, ecaputd, tecaputd, neaputd, tneaputd, necaputd, tnecaputd,
353
354 /* 64-bit instructions */
355- addl, rsubl, addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull,
356+ addl, addli, addlic, addlik, addlikc, rsubl, rsubli, rsublic, rsublik, rsublikc,
357+ addlc, rsublc, addlk, rsublk, addlkc, rsublkc, cmpl, cmplu, mull,
358+ andli, andnli, orli, xorli,
359 bslll, bslra, bslrl, bsllli, bslrai, bslrli, bslefi, bslifi, orl, andl, xorl,
360 andnl, pcmplbf, pcmpleq, pcmplne, srla, srlc, srll, sextl8, sextl16, sextl32,
361 brea, bread, breald, beaeq, bealeq, beaeqd, bealeqd, beane, bealne, beaned,
362@@ -167,5 +169,6 @@ enum microblaze_instr_type
363
364 /* Imm mask for msrset, msrclr instructions. */
365 #define IMM15_MASK 0x00007FFF
366+#define IMM16_MASK 0x0000FFFF
367
368 #endif /* MICROBLAZE-OPCM */
369--
3702.34.1
371
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0030-double-imml-generation-for-64-bit-values.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0030-double-imml-generation-for-64-bit-values.patch
new file mode 100644
index 00000000..eb62eaeb
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0030-double-imml-generation-for-64-bit-values.patch
@@ -0,0 +1,545 @@
1From e4d7207d18e47a9ce5fbf57fc4faa370bf150284 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 26 Aug 2019 15:29:42 +0530
4Subject: [PATCH 30/53] double imml generation for 64 bit values.
5
6Conflicts:
7 gas/config/tc-microblaze.c
8
9Signed-off-by: Aayush Misra <aayushm@amd.com>
10---
11 gas/config/tc-microblaze.c | 321 ++++++++++++++++++++++++++++++-------
12 opcodes/microblaze-opc.h | 4 +-
13 2 files changed, 262 insertions(+), 63 deletions(-)
14
15diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
16index 3c9aec4c1f9..4da765223be 100644
17--- a/gas/config/tc-microblaze.c
18+++ b/gas/config/tc-microblaze.c
19@@ -979,7 +979,7 @@ md_assemble (char * str)
20 char * op_start;
21 char * op_end;
22 char * temp_op_end;
23- struct op_code_struct * opcode, *opcode1;
24+ struct op_code_struct * opcode, *opcode1, *opcode2;
25 char * output = NULL;
26 int nlen = 0;
27 int i;
28@@ -1163,7 +1163,12 @@ md_assemble (char * str)
29 reg2 = 0;
30 }
31 if (strcmp (op_end, ""))
32+ {
33+ if(microblaze_arch_size == 64)
34+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
35+ else
36 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
37+ }
38 else
39 as_fatal (_("Error in statement syntax"));
40
41@@ -1263,26 +1268,51 @@ md_assemble (char * str)
42 || streq (name, "lwi") || streq (name, "sbi")
43 || streq (name, "shi") || streq (name, "swi"))))
44 {
45- temp = immed & 0xFFFFFF8000;
46- if (temp != 0 && temp != 0xFFFFFF8000)
47+ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000;
48+ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000)
49 {
50 /* Needs an immediate inst. */
51- opcode1
52- = (struct op_code_struct *) str_hash_find (opcode_hash_control,
53- "imml");
54- if (opcode1 == NULL)
55+ if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
56+ {
57+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
58+ if (opcode1 == NULL)
59 {
60 as_bad (_("unknown opcode \"%s\""), "imml");
61 return;
62 }
63 inst1 = opcode1->bit_sequence;
64- inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
65+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
66 output[0] = INST_BYTE0 (inst1);
67 output[1] = INST_BYTE1 (inst1);
68 output[2] = INST_BYTE2 (inst1);
69 output[3] = INST_BYTE3 (inst1);
70 output = frag_more (isize);
71 }
72+ else
73+ {
74+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
75+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
76+ if (opcode1 == NULL || opcode2 == NULL)
77+ {
78+ as_bad (_("unknown opcode \"%s\""), "imml");
79+ return;
80+ }
81+ inst1 = opcode2->bit_sequence;
82+ inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
83+ output[0] = INST_BYTE0 (inst1);
84+ output[1] = INST_BYTE1 (inst1);
85+ output[2] = INST_BYTE2 (inst1);
86+ output[3] = INST_BYTE3 (inst1);
87+ output = frag_more (isize);
88+ inst1 = opcode1->bit_sequence;
89+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
90+ output[0] = INST_BYTE0 (inst1);
91+ output[1] = INST_BYTE1 (inst1);
92+ output[2] = INST_BYTE2 (inst1);
93+ output[3] = INST_BYTE3 (inst1);
94+ output = frag_more (isize);
95+ }
96+ }
97 inst |= (reg1 << RD_LOW) & RD_MASK;
98 inst |= (reg2 << RA_LOW) & RA_MASK;
99 inst |= (immed << IMM_LOW) & IMM_MASK;
100@@ -1299,8 +1329,7 @@ md_assemble (char * str)
101 as_bad (_("unknown opcode \"%s\""), "imm");
102 return;
103 }
104-
105- inst1 = opcode1->bit_sequence;
106+ inst1 = opcode1->bit_sequence;
107 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
108 output[0] = INST_BYTE0 (inst1);
109 output[1] = INST_BYTE1 (inst1);
110@@ -1541,7 +1570,7 @@ md_assemble (char * str)
111 as_fatal (_("Cannot use special register with this instruction"));
112
113 if (exp.X_op != O_constant)
114- as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
115+ as_fatal (_("Symbol used as immediate value for arithmetic long instructions"));
116 else
117 {
118 output = frag_more (isize);
119@@ -1875,6 +1904,7 @@ md_assemble (char * str)
120 temp = immed & 0xFFFF8000;
121 if ((temp != 0) && (temp != 0xFFFF8000))
122 {
123+
124 /* Needs an immediate inst. */
125 opcode1
126 = (struct op_code_struct *) str_hash_find (opcode_hash_control,
127@@ -1907,7 +1937,12 @@ md_assemble (char * str)
128 reg1 = 0;
129 }
130 if (strcmp (op_end, ""))
131+ {
132+ if(microblaze_arch_size == 64)
133+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
134+ else
135 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
136+ }
137 else
138 as_fatal (_("Error in statement syntax"));
139
140@@ -1946,30 +1981,55 @@ md_assemble (char * str)
141 }
142 if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
143 {
144- temp = immed & 0xFFFFFF8000;
145- if (temp != 0 && temp != 0xFFFFFF8000)
146+ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000;
147+ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000)
148 {
149 /* Needs an immediate inst. */
150- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
151+ if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
152+ {
153+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
154 if (opcode1 == NULL)
155 {
156 as_bad (_("unknown opcode \"%s\""), "imml");
157 return;
158 }
159 inst1 = opcode1->bit_sequence;
160- inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
161+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
162 output[0] = INST_BYTE0 (inst1);
163 output[1] = INST_BYTE1 (inst1);
164 output[2] = INST_BYTE2 (inst1);
165 output[3] = INST_BYTE3 (inst1);
166 output = frag_more (isize);
167 }
168+ else {
169+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
170+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
171+ if (opcode1 == NULL || opcode2 == NULL)
172+ {
173+ as_bad (_("unknown opcode \"%s\""), "imml");
174+ return;
175+ }
176+ inst1 = opcode2->bit_sequence;
177+ inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
178+ output[0] = INST_BYTE0 (inst1);
179+ output[1] = INST_BYTE1 (inst1);
180+ output[2] = INST_BYTE2 (inst1);
181+ output[3] = INST_BYTE3 (inst1);
182+ output = frag_more (isize);
183+ inst1 = opcode1->bit_sequence;
184+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
185+ output[0] = INST_BYTE0 (inst1);
186+ output[1] = INST_BYTE1 (inst1);
187+ output[2] = INST_BYTE2 (inst1);
188+ output[3] = INST_BYTE3 (inst1);
189+ output = frag_more (isize);
190+ }
191+ }
192 inst |= (reg1 << RD_LOW) & RD_MASK;
193 inst |= (immed << IMM_LOW) & IMM_MASK;
194 }
195 else
196 {
197-
198 temp = immed & 0xFFFF8000;
199 if ((temp != 0) && (temp != 0xFFFF8000))
200 {
201@@ -2057,24 +2117,50 @@ md_assemble (char * str)
202 streq (name, "breaid") ||
203 streq (name, "brai") || streq (name, "braid")))
204 {
205- temp = immed & 0xFFFFFF8000;
206+ temp = immed & 0xFFFFFFFFFFFF8000;
207 if (temp != 0)
208 {
209 /* Needs an immediate inst. */
210- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
211+ if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
212+ {
213+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
214 if (opcode1 == NULL)
215 {
216 as_bad (_("unknown opcode \"%s\""), "imml");
217 return;
218 }
219 inst1 = opcode1->bit_sequence;
220- inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
221+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
222 output[0] = INST_BYTE0 (inst1);
223 output[1] = INST_BYTE1 (inst1);
224 output[2] = INST_BYTE2 (inst1);
225 output[3] = INST_BYTE3 (inst1);
226 output = frag_more (isize);
227 }
228+ else {
229+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
230+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
231+ if (opcode1 == NULL || opcode2 == NULL)
232+ {
233+ as_bad (_("unknown opcode \"%s\""), "imml");
234+ return;
235+ }
236+ inst1 = opcode2->bit_sequence;
237+ inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
238+ output[0] = INST_BYTE0 (inst1);
239+ output[1] = INST_BYTE1 (inst1);
240+ output[2] = INST_BYTE2 (inst1);
241+ output[3] = INST_BYTE3 (inst1);
242+ output = frag_more (isize);
243+ inst1 = opcode1->bit_sequence;
244+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
245+ output[0] = INST_BYTE0 (inst1);
246+ output[1] = INST_BYTE1 (inst1);
247+ output[2] = INST_BYTE2 (inst1);
248+ output[3] = INST_BYTE3 (inst1);
249+ output = frag_more (isize);
250+ }
251+ }
252 inst |= (immed << IMM_LOW) & IMM_MASK;
253 }
254 else
255@@ -2394,8 +2480,8 @@ md_apply_fix (fixS * fixP,
256 /* Note: use offsetT because it is signed, valueT is unsigned. */
257 offsetT val = (offsetT) * valp;
258 int i;
259- struct op_code_struct * opcode1;
260- unsigned long inst1;
261+ struct op_code_struct * opcode1, * opcode2;
262+ unsigned long inst1,inst2;
263
264 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
265
266@@ -2576,30 +2662,75 @@ md_apply_fix (fixS * fixP,
267 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
268 case BFD_RELOC_MICROBLAZE_64:
269 case BFD_RELOC_MICROBLAZE_64_PCREL:
270- /* Add an imm instruction. First save the current instruction. */
271- for (i = 0; i < INST_WORD_SIZE; i++)
272- buf[i + INST_WORD_SIZE] = buf[i];
273 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64
274 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
275 {
276 /* Generate the imm instruction. */
277- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
278+ if (((long long)val) > (long long)-549755813888 && ((long long)val) < (long long)549755813887)
279+ {
280+ /* Add an imm instruction. First save the current instruction. */
281+ for (i = 0; i < INST_WORD_SIZE; i++)
282+ buf[i + INST_WORD_SIZE] = buf[i];
283+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
284 if (opcode1 == NULL)
285- {
286- as_bad (_("unknown opcode \"%s\""), "imml");
287- return;
288- }
289+ {
290+ as_bad (_("unknown opcode \"%s\""), "imml");
291+ return;
292+ }
293
294 inst1 = opcode1->bit_sequence;
295 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
296- inst1 |= ((val & 0xFFFFFF0000L) >> 16) & IMML_MASK;
297+ inst1 |= ((val & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
298+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
299+ fixP->fx_r_type = BFD_RELOC_64;
300+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
301+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
302+ buf[0] = INST_BYTE0 (inst1);
303+ buf[1] = INST_BYTE1 (inst1);
304+ buf[2] = INST_BYTE2 (inst1);
305+ buf[3] = INST_BYTE3 (inst1);
306+ }
307+ else {
308+ /* Add an imm instruction. First save the current instruction. */
309+ for (i = 0; i < INST_WORD_SIZE; i++)
310+ buf[i + INST_WORD_SIZE + 4] = buf[i];
311+
312+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
313+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
314+ if (opcode1 == NULL || opcode2 ==NULL)
315+ {
316+ as_bad (_("unknown opcode \"%s\""), "imml");
317+ return;
318+ }
319+ inst1 = opcode2->bit_sequence;
320+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
321+ inst1 |= ((val & 0x000000FFFFFF0000L) >> 40) & IMML_MASK;
322+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
323+ fixP->fx_r_type = BFD_RELOC_64;
324+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
325+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
326+ inst2 = opcode1->bit_sequence;
327+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
328+ inst1 |= ((val & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
329 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
330- fixP->fx_r_type = BFD_RELOC_64;
331+ fixP->fx_r_type = BFD_RELOC_64;
332 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
333- fixP->fx_r_type = BFD_RELOC_64_PCREL;
334+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
335+ buf[0] = INST_BYTE0 (inst1);
336+ buf[1] = INST_BYTE1 (inst1);
337+ buf[2] = INST_BYTE2 (inst1);
338+ buf[3] = INST_BYTE3 (inst1);
339+ buf[4] = INST_BYTE0 (inst2);
340+ buf[5] = INST_BYTE1 (inst2);
341+ buf[6] = INST_BYTE2 (inst2);
342+ buf[7] = INST_BYTE3 (inst2);
343+ }
344 }
345 else
346 {
347+ /* Add an imm instruction. First save the current instruction. */
348+ for (i = 0; i < INST_WORD_SIZE; i++)
349+ buf[i + INST_WORD_SIZE] = buf[i];
350 /* Generate the imm instruction. */
351 opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
352 if (opcode1 == NULL)
353@@ -2611,12 +2742,11 @@ md_apply_fix (fixS * fixP,
354 inst1 = opcode1->bit_sequence;
355 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
356 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
357- }
358 buf[0] = INST_BYTE0 (inst1);
359 buf[1] = INST_BYTE1 (inst1);
360 buf[2] = INST_BYTE2 (inst1);
361 buf[3] = INST_BYTE3 (inst1);
362-
363+ }
364 /* Add the value only if the symbol is defined. */
365 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
366 {
367@@ -2649,21 +2779,41 @@ md_apply_fix (fixS * fixP,
368 for (i = 0; i < INST_WORD_SIZE; i++)
369 buf[i + INST_WORD_SIZE] = buf[i];
370 /* Generate the imm instruction. */
371- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
372- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
373+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC) {
374+ if (((long long)val) > (long long)-549755813888 && ((long long)val) < (long long)549755813887)
375+ {
376+ for (i = 0; i < INST_WORD_SIZE; i++)
377+ buf[i + INST_WORD_SIZE] = buf[i];
378+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
379+ }
380+ else {
381+ for (i = 0; i < INST_WORD_SIZE; i++)
382+ buf[i + INST_WORD_SIZE + 4] = buf[i];
383+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
384+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
385+ inst2 = opcode2->bit_sequence;
386+
387+ /* We can fixup call to a defined non-global address
388+ * within the same section only. */
389+ buf[4] = INST_BYTE0 (inst2);
390+ buf[5] = INST_BYTE1 (inst2);
391+ buf[6] = INST_BYTE2 (inst2);
392+ buf[7] = INST_BYTE3 (inst2);
393+ }
394+ }
395 else
396 opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
397 if (opcode1 == NULL)
398 {
399+ for (i = 0; i < INST_WORD_SIZE; i++)
400+ buf[i + INST_WORD_SIZE] = buf[i];
401 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
402 as_bad (_("unknown opcode \"%s\""), "imml");
403 else
404 as_bad (_("unknown opcode \"%s\""), "imm");
405 return;
406 }
407-
408 inst1 = opcode1->bit_sequence;
409-
410 /* We can fixup call to a defined non-global address
411 within the same section only. */
412 buf[0] = INST_BYTE0 (inst1);
413@@ -3025,21 +3175,45 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
414 {
415 output = frag_more (isize);
416 immedl = exp.X_add_number;
417-
418- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
419- if (opcode1 == NULL)
420- {
421- as_bad (_("unknown opcode \"%s\""), "imml");
422- return;
423- }
424-
425- inst1 = opcode1->bit_sequence;
426- inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
427- output[0] = INST_BYTE0 (inst1);
428- output[1] = INST_BYTE1 (inst1);
429- output[2] = INST_BYTE2 (inst1);
430- output[3] = INST_BYTE3 (inst1);
431- output = frag_more (isize);
432+ if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887)
433+ {
434+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
435+ if (opcode1 == NULL)
436+ {
437+ as_bad (_("unknown opcode \"%s\""), "imml");
438+ return;
439+ }
440+ inst1 = opcode1->bit_sequence;
441+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
442+ output[0] = INST_BYTE0 (inst1);
443+ output[1] = INST_BYTE1 (inst1);
444+ output[2] = INST_BYTE2 (inst1);
445+ output[3] = INST_BYTE3 (inst1);
446+ output = frag_more (isize);
447+ }
448+ else {
449+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
450+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
451+ if (opcode2 == NULL || opcode1 == NULL)
452+ {
453+ as_bad (_("unknown opcode \"%s\""), "imml");
454+ return;
455+ }
456+ inst1 = opcode2->bit_sequence;
457+ inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
458+ output[0] = INST_BYTE0 (inst1);
459+ output[1] = INST_BYTE1 (inst1);
460+ output[2] = INST_BYTE2 (inst1);
461+ output[3] = INST_BYTE3 (inst1);
462+ output = frag_more (isize);
463+ inst1 = opcode1->bit_sequence;
464+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
465+ output[0] = INST_BYTE0 (inst1);
466+ output[1] = INST_BYTE1 (inst1);
467+ output[2] = INST_BYTE2 (inst1);
468+ output[3] = INST_BYTE3 (inst1);
469+ output = frag_more (isize);
470+ }
471 }
472
473 inst |= (reg1 << RD_LOW) & RD_MASK;
474@@ -3088,20 +3262,45 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
475 {
476 output = frag_more (isize);
477 immedl = exp.X_add_number;
478- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
479- if (opcode1 == NULL)
480- {
481- as_bad (_("unknown opcode \"%s\""), "imml");
482- return;
483- }
484-
485+ if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887)
486+ {
487+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
488+ if (opcode1 == NULL)
489+ {
490+ as_bad (_("unknown opcode \"%s\""), "imml");
491+ return;
492+ }
493 inst1 = opcode1->bit_sequence;
494- inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
495+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
496 output[0] = INST_BYTE0 (inst1);
497 output[1] = INST_BYTE1 (inst1);
498 output[2] = INST_BYTE2 (inst1);
499 output[3] = INST_BYTE3 (inst1);
500 output = frag_more (isize);
501+ }
502+ else {
503+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
504+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
505+ if (opcode2 == NULL || opcode1 == NULL)
506+ {
507+ as_bad (_("unknown opcode \"%s\""), "imml");
508+ return;
509+ }
510+ inst1 = opcode2->bit_sequence;
511+ inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
512+ output[0] = INST_BYTE0 (inst1);
513+ output[1] = INST_BYTE1 (inst1);
514+ output[2] = INST_BYTE2 (inst1);
515+ output[3] = INST_BYTE3 (inst1);
516+ output = frag_more (isize);
517+ inst1 = opcode1->bit_sequence;
518+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
519+ output[0] = INST_BYTE0 (inst1);
520+ output[1] = INST_BYTE1 (inst1);
521+ output[2] = INST_BYTE2 (inst1);
522+ output[3] = INST_BYTE3 (inst1);
523+ output = frag_more (isize);
524+ }
525 }
526
527 inst |= (reg1 << RA_LOW) & RA_MASK;
528diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
529index 6228114698b..f46fc76a94a 100644
530--- a/opcodes/microblaze-opc.h
531+++ b/opcodes/microblaze-opc.h
532@@ -633,8 +633,8 @@ char pvr_register_prefix[] = "rpvr";
533 #define MIN_IMM6_WIDTH ((int) 0x00000001)
534 #define MAX_IMM6_WIDTH ((int) 0x00000040)
535
536-#define MIN_IMML ((long long) 0xffffff8000000000L)
537-#define MAX_IMML ((long long) 0x0000007fffffffffL)
538+#define MIN_IMML ((long long) -9223372036854775808)
539+#define MAX_IMML ((long long) 9223372036854775807)
540
541 #endif /* MICROBLAZE_OPC */
542
543--
5442.34.1
545
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0031-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0031-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch
new file mode 100644
index 00000000..5bc507ce
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0031-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch
@@ -0,0 +1,88 @@
1From 3cd07844b77691afeb675806cc4c73fe08d2c30e Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Wed, 3 Nov 2021 12:13:32 +0530
4Subject: [PATCH 31/53] Fixed bug in generation of IMML instruction for the
5
6new MB-64 instructions with single register.
7
8Signed-off-by: Aayush Misra <aayushm@amd.com>
9---
10 gas/config/tc-microblaze.c | 50 +++++++++++++++++++++++++++++++++++---
11 1 file changed, 47 insertions(+), 3 deletions(-)
12
13diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
14index 4da765223be..651d855c800 100644
15--- a/gas/config/tc-microblaze.c
16+++ b/gas/config/tc-microblaze.c
17@@ -1614,12 +1614,56 @@ md_assemble (char * str)
18 exp.X_add_symbol,
19 exp.X_add_number,
20 (char *) opc);
21- immedl = 0L;
22+ immed = 0L;
23 }
24 else
25 {
26 output = frag_more (isize);
27 immed = exp.X_add_number;
28+ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000;
29+ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000 && temp != 0x8000)
30+ {
31+ /* Needs an immediate inst. */
32+ if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
33+ {
34+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
35+ if (opcode1 == NULL)
36+ {
37+ as_bad (_("unknown opcode \"%s\""), "imml");
38+ return;
39+ }
40+ inst1 = opcode1->bit_sequence;
41+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
42+ output[0] = INST_BYTE0 (inst1);
43+ output[1] = INST_BYTE1 (inst1);
44+ output[2] = INST_BYTE2 (inst1);
45+ output[3] = INST_BYTE3 (inst1);
46+ output = frag_more (isize);
47+ }
48+ else {
49+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
50+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
51+ if (opcode1 == NULL || opcode2 == NULL)
52+ {
53+ as_bad (_("unknown opcode \"%s\""), "imml");
54+ return;
55+ }
56+ inst1 = opcode2->bit_sequence;
57+ inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
58+ output[0] = INST_BYTE0 (inst1);
59+ output[1] = INST_BYTE1 (inst1);
60+ output[2] = INST_BYTE2 (inst1);
61+ output[3] = INST_BYTE3 (inst1);
62+ output = frag_more (isize);
63+ inst1 = opcode1->bit_sequence;
64+ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
65+ output[0] = INST_BYTE0 (inst1);
66+ output[1] = INST_BYTE1 (inst1);
67+ output[2] = INST_BYTE2 (inst1);
68+ output[3] = INST_BYTE3 (inst1);
69+ output = frag_more (isize);
70+ }
71+ }
72 }
73 inst |= (reg1 << RD_LOW) & RD_MASK;
74 inst |= (immed << IMM_LOW) & IMM16_MASK;
75@@ -2117,8 +2161,8 @@ md_assemble (char * str)
76 streq (name, "breaid") ||
77 streq (name, "brai") || streq (name, "braid")))
78 {
79- temp = immed & 0xFFFFFFFFFFFF8000;
80- if (temp != 0)
81+ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000;
82+ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000 && temp != 0x8000)
83 {
84 /* Needs an immediate inst. */
85 if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887)
86--
872.34.1
88
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0032-This-patch-will-remove-imml-0-and-imml-1-instruction.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0032-This-patch-will-remove-imml-0-and-imml-1-instruction.patch
new file mode 100644
index 00000000..686c8827
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0032-This-patch-will-remove-imml-0-and-imml-1-instruction.patch
@@ -0,0 +1,38 @@
1From 6e672cb099ae9670a9be1d26e36fa33df5757191 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Thu, 16 Apr 2020 18:08:58 +0530
4Subject: [PATCH 32/53] This patch will remove imml 0 and imml -1 instructions
5 when the offset is less than 16 bit for Type A branch EA instructions.
6
7Signed-off-by: Aayush Misra <aayushm@amd.com>
8---
9 gas/config/tc-microblaze.c | 6 ++----
10 1 file changed, 2 insertions(+), 4 deletions(-)
11
12diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
13index 651d855c800..ce0d3e26204 100644
14--- a/gas/config/tc-microblaze.c
15+++ b/gas/config/tc-microblaze.c
16@@ -2129,9 +2129,7 @@ md_assemble (char * str)
17 if (exp.X_op != O_constant)
18 {
19 char *opc;
20- if (microblaze_arch_size == 64 && (streq (name, "breai") ||
21- streq (name, "breaid") ||
22- streq (name, "brai") || streq (name, "braid")))
23+ if (microblaze_arch_size == 64 && (streq (name, "brai") || streq (name, "braid")))
24 opc = str_microblaze_64;
25 else
26 opc = NULL;
27@@ -2707,7 +2705,7 @@ md_apply_fix (fixS * fixP,
28 case BFD_RELOC_MICROBLAZE_64:
29 case BFD_RELOC_MICROBLAZE_64_PCREL:
30 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64
31- || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
32+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL || (fixP->fx_r_type == BFD_RELOC_64_PCREL && microblaze_arch_size == 64))
33 {
34 /* Generate the imm instruction. */
35 if (((long long)val) > (long long)-549755813888 && ((long long)val) < (long long)549755813887)
36--
372.34.1
38
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0033-Changing-the-long-to-long-long-as-in-Windows-long-is.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0033-Changing-the-long-to-long-long-as-in-Windows-long-is.patch
new file mode 100644
index 00000000..1dbeaf0e
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0033-Changing-the-long-to-long-long-as-in-Windows-long-is.patch
@@ -0,0 +1,32 @@
1From 0c29905801152c8b8230bcca00b49b945054586b Mon Sep 17 00:00:00 2001
2From: Nagaraju Mekala <nmekala@xilinx.com>
3Date: Tue, 20 Apr 2021 21:22:06 +0530
4Subject: [PATCH 33/53] Changing the long to long long as in Windows long is
5 32-bit but we need the variable to be 64-bit
6
7Signed-off-by :Nagaraju Mekala <nmekala@xilix.com>
8
9Conflicts:
10 gas/config/tc-microblaze.c
11
12Signed-off-by: Aayush Misra <aayushm@amd.com>
13---
14 gas/config/tc-microblaze.c | 2 +-
15 1 file changed, 1 insertion(+), 1 deletion(-)
16
17diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
18index ce0d3e26204..dc87429a4e8 100644
19--- a/gas/config/tc-microblaze.c
20+++ b/gas/config/tc-microblaze.c
21@@ -988,7 +988,7 @@ md_assemble (char * str)
22 unsigned reg2;
23 unsigned reg3;
24 unsigned isize;
25- unsigned long immed = 0, immed2 = 0, temp;
26+ unsigned long long immed = 0, immed2 = 0, temp;
27 expressionS exp,exp1;
28 char name[20];
29 long immedl;
30--
312.34.1
32
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0034-gas-revert-moving-of-md_pseudo_table-from-const.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0034-gas-revert-moving-of-md_pseudo_table-from-const.patch
new file mode 100644
index 00000000..943d3158
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0034-gas-revert-moving-of-md_pseudo_table-from-const.patch
@@ -0,0 +1,62 @@
1From ec4fac4177c4364f52d1bc6ba53ffd971323cc22 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 8 Nov 2021 21:57:13 +0530
4Subject: [PATCH 34/53] gas: revert moving of md_pseudo_table from const
5
6The base system expect md_pseudo_table to be constant, Changing the
7definition will break other architectures when compiled with a
8unified source code.
9
10Patch reverts the change away from const, and implements a newer
11dynamic handler that passes the correct argument value based on word
12size.
13
14Signed-off-by: Mark Hatle <mark.hatle@kernel.crashing.org>
15Signed-off-by: Aayush Misra <aayushm@amd.com>
16---
17 gas/config/tc-microblaze.c | 15 ++++++++++++---
18 1 file changed, 12 insertions(+), 3 deletions(-)
19
20diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
21index dc87429a4e8..faa458af3a0 100644
22--- a/gas/config/tc-microblaze.c
23+++ b/gas/config/tc-microblaze.c
24@@ -356,6 +356,17 @@ microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
25 demand_empty_rest_of_line ();
26 }
27
28+/* Handle the .gpword pseudo-op, Pass to s_rva */
29+
30+static void
31+microblaze_s_gpword (int ignore ATTRIBUTE_UNUSED)
32+{
33+ int size = 4;
34+ if (microblaze_arch_size == 64)
35+ size = 8;
36+ s_rva(size);
37+}
38+
39 /* This table describes all the machine specific pseudo-ops the assembler
40 has to support. The fields are:
41 Pseudo-op name without dot
42@@ -371,7 +382,7 @@ const pseudo_typeS md_pseudo_table[] =
43 {"data32", cons, 4}, /* Same as word. */
44 {"ent", s_func, 0}, /* Treat ent as function entry point. */
45 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
46- {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
47+ {"gpword", microblaze_s_gpword, 0}, /* gpword label => store resolved label address in data section. */
48 {"weakext", microblaze_s_weakext, 0},
49 {"rodata", microblaze_s_rdata, 0},
50 {"sdata2", microblaze_s_rdata, 1},
51@@ -3425,8 +3436,6 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
52 case OPTION_M64:
53 //if (arg != NULL && strcmp (arg, "64") == 0)
54 microblaze_arch_size = 64;
55- // UPSTREAM/REVISIT - md_pseudo_table is const
56- // md_pseudo_table[7].poc_val = 8;
57 break;
58 default:
59 return 0;
60--
612.34.1
62
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0035-ld-emulparams-elf64microblaze-Fix-emulation-generati.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0035-ld-emulparams-elf64microblaze-Fix-emulation-generati.patch
new file mode 100644
index 00000000..c3ff9baf
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0035-ld-emulparams-elf64microblaze-Fix-emulation-generati.patch
@@ -0,0 +1,44 @@
1From 2148cf1617fe1168ea747346d407e2ece94e163a Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 8 Nov 2021 22:01:23 +0530
4Subject: [PATCH 35/53] ld/emulparams/elf64microblaze: Fix emulation generation
5
6Compilation fails when building ld-new with:
7
8ldemul.o:(.data.rel+0x820): undefined reference to `ld_elf64microblazeel_emulation'
9ldemul.o:(.data.rel+0x828): undefined reference to `ld_elf64microblaze_emulation'
10
11The error appears to be that the elf64 files were referencing the elf32 emulation.
12
13Signed-off-by: Mark Hatle <mark.hatle@xilinx.com>
14Signed-off-by: Aayush Misra <aayushm@amd.com>
15---
16 ld/emulparams/elf64microblaze.sh | 2 +-
17 ld/emulparams/elf64microblazeel.sh | 2 +-
18 2 files changed, 2 insertions(+), 2 deletions(-)
19
20diff --git a/ld/emulparams/elf64microblaze.sh b/ld/emulparams/elf64microblaze.sh
21index 9c7b0eb7080..7b4c7c411bd 100644
22--- a/ld/emulparams/elf64microblaze.sh
23+++ b/ld/emulparams/elf64microblaze.sh
24@@ -19,5 +19,5 @@ NOP=0x80000000
25 #$@{RELOCATING+ PROVIDE (__stack = 0x7000);@}
26 #OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);'
27
28-TEMPLATE_NAME=elf32
29+TEMPLATE_NAME=elf
30 #GENERATE_SHLIB_SCRIPT=yes
31diff --git a/ld/emulparams/elf64microblazeel.sh b/ld/emulparams/elf64microblazeel.sh
32index 9c7b0eb7080..7b4c7c411bd 100644
33--- a/ld/emulparams/elf64microblazeel.sh
34+++ b/ld/emulparams/elf64microblazeel.sh
35@@ -19,5 +19,5 @@ NOP=0x80000000
36 #$@{RELOCATING+ PROVIDE (__stack = 0x7000);@}
37 #OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);'
38
39-TEMPLATE_NAME=elf32
40+TEMPLATE_NAME=elf
41 #GENERATE_SHLIB_SCRIPT=yes
42--
432.34.1
44
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0036-Invalid-data-offsets-pointer-after-relaxation.-Propo.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0036-Invalid-data-offsets-pointer-after-relaxation.-Propo.patch
new file mode 100644
index 00000000..fd03fc4c
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0036-Invalid-data-offsets-pointer-after-relaxation.-Propo.patch
@@ -0,0 +1,79 @@
1From 9d691c146a484002e678babb0d40a9387272cb97 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 24 Jan 2022 16:04:07 +0530
4Subject: [PATCH 36/53] Invalid data offsets (pointer) after relaxation.
5 Proposed patch from community member (dednev@rambler.ru) against 2021.1
6 [CR-1115232]
7
8Signed-off-by: Aayush Misra <aayushm@amd.com>
9---
10 bfd/elf32-microblaze.c | 18 ++++++++++++++++++
11 1 file changed, 18 insertions(+)
12
13diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
14index 7e7c4bf471d..0ba7e36aa5f 100644
15--- a/bfd/elf32-microblaze.c
16+++ b/bfd/elf32-microblaze.c
17@@ -2176,6 +2176,9 @@ microblaze_elf_relax_section (bfd *abfd,
18 {
19 unsigned int val;
20
21+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
22+ continue;
23+
24 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
25
26 /* hax: We only do the following fixup for debug location lists. */
27@@ -2215,6 +2218,9 @@ microblaze_elf_relax_section (bfd *abfd,
28 }
29 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)// || ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
30 {
31+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
32+ continue;
33+
34 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
35
36 /* Look at the reloc only if the value has been resolved. */
37@@ -2247,6 +2253,9 @@ microblaze_elf_relax_section (bfd *abfd,
38 }
39 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
40 {
41+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
42+ continue;
43+
44 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
45
46 /* Look at the reloc only if the value has been resolved. */
47@@ -2284,6 +2293,9 @@ microblaze_elf_relax_section (bfd *abfd,
48 || (ELF32_R_TYPE (irelscan->r_info)
49 == (int) R_MICROBLAZE_TEXTREL_32_LO))
50 {
51+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
52+ continue;
53+
54 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
55
56 /* Look at the reloc only if the value has been resolved. */
57@@ -2330,6 +2342,9 @@ microblaze_elf_relax_section (bfd *abfd,
58 || (ELF32_R_TYPE (irelscan->r_info)
59 == (int) R_MICROBLAZE_TEXTREL_64))
60 {
61+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
62+ continue;
63+
64 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
65
66 /* Look at the reloc only if the value has been resolved. */
67@@ -2364,6 +2379,9 @@ microblaze_elf_relax_section (bfd *abfd,
68 }
69 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
70 {
71+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
72+ continue;
73+
74 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
75
76 /* Look at the reloc only if the value has been resolved. */
77--
782.34.1
79
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0037-Double-free-with-ld-no-keep-memory.-Proposed-patches.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0037-Double-free-with-ld-no-keep-memory.-Proposed-patches.patch
new file mode 100644
index 00000000..2e632939
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0037-Double-free-with-ld-no-keep-memory.-Proposed-patches.patch
@@ -0,0 +1,107 @@
1From 36e578efe3e94a6c13b21c364d818d0a8fd675ca Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 24 Jan 2022 16:59:19 +0530
4Subject: [PATCH 37/53] Double free with ld --no-keep-memory. Proposed patches
5 from the community member (dednev@rambler.ru) for 2021.1. [CR-1115233]
6
7Conflicts:
8 bfd/elf32-microblaze.c
9 bfd/elf64-microblaze.c
10
11Signed-off-by: Aayush Misra <aayushm@amd.com>
12---
13 bfd/elf32-microblaze.c | 40 ++++++++++++++++++++++------------------
14 1 file changed, 22 insertions(+), 18 deletions(-)
15
16diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
17index 0ba7e36aa5f..1ff552a151b 100644
18--- a/bfd/elf32-microblaze.c
19+++ b/bfd/elf32-microblaze.c
20@@ -1882,10 +1882,8 @@ microblaze_elf_relax_section (bfd *abfd,
21 {
22 Elf_Internal_Shdr *symtab_hdr;
23 Elf_Internal_Rela *internal_relocs;
24- Elf_Internal_Rela *free_relocs = NULL;
25 Elf_Internal_Rela *irel, *irelend;
26 bfd_byte *contents = NULL;
27- bfd_byte *free_contents = NULL;
28 int rel_count;
29 unsigned int shndx;
30 size_t i, sym_index;
31@@ -1929,8 +1927,6 @@ microblaze_elf_relax_section (bfd *abfd,
32 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
33 if (internal_relocs == NULL)
34 goto error_return;
35- if (! link_info->keep_memory)
36- free_relocs = internal_relocs;
37
38 sdata->relax_count = 0;
39 sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
40@@ -1958,7 +1954,6 @@ microblaze_elf_relax_section (bfd *abfd,
41 contents = (bfd_byte *) bfd_malloc (sec->size);
42 if (contents == NULL)
43 goto error_return;
44- free_contents = contents;
45
46 if (!bfd_get_section_contents (abfd, sec, contents,
47 (file_ptr) 0, sec->size))
48@@ -2475,25 +2470,26 @@ microblaze_elf_relax_section (bfd *abfd,
49 }
50
51 elf_section_data (sec)->relocs = internal_relocs;
52- free_relocs = NULL;
53
54 elf_section_data (sec)->this_hdr.contents = contents;
55- free_contents = NULL;
56
57 symtab_hdr->contents = (bfd_byte *) isymbuf;
58 }
59
60- free (free_relocs);
61- free_relocs = NULL;
62+ if (internal_relocs != NULL
63+ && elf_section_data (sec)->relocs != internal_relocs)
64+ free (internal_relocs);
65
66- if (free_contents != NULL)
67- {
68- if (!link_info->keep_memory)
69- free (free_contents);
70+ if (contents != NULL
71+ && elf_section_data (sec)->this_hdr.contents != contents)
72+ {
73+ if (! link_info->keep_memory)
74+ free (contents);
75 else
76- /* Cache the section contents for elf_link_input_bfd. */
77- elf_section_data (sec)->this_hdr.contents = contents;
78- free_contents = NULL;
79+ {
80+ /* Cache the section contents for elf_link_input_bfd. */
81+ elf_section_data (sec)->this_hdr.contents = contents;
82+ }
83 }
84
85 if (sdata->relax_count == 0)
86@@ -2507,8 +2503,16 @@ microblaze_elf_relax_section (bfd *abfd,
87 return true;
88
89 error_return:
90- free (free_relocs);
91- free (free_contents);
92+
93+ if (isymbuf != NULL
94+ && symtab_hdr->contents != (unsigned char *) isymbuf)
95+ free (isymbuf);
96+ if (internal_relocs != NULL
97+ && elf_section_data (sec)->relocs != internal_relocs)
98+ free (internal_relocs);
99+ if (contents != NULL
100+ && elf_section_data (sec)->this_hdr.contents != contents)
101+ free (contents);
102 free (sdata->relax);
103 sdata->relax = NULL;
104 sdata->relax_count = 0;
105--
1062.34.1
107
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0038-MB-binutils-Upstream-port-issues.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0038-MB-binutils-Upstream-port-issues.patch
new file mode 100644
index 00000000..cfa1a49e
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0038-MB-binutils-Upstream-port-issues.patch
@@ -0,0 +1,99 @@
1From b960fb122b35cb327b9db8fd1bb835899b24d106 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Sun, 28 Nov 2021 17:17:15 +0530
4Subject: [PATCH 38/53] MB binutils Upstream port issues.
5
6It's resolving the seg faults with ADDLIK
7Conflicts:
8 bfd/elf64-microblaze.c
9
10Signed-off-by: Aayush Misra <aayushm@amd.com>
11---
12 gas/config/tc-microblaze.c | 2 +-
13 opcodes/microblaze-dis.c | 12 ++++++------
14 opcodes/microblaze-opc.h | 2 +-
15 3 files changed, 8 insertions(+), 8 deletions(-)
16
17diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
18index faa458af3a0..686b1a00177 100644
19--- a/gas/config/tc-microblaze.c
20+++ b/gas/config/tc-microblaze.c
21@@ -404,7 +404,7 @@ const pseudo_typeS md_pseudo_table[] =
22 void
23 md_begin (void)
24 {
25- const struct op_code_struct * opcode;
26+ struct op_code_struct * opcode;
27 const char *prev_name = "";
28
29 opcode_hash_control = str_htab_create ();
30diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
31index bdc6db79726..d61d6bcfeba 100644
32--- a/opcodes/microblaze-dis.c
33+++ b/opcodes/microblaze-dis.c
34@@ -153,7 +153,7 @@ get_field_imm16 (struct string_buf *buf, long instr)
35
36 static char *
37 get_field_special (struct string_buf *buf, long instr,
38- const struct op_code_struct *op)
39+ struct op_code_struct *op)
40 {
41 char *p = strbuf (buf);
42 char *spr;
43@@ -226,11 +226,11 @@ get_field_special (struct string_buf *buf, long instr,
44 static unsigned long
45 read_insn_microblaze (bfd_vma memaddr,
46 struct disassemble_info *info,
47- const struct op_code_struct **opr)
48+ struct op_code_struct **opr)
49 {
50 unsigned char ibytes[4];
51 int status;
52- const struct op_code_struct *op;
53+ struct op_code_struct *op;
54 unsigned long inst;
55
56 status = info->read_memory_func (memaddr, ibytes, 4, info);
57@@ -266,7 +266,7 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
58 fprintf_ftype print_func = info->fprintf_func;
59 void *stream = info->stream;
60 unsigned long inst, prev_inst;
61- const struct op_code_struct *op, *pop;
62+ struct op_code_struct *op, *pop;
63 int immval = 0;
64 bool immfound = false;
65 static bfd_vma prev_insn_addr = -1; /* Init the prev insn addr. */
66@@ -518,7 +518,7 @@ get_insn_microblaze (long inst,
67 enum microblaze_instr_type *insn_type,
68 short *delay_slots)
69 {
70- const struct op_code_struct *op;
71+ struct op_code_struct *op;
72 *isunsignedimm = false;
73
74 /* Just a linear search of the table. */
75@@ -560,7 +560,7 @@ microblaze_get_target_address (long inst, bool immfound, int immval,
76 bool *targetvalid,
77 bool *unconditionalbranch)
78 {
79- const struct op_code_struct *op;
80+ struct op_code_struct *op;
81 long targetaddr = 0;
82
83 *unconditionalbranch = false;
84diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
85index f46fc76a94a..9f6d5456701 100644
86--- a/opcodes/microblaze-opc.h
87+++ b/opcodes/microblaze-opc.h
88@@ -153,7 +153,7 @@
89
90 #define MAX_OPCODES 424
91
92-const struct op_code_struct
93+struct op_code_struct
94 {
95 const char * name;
96 short inst_type; /* Registers and immediate values involved. */
97--
982.34.1
99
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0039-Initial-port-of-core-reading-support-Added-support-f.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0039-Initial-port-of-core-reading-support-Added-support-f.patch
new file mode 100644
index 00000000..06fefe2f
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0039-Initial-port-of-core-reading-support-Added-support-f.patch
@@ -0,0 +1,89 @@
1From ac87f4a6b9e35083a0403f188b61a317b53cfdbc Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 10 Oct 2022 16:37:53 +0530
4Subject: [PATCH 39/53] Initial port of core reading support Added support for
5 reading notes in linux core dumps Support for reading of PRSTATUS and PSINFO
6 information for rebuilding ".reg" sections of core dumps at run time.
7
8Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com>
9Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com>
10Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
11Signed-off-by: Aayush Misra <aayushm@amd.com>
12---
13 gdb/microblaze-linux-tdep.c | 11 +++++++++++
14 gdb/microblaze-tdep.c | 37 +++++++++++++++++++++++++++++++++++++
15 2 files changed, 48 insertions(+)
16
17diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
18index f34b0fa9fd4..babc9020f0f 100644
19--- a/gdb/microblaze-linux-tdep.c
20+++ b/gdb/microblaze-linux-tdep.c
21@@ -193,6 +193,17 @@ microblaze_linux_init_abi (struct gdbarch_info info,
22 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
23 set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
24
25+ /* BFD target for core files. */
26+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
27+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze");
28+ else
29+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel");
30+
31+
32+ /* Shared library handling. */
33+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
34+ set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
35+
36 /* Enable TLS support. */
37 set_gdbarch_fetch_tls_load_module_address (gdbarch,
38 svr4_fetch_objfile_link_map);
39diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
40index f9cb3dfda33..fdea9721b17 100644
41--- a/gdb/microblaze-tdep.c
42+++ b/gdb/microblaze-tdep.c
43@@ -957,6 +957,43 @@ make_regs (struct gdbarch *arch)
44 }
45 #endif
46
47+void
48+microblaze_supply_gregset (const struct regset *regset,
49+ struct regcache *regcache,
50+ int regnum, const void *gregs)
51+{
52+ const unsigned int *regs = (const unsigned int *)gregs;
53+ if (regnum >= 0)
54+ regcache->raw_supply (regnum, regs + regnum);
55+
56+ if (regnum == -1) {
57+ int i;
58+
59+ for (i = 0; i < 50; i++) {
60+ regcache->raw_supply (i, regs + i);
61+ }
62+ }
63+}
64+
65+
66+/* Return the appropriate register set for the core section identified
67+ by SECT_NAME and SECT_SIZE. */
68+
69+static void
70+microblaze_iterate_over_regset_sections (struct gdbarch *gdbarch,
71+ iterate_over_regset_sections_cb *cb,
72+ void *cb_data,
73+ const struct regcache *regcache)
74+{
75+ struct microblaze_gdbarch_tdep *tdep =(microblaze_gdbarch_tdep *) gdbarch_tdep (gdbarch);
76+
77+ cb(".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, tdep->gregset, NULL, cb_data);
78+
79+ cb(".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, tdep->fpregset, NULL, cb_data);
80+}
81+
82+
83+
84 static struct gdbarch *
85 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
86 {
87--
882.34.1
89
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0040-Fix-build-issues-after-Xilinx-2023.2-binutils-merge.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0040-Fix-build-issues-after-Xilinx-2023.2-binutils-merge.patch
new file mode 100644
index 00000000..85ae3f02
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0040-Fix-build-issues-after-Xilinx-2023.2-binutils-merge.patch
@@ -0,0 +1,185 @@
1From fc4d292d4154cad199cbe1635790867c98a84fc6 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 14 Mar 2024 10:41:33 +0530
4Subject: [PATCH 40/53] Fix build issues after Xilinx 2023.2 binutils merge
5
6Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
7Signed-off-by: Aayush Misra <aayushm@amd.com>
8---
9 bfd/bfd-in2.h | 10 ------
10 gdb/microblaze-tdep.c | 71 ++++++++++++++--------------------------
11 opcodes/microblaze-dis.c | 10 ------
12 3 files changed, 25 insertions(+), 66 deletions(-)
13
14diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
15index 8b2815d7303..cfab5c99b76 100644
16--- a/bfd/bfd-in2.h
17+++ b/bfd/bfd-in2.h
18@@ -6456,11 +6456,6 @@ done here - only used for relaxing */
19 * +done here - only used for relaxing */
20 BFD_RELOC_MICROBLAZE_64_PCREL,
21
22-/* This is a 64 bit reloc that stores the 32 bit relative
23- * +value in two words (with an imml instruction). No relocation is
24- * +done here - only used for relaxing */
25- BFD_RELOC_MICROBLAZE_64,
26-
27 /* This is a 64 bit reloc that stores the 32 bit relative
28 * +value in two words (with an imml instruction). No relocation is
29 * +done here - only used for relaxing */
30@@ -6486,11 +6481,6 @@ value in two words (with an imml instruction). The relocation is
31 PC-relative GOT offset */
32 BFD_RELOC_MICROBLAZE_64_GPC,
33
34-/* This is a 64 bit reloc that stores the 32 bit pc relative
35-value in two words (with an imml instruction). The relocation is
36-PC-relative GOT offset */
37- BFD_RELOC_MICROBLAZE_64_GPC,
38-
39 /* This is a 64 bit reloc that stores the 32 bit pc relative
40 value in two words (with an imm instruction). The relocation is
41 GOT offset */
42diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
43index fdea9721b17..d83e508b82b 100644
44--- a/gdb/microblaze-tdep.c
45+++ b/gdb/microblaze-tdep.c
46@@ -70,6 +70,7 @@ static const char *microblaze_abi_string;
47 static const char *const microblaze_abi_strings[] = {
48 "auto",
49 "m64",
50+ NULL
51 };
52
53 enum microblaze_abi
54@@ -105,7 +106,7 @@ global_microblaze_abi (void)
55 if (microblaze_abi_strings[i] == microblaze_abi_string)
56 return (enum microblaze_abi) i;
57
58-// internal_error (__FILE__, __LINE__, _("unknown ABI string"));
59+ internal_error (__FILE__, __LINE__, _("unknown ABI string"));
60 }
61
62 static void
63@@ -894,16 +895,31 @@ microblaze_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
64 }
65
66 static void
67-microblaze_register_g_packet_guesses (struct gdbarch *gdbarch)
68+microblaze_register_g_packet_guesses (struct gdbarch *gdbarch, enum microblaze_abi abi)
69 {
70
71- register_remote_g_packet_guess (gdbarch,
72- 4 * MICROBLAZE_NUM_CORE_REGS,
73- tdesc_microblaze64);
74+ if (abi == MICROBLAZE_ABI_M64)
75+ {
76+
77+ register_remote_g_packet_guess (gdbarch,
78+ 8 * MICROBLAZE_NUM_CORE_REGS,
79+ tdesc_microblaze64);
80+
81+ register_remote_g_packet_guess (gdbarch,
82+ 8 * MICROBLAZE_NUM_REGS,
83+ tdesc_microblaze64_with_stack_protect);
84+ }
85+ else
86+ {
87+
88+ register_remote_g_packet_guess (gdbarch,
89+ 4 * MICROBLAZE_NUM_CORE_REGS,
90+ tdesc_microblaze);
91
92- register_remote_g_packet_guess (gdbarch,
93- 4 * MICROBLAZE_NUM_REGS,
94- tdesc_microblaze64_with_stack_protect);
95+ register_remote_g_packet_guess (gdbarch,
96+ 4 * MICROBLAZE_NUM_REGS,
97+ tdesc_microblaze_with_stack_protect);
98+ }
99 }
100
101 void
102@@ -957,43 +973,6 @@ make_regs (struct gdbarch *arch)
103 }
104 #endif
105
106-void
107-microblaze_supply_gregset (const struct regset *regset,
108- struct regcache *regcache,
109- int regnum, const void *gregs)
110-{
111- const unsigned int *regs = (const unsigned int *)gregs;
112- if (regnum >= 0)
113- regcache->raw_supply (regnum, regs + regnum);
114-
115- if (regnum == -1) {
116- int i;
117-
118- for (i = 0; i < 50; i++) {
119- regcache->raw_supply (i, regs + i);
120- }
121- }
122-}
123-
124-
125-/* Return the appropriate register set for the core section identified
126- by SECT_NAME and SECT_SIZE. */
127-
128-static void
129-microblaze_iterate_over_regset_sections (struct gdbarch *gdbarch,
130- iterate_over_regset_sections_cb *cb,
131- void *cb_data,
132- const struct regcache *regcache)
133-{
134- struct microblaze_gdbarch_tdep *tdep =(microblaze_gdbarch_tdep *) gdbarch_tdep (gdbarch);
135-
136- cb(".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, tdep->gregset, NULL, cb_data);
137-
138- cb(".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, tdep->fpregset, NULL, cb_data);
139-}
140-
141-
142-
143 static struct gdbarch *
144 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
145 {
146@@ -1134,7 +1113,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
147
148 set_gdbarch_unwind_pc (gdbarch, microblaze_unwind_pc);
149
150- //microblaze_register_g_packet_guesses (gdbarch);
151+ // microblaze_register_g_packet_guesses (gdbarch, microblaze_abi);
152
153 frame_base_set_default (gdbarch, &microblaze_frame_base);
154
155diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
156index d61d6bcfeba..692c977ac00 100644
157--- a/opcodes/microblaze-dis.c
158+++ b/opcodes/microblaze-dis.c
159@@ -466,10 +466,6 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
160 print_func (stream, "\t%s, %s", get_field_r1 (&buf, inst),
161 get_field_r2 (&buf, inst));
162 break;
163- case INST_TYPE_IMML:
164- print_func (stream, "\t%s", get_field_imml (&buf, inst));
165- /* TODO: Also print symbol */
166- break;
167 case INST_TYPE_RD_IMM15:
168 print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
169 get_field_imm15 (&buf, inst));
170@@ -484,12 +480,6 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
171 case INST_TYPE_RD_IMML:
172 print_func (stream, "\t%s, %s", get_field_rd (&buf, inst), get_field_imm16 (&buf, inst));
173 break;
174- /* For bit field insns. */
175- case INST_TYPE_RD_R1_IMMW_IMMS:
176- print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst), get_field_r1(&buf, inst),
177- get_field_immw (&buf, inst), get_field_imms (&buf, inst));
178- break;
179- /* For bit field insns. */
180 case INST_TYPE_RD_R1_IMMW_IMMS:
181 print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst),get_field_r1(&buf, inst),get_field_immw (&buf, inst), get_field_imms (&buf, inst));
182 break;
183--
1842.34.1
185
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0041-disable-truncated-register-warning-gdb-remote.c.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0041-disable-truncated-register-warning-gdb-remote.c.patch
new file mode 100644
index 00000000..5a7e4dc3
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0041-disable-truncated-register-warning-gdb-remote.c.patch
@@ -0,0 +1,26 @@
1From 0dc1b1aebeba31dff808a20fcc6444c9acfb99a3 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 14 Mar 2024 15:44:56 +0530
4Subject: [PATCH 41/53] disable truncated register warning (gdb/remote.c)
5
6Signed-off-by: Aayush Misra <aayushm@amd.com>
7---
8 gdb/remote.c | 2 +-
9 1 file changed, 1 insertion(+), 1 deletion(-)
10
11diff --git a/gdb/remote.c b/gdb/remote.c
12index 72f14e28f54..cb99e5bc7b1 100644
13--- a/gdb/remote.c
14+++ b/gdb/remote.c
15@@ -8857,7 +8857,7 @@ remote_target::process_g_packet (struct regcache *regcache)
16 if (rsa->regs[i].pnum == -1)
17 continue;
18
19- if (offset >= sizeof_g_packet)
20+ if (offset >= sizeof_g_packet || (offset + reg_size > sizeof_g_packet))
21 rsa->regs[i].in_g_packet = 0;
22 else if (offset + reg_size > sizeof_g_packet)
23 error (_("Truncated register %d in remote 'g' packet"), i);
24--
252.34.1
26
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0042-Fix-unresolved-conflicts-from-binutils_2_42_merge.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0042-Fix-unresolved-conflicts-from-binutils_2_42_merge.patch
new file mode 100644
index 00000000..88aefa2f
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0042-Fix-unresolved-conflicts-from-binutils_2_42_merge.patch
@@ -0,0 +1,42 @@
1From 81f86c3d6f787a9694e1c95625736f7c921b74df Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 28 Mar 2024 10:20:48 +0530
4Subject: [PATCH 42/53] Fix unresolved conflicts from binutils_2_42_merge
5
6opcodes/microblaze-dis.c
7
8Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
9Signed-off-by: Aayush Misra <aayushm@amd.com>
10---
11 opcodes/microblaze-dis.c | 15 ++++++++++-----
12 1 file changed, 10 insertions(+), 5 deletions(-)
13
14diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
15index 692c977ac00..912fa31be79 100644
16--- a/opcodes/microblaze-dis.c
17+++ b/opcodes/microblaze-dis.c
18@@ -478,11 +478,16 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
19 case INST_TYPE_NONE:
20 break;
21 case INST_TYPE_RD_IMML:
22- print_func (stream, "\t%s, %s", get_field_rd (&buf, inst), get_field_imm16 (&buf, inst));
23- break;
24- case INST_TYPE_RD_R1_IMMW_IMMS:
25- print_func (stream, "\t%s, %s, %s, %s", get_field_rd (&buf, inst),get_field_r1(&buf, inst),get_field_immw (&buf, inst), get_field_imms (&buf, inst));
26- break;
27+ print_func (stream, "\t%s, %s",
28+ get_field_rd (&buf, inst), get_field_imm16 (&buf, inst));
29+ break;
30+ case INST_TYPE_RD_R1_IMMW_IMMS:
31+ print_func (stream, "\t%s, %s, %s, %s",
32+ get_field_rd (&buf, inst),
33+ get_field_r1(&buf, inst),
34+ get_field_immw (&buf, inst),
35+ get_field_imms (&buf, inst));
36+ break;
37 /* For tuqula instruction */
38 case INST_TYPE_RD:
39 print_func (stream, "\t%s", get_field_rd (&buf, inst));
40--
412.34.1
42
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0043-microblaze_gdbarch_init-set-microblaze_abi-based-on-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0043-microblaze_gdbarch_init-set-microblaze_abi-based-on-.patch
new file mode 100644
index 00000000..c5fa72d8
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0043-microblaze_gdbarch_init-set-microblaze_abi-based-on-.patch
@@ -0,0 +1,177 @@
1From a949ac58b5a3e6cbef03fc431f64052827fc9640 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 28 Mar 2024 10:59:40 +0530
4Subject: [PATCH 43/53] microblaze_gdbarch_init: set microblaze_abi based on
5 wanted_abi and found_abi
6
7Earlier found_abi was declared but not set, instead gdbarch_info info
8was checked every time. Also, microblaze_abi remained undefined for 32-bit
9machines. As a result, gdb would show 64-bit registers when connecting
10to 32-bit targets with all register values garbled (r5 ended up in r2).
11This defect is fixed. found_abi is set from gdbarch_info, microblaze_abi
12is set based on wanted_abi and found_abi. Now upon connecting to a 32-bit
13remote target (mb-qemu) registers have the correct 32-bit size.
14
15Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
16Signed-off-by: Aayush Misra <aayushm@amd.com>
17---
18 gdb/microblaze-tdep.c | 73 +++++++++++++++++++------------------------
19 1 file changed, 33 insertions(+), 40 deletions(-)
20
21diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
22index d83e508b82b..6dcdeee76b3 100644
23--- a/gdb/microblaze-tdep.c
24+++ b/gdb/microblaze-tdep.c
25@@ -116,7 +116,7 @@ show_microblaze_abi (struct ui_file *file,
26 const char *ignored_value)
27 {
28 enum microblaze_abi global_abi = global_microblaze_abi ();
29- enum microblaze_abi actual_abi = microblaze_abi (target_gdbarch ());
30+ enum microblaze_abi actual_abi = microblaze_abi (current_inferior ()->arch ());
31 const char *actual_abi_str = microblaze_abi_strings[actual_abi];
32
33 #if 1
34@@ -203,6 +203,13 @@ microblaze_register_name (struct gdbarch *gdbarch, int regnum)
35 static struct type *
36 microblaze_register_type (struct gdbarch *gdbarch, int regnum)
37 {
38+
39+ int mb_reg_size = microblaze_abi_regsize(gdbarch);
40+
41+ if (gdbarch_debug)
42+ gdb_printf (gdb_stdlog, "microblaze_register_type: reg_size = %d\n",
43+ mb_reg_size);
44+
45 if (regnum == MICROBLAZE_SP_REGNUM)
46 return builtin_type (gdbarch)->builtin_data_ptr;
47
48@@ -980,34 +987,38 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
49 enum microblaze_abi microblaze_abi, found_abi, wanted_abi;
50 const struct target_desc *tdesc = info.target_desc;
51
52+ /* If there is already a candidate, use it. */
53+ arches = gdbarch_list_lookup_by_info (arches, &info);
54+ if ((arches != NULL) && (microblaze_abi != MICROBLAZE_ABI_M64))
55+ return arches->gdbarch;
56+
57 /* What has the user specified from the command line? */
58 wanted_abi = global_microblaze_abi ();
59 if (gdbarch_debug)
60 gdb_printf (gdb_stdlog, "microblaze_gdbarch_init: wanted_abi = %d\n",
61 wanted_abi);
62+
63+ found_abi = MICROBLAZE_ABI_AUTO;
64+
65+ if (info.bfd_arch_info->mach == bfd_mach_microblaze64)
66+ found_abi = MICROBLAZE_ABI_M64;
67+
68 if (wanted_abi != MICROBLAZE_ABI_AUTO)
69 microblaze_abi = wanted_abi;
70-
71- /* If there is already a candidate, use it. */
72- arches = gdbarch_list_lookup_by_info (arches, &info);
73- if ((arches != NULL) && (microblaze_abi != MICROBLAZE_ABI_M64))
74- return arches->gdbarch;
75+ else
76+ microblaze_abi = found_abi;
77
78 if (microblaze_abi == MICROBLAZE_ABI_M64)
79 {
80- tdesc = tdesc_microblaze64;
81- reg_size = 8;
82+ tdesc = tdesc_microblaze64;
83+ reg_size = 8;
84 }
85- if (tdesc == NULL)
86+ else
87 {
88- if ((info.bfd_arch_info->mach == bfd_mach_microblaze64) || (microblaze_abi == MICROBLAZE_ABI_M64))
89- {
90- tdesc = tdesc_microblaze64;
91- reg_size = 8;
92- }
93- else
94- tdesc = tdesc_microblaze;
95+ tdesc = tdesc_microblaze;
96+ reg_size = 4;
97 }
98+
99 /* Check any target description for validity. */
100 if (tdesc_has_registers (tdesc))
101 {
102@@ -1015,7 +1026,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
103 int valid_p;
104 int i;
105
106- if ((info.bfd_arch_info->mach == bfd_mach_microblaze64) || (microblaze_abi == MICROBLAZE_ABI_M64))
107+ if (microblaze_abi == MICROBLAZE_ABI_M64)
108 feature = tdesc_find_feature (tdesc,
109 "org.gnu.gdb.microblaze64.core");
110 else
111@@ -1029,7 +1040,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
112 for (i = 0; i < MICROBLAZE_NUM_REGS; i++)
113 valid_p &= tdesc_numbered_register (feature, tdesc_data.get(), i,
114 microblaze_register_names[i]);
115- if ((info.bfd_arch_info->mach == bfd_mach_microblaze64) || (microblaze_abi == MICROBLAZE_ABI_M64))
116+ if (microblaze_abi == MICROBLAZE_ABI_M64)
117 feature = tdesc_find_feature (tdesc,
118 "org.gnu.gdb.microblaze64.stack-protect");
119 else
120@@ -1075,15 +1086,11 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
121
122 /* Register set.
123 make_regs (gdbarch); */
124- switch (info.bfd_arch_info->mach)
125- {
126- case bfd_mach_microblaze64:
127- set_gdbarch_ptr_bit (gdbarch, 64);
128- break;
129- }
130- if(microblaze_abi == MICROBLAZE_ABI_M64)
131+ if (microblaze_abi == MICROBLAZE_ABI_M64)
132 set_gdbarch_ptr_bit (gdbarch, 64);
133-
134+ else
135+ set_gdbarch_ptr_bit (gdbarch, 32);
136+
137 /* Map Dwarf2 registers to GDB registers. */
138 set_gdbarch_dwarf2_reg_to_regnum (gdbarch, microblaze_dwarf2_reg_to_regnum);
139
140@@ -1105,8 +1112,6 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
141 microblaze_breakpoint::bp_from_kind);
142 // set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
143
144-// set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step);
145-
146 set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step);
147
148 set_gdbarch_frame_args_skip (gdbarch, 8);
149@@ -1145,9 +1150,6 @@ _initialize_microblaze_tdep ()
150
151 gdbarch_register (bfd_arch_microblaze, microblaze_gdbarch_init);
152
153-// static struct cmd_list_element *setmicroblazecmdlist = NULL;
154-// static struct cmd_list_element *showmicroblazecmdlist = NULL;
155-
156 /* Add root prefix command for all "set microblaze"/"show microblaze" commands. */
157
158 add_setshow_prefix_cmd ("microblaze", no_class,
159@@ -1155,15 +1157,6 @@ _initialize_microblaze_tdep ()
160 _("Various microblaze specific commands."),
161 &setmicroblazecmdlist,&showmicroblazecmdlist,
162 &setlist,&showlist);
163-#if 0
164- add_prefix_cmd ("microblaze", no_class, set_microblaze_command,
165- _("Various microblaze specific commands."),
166- &setmicroblazecmdlist, "set microblaze ", 0, &setlist);
167-
168- add_prefix_cmd ("microblaze", no_class, show_microblaze_command,
169- _("Various microblaze specific commands."),
170- &showmicroblazecmdlist, "show microblaze ", 0, &showlist);
171-#endif
172
173 /* Allow the user to override the ABI. */
174 add_setshow_enum_cmd ("abi", class_obscure, microblaze_abi_strings,
175--
1762.34.1
177
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0044-Start-bfd_mach_microblaze-values-from-0-0-1-instead-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0044-Start-bfd_mach_microblaze-values-from-0-0-1-instead-.patch
new file mode 100644
index 00000000..a22fdb26
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0044-Start-bfd_mach_microblaze-values-from-0-0-1-instead-.patch
@@ -0,0 +1,32 @@
1From 70d94c8a627a91b7a59d99abf5c137f650a687d3 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 28 Mar 2024 11:36:32 +0530
4Subject: [PATCH 44/53] Start bfd_mach_microblaze values from 0 (0,1) instead
5 of (1,2)
6
7Before 64-bit support there was only bfd_mach_microblaze (implicitly set to 0),
8setting microblaze_mach_microblaze64 to 1
9
10Signed-off-by: Aayush Misra <aayushm@amd.com>
11---
12 bfd/archures.c | 4 ++--
13 1 file changed, 2 insertions(+), 2 deletions(-)
14
15diff --git a/bfd/archures.c b/bfd/archures.c
16index b9db26627ea..604e65b7256 100644
17--- a/bfd/archures.c
18+++ b/bfd/archures.c
19@@ -515,8 +515,8 @@ DESCRIPTION
20 . bfd_arch_lm32, {* Lattice Mico32. *}
21 .#define bfd_mach_lm32 1
22 . bfd_arch_microblaze,{* Xilinx MicroBlaze. *}
23-.#define bfd_mach_microblaze 1
24-.#define bfd_mach_microblaze64 2
25+.#define bfd_mach_microblaze 0
26+.#define bfd_mach_microblaze64 1
27 . bfd_arch_kvx, {* Kalray VLIW core of the MPPA processor family *}
28 .#define bfd_mach_kv3_unknown 0
29 .#define bfd_mach_kv3_1 1
30--
312.34.1
32
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0045-Fix-build-issues-bfd-reloc.c-add-missing-relocs-used.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0045-Fix-build-issues-bfd-reloc.c-add-missing-relocs-used.patch
new file mode 100644
index 00000000..a9f96637
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0045-Fix-build-issues-bfd-reloc.c-add-missing-relocs-used.patch
@@ -0,0 +1,61 @@
1From 8fd6902a818f28422bd98b18ff3f0fe9b872e5cf Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 28 Mar 2024 15:37:11 +0530
4Subject: [PATCH 45/53] Fix build issues - bfd/reloc.c add missing relocs used
5 elsewhere
6
7 BFD_RELOC_MICROBLAZE_EA64
8 BFD_RELOC_MICROBLAZE_64_GPC
9
10Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
11Signed-off-by: Aayush Misra <aayushm@amd.com>
12---
13 bfd/reloc.c | 16 +++++++++++-----
14 1 file changed, 11 insertions(+), 5 deletions(-)
15
16diff --git a/bfd/reloc.c b/bfd/reloc.c
17index b6c9c22a0be..86ca1283582 100644
18--- a/bfd/reloc.c
19+++ b/bfd/reloc.c
20@@ -6637,13 +6637,19 @@ ENUMDOC
21 This is a 64 bit reloc that stores 64-bit thread pointer relative offset
22 to two words (uses imml instruction).
23 ENUM
24-BFD_RELOC_MICROBLAZE_64,
25+BFD_RELOC_MICROBLAZE_64
26 ENUMDOC
27 This is a 64 bit reloc that stores the 64 bit pc relative
28 value in two words (with an imml instruction). No relocation is
29 done here - only used for relaxing
30 ENUM
31-BFD_RELOC_MICROBLAZE_64_PCREL,
32+BFD_RELOC_MICROBLAZE_EA64
33+ENUMDOC
34+ This is a 64 bit reloc that stores the 64 bit pc relative
35+ value in two words (with an imml instruction). No relocation is
36+ done here - only used for relaxing
37+ENUM
38+BFD_RELOC_MICROBLAZE_64_PCREL
39 ENUMDOC
40 This is a 32 bit reloc that stores the 32 bit pc relative
41 value in two words (with an imml instruction). No relocation is
42@@ -6686,13 +6692,13 @@ ENUMDOC
43 two words (with an imm instruction). No relocation is done here -
44 only used for relaxing.
45 ENUM
46-BFD_RELOC_MICROBLAZE_64_PCREL,
47+BFD_RELOC_MICROBLAZE_64_GOTPC
48 ENUMDOC
49- This is a 32 bit reloc that stores the 32 bit pc relative
50+ This is a 64 bit reloc that stores the 32 bit pc relative
51 value in two words (with an imml instruction). No relocation is
52 done here - only used for relaxing
53 ENUM
54- BFD_RELOC_MICROBLAZE_64_GOTPC
55+ BFD_RELOC_MICROBLAZE_64_GPC
56 ENUMDOC
57 This is a 64 bit reloc that stores the 32 bit pc relative
58 value in two words (with an imml instruction). No relocation is
59--
602.34.1
61
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0046-Regenerate-bfd-bfd-in2.h-bfd-libbfd.h.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0046-Regenerate-bfd-bfd-in2.h-bfd-libbfd.h.patch
new file mode 100644
index 00000000..3e6be541
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0046-Regenerate-bfd-bfd-in2.h-bfd-libbfd.h.patch
@@ -0,0 +1,116 @@
1From 84bb72aa81dddd5f21ac49ddf7b38bce74942cdf Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 28 Mar 2024 15:47:56 +0530
4Subject: [PATCH 46/53] Regenerate - bfd/bfd-in2.h bfd/libbfd.h
5
6Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
7Signed-off-by: Aayush Misra <aayushm@amd.com>
8---
9 bfd/bfd-in2.h | 70 +++++++++++++++++++++++++--------------------------
10 1 file changed, 35 insertions(+), 35 deletions(-)
11
12diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
13index cfab5c99b76..96949605e50 100644
14--- a/bfd/bfd-in2.h
15+++ b/bfd/bfd-in2.h
16@@ -1771,8 +1771,8 @@ enum bfd_architecture
17 bfd_arch_lm32, /* Lattice Mico32. */
18 #define bfd_mach_lm32 1
19 bfd_arch_microblaze,/* Xilinx MicroBlaze. */
20-#define bfd_mach_microblaze 1
21-#define bfd_mach_microblaze64 2
22+#define bfd_mach_microblaze 0
23+#define bfd_mach_microblaze64 1
24 bfd_arch_kvx, /* Kalray VLIW core of the MPPA processor family */
25 #define bfd_mach_kv3_unknown 0
26 #define bfd_mach_kv3_1 1
27@@ -6426,8 +6426,23 @@ enum bfd_reloc_code_real
28 /* Address of a GOT entry. */
29 BFD_RELOC_MACH_O_ARM64_POINTER_TO_GOT,
30
31- /* This is a 32 bit reloc for the microblaze that stores the low 16
32- bits of a value. */
33+ /* This is a 64 bit reloc that stores the 64 bit pc relative
34+ value in two words (with an imml instruction). No relocation is
35+ done here - only used for relaxing */
36+ BFD_RELOC_MICROBLAZE_64,
37+
38+ /* This is a 64 bit reloc that stores the 64 bit pc relative
39+ value in two words (with an imml instruction). No relocation is
40+ done here - only used for relaxing */
41+ BFD_RELOC_MICROBLAZE_EA64,
42+
43+ /* This is a 32 bit reloc that stores the 32 bit pc relative
44+ value in two words (with an imml instruction). No relocation is
45+ done here - only used for relaxing */
46+ BFD_RELOC_MICROBLAZE_64_PCREL,
47+
48+ /* This is a 32 bit reloc for the microblaze that stores the
49+ low 16 bits of a value */
50 BFD_RELOC_MICROBLAZE_32_LO,
51
52 /* This is a 32 bit pc-relative reloc for the microblaze that stores
53@@ -6446,44 +6461,29 @@ enum bfd_reloc_code_real
54 the form "Symbol Op Symbol". */
55 BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM,
56
57-/* This is a 32 bit reloc that stores the 32 bit pc relative
58-value in two words (with an imm instruction). No relocation is
59-done here - only used for relaxing */
60+ /* This is a 32 bit reloc that stores the 32 bit pc relative
61+ value in two words (with an imm instruction). No relocation is
62+ done here - only used for relaxing */
63 BFD_RELOC_MICROBLAZE_32_NONE,
64
65-/* This is a 64 bit reloc that stores the 32 bit pc relative
66- * +value in two words (with an imml instruction). No relocation is
67- * +done here - only used for relaxing */
68- BFD_RELOC_MICROBLAZE_64_PCREL,
69-
70-/* This is a 64 bit reloc that stores the 32 bit relative
71- * +value in two words (with an imml instruction). No relocation is
72- * +done here - only used for relaxing */
73- BFD_RELOC_MICROBLAZE_EA64,
74-
75-/* This is a 64 bit reloc that stores the 32 bit pc relative
76- * +value in two words (with an imm instruction). No relocation is
77- * +done here - only used for relaxing */
78- BFD_RELOC_MICROBLAZE_64_NONE,
79-
80- /* This is a 64 bit reloc that stores the 32 bit pc relative value in
81- two words (with an imm instruction). No relocation is done here
82- only used for relaxing */
83- BFD_RELOC_MICROBLAZE_64,
84+ /* This is a 32 bit reloc that stores the 32 bit pc relative
85+ value in two words (with an imml instruction). No relocation is
86+ done here - only used for relaxing */
87+ BFD_RELOC_MICROBLAZE_64_NONE,
88
89-/* This is a 64 bit reloc that stores the 32 bit pc relative
90-value in two words (with an imm instruction). The relocation is
91-PC-relative GOT offset */
92+ /* This is a 64 bit reloc that stores the 32 bit pc relative
93+ value in two words (with an imm instruction). The relocation is
94+ PC-relative GOT offset */
95 BFD_RELOC_MICROBLAZE_64_GOTPC,
96
97-/* This is a 64 bit reloc that stores the 32 bit pc relative
98-value in two words (with an imml instruction). The relocation is
99-PC-relative GOT offset */
100+ /* This is a 64 bit reloc that stores the 32 bit pc relative
101+ value in two words (with an imml instruction). No relocation is
102+ done here - only used for relaxing */
103 BFD_RELOC_MICROBLAZE_64_GPC,
104
105-/* This is a 64 bit reloc that stores the 32 bit pc relative
106-value in two words (with an imm instruction). The relocation is
107-GOT offset */
108+ /* This is a 64 bit reloc that stores the 32 bit pc relative
109+ value in two words (with an imm instruction). The relocation is
110+ GOT offset */
111 BFD_RELOC_MICROBLAZE_64_GOT,
112
113 /* This is a 64 bit reloc that stores the 32 bit pc relative value in
114--
1152.34.1
116
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0047-gdb-remote.c-revert-earlier-change-to-process_g_pack.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0047-gdb-remote.c-revert-earlier-change-to-process_g_pack.patch
new file mode 100644
index 00000000..bf82b0ef
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0047-gdb-remote.c-revert-earlier-change-to-process_g_pack.patch
@@ -0,0 +1,32 @@
1From 8deda21efd527564a262dc07a519f8bd03095b3c Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 28 Mar 2024 16:32:22 +0530
4Subject: [PATCH 47/53] gdb/remote.c - revert earlier change to
5 process_g_packet
6
7When connecting to remote target, gdb (microblaze-xilinx-elf) was
8generating Truncated register 29 error when parsing the g packet,
9workaround added being reverted.
10
11Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
12Signed-off-by: Aayush Misra <aayushm@amd.com>
13---
14 gdb/remote.c | 2 +-
15 1 file changed, 1 insertion(+), 1 deletion(-)
16
17diff --git a/gdb/remote.c b/gdb/remote.c
18index cb99e5bc7b1..72f14e28f54 100644
19--- a/gdb/remote.c
20+++ b/gdb/remote.c
21@@ -8857,7 +8857,7 @@ remote_target::process_g_packet (struct regcache *regcache)
22 if (rsa->regs[i].pnum == -1)
23 continue;
24
25- if (offset >= sizeof_g_packet || (offset + reg_size > sizeof_g_packet))
26+ if (offset >= sizeof_g_packet)
27 rsa->regs[i].in_g_packet = 0;
28 else if (offset + reg_size > sizeof_g_packet)
29 error (_("Truncated register %d in remote 'g' packet"), i);
30--
312.34.1
32
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0048-Fix-build-issues-after-Xilinx-2023.2-binutils-patch-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0048-Fix-build-issues-after-Xilinx-2023.2-binutils-patch-.patch
new file mode 100644
index 00000000..6c40a7e4
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0048-Fix-build-issues-after-Xilinx-2023.2-binutils-patch-.patch
@@ -0,0 +1,465 @@
1From e372266dde792b03fb1754769a9615c818336171 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Mon, 1 Apr 2024 16:21:28 +0530
4Subject: [PATCH 48/53] Fix build issues after Xilinx 2023.2 binutils patch
5 merge
6
7binutils/readelf.c - duplicate case statement
8gas/config/tc-microblaze.c - Missing , between array elements
9gas/config/tc-microblaze.c - A whole hunk ended up in wrong function/switch
10
11Signed-off-by: Aayush Misra <aayushm@amd.com>
12---
13 bfd/libbfd.h | 6 +-
14 binutils/readelf.c | 5 -
15 gas/config/tc-microblaze.c | 375 +++++++++++++++++++------------------
16 3 files changed, 192 insertions(+), 194 deletions(-)
17
18diff --git a/bfd/libbfd.h b/bfd/libbfd.h
19index 7a3e558d70a..5f78d16db18 100644
20--- a/bfd/libbfd.h
21+++ b/bfd/libbfd.h
22@@ -2998,6 +2998,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
23 "BFD_RELOC_MACH_O_ARM64_GOT_LOAD_PAGE21",
24 "BFD_RELOC_MACH_O_ARM64_GOT_LOAD_PAGEOFF12",
25 "BFD_RELOC_MACH_O_ARM64_POINTER_TO_GOT",
26+ "BFD_RELOC_MICROBLAZE_64",
27+ "BFD_RELOC_MICROBLAZE_EA64",
28+ "BFD_RELOC_MICROBLAZE_64_PCREL",
29 "BFD_RELOC_MICROBLAZE_32_LO",
30 "BFD_RELOC_MICROBLAZE_32_LO_PCREL",
31 "BFD_RELOC_MICROBLAZE_32_ROSDA",
32@@ -3006,13 +3009,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
33 "BFD_RELOC_MICROBLAZE_32_NONE",
34 "BFD_RELOC_MICROBLAZE_64_NONE",
35 "BFD_RELOC_MICROBLAZE_64_GOTPC",
36+ "BFD_RELOC_MICROBLAZE_64_GPC",
37 "BFD_RELOC_MICROBLAZE_64_GOT",
38 "BFD_RELOC_MICROBLAZE_64_PLT",
39 "BFD_RELOC_MICROBLAZE_64_GOTOFF",
40 "BFD_RELOC_MICROBLAZE_32_GOTOFF",
41 "BFD_RELOC_MICROBLAZE_COPY",
42- "BFD_RELOC_MICROBLAZE_64",
43- "BFD_RELOC_MICROBLAZE_64_PCREL",
44 "BFD_RELOC_MICROBLAZE_64_TLS",
45 "BFD_RELOC_MICROBLAZE_64_TLSGD",
46 "BFD_RELOC_MICROBLAZE_64_TLSLD",
47diff --git a/binutils/readelf.c b/binutils/readelf.c
48index 3ca9f3697d1..5e4ad6ea6ad 100644
49--- a/binutils/readelf.c
50+++ b/binutils/readelf.c
51@@ -15288,11 +15288,6 @@ is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
52 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
53 default:
54 return false;
55- /* REVISIT microblaze-binutils-merge */
56- case EM_MICROBLAZE:
57- return reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
58- || reloc_type == 0 /* R_MICROBLAZE_NONE. */
59- || reloc_type == 9; /* R_MICROBLAZE_64_NONE. */
60 }
61 }
62
63diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
64index 686b1a00177..d3d1e334bb5 100644
65--- a/gas/config/tc-microblaze.c
66+++ b/gas/config/tc-microblaze.c
67@@ -118,7 +118,7 @@ const relax_typeS md_relax_table[] =
68 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
69 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 16: TLSTPREL_OFFSET. */
70 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
71- { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
72+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 18: TEXT_PC_OFFSET. */
73 { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 }, /* 19: DEFINED_64_OFFSET. */
74 { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE*2, 0 } /* 20: DEFINED_64_PC_OFFSET. */
75 };
76@@ -2263,6 +2263,193 @@ md_assemble (char * str)
77 inst |= (immed << IMM_MBAR);
78 break;
79
80+ /* For 64-bit instructions */
81+ case INST_TYPE_RD_R1_IMML:
82+ if (strcmp (op_end, ""))
83+ op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
84+ else
85+ {
86+ as_fatal (_("Error in statement syntax"));
87+ reg1 = 0;
88+ }
89+ if (strcmp (op_end, ""))
90+ op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
91+ else
92+ {
93+ as_fatal (_("Error in statement syntax"));
94+ reg2 = 0;
95+ }
96+ if (strcmp (op_end, ""))
97+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
98+ else
99+ as_fatal (_("Error in statement syntax"));
100+
101+ /* Check for spl registers. */
102+ if (check_spl_reg (& reg1))
103+ as_fatal (_("Cannot use special register with this instruction"));
104+ if (check_spl_reg (& reg2))
105+ as_fatal (_("Cannot use special register with this instruction"));
106+
107+ if (exp.X_op != O_constant)
108+ {
109+ char *opc = NULL;
110+ //char *opc = str_microblaze_64;
111+ relax_substateT subtype;
112+
113+ if (exp.X_md != 0)
114+ subtype = get_imm_otype(exp.X_md);
115+ else
116+ subtype = opcode->inst_offset_type;
117+
118+ output = frag_var (rs_machine_dependent,
119+ isize * 2, /* maxm of 2 words. */
120+ isize * 2, /* minm of 2 words. */
121+ subtype, /* PC-relative or not. */
122+ exp.X_add_symbol,
123+ exp.X_add_number,
124+ (char *) opc);
125+ immedl = 0L;
126+ }
127+ else
128+ {
129+ output = frag_more (isize);
130+ immedl = exp.X_add_number;
131+ if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887)
132+ {
133+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
134+ if (opcode1 == NULL)
135+ {
136+ as_bad (_("unknown opcode \"%s\""), "imml");
137+ return;
138+ }
139+ inst1 = opcode1->bit_sequence;
140+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
141+ output[0] = INST_BYTE0 (inst1);
142+ output[1] = INST_BYTE1 (inst1);
143+ output[2] = INST_BYTE2 (inst1);
144+ output[3] = INST_BYTE3 (inst1);
145+ output = frag_more (isize);
146+ }
147+ else {
148+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
149+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
150+ if (opcode2 == NULL || opcode1 == NULL)
151+ {
152+ as_bad (_("unknown opcode \"%s\""), "imml");
153+ return;
154+ }
155+ inst1 = opcode2->bit_sequence;
156+ inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
157+ output[0] = INST_BYTE0 (inst1);
158+ output[1] = INST_BYTE1 (inst1);
159+ output[2] = INST_BYTE2 (inst1);
160+ output[3] = INST_BYTE3 (inst1);
161+ output = frag_more (isize);
162+ inst1 = opcode1->bit_sequence;
163+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
164+ output[0] = INST_BYTE0 (inst1);
165+ output[1] = INST_BYTE1 (inst1);
166+ output[2] = INST_BYTE2 (inst1);
167+ output[3] = INST_BYTE3 (inst1);
168+ output = frag_more (isize);
169+ }
170+ }
171+
172+ inst |= (reg1 << RD_LOW) & RD_MASK;
173+ inst |= (reg2 << RA_LOW) & RA_MASK;
174+ inst |= (immedl << IMM_LOW) & IMM_MASK;
175+ break;
176+
177+ case INST_TYPE_R1_IMML:
178+ if (strcmp (op_end, ""))
179+ op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
180+ else
181+ {
182+ as_fatal (_("Error in statement syntax"));
183+ reg1 = 0;
184+ }
185+ if (strcmp (op_end, ""))
186+ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
187+ else
188+ as_fatal (_("Error in statement syntax"));
189+
190+ /* Check for spl registers. */
191+ if (check_spl_reg (&reg1))
192+ as_fatal (_("Cannot use special register with this instruction"));
193+
194+ if (exp.X_op != O_constant)
195+ {
196+ //char *opc = NULL;
197+ char *opc = str_microblaze_64;
198+ relax_substateT subtype;
199+
200+ if (exp.X_md != 0)
201+ subtype = get_imm_otype(exp.X_md);
202+ else
203+ subtype = opcode->inst_offset_type;
204+
205+ output = frag_var (rs_machine_dependent,
206+ isize * 2, /* maxm of 2 words. */
207+ isize * 2, /* minm of 2 words. */
208+ subtype, /* PC-relative or not. */
209+ exp.X_add_symbol,
210+ exp.X_add_number,
211+ (char *) opc);
212+ immedl = 0L;
213+ }
214+ else
215+ {
216+ output = frag_more (isize);
217+ immedl = exp.X_add_number;
218+ if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887)
219+ {
220+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
221+ if (opcode1 == NULL)
222+ {
223+ as_bad (_("unknown opcode \"%s\""), "imml");
224+ return;
225+ }
226+ inst1 = opcode1->bit_sequence;
227+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
228+ output[0] = INST_BYTE0 (inst1);
229+ output[1] = INST_BYTE1 (inst1);
230+ output[2] = INST_BYTE2 (inst1);
231+ output[3] = INST_BYTE3 (inst1);
232+ output = frag_more (isize);
233+ }
234+ else {
235+ opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
236+ opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
237+ if (opcode2 == NULL || opcode1 == NULL)
238+ {
239+ as_bad (_("unknown opcode \"%s\""), "imml");
240+ return;
241+ }
242+ inst1 = opcode2->bit_sequence;
243+ inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
244+ output[0] = INST_BYTE0 (inst1);
245+ output[1] = INST_BYTE1 (inst1);
246+ output[2] = INST_BYTE2 (inst1);
247+ output[3] = INST_BYTE3 (inst1);
248+ output = frag_more (isize);
249+ inst1 = opcode1->bit_sequence;
250+ inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
251+ output[0] = INST_BYTE0 (inst1);
252+ output[1] = INST_BYTE1 (inst1);
253+ output[2] = INST_BYTE2 (inst1);
254+ output[3] = INST_BYTE3 (inst1);
255+ output = frag_more (isize);
256+ }
257+ }
258+
259+ inst |= (reg1 << RA_LOW) & RA_MASK;
260+ inst |= (immedl << IMM_LOW) & IMM_MASK;
261+ break;
262+
263+ case INST_TYPE_IMML:
264+ as_fatal (_("An IMML instruction should not be present in the .s file"));
265+ break;
266+
267 default:
268 as_fatal (_("unimplemented opcode \"%s\""), name);
269 }
270@@ -3177,192 +3364,6 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
271 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
272 code = fixp->fx_r_type;
273 break;
274- /* For 64-bit instructions */
275- case INST_TYPE_RD_R1_IMML:
276- if (strcmp (op_end, ""))
277- op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
278- else
279- {
280- as_fatal (_("Error in statement syntax"));
281- reg1 = 0;
282- }
283- if (strcmp (op_end, ""))
284- op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
285- else
286- {
287- as_fatal (_("Error in statement syntax"));
288- reg2 = 0;
289- }
290- if (strcmp (op_end, ""))
291- op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
292- else
293- as_fatal (_("Error in statement syntax"));
294-
295- /* Check for spl registers. */
296- if (check_spl_reg (& reg1))
297- as_fatal (_("Cannot use special register with this instruction"));
298- if (check_spl_reg (& reg2))
299- as_fatal (_("Cannot use special register with this instruction"));
300-
301- if (exp.X_op != O_constant)
302- {
303- char *opc = NULL;
304- //char *opc = str_microblaze_64;
305- relax_substateT subtype;
306-
307- if (exp.X_md != 0)
308- subtype = get_imm_otype(exp.X_md);
309- else
310- subtype = opcode->inst_offset_type;
311-
312- output = frag_var (rs_machine_dependent,
313- isize * 2, /* maxm of 2 words. */
314- isize * 2, /* minm of 2 words. */
315- subtype, /* PC-relative or not. */
316- exp.X_add_symbol,
317- exp.X_add_number,
318- (char *) opc);
319- immedl = 0L;
320- }
321- else
322- {
323- output = frag_more (isize);
324- immedl = exp.X_add_number;
325- if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887)
326- {
327- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
328- if (opcode1 == NULL)
329- {
330- as_bad (_("unknown opcode \"%s\""), "imml");
331- return;
332- }
333- inst1 = opcode1->bit_sequence;
334- inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
335- output[0] = INST_BYTE0 (inst1);
336- output[1] = INST_BYTE1 (inst1);
337- output[2] = INST_BYTE2 (inst1);
338- output[3] = INST_BYTE3 (inst1);
339- output = frag_more (isize);
340- }
341- else {
342- opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
343- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
344- if (opcode2 == NULL || opcode1 == NULL)
345- {
346- as_bad (_("unknown opcode \"%s\""), "imml");
347- return;
348- }
349- inst1 = opcode2->bit_sequence;
350- inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
351- output[0] = INST_BYTE0 (inst1);
352- output[1] = INST_BYTE1 (inst1);
353- output[2] = INST_BYTE2 (inst1);
354- output[3] = INST_BYTE3 (inst1);
355- output = frag_more (isize);
356- inst1 = opcode1->bit_sequence;
357- inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
358- output[0] = INST_BYTE0 (inst1);
359- output[1] = INST_BYTE1 (inst1);
360- output[2] = INST_BYTE2 (inst1);
361- output[3] = INST_BYTE3 (inst1);
362- output = frag_more (isize);
363- }
364- }
365-
366- inst |= (reg1 << RD_LOW) & RD_MASK;
367- inst |= (reg2 << RA_LOW) & RA_MASK;
368- inst |= (immedl << IMM_LOW) & IMM_MASK;
369- break;
370-
371- case INST_TYPE_R1_IMML:
372- if (strcmp (op_end, ""))
373- op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
374- else
375- {
376- as_fatal (_("Error in statement syntax"));
377- reg1 = 0;
378- }
379- if (strcmp (op_end, ""))
380- op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
381- else
382- as_fatal (_("Error in statement syntax"));
383-
384- /* Check for spl registers. */
385- if (check_spl_reg (&reg1))
386- as_fatal (_("Cannot use special register with this instruction"));
387-
388- if (exp.X_op != O_constant)
389- {
390- //char *opc = NULL;
391- char *opc = str_microblaze_64;
392- relax_substateT subtype;
393-
394- if (exp.X_md != 0)
395- subtype = get_imm_otype(exp.X_md);
396- else
397- subtype = opcode->inst_offset_type;
398-
399- output = frag_var (rs_machine_dependent,
400- isize * 2, /* maxm of 2 words. */
401- isize * 2, /* minm of 2 words. */
402- subtype, /* PC-relative or not. */
403- exp.X_add_symbol,
404- exp.X_add_number,
405- (char *) opc);
406- immedl = 0L;
407- }
408- else
409- {
410- output = frag_more (isize);
411- immedl = exp.X_add_number;
412- if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887)
413- {
414- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
415- if (opcode1 == NULL)
416- {
417- as_bad (_("unknown opcode \"%s\""), "imml");
418- return;
419- }
420- inst1 = opcode1->bit_sequence;
421- inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
422- output[0] = INST_BYTE0 (inst1);
423- output[1] = INST_BYTE1 (inst1);
424- output[2] = INST_BYTE2 (inst1);
425- output[3] = INST_BYTE3 (inst1);
426- output = frag_more (isize);
427- }
428- else {
429- opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
430- opcode2 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml");
431- if (opcode2 == NULL || opcode1 == NULL)
432- {
433- as_bad (_("unknown opcode \"%s\""), "imml");
434- return;
435- }
436- inst1 = opcode2->bit_sequence;
437- inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK;
438- output[0] = INST_BYTE0 (inst1);
439- output[1] = INST_BYTE1 (inst1);
440- output[2] = INST_BYTE2 (inst1);
441- output[3] = INST_BYTE3 (inst1);
442- output = frag_more (isize);
443- inst1 = opcode1->bit_sequence;
444- inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK;
445- output[0] = INST_BYTE0 (inst1);
446- output[1] = INST_BYTE1 (inst1);
447- output[2] = INST_BYTE2 (inst1);
448- output[3] = INST_BYTE3 (inst1);
449- output = frag_more (isize);
450- }
451- }
452-
453- inst |= (reg1 << RA_LOW) & RA_MASK;
454- inst |= (immedl << IMM_LOW) & IMM_MASK;
455- break;
456-
457- case INST_TYPE_IMML:
458- as_fatal (_("An IMML instruction should not be present in the .s file"));
459- break;
460
461 default:
462 switch (F (fixp->fx_size, fixp->fx_pcrel))
463--
4642.34.1
465
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0049-When-unwinding-pc-value-adjust-return-pc-value.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0049-When-unwinding-pc-value-adjust-return-pc-value.patch
new file mode 100644
index 00000000..f7869532
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0049-When-unwinding-pc-value-adjust-return-pc-value.patch
@@ -0,0 +1,92 @@
1From 21527b2edc1359417cc7978558167ef9c8c92afd Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Wed, 1 May 2024 11:12:32 +0530
4Subject: [PATCH 49/53] When unwinding pc value, adjust return pc value
5
6A call (branch and link) instruction can include a delay slot, the
7value of pc stored in the link register for Microblaze architecture
8is the pc value corresponding to last executed instruction (call)
9in the caller. The return instruction (branch reg) includes an
10offset of 8 so that when function returns execution continues from
11the address at : link register + 8, as the instruction in delay slot
12(link register + 4) is already executed at the time of call.
13
14Handle this by adjusting pc value during unwind-pc.
15
16Basically restoring code to do this that seems to have been removed
17as part of a gdb patch (gdb patch #8, Xilinx Yocto 2023.2)
18
19That patch caused hundreds of regressions in gdb testuite, including
20gdb.base/advance.exp, which is now fixed.
21
22Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
23Signed-off-by: Aayush Misra <aayushm@amd.com>
24---
25 gdb/microblaze-tdep.c | 24 ++++++++++++++++++------
26 1 file changed, 18 insertions(+), 6 deletions(-)
27
28diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
29index 6dcdeee76b3..2507cfe540f 100644
30--- a/gdb/microblaze-tdep.c
31+++ b/gdb/microblaze-tdep.c
32@@ -523,6 +523,12 @@ microblaze_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
33 {
34 CORE_ADDR pc;
35 pc=frame_unwind_register_unsigned (next_frame, MICROBLAZE_PC_REGNUM);
36+ /* For sentinel frame, return address is actual PC. For other frames,
37+ return address is pc+8. This is a workaround because gcc does not
38+ generate correct return address in CIE. */
39+ if (frame_relative_level (next_frame) >= 0)
40+ pc = pc + 8;
41+ microblaze_debug ("unwind pc = 0x%x\n", (int) pc);
42 return pc;
43 }
44
45@@ -615,6 +621,7 @@ microblaze_frame_prev_register (frame_info_ptr this_frame,
46 struct microblaze_frame_cache *cache =
47 microblaze_frame_cache (this_frame, this_cache);
48
49+#if 1
50 if ((regnum == MICROBLAZE_SP_REGNUM &&
51 cache->register_offsets[MICROBLAZE_SP_REGNUM])
52 || (regnum == MICROBLAZE_FP_REGNUM &&
53@@ -625,15 +632,22 @@ if ((regnum == MICROBLAZE_SP_REGNUM &&
54
55 if (regnum == MICROBLAZE_PC_REGNUM)
56 {
57- regnum = 15;
58+ regnum = MICROBLAZE_PREV_PC_REGNUM;
59+
60+ microblaze_debug ("prev pc is r15 @ frame offset 0x%x\n",
61+ (int) cache->register_offsets[regnum] );
62+
63 return frame_unwind_got_memory (this_frame, regnum,
64 cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM]);
65-
66 }
67+
68 if (regnum == MICROBLAZE_SP_REGNUM)
69 regnum = 1;
70-#if 0
71
72+ return trad_frame_get_prev_register (this_frame, cache->saved_regs,
73+ regnum);
74+
75+#else
76 if (cache->frameless_p)
77 {
78 if (regnum == MICROBLAZE_PC_REGNUM)
79@@ -646,9 +660,7 @@ if (regnum == MICROBLAZE_SP_REGNUM)
80 else
81 return trad_frame_get_prev_register (this_frame, cache->saved_regs,
82 regnum);
83-#endif
84- return trad_frame_get_prev_register (this_frame, cache->saved_regs,
85- regnum);
86+#endif
87 }
88
89 static const struct frame_unwind microblaze_frame_unwind =
90--
912.34.1
92
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0050-info-reg-pc-does-not-print-symbolic-value.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0050-info-reg-pc-does-not-print-symbolic-value.patch
new file mode 100644
index 00000000..c9bca41d
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0050-info-reg-pc-does-not-print-symbolic-value.patch
@@ -0,0 +1,116 @@
1From 54a6eedd59d70a80be5dc8b4a5abe642113ea291 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 9 May 2024 11:30:22 +0530
4Subject: [PATCH 50/53] info reg pc does not print symbolic value
5
6Problem - Test gdb.base/pc-fp.exp fails
7Fix - Change feature/microblaze-core.xml add type=code_ptr for pc
8
9Files changed
10 features/microblaze-core.xml
11 features/microblaze.c (generated)
12 features/microblaze-with-stack-protect.c (generated)
13
14Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
15Signed-off-by: Aayush Misra <aayushm@amd.com>
16---
17 gdb/features/microblaze-core.xml | 4 ++--
18 gdb/features/microblaze-with-stack-protect.c | 10 ++++++----
19 gdb/features/microblaze.c | 8 ++++----
20 3 files changed, 12 insertions(+), 10 deletions(-)
21
22diff --git a/gdb/features/microblaze-core.xml b/gdb/features/microblaze-core.xml
23index 4d77d9d898f..f49d048fc73 100644
24--- a/gdb/features/microblaze-core.xml
25+++ b/gdb/features/microblaze-core.xml
26@@ -8,7 +8,7 @@
27 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
28 <feature name="org.gnu.gdb.microblaze.core">
29 <reg name="r0" bitsize="32" regnum="0"/>
30- <reg name="r1" bitsize="32"/>
31+ <reg name="r1" bitsize="32" type="data_ptr"/>
32 <reg name="r2" bitsize="32"/>
33 <reg name="r3" bitsize="32"/>
34 <reg name="r4" bitsize="32"/>
35@@ -39,7 +39,7 @@
36 <reg name="r29" bitsize="32"/>
37 <reg name="r30" bitsize="32"/>
38 <reg name="r31" bitsize="32"/>
39- <reg name="rpc" bitsize="32"/>
40+ <reg name="rpc" bitsize="32" type="code_ptr"/>
41 <reg name="rmsr" bitsize="32"/>
42 <reg name="rear" bitsize="32"/>
43 <reg name="resr" bitsize="32"/>
44diff --git a/gdb/features/microblaze-with-stack-protect.c b/gdb/features/microblaze-with-stack-protect.c
45index 8ab9565a047..95e3eed1a4e 100644
46--- a/gdb/features/microblaze-with-stack-protect.c
47+++ b/gdb/features/microblaze-with-stack-protect.c
48@@ -14,7 +14,7 @@ initialize_tdesc_microblaze_with_stack_protect (void)
49
50 feature = tdesc_create_feature (result.get (), "org.gnu.gdb.microblaze.core");
51 tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
52- tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
53+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "data_ptr");
54 tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
55 tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
56 tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
57@@ -45,7 +45,7 @@ initialize_tdesc_microblaze_with_stack_protect (void)
58 tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "int");
59 tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "int");
60 tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "int");
61- tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "int");
62+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "code_ptr");
63 tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
64 tdesc_create_reg (feature, "rear", 34, 1, NULL, 32, "int");
65 tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
66@@ -70,10 +70,12 @@ initialize_tdesc_microblaze_with_stack_protect (void)
67 tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
68 tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
69 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
70-
71- feature = tdesc_create_feature (result.get (), "org.gnu.gdb.microblaze.stack-protect");
72 tdesc_create_reg (feature, "slr", 57, 1, NULL, 32, "int");
73 tdesc_create_reg (feature, "shr", 58, 1, NULL, 32, "int");
74
75+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.microblaze.stack-protect");
76+ tdesc_create_reg (feature, "slr", 59, 1, NULL, 32, "int");
77+ tdesc_create_reg (feature, "shr", 60, 1, NULL, 32, "int");
78+
79 tdesc_microblaze_with_stack_protect = result.release ();
80 }
81diff --git a/gdb/features/microblaze.c b/gdb/features/microblaze.c
82index ed12e5bcfd2..ff4865b2acc 100644
83--- a/gdb/features/microblaze.c
84+++ b/gdb/features/microblaze.c
85@@ -14,7 +14,7 @@ initialize_tdesc_microblaze (void)
86
87 feature = tdesc_create_feature (result.get (), "org.gnu.gdb.microblaze.core");
88 tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
89- tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
90+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "data_ptr");
91 tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
92 tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
93 tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
94@@ -45,7 +45,7 @@ initialize_tdesc_microblaze (void)
95 tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "int");
96 tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "int");
97 tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "int");
98- tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "int");
99+ tdesc_create_reg (feature, "rpc", 32, 1, NULL, 32, "code_ptr");
100 tdesc_create_reg (feature, "rmsr", 33, 1, NULL, 32, "int");
101 tdesc_create_reg (feature, "rear", 34, 1, NULL, 32, "int");
102 tdesc_create_reg (feature, "resr", 35, 1, NULL, 32, "int");
103@@ -70,8 +70,8 @@ initialize_tdesc_microblaze (void)
104 tdesc_create_reg (feature, "rtlbsx", 54, 1, NULL, 32, "int");
105 tdesc_create_reg (feature, "rtlblo", 55, 1, NULL, 32, "int");
106 tdesc_create_reg (feature, "rtlbhi", 56, 1, NULL, 32, "int");
107- tdesc_create_reg (feature, "slr", 57, 1, NULL, 64, "uint64");
108- tdesc_create_reg (feature, "shr", 58, 1, NULL, 64, "uint64");
109+ tdesc_create_reg (feature, "slr", 57, 1, NULL, 32, "int");
110+ tdesc_create_reg (feature, "shr", 58, 1, NULL, 32, "int");
111
112 tdesc_microblaze = result.release ();
113 }
114--
1152.34.1
116
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0051-Wrong-target-description-accepted-by-microblaze-arch.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0051-Wrong-target-description-accepted-by-microblaze-arch.patch
new file mode 100644
index 00000000..65993021
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0051-Wrong-target-description-accepted-by-microblaze-arch.patch
@@ -0,0 +1,51 @@
1From 80f3d1ca2ece1ef143f00365b938e0d0b575d239 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 9 May 2024 11:34:04 +0530
4Subject: [PATCH 51/53] Wrong target description accepted by microblaze
5 architecture
6
7Fix - Modify microblaze_gdbarch_init, set tdesc only when it is NULL
8
9Files changed - gdb/microblaze-tdep.c
10
11Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
12Signed-off-by: Aayush Misra <aayushm@amd.com>
13---
14 gdb/microblaze-tdep.c | 21 ++++++++++++---------
15 1 file changed, 12 insertions(+), 9 deletions(-)
16
17diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
18index 2507cfe540f..cc80e4f0e6b 100644
19--- a/gdb/microblaze-tdep.c
20+++ b/gdb/microblaze-tdep.c
21@@ -1020,15 +1020,18 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
22 else
23 microblaze_abi = found_abi;
24
25- if (microblaze_abi == MICROBLAZE_ABI_M64)
26- {
27- tdesc = tdesc_microblaze64;
28- reg_size = 8;
29- }
30- else
31- {
32- tdesc = tdesc_microblaze;
33- reg_size = 4;
34+ if (tdesc == NULL)
35+ {
36+ if (microblaze_abi == MICROBLAZE_ABI_M64)
37+ {
38+ tdesc = tdesc_microblaze64;
39+ reg_size = 8;
40+ }
41+ else
42+ {
43+ tdesc = tdesc_microblaze;
44+ reg_size = 4;
45+ }
46 }
47
48 /* Check any target description for validity. */
49--
502.34.1
51
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0052-Merge-gdb-microblaze-linux-tdep.c-to-gdb-14-and-fix-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0052-Merge-gdb-microblaze-linux-tdep.c-to-gdb-14-and-fix-.patch
new file mode 100644
index 00000000..f358e45e
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0052-Merge-gdb-microblaze-linux-tdep.c-to-gdb-14-and-fix-.patch
@@ -0,0 +1,42 @@
1From 2e4370f257fae84d18d1f6ef3a756795d77d5707 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Thu, 23 May 2024 16:02:59 +0530
4Subject: [PATCH 52/53] Merge gdb/microblaze-linux-tdep.c to gdb-14 and fix
5 compilation issues.
6
7Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
8Signed-off-by: Aayush Misra <aayushm@amd.com>
9---
10 gdb/microblaze-linux-tdep.c | 6 ++++--
11 1 file changed, 4 insertions(+), 2 deletions(-)
12
13diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
14index babc9020f0f..00112b8f540 100644
15--- a/gdb/microblaze-linux-tdep.c
16+++ b/gdb/microblaze-linux-tdep.c
17@@ -48,10 +48,12 @@ microblaze_debug (const char *fmt, ...)
18 if (microblaze_debug_flag)
19 {
20 va_list args;
21+ string_file file (gdb_stdout->can_emit_style_escape ());
22
23 va_start (args, fmt);
24 printf_unfiltered ("MICROBLAZE LINUX: ");
25- vprintf_unfiltered (fmt, args);
26+ file.vprintf (fmt, args);
27+ gdb_stdout->puts_unfiltered (file.string ().c_str ());
28 va_end (args);
29 }
30 }
31@@ -145,7 +147,7 @@ static void
32 microblaze_linux_init_abi (struct gdbarch_info info,
33 struct gdbarch *gdbarch)
34 {
35- struct microblaze_gdbarch_tdep *tdep =(microblaze_gdbarch_tdep *) gdbarch_tdep (gdbarch);
36+ struct microblaze_gdbarch_tdep *tdep = gdbarch_tdep<microblaze_gdbarch_tdep> (gdbarch);
37
38 tdep->sizeof_gregset = 200;
39
40--
412.34.1
42
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0053-Roll-back-an-improvement-which-inlines-target_gdbarc.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0053-Roll-back-an-improvement-which-inlines-target_gdbarc.patch
new file mode 100644
index 00000000..f7d32927
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0053-Roll-back-an-improvement-which-inlines-target_gdbarc.patch
@@ -0,0 +1,29 @@
1From 13146f53b89c03b086e883e1f4bd9e14c32e6943 Mon Sep 17 00:00:00 2001
2From: Gopi Kumar Bulusu <gopi@sankhya.com>
3Date: Fri, 19 Jul 2024 12:39:24 +0530
4Subject: [PATCH 53/53] Roll back an improvement which inlines target_gdbarch
5 () inherited from binutils 2.42 merge that causes compilation issues on gdb
6 14.2
7
8Signed-off-by: Gopi Kumar Bulusu <gopi@sankhya.com>
9Signed-off-by: Aayush Misra <aayushm@amd.com>
10---
11 gdb/microblaze-tdep.c | 2 +-
12 1 file changed, 1 insertion(+), 1 deletion(-)
13
14diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
15index cc80e4f0e6b..86dedafdbd6 100644
16--- a/gdb/microblaze-tdep.c
17+++ b/gdb/microblaze-tdep.c
18@@ -116,7 +116,7 @@ show_microblaze_abi (struct ui_file *file,
19 const char *ignored_value)
20 {
21 enum microblaze_abi global_abi = global_microblaze_abi ();
22- enum microblaze_abi actual_abi = microblaze_abi (current_inferior ()->arch ());
23+ enum microblaze_abi actual_abi = microblaze_abi ( target_gdbarch () );
24 const char *actual_abi_str = microblaze_abi_strings[actual_abi];
25
26 #if 1
27--
282.34.1
29
diff --git a/meta-vitis-tc/conf/machine/microblaze-tc.conf b/meta-vitis-tc/conf/machine/microblaze-tc.conf
index 8e9d9500..38e0b01b 100644
--- a/meta-vitis-tc/conf/machine/microblaze-tc.conf
+++ b/meta-vitis-tc/conf/machine/microblaze-tc.conf
@@ -37,7 +37,7 @@ MULTILIBS += "multilib:libmbbsmfpd"
37MULTILIBS += "multilib:libmbbspm" 37MULTILIBS += "multilib:libmbbspm"
38MULTILIBS += "multilib:libmbbspfpd" 38MULTILIBS += "multilib:libmbbspfpd"
39MULTILIBS += "multilib:libmbbspmfpd" 39MULTILIBS += "multilib:libmbbspmfpd"
40#MULTILIBS += "multilib:libmblem64" 40MULTILIBS += "multilib:libmblem64"
41MULTILIBS += "multilib:libmblebs" 41MULTILIBS += "multilib:libmblebs"
42MULTILIBS += "multilib:libmblep" 42MULTILIBS += "multilib:libmblep"
43MULTILIBS += "multilib:libmblem" 43MULTILIBS += "multilib:libmblem"
@@ -53,21 +53,21 @@ MULTILIBS += "multilib:libmblebsmfpd"
53MULTILIBS += "multilib:libmblebspm" 53MULTILIBS += "multilib:libmblebspm"
54MULTILIBS += "multilib:libmblebspfpd" 54MULTILIBS += "multilib:libmblebspfpd"
55MULTILIBS += "multilib:libmblebspmfpd" 55MULTILIBS += "multilib:libmblebspmfpd"
56#MULTILIBS += "multilib:libmblem64bs" 56MULTILIBS += "multilib:libmblem64bs"
57#MULTILIBS += "multilib:libmblem64p" 57MULTILIBS += "multilib:libmblem64p"
58#MULTILIBS += "multilib:libmblem64m" 58MULTILIBS += "multilib:libmblem64m"
59#MULTILIBS += "multilib:libmblem64fpd" 59MULTILIBS += "multilib:libmblem64fpd"
60#MULTILIBS += "multilib:libmblem64mfpd" 60MULTILIBS += "multilib:libmblem64mfpd"
61#MULTILIBS += "multilib:libmblem64pm" 61MULTILIBS += "multilib:libmblem64pm"
62#MULTILIBS += "multilib:libmblem64pfpd" 62MULTILIBS += "multilib:libmblem64pfpd"
63#MULTILIBS += "multilib:libmblem64pmfpd" 63MULTILIBS += "multilib:libmblem64pmfpd"
64#MULTILIBS += "multilib:libmblem64bsp" 64MULTILIBS += "multilib:libmblem64bsp"
65#MULTILIBS += "multilib:libmblem64bsm" 65MULTILIBS += "multilib:libmblem64bsm"
66#MULTILIBS += "multilib:libmblem64bsfpd" 66MULTILIBS += "multilib:libmblem64bsfpd"
67#MULTILIBS += "multilib:libmblem64bsmfpd" 67MULTILIBS += "multilib:libmblem64bsmfpd"
68#MULTILIBS += "multilib:libmblem64bspm" 68MULTILIBS += "multilib:libmblem64bspm"
69#MULTILIBS += "multilib:libmblem64bspfpd" 69MULTILIBS += "multilib:libmblem64bspfpd"
70#MULTILIBS += "multilib:libmblem64bspmfpd" 70MULTILIBS += "multilib:libmblem64bspmfpd"
71 71
72 72
73# Base configuration 73# Base configuration