diff options
Diffstat (limited to 'meta-microblaze/recipes-devtools/gdb/gdb/0038-Initial-support-for-native-gdb.patch')
-rw-r--r-- | meta-microblaze/recipes-devtools/gdb/gdb/0038-Initial-support-for-native-gdb.patch | 511 |
1 files changed, 511 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/gdb/gdb/0038-Initial-support-for-native-gdb.patch b/meta-microblaze/recipes-devtools/gdb/gdb/0038-Initial-support-for-native-gdb.patch new file mode 100644 index 00000000..ca37355c --- /dev/null +++ b/meta-microblaze/recipes-devtools/gdb/gdb/0038-Initial-support-for-native-gdb.patch | |||
@@ -0,0 +1,511 @@ | |||
1 | From fef2dfc9c55d19be25262175a4fa4921167a30b7 Mon Sep 17 00:00:00 2001 | ||
2 | From: David Holsgrove <david.holsgrove@petalogix.com> | ||
3 | Date: Fri, 20 Jul 2012 15:18:35 +1000 | ||
4 | Subject: [PATCH 38/43] Initial support for native gdb | ||
5 | |||
6 | microblaze: Follow PPC method of getting setting registers | ||
7 | using PTRACE PEEK/POKE | ||
8 | |||
9 | Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com> | ||
10 | |||
11 | Conflicts: | ||
12 | gdb/Makefile.in | ||
13 | --- | ||
14 | gdb/Makefile.in | 4 +- | ||
15 | gdb/config/microblaze/linux.mh | 9 + | ||
16 | gdb/microblaze-linux-nat.c | 431 +++++++++++++++++++++++++++++++++ | ||
17 | 3 files changed, 443 insertions(+), 1 deletion(-) | ||
18 | create mode 100644 gdb/config/microblaze/linux.mh | ||
19 | create mode 100644 gdb/microblaze-linux-nat.c | ||
20 | |||
21 | diff --git a/gdb/Makefile.in b/gdb/Makefile.in | ||
22 | index 5614cc3386..d620580498 100644 | ||
23 | --- a/gdb/Makefile.in | ||
24 | +++ b/gdb/Makefile.in | ||
25 | @@ -1316,6 +1316,7 @@ HFILES_NO_SRCDIR = \ | ||
26 | memory-map.h \ | ||
27 | memrange.h \ | ||
28 | microblaze-tdep.h \ | ||
29 | + microblaze-linux-tdep.h \ | ||
30 | mips-linux-tdep.h \ | ||
31 | mips-nbsd-tdep.h \ | ||
32 | mips-tdep.h \ | ||
33 | @@ -1349,6 +1350,7 @@ HFILES_NO_SRCDIR = \ | ||
34 | prologue-value.h \ | ||
35 | psympriv.h \ | ||
36 | psymtab.h \ | ||
37 | + ia64-hpux-tdep.h \ | ||
38 | ravenscar-thread.h \ | ||
39 | record.h \ | ||
40 | record-full.h \ | ||
41 | @@ -2263,6 +2265,7 @@ ALLDEPFILES = \ | ||
42 | m68k-tdep.c \ | ||
43 | microblaze-linux-tdep.c \ | ||
44 | microblaze-tdep.c \ | ||
45 | + microblaze-linux-nat.c \ | ||
46 | mingw-hdep.c \ | ||
47 | mips-fbsd-nat.c \ | ||
48 | mips-fbsd-tdep.c \ | ||
49 | @@ -2365,7 +2368,6 @@ ALLDEPFILES = \ | ||
50 | xtensa-linux-tdep.c \ | ||
51 | xtensa-tdep.c \ | ||
52 | xtensa-xtregs.c \ | ||
53 | - common/mingw-strerror.c \ | ||
54 | common/posix-strerror.c | ||
55 | |||
56 | # Some files need explicit build rules (due to -Werror problems) or due | ||
57 | diff --git a/gdb/config/microblaze/linux.mh b/gdb/config/microblaze/linux.mh | ||
58 | new file mode 100644 | ||
59 | index 0000000000..a4eaf540e1 | ||
60 | --- /dev/null | ||
61 | +++ b/gdb/config/microblaze/linux.mh | ||
62 | @@ -0,0 +1,9 @@ | ||
63 | +# Host: Microblaze, running Linux | ||
64 | + | ||
65 | +NAT_FILE= config/nm-linux.h | ||
66 | +NATDEPFILES= inf-ptrace.o fork-child.o \ | ||
67 | + microblaze-linux-nat.o proc-service.o linux-thread-db.o \ | ||
68 | + linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o | ||
69 | +NAT_CDEPS = $(srcdir)/proc-service.list | ||
70 | + | ||
71 | +LOADLIBES = -ldl $(RDYNAMIC) | ||
72 | diff --git a/gdb/microblaze-linux-nat.c b/gdb/microblaze-linux-nat.c | ||
73 | new file mode 100644 | ||
74 | index 0000000000..e9b8c9c522 | ||
75 | --- /dev/null | ||
76 | +++ b/gdb/microblaze-linux-nat.c | ||
77 | @@ -0,0 +1,431 @@ | ||
78 | +/* Microblaze GNU/Linux native support. | ||
79 | + | ||
80 | + Copyright (C) 1988-1989, 1991-1992, 1994, 1996, 2000-2012 Free | ||
81 | + Software Foundation, Inc. | ||
82 | + | ||
83 | + This file is part of GDB. | ||
84 | + | ||
85 | + This program is free software; you can redistribute it and/or modify | ||
86 | + it under the terms of the GNU General Public License as published by | ||
87 | + the Free Software Foundation; either version 3 of the License, or | ||
88 | + (at your option) any later version. | ||
89 | + | ||
90 | + This program is distributed in the hope that it will be useful, | ||
91 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
92 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
93 | + GNU General Public License for more details. | ||
94 | + | ||
95 | + You should have received a copy of the GNU General Public License | ||
96 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
97 | + | ||
98 | +#include "defs.h" | ||
99 | +#include "arch-utils.h" | ||
100 | +#include "dis-asm.h" | ||
101 | +#include "frame.h" | ||
102 | +#include "trad-frame.h" | ||
103 | +#include "symtab.h" | ||
104 | +#include "value.h" | ||
105 | +#include "gdbcmd.h" | ||
106 | +#include "breakpoint.h" | ||
107 | +#include "inferior.h" | ||
108 | +#include "regcache.h" | ||
109 | +#include "target.h" | ||
110 | +#include "frame.h" | ||
111 | +#include "frame-base.h" | ||
112 | +#include "frame-unwind.h" | ||
113 | +#include "dwarf2-frame.h" | ||
114 | +#include "osabi.h" | ||
115 | + | ||
116 | +#include "gdb_assert.h" | ||
117 | +#include "gdb_string.h" | ||
118 | +#include "target-descriptions.h" | ||
119 | +#include "opcodes/microblaze-opcm.h" | ||
120 | +#include "opcodes/microblaze-dis.h" | ||
121 | + | ||
122 | +#include "linux-nat.h" | ||
123 | +#include "target-descriptions.h" | ||
124 | + | ||
125 | +#include <sys/user.h> | ||
126 | +#include <sys/utsname.h> | ||
127 | +#include <sys/procfs.h> | ||
128 | +#include <sys/ptrace.h> | ||
129 | + | ||
130 | +/* Prototypes for supply_gregset etc. */ | ||
131 | +#include "gregset.h" | ||
132 | + | ||
133 | +#include "microblaze-tdep.h" | ||
134 | + | ||
135 | +#include <elf/common.h> | ||
136 | +#include "auxv.h" | ||
137 | + | ||
138 | +/* Defines ps_err_e, struct ps_prochandle. */ | ||
139 | +#include "gdb_proc_service.h" | ||
140 | + | ||
141 | +/* On GNU/Linux, threads are implemented as pseudo-processes, in which | ||
142 | + case we may be tracing more than one process at a time. In that | ||
143 | + case, inferior_ptid will contain the main process ID and the | ||
144 | + individual thread (process) ID. get_thread_id () is used to get | ||
145 | + the thread id if it's available, and the process id otherwise. */ | ||
146 | + | ||
147 | +int | ||
148 | +get_thread_id (ptid_t ptid) | ||
149 | +{ | ||
150 | + int tid = TIDGET (ptid); | ||
151 | + if (0 == tid) | ||
152 | + tid = PIDGET (ptid); | ||
153 | + return tid; | ||
154 | +} | ||
155 | + | ||
156 | +#define GET_THREAD_ID(PTID) get_thread_id (PTID) | ||
157 | + | ||
158 | +/* Non-zero if our kernel may support the PTRACE_GETREGS and | ||
159 | + PTRACE_SETREGS requests, for reading and writing the | ||
160 | + general-purpose registers. Zero if we've tried one of | ||
161 | + them and gotten an error. */ | ||
162 | +int have_ptrace_getsetregs = 1; | ||
163 | + | ||
164 | +static int | ||
165 | +microblaze_register_u_addr (struct gdbarch *gdbarch, int regno) | ||
166 | +{ | ||
167 | + int u_addr = -1; | ||
168 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
169 | + /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace | ||
170 | + interface, and not the wordsize of the program's ABI. */ | ||
171 | + int wordsize = sizeof (long); | ||
172 | + | ||
173 | + /* General purpose registers occupy 1 slot each in the buffer. */ | ||
174 | + if (regno >= MICROBLAZE_R0_REGNUM | ||
175 | + && regno <= MICROBLAZE_FSR_REGNUM) | ||
176 | + u_addr = (regno * wordsize); | ||
177 | + | ||
178 | + return u_addr; | ||
179 | +} | ||
180 | + | ||
181 | + | ||
182 | +static void | ||
183 | +fetch_register (struct regcache *regcache, int tid, int regno) | ||
184 | +{ | ||
185 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
186 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
187 | + /* This isn't really an address. But ptrace thinks of it as one. */ | ||
188 | + CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno); | ||
189 | + int bytes_transferred; | ||
190 | + unsigned int offset; /* Offset of registers within the u area. */ | ||
191 | + char buf[MAX_REGISTER_SIZE]; | ||
192 | + | ||
193 | + if (regaddr == -1) | ||
194 | + { | ||
195 | + memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */ | ||
196 | + regcache_raw_supply (regcache, regno, buf); | ||
197 | + return; | ||
198 | + } | ||
199 | + | ||
200 | + /* Read the raw register using sizeof(long) sized chunks. On a | ||
201 | + 32-bit platform, 64-bit floating-point registers will require two | ||
202 | + transfers. */ | ||
203 | + for (bytes_transferred = 0; | ||
204 | + bytes_transferred < register_size (gdbarch, regno); | ||
205 | + bytes_transferred += sizeof (long)) | ||
206 | + { | ||
207 | + long l; | ||
208 | + | ||
209 | + errno = 0; | ||
210 | + l = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0); | ||
211 | + regaddr += sizeof (long); | ||
212 | + if (errno != 0) | ||
213 | + { | ||
214 | + char message[128]; | ||
215 | + sprintf (message, "reading register %s (#%d)", | ||
216 | + gdbarch_register_name (gdbarch, regno), regno); | ||
217 | + perror_with_name (message); | ||
218 | + } | ||
219 | + memcpy (&buf[bytes_transferred], &l, sizeof (l)); | ||
220 | + } | ||
221 | + | ||
222 | + /* Now supply the register. Keep in mind that the regcache's idea | ||
223 | + of the register's size may not be a multiple of sizeof | ||
224 | + (long). */ | ||
225 | + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) | ||
226 | + { | ||
227 | + /* Little-endian values are always found at the left end of the | ||
228 | + bytes transferred. */ | ||
229 | + regcache_raw_supply (regcache, regno, buf); | ||
230 | + } | ||
231 | + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) | ||
232 | + { | ||
233 | + /* Big-endian values are found at the right end of the bytes | ||
234 | + transferred. */ | ||
235 | + size_t padding = (bytes_transferred - register_size (gdbarch, regno)); | ||
236 | + regcache_raw_supply (regcache, regno, buf + padding); | ||
237 | + } | ||
238 | + else | ||
239 | + internal_error (__FILE__, __LINE__, | ||
240 | + _("fetch_register: unexpected byte order: %d"), | ||
241 | + gdbarch_byte_order (gdbarch)); | ||
242 | +} | ||
243 | + | ||
244 | +/* This function actually issues the request to ptrace, telling | ||
245 | + it to get all general-purpose registers and put them into the | ||
246 | + specified regset. | ||
247 | + | ||
248 | + If the ptrace request does not exist, this function returns 0 | ||
249 | + and properly sets the have_ptrace_* flag. If the request fails, | ||
250 | + this function calls perror_with_name. Otherwise, if the request | ||
251 | + succeeds, then the regcache gets filled and 1 is returned. */ | ||
252 | +static int | ||
253 | +fetch_all_gp_regs (struct regcache *regcache, int tid) | ||
254 | +{ | ||
255 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
256 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
257 | + gdb_gregset_t gregset; | ||
258 | + | ||
259 | + if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0) | ||
260 | + { | ||
261 | + if (errno == EIO) | ||
262 | + { | ||
263 | + have_ptrace_getsetregs = 0; | ||
264 | + return 0; | ||
265 | + } | ||
266 | + perror_with_name (_("Couldn't get general-purpose registers.")); | ||
267 | + } | ||
268 | + | ||
269 | + supply_gregset (regcache, (const gdb_gregset_t *) &gregset); | ||
270 | + | ||
271 | + return 1; | ||
272 | +} | ||
273 | + | ||
274 | + | ||
275 | +/* This is a wrapper for the fetch_all_gp_regs function. It is | ||
276 | + responsible for verifying if this target has the ptrace request | ||
277 | + that can be used to fetch all general-purpose registers at one | ||
278 | + shot. If it doesn't, then we should fetch them using the | ||
279 | + old-fashioned way, which is to iterate over the registers and | ||
280 | + request them one by one. */ | ||
281 | +static void | ||
282 | +fetch_gp_regs (struct regcache *regcache, int tid) | ||
283 | +{ | ||
284 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
285 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
286 | + int i; | ||
287 | + | ||
288 | + if (have_ptrace_getsetregs) | ||
289 | + if (fetch_all_gp_regs (regcache, tid)) | ||
290 | + return; | ||
291 | + | ||
292 | + /* If we've hit this point, it doesn't really matter which | ||
293 | + architecture we are using. We just need to read the | ||
294 | + registers in the "old-fashioned way". */ | ||
295 | + for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++) | ||
296 | + fetch_register (regcache, tid, i); | ||
297 | +} | ||
298 | + | ||
299 | + | ||
300 | +static void | ||
301 | +store_register (const struct regcache *regcache, int tid, int regno) | ||
302 | +{ | ||
303 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
304 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
305 | + /* This isn't really an address. But ptrace thinks of it as one. */ | ||
306 | + CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno); | ||
307 | + int i; | ||
308 | + size_t bytes_to_transfer; | ||
309 | + char buf[MAX_REGISTER_SIZE]; | ||
310 | + | ||
311 | + if (regaddr == -1) | ||
312 | + return; | ||
313 | + | ||
314 | + /* First collect the register. Keep in mind that the regcache's | ||
315 | + idea of the register's size may not be a multiple of sizeof | ||
316 | + (long). */ | ||
317 | + memset (buf, 0, sizeof buf); | ||
318 | + bytes_to_transfer = align_up (register_size (gdbarch, regno), sizeof (long)); | ||
319 | + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) | ||
320 | + { | ||
321 | + /* Little-endian values always sit at the left end of the buffer. */ | ||
322 | + regcache_raw_collect (regcache, regno, buf); | ||
323 | + } | ||
324 | + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) | ||
325 | + { | ||
326 | + /* Big-endian values sit at the right end of the buffer. */ | ||
327 | + size_t padding = (bytes_to_transfer - register_size (gdbarch, regno)); | ||
328 | + regcache_raw_collect (regcache, regno, buf + padding); | ||
329 | + } | ||
330 | + | ||
331 | + for (i = 0; i < bytes_to_transfer; i += sizeof (long)) | ||
332 | + { | ||
333 | + long l; | ||
334 | + | ||
335 | + memcpy (&l, &buf[i], sizeof (l)); | ||
336 | + errno = 0; | ||
337 | + ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, l); | ||
338 | + regaddr += sizeof (long); | ||
339 | + | ||
340 | + if (errno != 0) | ||
341 | + { | ||
342 | + char message[128]; | ||
343 | + sprintf (message, "writing register %s (#%d)", | ||
344 | + gdbarch_register_name (gdbarch, regno), regno); | ||
345 | + perror_with_name (message); | ||
346 | + } | ||
347 | + } | ||
348 | +} | ||
349 | + | ||
350 | +/* This function actually issues the request to ptrace, telling | ||
351 | + it to store all general-purpose registers present in the specified | ||
352 | + regset. | ||
353 | + | ||
354 | + If the ptrace request does not exist, this function returns 0 | ||
355 | + and properly sets the have_ptrace_* flag. If the request fails, | ||
356 | + this function calls perror_with_name. Otherwise, if the request | ||
357 | + succeeds, then the regcache is stored and 1 is returned. */ | ||
358 | +static int | ||
359 | +store_all_gp_regs (const struct regcache *regcache, int tid, int regno) | ||
360 | +{ | ||
361 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
362 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
363 | + gdb_gregset_t gregset; | ||
364 | + | ||
365 | + if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0) | ||
366 | + { | ||
367 | + if (errno == EIO) | ||
368 | + { | ||
369 | + have_ptrace_getsetregs = 0; | ||
370 | + return 0; | ||
371 | + } | ||
372 | + perror_with_name (_("Couldn't get general-purpose registers.")); | ||
373 | + } | ||
374 | + | ||
375 | + fill_gregset (regcache, &gregset, regno); | ||
376 | + | ||
377 | + if (ptrace (PTRACE_SETREGS, tid, 0, (void *) &gregset) < 0) | ||
378 | + { | ||
379 | + if (errno == EIO) | ||
380 | + { | ||
381 | + have_ptrace_getsetregs = 0; | ||
382 | + return 0; | ||
383 | + } | ||
384 | + perror_with_name (_("Couldn't set general-purpose registers.")); | ||
385 | + } | ||
386 | + | ||
387 | + return 1; | ||
388 | +} | ||
389 | + | ||
390 | +/* This is a wrapper for the store_all_gp_regs function. It is | ||
391 | + responsible for verifying if this target has the ptrace request | ||
392 | + that can be used to store all general-purpose registers at one | ||
393 | + shot. If it doesn't, then we should store them using the | ||
394 | + old-fashioned way, which is to iterate over the registers and | ||
395 | + store them one by one. */ | ||
396 | +static void | ||
397 | +store_gp_regs (const struct regcache *regcache, int tid, int regno) | ||
398 | +{ | ||
399 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | ||
400 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||
401 | + int i; | ||
402 | + | ||
403 | + if (have_ptrace_getsetregs) | ||
404 | + if (store_all_gp_regs (regcache, tid, regno)) | ||
405 | + return; | ||
406 | + | ||
407 | + /* If we hit this point, it doesn't really matter which | ||
408 | + architecture we are using. We just need to store the | ||
409 | + registers in the "old-fashioned way". */ | ||
410 | + for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++) | ||
411 | + store_register (regcache, tid, i); | ||
412 | +} | ||
413 | + | ||
414 | + | ||
415 | +/* Fetch registers from the child process. Fetch all registers if | ||
416 | + regno == -1, otherwise fetch all general registers or all floating | ||
417 | + point registers depending upon the value of regno. */ | ||
418 | + | ||
419 | +static void | ||
420 | +microblaze_linux_fetch_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 == -1) | ||
427 | + fetch_gp_regs (regcache, tid); | ||
428 | + else | ||
429 | + fetch_register (regcache, tid, regno); | ||
430 | +} | ||
431 | + | ||
432 | +/* Store registers back into the inferior. Store all registers if | ||
433 | + regno == -1, otherwise store all general registers or all floating | ||
434 | + point registers depending upon the value of regno. */ | ||
435 | + | ||
436 | +static void | ||
437 | +microblaze_linux_store_inferior_registers (struct target_ops *ops, | ||
438 | + struct regcache *regcache, int regno) | ||
439 | +{ | ||
440 | + /* Get the thread id for the ptrace call. */ | ||
441 | + int tid = GET_THREAD_ID (inferior_ptid); | ||
442 | + | ||
443 | + if (regno >= 0) | ||
444 | + store_register (regcache, tid, regno); | ||
445 | + else | ||
446 | + store_gp_regs (regcache, tid, -1); | ||
447 | +} | ||
448 | + | ||
449 | +/* Wrapper functions for the standard regset handling, used by | ||
450 | + thread debugging. */ | ||
451 | + | ||
452 | +void | ||
453 | +fill_gregset (const struct regcache *regcache, | ||
454 | + gdb_gregset_t *gregsetp, int regno) | ||
455 | +{ | ||
456 | + microblaze_collect_gregset (NULL, regcache, regno, gregsetp); | ||
457 | +} | ||
458 | + | ||
459 | +void | ||
460 | +supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) | ||
461 | +{ | ||
462 | + microblaze_supply_gregset (NULL, regcache, -1, gregsetp); | ||
463 | +} | ||
464 | + | ||
465 | +void | ||
466 | +fill_fpregset (const struct regcache *regcache, | ||
467 | + gdb_fpregset_t *fpregsetp, int regno) | ||
468 | +{ | ||
469 | + /* FIXME. */ | ||
470 | +} | ||
471 | + | ||
472 | +void | ||
473 | +supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) | ||
474 | +{ | ||
475 | + /* FIXME. */ | ||
476 | +} | ||
477 | + | ||
478 | +static const struct target_desc * | ||
479 | +microblaze_linux_read_description (struct target_ops *ops) | ||
480 | +{ | ||
481 | + CORE_ADDR microblaze_hwcap = 0; | ||
482 | + | ||
483 | + if (target_auxv_search (ops, AT_HWCAP, µblaze_hwcap) != 1) | ||
484 | + return NULL; | ||
485 | + | ||
486 | + return NULL; | ||
487 | +} | ||
488 | + | ||
489 | + | ||
490 | +void _initialize_microblaze_linux_nat (void); | ||
491 | + | ||
492 | +void | ||
493 | +_initialize_microblaze_linux_nat (void) | ||
494 | +{ | ||
495 | + struct target_ops *t; | ||
496 | + | ||
497 | + /* Fill in the generic GNU/Linux methods. */ | ||
498 | + t = linux_target (); | ||
499 | + | ||
500 | + /* Add our register access methods. */ | ||
501 | + t->to_fetch_registers = microblaze_linux_fetch_inferior_registers; | ||
502 | + t->to_store_registers = microblaze_linux_store_inferior_registers; | ||
503 | + | ||
504 | + t->to_read_description = microblaze_linux_read_description; | ||
505 | + | ||
506 | + /* Register the target. */ | ||
507 | + linux_nat_add_target (t); | ||
508 | +} | ||
509 | -- | ||
510 | 2.17.1 | ||
511 | |||