文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Simple example for ppc (gnu-linux) Stack backtrace

Simple example for ppc (gnu-linux) Stack backtrace

时间:2009-06-16  来源:sigsegv11

由于比较简单,就不需要解释了吧,看注释应该足够了
最后打印出来的possible entry为函数调用的入口
由于仅仅是一个demo,就不要要求太精确了,主要还是为了演示ppc的堆栈结构
符号可以通过多lookup_symbol()解析(需要自己实现,查询相关ELF文件字段)

/**
 * ppc stack back trace simple demo
 * for 32bit ppc only (gnu-linux)
 * compile with -O0
 */

/*
 run-time stack layout

| ... |
| LR saved |
+---------------+
| Back chain |
| reserved |
| GPR saved |
| locals |
| dyn alloc |
| param(callee) |
| LR saved |
+---------------+
| Back Chain |
| ... |

*/

#include <stdio.h>

/**
 * dummy entry finding routine
 */
unsigned long find_entry(unsigned long current)
{
        unsigned long p = current;
        unsigned long entry;
        unsigned long ret = 0;

        if(current == 0)
                return 0;

        while(1) {
                p -= 4;
                entry = *(unsigned long*)p;

                /* b but not bl */
                if((entry & 0x48000001 == 0x48000000)) {
                        break;
                } else if (entry == 0x4e800020) { /* blr */
                        break;
                } else if ((entry & 0x94210000) == 0x94210000) { /* stwu */
                        ret = p;
                        break;
                }
        }

        return ret;
}

int foo(void)
{
        unsigned long r1, lr, p;
        char buf[24]; /* consume more stack */

        /* get the current stack pointer */
        __asm__ __volatile__ ("mr %0, 1\n\t": "=r"(r1));

        /* don't work for self-modify code, though */
        lr = (unsigned long)&foo + 32; /* assume foo >32 bytes */
        p = lr;
        while(1) {
                unsigned long entry = *(unsigned long*)p;
                /* don't care with stwux */
                if( (entry & 0x94210000) == 0x94210000) { /* stwu */
                        long off;
                        off = entry & 0xFFFF;
                        if(off & 0x8000) {
                                off |= ((0xFFFF) << 16); /* signed extend */
                        }
                        printf("off: %d\n", off);

                        /* unsigned arith: find stack entry */
                        r1 += (-off);
                        break;
                }
                p -= 4;
        }

        while(r1) {
                lr = *(unsigned long*)(r1+4);
                printf("stack dump: 0x%lx\n", r1);
                printf("lr dump: 0x%lx\n", lr);

                /* this is the call stack entry function
                 * please verify with objdump
                 */
                printf("possible entry: 0x%lx\n", find_entry(lr));
                r1 = *(unsigned long*)r1; /* previous stack frame */
        }
        return 0;
}

/* create more function calls for back trace testing */
void bar(int p)
{
        foo();
}

void baz(void)
{
        bar(0);
}

int main(int argc, char* argv[])
{
        baz();

        return 0;
}

相关阅读 更多 +
排行榜 更多 +
山雾搜剧 1.0.0

山雾搜剧 1.0.0

系统软件 下载
漫千绘

漫千绘

浏览阅读 下载
布鲁伊一起玩吧2025年

布鲁伊一起玩吧2025年

休闲益智 下载