diff options
| author | Nathan Rossi <nathan.rossi@xilinx.com> | 2013-12-16 16:48:36 +1000 |
|---|---|---|
| committer | Nathan Rossi <nathan.rossi@xilinx.com> | 2013-12-16 16:48:36 +1000 |
| commit | 74f73159e5c659d8ee52a3d48238932b36e4fe93 (patch) | |
| tree | 824b4a830e733161d055a12d6993dc6c8cd45da3 /recipes-devtools | |
| parent | 3ec0d044ea0c5fca26eecc0335bb9847871255ea (diff) | |
| download | meta-xilinx-74f73159e5c659d8ee52a3d48238932b36e4fe93.tar.gz | |
gdb: Add MicroBlaze support
* Import Xilinx gdb patches for MicroBlaze
* Disable dependence on LTTng-UST for MicroBlaze, it is not supported
Signed-off-by: Nathan Rossi <nathan.rossi@xilinx.com>
Diffstat (limited to 'recipes-devtools')
18 files changed, 2427 insertions, 0 deletions
diff --git a/recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch b/recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch new file mode 100644 index 00000000..5c195538 --- /dev/null +++ b/recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch | |||
| @@ -0,0 +1,471 @@ | |||
| 1 | From: David Holsgrove <david.holsgrove@petalogix.com> | ||
| 2 | Date: Mon, 6 Feb 2012 10:28:29 +1000 | ||
| 3 | Subject: Add initial port of linux gdbserver | ||
| 4 | |||
| 5 | add gdb_proc_service_h to gdbserver microblaze-linux | ||
| 6 | |||
| 7 | gdbserver needs to initialise the microblaze registers | ||
| 8 | |||
| 9 | other archs use this step to run a *_arch_setup() to carry out all | ||
| 10 | architecture 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 | |||
| 20 | Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com> | ||
| 21 | Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com> | ||
| 22 | Upstream-Status: Pending | ||
| 23 | --- | ||
| 24 | gdb/configure.host | 3 + | ||
| 25 | gdb/gdbserver/linux-microblaze-low.c | 228 ++++++++++++++++++++++++++++++++++ | ||
| 26 | gdb/microblaze-linux-tdep.c | 30 ++++- | ||
| 27 | gdb/microblaze-tdep.c | 35 ++++++ | ||
| 28 | gdb/microblaze-tdep.h | 3 +- | ||
| 29 | gdb/regformats/reg-microblaze.dat | 39 ++++++ | ||
| 30 | 6 files changed, 336 insertions(+), 2 deletions(-) | ||
| 31 | create mode 100644 gdb/gdbserver/linux-microblaze-low.c | ||
| 32 | create mode 100644 gdb/regformats/reg-microblaze.dat | ||
| 33 | |||
| 34 | diff --git a/gdb/configure.host b/gdb/configure.host | ||
| 35 | index 85f4491..98b0f43 100644 | ||
| 36 | --- a/gdb/configure.host | ||
| 37 | +++ b/gdb/configure.host | ||
| 38 | @@ -47,6 +47,7 @@ i[34567]86*) gdb_host_cpu=i386 ;; | ||
| 39 | m68*) gdb_host_cpu=m68k ;; | ||
| 40 | m88*) gdb_host_cpu=m88k ;; | ||
| 41 | mips*) gdb_host_cpu=mips ;; | ||
| 42 | +microblaze*) gdb_host_cpu=microblaze ;; | ||
| 43 | powerpc* | rs6000) gdb_host_cpu=powerpc ;; | ||
| 44 | sparcv9 | sparc64) gdb_host_cpu=sparc ;; | ||
| 45 | s390*) gdb_host_cpu=s390 ;; | ||
| 46 | @@ -126,6 +127,8 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu) | ||
| 47 | gdb_host=nbsd ;; | ||
| 48 | mips64*-*-openbsd*) gdb_host=obsd64 ;; | ||
| 49 | |||
| 50 | +microblaze*-*linux*) gdb_host=linux ;; | ||
| 51 | + | ||
| 52 | powerpc-*-aix* | rs6000-*-*) | ||
| 53 | gdb_host=aix ;; | ||
| 54 | powerpc*-*-freebsd*) gdb_host=fbsd ;; | ||
| 55 | diff --git a/gdb/gdbserver/linux-microblaze-low.c b/gdb/gdbserver/linux-microblaze-low.c | ||
| 56 | new file mode 100644 | ||
| 57 | index 0000000..279df9f | ||
| 58 | --- /dev/null | ||
| 59 | +++ b/gdb/gdbserver/linux-microblaze-low.c | ||
| 60 | @@ -0,0 +1,228 @@ | ||
| 61 | +/* GNU/Linux/Microblaze specific low level interface, for the remote server for | ||
| 62 | + GDB. | ||
| 63 | + Copyright (C) 1995-2013 Free Software Foundation, Inc. | ||
| 64 | + | ||
| 65 | + This file is part of GDB. | ||
| 66 | + | ||
| 67 | + This program is free software; you can redistribute it and/or modify | ||
| 68 | + it under the terms of the GNU General Public License as published by | ||
| 69 | + the Free Software Foundation; either version 3 of the License, or | ||
| 70 | + (at your option) any later version. | ||
| 71 | + | ||
| 72 | + This program is distributed in the hope that it will be useful, | ||
| 73 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 74 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 75 | + GNU General Public License for more details. | ||
| 76 | + | ||
| 77 | + You should have received a copy of the GNU General Public License | ||
| 78 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 79 | + | ||
| 80 | +#include "server.h" | ||
| 81 | +#include "linux-low.h" | ||
| 82 | + | ||
| 83 | +#include <asm/ptrace.h> | ||
| 84 | +#include <sys/procfs.h> | ||
| 85 | +#include <sys/ptrace.h> | ||
| 86 | + | ||
| 87 | +#include "gdb_proc_service.h" | ||
| 88 | + | ||
| 89 | +static int microblaze_regmap[] = | ||
| 90 | + {PT_GPR(0), PT_GPR(1), PT_GPR(2), PT_GPR(3), | ||
| 91 | + PT_GPR(4), PT_GPR(5), PT_GPR(6), PT_GPR(7), | ||
| 92 | + PT_GPR(8), PT_GPR(9), PT_GPR(10), PT_GPR(11), | ||
| 93 | + PT_GPR(12), PT_GPR(13), PT_GPR(14), PT_GPR(15), | ||
| 94 | + PT_GPR(16), PT_GPR(17), PT_GPR(18), PT_GPR(19), | ||
| 95 | + PT_GPR(20), PT_GPR(21), PT_GPR(22), PT_GPR(23), | ||
| 96 | + PT_GPR(24), PT_GPR(25), PT_GPR(26), PT_GPR(27), | ||
| 97 | + PT_GPR(28), PT_GPR(29), PT_GPR(30), PT_GPR(31), | ||
| 98 | + PT_PC, PT_MSR, PT_EAR, PT_ESR, | ||
| 99 | + PT_FSR | ||
| 100 | + }; | ||
| 101 | + | ||
| 102 | +#define microblaze_num_regs (sizeof microblaze_regmap / sizeof microblaze_regmap[0]) | ||
| 103 | + | ||
| 104 | +/* Defined in auto-generated file microblaze-linux.c. */ | ||
| 105 | +void init_registers_microblaze (void); | ||
| 106 | +extern const struct target_desc *tdesc_microblaze; | ||
| 107 | + | ||
| 108 | +static int | ||
| 109 | +microblaze_cannot_store_register (int regno) | ||
| 110 | +{ | ||
| 111 | + if (microblaze_regmap[regno] == -1 || regno == 0) | ||
| 112 | + return 1; | ||
| 113 | + | ||
| 114 | + return 0; | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +static int | ||
| 118 | +microblaze_cannot_fetch_register (int regno) | ||
| 119 | +{ | ||
| 120 | + return 0; | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +static CORE_ADDR | ||
| 124 | +microblaze_get_pc (struct regcache *regcache) | ||
| 125 | +{ | ||
| 126 | + unsigned long pc; | ||
| 127 | + | ||
| 128 | + collect_register_by_name (regcache, "pc", &pc); | ||
| 129 | + return (CORE_ADDR) pc; | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | +static void | ||
| 133 | +microblaze_set_pc (struct regcache *regcache, CORE_ADDR pc) | ||
| 134 | +{ | ||
| 135 | + unsigned long newpc = pc; | ||
| 136 | + | ||
| 137 | + supply_register_by_name (regcache, "pc", &newpc); | ||
| 138 | +} | ||
| 139 | + | ||
| 140 | +/* dbtrap insn */ | ||
| 141 | +/* brki r16, 0x18; */ | ||
| 142 | +static const unsigned long microblaze_breakpoint = 0xba0c0018; | ||
| 143 | +#define microblaze_breakpoint_len 4 | ||
| 144 | + | ||
| 145 | +static int | ||
| 146 | +microblaze_breakpoint_at (CORE_ADDR where) | ||
| 147 | +{ | ||
| 148 | + unsigned long insn; | ||
| 149 | + | ||
| 150 | + (*the_target->read_memory) (where, (unsigned char *) &insn, 4); | ||
| 151 | + if (insn == microblaze_breakpoint) | ||
| 152 | + return 1; | ||
| 153 | + /* If necessary, recognize more trap instructions here. GDB only uses the | ||
| 154 | + one. */ | ||
| 155 | + return 0; | ||
| 156 | +} | ||
| 157 | + | ||
| 158 | +static CORE_ADDR | ||
| 159 | +microblaze_reinsert_addr (struct regcache *regcache) | ||
| 160 | +{ | ||
| 161 | + unsigned long pc; | ||
| 162 | + collect_register_by_name (regcache, "r15", &pc); | ||
| 163 | + return pc; | ||
| 164 | +} | ||
| 165 | + | ||
| 166 | +#ifdef HAVE_PTRACE_GETREGS | ||
| 167 | + | ||
| 168 | +static void | ||
| 169 | +microblaze_collect_ptrace_register (struct regcache *regcache, int regno, char *buf) | ||
| 170 | +{ | ||
| 171 | + int size = register_size (regcache->tdesc, regno); | ||
| 172 | + | ||
| 173 | + memset (buf, 0, sizeof (long)); | ||
| 174 | + | ||
| 175 | + if (size < sizeof (long)) | ||
| 176 | + collect_register (regcache, regno, buf + sizeof (long) - size); | ||
| 177 | + else | ||
| 178 | + collect_register (regcache, regno, buf); | ||
| 179 | +} | ||
| 180 | + | ||
| 181 | +static void | ||
| 182 | +microblaze_supply_ptrace_register (struct regcache *regcache, | ||
| 183 | + int regno, const char *buf) | ||
| 184 | +{ | ||
| 185 | + int size = register_size (regcache->tdesc, regno); | ||
| 186 | + | ||
| 187 | + if (regno == 0) { | ||
| 188 | + unsigned long regbuf_0 = 0; | ||
| 189 | + /* clobbering r0 so that it is always 0 as enforced by hardware */ | ||
| 190 | + supply_register (regcache, regno, (const char*)®buf_0); | ||
| 191 | + } else { | ||
| 192 | + if (size < sizeof (long)) | ||
| 193 | + supply_register (regcache, regno, buf + sizeof (long) - size); | ||
| 194 | + else | ||
| 195 | + supply_register (regcache, regno, buf); | ||
| 196 | + } | ||
| 197 | +} | ||
| 198 | + | ||
| 199 | +/* Provide only a fill function for the general register set. ps_lgetregs | ||
| 200 | + will use this for NPTL support. */ | ||
| 201 | + | ||
| 202 | +static void microblaze_fill_gregset (struct regcache *regcache, void *buf) | ||
| 203 | +{ | ||
| 204 | + int i; | ||
| 205 | + | ||
| 206 | + for (i = 0; i < 32; i++) | ||
| 207 | + microblaze_collect_ptrace_register (regcache, i, (char *) buf + microblaze_regmap[i]); | ||
| 208 | +} | ||
| 209 | + | ||
| 210 | +static void | ||
| 211 | +microblaze_store_gregset (struct regcache *regcache, const void *buf) | ||
| 212 | +{ | ||
| 213 | + int i; | ||
| 214 | + | ||
| 215 | + for (i = 0; i < 32; i++) | ||
| 216 | + supply_register (regcache, i, (char *) buf + microblaze_regmap[i]); | ||
| 217 | +} | ||
| 218 | + | ||
| 219 | +#endif /* HAVE_PTRACE_GETREGS */ | ||
| 220 | + | ||
| 221 | +static struct regset_info microblaze_regsets[] = { | ||
| 222 | +#ifdef HAVE_PTRACE_GETREGS | ||
| 223 | + { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, microblaze_fill_gregset, microblaze_store_gregset }, | ||
| 224 | + { 0, 0, 0, -1, -1, NULL, NULL }, | ||
| 225 | +#endif /* HAVE_PTRACE_GETREGS */ | ||
| 226 | + { 0, 0, 0, -1, -1, NULL, NULL } | ||
| 227 | +}; | ||
| 228 | + | ||
| 229 | +static struct regsets_info microblaze_regsets_info = | ||
| 230 | + { | ||
| 231 | + microblaze_regsets, /* regsets */ | ||
| 232 | + 0, /* num_regsets */ | ||
| 233 | + NULL, /* disabled_regsets */ | ||
| 234 | + }; | ||
| 235 | + | ||
| 236 | +static struct usrregs_info microblaze_usrregs_info = | ||
| 237 | + { | ||
| 238 | + microblaze_num_regs, | ||
| 239 | + microblaze_regmap, | ||
| 240 | + }; | ||
| 241 | + | ||
| 242 | +static struct regs_info regs_info = | ||
| 243 | + { | ||
| 244 | + NULL, /* regset_bitmap */ | ||
| 245 | + µblaze_usrregs_info, | ||
| 246 | + µblaze_regsets_info | ||
| 247 | + }; | ||
| 248 | + | ||
| 249 | +static const struct regs_info * | ||
| 250 | +microblaze_regs_info (void) | ||
| 251 | +{ | ||
| 252 | + return ®s_info; | ||
| 253 | +} | ||
| 254 | + | ||
| 255 | +static void | ||
| 256 | +microblaze_arch_setup (void) | ||
| 257 | +{ | ||
| 258 | + current_process ()->tdesc = tdesc_microblaze; | ||
| 259 | +} | ||
| 260 | + | ||
| 261 | +struct linux_target_ops the_low_target = { | ||
| 262 | + microblaze_arch_setup, | ||
| 263 | + microblaze_regs_info, | ||
| 264 | + microblaze_cannot_fetch_register, | ||
| 265 | + microblaze_cannot_store_register, | ||
| 266 | + NULL, /* fetch_register */ | ||
| 267 | + microblaze_get_pc, | ||
| 268 | + microblaze_set_pc, | ||
| 269 | + (const unsigned char *) µblaze_breakpoint, | ||
| 270 | + microblaze_breakpoint_len, | ||
| 271 | + microblaze_reinsert_addr, | ||
| 272 | + 0, | ||
| 273 | + microblaze_breakpoint_at, | ||
| 274 | + NULL, | ||
| 275 | + NULL, | ||
| 276 | + NULL, | ||
| 277 | + NULL, | ||
| 278 | + microblaze_collect_ptrace_register, | ||
| 279 | + microblaze_supply_ptrace_register, | ||
| 280 | +}; | ||
| 281 | + | ||
| 282 | +void | ||
| 283 | +initialize_low_arch (void) | ||
| 284 | +{ | ||
| 285 | + init_registers_microblaze (); | ||
| 286 | + | ||
| 287 | + initialize_regsets_info (µblaze_regsets_info); | ||
| 288 | +} | ||
| 289 | \ No newline at end of file | ||
| 290 | diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c | ||
| 291 | index 99fc497..69c333e 100644 | ||
| 292 | --- a/gdb/microblaze-linux-tdep.c | ||
| 293 | +++ b/gdb/microblaze-linux-tdep.c | ||
| 294 | @@ -37,6 +37,22 @@ | ||
| 295 | #include "tramp-frame.h" | ||
| 296 | #include "linux-tdep.h" | ||
| 297 | |||
| 298 | +static int microblaze_debug_flag = 0; | ||
| 299 | + | ||
| 300 | +static void | ||
| 301 | +microblaze_debug (const char *fmt, ...) | ||
| 302 | +{ | ||
| 303 | + if (microblaze_debug_flag) | ||
| 304 | + { | ||
| 305 | + va_list args; | ||
| 306 | + | ||
| 307 | + va_start (args, fmt); | ||
| 308 | + printf_unfiltered ("MICROBLAZE LINUX: "); | ||
| 309 | + vprintf_unfiltered (fmt, args); | ||
| 310 | + va_end (args); | ||
| 311 | + } | ||
| 312 | +} | ||
| 313 | + | ||
| 314 | static int | ||
| 315 | microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, | ||
| 316 | struct bp_target_info *bp_tgt) | ||
| 317 | @@ -46,20 +62,27 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, | ||
| 318 | int val; | ||
| 319 | int bplen; | ||
| 320 | gdb_byte old_contents[BREAKPOINT_MAX]; | ||
| 321 | + struct cleanup *cleanup; | ||
| 322 | |||
| 323 | /* Determine appropriate breakpoint contents and size for this address. */ | ||
| 324 | bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen); | ||
| 325 | if (bp == NULL) | ||
| 326 | error (_("Software breakpoints not implemented for this target.")); | ||
| 327 | |||
| 328 | + /* Make sure we see the memory breakpoints. */ | ||
| 329 | + cleanup = make_show_memory_breakpoints_cleanup (1); | ||
| 330 | val = target_read_memory (addr, old_contents, bplen); | ||
| 331 | |||
| 332 | /* If our breakpoint is no longer at the address, this means that the | ||
| 333 | program modified the code on us, so it is wrong to put back the | ||
| 334 | old value. */ | ||
| 335 | if (val == 0 && memcmp (bp, old_contents, bplen) == 0) | ||
| 336 | - val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen); | ||
| 337 | + { | ||
| 338 | + val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen); | ||
| 339 | + microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr); | ||
| 340 | + } | ||
| 341 | |||
| 342 | + do_cleanups (cleanup); | ||
| 343 | return val; | ||
| 344 | } | ||
| 345 | |||
| 346 | @@ -135,6 +158,11 @@ microblaze_linux_init_abi (struct gdbarch_info info, | ||
| 347 | /* Trampolines. */ | ||
| 348 | tramp_frame_prepend_unwinder (gdbarch, | ||
| 349 | µblaze_linux_sighandler_tramp_frame); | ||
| 350 | + | ||
| 351 | + /* Enable TLS support. */ | ||
| 352 | + set_gdbarch_fetch_tls_load_module_address (gdbarch, | ||
| 353 | + svr4_fetch_objfile_link_map); | ||
| 354 | + | ||
| 355 | } | ||
| 356 | |||
| 357 | /* -Wmissing-prototypes */ | ||
| 358 | diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c | ||
| 359 | index dcf556f..079d34e 100644 | ||
| 360 | --- a/gdb/microblaze-tdep.c | ||
| 361 | +++ b/gdb/microblaze-tdep.c | ||
| 362 | @@ -157,6 +157,39 @@ microblaze_push_dummy_call (struct gdbarch *gdbarch, struct value *function, | ||
| 363 | return sp; | ||
| 364 | } | ||
| 365 | |||
| 366 | +static int | ||
| 367 | +microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, | ||
| 368 | + struct bp_target_info *bp_tgt) | ||
| 369 | +{ | ||
| 370 | + CORE_ADDR addr = bp_tgt->placed_address; | ||
| 371 | + const unsigned char *bp; | ||
| 372 | + int val; | ||
| 373 | + int bplen; | ||
| 374 | + gdb_byte old_contents[BREAKPOINT_MAX]; | ||
| 375 | + struct cleanup *cleanup; | ||
| 376 | + | ||
| 377 | + /* Determine appropriate breakpoint contents and size for this address. */ | ||
| 378 | + bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen); | ||
| 379 | + if (bp == NULL) | ||
| 380 | + error (_("Software breakpoints not implemented for this target.")); | ||
| 381 | + | ||
| 382 | + /* Make sure we see the memory breakpoints. */ | ||
| 383 | + cleanup = make_show_memory_breakpoints_cleanup (1); | ||
| 384 | + val = target_read_memory (addr, old_contents, bplen); | ||
| 385 | + | ||
| 386 | + /* If our breakpoint is no longer at the address, this means that the | ||
| 387 | + program modified the code on us, so it is wrong to put back the | ||
| 388 | + old value. */ | ||
| 389 | + if (val == 0 && memcmp (bp, old_contents, bplen) == 0) | ||
| 390 | + { | ||
| 391 | + val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen); | ||
| 392 | + microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr); | ||
| 393 | + } | ||
| 394 | + | ||
| 395 | + do_cleanups (cleanup); | ||
| 396 | + return val; | ||
| 397 | +} | ||
| 398 | + | ||
| 399 | static const gdb_byte * | ||
| 400 | microblaze_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, | ||
| 401 | int *len) | ||
| 402 | @@ -707,6 +740,8 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | ||
| 403 | /* Stack grows downward. */ | ||
| 404 | set_gdbarch_inner_than (gdbarch, core_addr_lessthan); | ||
| 405 | |||
| 406 | + set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint); | ||
| 407 | + | ||
| 408 | set_gdbarch_breakpoint_from_pc (gdbarch, microblaze_breakpoint_from_pc); | ||
| 409 | |||
| 410 | set_gdbarch_frame_args_skip (gdbarch, 8); | ||
| 411 | diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h | ||
| 412 | index ff4515e..9fdbda7 100644 | ||
| 413 | --- a/gdb/microblaze-tdep.h | ||
| 414 | +++ b/gdb/microblaze-tdep.h | ||
| 415 | @@ -115,6 +115,7 @@ enum microblaze_regnum | ||
| 416 | |||
| 417 | /* MICROBLAZE_BREAKPOINT defines the breakpoint that should be used. | ||
| 418 | Only used for native debugging. */ | ||
| 419 | -#define MICROBLAZE_BREAKPOINT {0xb9, 0xcc, 0x00, 0x60} | ||
| 420 | +#define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18} | ||
| 421 | +#define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba} | ||
| 422 | |||
| 423 | #endif /* microblaze-tdep.h */ | ||
| 424 | diff --git a/gdb/regformats/reg-microblaze.dat b/gdb/regformats/reg-microblaze.dat | ||
| 425 | new file mode 100644 | ||
| 426 | index 0000000..a5dd0a0 | ||
| 427 | --- /dev/null | ||
| 428 | +++ b/gdb/regformats/reg-microblaze.dat | ||
| 429 | @@ -0,0 +1,39 @@ | ||
| 430 | +name:microblaze | ||
| 431 | +expedite:r1,pc | ||
| 432 | +32:r0 | ||
| 433 | +32:r1 | ||
| 434 | +32:r2 | ||
| 435 | +32:r3 | ||
| 436 | +32:r4 | ||
| 437 | +32:r5 | ||
| 438 | +32:r6 | ||
| 439 | +32:r7 | ||
| 440 | +32:r8 | ||
| 441 | +32:r9 | ||
| 442 | +32:r10 | ||
| 443 | +32:r11 | ||
| 444 | +32:r12 | ||
| 445 | +32:r13 | ||
| 446 | +32:r14 | ||
| 447 | +32:r15 | ||
| 448 | +32:r16 | ||
| 449 | +32:r17 | ||
| 450 | +32:r18 | ||
| 451 | +32:r19 | ||
| 452 | +32:r20 | ||
| 453 | +32:r21 | ||
| 454 | +32:r22 | ||
| 455 | +32:r23 | ||
| 456 | +32:r24 | ||
| 457 | +32:r25 | ||
| 458 | +32:r26 | ||
| 459 | +32:r27 | ||
| 460 | +32:r28 | ||
| 461 | +32:r29 | ||
| 462 | +32:r30 | ||
| 463 | +32:r31 | ||
| 464 | +32:pc | ||
| 465 | +32:msr | ||
| 466 | +32:ear | ||
| 467 | +32:esr | ||
| 468 | +32:fsr | ||
| 469 | -- | ||
| 470 | 1.7.9.5 | ||
| 471 | |||
diff --git a/recipes-devtools/gdb/files/0002-Initial-port-of-core-reading-support.patch b/recipes-devtools/gdb/files/0002-Initial-port-of-core-reading-support.patch new file mode 100644 index 00000000..f0020ed4 --- /dev/null +++ b/recipes-devtools/gdb/files/0002-Initial-port-of-core-reading-support.patch | |||
| @@ -0,0 +1,378 @@ | |||
| 1 | From: David Holsgrove <david.holsgrove@petalogix.com> | ||
| 2 | Date: Fri, 18 May 2012 11:49:50 +1000 | ||
| 3 | Subject: Initial port of core reading support | ||
| 4 | |||
| 5 | Added support for reading notes in linux core dumps | ||
| 6 | Support for reading of PRSTATUS and PSINFO information for rebuilding | ||
| 7 | ".reg" sections of core dumps at run time. | ||
| 8 | |||
| 9 | Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com> | ||
| 10 | Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com> | ||
| 11 | Upstream-Status: Pending | ||
| 12 | --- | ||
| 13 | bfd/elf32-microblaze.c | 64 ++++++++++++++++++++++++++++++ | ||
| 14 | gdb/configure.tgt | 2 +- | ||
| 15 | gdb/microblaze-linux-tdep.c | 56 +++++++++++++++++++++++++++ | ||
| 16 | gdb/microblaze-tdep.c | 90 +++++++++++++++++++++++++++++++++++++++++++ | ||
| 17 | gdb/microblaze-tdep.h | 28 ++++++++++++++ | ||
| 18 | 5 files changed, 239 insertions(+), 1 deletion(-) | ||
| 19 | |||
| 20 | diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c | ||
| 21 | index 8aafe72..365546c 100644 | ||
| 22 | --- a/bfd/elf32-microblaze.c | ||
| 23 | +++ b/bfd/elf32-microblaze.c | ||
| 24 | @@ -668,6 +668,67 @@ 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 bfd_boolean | ||
| 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 bfd_boolean | ||
| 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 | @@ -3499,4 +3560,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd, | ||
| 93 | #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections | ||
| 94 | #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook | ||
| 95 | |||
| 96 | +#define elf_backend_grok_prstatus microblaze_elf_grok_prstatus | ||
| 97 | +#define elf_backend_grok_psinfo microblaze_elf_grok_psinfo | ||
| 98 | + | ||
| 99 | #include "elf32-target.h" | ||
| 100 | diff --git a/gdb/configure.tgt b/gdb/configure.tgt | ||
| 101 | index 720d3d3..1285aac 100644 | ||
| 102 | --- a/gdb/configure.tgt | ||
| 103 | +++ b/gdb/configure.tgt | ||
| 104 | @@ -339,7 +339,7 @@ mep-*-*) | ||
| 105 | |||
| 106 | microblaze*-linux-*|microblaze*-*-linux*) | ||
| 107 | # Target: Xilinx MicroBlaze running Linux | ||
| 108 | - gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o microblaze-rom.o \ | ||
| 109 | + gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o microblaze-rom.o glibc-tdep.o \ | ||
| 110 | monitor.o dsrec.o solib-svr4.o symfile-mem.o linux-tdep.o" | ||
| 111 | gdb_sim=../sim/microblaze/libsim.a | ||
| 112 | ;; | ||
| 113 | diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c | ||
| 114 | index 69c333e..9dc4f85 100644 | ||
| 115 | --- a/gdb/microblaze-linux-tdep.c | ||
| 116 | +++ b/gdb/microblaze-linux-tdep.c | ||
| 117 | @@ -32,6 +32,7 @@ | ||
| 118 | #include "regset.h" | ||
| 119 | #include "solib-svr4.h" | ||
| 120 | #include "microblaze-tdep.h" | ||
| 121 | +#include "glibc-tdep.h" | ||
| 122 | #include "trad-frame.h" | ||
| 123 | #include "frame-unwind.h" | ||
| 124 | #include "tramp-frame.h" | ||
| 125 | @@ -139,6 +140,43 @@ static struct tramp_frame microblaze_linux_sighandler_tramp_frame = | ||
| 126 | microblaze_linux_sighandler_cache_init | ||
| 127 | }; | ||
| 128 | |||
| 129 | +const struct microblaze_gregset microblaze_linux_core_gregset; | ||
| 130 | + | ||
| 131 | +static void | ||
| 132 | +microblaze_linux_supply_core_gregset (const struct regset *regset, | ||
| 133 | + struct regcache *regcache, | ||
| 134 | + int regnum, const void *gregs, size_t len) | ||
| 135 | +{ | ||
| 136 | + microblaze_supply_gregset (µblaze_linux_core_gregset, regcache, | ||
| 137 | + regnum, gregs); | ||
| 138 | +} | ||
| 139 | + | ||
| 140 | +static void | ||
| 141 | +microblaze_linux_collect_core_gregset (const struct regset *regset, | ||
| 142 | + const struct regcache *regcache, | ||
| 143 | + int regnum, void *gregs, size_t len) | ||
| 144 | +{ | ||
| 145 | + microblaze_collect_gregset (µblaze_linux_core_gregset, regcache, | ||
| 146 | + regnum, gregs); | ||
| 147 | +} | ||
| 148 | + | ||
| 149 | +static void | ||
| 150 | +microblaze_linux_supply_core_fpregset (const struct regset *regset, | ||
| 151 | + struct regcache *regcache, | ||
| 152 | + int regnum, const void *fpregs, size_t len) | ||
| 153 | +{ | ||
| 154 | + /* FIXME. */ | ||
| 155 | + microblaze_supply_fpregset (regcache, regnum, fpregs); | ||
| 156 | +} | ||
| 157 | + | ||
| 158 | +static void | ||
| 159 | +microblaze_linux_collect_core_fpregset (const struct regset *regset, | ||
| 160 | + const struct regcache *regcache, | ||
| 161 | + int regnum, void *fpregs, size_t len) | ||
| 162 | +{ | ||
| 163 | + /* FIXME. */ | ||
| 164 | + microblaze_collect_fpregset (regcache, regnum, fpregs); | ||
| 165 | +} | ||
| 166 | |||
| 167 | static void | ||
| 168 | microblaze_linux_init_abi (struct gdbarch_info info, | ||
| 169 | @@ -146,6 +184,10 @@ microblaze_linux_init_abi (struct gdbarch_info info, | ||
| 170 | { | ||
| 171 | struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
| 172 | |||
| 173 | + tdep->gregset = regset_alloc (gdbarch, microblaze_linux_supply_core_gregset, | ||
| 174 | + microblaze_linux_collect_core_gregset); | ||
| 175 | + tdep->sizeof_gregset = 200; | ||
| 176 | + | ||
| 177 | linux_init_abi (info, gdbarch); | ||
| 178 | |||
| 179 | set_gdbarch_memory_remove_breakpoint (gdbarch, | ||
| 180 | @@ -159,6 +201,20 @@ microblaze_linux_init_abi (struct gdbarch_info info, | ||
| 181 | tramp_frame_prepend_unwinder (gdbarch, | ||
| 182 | µblaze_linux_sighandler_tramp_frame); | ||
| 183 | |||
| 184 | + /* BFD target for core files. */ | ||
| 185 | + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) | ||
| 186 | + set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze"); | ||
| 187 | + else | ||
| 188 | + set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel"); | ||
| 189 | + | ||
| 190 | + | ||
| 191 | + /* Shared library handling. */ | ||
| 192 | + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); | ||
| 193 | + set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); | ||
| 194 | + | ||
| 195 | + set_gdbarch_regset_from_core_section (gdbarch, | ||
| 196 | + microblaze_regset_from_core_section); | ||
| 197 | + | ||
| 198 | /* Enable TLS support. */ | ||
| 199 | set_gdbarch_fetch_tls_load_module_address (gdbarch, | ||
| 200 | svr4_fetch_objfile_link_map); | ||
| 201 | diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c | ||
| 202 | index 079d34e..cfc227d 100644 | ||
| 203 | --- a/gdb/microblaze-tdep.c | ||
| 204 | +++ b/gdb/microblaze-tdep.c | ||
| 205 | @@ -146,6 +146,14 @@ microblaze_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, | ||
| 206 | return sp; | ||
| 207 | } | ||
| 208 | |||
| 209 | +static CORE_ADDR | ||
| 210 | +microblaze_store_arguments (struct regcache *regcache, int nargs, | ||
| 211 | + struct value **args, CORE_ADDR sp, | ||
| 212 | + int struct_return, CORE_ADDR struct_addr) | ||
| 213 | +{ | ||
| 214 | + error (_("store_arguments not implemented")); | ||
| 215 | + return sp; | ||
| 216 | +} | ||
| 217 | |||
| 218 | static CORE_ADDR | ||
| 219 | microblaze_push_dummy_call (struct gdbarch *gdbarch, struct value *function, | ||
| 220 | @@ -570,6 +578,12 @@ microblaze_frame_base_address (struct frame_info *next_frame, | ||
| 221 | return cache->base; | ||
| 222 | } | ||
| 223 | |||
| 224 | +static const struct frame_unwind * | ||
| 225 | +microblaze_frame_sniffer (struct frame_info *next_frame) | ||
| 226 | +{ | ||
| 227 | + return µblaze_frame_unwind; | ||
| 228 | +} | ||
| 229 | + | ||
| 230 | static const struct frame_base microblaze_frame_base = | ||
| 231 | { | ||
| 232 | µblaze_frame_unwind, | ||
| 233 | @@ -698,6 +712,70 @@ microblaze_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg) | ||
| 234 | return dwarf2_to_reg_map[reg]; | ||
| 235 | } | ||
| 236 | |||
| 237 | + | ||
| 238 | +void | ||
| 239 | +microblaze_supply_gregset (const struct microblaze_gregset *gregset, | ||
| 240 | + struct regcache *regcache, | ||
| 241 | + int regnum, const void *gregs) | ||
| 242 | +{ | ||
| 243 | + unsigned int *regs = gregs; | ||
| 244 | + if (regnum >= 0) | ||
| 245 | + regcache_raw_supply (regcache, regnum, regs + regnum); | ||
| 246 | + | ||
| 247 | + if (regnum == -1) { | ||
| 248 | + int i; | ||
| 249 | + | ||
| 250 | + for (i = 0; i < 50; i++) { | ||
| 251 | + regcache_raw_supply (regcache, i, regs + i); | ||
| 252 | + } | ||
| 253 | + } | ||
| 254 | +} | ||
| 255 | + | ||
| 256 | + | ||
| 257 | +void | ||
| 258 | +microblaze_collect_gregset (const struct microblaze_gregset *gregset, | ||
| 259 | + const struct regcache *regcache, | ||
| 260 | + int regnum, void *gregs) | ||
| 261 | +{ | ||
| 262 | + /* FIXME. */ | ||
| 263 | +} | ||
| 264 | + | ||
| 265 | +void | ||
| 266 | +microblaze_supply_fpregset (struct regcache *regcache, | ||
| 267 | + int regnum, const void *fpregs) | ||
| 268 | +{ | ||
| 269 | + /* FIXME. */ | ||
| 270 | +} | ||
| 271 | + | ||
| 272 | +void | ||
| 273 | +microblaze_collect_fpregset (const struct regcache *regcache, | ||
| 274 | + int regnum, void *fpregs) | ||
| 275 | +{ | ||
| 276 | + /* FIXME. */ | ||
| 277 | +} | ||
| 278 | + | ||
| 279 | + | ||
| 280 | +/* Return the appropriate register set for the core section identified | ||
| 281 | + by SECT_NAME and SECT_SIZE. */ | ||
| 282 | + | ||
| 283 | +const struct regset * | ||
| 284 | +microblaze_regset_from_core_section (struct gdbarch *gdbarch, | ||
| 285 | + const char *sect_name, size_t sect_size) | ||
| 286 | +{ | ||
| 287 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
| 288 | + | ||
| 289 | + microblaze_debug ("microblaze_regset_from_core_section, sect_name = %s\n", sect_name); | ||
| 290 | + | ||
| 291 | + if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset) | ||
| 292 | + return tdep->gregset; | ||
| 293 | + | ||
| 294 | + if (strcmp (sect_name, ".reg2") == 0 && sect_size >= tdep->sizeof_fpregset) | ||
| 295 | + return tdep->fpregset; | ||
| 296 | + | ||
| 297 | + microblaze_debug ("microblaze_regset_from_core_section returning null :-( \n"); | ||
| 298 | + return NULL; | ||
| 299 | +} | ||
| 300 | + | ||
| 301 | static struct gdbarch * | ||
| 302 | microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | ||
| 303 | { | ||
| 304 | @@ -713,6 +791,11 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | ||
| 305 | tdep = XMALLOC (struct gdbarch_tdep); | ||
| 306 | gdbarch = gdbarch_alloc (&info, tdep); | ||
| 307 | |||
| 308 | + tdep->gregset = NULL; | ||
| 309 | + tdep->sizeof_gregset = 0; | ||
| 310 | + tdep->fpregset = NULL; | ||
| 311 | + tdep->sizeof_fpregset = 0; | ||
| 312 | + | ||
| 313 | set_gdbarch_long_double_bit (gdbarch, 128); | ||
| 314 | |||
| 315 | set_gdbarch_num_regs (gdbarch, MICROBLAZE_NUM_REGS); | ||
| 316 | @@ -761,6 +844,13 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | ||
| 317 | dwarf2_append_unwinders (gdbarch); | ||
| 318 | frame_unwind_append_unwinder (gdbarch, µblaze_frame_unwind); | ||
| 319 | frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer); | ||
| 320 | + //frame_base_append_sniffer (gdbarch, microblaze_frame_sniffer); | ||
| 321 | + | ||
| 322 | + /* If we have register sets, enable the generic core file support. */ | ||
| 323 | + if (tdep->gregset) { | ||
| 324 | + set_gdbarch_regset_from_core_section (gdbarch, | ||
| 325 | + microblaze_regset_from_core_section); | ||
| 326 | + } | ||
| 327 | |||
| 328 | return gdbarch; | ||
| 329 | } | ||
| 330 | diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h | ||
| 331 | index 9fdbda7..7de4463 100644 | ||
| 332 | --- a/gdb/microblaze-tdep.h | ||
| 333 | +++ b/gdb/microblaze-tdep.h | ||
| 334 | @@ -22,8 +22,22 @@ | ||
| 335 | |||
| 336 | |||
| 337 | /* Microblaze architecture-specific information. */ | ||
| 338 | +struct microblaze_gregset | ||
| 339 | +{ | ||
| 340 | + unsigned int gregs[32]; | ||
| 341 | + unsigned int fpregs[32]; | ||
| 342 | + unsigned int pregs[16]; | ||
| 343 | +}; | ||
| 344 | + | ||
| 345 | struct gdbarch_tdep | ||
| 346 | { | ||
| 347 | + int dummy; // declare something. | ||
| 348 | + | ||
| 349 | + /* Register sets. */ | ||
| 350 | + struct regset *gregset; | ||
| 351 | + size_t sizeof_gregset; | ||
| 352 | + struct regset *fpregset; | ||
| 353 | + size_t sizeof_fpregset; | ||
| 354 | }; | ||
| 355 | |||
| 356 | struct microblaze_frame_cache | ||
| 357 | @@ -118,4 +132,18 @@ enum microblaze_regnum | ||
| 358 | #define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18} | ||
| 359 | #define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba} | ||
| 360 | |||
| 361 | +extern void microblaze_supply_gregset (const struct microblaze_gregset *gregset, | ||
| 362 | + struct regcache *regcache, | ||
| 363 | + int regnum, const void *gregs); | ||
| 364 | +extern void microblaze_collect_gregset (const struct microblaze_gregset *gregset, | ||
| 365 | + const struct regcache *regcache, | ||
| 366 | + int regnum, void *gregs); | ||
| 367 | +extern void microblaze_supply_fpregset (struct regcache *regcache, | ||
| 368 | + int regnum, const void *fpregs); | ||
| 369 | +extern void microblaze_collect_fpregset (const struct regcache *regcache, | ||
| 370 | + int regnum, void *fpregs); | ||
| 371 | + | ||
| 372 | +extern const struct regset * microblaze_regset_from_core_section (struct gdbarch *gdbarch, | ||
| 373 | + const char *sect_name, size_t sect_size); | ||
| 374 | + | ||
| 375 | #endif /* microblaze-tdep.h */ | ||
| 376 | -- | ||
| 377 | 1.7.9.5 | ||
| 378 | |||
diff --git a/recipes-devtools/gdb/files/0003-Initial-support-for-native-gdb.patch b/recipes-devtools/gdb/files/0003-Initial-support-for-native-gdb.patch new file mode 100644 index 00000000..8281352e --- /dev/null +++ b/recipes-devtools/gdb/files/0003-Initial-support-for-native-gdb.patch | |||
| @@ -0,0 +1,494 @@ | |||
| 1 | From: David Holsgrove <david.holsgrove@petalogix.com> | ||
| 2 | Date: Fri, 20 Jul 2012 15:18:35 +1000 | ||
| 3 | Subject: Initial support for native gdb | ||
| 4 | |||
| 5 | microblaze: Follow PPC method of getting setting registers | ||
| 6 | using PTRACE PEEK/POKE | ||
| 7 | |||
| 8 | Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com> | ||
| 9 | Upstream-Status: Pending | ||
| 10 | --- | ||
| 11 | gdb/Makefile.in | 4 +- | ||
| 12 | gdb/config/microblaze/linux.mh | 9 + | ||
| 13 | gdb/microblaze-linux-nat.c | 431 ++++++++++++++++++++++++++++++++++++++++ | ||
| 14 | 3 files changed, 442 insertions(+), 2 deletions(-) | ||
| 15 | create mode 100644 gdb/config/microblaze/linux.mh | ||
| 16 | create mode 100644 gdb/microblaze-linux-nat.c | ||
| 17 | |||
| 18 | diff --git a/gdb/Makefile.in b/gdb/Makefile.in | ||
| 19 | index 3fd5425..e5781f2 100644 | ||
| 20 | --- a/gdb/Makefile.in | ||
| 21 | +++ b/gdb/Makefile.in | ||
| 22 | @@ -821,7 +821,7 @@ config/rs6000/nm-rs6000.h top.h bsd-kvm.h gdb-stabs.h reggroups.h \ | ||
| 23 | annotate.h sim-regno.h dictionary.h dfp.h main.h frame-unwind.h \ | ||
| 24 | remote-fileio.h i386-linux-tdep.h vax-tdep.h objc-lang.h \ | ||
| 25 | sentinel-frame.h bcache.h symfile.h windows-tdep.h linux-tdep.h \ | ||
| 26 | -gdb_usleep.h jit.h xml-syscall.h microblaze-tdep.h \ | ||
| 27 | +gdb_usleep.h jit.h xml-syscall.h microblaze-tdep.h microblaze-linux-tdep.h \ | ||
| 28 | psymtab.h psympriv.h progspace.h bfin-tdep.h ia64-hpux-tdep.h \ | ||
| 29 | amd64-darwin-tdep.h charset-list.h \ | ||
| 30 | config/djgpp/langinfo.h config/djgpp/nl_types.h darwin-nat.h \ | ||
| 31 | @@ -1481,7 +1481,7 @@ ALLDEPFILES = \ | ||
| 32 | m68kbsd-nat.c m68kbsd-tdep.c \ | ||
| 33 | m68klinux-nat.c m68klinux-tdep.c \ | ||
| 34 | m88k-tdep.c m88kbsd-nat.c \ | ||
| 35 | - microblaze-tdep.c microblaze-linux-tdep.c \ | ||
| 36 | + microblaze-tdep.c microblaze-linux-nat.c microblaze-linux-tdep.c \ | ||
| 37 | mingw-hdep.c \ | ||
| 38 | mips-linux-nat.c mips-linux-tdep.c \ | ||
| 39 | mips-irix-tdep.c \ | ||
| 40 | diff --git a/gdb/config/microblaze/linux.mh b/gdb/config/microblaze/linux.mh | ||
| 41 | new file mode 100644 | ||
| 42 | index 0000000..a4eaf54 | ||
| 43 | --- /dev/null | ||
| 44 | +++ b/gdb/config/microblaze/linux.mh | ||
| 45 | @@ -0,0 +1,9 @@ | ||
| 46 | +# Host: Microblaze, running Linux | ||
| 47 | + | ||
| 48 | +NAT_FILE= config/nm-linux.h | ||
| 49 | +NATDEPFILES= inf-ptrace.o fork-child.o \ | ||
| 50 | + microblaze-linux-nat.o proc-service.o linux-thread-db.o \ | ||
| 51 | + linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o | ||
| 52 | +NAT_CDEPS = $(srcdir)/proc-service.list | ||
| 53 | + | ||
| 54 | +LOADLIBES = -ldl $(RDYNAMIC) | ||
| 55 | diff --git a/gdb/microblaze-linux-nat.c b/gdb/microblaze-linux-nat.c | ||
| 56 | new file mode 100644 | ||
| 57 | index 0000000..e9b8c9c | ||
| 58 | --- /dev/null | ||
| 59 | +++ b/gdb/microblaze-linux-nat.c | ||
| 60 | @@ -0,0 +1,431 @@ | ||
| 61 | +/* Microblaze GNU/Linux native support. | ||
| 62 | + | ||
| 63 | + Copyright (C) 1988-1989, 1991-1992, 1994, 1996, 2000-2012 Free | ||
| 64 | + Software Foundation, Inc. | ||
| 65 | + | ||
| 66 | + This file is part of GDB. | ||
| 67 | + | ||
| 68 | + This program is free software; you can redistribute it and/or modify | ||
| 69 | + it under the terms of the GNU General Public License as published by | ||
| 70 | + the Free Software Foundation; either version 3 of the License, or | ||
| 71 | + (at your option) any later version. | ||
| 72 | + | ||
| 73 | + This program is distributed in the hope that it will be useful, | ||
| 74 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 75 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 76 | + GNU General Public License for more details. | ||
| 77 | + | ||
| 78 | + You should have received a copy of the GNU General Public License | ||
| 79 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 80 | + | ||
| 81 | +#include "defs.h" | ||
| 82 | +#include "arch-utils.h" | ||
| 83 | +#include "dis-asm.h" | ||
| 84 | +#include "frame.h" | ||
| 85 | +#include "trad-frame.h" | ||
| 86 | +#include "symtab.h" | ||
| 87 | +#include "value.h" | ||
| 88 | +#include "gdbcmd.h" | ||
| 89 | +#include "breakpoint.h" | ||
| 90 | +#include "inferior.h" | ||
| 91 | +#include "regcache.h" | ||
| 92 | +#include "target.h" | ||
| 93 | +#include "frame.h" | ||
| 94 | +#include "frame-base.h" | ||
| 95 | +#include "frame-unwind.h" | ||
| 96 | +#include "dwarf2-frame.h" | ||
| 97 | +#include "osabi.h" | ||
| 98 | + | ||
| 99 | +#include "gdb_assert.h" | ||
| 100 | +#include "gdb_string.h" | ||
| 101 | +#include "target-descriptions.h" | ||
| 102 | +#include "opcodes/microblaze-opcm.h" | ||
| 103 | +#include "opcodes/microblaze-dis.h" | ||
| 104 | + | ||
| 105 | +#include "linux-nat.h" | ||
| 106 | +#include "target-descriptions.h" | ||
| 107 | + | ||
| 108 | +#include <sys/user.h> | ||
| 109 | +#include <sys/utsname.h> | ||
| 110 | +#include <sys/procfs.h> | ||
| 111 | +#include <sys/ptrace.h> | ||
| 112 | + | ||
| 113 | +/* Prototypes for supply_gregset etc. */ | ||
| 114 | +#include "gregset.h" | ||
| 115 | + | ||
| 116 | +#include "microblaze-tdep.h" | ||
| 117 | + | ||
| 118 | +#include <elf/common.h> | ||
| 119 | +#include "auxv.h" | ||
| 120 | + | ||
| 121 | +/* Defines ps_err_e, struct ps_prochandle. */ | ||
| 122 | +#include "gdb_proc_service.h" | ||
| 123 | + | ||
| 124 | +/* On GNU/Linux, threads are implemented as pseudo-processes, in which | ||
| 125 | + case we may be tracing more than one process at a time. In that | ||
| 126 | + case, inferior_ptid will contain the main process ID and the | ||
| 127 | + individual thread (process) ID. get_thread_id () is used to get | ||
| 128 | + the thread id if it's available, and the process id otherwise. */ | ||
| 129 | + | ||
| 130 | +int | ||
| 131 | +get_thread_id (ptid_t ptid) | ||
| 132 | +{ | ||
| 133 | + int tid = TIDGET (ptid); | ||
| 134 | + if (0 == tid) | ||
| 135 | + tid = PIDGET (ptid); | ||
| 136 | + return tid; | ||
| 137 | +} | ||
| 138 | + | ||
| 139 | +#define GET_THREAD_ID(PTID) get_thread_id (PTID) | ||
| 140 | + | ||
| 141 | +/* Non-zero if our kernel may support the PTRACE_GETREGS and | ||
| 142 | + PTRACE_SETREGS requests, for reading and writing the | ||
| 143 | + general-purpose registers. Zero if we've tried one of | ||
| 144 | + them and gotten an error. */ | ||
| 145 | +int have_ptrace_getsetregs = 1; | ||
| 146 | + | ||
| 147 | +static int | ||
| 148 | +microblaze_register_u_addr (struct gdbarch *gdbarch, int regno) | ||
| 149 | +{ | ||
| 150 | + int u_addr = -1; | ||
| 151 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
| 152 | + /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace | ||
| 153 | + interface, and not the wordsize of the program's ABI. */ | ||
| 154 | + int wordsize = sizeof (long); | ||
| 155 | + | ||
| 156 | + /* General purpose registers occupy 1 slot each in the buffer. */ | ||
| 157 | + if (regno >= MICROBLAZE_R0_REGNUM | ||
| 158 | + && regno <= MICROBLAZE_FSR_REGNUM) | ||
| 159 | + u_addr = (regno * wordsize); | ||
| 160 | + | ||
| 161 | + return u_addr; | ||
| 162 | +} | ||
| 163 | + | ||
| 164 | + | ||
| 165 | +static void | ||
| 166 | +fetch_register (struct regcache *regcache, int tid, int regno) | ||
| 167 | +{ | ||
| 168 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
| 169 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
| 170 | + /* This isn't really an address. But ptrace thinks of it as one. */ | ||
| 171 | + CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno); | ||
| 172 | + int bytes_transferred; | ||
| 173 | + unsigned int offset; /* Offset of registers within the u area. */ | ||
| 174 | + char buf[MAX_REGISTER_SIZE]; | ||
| 175 | + | ||
| 176 | + if (regaddr == -1) | ||
| 177 | + { | ||
| 178 | + memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */ | ||
| 179 | + regcache_raw_supply (regcache, regno, buf); | ||
| 180 | + return; | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + /* Read the raw register using sizeof(long) sized chunks. On a | ||
| 184 | + 32-bit platform, 64-bit floating-point registers will require two | ||
| 185 | + transfers. */ | ||
| 186 | + for (bytes_transferred = 0; | ||
| 187 | + bytes_transferred < register_size (gdbarch, regno); | ||
| 188 | + bytes_transferred += sizeof (long)) | ||
| 189 | + { | ||
| 190 | + long l; | ||
| 191 | + | ||
| 192 | + errno = 0; | ||
| 193 | + l = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0); | ||
| 194 | + regaddr += sizeof (long); | ||
| 195 | + if (errno != 0) | ||
| 196 | + { | ||
| 197 | + char message[128]; | ||
| 198 | + sprintf (message, "reading register %s (#%d)", | ||
| 199 | + gdbarch_register_name (gdbarch, regno), regno); | ||
| 200 | + perror_with_name (message); | ||
| 201 | + } | ||
| 202 | + memcpy (&buf[bytes_transferred], &l, sizeof (l)); | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + /* Now supply the register. Keep in mind that the regcache's idea | ||
| 206 | + of the register's size may not be a multiple of sizeof | ||
| 207 | + (long). */ | ||
| 208 | + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) | ||
| 209 | + { | ||
| 210 | + /* Little-endian values are always found at the left end of the | ||
| 211 | + bytes transferred. */ | ||
| 212 | + regcache_raw_supply (regcache, regno, buf); | ||
| 213 | + } | ||
| 214 | + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) | ||
| 215 | + { | ||
| 216 | + /* Big-endian values are found at the right end of the bytes | ||
| 217 | + transferred. */ | ||
| 218 | + size_t padding = (bytes_transferred - register_size (gdbarch, regno)); | ||
| 219 | + regcache_raw_supply (regcache, regno, buf + padding); | ||
| 220 | + } | ||
| 221 | + else | ||
| 222 | + internal_error (__FILE__, __LINE__, | ||
| 223 | + _("fetch_register: unexpected byte order: %d"), | ||
| 224 | + gdbarch_byte_order (gdbarch)); | ||
| 225 | +} | ||
| 226 | + | ||
| 227 | +/* This function actually issues the request to ptrace, telling | ||
| 228 | + it to get all general-purpose registers and put them into the | ||
| 229 | + specified regset. | ||
| 230 | + | ||
| 231 | + If the ptrace request does not exist, this function returns 0 | ||
| 232 | + and properly sets the have_ptrace_* flag. If the request fails, | ||
| 233 | + this function calls perror_with_name. Otherwise, if the request | ||
| 234 | + succeeds, then the regcache gets filled and 1 is returned. */ | ||
| 235 | +static int | ||
| 236 | +fetch_all_gp_regs (struct regcache *regcache, int tid) | ||
| 237 | +{ | ||
| 238 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
| 239 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
| 240 | + gdb_gregset_t gregset; | ||
| 241 | + | ||
| 242 | + if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0) | ||
| 243 | + { | ||
| 244 | + if (errno == EIO) | ||
| 245 | + { | ||
| 246 | + have_ptrace_getsetregs = 0; | ||
| 247 | + return 0; | ||
| 248 | + } | ||
| 249 | + perror_with_name (_("Couldn't get general-purpose registers.")); | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + supply_gregset (regcache, (const gdb_gregset_t *) &gregset); | ||
| 253 | + | ||
| 254 | + return 1; | ||
| 255 | +} | ||
| 256 | + | ||
| 257 | + | ||
| 258 | +/* This is a wrapper for the fetch_all_gp_regs function. It is | ||
| 259 | + responsible for verifying if this target has the ptrace request | ||
| 260 | + that can be used to fetch all general-purpose registers at one | ||
| 261 | + shot. If it doesn't, then we should fetch them using the | ||
| 262 | + old-fashioned way, which is to iterate over the registers and | ||
| 263 | + request them one by one. */ | ||
| 264 | +static void | ||
| 265 | +fetch_gp_regs (struct regcache *regcache, int tid) | ||
| 266 | +{ | ||
| 267 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
| 268 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
| 269 | + int i; | ||
| 270 | + | ||
| 271 | + if (have_ptrace_getsetregs) | ||
| 272 | + if (fetch_all_gp_regs (regcache, tid)) | ||
| 273 | + return; | ||
| 274 | + | ||
| 275 | + /* If we've hit this point, it doesn't really matter which | ||
| 276 | + architecture we are using. We just need to read the | ||
| 277 | + registers in the "old-fashioned way". */ | ||
| 278 | + for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++) | ||
| 279 | + fetch_register (regcache, tid, i); | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | + | ||
| 283 | +static void | ||
| 284 | +store_register (const struct regcache *regcache, int tid, int regno) | ||
| 285 | +{ | ||
| 286 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
| 287 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
| 288 | + /* This isn't really an address. But ptrace thinks of it as one. */ | ||
| 289 | + CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno); | ||
| 290 | + int i; | ||
| 291 | + size_t bytes_to_transfer; | ||
| 292 | + char buf[MAX_REGISTER_SIZE]; | ||
| 293 | + | ||
| 294 | + if (regaddr == -1) | ||
| 295 | + return; | ||
| 296 | + | ||
| 297 | + /* First collect the register. Keep in mind that the regcache's | ||
| 298 | + idea of the register's size may not be a multiple of sizeof | ||
| 299 | + (long). */ | ||
| 300 | + memset (buf, 0, sizeof buf); | ||
| 301 | + bytes_to_transfer = align_up (register_size (gdbarch, regno), sizeof (long)); | ||
| 302 | + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) | ||
| 303 | + { | ||
| 304 | + /* Little-endian values always sit at the left end of the buffer. */ | ||
| 305 | + regcache_raw_collect (regcache, regno, buf); | ||
| 306 | + } | ||
| 307 | + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) | ||
| 308 | + { | ||
| 309 | + /* Big-endian values sit at the right end of the buffer. */ | ||
| 310 | + size_t padding = (bytes_to_transfer - register_size (gdbarch, regno)); | ||
| 311 | + regcache_raw_collect (regcache, regno, buf + padding); | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + for (i = 0; i < bytes_to_transfer; i += sizeof (long)) | ||
| 315 | + { | ||
| 316 | + long l; | ||
| 317 | + | ||
| 318 | + memcpy (&l, &buf[i], sizeof (l)); | ||
| 319 | + errno = 0; | ||
| 320 | + ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, l); | ||
| 321 | + regaddr += sizeof (long); | ||
| 322 | + | ||
| 323 | + if (errno != 0) | ||
| 324 | + { | ||
| 325 | + char message[128]; | ||
| 326 | + sprintf (message, "writing register %s (#%d)", | ||
| 327 | + gdbarch_register_name (gdbarch, regno), regno); | ||
| 328 | + perror_with_name (message); | ||
| 329 | + } | ||
| 330 | + } | ||
| 331 | +} | ||
| 332 | + | ||
| 333 | +/* This function actually issues the request to ptrace, telling | ||
| 334 | + it to store all general-purpose registers present in the specified | ||
| 335 | + regset. | ||
| 336 | + | ||
| 337 | + If the ptrace request does not exist, this function returns 0 | ||
| 338 | + and properly sets the have_ptrace_* flag. If the request fails, | ||
| 339 | + this function calls perror_with_name. Otherwise, if the request | ||
| 340 | + succeeds, then the regcache is stored and 1 is returned. */ | ||
| 341 | +static int | ||
| 342 | +store_all_gp_regs (const struct regcache *regcache, int tid, int regno) | ||
| 343 | +{ | ||
| 344 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
| 345 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
| 346 | + gdb_gregset_t gregset; | ||
| 347 | + | ||
| 348 | + if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0) | ||
| 349 | + { | ||
| 350 | + if (errno == EIO) | ||
| 351 | + { | ||
| 352 | + have_ptrace_getsetregs = 0; | ||
| 353 | + return 0; | ||
| 354 | + } | ||
| 355 | + perror_with_name (_("Couldn't get general-purpose registers.")); | ||
| 356 | + } | ||
| 357 | + | ||
| 358 | + fill_gregset (regcache, &gregset, regno); | ||
| 359 | + | ||
| 360 | + if (ptrace (PTRACE_SETREGS, tid, 0, (void *) &gregset) < 0) | ||
| 361 | + { | ||
| 362 | + if (errno == EIO) | ||
| 363 | + { | ||
| 364 | + have_ptrace_getsetregs = 0; | ||
| 365 | + return 0; | ||
| 366 | + } | ||
| 367 | + perror_with_name (_("Couldn't set general-purpose registers.")); | ||
| 368 | + } | ||
| 369 | + | ||
| 370 | + return 1; | ||
| 371 | +} | ||
| 372 | + | ||
| 373 | +/* This is a wrapper for the store_all_gp_regs function. It is | ||
| 374 | + responsible for verifying if this target has the ptrace request | ||
| 375 | + that can be used to store all general-purpose registers at one | ||
| 376 | + shot. If it doesn't, then we should store them using the | ||
| 377 | + old-fashioned way, which is to iterate over the registers and | ||
| 378 | + store them one by one. */ | ||
| 379 | +static void | ||
| 380 | +store_gp_regs (const struct regcache *regcache, int tid, int regno) | ||
| 381 | +{ | ||
| 382 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
| 383 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
| 384 | + int i; | ||
| 385 | + | ||
| 386 | + if (have_ptrace_getsetregs) | ||
| 387 | + if (store_all_gp_regs (regcache, tid, regno)) | ||
| 388 | + return; | ||
| 389 | + | ||
| 390 | + /* If we hit this point, it doesn't really matter which | ||
| 391 | + architecture we are using. We just need to store the | ||
| 392 | + registers in the "old-fashioned way". */ | ||
| 393 | + for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++) | ||
| 394 | + store_register (regcache, tid, i); | ||
| 395 | +} | ||
| 396 | + | ||
| 397 | + | ||
| 398 | +/* Fetch registers from the child process. Fetch all registers if | ||
| 399 | + regno == -1, otherwise fetch all general registers or all floating | ||
| 400 | + point registers depending upon the value of regno. */ | ||
| 401 | + | ||
| 402 | +static void | ||
| 403 | +microblaze_linux_fetch_inferior_registers (struct target_ops *ops, | ||
| 404 | + struct regcache *regcache, int regno) | ||
| 405 | +{ | ||
| 406 | + /* Get the thread id for the ptrace call. */ | ||
| 407 | + int tid = GET_THREAD_ID (inferior_ptid); | ||
| 408 | + | ||
| 409 | + if (regno == -1) | ||
| 410 | + fetch_gp_regs (regcache, tid); | ||
| 411 | + else | ||
| 412 | + fetch_register (regcache, tid, regno); | ||
| 413 | +} | ||
| 414 | + | ||
| 415 | +/* Store registers back into the inferior. Store all registers if | ||
| 416 | + regno == -1, otherwise store all general registers or all floating | ||
| 417 | + point registers depending upon the value of regno. */ | ||
| 418 | + | ||
| 419 | +static void | ||
| 420 | +microblaze_linux_store_inferior_registers (struct target_ops *ops, | ||
| 421 | + struct regcache *regcache, int regno) | ||
| 422 | +{ | ||
| 423 | + /* Get the thread id for the ptrace call. */ | ||
| 424 | + int tid = GET_THREAD_ID (inferior_ptid); | ||
| 425 | + | ||
| 426 | + if (regno >= 0) | ||
| 427 | + store_register (regcache, tid, regno); | ||
| 428 | + else | ||
| 429 | + store_gp_regs (regcache, tid, -1); | ||
| 430 | +} | ||
| 431 | + | ||
| 432 | +/* Wrapper functions for the standard regset handling, used by | ||
| 433 | + thread debugging. */ | ||
| 434 | + | ||
| 435 | +void | ||
| 436 | +fill_gregset (const struct regcache *regcache, | ||
| 437 | + gdb_gregset_t *gregsetp, int regno) | ||
| 438 | +{ | ||
| 439 | + microblaze_collect_gregset (NULL, regcache, regno, gregsetp); | ||
| 440 | +} | ||
| 441 | + | ||
| 442 | +void | ||
| 443 | +supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) | ||
| 444 | +{ | ||
| 445 | + microblaze_supply_gregset (NULL, regcache, -1, gregsetp); | ||
| 446 | +} | ||
| 447 | + | ||
| 448 | +void | ||
| 449 | +fill_fpregset (const struct regcache *regcache, | ||
| 450 | + gdb_fpregset_t *fpregsetp, int regno) | ||
| 451 | +{ | ||
| 452 | + /* FIXME. */ | ||
| 453 | +} | ||
| 454 | + | ||
| 455 | +void | ||
| 456 | +supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) | ||
| 457 | +{ | ||
| 458 | + /* FIXME. */ | ||
| 459 | +} | ||
| 460 | + | ||
| 461 | +static const struct target_desc * | ||
| 462 | +microblaze_linux_read_description (struct target_ops *ops) | ||
| 463 | +{ | ||
| 464 | + CORE_ADDR microblaze_hwcap = 0; | ||
| 465 | + | ||
| 466 | + if (target_auxv_search (ops, AT_HWCAP, µblaze_hwcap) != 1) | ||
| 467 | + return NULL; | ||
| 468 | + | ||
| 469 | + return NULL; | ||
| 470 | +} | ||
| 471 | + | ||
| 472 | + | ||
| 473 | +void _initialize_microblaze_linux_nat (void); | ||
| 474 | + | ||
| 475 | +void | ||
| 476 | +_initialize_microblaze_linux_nat (void) | ||
| 477 | +{ | ||
| 478 | + struct target_ops *t; | ||
| 479 | + | ||
| 480 | + /* Fill in the generic GNU/Linux methods. */ | ||
| 481 | + t = linux_target (); | ||
| 482 | + | ||
| 483 | + /* Add our register access methods. */ | ||
| 484 | + t->to_fetch_registers = microblaze_linux_fetch_inferior_registers; | ||
| 485 | + t->to_store_registers = microblaze_linux_store_inferior_registers; | ||
| 486 | + | ||
| 487 | + t->to_read_description = microblaze_linux_read_description; | ||
| 488 | + | ||
| 489 | + /* Register the target. */ | ||
| 490 | + linux_nat_add_target (t); | ||
| 491 | +} | ||
| 492 | -- | ||
| 493 | 1.7.9.5 | ||
| 494 | |||
diff --git a/recipes-devtools/gdb/files/0004-Robustify-inline-function-support.patch b/recipes-devtools/gdb/files/0004-Robustify-inline-function-support.patch new file mode 100644 index 00000000..24759d73 --- /dev/null +++ b/recipes-devtools/gdb/files/0004-Robustify-inline-function-support.patch | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | From: "Edgar E. Iglesias" <edgar@axis.com> | ||
| 2 | Date: Mon, 27 Feb 2012 06:28:00 +0100 | ||
| 3 | Subject: Robustify inline function support | ||
| 4 | |||
| 5 | Signed-off-by: Edgar E. Iglesias <edgar@axis.com> | ||
| 6 | Upstream-Status: Pending | ||
| 7 | --- | ||
| 8 | gdb/blockframe.c | 3 ++- | ||
| 9 | gdb/inline-frame.c | 3 +++ | ||
| 10 | 2 files changed, 5 insertions(+), 1 deletion(-) | ||
| 11 | |||
| 12 | diff --git a/gdb/blockframe.c b/gdb/blockframe.c | ||
| 13 | index d5787f1..80e40a3 100644 | ||
| 14 | --- a/gdb/blockframe.c | ||
| 15 | +++ b/gdb/blockframe.c | ||
| 16 | @@ -78,7 +78,8 @@ get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block) | ||
| 17 | inline_count--; | ||
| 18 | |||
| 19 | bl = BLOCK_SUPERBLOCK (bl); | ||
| 20 | - gdb_assert (bl != NULL); | ||
| 21 | + if (!bl) | ||
| 22 | + return NULL; | ||
| 23 | } | ||
| 24 | |||
| 25 | return bl; | ||
| 26 | diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c | ||
| 27 | index 2773814..c3a77ad 100644 | ||
| 28 | --- a/gdb/inline-frame.c | ||
| 29 | +++ b/gdb/inline-frame.c | ||
| 30 | @@ -230,6 +230,9 @@ inline_frame_sniffer (const struct frame_unwind *self, | ||
| 31 | cur_block = BLOCK_SUPERBLOCK (cur_block); | ||
| 32 | } | ||
| 33 | |||
| 34 | + if (depth == 0) | ||
| 35 | + return 0; | ||
| 36 | + | ||
| 37 | /* Check how many inlined functions already have frames. */ | ||
| 38 | for (next_frame = get_next_frame (this_frame); | ||
| 39 | next_frame && get_frame_type (next_frame) == INLINE_FRAME; | ||
| 40 | -- | ||
| 41 | 1.7.9.5 | ||
| 42 | |||
diff --git a/recipes-devtools/gdb/files/0005-Fix-debug-message-when-register-is-unavailable.patch b/recipes-devtools/gdb/files/0005-Fix-debug-message-when-register-is-unavailable.patch new file mode 100644 index 00000000..67520f4c --- /dev/null +++ b/recipes-devtools/gdb/files/0005-Fix-debug-message-when-register-is-unavailable.patch | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | From: Nathan Rossi <nathan.rossi@petalogix.com> | ||
| 2 | Date: Tue, 8 May 2012 18:11:17 +1000 | ||
| 3 | Subject: Fix debug message when register is unavailable | ||
| 4 | |||
| 5 | Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com> | ||
| 6 | Upstream-Status: Pending | ||
| 7 | --- | ||
| 8 | gdb/frame.c | 13 ++++++++++--- | ||
| 9 | 1 file changed, 10 insertions(+), 3 deletions(-) | ||
| 10 | |||
| 11 | diff --git a/gdb/frame.c b/gdb/frame.c | ||
| 12 | index 4b8ab60..7ad7cb3 100644 | ||
| 13 | --- a/gdb/frame.c | ||
| 14 | +++ b/gdb/frame.c | ||
| 15 | @@ -979,12 +979,19 @@ frame_unwind_register_value (struct frame_info *frame, int regnum) | ||
| 16 | else | ||
| 17 | { | ||
| 18 | int i; | ||
| 19 | - const gdb_byte *buf = value_contents (value); | ||
| 20 | + const gdb_byte *buf = NULL; | ||
| 21 | + if (value_entirely_available(value)) { | ||
| 22 | + buf = value_contents (value); | ||
| 23 | + } | ||
| 24 | |||
| 25 | fprintf_unfiltered (gdb_stdlog, " bytes="); | ||
| 26 | fprintf_unfiltered (gdb_stdlog, "["); | ||
| 27 | - for (i = 0; i < register_size (gdbarch, regnum); i++) | ||
| 28 | - fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]); | ||
| 29 | + if (buf != NULL) { | ||
| 30 | + for (i = 0; i < register_size (gdbarch, regnum); i++) | ||
| 31 | + fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]); | ||
| 32 | + } else { | ||
| 33 | + fprintf_unfiltered (gdb_stdlog, "unavailable"); | ||
| 34 | + } | ||
| 35 | fprintf_unfiltered (gdb_stdlog, "]"); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | -- | ||
| 39 | 1.7.9.5 | ||
| 40 | |||
diff --git a/recipes-devtools/gdb/files/0006-Add-slr-and-shr-regs-and-little-endian-breakpoint.patch b/recipes-devtools/gdb/files/0006-Add-slr-and-shr-regs-and-little-endian-breakpoint.patch new file mode 100644 index 00000000..53020f9d --- /dev/null +++ b/recipes-devtools/gdb/files/0006-Add-slr-and-shr-regs-and-little-endian-breakpoint.patch | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | From: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 2 | Date: Mon, 26 Nov 2012 17:39:17 +1000 | ||
| 3 | Subject: Add slr and shr regs and little-endian breakpoint | ||
| 4 | |||
| 5 | Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 6 | Upstream-Status: Pending | ||
| 7 | --- | ||
| 8 | gdb/microblaze-tdep.c | 10 ++++++++-- | ||
| 9 | gdb/microblaze-tdep.h | 6 ++++-- | ||
| 10 | gdb/regformats/reg-microblaze.dat | 2 ++ | ||
| 11 | 3 files changed, 14 insertions(+), 4 deletions(-) | ||
| 12 | |||
| 13 | diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c | ||
| 14 | index cfc227d..a245169 100644 | ||
| 15 | --- a/gdb/microblaze-tdep.c | ||
| 16 | +++ b/gdb/microblaze-tdep.c | ||
| 17 | @@ -74,7 +74,8 @@ static const char *microblaze_register_names[] = | ||
| 18 | "rpc", "rmsr", "rear", "resr", "rfsr", "rbtr", | ||
| 19 | "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6", | ||
| 20 | "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11", | ||
| 21 | - "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi" | ||
| 22 | + "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi", | ||
| 23 | + "rslr", "rshr" | ||
| 24 | }; | ||
| 25 | |||
| 26 | #define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names) | ||
| 27 | @@ -202,10 +203,15 @@ static const gdb_byte * | ||
| 28 | microblaze_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, | ||
| 29 | int *len) | ||
| 30 | { | ||
| 31 | + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | ||
| 32 | static gdb_byte break_insn[] = MICROBLAZE_BREAKPOINT; | ||
| 33 | + static gdb_byte break_insn_le[] = MICROBLAZE_BREAKPOINT_LE; | ||
| 34 | |||
| 35 | *len = sizeof (break_insn); | ||
| 36 | - return break_insn; | ||
| 37 | + if (byte_order == BFD_ENDIAN_BIG) | ||
| 38 | + return break_insn; | ||
| 39 | + else | ||
| 40 | + return break_insn_le; | ||
| 41 | } | ||
| 42 | |||
| 43 | /* Allocate and initialize a frame cache. */ | ||
| 44 | diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h | ||
| 45 | index 7de4463..23dc77a 100644 | ||
| 46 | --- a/gdb/microblaze-tdep.h | ||
| 47 | +++ b/gdb/microblaze-tdep.h | ||
| 48 | @@ -56,7 +56,7 @@ struct microblaze_frame_cache | ||
| 49 | int fp_regnum; | ||
| 50 | |||
| 51 | /* Offsets to saved registers. */ | ||
| 52 | - int register_offsets[57]; /* Must match MICROBLAZE_NUM_REGS. */ | ||
| 53 | + int register_offsets[59]; /* Must match MICROBLAZE_NUM_REGS. */ | ||
| 54 | |||
| 55 | /* Table of saved registers. */ | ||
| 56 | struct trad_frame_saved_reg *saved_regs; | ||
| 57 | @@ -121,7 +121,9 @@ enum microblaze_regnum | ||
| 58 | MICROBLAZE_RTLBX_REGNUM, | ||
| 59 | MICROBLAZE_RTLBSX_REGNUM, | ||
| 60 | MICROBLAZE_RTLBLO_REGNUM, | ||
| 61 | - MICROBLAZE_RTLBHI_REGNUM | ||
| 62 | + MICROBLAZE_RTLBHI_REGNUM, | ||
| 63 | + MICROBLAZE_SLR_REGNUM, | ||
| 64 | + MICROBLAZE_SHR_REGNUM | ||
| 65 | }; | ||
| 66 | |||
| 67 | /* All registers are 32 bits. */ | ||
| 68 | diff --git a/gdb/regformats/reg-microblaze.dat b/gdb/regformats/reg-microblaze.dat | ||
| 69 | index a5dd0a0..bd8a438 100644 | ||
| 70 | --- a/gdb/regformats/reg-microblaze.dat | ||
| 71 | +++ b/gdb/regformats/reg-microblaze.dat | ||
| 72 | @@ -37,3 +37,5 @@ expedite:r1,pc | ||
| 73 | 32:ear | ||
| 74 | 32:esr | ||
| 75 | 32:fsr | ||
| 76 | +32:slr | ||
| 77 | +32:shr | ||
| 78 | -- | ||
| 79 | 1.7.9.5 | ||
| 80 | |||
diff --git a/recipes-devtools/gdb/files/0007-Fix-relaxation-of-assembler-resolved-references.patch b/recipes-devtools/gdb/files/0007-Fix-relaxation-of-assembler-resolved-references.patch new file mode 100644 index 00000000..3aaaf0ab --- /dev/null +++ b/recipes-devtools/gdb/files/0007-Fix-relaxation-of-assembler-resolved-references.patch | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com> | ||
| 2 | Date: Tue, 14 Feb 2012 01:00:22 +0100 | ||
| 3 | Subject: Fix relaxation of assembler resolved references | ||
| 4 | |||
| 5 | Upstream-Status: Pending | ||
| 6 | --- | ||
| 7 | bfd/elf32-microblaze.c | 39 +++++++++++++++++++++++++++++++++++++++ | ||
| 8 | 1 file changed, 39 insertions(+) | ||
| 9 | |||
| 10 | diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c | ||
| 11 | index 365546c..61926a4 100644 | ||
| 12 | --- a/bfd/elf32-microblaze.c | ||
| 13 | +++ b/bfd/elf32-microblaze.c | ||
| 14 | @@ -1967,6 +1967,45 @@ microblaze_elf_relax_section (bfd *abfd, | ||
| 15 | irelscanend = irelocs + o->reloc_count; | ||
| 16 | for (irelscan = irelocs; irelscan < irelscanend; irelscan++) | ||
| 17 | { | ||
| 18 | + if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_NONE) | ||
| 19 | + { | ||
| 20 | + unsigned int val; | ||
| 21 | + | ||
| 22 | + isym = isymbuf + ELF32_R_SYM (irelscan->r_info); | ||
| 23 | + | ||
| 24 | + /* This was a PC-relative instruction that was completely resolved. */ | ||
| 25 | + if (ocontents == NULL) | ||
| 26 | + { | ||
| 27 | + if (elf_section_data (o)->this_hdr.contents != NULL) | ||
| 28 | + ocontents = elf_section_data (o)->this_hdr.contents; | ||
| 29 | + else | ||
| 30 | + { | ||
| 31 | + /* We always cache the section contents. | ||
| 32 | + Perhaps, if info->keep_memory is FALSE, we | ||
| 33 | + should free them, if we are permitted to. */ | ||
| 34 | + | ||
| 35 | + if (o->rawsize == 0) | ||
| 36 | + o->rawsize = o->size; | ||
| 37 | + ocontents = (bfd_byte *) bfd_malloc (o->rawsize); | ||
| 38 | + if (ocontents == NULL) | ||
| 39 | + goto error_return; | ||
| 40 | + if (!bfd_get_section_contents (abfd, o, ocontents, | ||
| 41 | + (file_ptr) 0, | ||
| 42 | + o->rawsize)) | ||
| 43 | + goto error_return; | ||
| 44 | + elf_section_data (o)->this_hdr.contents = ocontents; | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + irelscan->r_addend -= calc_fixup (irelscan->r_addend | ||
| 49 | + + isym->st_value, sec); | ||
| 50 | + val = bfd_get_32 (abfd, ocontents + irelscan->r_offset); | ||
| 51 | + microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset, | ||
| 52 | + irelscan->r_addend); | ||
| 53 | + } | ||
| 54 | + if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_NONE) { | ||
| 55 | + fprintf(stderr, "Unhandled NONE 64\n"); | ||
| 56 | + } | ||
| 57 | if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32) | ||
| 58 | { | ||
| 59 | isym = isymbuf + ELF32_R_SYM (irelscan->r_info); | ||
| 60 | -- | ||
| 61 | 1.7.9.5 | ||
| 62 | |||
diff --git a/recipes-devtools/gdb/files/0008-Fixup-debug_loc-sections-after-linker-relaxation.patch b/recipes-devtools/gdb/files/0008-Fixup-debug_loc-sections-after-linker-relaxation.patch new file mode 100644 index 00000000..95fc629b --- /dev/null +++ b/recipes-devtools/gdb/files/0008-Fixup-debug_loc-sections-after-linker-relaxation.patch | |||
| @@ -0,0 +1,195 @@ | |||
| 1 | From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com> | ||
| 2 | Date: Wed, 15 Feb 2012 13:53:02 +0100 | ||
| 3 | Subject: Fixup debug_loc sections after linker relaxation | ||
| 4 | |||
| 5 | Adds a new reloctype R_MICROBLAZE_32_NONE, used for passing | ||
| 6 | reloc info from the assembler to the linker when the linker | ||
| 7 | manages to fully resolve a local symbol reference. | ||
| 8 | |||
| 9 | This is a workaround for design flaws in the assembler to | ||
| 10 | linker interface with regards to linker relaxation. | ||
| 11 | |||
| 12 | Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com> | ||
| 13 | Upstream-Status: Pending | ||
| 14 | --- | ||
| 15 | bfd/bfd-in2.h | 5 +++++ | ||
| 16 | bfd/elf32-microblaze.c | 45 +++++++++++++++++++++++++++++++++++++-------- | ||
| 17 | bfd/libbfd.h | 1 + | ||
| 18 | bfd/reloc.c | 6 ++++++ | ||
| 19 | include/elf/microblaze.h | 1 + | ||
| 20 | 5 files changed, 50 insertions(+), 8 deletions(-) | ||
| 21 | mode change 100644 => 100755 bfd/elf32-microblaze.c | ||
| 22 | mode change 100644 => 100755 include/elf/microblaze.h | ||
| 23 | |||
| 24 | diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h | ||
| 25 | index 524e97e..17a5769 100644 | ||
| 26 | --- a/bfd/bfd-in2.h | ||
| 27 | +++ b/bfd/bfd-in2.h | ||
| 28 | @@ -5125,6 +5125,11 @@ value relative to the read-write small data area anchor */ | ||
| 29 | expressions of the form "Symbol Op Symbol" */ | ||
| 30 | BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM, | ||
| 31 | |||
| 32 | +/* This is a 32 bit reloc that stores the 32 bit pc relative | ||
| 33 | +value in two words (with an imm instruction). No relocation is | ||
| 34 | +done here - only used for relaxing */ | ||
| 35 | + BFD_RELOC_MICROBLAZE_32_NONE, | ||
| 36 | + | ||
| 37 | /* This is a 64 bit reloc that stores the 32 bit pc relative | ||
| 38 | value in two words (with an imm instruction). No relocation is | ||
| 39 | done here - only used for relaxing */ | ||
| 40 | diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c | ||
| 41 | old mode 100644 | ||
| 42 | new mode 100755 | ||
| 43 | index 61926a4..c44c76f | ||
| 44 | --- a/bfd/elf32-microblaze.c | ||
| 45 | +++ b/bfd/elf32-microblaze.c | ||
| 46 | @@ -177,6 +177,20 @@ static reloc_howto_type microblaze_elf_howto_raw[] = | ||
| 47 | FALSE), /* PC relative offset? */ | ||
| 48 | |||
| 49 | /* This reloc does nothing. Used for relaxation. */ | ||
| 50 | + HOWTO (R_MICROBLAZE_32_NONE, /* Type. */ | ||
| 51 | + 0, /* Rightshift. */ | ||
| 52 | + 2, /* Size (0 = byte, 1 = short, 2 = long). */ | ||
| 53 | + 32, /* Bitsize. */ | ||
| 54 | + TRUE, /* PC_relative. */ | ||
| 55 | + 0, /* Bitpos. */ | ||
| 56 | + complain_overflow_bitfield, /* Complain on overflow. */ | ||
| 57 | + NULL, /* Special Function. */ | ||
| 58 | + "R_MICROBLAZE_32_NONE",/* Name. */ | ||
| 59 | + FALSE, /* Partial Inplace. */ | ||
| 60 | + 0, /* Source Mask. */ | ||
| 61 | + 0, /* Dest Mask. */ | ||
| 62 | + FALSE), /* PC relative offset? */ | ||
| 63 | + | ||
| 64 | HOWTO (R_MICROBLAZE_64_NONE, /* Type. */ | ||
| 65 | 0, /* Rightshift. */ | ||
| 66 | 2, /* Size (0 = byte, 1 = short, 2 = long). */ | ||
| 67 | @@ -532,7 +546,10 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, | ||
| 68 | case BFD_RELOC_NONE: | ||
| 69 | microblaze_reloc = R_MICROBLAZE_NONE; | ||
| 70 | break; | ||
| 71 | - case BFD_RELOC_MICROBLAZE_64_NONE: | ||
| 72 | + case BFD_RELOC_MICROBLAZE_32_NONE: | ||
| 73 | + microblaze_reloc = R_MICROBLAZE_32_NONE; | ||
| 74 | + break; | ||
| 75 | + case BFD_RELOC_MICROBLAZE_64_NONE: | ||
| 76 | microblaze_reloc = R_MICROBLAZE_64_NONE; | ||
| 77 | break; | ||
| 78 | case BFD_RELOC_32: | ||
| 79 | @@ -1912,14 +1929,22 @@ microblaze_elf_relax_section (bfd *abfd, | ||
| 80 | } | ||
| 81 | break; | ||
| 82 | case R_MICROBLAZE_NONE: | ||
| 83 | + case R_MICROBLAZE_32_NONE: | ||
| 84 | { | ||
| 85 | /* This was a PC-relative instruction that was | ||
| 86 | completely resolved. */ | ||
| 87 | int sfix, efix; | ||
| 88 | + unsigned int val; | ||
| 89 | bfd_vma target_address; | ||
| 90 | target_address = irel->r_addend + irel->r_offset; | ||
| 91 | sfix = calc_fixup (irel->r_offset, 0, sec); | ||
| 92 | efix = calc_fixup (target_address, 0, sec); | ||
| 93 | + | ||
| 94 | + /* Validate the in-band val. */ | ||
| 95 | + val = bfd_get_32 (abfd, contents + irel->r_offset); | ||
| 96 | + if (val != irel->r_addend && ELF32_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) { | ||
| 97 | + fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend); | ||
| 98 | + } | ||
| 99 | irel->r_addend -= (efix - sfix); | ||
| 100 | /* Should use HOWTO. */ | ||
| 101 | microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset, | ||
| 102 | @@ -1967,12 +1992,16 @@ microblaze_elf_relax_section (bfd *abfd, | ||
| 103 | irelscanend = irelocs + o->reloc_count; | ||
| 104 | for (irelscan = irelocs; irelscan < irelscanend; irelscan++) | ||
| 105 | { | ||
| 106 | - if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_NONE) | ||
| 107 | + if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE) | ||
| 108 | { | ||
| 109 | unsigned int val; | ||
| 110 | |||
| 111 | isym = isymbuf + ELF32_R_SYM (irelscan->r_info); | ||
| 112 | |||
| 113 | + /* hax: We only do the following fixup for debug location lists. */ | ||
| 114 | + if (strcmp(".debug_loc", o->name)) | ||
| 115 | + continue; | ||
| 116 | + | ||
| 117 | /* This was a PC-relative instruction that was completely resolved. */ | ||
| 118 | if (ocontents == NULL) | ||
| 119 | { | ||
| 120 | @@ -1997,15 +2026,15 @@ microblaze_elf_relax_section (bfd *abfd, | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | - irelscan->r_addend -= calc_fixup (irelscan->r_addend | ||
| 125 | - + isym->st_value, sec); | ||
| 126 | val = bfd_get_32 (abfd, ocontents + irelscan->r_offset); | ||
| 127 | + if (val != irelscan->r_addend) { | ||
| 128 | + fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend); | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec); | ||
| 132 | microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset, | ||
| 133 | irelscan->r_addend); | ||
| 134 | } | ||
| 135 | - if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_NONE) { | ||
| 136 | - fprintf(stderr, "Unhandled NONE 64\n"); | ||
| 137 | - } | ||
| 138 | if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32) | ||
| 139 | { | ||
| 140 | isym = isymbuf + ELF32_R_SYM (irelscan->r_info); | ||
| 141 | @@ -2065,7 +2094,7 @@ microblaze_elf_relax_section (bfd *abfd, | ||
| 142 | elf_section_data (o)->this_hdr.contents = ocontents; | ||
| 143 | } | ||
| 144 | } | ||
| 145 | - irelscan->r_addend -= calc_fixup (irel->r_addend | ||
| 146 | + irelscan->r_addend -= calc_fixup (irelscan->r_addend | ||
| 147 | + isym->st_value, | ||
| 148 | 0, | ||
| 149 | sec); | ||
| 150 | diff --git a/bfd/libbfd.h b/bfd/libbfd.h | ||
| 151 | index 857d1ea..5c627fe 100644 | ||
| 152 | --- a/bfd/libbfd.h | ||
| 153 | +++ b/bfd/libbfd.h | ||
| 154 | @@ -2492,6 +2492,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", | ||
| 155 | "BFD_RELOC_MICROBLAZE_32_ROSDA", | ||
| 156 | "BFD_RELOC_MICROBLAZE_32_RWSDA", | ||
| 157 | "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM", | ||
| 158 | + "BFD_RELOC_MICROBLAZE_32_NONE", | ||
| 159 | "BFD_RELOC_MICROBLAZE_64_NONE", | ||
| 160 | "BFD_RELOC_MICROBLAZE_64_GOTPC", | ||
| 161 | "BFD_RELOC_MICROBLAZE_64_GOT", | ||
| 162 | diff --git a/bfd/reloc.c b/bfd/reloc.c | ||
| 163 | index b59ca00..c9c547e 100644 | ||
| 164 | --- a/bfd/reloc.c | ||
| 165 | +++ b/bfd/reloc.c | ||
| 166 | @@ -6001,6 +6001,12 @@ ENUMDOC | ||
| 167 | This is a 32 bit reloc for the microblaze to handle | ||
| 168 | expressions of the form "Symbol Op Symbol" | ||
| 169 | ENUM | ||
| 170 | + BFD_RELOC_MICROBLAZE_32_NONE | ||
| 171 | +ENUMDOC | ||
| 172 | + This is a 32 bit reloc that stores the 32 bit pc relative | ||
| 173 | + value in two words (with an imm instruction). No relocation is | ||
| 174 | + done here - only used for relaxing | ||
| 175 | +ENUM | ||
| 176 | BFD_RELOC_MICROBLAZE_64_NONE | ||
| 177 | ENUMDOC | ||
| 178 | This is a 64 bit reloc that stores the 32 bit pc relative | ||
| 179 | diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h | ||
| 180 | old mode 100644 | ||
| 181 | new mode 100755 | ||
| 182 | index c4d9821..72771e8 | ||
| 183 | --- a/include/elf/microblaze.h | ||
| 184 | +++ b/include/elf/microblaze.h | ||
| 185 | @@ -58,6 +58,7 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type) | ||
| 186 | RELOC_NUMBER (R_MICROBLAZE_TLSDTPREL64, 27) /* TLS Offset Within TLS Block */ | ||
| 187 | RELOC_NUMBER (R_MICROBLAZE_TLSGOTTPREL32, 28) /* TLS Offset From Thread Pointer */ | ||
| 188 | RELOC_NUMBER (R_MICROBLAZE_TLSTPREL32, 29) /* TLS Offset From Thread Pointer */ | ||
| 189 | + RELOC_NUMBER (R_MICROBLAZE_32_NONE, 30) | ||
| 190 | |||
| 191 | END_RELOC_NUMBERS (R_MICROBLAZE_max) | ||
| 192 | |||
| 193 | -- | ||
| 194 | 1.7.9.5 | ||
| 195 | |||
diff --git a/recipes-devtools/gdb/files/0009-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch b/recipes-devtools/gdb/files/0009-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch new file mode 100644 index 00000000..cb58f603 --- /dev/null +++ b/recipes-devtools/gdb/files/0009-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | From: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 2 | Date: Wed, 8 May 2013 11:03:36 +1000 | ||
| 3 | Subject: Add wdc.ext.clear and wdc.ext.flush insns | ||
| 4 | |||
| 5 | Added two new instructions, wdc.ext.clear and wdc.ext.flush, | ||
| 6 | to enable MicroBlaze to flush an external cache, which is | ||
| 7 | used with the new coherency support for multiprocessing. | ||
| 8 | |||
| 9 | Signed-off-by:nagaraju <nmekala@xilix.com> | ||
| 10 | Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 11 | Upstream-Status: Pending | ||
| 12 | --- | ||
| 13 | opcodes/microblaze-opc.h | 5 ++++- | ||
| 14 | opcodes/microblaze-opcm.h | 6 +++--- | ||
| 15 | 2 files changed, 7 insertions(+), 4 deletions(-) | ||
| 16 | |||
| 17 | diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h | ||
| 18 | index e9da12a..dd56ab5 100644 | ||
| 19 | --- a/opcodes/microblaze-opc.h | ||
| 20 | +++ b/opcodes/microblaze-opc.h | ||
| 21 | @@ -91,6 +91,7 @@ | ||
| 22 | #define OPCODE_MASK_H3 0xFC000600 /* High 6 bits and bits 21, 22. */ | ||
| 23 | #define OPCODE_MASK_H32 0xFC00FC00 /* High 6 bits and bit 16-21. */ | ||
| 24 | #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits. */ | ||
| 25 | +#define OPCODE_MASK_H35B 0xFC0004FF /* High 6 bits and low 9 bits. */ | ||
| 26 | #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26. */ | ||
| 27 | |||
| 28 | /* New Mask for msrset, msrclr insns. */ | ||
| 29 | @@ -101,7 +102,7 @@ | ||
| 30 | #define DELAY_SLOT 1 | ||
| 31 | #define NO_DELAY_SLOT 0 | ||
| 32 | |||
| 33 | -#define MAX_OPCODES 289 | ||
| 34 | +#define MAX_OPCODES 291 | ||
| 35 | |||
| 36 | struct op_code_struct | ||
| 37 | { | ||
| 38 | @@ -174,7 +175,9 @@ struct op_code_struct | ||
| 39 | {"wic", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst }, | ||
| 40 | {"wdc", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst }, | ||
| 41 | {"wdc.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000066, OPCODE_MASK_H34B, wdcclear, special_inst }, | ||
| 42 | + {"wdc.ext.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000466, OPCODE_MASK_H35B, wdcextclear, special_inst }, | ||
| 43 | {"wdc.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000074, OPCODE_MASK_H34B, wdcflush, special_inst }, | ||
| 44 | + {"wdc.ext.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000476, OPCODE_MASK_H35B, wdcextflush, special_inst }, | ||
| 45 | {"mts", INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9400C000, OPCODE_MASK_H13S, mts, special_inst }, | ||
| 46 | {"mfs", INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94008000, OPCODE_MASK_H23S, mfs, special_inst }, | ||
| 47 | {"br", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98000000, OPCODE_MASK_H124, br, branch_inst }, | ||
| 48 | diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h | ||
| 49 | index 124cdec..8e531f9 100644 | ||
| 50 | --- a/opcodes/microblaze-opcm.h | ||
| 51 | +++ b/opcodes/microblaze-opcm.h | ||
| 52 | @@ -31,9 +31,9 @@ enum microblaze_instr | ||
| 53 | idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput, | ||
| 54 | ncget, ncput, muli, bslli, bsrai, bsrli, mului, or, and, xor, | ||
| 55 | andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16, | ||
| 56 | - wic, wdc, wdcclear, wdcflush, mts, mfs, mbar, br, brd, | ||
| 57 | - brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt, | ||
| 58 | - bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni, | ||
| 59 | + wic, wdc, wdcclear, wdcextclear, wdcflush, wdcextflush, mts, mfs, mbar, | ||
| 60 | + br, brd, brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, | ||
| 61 | + blt, bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni, | ||
| 62 | imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid, | ||
| 63 | brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti, | ||
| 64 | bgtid, bgei, bgeid, lbu, lbur, lhu, lhur, lw, lwr, lwx, sb, sbr, sh, | ||
| 65 | -- | ||
| 66 | 1.7.9.5 | ||
| 67 | |||
diff --git a/recipes-devtools/gdb/files/0010-revert-master-rebase-changes-to-gdbserver.patch b/recipes-devtools/gdb/files/0010-revert-master-rebase-changes-to-gdbserver.patch new file mode 100644 index 00000000..edd6a5a7 --- /dev/null +++ b/recipes-devtools/gdb/files/0010-revert-master-rebase-changes-to-gdbserver.patch | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | From: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 2 | Date: Mon, 22 Jul 2013 11:16:05 +1000 | ||
| 3 | Subject: revert master-rebase changes to gdbserver | ||
| 4 | |||
| 5 | Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 6 | Upstream-Status: Pending | ||
| 7 | --- | ||
| 8 | gdb/gdbserver/Makefile.in | 4 +++ | ||
| 9 | gdb/gdbserver/configure.srv | 7 +++++ | ||
| 10 | gdb/gdbserver/linux-microblaze-low.c | 53 +++++----------------------------- | ||
| 11 | 3 files changed, 18 insertions(+), 46 deletions(-) | ||
| 12 | |||
| 13 | diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in | ||
| 14 | index 08db2cc..aa76959 100644 | ||
| 15 | --- a/gdb/gdbserver/Makefile.in | ||
| 16 | +++ b/gdb/gdbserver/Makefile.in | ||
| 17 | @@ -143,6 +143,7 @@ SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \ | ||
| 18 | $(srcdir)/linux-ia64-low.c $(srcdir)/linux-low.c \ | ||
| 19 | $(srcdir)/linux-m32r-low.c \ | ||
| 20 | $(srcdir)/linux-m68k-low.c $(srcdir)/linux-mips-low.c \ | ||
| 21 | + $(srcdir)/linux-microblaze-low.c \ | ||
| 22 | $(srcdir)/linux-ppc-low.c \ | ||
| 23 | $(srcdir)/linux-s390-low.c \ | ||
| 24 | $(srcdir)/linux-sh-low.c $(srcdir)/linux-sparc-low.c \ | ||
| 25 | @@ -336,6 +337,7 @@ clean: | ||
| 26 | rm -f i386-avx.c i386-avx-linux.c | ||
| 27 | rm -f amd64-avx.c amd64-avx-linux.c | ||
| 28 | rm -f i386-mmx.c i386-mmx-linux.c | ||
| 29 | + rm -f microblaze-linux.c | ||
| 30 | rm -f x32.c x32-linux.c | ||
| 31 | rm -f x32-avx.c x32-avx-linux.c | ||
| 32 | @$(MAKE) $(FLAGS_TO_PASS) DO=$@ "DODIRS=$(SUBDIRS)" subdir_do | ||
| 33 | @@ -616,6 +618,8 @@ mips64-linux.c : $(srcdir)/../regformats/mips64-linux.dat $(regdat_sh) | ||
| 34 | $(SHELL) $(regdat_sh) $(srcdir)/../regformats/mips64-linux.dat mips64-linux.c | ||
| 35 | mips64-dsp-linux.c : $(srcdir)/../regformats/mips64-dsp-linux.dat $(regdat_sh) | ||
| 36 | $(SHELL) $(regdat_sh) $(srcdir)/../regformats/mips64-dsp-linux.dat mips64-dsp-linux.c | ||
| 37 | +microblaze-linux.c : $(srcdir)/../regformats/reg-microblaze.dat $(regdat_sh) | ||
| 38 | + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-microblaze.dat microblaze-linux.c | ||
| 39 | powerpc-32.c : $(srcdir)/../regformats/rs6000/powerpc-32.dat $(regdat_sh) | ||
| 40 | $(SHELL) $(regdat_sh) $(srcdir)/../regformats/rs6000/powerpc-32.dat powerpc-32.c | ||
| 41 | powerpc-32l.c : $(srcdir)/../regformats/rs6000/powerpc-32l.dat $(regdat_sh) | ||
| 42 | diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv | ||
| 43 | index 271a0fe..57bd3a4c 100644 | ||
| 44 | --- a/gdb/gdbserver/configure.srv | ||
| 45 | +++ b/gdb/gdbserver/configure.srv | ||
| 46 | @@ -201,6 +201,13 @@ case "${target}" in | ||
| 47 | srv_linux_usrregs=yes | ||
| 48 | srv_linux_thread_db=yes | ||
| 49 | ;; | ||
| 50 | + microblaze*-*-linux*) srv_regobj=microblaze-linux.o | ||
| 51 | + srv_tgtobj="linux-low.o linux-osdata.o linux-microblaze-low.o " | ||
| 52 | + srv_tgtobj="${srv_tgtobj} linux-procfs.o linux-ptrace.o" | ||
| 53 | + srv_linux_regsets=yes | ||
| 54 | + srv_linux_usrregs=yes | ||
| 55 | + srv_linux_thread_db=yes | ||
| 56 | + ;; | ||
| 57 | powerpc*-*-linux*) srv_regobj="powerpc-32l.o" | ||
| 58 | srv_regobj="${srv_regobj} powerpc-altivec32l.o" | ||
| 59 | srv_regobj="${srv_regobj} powerpc-cell32l.o" | ||
| 60 | diff --git a/gdb/gdbserver/linux-microblaze-low.c b/gdb/gdbserver/linux-microblaze-low.c | ||
| 61 | index 279df9f..cba5d6f 100644 | ||
| 62 | --- a/gdb/gdbserver/linux-microblaze-low.c | ||
| 63 | +++ b/gdb/gdbserver/linux-microblaze-low.c | ||
| 64 | @@ -43,7 +43,6 @@ static int microblaze_regmap[] = | ||
| 65 | |||
| 66 | /* Defined in auto-generated file microblaze-linux.c. */ | ||
| 67 | void init_registers_microblaze (void); | ||
| 68 | -extern const struct target_desc *tdesc_microblaze; | ||
| 69 | |||
| 70 | static int | ||
| 71 | microblaze_cannot_store_register (int regno) | ||
| 72 | @@ -108,7 +107,7 @@ microblaze_reinsert_addr (struct regcache *regcache) | ||
| 73 | static void | ||
| 74 | microblaze_collect_ptrace_register (struct regcache *regcache, int regno, char *buf) | ||
| 75 | { | ||
| 76 | - int size = register_size (regcache->tdesc, regno); | ||
| 77 | + int size = register_size (regno); | ||
| 78 | |||
| 79 | memset (buf, 0, sizeof (long)); | ||
| 80 | |||
| 81 | @@ -122,7 +121,7 @@ static void | ||
| 82 | microblaze_supply_ptrace_register (struct regcache *regcache, | ||
| 83 | int regno, const char *buf) | ||
| 84 | { | ||
| 85 | - int size = register_size (regcache->tdesc, regno); | ||
| 86 | + int size = register_size (regno); | ||
| 87 | |||
| 88 | if (regno == 0) { | ||
| 89 | unsigned long regbuf_0 = 0; | ||
| 90 | @@ -158,7 +157,7 @@ microblaze_store_gregset (struct regcache *regcache, const void *buf) | ||
| 91 | |||
| 92 | #endif /* HAVE_PTRACE_GETREGS */ | ||
| 93 | |||
| 94 | -static struct regset_info microblaze_regsets[] = { | ||
| 95 | +struct regset_info target_regsets[] = { | ||
| 96 | #ifdef HAVE_PTRACE_GETREGS | ||
| 97 | { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, microblaze_fill_gregset, microblaze_store_gregset }, | ||
| 98 | { 0, 0, 0, -1, -1, NULL, NULL }, | ||
| 99 | @@ -166,41 +165,11 @@ static struct regset_info microblaze_regsets[] = { | ||
| 100 | { 0, 0, 0, -1, -1, NULL, NULL } | ||
| 101 | }; | ||
| 102 | |||
| 103 | -static struct regsets_info microblaze_regsets_info = | ||
| 104 | - { | ||
| 105 | - microblaze_regsets, /* regsets */ | ||
| 106 | - 0, /* num_regsets */ | ||
| 107 | - NULL, /* disabled_regsets */ | ||
| 108 | - }; | ||
| 109 | - | ||
| 110 | -static struct usrregs_info microblaze_usrregs_info = | ||
| 111 | - { | ||
| 112 | - microblaze_num_regs, | ||
| 113 | - microblaze_regmap, | ||
| 114 | - }; | ||
| 115 | - | ||
| 116 | -static struct regs_info regs_info = | ||
| 117 | - { | ||
| 118 | - NULL, /* regset_bitmap */ | ||
| 119 | - µblaze_usrregs_info, | ||
| 120 | - µblaze_regsets_info | ||
| 121 | - }; | ||
| 122 | - | ||
| 123 | -static const struct regs_info * | ||
| 124 | -microblaze_regs_info (void) | ||
| 125 | -{ | ||
| 126 | - return ®s_info; | ||
| 127 | -} | ||
| 128 | - | ||
| 129 | -static void | ||
| 130 | -microblaze_arch_setup (void) | ||
| 131 | -{ | ||
| 132 | - current_process ()->tdesc = tdesc_microblaze; | ||
| 133 | -} | ||
| 134 | - | ||
| 135 | struct linux_target_ops the_low_target = { | ||
| 136 | - microblaze_arch_setup, | ||
| 137 | - microblaze_regs_info, | ||
| 138 | + init_registers_microblaze, | ||
| 139 | + microblaze_num_regs, | ||
| 140 | + microblaze_regmap, | ||
| 141 | + NULL, | ||
| 142 | microblaze_cannot_fetch_register, | ||
| 143 | microblaze_cannot_store_register, | ||
| 144 | NULL, /* fetch_register */ | ||
| 145 | @@ -218,11 +187,3 @@ struct linux_target_ops the_low_target = { | ||
| 146 | microblaze_collect_ptrace_register, | ||
| 147 | microblaze_supply_ptrace_register, | ||
| 148 | }; | ||
| 149 | - | ||
| 150 | -void | ||
| 151 | -initialize_low_arch (void) | ||
| 152 | -{ | ||
| 153 | - init_registers_microblaze (); | ||
| 154 | - | ||
| 155 | - initialize_regsets_info (µblaze_regsets_info); | ||
| 156 | -} | ||
| 157 | \ No newline at end of file | ||
| 158 | -- | ||
| 159 | 1.7.9.5 | ||
| 160 | |||
diff --git a/recipes-devtools/gdb/files/0011-Patch-microblaze-Add-mb-singlestepping.patch b/recipes-devtools/gdb/files/0011-Patch-microblaze-Add-mb-singlestepping.patch new file mode 100644 index 00000000..51b2e36e --- /dev/null +++ b/recipes-devtools/gdb/files/0011-Patch-microblaze-Add-mb-singlestepping.patch | |||
| @@ -0,0 +1,196 @@ | |||
| 1 | From: "Edgar E. Iglesias" <edgar@axis.com> | ||
| 2 | Date: Fri, 24 Feb 2012 11:52:30 +0100 | ||
| 3 | Subject: Add mb singlestepping. | ||
| 4 | |||
| 5 | Fix prologue analysis for little-endian. | ||
| 6 | Always provide a frame base. | ||
| 7 | |||
| 8 | Signed-off-by: Edgar E. Iglesias <edgar@axis.com> | ||
| 9 | |||
| 10 | Conflicts: | ||
| 11 | |||
| 12 | gdb/microblaze-tdep.c | ||
| 13 | |||
| 14 | Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 15 | Upstream-Status: Pending | ||
| 16 | --- | ||
| 17 | gdb/microblaze-tdep.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++-- | ||
| 18 | 1 file changed, 114 insertions(+), 3 deletions(-) | ||
| 19 | |||
| 20 | diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c | ||
| 21 | index a245169..9c9f3a9 100644 | ||
| 22 | --- a/gdb/microblaze-tdep.c | ||
| 23 | +++ b/gdb/microblaze-tdep.c | ||
| 24 | @@ -282,6 +282,8 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, | ||
| 25 | int flags = 0; | ||
| 26 | int save_hidden_pointer_found = 0; | ||
| 27 | int non_stack_instruction_found = 0; | ||
| 28 | + int n_insns; | ||
| 29 | + unsigned int *insn_block; | ||
| 30 | |||
| 31 | /* Find the start of this function. */ | ||
| 32 | find_pc_partial_function (pc, &name, &func_addr, &func_end); | ||
| 33 | @@ -321,11 +323,17 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, | ||
| 34 | name, paddress (gdbarch, func_addr), | ||
| 35 | paddress (gdbarch, stop)); | ||
| 36 | |||
| 37 | + /* Do a block read to minimize the transaction with the Debug Agent */ | ||
| 38 | + n_insns = (stop == func_addr) ? 1 : ((stop - func_addr) / INST_WORD_SIZE); | ||
| 39 | + insn_block = calloc(n_insns, sizeof(unsigned long)); | ||
| 40 | + | ||
| 41 | + target_read_memory (func_addr, (void*) insn_block, n_insns * INST_WORD_SIZE ); | ||
| 42 | + | ||
| 43 | for (addr = func_addr; addr < stop; addr += INST_WORD_SIZE) | ||
| 44 | { | ||
| 45 | insn = microblaze_fetch_instruction (addr); | ||
| 46 | op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm); | ||
| 47 | - microblaze_debug ("%s %08lx\n", paddress (gdbarch, pc), insn); | ||
| 48 | + microblaze_debug ("%s %08lx op=%x r%d r%d imm=%d\n", paddress (gdbarch, addr), insn, op, rd, ra, imm); | ||
| 49 | |||
| 50 | /* This code is very sensitive to what functions are present in the | ||
| 51 | prologue. It assumes that the (addi, addik, swi, sw) can be the | ||
| 52 | @@ -449,7 +457,7 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, | ||
| 53 | part of the prologue. */ | ||
| 54 | if (save_hidden_pointer_found) | ||
| 55 | prologue_end_addr -= INST_WORD_SIZE; | ||
| 56 | - | ||
| 57 | + free(insn_block); | ||
| 58 | return prologue_end_addr; | ||
| 59 | } | ||
| 60 | |||
| 61 | @@ -523,6 +531,7 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache) | ||
| 62 | |||
| 63 | func = get_frame_func (next_frame); | ||
| 64 | |||
| 65 | + cache->base = get_frame_register_unsigned (next_frame, gdbarch_sp_regnum (gdbarch)); | ||
| 66 | cache->pc = get_frame_address_in_block (next_frame); | ||
| 67 | |||
| 68 | return cache; | ||
| 69 | @@ -539,7 +548,7 @@ microblaze_frame_this_id (struct frame_info *next_frame, void **this_cache, | ||
| 70 | if (cache->base == 0) | ||
| 71 | return; | ||
| 72 | |||
| 73 | - (*this_id) = frame_id_build (cache->base, cache->pc); | ||
| 74 | + (*this_id) = frame_id_build (cache->base, get_frame_pc (next_frame)); | ||
| 75 | } | ||
| 76 | |||
| 77 | static struct value * | ||
| 78 | @@ -682,6 +691,107 @@ microblaze_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type) | ||
| 79 | return (TYPE_LENGTH (type) == 16); | ||
| 80 | } | ||
| 81 | |||
| 82 | +int | ||
| 83 | +microblaze_software_single_step (struct frame_info *frame) | ||
| 84 | +{ | ||
| 85 | + struct gdbarch *arch = get_frame_arch (frame); | ||
| 86 | + struct address_space *aspace = get_frame_address_space (frame); | ||
| 87 | + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); | ||
| 88 | + static char le_breakp[] = MICROBLAZE_BREAKPOINT_LE; | ||
| 89 | + static char be_breakp[] = MICROBLAZE_BREAKPOINT; | ||
| 90 | + enum bfd_endian byte_order = gdbarch_byte_order (arch); | ||
| 91 | + char *breakp = byte_order == BFD_ENDIAN_BIG ? be_breakp : le_breakp; | ||
| 92 | + int ret = 0; | ||
| 93 | + | ||
| 94 | + /* Save the address and the values of the next_pc and the target */ | ||
| 95 | + static struct sstep_breaks | ||
| 96 | + { | ||
| 97 | + CORE_ADDR address; | ||
| 98 | + bfd_boolean valid; | ||
| 99 | + /* Shadow contents. */ | ||
| 100 | + char data[INST_WORD_SIZE]; | ||
| 101 | + } stepbreaks[2]; | ||
| 102 | + int ii; | ||
| 103 | + | ||
| 104 | + if (1) | ||
| 105 | + { | ||
| 106 | + CORE_ADDR pc; | ||
| 107 | + long insn; | ||
| 108 | + enum microblaze_instr minstr; | ||
| 109 | + bfd_boolean isunsignednum; | ||
| 110 | + enum microblaze_instr_type insn_type; | ||
| 111 | + short delay_slots; | ||
| 112 | + int imm; | ||
| 113 | + bfd_boolean immfound = FALSE; | ||
| 114 | + | ||
| 115 | + /* Set a breakpoint at the next instruction */ | ||
| 116 | + /* If the current instruction is an imm, set it at the inst after */ | ||
| 117 | + /* If the instruction has a delay slot, skip the delay slot */ | ||
| 118 | + pc = get_frame_pc (frame); | ||
| 119 | + insn = microblaze_fetch_instruction (pc); | ||
| 120 | + minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots); | ||
| 121 | + if (insn_type == immediate_inst) | ||
| 122 | + { | ||
| 123 | + int rd, ra, rb; | ||
| 124 | + immfound = TRUE; | ||
| 125 | + minstr = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm); | ||
| 126 | + pc = pc + INST_WORD_SIZE; | ||
| 127 | + insn = microblaze_fetch_instruction (pc); | ||
| 128 | + minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots); | ||
| 129 | + } | ||
| 130 | + stepbreaks[0].address = pc + (delay_slots * INST_WORD_SIZE) + INST_WORD_SIZE; | ||
| 131 | + if (insn_type != return_inst) { | ||
| 132 | + stepbreaks[0].valid = TRUE; | ||
| 133 | + } else { | ||
| 134 | + stepbreaks[0].valid = FALSE; | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + microblaze_debug ("single-step insn_type=%x insn=%x\n", insn_type, insn); | ||
| 138 | + /* Now check for branch or return instructions */ | ||
| 139 | + if (insn_type == branch_inst || insn_type == return_inst) { | ||
| 140 | + int limm; | ||
| 141 | + int lrd, lra, lrb; | ||
| 142 | + int ra, rb; | ||
| 143 | + bfd_boolean targetvalid; | ||
| 144 | + bfd_boolean unconditionalbranch; | ||
| 145 | + microblaze_decode_insn(insn, &lrd, &lra, &lrb, &limm); | ||
| 146 | + if (lra >= 0 && lra < MICROBLAZE_NUM_REGS) | ||
| 147 | + ra = get_frame_register_unsigned (frame, lra); | ||
| 148 | + else | ||
| 149 | + ra = 0; | ||
| 150 | + if (lrb >= 0 && lrb < MICROBLAZE_NUM_REGS) | ||
| 151 | + rb = get_frame_register_unsigned (frame, lrb); | ||
| 152 | + else | ||
| 153 | + rb = 0; | ||
| 154 | + stepbreaks[1].address = microblaze_get_target_address (insn, immfound, imm, pc, ra, rb, &targetvalid, &unconditionalbranch); | ||
| 155 | + microblaze_debug ("single-step uncondbr=%d targetvalid=%d target=%x\n", unconditionalbranch, targetvalid, stepbreaks[1].address); | ||
| 156 | + if (unconditionalbranch) | ||
| 157 | + stepbreaks[0].valid = FALSE; /* This is a unconditional branch: will not come to the next address */ | ||
| 158 | + if (targetvalid && (stepbreaks[0].valid == FALSE || | ||
| 159 | + (stepbreaks[0].address != stepbreaks[1].address)) | ||
| 160 | + && (stepbreaks[1].address != pc)) { | ||
| 161 | + stepbreaks[1].valid = TRUE; | ||
| 162 | + } else { | ||
| 163 | + stepbreaks[1].valid = FALSE; | ||
| 164 | + } | ||
| 165 | + } else { | ||
| 166 | + stepbreaks[1].valid = FALSE; | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + /* Insert the breakpoints */ | ||
| 170 | + for (ii = 0; ii < 2; ++ii) | ||
| 171 | + { | ||
| 172 | + | ||
| 173 | + /* ignore invalid breakpoint. */ | ||
| 174 | + if (stepbreaks[ii].valid) { | ||
| 175 | + insert_single_step_breakpoint (arch, aspace, stepbreaks[ii].address); | ||
| 176 | + ret = 1; | ||
| 177 | + } | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | + return ret; | ||
| 181 | +} | ||
| 182 | + | ||
| 183 | static void | ||
| 184 | microblaze_write_pc (struct regcache *regcache, CORE_ADDR pc) | ||
| 185 | { | ||
| 186 | @@ -832,6 +942,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | ||
| 187 | set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint); | ||
| 188 | |||
| 189 | set_gdbarch_breakpoint_from_pc (gdbarch, microblaze_breakpoint_from_pc); | ||
| 190 | + set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step); | ||
| 191 | |||
| 192 | set_gdbarch_frame_args_skip (gdbarch, 8); | ||
| 193 | |||
| 194 | -- | ||
| 195 | 1.7.9.5 | ||
| 196 | |||
diff --git a/recipes-devtools/gdb/files/0012-Added-Backtrace-support-to-GDB.patch b/recipes-devtools/gdb/files/0012-Added-Backtrace-support-to-GDB.patch new file mode 100644 index 00000000..b6bbe497 --- /dev/null +++ b/recipes-devtools/gdb/files/0012-Added-Backtrace-support-to-GDB.patch | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | From: nagaraju <nmekala@xilix.com> | ||
| 2 | Date: Tue, 3 Sep 2013 12:09:47 +0530 | ||
| 3 | Subject: Added Backtrace support to GDB | ||
| 4 | |||
| 5 | Added backtrace support without debugging information, Earlier backtrace used to work only when debug information is avialable. | ||
| 6 | Previous pc & sp values are calculated incorrectly due to which backtrace was failing. | ||
| 7 | In this patch, previous frame sp & pc values are calculated correctly in microblaze_frame_cache function | ||
| 8 | and supplied them to microblaze_frame_prev_register function | ||
| 9 | |||
| 10 | Signed-off-by:nagaraju <nmekala@xilix.com> | ||
| 11 | Upstream-Status: Pending | ||
| 12 | --- | ||
| 13 | gdb/microblaze-tdep.c | 44 ++++++++++++++++++++++++++++++-------------- | ||
| 14 | gdb/microblaze-tdep.h | 5 +++-- | ||
| 15 | 2 files changed, 33 insertions(+), 16 deletions(-) | ||
| 16 | |||
| 17 | diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c | ||
| 18 | index 9c9f3a9..f4b48a6 100644 | ||
| 19 | --- a/gdb/microblaze-tdep.c | ||
| 20 | +++ b/gdb/microblaze-tdep.c | ||
| 21 | @@ -226,6 +226,7 @@ microblaze_alloc_frame_cache (void) | ||
| 22 | /* Base address. */ | ||
| 23 | cache->base = 0; | ||
| 24 | cache->pc = 0; | ||
| 25 | + cache->saved_sp = 0; | ||
| 26 | |||
| 27 | /* Frameless until proven otherwise. */ | ||
| 28 | cache->frameless_p = 1; | ||
| 29 | @@ -347,6 +348,7 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, | ||
| 30 | cache->frameless_p = 0; /* Frame found. */ | ||
| 31 | save_hidden_pointer_found = 0; | ||
| 32 | non_stack_instruction_found = 0; | ||
| 33 | + cache->register_offsets[rd] = -imm; | ||
| 34 | continue; | ||
| 35 | } | ||
| 36 | else if (IS_SPILL_SP(op, rd, ra)) | ||
| 37 | @@ -508,6 +510,7 @@ microblaze_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) | ||
| 38 | return start_pc; | ||
| 39 | } | ||
| 40 | |||
| 41 | +enum { REG_UNAVAIL = (CORE_ADDR) -1 }; | ||
| 42 | /* Normal frames. */ | ||
| 43 | |||
| 44 | static struct microblaze_frame_cache * | ||
| 45 | @@ -515,7 +518,7 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache) | ||
| 46 | { | ||
| 47 | struct microblaze_frame_cache *cache; | ||
| 48 | struct gdbarch *gdbarch = get_frame_arch (next_frame); | ||
| 49 | - CORE_ADDR func; | ||
| 50 | + CORE_ADDR current_pc; | ||
| 51 | int rn; | ||
| 52 | |||
| 53 | if (*this_cache) | ||
| 54 | @@ -529,10 +532,18 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache) | ||
| 55 | for (rn = 0; rn < gdbarch_num_regs (gdbarch); rn++) | ||
| 56 | cache->register_offsets[rn] = -1; | ||
| 57 | |||
| 58 | - func = get_frame_func (next_frame); | ||
| 59 | + cache->pc = get_frame_func (next_frame); | ||
| 60 | + current_pc = get_frame_pc (next_frame); | ||
| 61 | + | ||
| 62 | + if (cache->pc) | ||
| 63 | + microblaze_analyze_prologue (gdbarch, cache->pc, current_pc, | ||
| 64 | + cache); | ||
| 65 | |||
| 66 | cache->base = get_frame_register_unsigned (next_frame, gdbarch_sp_regnum (gdbarch)); | ||
| 67 | - cache->pc = get_frame_address_in_block (next_frame); | ||
| 68 | + cache->saved_sp = cache->base + cache->framesize; | ||
| 69 | + | ||
| 70 | + cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM] = cache->base; | ||
| 71 | + cache->register_offsets[MICROBLAZE_SP_REGNUM] = cache->saved_sp; | ||
| 72 | |||
| 73 | return cache; | ||
| 74 | } | ||
| 75 | @@ -548,7 +559,7 @@ microblaze_frame_this_id (struct frame_info *next_frame, void **this_cache, | ||
| 76 | if (cache->base == 0) | ||
| 77 | return; | ||
| 78 | |||
| 79 | - (*this_id) = frame_id_build (cache->base, get_frame_pc (next_frame)); | ||
| 80 | + (*this_id) = frame_id_build (cache->base, cache->pc); | ||
| 81 | } | ||
| 82 | |||
| 83 | static struct value * | ||
| 84 | @@ -558,18 +569,23 @@ microblaze_frame_prev_register (struct frame_info *this_frame, | ||
| 85 | struct microblaze_frame_cache *cache = | ||
| 86 | microblaze_frame_cache (this_frame, this_cache); | ||
| 87 | |||
| 88 | - if (cache->frameless_p) | ||
| 89 | + if ((regnum == MICROBLAZE_SP_REGNUM && | ||
| 90 | + cache->register_offsets[MICROBLAZE_SP_REGNUM]) | ||
| 91 | + || (regnum == MICROBLAZE_FP_REGNUM && | ||
| 92 | + cache->register_offsets[MICROBLAZE_SP_REGNUM])) | ||
| 93 | + | ||
| 94 | + return frame_unwind_got_constant (this_frame, regnum, | ||
| 95 | + cache->register_offsets[MICROBLAZE_SP_REGNUM]); | ||
| 96 | + | ||
| 97 | + if (regnum == MICROBLAZE_PC_REGNUM) | ||
| 98 | { | ||
| 99 | - if (regnum == MICROBLAZE_PC_REGNUM) | ||
| 100 | - regnum = 15; | ||
| 101 | - if (regnum == MICROBLAZE_SP_REGNUM) | ||
| 102 | - regnum = 1; | ||
| 103 | - return trad_frame_get_prev_register (this_frame, | ||
| 104 | - cache->saved_regs, regnum); | ||
| 105 | + regnum = 15; | ||
| 106 | + return frame_unwind_got_memory (this_frame, regnum, | ||
| 107 | + cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM]); | ||
| 108 | } | ||
| 109 | - else | ||
| 110 | - return trad_frame_get_prev_register (this_frame, cache->saved_regs, | ||
| 111 | - regnum); | ||
| 112 | + | ||
| 113 | + return trad_frame_get_prev_register (this_frame, cache->saved_regs, | ||
| 114 | + regnum); | ||
| 115 | |||
| 116 | } | ||
| 117 | |||
| 118 | diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h | ||
| 119 | index 23dc77a..cf24ed4 100644 | ||
| 120 | --- a/gdb/microblaze-tdep.h | ||
| 121 | +++ b/gdb/microblaze-tdep.h | ||
| 122 | @@ -57,6 +57,7 @@ struct microblaze_frame_cache | ||
| 123 | |||
| 124 | /* Offsets to saved registers. */ | ||
| 125 | int register_offsets[59]; /* Must match MICROBLAZE_NUM_REGS. */ | ||
| 126 | + CORE_ADDR saved_sp; | ||
| 127 | |||
| 128 | /* Table of saved registers. */ | ||
| 129 | struct trad_frame_saved_reg *saved_regs; | ||
| 130 | @@ -80,11 +81,11 @@ enum microblaze_regnum | ||
| 131 | MICROBLAZE_R12_REGNUM, | ||
| 132 | MICROBLAZE_R13_REGNUM, | ||
| 133 | MICROBLAZE_R14_REGNUM, | ||
| 134 | - MICROBLAZE_R15_REGNUM, | ||
| 135 | + MICROBLAZE_R15_REGNUM, MICROBLAZE_PREV_PC_REGNUM = MICROBLAZE_R15_REGNUM, | ||
| 136 | MICROBLAZE_R16_REGNUM, | ||
| 137 | MICROBLAZE_R17_REGNUM, | ||
| 138 | MICROBLAZE_R18_REGNUM, | ||
| 139 | - MICROBLAZE_R19_REGNUM, | ||
| 140 | + MICROBLAZE_R19_REGNUM, MICROBLAZE_FP_REGNUM = MICROBLAZE_R19_REGNUM, | ||
| 141 | MICROBLAZE_R20_REGNUM, | ||
| 142 | MICROBLAZE_R21_REGNUM, | ||
| 143 | MICROBLAZE_R22_REGNUM, | ||
| 144 | -- | ||
| 145 | 1.7.9.5 | ||
| 146 | |||
diff --git a/recipes-devtools/gdb/files/0013-microblaze-Handle-framless-functions-in-determining-.patch b/recipes-devtools/gdb/files/0013-microblaze-Handle-framless-functions-in-determining-.patch new file mode 100644 index 00000000..70dcbe43 --- /dev/null +++ b/recipes-devtools/gdb/files/0013-microblaze-Handle-framless-functions-in-determining-.patch | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | From: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 2 | Date: Thu, 7 Nov 2013 16:58:48 +1000 | ||
| 3 | Subject: microblaze: Handle framless functions in determining | ||
| 4 | prev reg | ||
| 5 | |||
| 6 | Add check for cache->frameless_p in microblaze_frame_prev_register | ||
| 7 | to handle frameless functions, and correct the behaviour of using | ||
| 8 | 'next' to step through debugging | ||
| 9 | |||
| 10 | Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 11 | Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com> | ||
| 12 | Upstream-Status: Pending | ||
| 13 | --- | ||
| 14 | gdb/microblaze-tdep.c | 10 ++++++++++ | ||
| 15 | 1 file changed, 10 insertions(+) | ||
| 16 | |||
| 17 | diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c | ||
| 18 | index f4b48a6..a85adea6 100644 | ||
| 19 | --- a/gdb/microblaze-tdep.c | ||
| 20 | +++ b/gdb/microblaze-tdep.c | ||
| 21 | @@ -577,6 +577,16 @@ microblaze_frame_prev_register (struct frame_info *this_frame, | ||
| 22 | return frame_unwind_got_constant (this_frame, regnum, | ||
| 23 | cache->register_offsets[MICROBLAZE_SP_REGNUM]); | ||
| 24 | |||
| 25 | + if (cache->frameless_p) | ||
| 26 | + { | ||
| 27 | + if (regnum == MICROBLAZE_PC_REGNUM) | ||
| 28 | + regnum = 15; | ||
| 29 | + if (regnum == MICROBLAZE_SP_REGNUM) | ||
| 30 | + regnum = 1; | ||
| 31 | + return trad_frame_get_prev_register (this_frame, | ||
| 32 | + cache->saved_regs, regnum); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | if (regnum == MICROBLAZE_PC_REGNUM) | ||
| 36 | { | ||
| 37 | regnum = 15; | ||
| 38 | -- | ||
| 39 | 1.7.9.5 | ||
| 40 | |||
diff --git a/recipes-devtools/gdb/files/0014-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch b/recipes-devtools/gdb/files/0014-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch new file mode 100644 index 00000000..78067c87 --- /dev/null +++ b/recipes-devtools/gdb/files/0014-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | From: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 2 | Date: Mon, 16 Dec 2013 16:37:32 +1000 | ||
| 3 | Subject: microblaze: Add build_gdbserver=yes to top level configure.tgt | ||
| 4 | |||
| 5 | For Microblaze linux toolchains, set the build_gdbserver=yes | ||
| 6 | to allow driving gdbserver configuration from the upper level | ||
| 7 | |||
| 8 | This patch has been absorbed into the original patch to add | ||
| 9 | linux gdbserver support for Microblaze. | ||
| 10 | |||
| 11 | Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 12 | Upstream-Status: Pending | ||
| 13 | --- | ||
| 14 | gdb/configure.tgt | 1 + | ||
| 15 | 1 file changed, 1 insertion(+) | ||
| 16 | |||
| 17 | diff --git a/gdb/configure.tgt b/gdb/configure.tgt | ||
| 18 | index 1285aac..6ea10a2 100644 | ||
| 19 | --- a/gdb/configure.tgt | ||
| 20 | +++ b/gdb/configure.tgt | ||
| 21 | @@ -342,6 +342,7 @@ microblaze*-linux-*|microblaze*-*-linux*) | ||
| 22 | gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o microblaze-rom.o glibc-tdep.o \ | ||
| 23 | monitor.o dsrec.o solib-svr4.o symfile-mem.o linux-tdep.o" | ||
| 24 | gdb_sim=../sim/microblaze/libsim.a | ||
| 25 | + build_gdbserver=yes | ||
| 26 | ;; | ||
| 27 | microblaze*-*-*) | ||
| 28 | # Target: Xilinx MicroBlaze running standalone | ||
| 29 | -- | ||
| 30 | 1.7.9.5 | ||
| 31 | |||
diff --git a/recipes-devtools/gdb/gdb-cross-canadian_7.6.1.bbappend b/recipes-devtools/gdb/gdb-cross-canadian_7.6.1.bbappend new file mode 100644 index 00000000..db1e3127 --- /dev/null +++ b/recipes-devtools/gdb/gdb-cross-canadian_7.6.1.bbappend | |||
| @@ -0,0 +1 @@ | |||
| require gdb-microblaze-${PV}.inc | |||
diff --git a/recipes-devtools/gdb/gdb-cross_7.6.1.bbappend b/recipes-devtools/gdb/gdb-cross_7.6.1.bbappend new file mode 100644 index 00000000..db1e3127 --- /dev/null +++ b/recipes-devtools/gdb/gdb-cross_7.6.1.bbappend | |||
| @@ -0,0 +1 @@ | |||
| require gdb-microblaze-${PV}.inc | |||
diff --git a/recipes-devtools/gdb/gdb-microblaze-7.6.1.inc b/recipes-devtools/gdb/gdb-microblaze-7.6.1.inc new file mode 100644 index 00000000..9f30eb9a --- /dev/null +++ b/recipes-devtools/gdb/gdb-microblaze-7.6.1.inc | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | |||
| 2 | # MicroBlaze does not support LTTng UST | ||
| 3 | LTTNGUST_microblaze = "" | ||
| 4 | |||
| 5 | # Add MicroBlaze Patches | ||
| 6 | FILESEXTRAPATHS_append := "${THISDIR}/files:" | ||
| 7 | SRC_URI_append += " \ | ||
| 8 | file://0001-Add-initial-port-of-linux-gdbserver.patch \ | ||
| 9 | file://0002-Initial-port-of-core-reading-support.patch \ | ||
| 10 | file://0003-Initial-support-for-native-gdb.patch \ | ||
| 11 | file://0004-Robustify-inline-function-support.patch \ | ||
| 12 | file://0005-Fix-debug-message-when-register-is-unavailable.patch \ | ||
| 13 | file://0006-Add-slr-and-shr-regs-and-little-endian-breakpoint.patch \ | ||
| 14 | file://0007-Fix-relaxation-of-assembler-resolved-references.patch \ | ||
| 15 | file://0008-Fixup-debug_loc-sections-after-linker-relaxation.patch \ | ||
| 16 | file://0009-Add-wdc.ext.clear-and-wdc.ext.flush-insns.patch \ | ||
| 17 | file://0010-revert-master-rebase-changes-to-gdbserver.patch \ | ||
| 18 | file://0011-Patch-microblaze-Add-mb-singlestepping.patch \ | ||
| 19 | file://0012-Added-Backtrace-support-to-GDB.patch \ | ||
| 20 | file://0013-microblaze-Handle-framless-functions-in-determining-.patch \ | ||
| 21 | file://0014-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch \ | ||
| 22 | " | ||
diff --git a/recipes-devtools/gdb/gdb_7.6.1.bbappend b/recipes-devtools/gdb/gdb_7.6.1.bbappend new file mode 100644 index 00000000..db1e3127 --- /dev/null +++ b/recipes-devtools/gdb/gdb_7.6.1.bbappend | |||
| @@ -0,0 +1 @@ | |||
| require gdb-microblaze-${PV}.inc | |||
