unwind.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:55k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) 1999-2001 Hewlett-Packard Co
  3.  * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  4.  */
  5. /*
  6.  * This file implements call frame unwind support for the Linux
  7.  * kernel.  Parsing and processing the unwind information is
  8.  * time-consuming, so this implementation translates the unwind
  9.  * descriptors into unwind scripts.  These scripts are very simple
  10.  * (basically a sequence of assignments) and efficient to execute.
  11.  * They are cached for later re-use.  Each script is specific for a
  12.  * given instruction pointer address and the set of predicate values
  13.  * that the script depends on (most unwind descriptors are
  14.  * unconditional and scripts often do not depend on predicates at
  15.  * all).  This code is based on the unwind conventions described in
  16.  * the "IA-64 Software Conventions and Runtime Architecture" manual.
  17.  *
  18.  * SMP conventions:
  19.  * o updates to the global unwind data (in structure "unw") are serialized
  20.  *   by the unw.lock spinlock
  21.  * o each unwind script has its own read-write lock; a thread must acquire
  22.  *   a read lock before executing a script and must acquire a write lock
  23.  *   before modifying a script
  24.  * o if both the unw.lock spinlock and a script's read-write lock must be
  25.  *   acquired, then the read-write lock must be acquired first.
  26.  */
  27. #include <linux/bootmem.h>
  28. #include <linux/kernel.h>
  29. #include <linux/sched.h>
  30. #include <linux/slab.h>
  31. #include <asm/unwind.h>
  32. #include <asm/delay.h>
  33. #include <asm/page.h>
  34. #include <asm/ptrace.h>
  35. #include <asm/ptrace_offsets.h>
  36. #include <asm/rse.h>
  37. #include <asm/system.h>
  38. #include <asm/uaccess.h>
  39. #include "entry.h"
  40. #include "unwind_i.h"
  41. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  42. #define p5 5
  43. #define UNW_LOG_CACHE_SIZE 7 /* each unw_script is ~256 bytes in size */
  44. #define UNW_CACHE_SIZE (1 << UNW_LOG_CACHE_SIZE)
  45. #define UNW_LOG_HASH_SIZE (UNW_LOG_CACHE_SIZE + 1)
  46. #define UNW_HASH_SIZE (1 << UNW_LOG_HASH_SIZE)
  47. #define UNW_DEBUG 0
  48. #define UNW_STATS 0 /* WARNING: this disabled interrupts for long time-spans!! */
  49. #if UNW_DEBUG
  50.   static long unw_debug_level = 255;
  51. # define debug(level,format...) if (unw_debug_level > level) printk(format)
  52. # define dprintk(format...) printk(format)
  53. # define inline
  54. #else
  55. # define debug(level,format...)
  56. # define dprintk(format...)
  57. #endif
  58. #if UNW_STATS
  59. # define STAT(x...) x
  60. #else
  61. # define STAT(x...)
  62. #endif
  63. #define alloc_reg_state() kmalloc(sizeof(struct unw_state_record), GFP_ATOMIC)
  64. #define free_reg_state(usr) kfree(usr)
  65. typedef unsigned long unw_word;
  66. typedef unsigned char unw_hash_index_t;
  67. #define struct_offset(str,fld) ((char *)&((str *)NULL)->fld - (char *) 0)
  68. static struct {
  69. spinlock_t lock; /* spinlock for unwind data */
  70. /* list of unwind tables (one per load-module) */
  71. struct unw_table *tables;
  72. /* table of registers that prologues can save (and order in which they're saved): */
  73. const unsigned char save_order[8];
  74. /* maps a preserved register index (preg_index) to corresponding switch_stack offset: */
  75. unsigned short sw_off[sizeof(struct unw_frame_info) / 8];
  76. unsigned short lru_head; /* index of lead-recently used script */
  77. unsigned short lru_tail; /* index of most-recently used script */
  78. /* index into unw_frame_info for preserved register i */
  79. unsigned short preg_index[UNW_NUM_REGS];
  80. /* unwind table for the kernel: */
  81. struct unw_table kernel_table;
  82. /* unwind table describing the gate page (kernel code that is mapped into user space): */
  83. size_t gate_table_size;
  84. unsigned long *gate_table;
  85. /* hash table that maps instruction pointer to script index: */
  86. unsigned short hash[UNW_HASH_SIZE];
  87. /* script cache: */
  88. struct unw_script cache[UNW_CACHE_SIZE];
  89. # if UNW_DEBUG
  90. const char *preg_name[UNW_NUM_REGS];
  91. # endif
  92. # if UNW_STATS
  93. struct {
  94. struct {
  95. int lookups;
  96. int hinted_hits;
  97. int normal_hits;
  98. int collision_chain_traversals;
  99. } cache;
  100. struct {
  101. unsigned long build_time;
  102. unsigned long run_time;
  103. unsigned long parse_time;
  104. int builds;
  105. int news;
  106. int collisions;
  107. int runs;
  108. } script;
  109. struct {
  110. unsigned long init_time;
  111. unsigned long unwind_time;
  112. int inits;
  113. int unwinds;
  114. } api;
  115. } stat;
  116. # endif
  117. } unw = {
  118. tables: &unw.kernel_table,
  119. lock: SPIN_LOCK_UNLOCKED,
  120. save_order: {
  121. UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
  122. UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
  123. },
  124. preg_index: {
  125. struct_offset(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_GR */
  126. struct_offset(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_MEM */
  127. struct_offset(struct unw_frame_info, bsp_loc)/8,
  128. struct_offset(struct unw_frame_info, bspstore_loc)/8,
  129. struct_offset(struct unw_frame_info, pfs_loc)/8,
  130. struct_offset(struct unw_frame_info, rnat_loc)/8,
  131. struct_offset(struct unw_frame_info, psp)/8,
  132. struct_offset(struct unw_frame_info, rp_loc)/8,
  133. struct_offset(struct unw_frame_info, r4)/8,
  134. struct_offset(struct unw_frame_info, r5)/8,
  135. struct_offset(struct unw_frame_info, r6)/8,
  136. struct_offset(struct unw_frame_info, r7)/8,
  137. struct_offset(struct unw_frame_info, unat_loc)/8,
  138. struct_offset(struct unw_frame_info, pr_loc)/8,
  139. struct_offset(struct unw_frame_info, lc_loc)/8,
  140. struct_offset(struct unw_frame_info, fpsr_loc)/8,
  141. struct_offset(struct unw_frame_info, b1_loc)/8,
  142. struct_offset(struct unw_frame_info, b2_loc)/8,
  143. struct_offset(struct unw_frame_info, b3_loc)/8,
  144. struct_offset(struct unw_frame_info, b4_loc)/8,
  145. struct_offset(struct unw_frame_info, b5_loc)/8,
  146. struct_offset(struct unw_frame_info, f2_loc)/8,
  147. struct_offset(struct unw_frame_info, f3_loc)/8,
  148. struct_offset(struct unw_frame_info, f4_loc)/8,
  149. struct_offset(struct unw_frame_info, f5_loc)/8,
  150. struct_offset(struct unw_frame_info, fr_loc[16 - 16])/8,
  151. struct_offset(struct unw_frame_info, fr_loc[17 - 16])/8,
  152. struct_offset(struct unw_frame_info, fr_loc[18 - 16])/8,
  153. struct_offset(struct unw_frame_info, fr_loc[19 - 16])/8,
  154. struct_offset(struct unw_frame_info, fr_loc[20 - 16])/8,
  155. struct_offset(struct unw_frame_info, fr_loc[21 - 16])/8,
  156. struct_offset(struct unw_frame_info, fr_loc[22 - 16])/8,
  157. struct_offset(struct unw_frame_info, fr_loc[23 - 16])/8,
  158. struct_offset(struct unw_frame_info, fr_loc[24 - 16])/8,
  159. struct_offset(struct unw_frame_info, fr_loc[25 - 16])/8,
  160. struct_offset(struct unw_frame_info, fr_loc[26 - 16])/8,
  161. struct_offset(struct unw_frame_info, fr_loc[27 - 16])/8,
  162. struct_offset(struct unw_frame_info, fr_loc[28 - 16])/8,
  163. struct_offset(struct unw_frame_info, fr_loc[29 - 16])/8,
  164. struct_offset(struct unw_frame_info, fr_loc[30 - 16])/8,
  165. struct_offset(struct unw_frame_info, fr_loc[31 - 16])/8,
  166. },
  167. hash : { [0 ... UNW_HASH_SIZE - 1] = -1 },
  168. #if UNW_DEBUG
  169. preg_name: {
  170. "pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat", "psp", "rp",
  171. "r4", "r5", "r6", "r7",
  172. "ar.unat", "pr", "ar.lc", "ar.fpsr",
  173. "b1", "b2", "b3", "b4", "b5",
  174. "f2", "f3", "f4", "f5",
  175. "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
  176. "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
  177. }
  178. #endif
  179. };
  180. /* Unwind accessors.  */
  181. /*
  182.  * Returns offset of rREG in struct pt_regs.
  183.  */
  184. static inline unsigned long
  185. pt_regs_off (unsigned long reg)
  186. {
  187. unsigned long off =0;
  188. if (reg >= 1 && reg <= 3)
  189. off = struct_offset(struct pt_regs, r1) + 8*(reg - 1);
  190. else if (reg <= 11)
  191. off = struct_offset(struct pt_regs, r8) + 8*(reg - 8);
  192. else if (reg <= 15)
  193. off = struct_offset(struct pt_regs, r12) + 8*(reg - 12);
  194. else if (reg <= 31)
  195. off = struct_offset(struct pt_regs, r16) + 8*(reg - 16);
  196. else
  197. dprintk("unwind: bad scratch reg r%lun", reg);
  198. return off;
  199. }
  200. int
  201. unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char *nat, int write)
  202. {
  203. unsigned long *addr, *nat_addr, nat_mask = 0, dummy_nat;
  204. struct unw_ireg *ireg;
  205. struct pt_regs *pt;
  206. if ((unsigned) regnum - 1 >= 127) {
  207. dprintk("unwind: trying to access non-existent r%un", regnum);
  208. return -1;
  209. }
  210. if (regnum < 32) {
  211. if (regnum >= 4 && regnum <= 7) {
  212. /* access a preserved register */
  213. ireg = &info->r4 + (regnum - 4);
  214. addr = ireg->loc;
  215. if (addr) {
  216. nat_addr = addr + ireg->nat.off;
  217. switch (ireg->nat.type) {
  218.       case UNW_NAT_VAL:
  219. /* simulate getf.sig/setf.sig */
  220. if (write) {
  221. if (*nat) {
  222. /* write NaTVal and be done with it */
  223. addr[0] = 0;
  224. addr[1] = 0x1fffe;
  225. return 0;
  226. }
  227. addr[1] = 0x1003e;
  228. } else {
  229. if (addr[0] == 0 && addr[1] == 0x1ffe) {
  230. /* return NaT and be done with it */
  231. *val = 0;
  232. *nat = 1;
  233. return 0;
  234. }
  235. }
  236. /* fall through */
  237.       case UNW_NAT_NONE:
  238. dummy_nat = 0;
  239. nat_addr = &dummy_nat;
  240. break;
  241.       case UNW_NAT_MEMSTK:
  242. nat_mask = (1UL << ((long) addr & 0x1f8)/8);
  243. break;
  244.       case UNW_NAT_REGSTK:
  245. nat_addr = ia64_rse_rnat_addr(addr);
  246. if ((unsigned long) addr < info->regstk.limit
  247.     || (unsigned long) addr >= info->regstk.top)
  248. {
  249. dprintk("unwind: %p outside of regstk "
  250. "[0x%lx-0x%lx)n", (void *) addr,
  251. info->regstk.limit,
  252. info->regstk.top);
  253. return -1;
  254. }
  255. if ((unsigned long) nat_addr >= info->regstk.top)
  256. nat_addr = &info->sw->ar_rnat;
  257. nat_mask = (1UL << ia64_rse_slot_num(addr));
  258. break;
  259. }
  260. } else {
  261. addr = &info->sw->r4 + (regnum - 4);
  262. nat_addr = &info->sw->ar_unat;
  263. nat_mask = (1UL << ((long) addr & 0x1f8)/8);
  264. }
  265. } else {
  266. /* access a scratch register */
  267. if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
  268. pt = (struct pt_regs *) info->psp - 1;
  269. else
  270. pt = (struct pt_regs *) info->sp - 1;
  271. addr = (unsigned long *) ((long) pt + pt_regs_off(regnum));
  272. if (info->pri_unat_loc)
  273. nat_addr = info->pri_unat_loc;
  274. else
  275. nat_addr = &info->sw->ar_unat;
  276. nat_mask = (1UL << ((long) addr & 0x1f8)/8);
  277. }
  278. } else {
  279. /* access a stacked register */
  280. addr = ia64_rse_skip_regs((unsigned long *) info->bsp, regnum - 32);
  281. nat_addr = ia64_rse_rnat_addr(addr);
  282. if ((unsigned long) addr < info->regstk.limit
  283.     || (unsigned long) addr >= info->regstk.top)
  284. {
  285. dprintk("unwind: ignoring attempt to access register outside of rbsn");
  286. return -1;
  287. }
  288. if ((unsigned long) nat_addr >= info->regstk.top)
  289. nat_addr = &info->sw->ar_rnat;
  290. nat_mask = (1UL << ia64_rse_slot_num(addr));
  291. }
  292. if (write) {
  293. *addr = *val;
  294. if (*nat)
  295. *nat_addr |= nat_mask;
  296. else
  297. *nat_addr &= ~nat_mask;
  298. } else {
  299. if ((*nat_addr & nat_mask) == 0) {
  300. *val = *addr;
  301. *nat = 0;
  302. } else {
  303. *val = 0; /* if register is a NaT, *addr may contain kernel data! */
  304. *nat = 1;
  305. }
  306. }
  307. return 0;
  308. }
  309. int
  310. unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int write)
  311. {
  312. unsigned long *addr;
  313. struct pt_regs *pt;
  314. if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
  315. pt = (struct pt_regs *) info->psp - 1;
  316. else
  317. pt = (struct pt_regs *) info->sp - 1;
  318. switch (regnum) {
  319. /* scratch: */
  320.       case 0: addr = &pt->b0; break;
  321.       case 6: addr = &pt->b6; break;
  322.       case 7: addr = &pt->b7; break;
  323. /* preserved: */
  324.       case 1: case 2: case 3: case 4: case 5:
  325. addr = *(&info->b1_loc + (regnum - 1));
  326. if (!addr)
  327. addr = &info->sw->b1 + (regnum - 1);
  328. break;
  329.       default:
  330. dprintk("unwind: trying to access non-existent b%un", regnum);
  331. return -1;
  332. }
  333. if (write)
  334. *addr = *val;
  335. else
  336. *val = *addr;
  337. return 0;
  338. }
  339. int
  340. unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, int write)
  341. {
  342. struct ia64_fpreg *addr = 0;
  343. struct pt_regs *pt;
  344. if ((unsigned) (regnum - 2) >= 126) {
  345. dprintk("unwind: trying to access non-existent f%un", regnum);
  346. return -1;
  347. }
  348. if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
  349. pt = (struct pt_regs *) info->psp - 1;
  350. else
  351. pt = (struct pt_regs *) info->sp - 1;
  352. if (regnum <= 5) {
  353. addr = *(&info->f2_loc + (regnum - 2));
  354. if (!addr)
  355. addr = &info->sw->f2 + (regnum - 2);
  356. } else if (regnum <= 15) {
  357. if (regnum <= 9)
  358. addr = &pt->f6  + (regnum - 6);
  359. else
  360. addr = &info->sw->f10 + (regnum - 10);
  361. } else if (regnum <= 31) {
  362. addr = info->fr_loc[regnum - 16];
  363. if (!addr)
  364. addr = &info->sw->f16 + (regnum - 16);
  365. } else {
  366. struct task_struct *t = info->task;
  367. if (write)
  368. ia64_sync_fph(t);
  369. else
  370. ia64_flush_fph(t);
  371. addr = t->thread.fph + (regnum - 32);
  372. }
  373. if (write)
  374. *addr = *val;
  375. else
  376. *val = *addr;
  377. return 0;
  378. }
  379. int
  380. unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int write)
  381. {
  382. unsigned long *addr;
  383. struct pt_regs *pt;
  384. if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
  385. pt = (struct pt_regs *) info->psp - 1;
  386. else
  387. pt = (struct pt_regs *) info->sp - 1;
  388. switch (regnum) {
  389.       case UNW_AR_BSP:
  390. addr = info->bsp_loc;
  391. if (!addr)
  392. addr = &info->sw->ar_bspstore;
  393. break;
  394.       case UNW_AR_BSPSTORE:
  395. addr = info->bspstore_loc;
  396. if (!addr)
  397. addr = &info->sw->ar_bspstore;
  398. break;
  399.       case UNW_AR_PFS:
  400. addr = info->pfs_loc;
  401. if (!addr)
  402. addr = &info->sw->ar_pfs;
  403. break;
  404.       case UNW_AR_RNAT:
  405. addr = info->rnat_loc;
  406. if (!addr)
  407. addr = &info->sw->ar_rnat;
  408. break;
  409.       case UNW_AR_UNAT:
  410. addr = info->unat_loc;
  411. if (!addr)
  412. addr = &info->sw->ar_unat;
  413. break;
  414.       case UNW_AR_LC:
  415. addr = info->lc_loc;
  416. if (!addr)
  417. addr = &info->sw->ar_lc;
  418. break;
  419.       case UNW_AR_EC:
  420. if (!info->cfm_loc)
  421. return -1;
  422. if (write)
  423. *info->cfm_loc =
  424. (*info->cfm_loc & ~(0x3fUL << 52)) | ((*val & 0x3f) << 52);
  425. else
  426. *val = (*info->cfm_loc >> 52) & 0x3f;
  427. return 0;
  428.       case UNW_AR_FPSR:
  429. addr = info->fpsr_loc;
  430. if (!addr)
  431. addr = &info->sw->ar_fpsr;
  432. break;
  433.       case UNW_AR_RSC:
  434. addr = &pt->ar_rsc;
  435. break;
  436.       case UNW_AR_CCV:
  437. addr = &pt->ar_ccv;
  438. break;
  439.       default:
  440. dprintk("unwind: trying to access non-existent ar%un", regnum);
  441. return -1;
  442. }
  443. if (write)
  444. *addr = *val;
  445. else
  446. *val = *addr;
  447. return 0;
  448. }
  449. int
  450. unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write)
  451. {
  452. unsigned long *addr;
  453. addr = info->pr_loc;
  454. if (!addr)
  455. addr = &info->sw->pr;
  456. if (write)
  457. *addr = *val;
  458. else
  459. *val = *addr;
  460. return 0;
  461. }
  462. /* Unwind decoder routines */
  463. static inline void
  464. push (struct unw_state_record *sr)
  465. {
  466. struct unw_reg_state *rs;
  467. rs = alloc_reg_state();
  468. if (!rs) {
  469. printk("unwind: cannot stack reg state!n");
  470. return;
  471. }
  472. memcpy(rs, &sr->curr, sizeof(*rs));
  473. rs->next = sr->stack;
  474. sr->stack = rs;
  475. }
  476. static void
  477. pop (struct unw_state_record *sr)
  478. {
  479. struct unw_reg_state *rs;
  480. if (!sr->stack) {
  481. printk ("unwind: stack underflow!n");
  482. return;
  483. }
  484. rs = sr->stack;
  485. sr->stack = rs->next;
  486. free_reg_state(rs);
  487. }
  488. static enum unw_register_index __attribute__((const))
  489. decode_abreg (unsigned char abreg, int memory)
  490. {
  491. switch (abreg) {
  492.       case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04);
  493.       case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22);
  494.       case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30);
  495.       case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41);
  496.       case 0x60: return UNW_REG_PR;
  497.       case 0x61: return UNW_REG_PSP;
  498.       case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR;
  499.       case 0x63: return UNW_REG_RP;
  500.       case 0x64: return UNW_REG_BSP;
  501.       case 0x65: return UNW_REG_BSPSTORE;
  502.       case 0x66: return UNW_REG_RNAT;
  503.       case 0x67: return UNW_REG_UNAT;
  504.       case 0x68: return UNW_REG_FPSR;
  505.       case 0x69: return UNW_REG_PFS;
  506.       case 0x6a: return UNW_REG_LC;
  507.       default:
  508. break;
  509. }
  510. dprintk("unwind: bad abreg=0x%xn", abreg);
  511. return UNW_REG_LC;
  512. }
  513. static void
  514. set_reg (struct unw_reg_info *reg, enum unw_where where, int when, unsigned long val)
  515. {
  516. reg->val = val;
  517. reg->where = where;
  518. if (reg->when == UNW_WHEN_NEVER)
  519. reg->when = when;
  520. }
  521. static void
  522. alloc_spill_area (unsigned long *offp, unsigned long regsize,
  523.   struct unw_reg_info *lo, struct unw_reg_info *hi)
  524. {
  525. struct unw_reg_info *reg;
  526. for (reg = hi; reg >= lo; --reg) {
  527. if (reg->where == UNW_WHERE_SPILL_HOME) {
  528. reg->where = UNW_WHERE_PSPREL;
  529. reg->val = 0x10 - *offp;
  530. *offp += regsize;
  531. }
  532. }
  533. }
  534. static inline void
  535. spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, unw_word t)
  536. {
  537. struct unw_reg_info *reg;
  538. for (reg = *regp; reg <= lim; ++reg) {
  539. if (reg->where == UNW_WHERE_SPILL_HOME) {
  540. reg->when = t;
  541. *regp = reg + 1;
  542. return;
  543. }
  544. }
  545. dprintk("unwind: excess spill!n");
  546. }
  547. static inline void
  548. finish_prologue (struct unw_state_record *sr)
  549. {
  550. struct unw_reg_info *reg;
  551. unsigned long off;
  552. int i;
  553. /*
  554.  * First, resolve implicit register save locations (see Section "11.4.2.3 Rules
  555.  * for Using Unwind Descriptors", rule 3):
  556.  */
  557. for (i = 0; i < (int) sizeof(unw.save_order)/sizeof(unw.save_order[0]); ++i) {
  558. reg = sr->curr.reg + unw.save_order[i];
  559. if (reg->where == UNW_WHERE_GR_SAVE) {
  560. reg->where = UNW_WHERE_GR;
  561. reg->val = sr->gr_save_loc++;
  562. }
  563. }
  564. /*
  565.  * Next, compute when the fp, general, and branch registers get
  566.  * saved.  This must come before alloc_spill_area() because
  567.  * we need to know which registers are spilled to their home
  568.  * locations.
  569.  */
  570. if (sr->imask) {
  571. unsigned char kind, mask = 0, *cp = sr->imask;
  572. unsigned long t;
  573. static const unsigned char limit[3] = {
  574. UNW_REG_F31, UNW_REG_R7, UNW_REG_B5
  575. };
  576. struct unw_reg_info *(regs[3]);
  577. regs[0] = sr->curr.reg + UNW_REG_F2;
  578. regs[1] = sr->curr.reg + UNW_REG_R4;
  579. regs[2] = sr->curr.reg + UNW_REG_B1;
  580. for (t = 0; t < sr->region_len; ++t) {
  581. if ((t & 3) == 0)
  582. mask = *cp++;
  583. kind = (mask >> 2*(3-(t & 3))) & 3;
  584. if (kind > 0)
  585. spill_next_when(&regs[kind - 1], sr->curr.reg + limit[kind - 1],
  586. sr->region_start + t);
  587. }
  588. }
  589. /*
  590.  * Next, lay out the memory stack spill area:
  591.  */
  592. if (sr->any_spills) {
  593. off = sr->spill_offset;
  594. alloc_spill_area(&off, 16, sr->curr.reg + UNW_REG_F2, sr->curr.reg + UNW_REG_F31);
  595. alloc_spill_area(&off,  8, sr->curr.reg + UNW_REG_B1, sr->curr.reg + UNW_REG_B5);
  596. alloc_spill_area(&off,  8, sr->curr.reg + UNW_REG_R4, sr->curr.reg + UNW_REG_R7);
  597. }
  598. }
  599. /*
  600.  * Region header descriptors.
  601.  */
  602. static void
  603. desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave,
  604.        struct unw_state_record *sr)
  605. {
  606. int i;
  607. if (!(sr->in_body || sr->first_region))
  608. finish_prologue(sr);
  609. sr->first_region = 0;
  610. /* check if we're done: */
  611. if (body && sr->when_target < sr->region_start + sr->region_len) {
  612. sr->done = 1;
  613. return;
  614. }
  615. for (i = 0; i < sr->epilogue_count; ++i)
  616. pop(sr);
  617. sr->epilogue_count = 0;
  618. sr->epilogue_start = UNW_WHEN_NEVER;
  619. if (!body)
  620. push(sr);
  621. sr->region_start += sr->region_len;
  622. sr->region_len = rlen;
  623. sr->in_body = body;
  624. if (!body) {
  625. for (i = 0; i < 4; ++i) {
  626. if (mask & 0x8)
  627. set_reg(sr->curr.reg + unw.save_order[i], UNW_WHERE_GR,
  628. sr->region_start + sr->region_len - 1, grsave++);
  629. mask <<= 1;
  630. }
  631. sr->gr_save_loc = grsave;
  632. sr->any_spills = 0;
  633. sr->imask = 0;
  634. sr->spill_offset = 0x10; /* default to psp+16 */
  635. }
  636. }
  637. /*
  638.  * Prologue descriptors.
  639.  */
  640. static inline void
  641. desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr)
  642. {
  643. if (abi == 0 && context == 'i')
  644. sr->flags |= UNW_FLAG_INTERRUPT_FRAME;
  645. else
  646. dprintk("unwind: ignoring unwabi(abi=0x%x,context=0x%x)n", abi, context);
  647. }
  648. static inline void
  649. desc_br_gr (unsigned char brmask, unsigned char gr, struct unw_state_record *sr)
  650. {
  651. int i;
  652. for (i = 0; i < 5; ++i) {
  653. if (brmask & 1)
  654. set_reg(sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR,
  655. sr->region_start + sr->region_len - 1, gr++);
  656. brmask >>= 1;
  657. }
  658. }
  659. static inline void
  660. desc_br_mem (unsigned char brmask, struct unw_state_record *sr)
  661. {
  662. int i;
  663. for (i = 0; i < 5; ++i) {
  664. if (brmask & 1) {
  665. set_reg(sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME,
  666. sr->region_start + sr->region_len - 1, 0);
  667. sr->any_spills = 1;
  668. }
  669. brmask >>= 1;
  670. }
  671. }
  672. static inline void
  673. desc_frgr_mem (unsigned char grmask, unw_word frmask, struct unw_state_record *sr)
  674. {
  675. int i;
  676. for (i = 0; i < 4; ++i) {
  677. if ((grmask & 1) != 0) {
  678. set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
  679. sr->region_start + sr->region_len - 1, 0);
  680. sr->any_spills = 1;
  681. }
  682. grmask >>= 1;
  683. }
  684. for (i = 0; i < 20; ++i) {
  685. if ((frmask & 1) != 0) {
  686. set_reg(sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
  687. sr->region_start + sr->region_len - 1, 0);
  688. sr->any_spills = 1;
  689. }
  690. frmask >>= 1;
  691. }
  692. }
  693. static inline void
  694. desc_fr_mem (unsigned char frmask, struct unw_state_record *sr)
  695. {
  696. int i;
  697. for (i = 0; i < 4; ++i) {
  698. if ((frmask & 1) != 0) {
  699. set_reg(sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
  700. sr->region_start + sr->region_len - 1, 0);
  701. sr->any_spills = 1;
  702. }
  703. frmask >>= 1;
  704. }
  705. }
  706. static inline void
  707. desc_gr_gr (unsigned char grmask, unsigned char gr, struct unw_state_record *sr)
  708. {
  709. int i;
  710. for (i = 0; i < 4; ++i) {
  711. if ((grmask & 1) != 0)
  712. set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR,
  713. sr->region_start + sr->region_len - 1, gr++);
  714. grmask >>= 1;
  715. }
  716. }
  717. static inline void
  718. desc_gr_mem (unsigned char grmask, struct unw_state_record *sr)
  719. {
  720. int i;
  721. for (i = 0; i < 4; ++i) {
  722. if ((grmask & 1) != 0) {
  723. set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
  724. sr->region_start + sr->region_len - 1, 0);
  725. sr->any_spills = 1;
  726. }
  727. grmask >>= 1;
  728. }
  729. }
  730. static inline void
  731. desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr)
  732. {
  733. set_reg(sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE,
  734. sr->region_start + MIN((int)t, sr->region_len - 1), 16*size);
  735. }
  736. static inline void
  737. desc_mem_stack_v (unw_word t, struct unw_state_record *sr)
  738. {
  739. sr->curr.reg[UNW_REG_PSP].when = sr->region_start + MIN((int)t, sr->region_len - 1);
  740. }
  741. static inline void
  742. desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr)
  743. {
  744. set_reg(sr->curr.reg + reg, UNW_WHERE_GR, sr->region_start + sr->region_len - 1, dst);
  745. }
  746. static inline void
  747. desc_reg_psprel (unsigned char reg, unw_word pspoff, struct unw_state_record *sr)
  748. {
  749. set_reg(sr->curr.reg + reg, UNW_WHERE_PSPREL, sr->region_start + sr->region_len - 1,
  750. 0x10 - 4*pspoff);
  751. }
  752. static inline void
  753. desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr)
  754. {
  755. set_reg(sr->curr.reg + reg, UNW_WHERE_SPREL, sr->region_start + sr->region_len - 1,
  756. 4*spoff);
  757. }
  758. static inline void
  759. desc_rp_br (unsigned char dst, struct unw_state_record *sr)
  760. {
  761. sr->return_link_reg = dst;
  762. }
  763. static inline void
  764. desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr)
  765. {
  766. struct unw_reg_info *reg = sr->curr.reg + regnum;
  767. if (reg->where == UNW_WHERE_NONE)
  768. reg->where = UNW_WHERE_GR_SAVE;
  769. reg->when = sr->region_start + MIN((int)t, sr->region_len - 1);
  770. }
  771. static inline void
  772. desc_spill_base (unw_word pspoff, struct unw_state_record *sr)
  773. {
  774. sr->spill_offset = 0x10 - 4*pspoff;
  775. }
  776. static inline unsigned char *
  777. desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr)
  778. {
  779. sr->imask = imaskp;
  780. return imaskp + (2*sr->region_len + 7)/8;
  781. }
  782. /*
  783.  * Body descriptors.
  784.  */
  785. static inline void
  786. desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
  787. {
  788. sr->epilogue_start = sr->region_start + sr->region_len - 1 - t;
  789. sr->epilogue_count = ecount + 1;
  790. }
  791. static inline void
  792. desc_copy_state (unw_word label, struct unw_state_record *sr)
  793. {
  794. struct unw_reg_state *rs;
  795. for (rs = sr->reg_state_list; rs; rs = rs->next) {
  796. if (rs->label == label) {
  797. memcpy (&sr->curr, rs, sizeof(sr->curr));
  798. return;
  799. }
  800. }
  801. printk("unwind: failed to find state labelled 0x%lxn", label);
  802. }
  803. static inline void
  804. desc_label_state (unw_word label, struct unw_state_record *sr)
  805. {
  806. struct unw_reg_state *rs;
  807. rs = alloc_reg_state();
  808. if (!rs) {
  809. printk("unwind: cannot stack!n");
  810. return;
  811. }
  812. memcpy(rs, &sr->curr, sizeof(*rs));
  813. rs->label = label;
  814. rs->next = sr->reg_state_list;
  815. sr->reg_state_list = rs;
  816. }
  817. /*
  818.  * General descriptors.
  819.  */
  820. static inline int
  821. desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr)
  822. {
  823. if (sr->when_target <= sr->region_start + MIN((int)t, sr->region_len - 1))
  824. return 0;
  825. if (qp > 0) {
  826. if ((sr->pr_val & (1UL << qp)) == 0)
  827. return 0;
  828. sr->pr_mask |= (1UL << qp);
  829. }
  830. return 1;
  831. }
  832. static inline void
  833. desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, struct unw_state_record *sr)
  834. {
  835. struct unw_reg_info *r;
  836. if (!desc_is_active(qp, t, sr))
  837. return;
  838. r = sr->curr.reg + decode_abreg(abreg, 0);
  839. r->where = UNW_WHERE_NONE;
  840. r->when = UNW_WHEN_NEVER;
  841. r->val = 0;
  842. }
  843. static inline void
  844. desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, unsigned char x,
  845.      unsigned char ytreg, struct unw_state_record *sr)
  846. {
  847. enum unw_where where = UNW_WHERE_GR;
  848. struct unw_reg_info *r;
  849. if (!desc_is_active(qp, t, sr))
  850. return;
  851. if (x)
  852. where = UNW_WHERE_BR;
  853. else if (ytreg & 0x80)
  854. where = UNW_WHERE_FR;
  855. r = sr->curr.reg + decode_abreg(abreg, 0);
  856. r->where = where;
  857. r->when = sr->region_start + MIN((int)t, sr->region_len - 1);
  858. r->val = (ytreg & 0x7f);
  859. }
  860. static inline void
  861. desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word pspoff,
  862.      struct unw_state_record *sr)
  863. {
  864. struct unw_reg_info *r;
  865. if (!desc_is_active(qp, t, sr))
  866. return;
  867. r = sr->curr.reg + decode_abreg(abreg, 1);
  868. r->where = UNW_WHERE_PSPREL;
  869. r->when = sr->region_start + MIN((int)t, sr->region_len - 1);
  870. r->val = 0x10 - 4*pspoff;
  871. }
  872. static inline void
  873. desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word spoff,
  874.        struct unw_state_record *sr)
  875. {
  876. struct unw_reg_info *r;
  877. if (!desc_is_active(qp, t, sr))
  878. return;
  879. r = sr->curr.reg + decode_abreg(abreg, 1);
  880. r->where = UNW_WHERE_SPREL;
  881. r->when = sr->region_start + MIN((int)t, sr->region_len - 1);
  882. r->val = 4*spoff;
  883. }
  884. #define UNW_DEC_BAD_CODE(code) printk("unwind: unknown code 0x%02xn", code);
  885. /*
  886.  * region headers:
  887.  */
  888. #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
  889. #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
  890. /*
  891.  * prologue descriptors:
  892.  */
  893. #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
  894. #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
  895. #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
  896. #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
  897. #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
  898. #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
  899. #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
  900. #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
  901. #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
  902. #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
  903. #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
  904. #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
  905. #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
  906. #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
  907. #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
  908. #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
  909. #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
  910. #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
  911. #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
  912. #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
  913. #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
  914. /*
  915.  * body descriptors:
  916.  */
  917. #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
  918. #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
  919. #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
  920. /*
  921.  * general unwind descriptors:
  922.  */
  923. #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
  924. #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
  925. #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
  926. #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
  927. #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
  928. #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
  929. #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
  930. #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
  931. #include "unwind_decoder.c"
  932. /* Unwind scripts. */
  933. static inline unw_hash_index_t
  934. hash (unsigned long ip)
  935. {
  936. # define magic 0x9e3779b97f4a7c16 /* based on (sqrt(5)/2-1)*2^64 */
  937. return (ip >> 4)*magic >> (64 - UNW_LOG_HASH_SIZE);
  938. }
  939. static inline long
  940. cache_match (struct unw_script *script, unsigned long ip, unsigned long pr)
  941. {
  942. read_lock(&script->lock);
  943. if (ip == script->ip && ((pr ^ script->pr_val) & script->pr_mask) == 0)
  944. /* keep the read lock... */
  945. return 1;
  946. read_unlock(&script->lock);
  947. return 0;
  948. }
  949. static inline struct unw_script *
  950. script_lookup (struct unw_frame_info *info)
  951. {
  952. struct unw_script *script = unw.cache + info->hint;
  953. unsigned short index;
  954. unsigned long ip, pr;
  955. STAT(++unw.stat.cache.lookups);
  956. ip = info->ip;
  957. pr = info->pr;
  958. if (cache_match(script, ip, pr)) {
  959. STAT(++unw.stat.cache.hinted_hits);
  960. return script;
  961. }
  962. index = unw.hash[hash(ip)];
  963. if (index >= UNW_CACHE_SIZE)
  964. return 0;
  965. script = unw.cache + index;
  966. while (1) {
  967. if (cache_match(script, ip, pr)) {
  968. /* update hint; no locking required as single-word writes are atomic */
  969. STAT(++unw.stat.cache.normal_hits);
  970. unw.cache[info->prev_script].hint = script - unw.cache;
  971. return script;
  972. }
  973. if (script->coll_chain >= UNW_HASH_SIZE)
  974. return 0;
  975. script = unw.cache + script->coll_chain;
  976. STAT(++unw.stat.cache.collision_chain_traversals);
  977. }
  978. }
  979. /*
  980.  * On returning, a write lock for the SCRIPT is still being held.
  981.  */
  982. static inline struct unw_script *
  983. script_new (unsigned long ip)
  984. {
  985. struct unw_script *script, *prev, *tmp;
  986. unw_hash_index_t index;
  987. unsigned long flags;
  988. unsigned short head;
  989. STAT(++unw.stat.script.news);
  990. /*
  991.  * Can't (easily) use cmpxchg() here because of ABA problem
  992.  * that is intrinsic in cmpxchg()...
  993.  */
  994. spin_lock_irqsave(&unw.lock, flags);
  995. {
  996. head = unw.lru_head;
  997. script = unw.cache + head;
  998. unw.lru_head = script->lru_chain;
  999. }
  1000. spin_unlock(&unw.lock);
  1001. /*
  1002.  * XXX We'll deadlock here if we interrupt a thread that is
  1003.  * holding a read lock on script->lock.  A try_write_lock()
  1004.  * might be mighty handy here...  Alternatively, we could
  1005.  * disable interrupts whenever we hold a read-lock, but that
  1006.  * seems silly.
  1007.  */
  1008. write_lock(&script->lock);
  1009. spin_lock(&unw.lock);
  1010. {
  1011. /* re-insert script at the tail of the LRU chain: */
  1012. unw.cache[unw.lru_tail].lru_chain = head;
  1013. unw.lru_tail = head;
  1014. /* remove the old script from the hash table (if it's there): */
  1015. if (script->ip) {
  1016. index = hash(script->ip);
  1017. tmp = unw.cache + unw.hash[index];
  1018. prev = 0;
  1019. while (1) {
  1020. if (tmp == script) {
  1021. if (prev)
  1022. prev->coll_chain = tmp->coll_chain;
  1023. else
  1024. unw.hash[index] = tmp->coll_chain;
  1025. break;
  1026. } else
  1027. prev = tmp;
  1028. if (tmp->coll_chain >= UNW_CACHE_SIZE)
  1029. /* old script wasn't in the hash-table */
  1030. break;
  1031. tmp = unw.cache + tmp->coll_chain;
  1032. }
  1033. }
  1034. /* enter new script in the hash table */
  1035. index = hash(ip);
  1036. script->coll_chain = unw.hash[index];
  1037. unw.hash[index] = script - unw.cache;
  1038. script->ip = ip; /* set new IP while we're holding the locks */
  1039. STAT(if (script->coll_chain < UNW_CACHE_SIZE) ++unw.stat.script.collisions);
  1040. }
  1041. spin_unlock_irqrestore(&unw.lock, flags);
  1042. script->flags = 0;
  1043. script->hint = 0;
  1044. script->count = 0;
  1045. return script;
  1046. }
  1047. static void
  1048. script_finalize (struct unw_script *script, struct unw_state_record *sr)
  1049. {
  1050. script->pr_mask = sr->pr_mask;
  1051. script->pr_val = sr->pr_val;
  1052. /*
  1053.  * We could down-grade our write-lock on script->lock here but
  1054.  * the rwlock API doesn't offer atomic lock downgrading, so
  1055.  * we'll just keep the write-lock and release it later when
  1056.  * we're done using the script.
  1057.  */
  1058. }
  1059. static inline void
  1060. script_emit (struct unw_script *script, struct unw_insn insn)
  1061. {
  1062. if (script->count >= UNW_MAX_SCRIPT_LEN) {
  1063. dprintk("unwind: script exceeds maximum size of %u instructions!n",
  1064. UNW_MAX_SCRIPT_LEN);
  1065. return;
  1066. }
  1067. script->insn[script->count++] = insn;
  1068. }
  1069. static inline void
  1070. emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script)
  1071. {
  1072. struct unw_reg_info *r = sr->curr.reg + i;
  1073. enum unw_insn_opcode opc;
  1074. struct unw_insn insn;
  1075. unsigned long val = 0;
  1076. switch (r->where) {
  1077.       case UNW_WHERE_GR:
  1078. if (r->val >= 32) {
  1079. /* register got spilled to a stacked register */
  1080. opc = UNW_INSN_SETNAT_TYPE;
  1081. val = UNW_NAT_REGSTK;
  1082. } else
  1083. /* register got spilled to a scratch register */
  1084. opc = UNW_INSN_SETNAT_MEMSTK;
  1085. break;
  1086.       case UNW_WHERE_FR:
  1087. opc = UNW_INSN_SETNAT_TYPE;
  1088. val = UNW_NAT_VAL;
  1089. break;
  1090.       case UNW_WHERE_BR:
  1091. opc = UNW_INSN_SETNAT_TYPE;
  1092. val = UNW_NAT_NONE;
  1093. break;
  1094.       case UNW_WHERE_PSPREL:
  1095.       case UNW_WHERE_SPREL:
  1096. opc = UNW_INSN_SETNAT_MEMSTK;
  1097. break;
  1098.       default:
  1099. dprintk("unwind: don't know how to emit nat info for where = %un", r->where);
  1100. return;
  1101. }
  1102. insn.opc = opc;
  1103. insn.dst = unw.preg_index[i];
  1104. insn.val = val;
  1105. script_emit(script, insn);
  1106. }
  1107. static void
  1108. compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
  1109. {
  1110. struct unw_reg_info *r = sr->curr.reg + i;
  1111. enum unw_insn_opcode opc;
  1112. unsigned long val, rval;
  1113. struct unw_insn insn;
  1114. long need_nat_info;
  1115. if (r->where == UNW_WHERE_NONE || r->when >= sr->when_target)
  1116. return;
  1117. opc = UNW_INSN_MOVE;
  1118. val = rval = r->val;
  1119. need_nat_info = (i >= UNW_REG_R4 && i <= UNW_REG_R7);
  1120. switch (r->where) {
  1121.       case UNW_WHERE_GR:
  1122. if (rval >= 32) {
  1123. opc = UNW_INSN_MOVE_STACKED;
  1124. val = rval - 32;
  1125. } else if (rval >= 4 && rval <= 7) {
  1126. if (need_nat_info) {
  1127. opc = UNW_INSN_MOVE2;
  1128. need_nat_info = 0;
  1129. }
  1130. val = unw.preg_index[UNW_REG_R4 + (rval - 4)];
  1131. } else {
  1132. opc = UNW_INSN_ADD_SP;
  1133. val = -sizeof(struct pt_regs) + pt_regs_off(rval);
  1134. }
  1135. break;
  1136.       case UNW_WHERE_FR:
  1137. if (rval <= 5)
  1138. val = unw.preg_index[UNW_REG_F2  + (rval -  1)];
  1139. else if (rval >= 16 && rval <= 31)
  1140. val = unw.preg_index[UNW_REG_F16 + (rval - 16)];
  1141. else {
  1142. opc = UNW_INSN_ADD_SP;
  1143. val = -sizeof(struct pt_regs);
  1144. if (rval <= 9)
  1145. val += struct_offset(struct pt_regs, f6) + 16*(rval - 6);
  1146. else
  1147. dprintk("unwind: kernel may not touch f%lun", rval);
  1148. }
  1149. break;
  1150.       case UNW_WHERE_BR:
  1151. if (rval >= 1 && rval <= 5)
  1152. val = unw.preg_index[UNW_REG_B1 + (rval - 1)];
  1153. else {
  1154. opc = UNW_INSN_ADD_SP;
  1155. val = -sizeof(struct pt_regs);
  1156. if (rval == 0)
  1157. val += struct_offset(struct pt_regs, b0);
  1158. else if (rval == 6)
  1159. val += struct_offset(struct pt_regs, b6);
  1160. else
  1161. val += struct_offset(struct pt_regs, b7);
  1162. }
  1163. break;
  1164.       case UNW_WHERE_SPREL:
  1165. opc = UNW_INSN_ADD_SP;
  1166. break;
  1167.       case UNW_WHERE_PSPREL:
  1168. opc = UNW_INSN_ADD_PSP;
  1169. break;
  1170.       default:
  1171. dprintk("unwind: register %u has unexpected `where' value of %un", i, r->where);
  1172. break;
  1173. }
  1174. insn.opc = opc;
  1175. insn.dst = unw.preg_index[i];
  1176. insn.val = val;
  1177. script_emit(script, insn);
  1178. if (need_nat_info)
  1179. emit_nat_info(sr, i, script);
  1180. if (i == UNW_REG_PSP) {
  1181. /*
  1182.  * info->psp must contain the _value_ of the previous
  1183.  * sp, not it's save location.  We get this by
  1184.  * dereferencing the value we just stored in
  1185.  * info->psp:
  1186.  */
  1187. insn.opc = UNW_INSN_LOAD;
  1188. insn.dst = insn.val = unw.preg_index[UNW_REG_PSP];
  1189. script_emit(script, insn);
  1190. }
  1191. }
  1192. static inline const struct unw_table_entry *
  1193. lookup (struct unw_table *table, unsigned long rel_ip)
  1194. {
  1195. const struct unw_table_entry *e = 0;
  1196. unsigned long lo, hi, mid;
  1197. /* do a binary search for right entry: */
  1198. for (lo = 0, hi = table->length; lo < hi; ) {
  1199. mid = (lo + hi) / 2;
  1200. e = &table->array[mid];
  1201. if (rel_ip < e->start_offset)
  1202. hi = mid;
  1203. else if (rel_ip >= e->end_offset)
  1204. lo = mid + 1;
  1205. else
  1206. break;
  1207. }
  1208. return e;
  1209. }
  1210. /*
  1211.  * Build an unwind script that unwinds from state OLD_STATE to the
  1212.  * entrypoint of the function that called OLD_STATE.
  1213.  */
  1214. static inline struct unw_script *
  1215. build_script (struct unw_frame_info *info)
  1216. {
  1217. struct unw_reg_state *rs, *next;
  1218. const struct unw_table_entry *e = 0;
  1219. struct unw_script *script = 0;
  1220. unsigned long ip = info->ip;
  1221. struct unw_state_record sr;
  1222. struct unw_table *table;
  1223. struct unw_reg_info *r;
  1224. struct unw_insn insn;
  1225. u8 *dp, *desc_end;
  1226. u64 hdr;
  1227. int i;
  1228. STAT(unsigned long start, parse_start;)
  1229. STAT(++unw.stat.script.builds; start = ia64_get_itc());
  1230. /* build state record */
  1231. memset(&sr, 0, sizeof(sr));
  1232. for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r)
  1233. r->when = UNW_WHEN_NEVER;
  1234. sr.pr_val = info->pr;
  1235. script = script_new(ip);
  1236. if (!script) {
  1237. dprintk("unwind: failed to create unwind scriptn");
  1238. STAT(unw.stat.script.build_time += ia64_get_itc() - start);
  1239. return 0;
  1240. }
  1241. unw.cache[info->prev_script].hint = script - unw.cache;
  1242. /* search the kernels and the modules' unwind tables for IP: */
  1243. STAT(parse_start = ia64_get_itc());
  1244. for (table = unw.tables; table; table = table->next) {
  1245. if (ip >= table->start && ip < table->end) {
  1246. e = lookup(table, ip - table->segment_base);
  1247. break;
  1248. }
  1249. }
  1250. if (!e) {
  1251. /* no info, return default unwinder (leaf proc, no mem stack, no saved regs)  */
  1252. dprintk("unwind: no unwind info for ip=0x%lx (prev ip=0x%lx)n", ip,
  1253. unw.cache[info->prev_script].ip);
  1254. sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
  1255. sr.curr.reg[UNW_REG_RP].when = -1;
  1256. sr.curr.reg[UNW_REG_RP].val = 0;
  1257. compile_reg(&sr, UNW_REG_RP, script);
  1258. script_finalize(script, &sr);
  1259. STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
  1260. STAT(unw.stat.script.build_time += ia64_get_itc() - start);
  1261. return script;
  1262. }
  1263. sr.when_target = (3*((ip & ~0xfUL) - (table->segment_base + e->start_offset))/16
  1264.   + (ip & 0xfUL));
  1265. hdr = *(u64 *) (table->segment_base + e->info_offset);
  1266. dp =   (u8 *)  (table->segment_base + e->info_offset + 8);
  1267. desc_end = dp + 8*UNW_LENGTH(hdr);
  1268. while (!sr.done && dp < desc_end)
  1269. dp = unw_decode(dp, sr.in_body, &sr);
  1270. if (sr.when_target > sr.epilogue_start) {
  1271. /*
  1272.  * sp has been restored and all values on the memory stack below
  1273.  * psp also have been restored.
  1274.  */
  1275. sr.curr.reg[UNW_REG_PSP].val = 0;
  1276. sr.curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
  1277. sr.curr.reg[UNW_REG_PSP].when = UNW_WHEN_NEVER;
  1278. for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r)
  1279. if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10)
  1280.     || r->where == UNW_WHERE_SPREL)
  1281. {
  1282. r->val = 0;
  1283. r->where = UNW_WHERE_NONE;
  1284. r->when = UNW_WHEN_NEVER;
  1285. }
  1286. }
  1287. script->flags = sr.flags;
  1288. /*
  1289.  * If RP did't get saved, generate entry for the return link
  1290.  * register.
  1291.  */
  1292. if (sr.curr.reg[UNW_REG_RP].when >= sr.when_target) {
  1293. sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
  1294. sr.curr.reg[UNW_REG_RP].when = -1;
  1295. sr.curr.reg[UNW_REG_RP].val = sr.return_link_reg;
  1296. }
  1297. #if UNW_DEBUG
  1298. printk("unwind: state record for func 0x%lx, t=%u:n",
  1299.        table->segment_base + e->start_offset, sr.when_target);
  1300. for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) {
  1301. if (r->where != UNW_WHERE_NONE || r->when != UNW_WHEN_NEVER) {
  1302. printk("  %s <- ", unw.preg_name[r - sr.curr.reg]);
  1303. switch (r->where) {
  1304.       case UNW_WHERE_GR:     printk("r%lu", r->val); break;
  1305.       case UNW_WHERE_FR:     printk("f%lu", r->val); break;
  1306.       case UNW_WHERE_BR:     printk("b%lu", r->val); break;
  1307.       case UNW_WHERE_SPREL:  printk("[sp+0x%lx]", r->val); break;
  1308.       case UNW_WHERE_PSPREL: printk("[psp+0x%lx]", r->val); break;
  1309.       case UNW_WHERE_NONE:
  1310. printk("%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val);
  1311. break;
  1312.       default:      printk("BADWHERE(%d)", r->where); break;
  1313. }
  1314. printk("tt%dn", r->when);
  1315. }
  1316. }
  1317. #endif
  1318. STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
  1319. /* translate state record into unwinder instructions: */
  1320. /*
  1321.  * First, set psp if we're dealing with a fixed-size frame;
  1322.  * subsequent instructions may depend on this value.
  1323.  */
  1324. if (sr.when_target > sr.curr.reg[UNW_REG_PSP].when
  1325.     && (sr.curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE)
  1326.     && sr.curr.reg[UNW_REG_PSP].val != 0) {
  1327. /* new psp is sp plus frame size */
  1328. insn.opc = UNW_INSN_ADD;
  1329. insn.dst = struct_offset(struct unw_frame_info, psp)/8;
  1330. insn.val = sr.curr.reg[UNW_REG_PSP].val; /* frame size */
  1331. script_emit(script, insn);
  1332. }
  1333. /* determine where the primary UNaT is: */
  1334. if (sr.when_target < sr.curr.reg[UNW_REG_PRI_UNAT_GR].when)
  1335. i = UNW_REG_PRI_UNAT_MEM;
  1336. else if (sr.when_target < sr.curr.reg[UNW_REG_PRI_UNAT_MEM].when)
  1337. i = UNW_REG_PRI_UNAT_GR;
  1338. else if (sr.curr.reg[UNW_REG_PRI_UNAT_MEM].when > sr.curr.reg[UNW_REG_PRI_UNAT_GR].when)
  1339. i = UNW_REG_PRI_UNAT_MEM;
  1340. else
  1341. i = UNW_REG_PRI_UNAT_GR;
  1342. compile_reg(&sr, i, script);
  1343. for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i)
  1344. compile_reg(&sr, i, script);
  1345. /* free labelled register states & stack: */
  1346. STAT(parse_start = ia64_get_itc());
  1347. for (rs = sr.reg_state_list; rs; rs = next) {
  1348. next = rs->next;
  1349. free_reg_state(rs);
  1350. }
  1351. while (sr.stack)
  1352. pop(&sr);
  1353. STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
  1354. script_finalize(script, &sr);
  1355. STAT(unw.stat.script.build_time += ia64_get_itc() - start);
  1356. return script;
  1357. }
  1358. /*
  1359.  * Apply the unwinding actions represented by OPS and update SR to
  1360.  * reflect the state that existed upon entry to the function that this
  1361.  * unwinder represents.
  1362.  */
  1363. static inline void
  1364. run_script (struct unw_script *script, struct unw_frame_info *state)
  1365. {
  1366. struct unw_insn *ip, *limit, next_insn;
  1367. unsigned long opc, dst, val, off;
  1368. unsigned long *s = (unsigned long *) state;
  1369. STAT(unsigned long start;)
  1370. STAT(++unw.stat.script.runs; start = ia64_get_itc());
  1371. state->flags = script->flags;
  1372. ip = script->insn;
  1373. limit = script->insn + script->count;
  1374. next_insn = *ip;
  1375. while (ip++ < limit) {
  1376. opc = next_insn.opc;
  1377. dst = next_insn.dst;
  1378. val = next_insn.val;
  1379. next_insn = *ip;
  1380.   redo:
  1381. switch (opc) {
  1382.       case UNW_INSN_ADD:
  1383. s[dst] += val;
  1384. break;
  1385.       case UNW_INSN_MOVE2:
  1386. if (!s[val])
  1387. goto lazy_init;
  1388. s[dst+1] = s[val+1];
  1389. s[dst] = s[val];
  1390. break;
  1391.       case UNW_INSN_MOVE:
  1392. if (!s[val])
  1393. goto lazy_init;
  1394. s[dst] = s[val];
  1395. break;
  1396.       case UNW_INSN_MOVE_STACKED:
  1397. s[dst] = (unsigned long) ia64_rse_skip_regs((unsigned long *)state->bsp,
  1398.     val);
  1399. break;
  1400.       case UNW_INSN_ADD_PSP:
  1401. s[dst] = state->psp + val;
  1402. break;
  1403.       case UNW_INSN_ADD_SP:
  1404. s[dst] = state->sp + val;
  1405. break;
  1406.       case UNW_INSN_SETNAT_MEMSTK:
  1407. if (!state->pri_unat_loc)
  1408. state->pri_unat_loc = &state->sw->ar_unat;
  1409. /* register off. is a multiple of 8, so the least 3 bits (type) are 0 */
  1410. s[dst+1] = (*state->pri_unat_loc - s[dst]) | UNW_NAT_MEMSTK;
  1411. break;
  1412.       case UNW_INSN_SETNAT_TYPE:
  1413. s[dst+1] = val;
  1414. break;
  1415.       case UNW_INSN_LOAD:
  1416. #if UNW_DEBUG
  1417. if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7)) != 0
  1418.     || s[val] < TASK_SIZE)
  1419. {
  1420. debug(1, "unwind: rejecting bad psp=0x%lxn", s[val]);
  1421. break;
  1422. }
  1423. #endif
  1424. s[dst] = *(unsigned long *) s[val];
  1425. break;
  1426. }
  1427. }
  1428. STAT(unw.stat.script.run_time += ia64_get_itc() - start);
  1429. return;
  1430.   lazy_init:
  1431. off = unw.sw_off[val];
  1432. s[val] = (unsigned long) state->sw + off;
  1433. if (off >= struct_offset(struct switch_stack, r4)
  1434.     && off <= struct_offset(struct switch_stack, r7))
  1435. /*
  1436.  * We're initializing a general register: init NaT info, too.  Note that
  1437.  * the offset is a multiple of 8 which gives us the 3 bits needed for
  1438.  * the type field.
  1439.  */
  1440. s[val+1] = (struct_offset(struct switch_stack, ar_unat) - off) | UNW_NAT_MEMSTK;
  1441. goto redo;
  1442. }
  1443. static int
  1444. find_save_locs (struct unw_frame_info *info)
  1445. {
  1446. int have_write_lock = 0;
  1447. struct unw_script *scr;
  1448. if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) {
  1449. /* don't let obviously bad addresses pollute the cache */
  1450. debug(1, "unwind: rejecting bad ip=0x%lxn", info->ip);
  1451. info->rp_loc = 0;
  1452. return -1;
  1453. }
  1454. scr = script_lookup(info);
  1455. if (!scr) {
  1456. scr = build_script(info);
  1457. if (!scr) {
  1458. dprintk("unwind: failed to locate/build unwind script for ip %lxn",
  1459. info->ip);
  1460. return -1;
  1461. }
  1462. have_write_lock = 1;
  1463. }
  1464. info->hint = scr->hint;
  1465. info->prev_script = scr - unw.cache;
  1466. run_script(scr, info);
  1467. if (have_write_lock)
  1468. write_unlock(&scr->lock);
  1469. else
  1470. read_unlock(&scr->lock);
  1471. return 0;
  1472. }
  1473. int
  1474. unw_unwind (struct unw_frame_info *info)
  1475. {
  1476. unsigned long prev_ip, prev_sp, prev_bsp;
  1477. unsigned long ip, pr, num_regs;
  1478. STAT(unsigned long start, flags;)
  1479. int retval;
  1480. STAT(local_irq_save(flags); ++unw.stat.api.unwinds; start = ia64_get_itc());
  1481. prev_ip = info->ip;
  1482. prev_sp = info->sp;
  1483. prev_bsp = info->bsp;
  1484. /* restore the ip */
  1485. if (!info->rp_loc) {
  1486. debug(1, "unwind: failed to locate return link (ip=0x%lx)!n", info->ip);
  1487. STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
  1488. return -1;
  1489. }
  1490. ip = info->ip = *info->rp_loc;
  1491. if (ip < GATE_ADDR + PAGE_SIZE) {
  1492. /*
  1493.  * We don't have unwind info for the gate page, so we consider that part
  1494.  * of user-space for the purpose of unwinding.
  1495.  */
  1496. debug(1, "unwind: reached user-space (ip=0x%lx)n", ip);
  1497. STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
  1498. return -1;
  1499. }
  1500. /* restore the cfm: */
  1501. if (!info->pfs_loc) {
  1502. dprintk("unwind: failed to locate ar.pfs!n");
  1503. STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
  1504. return -1;
  1505. }
  1506. info->cfm_loc = info->pfs_loc;
  1507. /* restore the bsp: */
  1508. pr = info->pr;
  1509. num_regs = 0;
  1510. if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) {
  1511. if ((pr & (1UL << pNonSys)) != 0)
  1512. num_regs = *info->cfm_loc & 0x7f; /* size of frame */
  1513. info->pfs_loc =
  1514. (unsigned long *) (info->sp + 16 + struct_offset(struct pt_regs, ar_pfs));
  1515. } else
  1516. num_regs = (*info->cfm_loc >> 7) & 0x7f; /* size of locals */
  1517. info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -num_regs);
  1518. if (info->bsp < info->regstk.limit || info->bsp > info->regstk.top) {
  1519. dprintk("unwind: bsp (0x%lx) out of range [0x%lx-0x%lx]n",
  1520. info->bsp, info->regstk.limit, info->regstk.top);
  1521. STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
  1522. return -1;
  1523. }
  1524. /* restore the sp: */
  1525. info->sp = info->psp;
  1526. if (info->sp < info->memstk.top || info->sp > info->memstk.limit) {
  1527. dprintk("unwind: sp (0x%lx) out of range [0x%lx-0x%lx]n",
  1528. info->sp, info->memstk.top, info->memstk.limit);
  1529. STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
  1530. return -1;
  1531. }
  1532. if (info->ip == prev_ip && info->sp == prev_sp && info->bsp == prev_bsp) {
  1533. dprintk("unwind: ip, sp, bsp remain unchanged; stopping here (ip=0x%lx)n", ip);
  1534. STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
  1535. return -1;
  1536. }
  1537. /* as we unwind, the saved ar.unat becomes the primary unat: */
  1538. info->pri_unat_loc = info->unat_loc;
  1539. /* finally, restore the predicates: */
  1540. unw_get_pr(info, &info->pr);
  1541. retval = find_save_locs(info);
  1542. STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
  1543. return retval;
  1544. }
  1545. int
  1546. unw_unwind_to_user (struct unw_frame_info *info)
  1547. {
  1548. unsigned long ip;
  1549. while (unw_unwind(info) >= 0) {
  1550. if (unw_get_rp(info, &ip) < 0) {
  1551. unw_get_ip(info, &ip);
  1552. dprintk("unwind: failed to read return pointer (ip=0x%lx)n", ip);
  1553. return -1;
  1554. }
  1555. /*
  1556.  * We don't have unwind info for the gate page, so we consider that part
  1557.  * of user-space for the purpose of unwinding.
  1558.  */
  1559. if (ip < GATE_ADDR + PAGE_SIZE)
  1560. return 0;
  1561. }
  1562. unw_get_ip(info, &ip);
  1563. dprintk("unwind: failed to unwind to user-level (ip=0x%lx)n", ip);
  1564. return -1;
  1565. }
  1566. void
  1567. unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw)
  1568. {
  1569. unsigned long rbslimit, rbstop, stklimit, stktop, sol;
  1570. STAT(unsigned long start, flags;)
  1571. STAT(local_irq_save(flags); ++unw.stat.api.inits; start = ia64_get_itc());
  1572. /*
  1573.  * Subtle stuff here: we _could_ unwind through the
  1574.  * switch_stack frame but we don't want to do that because it
  1575.  * would be slow as each preserved register would have to be
  1576.  * processed.  Instead, what we do here is zero out the frame
  1577.  * info and start the unwind process at the function that
  1578.  * created the switch_stack frame.  When a preserved value in
  1579.  * switch_stack needs to be accessed, run_script() will
  1580.  * initialize the appropriate pointer on demand.
  1581.  */
  1582. memset(info, 0, sizeof(*info));
  1583. rbslimit = (unsigned long) t + IA64_RBS_OFFSET;
  1584. rbstop   = sw->ar_bspstore;
  1585. if (rbstop - (unsigned long) t >= IA64_STK_OFFSET)
  1586. rbstop = rbslimit;
  1587. stklimit = (unsigned long) t + IA64_STK_OFFSET;
  1588. stktop   = (unsigned long) sw - 16;
  1589. if (stktop <= rbstop)
  1590. stktop = rbstop;
  1591. info->regstk.limit = rbslimit;
  1592. info->regstk.top   = rbstop;
  1593. info->memstk.limit = stklimit;
  1594. info->memstk.top   = stktop;
  1595. info->task = t;
  1596. info->sw  = sw;
  1597. info->sp = info->psp = (unsigned long) (sw + 1) - 16;
  1598. info->cfm_loc = &sw->ar_pfs;
  1599. sol = (*info->cfm_loc >> 7) & 0x7f;
  1600. info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sol);
  1601. info->ip = sw->b0;
  1602. info->pr = sw->pr;
  1603. find_save_locs(info);
  1604. STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
  1605. }
  1606. void
  1607. unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
  1608. {
  1609. struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16);
  1610. unw_init_frame_info(info, t, sw);
  1611. }
  1612. static void
  1613. init_unwind_table (struct unw_table *table, const char *name, unsigned long segment_base,
  1614.    unsigned long gp, const void *table_start, const void *table_end)
  1615. {
  1616. const struct unw_table_entry *start = table_start, *end = table_end;
  1617. table->name = name;
  1618. table->segment_base = segment_base;
  1619. table->gp = gp;
  1620. table->start = segment_base + start[0].start_offset;
  1621. table->end = segment_base + end[-1].end_offset;
  1622. table->array = start;
  1623. table->length = end - start;
  1624. }
  1625. void *
  1626. unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned long gp,
  1627.       const void *table_start, const void *table_end)
  1628. {
  1629. const struct unw_table_entry *start = table_start, *end = table_end;
  1630. struct unw_table *table;
  1631. unsigned long flags;
  1632. if (end - start <= 0) {
  1633. dprintk("unwind: ignoring attempt to insert empty unwind tablen");
  1634. return 0;
  1635. }
  1636. table = kmalloc(sizeof(*table), GFP_USER);
  1637. if (!table)
  1638. return 0;
  1639. init_unwind_table(table, name, segment_base, gp, table_start, table_end);
  1640. spin_lock_irqsave(&unw.lock, flags);
  1641. {
  1642. /* keep kernel unwind table at the front (it's searched most commonly): */
  1643. table->next = unw.tables->next;
  1644. unw.tables->next = table;
  1645. }
  1646. spin_unlock_irqrestore(&unw.lock, flags);
  1647. return table;
  1648. }
  1649. void
  1650. unw_remove_unwind_table (void *handle)
  1651. {
  1652. struct unw_table *table, *prev;
  1653. struct unw_script *tmp;
  1654. unsigned long flags;
  1655. long index;
  1656. if (!handle) {
  1657. dprintk("unwind: ignoring attempt to remove non-existent unwind tablen");
  1658. return;
  1659. }
  1660. table = handle;
  1661. if (table == &unw.kernel_table) {
  1662. dprintk("unwind: sorry, freeing the kernel's unwind table is a no-can-do!n");
  1663. return;
  1664. }
  1665. spin_lock_irqsave(&unw.lock, flags);
  1666. {
  1667. /* first, delete the table: */
  1668. for (prev = (struct unw_table *) &unw.tables; prev; prev = prev->next)
  1669. if (prev->next == table)
  1670. break;
  1671. if (!prev) {
  1672. dprintk("unwind: failed to find unwind table %pn", (void *) table);
  1673. spin_unlock_irqrestore(&unw.lock, flags);
  1674. return;
  1675. }
  1676. prev->next = table->next;
  1677. }
  1678. spin_unlock_irqrestore(&unw.lock, flags);
  1679. /* next, remove hash table entries for this table */
  1680. for (index = 0; index <= UNW_HASH_SIZE; ++index) {
  1681. tmp = unw.cache + unw.hash[index];
  1682. if (unw.hash[index] >= UNW_CACHE_SIZE
  1683.     || tmp->ip < table->start || tmp->ip >= table->end)
  1684. continue;
  1685. write_lock(&tmp->lock);
  1686. {
  1687. if (tmp->ip >= table->start && tmp->ip < table->end) {
  1688. unw.hash[index] = tmp->coll_chain;
  1689. tmp->ip = 0;
  1690. }
  1691. }
  1692. write_unlock(&tmp->lock);
  1693. }
  1694. kfree(table);
  1695. }
  1696. void
  1697. unw_create_gate_table (void)
  1698. {
  1699. extern char __start_gate_section[], __stop_gate_section[];
  1700. unsigned long *lp, start, end, segbase = unw.kernel_table.segment_base;
  1701. const struct unw_table_entry *entry, *first;
  1702. size_t info_size, size;
  1703. char *info;
  1704. start = (unsigned long) __start_gate_section - segbase;
  1705. end   = (unsigned long) __stop_gate_section - segbase;
  1706. size  = 0;
  1707. first = lookup(&unw.kernel_table, start);
  1708. for (entry = first; entry->start_offset < end; ++entry)
  1709. size += 3*8 + 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
  1710. size += 8; /* reserve space for "end of table" marker */
  1711. unw.gate_table = alloc_bootmem(size);
  1712. if (!unw.gate_table) {
  1713. unw.gate_table_size = 0;
  1714. printk("unwind: unable to create unwind data for gate page!n");
  1715. return;
  1716. }
  1717. unw.gate_table_size = size;
  1718. lp = unw.gate_table;
  1719. info = (char *) unw.gate_table + size;
  1720. for (entry = first; entry->start_offset < end; ++entry, lp += 3) {
  1721. info_size = 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
  1722. info -= info_size;
  1723. memcpy(info, (char *) segbase + entry->info_offset, info_size);
  1724. lp[0] = entry->start_offset - start + GATE_ADDR; /* start */
  1725. lp[1] = entry->end_offset - start + GATE_ADDR; /* end */
  1726. lp[2] = info - (char *) unw.gate_table; /* info */
  1727. }
  1728. *lp = 0; /* end-of-table marker */
  1729. }
  1730. void
  1731. unw_init (void)
  1732. {
  1733. extern int ia64_unw_start, ia64_unw_end, __gp;
  1734. extern void unw_hash_index_t_is_too_narrow (void);
  1735. long i, off;
  1736. if (8*sizeof(unw_hash_index_t) < UNW_LOG_HASH_SIZE)
  1737. unw_hash_index_t_is_too_narrow();
  1738. unw.sw_off[unw.preg_index[UNW_REG_PRI_UNAT_GR]] = SW(AR_UNAT);
  1739. unw.sw_off[unw.preg_index[UNW_REG_BSPSTORE]] = SW(AR_BSPSTORE);
  1740. unw.sw_off[unw.preg_index[UNW_REG_PFS]] = SW(AR_UNAT);
  1741. unw.sw_off[unw.preg_index[UNW_REG_RP]] = SW(B0);
  1742. unw.sw_off[unw.preg_index[UNW_REG_UNAT]] = SW(AR_UNAT);
  1743. unw.sw_off[unw.preg_index[UNW_REG_PR]] = SW(PR);
  1744. unw.sw_off[unw.preg_index[UNW_REG_LC]] = SW(AR_LC);
  1745. unw.sw_off[unw.preg_index[UNW_REG_FPSR]] = SW(AR_FPSR);
  1746. for (i = UNW_REG_R4, off = SW(R4); i <= UNW_REG_R7; ++i, off += 8)
  1747. unw.sw_off[unw.preg_index[i]] = off;
  1748. for (i = UNW_REG_B1, off = SW(B1); i <= UNW_REG_B5; ++i, off += 8)
  1749. unw.sw_off[unw.preg_index[i]] = off;
  1750. for (i = UNW_REG_F2, off = SW(F2); i <= UNW_REG_F5; ++i, off += 16)
  1751. unw.sw_off[unw.preg_index[i]] = off;
  1752. for (i = UNW_REG_F16, off = SW(F16); i <= UNW_REG_F31; ++i, off += 16)
  1753. unw.sw_off[unw.preg_index[i]] = off;
  1754. for (i = 0; i < UNW_CACHE_SIZE; ++i) {
  1755. if (i > 0)
  1756. unw.cache[i].lru_chain = (i - 1);
  1757. unw.cache[i].coll_chain = -1;
  1758. unw.cache[i].lock = RW_LOCK_UNLOCKED;
  1759. }
  1760. unw.lru_head = UNW_CACHE_SIZE - 1;
  1761. unw.lru_tail = 0;
  1762. init_unwind_table(&unw.kernel_table, "kernel", KERNEL_START, (unsigned long) &__gp,
  1763.   &ia64_unw_start, &ia64_unw_end);
  1764. }
  1765. /*
  1766.  * This system call copies the unwind data into the buffer pointed to by BUF and returns
  1767.  * the size of the unwind data.  If BUF_SIZE is smaller than the size of the unwind data
  1768.  * or if BUF is NULL, nothing is copied, but the system call still returns the size of the
  1769.  * unwind data.
  1770.  *
  1771.  * The first portion of the unwind data contains an unwind table and rest contains the
  1772.  * associated unwind info (in no particular order).  The unwind table consists of a table
  1773.  * of entries of the form:
  1774.  *
  1775.  * u64 start; (64-bit address of start of function)
  1776.  * u64 end; (64-bit address of start of function)
  1777.  * u64 info; (BUF-relative offset to unwind info)
  1778.  *
  1779.  * The end of the unwind table is indicated by an entry with a START address of zero.
  1780.  *
  1781.  * Please see the IA-64 Software Conventions and Runtime Architecture manual for details
  1782.  * on the format of the unwind info.
  1783.  *
  1784.  * ERRORS
  1785.  * EFAULT BUF points outside your accessible address space.
  1786.  */
  1787. asmlinkage long
  1788. sys_getunwind (void *buf, size_t buf_size)
  1789. {
  1790. if (buf && buf_size >= unw.gate_table_size)
  1791. if (copy_to_user(buf, unw.gate_table, unw.gate_table_size) != 0)
  1792. return -EFAULT;
  1793. return unw.gate_table_size;
  1794. }