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 | #else | 544 | #else |
| 501 | 545 | ||