unwind.c 62 KB

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