linux-parisc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] parisc: add CALLER_ADDR{0-6} macros
@ 2009-10-25 21:48 Helge Deller
  2009-10-27  4:49 ` Randolph Chung
  0 siblings, 1 reply; 3+ messages in thread
From: Helge Deller @ 2009-10-25 21:48 UTC (permalink / raw)
  To: linux-parisc, Kyle McMartin, Randolph Chung

Signed-off-by: Helge Deller <deller@gmx.de>


diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h
index 2fa05dd..72c0faf 100644
--- a/arch/parisc/include/asm/ftrace.h
+++ b/arch/parisc/include/asm/ftrace.h
@@ -20,6 +20,20 @@ struct ftrace_ret_stack {
  * Defined in entry.S
  */
 extern void return_to_handler(void);
+
+
+extern unsigned long return_address(unsigned int);
+
+#define HAVE_ARCH_CALLER_ADDR
+
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 return_address(1)
+#define CALLER_ADDR2 return_address(2)
+#define CALLER_ADDR3 return_address(3)
+#define CALLER_ADDR4 return_address(4)
+#define CALLER_ADDR5 return_address(5)
+#define CALLER_ADDR6 return_address(6)
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_PARISC_FTRACE_H */
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 69dad5a..6c631bf 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -417,3 +429,31 @@ int unwind_to_user(struct unwind_frame_info *info)
 
 	return ret;
 }
+
+unsigned long return_address(unsigned int level)
+{
+	struct unwind_frame_info info;
+	struct pt_regs r;
+	unsigned long sp;
+
+	/* initialize unwind info */
+	asm volatile ("copy %%r30, %0" : "=r"(sp));
+	memset(&r, 0, sizeof(struct pt_regs));
+	r.iaoq[0] = (unsigned long) current_text_addr();
+	r.gr[2] = (unsigned long) __builtin_return_address(0);
+	r.gr[30] = sp;
+	unwind_frame_init(&info, current, &r);
+
+	/* unwind stack */
+	++level;
+	do {
+		if (unwind_once(&info) < 0 || info.ip == 0)
+			return 0;
+		if (!__kernel_text_address(info.ip)) {
+			return 0;
+		}
+	} while (info.ip && level--);
+
+	return info.ip;
+}
+

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

* Re: [PATCH] parisc: add CALLER_ADDR{0-6} macros
  2009-10-25 21:48 [PATCH] parisc: add CALLER_ADDR{0-6} macros Helge Deller
@ 2009-10-27  4:49 ` Randolph Chung
  2009-10-27 13:41   ` Helge Deller
  0 siblings, 1 reply; 3+ messages in thread
From: Randolph Chung @ 2009-10-27  4:49 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc, Kyle McMartin

Helge,

> +unsigned long return_address(unsigned int level)
> +{
> +	struct unwind_frame_info info;
> +	struct pt_regs r;
> +	unsigned long sp;
> +
> +	/* initialize unwind info */
> +	asm volatile ("copy %%r30, %0" : "=r"(sp));
> +	memset(&r, 0, sizeof(struct pt_regs));
> +	r.iaoq[0] = (unsigned long) current_text_addr();
> +	r.gr[2] = (unsigned long) __builtin_return_address(0);
> +	r.gr[30] = sp;
> +	unwind_frame_init(&info, current, &r);
> +
> +	/* unwind stack */
> +	++level;
> +	do {
> +		if (unwind_once(&info) < 0 || info.ip == 0)
> +			return 0;
> +		if (!__kernel_text_address(info.ip)) {
> +			return 0;
> +		}
> +	} while (info.ip && level--);
> +
> +	return info.ip;
> +}
> +

Can you show an objdump of this function once it is compiled? I suspect 
the stack pointer initialization here is not reliable.

Ideally unwind_frame_init is called with the frame address in gr[30]. 
With a big struct like pt_regs on the stack, the sp initialization might 
be quite far from the actual frame address.

The unwind_once() code uses like heuristics to try to recover from 
inaccurate stack pointers (by aligning and stepping the frame 64 bytes 
at a time) but that is really a brute force guess.

I realize I used a similar construct in traps.c, but even there I think 
it doesn't work reliably.

Maybe somebody else on the list (Dave? :) can suggest a better way to do 
this.

randolph

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

* Re: [PATCH] parisc: add CALLER_ADDR{0-6} macros
  2009-10-27  4:49 ` Randolph Chung
@ 2009-10-27 13:41   ` Helge Deller
  0 siblings, 0 replies; 3+ messages in thread
From: Helge Deller @ 2009-10-27 13:41 UTC (permalink / raw)
  To: Randolph Chung, linux-parisc, Kyle McMartin

* Randolph Chung <randolph@tausq.org>:
>> +unsigned long return_address(unsigned int level)
>> +{
>> +	struct unwind_frame_info info;
>> +	struct pt_regs r;
>> +	unsigned long sp;
>> +
>> +	/* initialize unwind info */
>> +	asm volatile ("copy %%r30, %0" : "=r"(sp));
>> +	memset(&r, 0, sizeof(struct pt_regs));
>> +	r.iaoq[0] = (unsigned long) current_text_addr();
>> +	r.gr[2] = (unsigned long) __builtin_return_address(0);
>> +	r.gr[30] = sp;
>> +	unwind_frame_init(&info, current, &r);
>> +
>> +	/* unwind stack */
>> +	++level;
>> +	do {
>> +		if (unwind_once(&info) < 0 || info.ip == 0)
>> +			return 0;
>> +		if (!__kernel_text_address(info.ip)) {
>> +			return 0;
>> +		}
>> +	} while (info.ip && level--);
>> +
>> +	return info.ip;
>> +}
>> +
>
> Can you show an objdump of this function once it is compiled? I suspect  
> the stack pointer initialization here is not reliable.

> Ideally unwind_frame_init is called with the frame address in gr[30].  
> With a big struct like pt_regs on the stack, the sp initialization might  
> be quite far from the actual frame address.
>
> The unwind_once() code uses like heuristics to try to recover from  
> inaccurate stack pointers (by aligning and stepping the frame 64 bytes  
> at a time) but that is really a brute force guess.
>
> I realize I used a similar construct in traps.c, but even there I think  
> it doesn't work reliably.

Hi Randolph,

I agree, that those kind of implementations may not always be reliable.
Nevertheless, I started off with a copy of your code, but it didn't
worked at all. I assume due to some compiler-trickery to include the
static local functions in other functions it does work in traps.c 
nevertheless.

I did sucessfully tested the patch I submitted here, both in 32- and 64-bit.

Below is the disassembly of the code which you asked for...

Helge


Disassembly of section .text.return_address:

00000000 <return_address>:
   0:	08 03 02 41 	copy r3,r1
   4:	6b c2 3f d9 	stw rp,-14(sp)
   8:	08 1e 02 43 	copy sp,r3
   c:	6f c1 04 80 	stw,ma r1,240(sp)
  10:	68 67 04 00 	stw r7,200(r3)
  14:	08 02 02 47 	copy rp,r7
  18:	68 66 04 08 	stw r6,204(r3)
  1c:	08 1a 02 46 	copy r26,r6
  20:	68 65 04 10 	stw r5,208(r3)
  24:	68 64 04 18 	stw r4,20c(r3)
  28:	08 1e 02 44 	copy sp,r4
  2c:	34 65 00 50 	ldo 28(r3),r5
  30:	34 19 00 00 	ldi 0,r25
  34:	08 05 02 5a 	copy r5,r26
  38:	e8 40 00 00 	b,l 40 <return_address+0x40>,rp
  3c:	34 18 03 b0 	ldi 1d8,r24
  40:	68 67 00 60 	stw r7,30(r3)
  44:	eb 80 40 00 	blr r0,ret0
  48:	08 00 02 40 	nop
  4c:	68 64 01 40 	stw r4,a0(r3)
  50:	68 7c 03 a0 	stw ret0,1d0(r3)
  54:	03 c0 08 bc 	mfctl tr6,ret0
  58:	34 64 00 10 	ldo 8(r3),r4
  5c:	0f 80 10 99 	ldw 0(ret0),r25
  60:	08 04 02 5a 	copy r4,r26
  64:	e8 40 00 00 	b,l 6c <return_address+0x6c>,rp
  68:	08 05 02 58 	copy r5,r24
  6c:	08 04 02 5a 	copy r4,r26
  70:	e8 40 00 00 	b,l 78 <return_address+0x78>,rp
  74:	34 c6 00 02 	ldo 1(r6),r6
  78:	8f 80 60 80 	cmpib,> 0,ret0,c0 <return_address+0xc0>
  7c:	34 1c 00 00 	ldi 0,ret0
  80:	48 7c 00 20 	ldw 10(r3),ret0
  84:	87 80 20 68 	cmpib,= 0,ret0,c0 <return_address+0xc0>
  88:	08 1c 02 5a 	copy ret0,r26
  8c:	e8 40 00 00 	b,l 94 <return_address+0x94>,rp
  90:	08 00 02 40 	nop
  94:	87 80 20 40 	cmpib,= 0,ret0,bc <return_address+0xbc>
  98:	48 7c 00 20 	ldw 10(r3),ret0
  9c:	87 80 20 40 	cmpib,= 0,ret0,c4 <return_address+0xc4>
  a0:	48 62 3f d9 	ldw -14(r3),rp
  a4:	84 c0 20 30 	cmpib,= 0,r6,c4 <return_address+0xc4>
  a8:	08 04 02 5a 	copy r4,r26
  ac:	e8 40 00 00 	b,l b4 <return_address+0xb4>,rp
  b0:	34 c6 3f ff 	ldo -1(r6),r6
  b4:	87 80 7f 95 	cmpib,<= 0,ret0,84 <return_address+0x84>
  b8:	48 7c 00 20 	ldw 10(r3),ret0
  bc:	34 1c 00 00 	ldi 0,ret0
  c0:	48 62 3f d9 	ldw -14(r3),rp
  c4:	48 67 04 00 	ldw 200(r3),r7
  c8:	48 66 04 08 	ldw 204(r3),r6
  cc:	48 65 04 10 	ldw 208(r3),r5
  d0:	48 64 04 18 	ldw 20c(r3),r4
  d4:	34 7e 00 80 	ldo 40(r3),sp
  d8:	e8 40 c0 00 	bv r0(rp)
  dc:	4f c3 3f 81 	ldw,mb -40(sp),r3


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

end of thread, other threads:[~2009-10-27 13:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-25 21:48 [PATCH] parisc: add CALLER_ADDR{0-6} macros Helge Deller
2009-10-27  4:49 ` Randolph Chung
2009-10-27 13:41   ` Helge Deller

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).