unwind.c 62 KB

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