From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <47F11DFF.8010406@wmipf.in-berlin.de> Date: Mon, 31 Mar 2008 19:23:11 +0200 From: =?UTF-8?B?TWljaGFlbCBUZWljaGdyw6RiZXI=?= User-Agent: Icedove 1.5.0.14pre (X11/20080208) MIME-Version: 1.0 To: Fans of the OS Plan 9 from Bell Labs <9fans@9fans.net> References: <20080331162530.C70ED1E8C3A@holo.morphisms.net> In-Reply-To: <20080331162530.C70ED1E8C3A@holo.morphisms.net> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: Re: [9fans] getcallerpc on arm7 Topicbox-Message-UUID: 85cd73b2-ead3-11e9-9d60-3106f5b1d025 > On architectures that don't push the return address on the > stack during the call instruction, the caller of getcallerpc > will have saved the desired return address somewhere in > its stack frame, and getcallerpc must root it out. It appears the implementation below works well with arm-elf-gcc on arm7tdmi: /* * Functions generated by arm-elf-gcc start * like this (always?): * mov ip, sp * stmdb sp!, {fp, ip, lr, pc} * * (The first argument, which is still in r0, * is pushed later, when its address is taken so * that it can be provided to getcallerpc.) * * To get the value of `lr', the return address, * walk up the stack, starting with x, until a * value *u is found which is the previous stack * pointer, i.e. which equals the address u+3. * In that case, the return address is expected * to be in u[1]. * * If no such address is found, return an invalid value. */ ulong getcallerpc(void *x) { ulong *u; int i; u = (ulong*)x; for (i=0; i<128; i++, u++) if (*u == (ulong)(u+3)) return u[1]; return ~0; } A helpful document was http://www.cems.uwe.ac.uk/~cduffy/es/5.ppt, to get an idea of how function arguments are provided and the stack is managed by the gcc on arm. If the stack contains a value which matches the condition for `ip', but which is not ip, getcallerpc will find it before the real ip/lr, and report a garbage address. Michael