All of lore.kernel.org
 help / color / mirror / Atom feed
From: "liyu@WAN" <liyu@ccoss.com.cn>
To: unlisted-recipients:; (no To-header on input)
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [Question] [Patch] How get instruction pointer of user space ???
Date: Thu, 01 Sep 2005 11:33:48 +0800	[thread overview]
Message-ID: <4316769C.5090303@ccoss.com.cn> (raw)
In-Reply-To: <20050831124318.98086.qmail@web15008.mail.cnb.yahoo.com>

[-- Attachment #1: Type: text/plain, Size: 4227 bytes --]

Hi:

Thanks to Yingchao Zhou and Gaurav Dhiman first, for your answers.

I get it now! but it look we must update knownledge about this.

I read copy_thread() in arch/i386/kernel/process.c, the code piece of
this function are:


/* childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long)
p->thread_info)) - 1;
** /*
* The below -8 is to reserve 8 bytes on top of the ring0 stack.
* This is necessary to guarantee that the entire "struct pt_regs"
* is accessable even if the CPU haven't stored the SS/ESP registers
* on the stack (interrupt gate does not save these registers
* when switching to the same priv ring).
* Therefore beware: accessing the xss/esp fields of the
* "struct pt_regs" is possible, but they may contain the
* completely wrong values.
*/
childregs = (struct pt_regs *) ((unsigned long) childregs - 8);
*childregs = *regs;
*/

Oh, clear all secrets on it now! that comment is very readable.

OK, see my code to do experiement in do_fork() :

/*
static void
my_check_regs_with_offset(struct pt_regs *orig_regs)
{
struct thread_info *thread_info;
struct pt_regs *pt_regs;
unsigned long *stack_bottom;

thread_info = current_thread_info();
pt_regs = (struct pt_regs*)((unsigned long)thread_info+THREAD_SIZE-8);
pt_regs--;
stack_bottom = 8+(unsigned long)(pt_regs+1),
printk("\tbottom=%p, pt_regs = %p eip=%p\n",
stack_bottom,
pt_regs,
pt_regs->eip);

}

static void
my_check_regs_without_offset(struct pt_regs *orig_regs)
{
struct thread_info *thread_info;
struct pt_regs *pt_regs;
unsigned long *stack_bottom;

thread_info = current_thread_info();
pt_regs = (struct pt_regs*)((unsigned long)thread_info+THREAD_SIZE);
pt_regs--;
stack_bottom = (unsigned long)(pt_regs+1),
printk("\tbottom=%p, pt_regs = %p eip=%p\n",
stack_bottom,
pt_regs,
pt_regs->eip);
}*/

in do_fork() function, I insert code:

/* if (current->tgid && (current->tgid % 10 == 0) && get_task_mm(current)) {
unsigned long stack_bottom;
struct thread_info *thread_info;
struct mm_struct *mm;

printk("withOUT offset: ");
my_check_regs_without_offset(regs);

printk("with offset: ");
my_check_regs_with_offset(regs);

printk("sizeof(struct pt_regs) = %d THREAD_SIZE=%x ",
sizeof(struct pt_regs),
THREAD_SIZE);
thread_info = current_thread_info();
printk("thread_info=%p\n", thread_info);

printk("In kernel words:");
printk(" KSTK_TOP(task)=%x\n", KSTK_TOP(current));
printk(" task_pt_regs(task)=%x\n", task_pt_regs(current));
printk(" KSTK_EIP(task)=%x\n", KSTK_EIP(current));

printk("In fact:\n");
stack_bottom = 8+(unsigned long)(regs+1);
printk(" bottom=%p, pt_regs=%p, eip=%p\n",stack_bottom,regs,regs->eip);
mm = get_task_mm(current);
printk(" code address range: [%x-%x]\n", mm->start_code, mm->end_code);
printk("\n");

}
*/
the printk() output:


*withOUT offset: bottom=dac16000, pt_regs = dac15fc4 eip=00000282
with offset: bottom=dac16000, pt_regs = dac15fbc eip=0012d402
sizeof(struct pt_regs) = 60 THREAD_SIZE=2000 thread_info=dac14000
In kernel words: KSTK_TOP(task)=deebb020
task_pt_regs(task)=dac15fc4
KSTK_EIP(task)=282
In fact:
bottom=dac16000, pt_regs=dac15fbc, eip=0012d402
code address range: [8047000-80d1b80]

withOUT offset: bottom=dac16000, pt_regs = dac15fc4 eip=00000282
with offset: bottom=dac16000, pt_regs = dac15fbc eip=00c1f402
sizeof(struct pt_regs) = 60 THREAD_SIZE=2000 thread_info=dac14000
In kernel words: KSTK_TOP(task)=deebb020
task_pt_regs(task)=dac15fc4
KSTK_EIP(task)=282
In fact:
bottom=dac16000, pt_regs=dac15fbc, eip=00c1f402
code address range: [8047000-80d1b80]

withOUT offset: bottom=dac16000, pt_regs = dac15fc4 eip=00000282
with offset: bottom=dac16000, pt_regs = dac15fbc eip=00c1f402
sizeof(struct pt_regs) = 60 THREAD_SIZE=2000 thread_info=dac14000
In kernel words: KSTK_TOP(task)=deebb020
task_pt_regs(task)=dac15fc4
KSTK_EIP(task)=282
In fact:
bottom=dac16000, pt_regs=dac15fbc, eip=00c1f402
code address range: [8047000-80d1b80]

* It's look there have one anonymous hero update copy_thread(), but
he/she forget to update
macro task_pt_regs(task). After browse LXR, I found 2.6.11 have not this
change yet.

the copy_thread() in 2.6.12.3 and 2.6.13 include this "dummy" offset, at
least.
the attachment is a patch for that.

Is right my words?

thanks again.

sailor












[-- Attachment #2: 2.6.13.dummy_offset.patch --]
[-- Type: text/x-patch, Size: 887 bytes --]

--- linux-2.6.13/include/asm-i386/processor.h.orig	2005-09-01 11:19:22.000000000 +0800
+++ linux-2.6.13/include/asm-i386/processor.h	2005-09-01 11:26:04.000000000 +0800
@@ -538,11 +538,13 @@
        unsigned long *__ptr = (unsigned long *)(info);                 \
        (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
 })
-
+/*
+ * subtract 8 here, to skip dummy offset, see copy_thread() for detailed comment.
+ */
 #define task_pt_regs(task)                                             \
 ({                                                                     \
        struct pt_regs *__regs__;                                       \
-       __regs__ = (struct pt_regs *)KSTK_TOP((task)->thread_info);     \
+       __regs__ = (struct pt_regs *)(KSTK_TOP((task)->thread_info)-8); \
        __regs__ - 1;                                                   \
 })
 

           reply	other threads:[~2005-09-01  3:33 UTC|newest]

Thread overview: expand[flat|nested]  mbox.gz  Atom feed
 [parent not found: <20050831124318.98086.qmail@web15008.mail.cnb.yahoo.com>]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4316769C.5090303@ccoss.com.cn \
    --to=liyu@ccoss.com.cn \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.