linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* nios2: is the ptrace ABI correct?
@ 2015-02-24  3:04 Ezequiel Garcia
  2015-02-24  8:54 ` Arnd Bergmann
  0 siblings, 1 reply; 18+ messages in thread
From: Ezequiel Garcia @ 2015-02-24  3:04 UTC (permalink / raw)
  To: Tobias Klauser, Chung-Ling Tang, Walter Goossens, Ley Foon Tan,
	Arnd Bergmann
  Cc: linux-arch, nios2-dev@lists.rocketboards.org,
	linux-kernel@vger.kernel.org

Hi everyone,

I've been trying to port strace to Nios-II, but came across some oddities
in the ptrace ABI. The pt_regs structure is exposed to userspace through
the ptrace.h UAPI header: arch/nios2/include/uapi/asm/ptrace.h

Such pt_regs has the following layout:

struct pt_regs {
        unsigned long  r8;
        unsigned long  r9;
        unsigned long  r10;
[and so on]
}

But the regset implementation in arch/nios2/kernel/ptrace.c
pushes a different layout to userspace, as it uses the PTR_
macros, also in the UAPI header:

#define PTR_R0          0
#define PTR_R1          1
#define PTR_R2          2
#define PTR_R3          3
#define PTR_R4          4
#define PTR_R5          5
#define PTR_R6          6
#define PTR_R7          7
#define PTR_R8          8
[..]

In other words, the PTRACE_GETREGSET will pass to userspace register
r8 at offset 8*4, but the pt_regs structure says it's at offset 0.

This difference appears because ptrace returns one layout to userspace,
and pushes the registers to the stack with another layout.

I've fixed this and managed to port strace by changing the genregs_get
implementation, so it returns a layout that matches pt_regs, and therefore
matches the stack.

Having this one-to-one correspondence, has a nice benefit. The implementation
is trivial:

static int genregs_get(struct task_struct *target,
                       const struct user_regset *regset,
                       unsigned int pos, unsigned int count,
                       void *kbuf, void __user *ubuf)
{
        const struct pt_regs *regs = task_pt_regs(target);
        const struct switch_stack *sw = (struct switch_stack *)regs - 1;
        int ret;

        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                  regs, 0, PT_REGS_SIZE);
        if (!ret)
                ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                          sw, 0, SWITCH_STACK_SIZE);
        return ret;
}

However, there's a problem. The ABI is already different, and current gdb
seems to rely in the current layout. However, it does it by *not* using the
pt_regs structure.

Give the ABI is already used, I'm reluctant to change it as I don't want to
break our beloved users.

So, tried a different approach and removed pt_regs from the UAPI ptrace.h,
replacing it with a new user_regs that describes how registers are passed
to user. This however is also problematic, as pt_regs is already used
by glibc (not really sure what for).

In conclusion, I'm lost and have no clue how a proper fix
would look like. (Or perhaps, I'm really lost and there's no fix needed.)

Any ideas?

-- 
Ezequiel Garcia, VanguardiaSur
www.vanguardiasur.com.ar

^ permalink raw reply	[flat|nested] 18+ messages in thread
* nios2: is the ptrace ABI correct?
@ 2015-02-24  2:30 Ezequiel Garcia
  0 siblings, 0 replies; 18+ messages in thread
From: Ezequiel Garcia @ 2015-02-24  2:30 UTC (permalink / raw)
  To: Tobias Klauser, Chung-Ling Tang, Walter Goossens, Ley Foon Tan,
	Linux Kernel Mailing List, Arnd Bergmann,
	nios2-dev@lists.rocketboards.org
  Cc: linux-arch

Hi everyone,

I've been trying to port strace to Nios-II, but came across some oddities
in the ptrace ABI. The pt_regs structure is exposed to userspace through
the ptrace.h UAPI header: arch/nios2/include/uapi/asm/ptrace.h

Such pt_regs has the following layout:

struct pt_regs {
        unsigned long  r8;
        unsigned long  r9;
        unsigned long  r10;
	[and so on]
}

But the regset implementation in arch/nios2/kernel/ptrace.c
pushes a different layout to userspace, as it uses the PTR_
macros, also in the UAPI header:

#define PTR_R0          0
#define PTR_R1          1
#define PTR_R2          2
#define PTR_R3          3
#define PTR_R4          4
#define PTR_R5          5
#define PTR_R6          6
#define PTR_R7          7
#define PTR_R8          8
[..]

In other words, the PTRACE_GETREGSET will pass to userspace register
r8 at offset 8*4, but the pt_regs structure says it's at offset 0.

This difference appears because ptrace returns one layout to userspace,
and pushes the registers to the stack with another layout.

I've fixed this and managed to port strace by changing the genregs_get
implementation, so it returns a layout that matches pt_regs, and therefore
matches the stack.

Having this one-to-one correspondence, has a nice benefit. The implementation
is trivial:

static int genregs_get(struct task_struct *target,
                       const struct user_regset *regset,
                       unsigned int pos, unsigned int count,
                       void *kbuf, void __user *ubuf)
{
        const struct pt_regs *regs = task_pt_regs(target);
        const struct switch_stack *sw = (struct switch_stack *)regs - 1;
        int ret;

        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                  regs, 0, PT_REGS_SIZE);
        if (!ret)
                ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                          sw, 0, SWITCH_STACK_SIZE);
        return ret;
}

However, there's a problem. The ABI is already different, and current gdb
seems to rely in the current layout. However, it does it by *not* using the
pt_regs structure.

Give the ABI is already used, I'm reluctant to change it as I don't want to
break our beloved users.

So, tried a different approach and removed pt_regs from the UAPI ptrace.h,
replacing it with a new user_regs that describes how registers are passed
to user. This however is also problematic, as pt_regs is already used
by glibc (not really sure what for).

In conclusion, I'm lost and have no clue how a proper fix
would look like. (Or perhaps, I'm really lost and there's no fix needed.)

Any ideas?

-- 
Ezequiel Garcia, VanguardiaSur
www.vanguardiasur.com.ar

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2015-03-12 11:12 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-24  3:04 nios2: is the ptrace ABI correct? Ezequiel Garcia
2015-02-24  8:54 ` Arnd Bergmann
2015-02-24 15:28   ` Ezequiel Garcia
2015-02-24 19:25     ` Arnd Bergmann
2015-02-25 11:33       ` Ezequiel Garcia
2015-02-25 14:07         ` Arnd Bergmann
2015-02-27  8:57           ` Chung-Lin Tang
2015-02-27 11:19             ` Ezequiel Garcia
2015-03-04 20:56               ` Ezequiel Garcia
2015-03-09 16:54               ` Chung-Lin Tang
2015-03-09 17:02                 ` Chung-Lin Tang
2015-03-09 17:05                   ` Ezequiel Garcia
2015-03-10  2:54                     ` Ley Foon Tan
2015-03-10  6:17                       ` Chung-Lin Tang
2015-03-11  7:48                         ` Ley Foon Tan
2015-03-11 14:31                           ` Ezequiel Garcia
2015-03-12 11:07                   ` Tobias Klauser
  -- strict thread matches above, loose matches on Subject: below --
2015-02-24  2:30 Ezequiel Garcia

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).