diff options
author | Paul Clothier <Paul.Clothier@imgtec.com> | 2013-03-19 08:04:43 -0400 |
---|---|---|
committer | James Hogan <james.hogan@imgtec.com> | 2013-03-27 10:37:47 -0400 |
commit | 876d6dcdf26a2e860801ec61195e580d03f7b204 (patch) | |
tree | 33f1145d6f524c75128747c90206ea70487f3b09 | |
parent | 2b8660ed3bfe95523561e6d6a6f1ce91389006b1 (diff) |
metag: ptrace: Implement NT_METAG_TLS
Implement functionality to get the TLS pointer for the metag
architecture using regsets.
This provides multi-threaded debug support for GDB.
Signed-off-by: Paul Clothier <Paul.Clothier@imgtec.com>
Signed-off-by: James Hogan <james.hogan@imgtec.com>
-rw-r--r-- | arch/metag/kernel/ptrace.c | 34 | ||||
-rw-r--r-- | include/uapi/linux/elf.h | 1 |
2 files changed, 35 insertions, 0 deletions
diff --git a/arch/metag/kernel/ptrace.c b/arch/metag/kernel/ptrace.c index 47a8828615a5..7563628822bd 100644 --- a/arch/metag/kernel/ptrace.c +++ b/arch/metag/kernel/ptrace.c | |||
@@ -288,10 +288,36 @@ static int metag_rp_state_set(struct task_struct *target, | |||
288 | return metag_rp_state_copyin(regs, pos, count, kbuf, ubuf); | 288 | return metag_rp_state_copyin(regs, pos, count, kbuf, ubuf); |
289 | } | 289 | } |
290 | 290 | ||
291 | static int metag_tls_get(struct task_struct *target, | ||
292 | const struct user_regset *regset, | ||
293 | unsigned int pos, unsigned int count, | ||
294 | void *kbuf, void __user *ubuf) | ||
295 | { | ||
296 | void __user *tls = target->thread.tls_ptr; | ||
297 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); | ||
298 | } | ||
299 | |||
300 | static int metag_tls_set(struct task_struct *target, | ||
301 | const struct user_regset *regset, | ||
302 | unsigned int pos, unsigned int count, | ||
303 | const void *kbuf, const void __user *ubuf) | ||
304 | { | ||
305 | int ret; | ||
306 | void __user *tls; | ||
307 | |||
308 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); | ||
309 | if (ret) | ||
310 | return ret; | ||
311 | |||
312 | target->thread.tls_ptr = tls; | ||
313 | return ret; | ||
314 | } | ||
315 | |||
291 | enum metag_regset { | 316 | enum metag_regset { |
292 | REGSET_GENERAL, | 317 | REGSET_GENERAL, |
293 | REGSET_CBUF, | 318 | REGSET_CBUF, |
294 | REGSET_READPIPE, | 319 | REGSET_READPIPE, |
320 | REGSET_TLS, | ||
295 | }; | 321 | }; |
296 | 322 | ||
297 | static const struct user_regset metag_regsets[] = { | 323 | static const struct user_regset metag_regsets[] = { |
@@ -319,6 +345,14 @@ static const struct user_regset metag_regsets[] = { | |||
319 | .get = metag_rp_state_get, | 345 | .get = metag_rp_state_get, |
320 | .set = metag_rp_state_set, | 346 | .set = metag_rp_state_set, |
321 | }, | 347 | }, |
348 | [REGSET_TLS] = { | ||
349 | .core_note_type = NT_METAG_TLS, | ||
350 | .n = 1, | ||
351 | .size = sizeof(void *), | ||
352 | .align = sizeof(void *), | ||
353 | .get = metag_tls_get, | ||
354 | .set = metag_tls_set, | ||
355 | }, | ||
322 | }; | 356 | }; |
323 | 357 | ||
324 | static const struct user_regset_view user_metag_view = { | 358 | static const struct user_regset_view user_metag_view = { |
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index 8072d352b98f..ef6103bf1f9b 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h | |||
@@ -397,6 +397,7 @@ typedef struct elf64_shdr { | |||
397 | #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ | 397 | #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ |
398 | #define NT_METAG_CBUF 0x500 /* Metag catch buffer registers */ | 398 | #define NT_METAG_CBUF 0x500 /* Metag catch buffer registers */ |
399 | #define NT_METAG_RPIPE 0x501 /* Metag read pipeline state */ | 399 | #define NT_METAG_RPIPE 0x501 /* Metag read pipeline state */ |
400 | #define NT_METAG_TLS 0x502 /* Metag TLS pointer */ | ||
400 | 401 | ||
401 | 402 | ||
402 | /* Note header in a PT_NOTE section */ | 403 | /* Note header in a PT_NOTE section */ |