Unified · Split
| @@ -496,6 +496,50 @@ static int rt_get_caller_pc(unsigned long *paddr, · 495 unmodified lines | ||
| 496 | 496 | } |
| 497 | 497 | } |
| 498 | 498 | |
| 499 | +/* ------------------------------------------------------------- */ | |
| 500 | +#elif defined(__arm__) | |
| 501 | + | |
| 502 | +/* return the PC at frame level 'level'. Return negative if not found */ | |
| 503 | +static int rt_get_caller_pc(unsigned long *paddr, | |
| 504 | + ucontext_t *uc, int level) | |
| 505 | +{ | |
| 506 | + uint32_t fp, sp; | |
| 507 | + int i; | |
| 508 | + | |
| 509 | + if (level == 0) { | |
| 510 | + /* XXX: only supports linux */ | |
| 511 | +#if defined(__linux__) | |
| 512 | + *paddr = uc->uc_mcontext.arm_pc; | |
| 513 | +#else | |
| 514 | + return -1; | |
| 515 | +#endif | |
| 516 | + return 0; | |
| 517 | + } else { | |
| 518 | +#if defined(__linux__) | |
| 519 | + fp = uc->uc_mcontext.arm_fp; | |
| 520 | + sp = uc->uc_mcontext.arm_sp; | |
| 521 | + if (sp < 0x1000) | |
| 522 | + sp = 0x1000; | |
| 523 | +#else | |
| 524 | + return -1; | |
| 525 | +#endif | |
| 526 | + /* XXX: specific to tinycc stack frames */ | |
| 527 | + if (fp < sp + 12 || fp & 3) | |
| 528 | + return -1; | |
| 529 | + for(i = 1; i < level; i++) { | |
| 530 | + sp = ((uint32_t *)fp)[-2]; | |
| 531 | + if (sp < fp || sp - fp > 16 || sp & 3) | |
| 532 | + return -1; | |
| 533 | + fp = ((uint32_t *)fp)[-3]; | |
| 534 | + if (fp <= sp || fp - sp < 12 || fp & 3) | |
| 535 | + return -1; | |
| 536 | + } | |
| 537 | + /* XXX: check address validity with program info */ | |
| 538 | + *paddr = ((uint32_t *)fp)[-1]; | |
| 539 | + return 0; | |
| 540 | + } | |
| 541 | +} | |
| 542 | + | |
| 499 | 543 | /* ------------------------------------------------------------- */ |
| 500 | 544 | #else |
| 501 | 545 | |