From ac744e63e208b5ddb6f799b041d0c0cd4ea2d144 Mon Sep 17 00:00:00 2001 From: Mark Hatle Date: Mon, 27 Jan 2020 10:34:43 -0800 Subject: binutils: Merge latest binutils work Update gdb item (not really applicable, but included to be complete). Fix an issue w/ microblaze 64 IMML instruction. Signed-off-by: Mark Hatle --- .../binutils/binutils-microblaze.inc | 2 + ...aze-linux-nat.c-Fix-target-compilation-of.patch | 364 +++++++++++++++++++++ ...in-generation-of-IMML-instruction-for-the.patch | 86 +++++ 3 files changed, 452 insertions(+) create mode 100644 meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch create mode 100644 meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-microblaze.inc b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-microblaze.inc index 3cb4dc26..5ccd78b2 100644 --- a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-microblaze.inc +++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-microblaze.inc @@ -44,4 +44,6 @@ SRC_URI_append = " \ file://0041-patch-MicroBlaze-porting-GDB-for-linux.patch \ file://0042-Correcting-the-register-names-from-slr-shr-to-rslr-r.patch \ file://0043-Removing-the-header-gdb_assert.h-from-MB-target-file.patch \ + file://0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch \ + file://0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch \ " diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch new file mode 100644 index 00000000..29e198cd --- /dev/null +++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0044-gdb-microblaze-linux-nat.c-Fix-target-compilation-of.patch @@ -0,0 +1,364 @@ +From 4f0e06249d23629e1d56b296e7a040b6968484e9 Mon Sep 17 00:00:00 2001 +From: Mark Hatle +Date: Mon, 20 Jan 2020 12:48:13 -0800 +Subject: [PATCH 44/45] gdb/microblaze-linux-nat.c: Fix target compilation of + gdb + +Add the nat to the configure file + +Remove gdb_assert.h and gdb_string.h. + +Adjust include for opcodes as well. + +Update to match latest style of components, similar to ppc-linux-nat.c + +Update: + get_regcache_arch(regcache) to regcache->arch() + regcache_raw_supply(regcache, ...) to regcache->raw_supply(...) + regcache_raw_collect(regcache, ...) to regcache->raw_collect(...) + +Signed-off-by: Mark Hatle +--- + gdb/configure.nat | 4 + + gdb/microblaze-linux-nat.c | 149 +++++++++++++------------------------ + gdb/microblaze-tdep.c | 3 +- + 3 files changed, 57 insertions(+), 99 deletions(-) + +diff --git a/gdb/configure.nat b/gdb/configure.nat +index 3118263ac6..b8dc7398a5 100644 +--- a/gdb/configure.nat ++++ b/gdb/configure.nat +@@ -260,6 +260,10 @@ case ${gdb_host} in + # Host: Motorola m68k running GNU/Linux. + NATDEPFILES="${NATDEPFILES} m68k-linux-nat.o" + ;; ++ microblaze*) ++ # Host: Microblaze, running Linux ++ NATDEPFILES="${NATDEPFILES} microblaze-linux-nat.o" ++ ;; + mips) + # Host: Linux/MIPS + NATDEPFILES="${NATDEPFILES} linux-nat-trad.o \ +diff --git a/gdb/microblaze-linux-nat.c b/gdb/microblaze-linux-nat.c +index e9b8c9c522..e09a86bb3f 100644 +--- a/gdb/microblaze-linux-nat.c ++++ b/gdb/microblaze-linux-nat.c +@@ -36,11 +36,9 @@ + #include "dwarf2-frame.h" + #include "osabi.h" + +-#include "gdb_assert.h" +-#include "gdb_string.h" + #include "target-descriptions.h" +-#include "opcodes/microblaze-opcm.h" +-#include "opcodes/microblaze-dis.h" ++#include "../opcodes/microblaze-opcm.h" ++#include "../opcodes/microblaze-dis.h" + + #include "linux-nat.h" + #include "target-descriptions.h" +@@ -61,34 +59,27 @@ + /* Defines ps_err_e, struct ps_prochandle. */ + #include "gdb_proc_service.h" + +-/* On GNU/Linux, threads are implemented as pseudo-processes, in which +- case we may be tracing more than one process at a time. In that +- case, inferior_ptid will contain the main process ID and the +- individual thread (process) ID. get_thread_id () is used to get +- the thread id if it's available, and the process id otherwise. */ +- +-int +-get_thread_id (ptid_t ptid) +-{ +- int tid = TIDGET (ptid); +- if (0 == tid) +- tid = PIDGET (ptid); +- return tid; +-} +- +-#define GET_THREAD_ID(PTID) get_thread_id (PTID) +- + /* Non-zero if our kernel may support the PTRACE_GETREGS and + PTRACE_SETREGS requests, for reading and writing the + general-purpose registers. Zero if we've tried one of + them and gotten an error. */ + int have_ptrace_getsetregs = 1; + ++struct microblaze_linux_nat_target final : public linux_nat_target ++{ ++ /* Add our register access methods. */ ++ void fetch_registers (struct regcache *, int) override; ++ void store_registers (struct regcache *, int) override; ++ ++ const struct target_desc *read_description () override; ++}; ++ ++static microblaze_linux_nat_target the_microblaze_linux_nat_target; ++ + static int + microblaze_register_u_addr (struct gdbarch *gdbarch, int regno) + { + int u_addr = -1; +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace + interface, and not the wordsize of the program's ABI. */ + int wordsize = sizeof (long); +@@ -105,18 +96,16 @@ microblaze_register_u_addr (struct gdbarch *gdbarch, int regno) + static void + fetch_register (struct regcache *regcache, int tid, int regno) + { +- struct gdbarch *gdbarch = get_regcache_arch (regcache); +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ struct gdbarch *gdbarch = regcache->arch(); + /* This isn't really an address. But ptrace thinks of it as one. */ + CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno); + int bytes_transferred; +- unsigned int offset; /* Offset of registers within the u area. */ +- char buf[MAX_REGISTER_SIZE]; ++ char buf[sizeof(long)]; + + if (regaddr == -1) + { + memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */ +- regcache_raw_supply (regcache, regno, buf); ++ regcache->raw_supply (regno, buf); + return; + } + +@@ -149,14 +138,14 @@ fetch_register (struct regcache *regcache, int tid, int regno) + { + /* Little-endian values are always found at the left end of the + bytes transferred. */ +- regcache_raw_supply (regcache, regno, buf); ++ regcache->raw_supply (regno, buf); + } + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + /* Big-endian values are found at the right end of the bytes + transferred. */ + size_t padding = (bytes_transferred - register_size (gdbarch, regno)); +- regcache_raw_supply (regcache, regno, buf + padding); ++ regcache->raw_supply (regno, buf + padding); + } + else + internal_error (__FILE__, __LINE__, +@@ -175,8 +164,6 @@ fetch_register (struct regcache *regcache, int tid, int regno) + static int + fetch_all_gp_regs (struct regcache *regcache, int tid) + { +- struct gdbarch *gdbarch = get_regcache_arch (regcache); +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + gdb_gregset_t gregset; + + if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0) +@@ -204,8 +191,6 @@ fetch_all_gp_regs (struct regcache *regcache, int tid) + static void + fetch_gp_regs (struct regcache *regcache, int tid) + { +- struct gdbarch *gdbarch = get_regcache_arch (regcache); +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int i; + + if (have_ptrace_getsetregs) +@@ -219,17 +204,29 @@ fetch_gp_regs (struct regcache *regcache, int tid) + fetch_register (regcache, tid, i); + } + ++/* Fetch registers from the child process. Fetch all registers if ++ regno == -1, otherwise fetch all general registers or all floating ++ point registers depending upon the value of regno. */ ++void ++microblaze_linux_nat_target::fetch_registers (struct regcache *regcache, int regno) ++{ ++ pid_t tid = get_ptrace_pid (regcache->ptid ()); ++ ++ if (regno == -1) ++ fetch_gp_regs (regcache, tid); ++ else ++ fetch_register (regcache, tid, regno); ++} + + static void + store_register (const struct regcache *regcache, int tid, int regno) + { +- struct gdbarch *gdbarch = get_regcache_arch (regcache); +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ struct gdbarch *gdbarch = regcache->arch(); + /* This isn't really an address. But ptrace thinks of it as one. */ + CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno); + int i; + size_t bytes_to_transfer; +- char buf[MAX_REGISTER_SIZE]; ++ char buf[sizeof(long)]; + + if (regaddr == -1) + return; +@@ -242,13 +239,13 @@ store_register (const struct regcache *regcache, int tid, int regno) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) + { + /* Little-endian values always sit at the left end of the buffer. */ +- regcache_raw_collect (regcache, regno, buf); ++ regcache->raw_collect (regno, buf); + } + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + /* Big-endian values sit at the right end of the buffer. */ + size_t padding = (bytes_to_transfer - register_size (gdbarch, regno)); +- regcache_raw_collect (regcache, regno, buf + padding); ++ regcache->raw_collect (regno, buf + padding); + } + + for (i = 0; i < bytes_to_transfer; i += sizeof (long)) +@@ -281,8 +278,6 @@ store_register (const struct regcache *regcache, int tid, int regno) + static int + store_all_gp_regs (const struct regcache *regcache, int tid, int regno) + { +- struct gdbarch *gdbarch = get_regcache_arch (regcache); +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + gdb_gregset_t gregset; + + if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0) +@@ -319,8 +314,6 @@ store_all_gp_regs (const struct regcache *regcache, int tid, int regno) + static void + store_gp_regs (const struct regcache *regcache, int tid, int regno) + { +- struct gdbarch *gdbarch = get_regcache_arch (regcache); +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int i; + + if (have_ptrace_getsetregs) +@@ -335,33 +328,10 @@ store_gp_regs (const struct regcache *regcache, int tid, int regno) + } + + +-/* Fetch registers from the child process. Fetch all registers if +- regno == -1, otherwise fetch all general registers or all floating +- point registers depending upon the value of regno. */ +- +-static void +-microblaze_linux_fetch_inferior_registers (struct target_ops *ops, +- struct regcache *regcache, int regno) +-{ +- /* Get the thread id for the ptrace call. */ +- int tid = GET_THREAD_ID (inferior_ptid); +- +- if (regno == -1) +- fetch_gp_regs (regcache, tid); +- else +- fetch_register (regcache, tid, regno); +-} +- +-/* Store registers back into the inferior. Store all registers if +- regno == -1, otherwise store all general registers or all floating +- point registers depending upon the value of regno. */ +- +-static void +-microblaze_linux_store_inferior_registers (struct target_ops *ops, +- struct regcache *regcache, int regno) ++void ++microblaze_linux_nat_target::store_registers (struct regcache *regcache, int regno) + { +- /* Get the thread id for the ptrace call. */ +- int tid = GET_THREAD_ID (inferior_ptid); ++ pid_t tid = get_ptrace_pid (regcache->ptid ()); + + if (regno >= 0) + store_register (regcache, tid, regno); +@@ -373,59 +343,44 @@ microblaze_linux_store_inferior_registers (struct target_ops *ops, + thread debugging. */ + + void +-fill_gregset (const struct regcache *regcache, +- gdb_gregset_t *gregsetp, int regno) ++supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) + { +- microblaze_collect_gregset (NULL, regcache, regno, gregsetp); ++ microblaze_supply_gregset (NULL, regcache, -1, gregsetp); + } + + void +-supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) ++fill_gregset (const struct regcache *regcache, ++ gdb_gregset_t *gregsetp, int regno) + { +- microblaze_supply_gregset (NULL, regcache, -1, gregsetp); ++ microblaze_collect_gregset (NULL, regcache, regno, gregsetp); + } + + void +-fill_fpregset (const struct regcache *regcache, +- gdb_fpregset_t *fpregsetp, int regno) ++supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) + { + /* FIXME. */ ++ return; + } + + void +-supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) ++fill_fpregset (const struct regcache *regcache, ++ gdb_fpregset_t *fpregsetp, int regno) + { + /* FIXME. */ ++ return; + } + +-static const struct target_desc * +-microblaze_linux_read_description (struct target_ops *ops) ++const struct target_desc * ++microblaze_linux_nat_target::read_description () + { +- CORE_ADDR microblaze_hwcap = 0; +- +- if (target_auxv_search (ops, AT_HWCAP, µblaze_hwcap) != 1) +- return NULL; +- + return NULL; + } + +- +-void _initialize_microblaze_linux_nat (void); +- + void + _initialize_microblaze_linux_nat (void) + { +- struct target_ops *t; +- +- /* Fill in the generic GNU/Linux methods. */ +- t = linux_target (); +- +- /* Add our register access methods. */ +- t->to_fetch_registers = microblaze_linux_fetch_inferior_registers; +- t->to_store_registers = microblaze_linux_store_inferior_registers; +- +- t->to_read_description = microblaze_linux_read_description; ++ linux_target = &the_microblaze_linux_nat_target; + + /* Register the target. */ +- linux_nat_add_target (t); ++ add_inf_child_target (linux_target); + } +diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c +index 7a0c2527f4..23deb24d26 100644 +--- a/gdb/microblaze-tdep.c ++++ b/gdb/microblaze-tdep.c +@@ -657,7 +657,7 @@ static std::vector + microblaze_software_single_step (struct regcache *regcache) + { + // struct gdbarch *arch = get_frame_arch(frame); +- struct gdbarch *arch = get_regcache_arch (regcache); ++ struct gdbarch *arch = regcache->arch(); + struct address_space *aspace = get_regcache_aspace (regcache); + // struct address_space *aspace = get_frame_address_space (frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); +@@ -876,7 +876,6 @@ microblaze_regset_from_core_section (struct gdbarch *gdbarch, + static void + make_regs (struct gdbarch *arch) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + int mach = gdbarch_bfd_arch_info (arch)->mach; + + if (mach == bfd_mach_microblaze64) +-- +2.17.1 + diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch new file mode 100644 index 00000000..118c5629 --- /dev/null +++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils/0045-Fixed-bug-in-generation-of-IMML-instruction-for-the.patch @@ -0,0 +1,86 @@ +From d64ce07a2b9206ce1e53d8958b28de02cc7cca2b Mon Sep 17 00:00:00 2001 +From: Nagaraju +Date: Wed, 22 Jan 2020 16:31:12 +0530 +Subject: [PATCH 45/45] Fixed bug in generation of IMML instruction for the new + MB-64 instructions with single register. + +--- + gas/config/tc-microblaze.c | 50 +++++++++++++++++++++++++++++++++++--- + 1 file changed, 47 insertions(+), 3 deletions(-) + +diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c +index 95a1e69729..dc79328df6 100644 +--- a/gas/config/tc-microblaze.c ++++ b/gas/config/tc-microblaze.c +@@ -1642,12 +1642,56 @@ md_assemble (char * str) + exp.X_add_symbol, + exp.X_add_number, + (char *) opc); +- immedl = 0L; ++ immed = 0L; + } + else + { + output = frag_more (isize); + immed = exp.X_add_number; ++ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000; ++ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000 && temp != 0x8000) ++ { ++ /* Needs an immediate inst. */ ++ if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887) ++ { ++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); ++ if (opcode1 == NULL) ++ { ++ as_bad (_("unknown opcode \"%s\""), "imml"); ++ return; ++ } ++ inst1 = opcode1->bit_sequence; ++ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; ++ output[0] = INST_BYTE0 (inst1); ++ output[1] = INST_BYTE1 (inst1); ++ output[2] = INST_BYTE2 (inst1); ++ output[3] = INST_BYTE3 (inst1); ++ output = frag_more (isize); ++ } ++ else { ++ opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); ++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); ++ if (opcode1 == NULL || opcode2 == NULL) ++ { ++ as_bad (_("unknown opcode \"%s\""), "imml"); ++ return; ++ } ++ inst1 = opcode2->bit_sequence; ++ inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK; ++ output[0] = INST_BYTE0 (inst1); ++ output[1] = INST_BYTE1 (inst1); ++ output[2] = INST_BYTE2 (inst1); ++ output[3] = INST_BYTE3 (inst1); ++ output = frag_more (isize); ++ inst1 = opcode1->bit_sequence; ++ inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; ++ output[0] = INST_BYTE0 (inst1); ++ output[1] = INST_BYTE1 (inst1); ++ output[2] = INST_BYTE2 (inst1); ++ output[3] = INST_BYTE3 (inst1); ++ output = frag_more (isize); ++ } ++ } + } + inst |= (reg1 << RD_LOW) & RD_MASK; + inst |= (immed << IMM_LOW) & IMM16_MASK; +@@ -2141,8 +2185,8 @@ md_assemble (char * str) + streq (name, "breaid") || + streq (name, "brai") || streq (name, "braid"))) + { +- temp = immed & 0xFFFFFFFFFFFF8000; +- if (temp != 0) ++ temp = ((long long)immed) & 0xFFFFFFFFFFFF8000; ++ if (temp != 0 && temp != 0xFFFFFFFFFFFF8000 && temp != 0x8000) + { + /* Needs an immediate inst. */ + if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887) +-- +2.17.1 + -- cgit v1.2.3-54-g00ecf