dwframe.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957
  1. /*++
  2. Copyright (c) 2015 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. dwframe.c
  9. Abstract:
  10. This module implements support for DWARF stack unwinding.
  11. Author:
  12. Evan Green 16-Dec-2015
  13. Environment:
  14. Debug
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <minoca/lib/types.h>
  20. #include <minoca/lib/status.h>
  21. #include <minoca/lib/im.h>
  22. #include "dwarfp.h"
  23. #include <assert.h>
  24. #include <errno.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. //
  29. // ---------------------------------------------------------------- Definitions
  30. //
  31. //
  32. // Define the highest known register number.
  33. //
  34. #define DWARF_MAX_REGISTERS (ArmRegisterD31 + 1)
  35. //
  36. // Define the maximum size of the remember stack.
  37. //
  38. #define DWARF_MAX_REMEMBER_STACK 32
  39. //
  40. // ------------------------------------------------------ Data Type Definitions
  41. //
  42. typedef enum _DWARF_FRAME_RULE_TYPE {
  43. DwarfFrameUndefined = 0,
  44. DwarfFrameSameValue,
  45. DwarfFrameCfaOffset,
  46. DwarfFrameCfaOffsetValue,
  47. DwarfFrameRegister,
  48. DwarfFrameExpression,
  49. DwarfFrameExpressionValue,
  50. DwarfFrameArchitectural
  51. } DWARF_FRAME_RULE_TYPE, *PDWARF_FRAME_RULE_TYPE;
  52. typedef struct _DWARF_FRAME_STACK DWARF_FRAME_STACK, *PDWARF_FRAME_STACK;
  53. /*++
  54. Structure Description:
  55. This structure stores a DWARF unwinding rule for a particular register.
  56. Members:
  57. Type - Stores the rule type.
  58. Operand - Stores the operand to the rule.
  59. Operand2 - Stores the second operand to the rule.
  60. --*/
  61. typedef struct _DWARF_FRAME_RULE {
  62. DWARF_FRAME_RULE_TYPE Type;
  63. ULONGLONG Operand;
  64. ULONGLONG Operand2;
  65. } DWARF_FRAME_RULE, *PDWARF_FRAME_RULE;
  66. /*++
  67. Structure Description:
  68. This structure stores an array of DWARF frame rules for every register,
  69. representing the current frame unwinding state.
  70. Members:
  71. Cfa - Stores the CFA rule.
  72. Registers - Stores the array of rules for each register.
  73. --*/
  74. typedef struct _DWARF_FRAME_RULE_SET {
  75. DWARF_FRAME_RULE Cfa;
  76. DWARF_FRAME_RULE Registers[DWARF_MAX_REGISTERS];
  77. } DWARF_FRAME_RULE_SET, *PDWARF_FRAME_RULE_SET;
  78. /*++
  79. Structure Description:
  80. This structure stores a stack entry of remembered rule states.
  81. Members:
  82. Next - Stores a pointer to the next stack element.
  83. RuleSet - Stores the set of rules on the stack.
  84. --*/
  85. struct _DWARF_FRAME_STACK {
  86. PDWARF_FRAME_STACK Next;
  87. DWARF_FRAME_RULE_SET RuleSet;
  88. };
  89. /*++
  90. Structure Description:
  91. This structure defines the state for executing frame unwinding.
  92. Members:
  93. Location - Stores the current location.
  94. Rules - Stores the current rules set.
  95. InitialRules - Stores the initial rules after executing the CIE initial
  96. instructions.
  97. RememberStack - Stores the stack of states pushed on by the remember
  98. instruction.
  99. RememberStackSize - Stores the size of the remember stack in bytes.
  100. MaxRegister - Stores the maximum register number that has been changed.
  101. NewValue - Stores the unwound register values.
  102. --*/
  103. typedef struct _DWARF_FRAME_STATE {
  104. ULONGLONG Location;
  105. DWARF_FRAME_RULE_SET Rules;
  106. DWARF_FRAME_RULE_SET InitialRules;
  107. PDWARF_FRAME_STACK RememberStack;
  108. UINTN RememberStackSize;
  109. ULONG MaxRegister;
  110. ULONGLONG NewValue[DWARF_MAX_REGISTERS];
  111. } DWARF_FRAME_STATE, *PDWARF_FRAME_STATE;
  112. //
  113. // ----------------------------------------------- Internal Function Prototypes
  114. //
  115. INT
  116. DwarfpExecuteFde (
  117. PDWARF_CONTEXT Context,
  118. ULONGLONG Pc,
  119. PDWARF_FDE Fde,
  120. PDWARF_CIE Cie,
  121. BOOL CfaOnly,
  122. PSTACK_FRAME Frame
  123. );
  124. INT
  125. DwarfpExecuteFrameInstructions (
  126. PDWARF_CONTEXT Context,
  127. ULONGLONG Pc,
  128. PDWARF_CIE Cie,
  129. PUCHAR Instructions,
  130. PUCHAR End,
  131. PDWARF_FRAME_STATE State
  132. );
  133. VOID
  134. DwarfpSetFrameRule (
  135. PDWARF_CONTEXT Context,
  136. PDWARF_FRAME_STATE State,
  137. ULONG Register,
  138. DWARF_FRAME_RULE_TYPE RuleType,
  139. ULONGLONG Operand,
  140. ULONGLONG Operand2
  141. );
  142. INT
  143. DwarfpGetValueFromRule (
  144. PDWARF_CONTEXT Context,
  145. PDWARF_FRAME_STATE State,
  146. ULONG Register,
  147. ULONG AddressSize,
  148. ULONGLONG Cfa,
  149. PULONGLONG UnwoundValue
  150. );
  151. INT
  152. DwarfpFindFrameInfo (
  153. PDWARF_CONTEXT Context,
  154. ULONGLONG Pc,
  155. PDWARF_CIE Cie,
  156. PDWARF_FDE Fde
  157. );
  158. INT
  159. DwarfpReadCieOrFde (
  160. PDWARF_CONTEXT Context,
  161. BOOL EhFrame,
  162. PUCHAR *Table,
  163. PUCHAR End,
  164. PDWARF_CIE Cie,
  165. PDWARF_FDE Fde,
  166. PBOOL IsCie
  167. );
  168. ULONGLONG
  169. DwarfpReadEncodedAddress (
  170. PDWARF_CONTEXT Context,
  171. DWARF_ADDRESS_ENCODING Encoding,
  172. UCHAR AddressSize,
  173. PUCHAR *Table
  174. );
  175. //
  176. // -------------------------------------------------------------------- Globals
  177. //
  178. PSTR DwarfCfaEncodingNames[] = {
  179. "DwarfCfaNop",
  180. "DwarfCfaSetLoc",
  181. "DwarfCfaAdvanceLoc1",
  182. "DwarfCfaAdvanceLoc2",
  183. "DwarfCfaAdvanceLoc4",
  184. "DwarfCfaOffsetExtended",
  185. "DwarfCfaRestoreExtended",
  186. "DwarfCfaUndefined",
  187. "DwarfCfaSameValue",
  188. "DwarfCfaRegister",
  189. "DwarfCfaRememberState",
  190. "DwarfCfaRestoreState",
  191. "DwarfCfaDefCfa",
  192. "DwarfCfaDefCfaRegister",
  193. "DwarfCfaDefCfaOffset",
  194. "DwarfCfaDefCfaExpression",
  195. "DwarfCfaExpression",
  196. "DwarfCfaOffsetExtendedSf",
  197. "DwarfCfaDefCfaSf",
  198. "DwarfCfaDefCfaOffsetSf",
  199. "DwarfCfaValOffset",
  200. "DwarfCfaValOffsetSf",
  201. "DwarfCfaValExpression",
  202. };
  203. PSTR DwarfFrameRuleNames[] = {
  204. "Undefined",
  205. "SameValue",
  206. "CfaOffset",
  207. "CfaOffsetValue",
  208. "Register",
  209. "Expression",
  210. "ExpressionValue",
  211. "Architectural"
  212. };
  213. //
  214. // ------------------------------------------------------------------ Functions
  215. //
  216. INT
  217. DwarfStackUnwind (
  218. PDEBUG_SYMBOLS Symbols,
  219. ULONGLONG DebasedPc,
  220. PSTACK_FRAME Frame
  221. )
  222. /*++
  223. Routine Description:
  224. This routine attempts to unwind the stack by one frame.
  225. Arguments:
  226. Symbols - Supplies a pointer to the debug symbols.
  227. DebasedPc - Supplies the program counter value, assuming the image were
  228. loaded at its preferred base address (that is, actual PC minus loaded
  229. base difference of the module).
  230. Frame - Supplies a pointer where the basic frame information for this
  231. frame will be returned.
  232. Return Value:
  233. 0 on success.
  234. EOF if there are no more stack frames.
  235. Returns an error code on failure.
  236. --*/
  237. {
  238. PDWARF_CONTEXT Context;
  239. INT Status;
  240. Context = Symbols->SymbolContext;
  241. Status = DwarfpStackUnwind(Context, DebasedPc, FALSE, Frame);
  242. if ((Context->Flags & DWARF_CONTEXT_DEBUG_FRAMES) != 0) {
  243. DbgOut("Unwind %d: %I64x %I64x\n",
  244. Status,
  245. Frame->FramePointer,
  246. Frame->ReturnAddress);
  247. }
  248. return Status;
  249. }
  250. INT
  251. DwarfpStackUnwind (
  252. PDWARF_CONTEXT Context,
  253. ULONGLONG DebasedPc,
  254. BOOL CfaOnly,
  255. PSTACK_FRAME Frame
  256. )
  257. /*++
  258. Routine Description:
  259. This routine attempts to unwind the stack by one frame.
  260. Arguments:
  261. Context - Supplies a pointer to the DWARF symbol context.
  262. DebasedPc - Supplies the program counter value, assuming the image were
  263. loaded at its preferred base address (that is, actual PC minus loaded
  264. base difference of the module).
  265. CfaOnly - Supplies a boolean indicating whether to only return the
  266. current Canonical Frame Address and not actually perform any unwinding
  267. (TRUE) or whether to fully unwind this function (FALSE).
  268. Frame - Supplies a pointer where the basic frame information for this
  269. frame will be returned.
  270. Return Value:
  271. 0 on success.
  272. EOF if there are no more stack frames.
  273. Returns an error code on failure.
  274. --*/
  275. {
  276. DWARF_CIE Cie;
  277. DWARF_FDE Fde;
  278. INT Status;
  279. Status = DwarfpFindFrameInfo(Context, DebasedPc, &Cie, &Fde);
  280. if (Status != 0) {
  281. return Status;
  282. }
  283. Status = DwarfpExecuteFde(Context, DebasedPc, &Fde, &Cie, CfaOnly, Frame);
  284. return Status;
  285. }
  286. //
  287. // --------------------------------------------------------- Internal Functions
  288. //
  289. INT
  290. DwarfpExecuteFde (
  291. PDWARF_CONTEXT Context,
  292. ULONGLONG Pc,
  293. PDWARF_FDE Fde,
  294. PDWARF_CIE Cie,
  295. BOOL CfaOnly,
  296. PSTACK_FRAME Frame
  297. )
  298. /*++
  299. Routine Description:
  300. This routine executes the instructions associated with a DWARF FDE to
  301. unwind the stack.
  302. Arguments:
  303. Context - Supplies a pointer to the DWARF context.
  304. Pc - Supplies the (debased) PC value.
  305. Fde - Supplies a pointer to the FDE containing the instructions.
  306. Cie - Supplies a pointer to the CIE.
  307. CfaOnly - Supplies a boolean indicating whether to only return the
  308. current Canonical Frame Address and not actually perform any unwinding
  309. (TRUE) or whether to fully unwind this function (FALSE).
  310. Frame - Supplies a pointer where the basic frame information for this
  311. frame will be returned.
  312. Return Value:
  313. 0 on success.
  314. Returns an error code on failure.
  315. --*/
  316. {
  317. ULONGLONG Cfa;
  318. ULONG DefaultCfaRegister;
  319. ULONG Index;
  320. ULONG NativeSize;
  321. ULONG ReturnRegister;
  322. DWARF_FRAME_STATE State;
  323. INT Status;
  324. ULONGLONG Value;
  325. assert((Pc >= Fde->InitialLocation) &&
  326. (Pc < (Fde->InitialLocation + Fde->Range)));
  327. memset(&State, 0, sizeof(DWARF_FRAME_STATE));
  328. State.Location = Fde->InitialLocation;
  329. NativeSize = DwarfGetNativeSize(Context);
  330. //
  331. // Set the return address register so that it keeps its same value.
  332. //
  333. ReturnRegister = Cie->ReturnAddressRegister;
  334. if (ReturnRegister < DWARF_MAX_REGISTERS) {
  335. State.Rules.Registers[ReturnRegister].Type = DwarfFrameSameValue;
  336. State.MaxRegister = ReturnRegister;
  337. }
  338. //
  339. // Execute the initial instructions to get the rules set up.
  340. //
  341. Status = DwarfpExecuteFrameInstructions(Context,
  342. Pc,
  343. Cie,
  344. Cie->InitialInstructions,
  345. Cie->End,
  346. &State);
  347. if ((Context->Flags & DWARF_CONTEXT_DEBUG_FRAMES) != 0) {
  348. DWARF_PRINT("\n");
  349. }
  350. DefaultCfaRegister = -1;
  351. if (State.Rules.Cfa.Type == DwarfFrameRegister) {
  352. DefaultCfaRegister = State.Rules.Cfa.Operand;
  353. }
  354. if (Status != 0) {
  355. DWARF_ERROR("DWARF: Failed to execute initial CIE instructions.\n");
  356. goto ExecuteFdeEnd;
  357. }
  358. //
  359. // Copy that into the initial state.
  360. //
  361. memcpy(&(State.InitialRules), &(State.Rules), sizeof(DWARF_FRAME_RULE_SET));
  362. //
  363. // Now execute the primary rules of the FDE.
  364. //
  365. Status = DwarfpExecuteFrameInstructions(Context,
  366. Pc,
  367. Cie,
  368. Fde->Instructions,
  369. Fde->End,
  370. &State);
  371. if ((Context->Flags & DWARF_CONTEXT_DEBUG_FRAMES) != 0) {
  372. DWARF_PRINT("\n");
  373. }
  374. if (Status != 0) {
  375. DWARF_ERROR("DWARF: Failed to execute FDE instructions.\n");
  376. goto ExecuteFdeEnd;
  377. }
  378. //
  379. // Get the CFA value.
  380. //
  381. Status = DwarfpGetValueFromRule(Context,
  382. &State,
  383. -1,
  384. NativeSize,
  385. 0,
  386. &Cfa);
  387. if (Status != 0) {
  388. DWARF_ERROR("DWARF: Failed to get CFA location.\n");
  389. goto ExecuteFdeEnd;
  390. }
  391. Frame->FramePointer = Cfa;
  392. Frame->ReturnAddress = 0;
  393. if (CfaOnly != FALSE) {
  394. Status = 0;
  395. goto ExecuteFdeEnd;
  396. }
  397. //
  398. // Now evaluate the rules to get all the new register values.
  399. //
  400. for (Index = 0; Index <= State.MaxRegister; Index += 1) {
  401. if (State.Rules.Registers[Index].Type == DwarfFrameUndefined) {
  402. continue;
  403. }
  404. Status = DwarfpGetValueFromRule(Context,
  405. &State,
  406. Index,
  407. NativeSize,
  408. Cfa,
  409. &Value);
  410. if (Status != 0) {
  411. DWARF_ERROR("DWARF: Failed to get value for register %d.\n", Index);
  412. goto ExecuteFdeEnd;
  413. }
  414. if (Index == ReturnRegister) {
  415. Frame->ReturnAddress = Value;
  416. }
  417. State.NewValue[Index] = Value;
  418. }
  419. //
  420. // Now apply all the new register values. This couldn't be done before
  421. // because the registers may have depended on each other's old contents.
  422. // Apply the return address register to the PC first because it's an
  423. // implicit rule.
  424. //
  425. if (ReturnRegister < DWARF_MAX_REGISTERS) {
  426. if (State.Rules.Registers[ReturnRegister].Type != DwarfFrameUndefined) {
  427. DwarfTargetWritePc(Context, State.NewValue[ReturnRegister]);
  428. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  429. DWARF_PRINT(" PC <- %I64x <- r%d (%s) (ReturnAddress)\n",
  430. State.NewValue[ReturnRegister],
  431. ReturnRegister,
  432. DwarfGetRegisterName(Context, ReturnRegister));
  433. }
  434. } else {
  435. DwarfTargetWritePc(Context, 0);
  436. }
  437. }
  438. for (Index = 0; Index <= State.MaxRegister; Index += 1) {
  439. if (State.Rules.Registers[Index].Type == DwarfFrameUndefined) {
  440. continue;
  441. }
  442. Status = DwarfTargetWriteRegister(Context,
  443. Index,
  444. State.NewValue[Index]);
  445. if (Status != 0) {
  446. DWARF_ERROR("DWARF: Failed to set register %d.\n", Index);
  447. goto ExecuteFdeEnd;
  448. }
  449. }
  450. //
  451. // Restore the CFA register if it wasn't explicitly restored.
  452. //
  453. if (DefaultCfaRegister != (ULONG)-1) {
  454. if (State.Rules.Registers[DefaultCfaRegister].Type ==
  455. DwarfFrameUndefined) {
  456. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  457. DWARF_PRINT(" r%d (%s) <- %I64x <- CFA (implicit)\n",
  458. DefaultCfaRegister,
  459. DwarfGetRegisterName(Context, DefaultCfaRegister),
  460. Cfa);
  461. }
  462. Status = DwarfTargetWriteRegister(Context, DefaultCfaRegister, Cfa);
  463. if (Status != 0) {
  464. DWARF_ERROR("DWARF: Failed to set CFA register %d.\n", Index);
  465. goto ExecuteFdeEnd;
  466. }
  467. }
  468. }
  469. Status = 0;
  470. ExecuteFdeEnd:
  471. return Status;
  472. }
  473. INT
  474. DwarfpExecuteFrameInstructions (
  475. PDWARF_CONTEXT Context,
  476. ULONGLONG Pc,
  477. PDWARF_CIE Cie,
  478. PUCHAR Instructions,
  479. PUCHAR End,
  480. PDWARF_FRAME_STATE State
  481. )
  482. /*++
  483. Routine Description:
  484. This routine executes the instructions associated with a DWARF FDE to
  485. unwind the stack.
  486. Arguments:
  487. Context - Supplies a pointer to the DWARF context.
  488. Pc - Supplies the (debased) PC value. Execution will stop if the location
  489. is ever advanced beyond this value.
  490. Cie - Supplies a pointer to the CIE associated with this value.
  491. Instructions - Supplies a pointer to the instructions to execute.
  492. End - Supplies a pointer just beyond the end of the last instruction to
  493. execute.
  494. State - Supplies a pointer where the rule state will be acted upon.
  495. Return Value:
  496. 0 on success.
  497. Returns an error code on failure.
  498. --*/
  499. {
  500. DWARF_CALL_FRAME_ENCODING Instruction;
  501. ULONGLONG Operand;
  502. ULONGLONG Operand2;
  503. BOOL Print;
  504. ULONG Register;
  505. DWARF_FRAME_RULE_TYPE RuleType;
  506. PDWARF_FRAME_STACK StackEntry;
  507. INT Status;
  508. Print = FALSE;
  509. if ((Context->Flags & DWARF_CONTEXT_DEBUG_FRAMES) != 0) {
  510. Print = TRUE;
  511. }
  512. while (Instructions < End) {
  513. Instruction = DwarfpRead1(&Instructions);
  514. if ((Instruction & DwarfCfaHighMask) != 0) {
  515. Operand = (UCHAR)(Instruction & (~DwarfCfaHighMask));
  516. switch (Instruction & DwarfCfaHighMask) {
  517. //
  518. // Advance the location by the lower 6 bits encoded in the
  519. // instruction.
  520. //
  521. case DwarfCfaAdvanceLoc:
  522. Operand *= Cie->CodeAlignmentFactor;
  523. State->Location += Operand;
  524. if (Print != FALSE) {
  525. DWARF_PRINT(" DwarfCfaAdvanceLoc: %I64d to %I64x",
  526. Operand,
  527. State->Location);
  528. }
  529. if (State->Location > Pc) {
  530. Status = 0;
  531. goto ExecuteFrameInstructionsEnd;
  532. }
  533. break;
  534. //
  535. // Set the rule for the register encoded in the low 6 bits of the
  536. // instruction to Offset(N), where N is LEB128 operand.
  537. //
  538. case DwarfCfaOffset:
  539. Operand2 = DwarfpReadLeb128(&Instructions) *
  540. Cie->DataAlignmentFactor;
  541. if (Print != FALSE) {
  542. DWARF_PRINT(" DwarfCfaOffset: %I64d %I64d",
  543. Operand,
  544. Operand2);
  545. }
  546. DwarfpSetFrameRule(Context,
  547. State,
  548. Operand,
  549. DwarfFrameCfaOffset,
  550. Operand2,
  551. 0);
  552. break;
  553. //
  554. // Chang the rule for the register encoded in the low 6 bits of the
  555. // instruction back to its initial rule from the CIE.
  556. //
  557. case DwarfCfaRestore:
  558. if (Print != FALSE) {
  559. DWARF_PRINT(" DwarfCfaRestore: %I64d", Operand);
  560. }
  561. DwarfpSetFrameRule(
  562. Context,
  563. State,
  564. Operand,
  565. State->InitialRules.Registers[Operand].Type,
  566. State->InitialRules.Registers[Operand].Operand,
  567. State->InitialRules.Registers[Operand].Operand2);
  568. break;
  569. default:
  570. assert(FALSE);
  571. break;
  572. }
  573. } else {
  574. if (Print != FALSE) {
  575. if ((Instruction >= DwarfCfaLowUser) &&
  576. (Instruction <= DwarfCfaHighUser)) {
  577. DWARF_PRINT(" DwarfCfaUser%x", Instruction);
  578. } else if (Instruction <= DwarfCfaValExpression) {
  579. DWARF_PRINT(" %s", DwarfCfaEncodingNames[Instruction]);
  580. } else {
  581. DWARF_PRINT(" DwarfCfaUNKNOWN%x", Instruction);
  582. }
  583. }
  584. switch (Instruction) {
  585. case DwarfCfaNop:
  586. break;
  587. //
  588. // The advance instructions move the current address by a given
  589. // amount.
  590. //
  591. case DwarfCfaSetLoc:
  592. if (Cie->AddressSize == 8) {
  593. Operand = DwarfpRead8(&Instructions);
  594. } else {
  595. assert(Cie->AddressSize == 4);
  596. Operand = DwarfpRead4(&Instructions);
  597. }
  598. State->Location = Operand;
  599. if (Print != FALSE) {
  600. DWARF_PRINT(": to %I64x", Operand);
  601. }
  602. if (State->Location > Pc) {
  603. Status = 0;
  604. goto ExecuteFrameInstructionsEnd;
  605. }
  606. break;
  607. case DwarfCfaAdvanceLoc1:
  608. case DwarfCfaAdvanceLoc2:
  609. case DwarfCfaAdvanceLoc4:
  610. switch (Instruction) {
  611. case DwarfCfaAdvanceLoc1:
  612. Operand = DwarfpRead1(&Instructions);
  613. break;
  614. case DwarfCfaAdvanceLoc2:
  615. Operand = DwarfpRead2(&Instructions);
  616. break;
  617. case DwarfCfaAdvanceLoc4:
  618. Operand = DwarfpRead4(&Instructions);
  619. break;
  620. default:
  621. assert(FALSE);
  622. Operand = 0;
  623. break;
  624. }
  625. State->Location += Operand * Cie->CodeAlignmentFactor;
  626. if (Print != FALSE) {
  627. DWARF_PRINT(": %I64d to %I64x",
  628. Operand,
  629. State->Location);
  630. }
  631. if (State->Location > Pc) {
  632. Status = 0;
  633. goto ExecuteFrameInstructionsEnd;
  634. }
  635. break;
  636. //
  637. // The extended offset instruction sets a register to the offset(N)
  638. // rule.
  639. //
  640. case DwarfCfaOffsetExtended:
  641. case DwarfCfaOffsetExtendedSf:
  642. Operand = DwarfpReadLeb128(&Instructions);
  643. if (Instruction == DwarfCfaOffsetExtendedSf) {
  644. Operand2 = DwarfpReadSleb128(&Instructions) *
  645. Cie->DataAlignmentFactor;
  646. } else {
  647. Operand2 = DwarfpReadLeb128(&Instructions) *
  648. Cie->DataAlignmentFactor;
  649. }
  650. if (Print != FALSE) {
  651. DWARF_PRINT(": %I64d to %I64x", Operand2, State->Location);
  652. }
  653. DwarfpSetFrameRule(Context,
  654. State,
  655. Operand,
  656. DwarfFrameCfaOffset,
  657. Operand2,
  658. 0);
  659. break;
  660. //
  661. // The restore extended instruction takes a register operand and
  662. // restores the current rule to the initial rule.
  663. //
  664. case DwarfCfaRestoreExtended:
  665. Operand = DwarfpReadLeb128(&Instructions);
  666. if (Print != FALSE) {
  667. DWARF_PRINT(": %I64d", Operand);
  668. }
  669. DwarfpSetFrameRule(
  670. Context,
  671. State,
  672. Operand,
  673. State->InitialRules.Registers[Operand].Type,
  674. State->InitialRules.Registers[Operand].Operand,
  675. State->InitialRules.Registers[Operand].Operand2);
  676. break;
  677. //
  678. // Set the rule to undefined.
  679. //
  680. case DwarfCfaUndefined:
  681. Operand = DwarfpReadLeb128(&Instructions);
  682. DwarfpSetFrameRule(Context,
  683. State,
  684. Operand,
  685. DwarfFrameUndefined,
  686. 0,
  687. 0);
  688. break;
  689. //
  690. // Set the given register operand to the same value rule.
  691. //
  692. case DwarfCfaSameValue:
  693. Operand = DwarfpReadLeb128(&Instructions);
  694. DwarfpSetFrameRule(Context,
  695. State,
  696. Operand,
  697. DwarfFrameSameValue,
  698. 0,
  699. 0);
  700. break;
  701. //
  702. // Set the register specified in the first operand to the rule
  703. // register(R), where R is the second operand.
  704. //
  705. case DwarfCfaRegister:
  706. Operand = DwarfpReadLeb128(&Instructions);
  707. Operand2 = DwarfpReadLeb128(&Instructions);
  708. DwarfpSetFrameRule(Context,
  709. State,
  710. Operand,
  711. DwarfFrameRegister,
  712. Operand2,
  713. 0);
  714. break;
  715. //
  716. // Save the current frame state for all registers, and push it on
  717. // a stack.
  718. //
  719. case DwarfCfaRememberState:
  720. if (State->RememberStackSize >= DWARF_MAX_REMEMBER_STACK) {
  721. DWARF_ERROR("DWARF: Frame remember stack size too big.\n");
  722. Status = ERANGE;
  723. goto ExecuteFrameInstructionsEnd;
  724. }
  725. StackEntry = malloc(sizeof(DWARF_FRAME_STACK));
  726. if (StackEntry == NULL) {
  727. Status = ENOMEM;
  728. goto ExecuteFrameInstructionsEnd;
  729. }
  730. memcpy(&(StackEntry->RuleSet),
  731. &(State->Rules),
  732. sizeof(DWARF_FRAME_RULE_SET));
  733. StackEntry->Next = State->RememberStack;
  734. State->RememberStack = StackEntry;
  735. State->RememberStackSize += 1;
  736. break;
  737. //
  738. // Pop the previously pushed register state and save it as the
  739. // current row.
  740. //
  741. case DwarfCfaRestoreState:
  742. if (State->RememberStackSize == 0) {
  743. DWARF_ERROR("DWARF: Popped empty remember stack.\n");
  744. Status = ERANGE;
  745. goto ExecuteFrameInstructionsEnd;
  746. }
  747. StackEntry = State->RememberStack;
  748. State->RememberStack = StackEntry->Next;
  749. State->RememberStackSize -= 1;
  750. memcpy(&(State->Rules),
  751. &(StackEntry->RuleSet),
  752. sizeof(DWARF_FRAME_RULE_SET));
  753. free(StackEntry);
  754. break;
  755. //
  756. // Set the CFA rule to be the given register (operand 1) plus the
  757. // given offset (operand2). The CFA register rule changes the
  758. // register but keeps the offset as it is. The CFA offset rule
  759. // changes the offset but leaves the regsister where it is.
  760. //
  761. case DwarfCfaDefCfa:
  762. case DwarfCfaDefCfaSf:
  763. case DwarfCfaDefCfaRegister:
  764. case DwarfCfaDefCfaOffset:
  765. case DwarfCfaDefCfaOffsetSf:
  766. //
  767. // Get the register, which is either the old value or the
  768. // operand.
  769. //
  770. if ((Instruction == DwarfCfaDefCfaOffset) ||
  771. (Instruction == DwarfCfaDefCfaOffsetSf)) {
  772. Operand = State->Rules.Cfa.Operand;
  773. } else {
  774. Operand = DwarfpReadLeb128(&Instructions);
  775. }
  776. //
  777. // Get the offset, which is either a signed and factored offset,
  778. // the original value, or an unsigned offset.
  779. //
  780. if ((Instruction == DwarfCfaDefCfaSf) ||
  781. (Instruction == DwarfCfaDefCfaOffsetSf)) {
  782. Operand2 = DwarfpReadSleb128(&Instructions) *
  783. Cie->DataAlignmentFactor;
  784. } else if (Instruction == DwarfCfaDefCfaRegister) {
  785. Operand2 = State->Rules.Cfa.Operand2;
  786. } else {
  787. Operand2 = DwarfpReadLeb128(&Instructions);
  788. }
  789. if (Print != FALSE) {
  790. DWARF_PRINT(": %I64d %I64d", Operand, Operand2);
  791. }
  792. DwarfpSetFrameRule(Context,
  793. State,
  794. -1,
  795. DwarfFrameRegister,
  796. Operand,
  797. Operand2);
  798. break;
  799. //
  800. // The CFA or register rule is determined by evaluating the given
  801. // DWARF expression. This is in the form "exprloc", which is a
  802. // leb128 length, followed by the expression bytes.
  803. //
  804. case DwarfCfaDefCfaExpression:
  805. case DwarfCfaExpression:
  806. case DwarfCfaValExpression:
  807. if (Instruction == DwarfCfaDefCfaExpression) {
  808. Register = -1;
  809. } else {
  810. Register = DwarfpReadLeb128(&Instructions);
  811. }
  812. Operand = DwarfpReadLeb128(&Instructions);
  813. Operand2 = (UINTN)(Instructions);
  814. Instructions += Operand;
  815. if (Print != FALSE) {
  816. DWARF_PRINT(": %d: {", Register);
  817. DwarfpPrintExpression(Context,
  818. Cie->AddressSize,
  819. NULL,
  820. (PUCHAR)(UINTN)Operand2,
  821. Operand);
  822. DWARF_PRINT("}");
  823. }
  824. RuleType = DwarfFrameExpressionValue;
  825. if (Instruction == DwarfCfaExpression) {
  826. RuleType = DwarfFrameExpression;
  827. }
  828. DwarfpSetFrameRule(Context,
  829. State,
  830. Register,
  831. RuleType,
  832. Operand,
  833. Operand2);
  834. break;
  835. //
  836. // Set the register rule to the value offset rule.
  837. //
  838. case DwarfCfaValOffset:
  839. case DwarfCfaValOffsetSf:
  840. Operand = DwarfpReadLeb128(&Instructions);
  841. if (Instruction == DwarfCfaValOffsetSf) {
  842. Operand2 = DwarfpReadSleb128(&Instructions) *
  843. Cie->DataAlignmentFactor;
  844. } else {
  845. Operand2 = DwarfpReadLeb128(&Instructions) *
  846. Cie->DataAlignmentFactor;
  847. }
  848. if (Print != FALSE) {
  849. DWARF_PRINT(": %I64d %I64d", Operand, Operand2);
  850. }
  851. DwarfpSetFrameRule(Context,
  852. State,
  853. Operand,
  854. DwarfFrameCfaOffsetValue,
  855. Operand2,
  856. 0);
  857. break;
  858. default:
  859. Status = EINVAL;
  860. goto ExecuteFrameInstructionsEnd;
  861. }
  862. }
  863. if (Print != FALSE) {
  864. DWARF_PRINT("\n");
  865. }
  866. }
  867. Status = 0;
  868. ExecuteFrameInstructionsEnd:
  869. //
  870. // Clear any old remember stack entries.
  871. //
  872. while (State->RememberStackSize != 0) {
  873. StackEntry = State->RememberStack;
  874. State->RememberStack = StackEntry->Next;
  875. State->RememberStackSize -= 1;
  876. free(StackEntry);
  877. }
  878. assert(State->RememberStack == NULL);
  879. return Status;
  880. }
  881. VOID
  882. DwarfpSetFrameRule (
  883. PDWARF_CONTEXT Context,
  884. PDWARF_FRAME_STATE State,
  885. ULONG Register,
  886. DWARF_FRAME_RULE_TYPE RuleType,
  887. ULONGLONG Operand,
  888. ULONGLONG Operand2
  889. )
  890. /*++
  891. Routine Description:
  892. This routine sets the rule for a given register.
  893. Arguments:
  894. Context - Supplies a pointer to the DWARF context.
  895. Register - Supplies the register to set the rule for. Supply -1 to set the
  896. CFA rule.
  897. State - Supplies a pointer to the frame state machine state.
  898. RuleType - Supplies the form of the rule.
  899. Operand - Supplies the rule operand.
  900. Operand2 - Supplies the second operand.
  901. Return Value:
  902. None.
  903. --*/
  904. {
  905. PDWARF_FRAME_RULE Rule;
  906. if (Register == (ULONG)-1) {
  907. Rule = &(State->Rules.Cfa);
  908. } else if (Register < DWARF_MAX_REGISTERS) {
  909. Rule = &(State->Rules.Registers[Register]);
  910. if (State->MaxRegister < Register) {
  911. State->MaxRegister = Register;
  912. }
  913. } else {
  914. DWARF_ERROR("DWARF: Register %d too big.\n", Register);
  915. return;
  916. }
  917. Rule->Type = RuleType;
  918. Rule->Operand = Operand;
  919. Rule->Operand2 = Operand2;
  920. if ((Context->Flags & DWARF_CONTEXT_DEBUG_FRAMES) != 0) {
  921. DWARF_PRINT("\n Rule: ");
  922. if (Register == (ULONG)-1) {
  923. DWARF_PRINT("CFA");
  924. } else {
  925. DWARF_PRINT("r%d (%s)",
  926. Register,
  927. DwarfGetRegisterName(Context, Register));
  928. }
  929. DWARF_PRINT(" %s: %I64x", DwarfFrameRuleNames[RuleType], Operand);
  930. if (Operand2 != 0) {
  931. DWARF_PRINT(" %I64x", Operand2);
  932. }
  933. }
  934. return;
  935. }
  936. INT
  937. DwarfpGetValueFromRule (
  938. PDWARF_CONTEXT Context,
  939. PDWARF_FRAME_STATE State,
  940. ULONG Register,
  941. ULONG AddressSize,
  942. ULONGLONG Cfa,
  943. PULONGLONG UnwoundValue
  944. )
  945. /*++
  946. Routine Description:
  947. This routine determines the final value by applying a given register rule.
  948. Arguments:
  949. Context - Supplies a pointer to the DWARF context.
  950. State - Supplies a pointer to the completed frame state.
  951. Register - Supplies the register to unwind. Supply -1 to get the CFA.
  952. AddressSize - Supplies the size of an address/register on the target.
  953. Cfa - Supplies the canonical frame address value.
  954. UnwoundValue - Supplies a pointer where the value will be returned on
  955. success.
  956. Return Value:
  957. Returns the value of the register by applying the rule.
  958. --*/
  959. {
  960. ULONGLONG InitialPush;
  961. DWARF_LOCATION Location;
  962. PSTR RegisterName;
  963. PDWARF_FRAME_RULE Rule;
  964. INT Status;
  965. ULONGLONG Value;
  966. Status = 0;
  967. if (Register == (ULONG)-1) {
  968. Rule = &(State->Rules.Cfa);
  969. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  970. DWARF_PRINT(" CFA <- ");
  971. }
  972. } else if (Register < DWARF_MAX_REGISTERS) {
  973. Rule = &(State->Rules.Registers[Register]);
  974. RegisterName = DwarfGetRegisterName(Context, Register);
  975. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  976. DWARF_PRINT(" r%d (%s) <- ", Register, RegisterName);
  977. }
  978. } else {
  979. DWARF_ERROR("DWARF: Register %d too big.\n", Register);
  980. return ERANGE;
  981. }
  982. switch (Rule->Type) {
  983. case DwarfFrameCfaOffset:
  984. assert(Register != (ULONG)-1);
  985. Value = 0;
  986. Status = DwarfTargetRead(Context,
  987. Cfa + Rule->Operand,
  988. DwarfGetNativeSize(Context),
  989. 0,
  990. &Value);
  991. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  992. DWARF_PRINT("%I64x <- [CFA%+I64d]\n", Value, Rule->Operand);
  993. }
  994. break;
  995. case DwarfFrameCfaOffsetValue:
  996. assert(Register != (ULONG)-1);
  997. Value = Cfa + Rule->Operand;
  998. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  999. DWARF_PRINT("%I64x <- [CFA%+I64d]\n", Value, Rule->Operand);
  1000. }
  1001. break;
  1002. case DwarfFrameRegister:
  1003. Value = 0;
  1004. Status = DwarfTargetReadRegister(Context, Rule->Operand, &Value);
  1005. Value += Rule->Operand2;
  1006. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  1007. DWARF_PRINT("%I64x <- r%d (%s) + %I64d\n",
  1008. Value,
  1009. (ULONG)(Rule->Operand),
  1010. DwarfGetRegisterName(Context, Rule->Operand),
  1011. Rule->Operand2);
  1012. }
  1013. break;
  1014. case DwarfFrameExpression:
  1015. case DwarfFrameExpressionValue:
  1016. Value = 0;
  1017. //
  1018. // Evaluate the expression, pushing the CFA address on initially unless
  1019. // this is the CFA rule.
  1020. //
  1021. InitialPush = -1ULL;
  1022. if (Register != (ULONG)-1) {
  1023. InitialPush = Cfa;
  1024. }
  1025. Status = DwarfpEvaluateSimpleExpression(Context,
  1026. AddressSize,
  1027. NULL,
  1028. InitialPush,
  1029. (PUCHAR)(UINTN)(Rule->Operand2),
  1030. Rule->Operand,
  1031. &Location);
  1032. if (Status != 0) {
  1033. DWARF_ERROR("DWARF: Failed to evaluate FDE expression.\n");
  1034. break;
  1035. }
  1036. //
  1037. // Only memory forms are expected.
  1038. //
  1039. if (Location.Form != DwarfLocationMemory) {
  1040. DWARF_ERROR("DWARF: Error: Got simple expression location %d.\n",
  1041. Location.Form);
  1042. Status = EINVAL;
  1043. break;
  1044. }
  1045. //
  1046. // For expression rules, read the value at the address to get the final
  1047. // unwind value.
  1048. //
  1049. if (Rule->Type == DwarfFrameExpression) {
  1050. Status = DwarfTargetRead(Context,
  1051. Location.Value.Address,
  1052. DwarfGetNativeSize(Context),
  1053. 0,
  1054. &Value);
  1055. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  1056. DWARF_PRINT("%I64x <- [%I64x]\n",
  1057. Value,
  1058. Location.Value.Address);
  1059. }
  1060. //
  1061. // For expression value rules, the output of the expression is the
  1062. // unwound value itself.
  1063. //
  1064. } else {
  1065. Value = Location.Value.Address;
  1066. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  1067. DWARF_PRINT("%I64x\n", Value);
  1068. }
  1069. Status = 0;
  1070. }
  1071. break;
  1072. case DwarfFrameUndefined:
  1073. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  1074. DWARF_PRINT("Undefined\n");
  1075. }
  1076. Value = 0;
  1077. break;
  1078. case DwarfFrameSameValue:
  1079. assert(Register != (ULONG)-1);
  1080. Value = 0;
  1081. Status = DwarfTargetReadRegister(Context, Register, &Value);
  1082. if ((Context->Flags & DWARF_CONTEXT_VERBOSE_UNWINDING) != 0) {
  1083. DWARF_PRINT("%I64x (same)\n", Value);
  1084. }
  1085. break;
  1086. default:
  1087. assert(FALSE);
  1088. Value = 0;
  1089. break;
  1090. }
  1091. *UnwoundValue = Value;
  1092. return Status;
  1093. }
  1094. INT
  1095. DwarfpFindFrameInfo (
  1096. PDWARF_CONTEXT Context,
  1097. ULONGLONG Pc,
  1098. PDWARF_CIE Cie,
  1099. PDWARF_FDE Fde
  1100. )
  1101. /*++
  1102. Routine Description:
  1103. This routine scans through the .debug_frame or .eh_frame sections to find
  1104. the unwind information for the given PC.
  1105. Arguments:
  1106. Context - Supplies a pointer to the DWARF context.
  1107. Pc - Supplies the (debased) PC value to match against.
  1108. Cie - Supplies a pointer where the relevant CIE will be returned.
  1109. Fde - Supplies a pointer where the relevant FDE will be returned.
  1110. Return Value:
  1111. 0 on success.
  1112. ENOENT if no frame information could be found.
  1113. Returns an error number on failure.
  1114. --*/
  1115. {
  1116. BOOL EhFrame;
  1117. PUCHAR End;
  1118. BOOL IsCie;
  1119. INT Status;
  1120. PUCHAR Table;
  1121. //
  1122. // Get the .debug_frame or .eh_frame sections.
  1123. //
  1124. if (Context->Sections.Frame.Size != 0) {
  1125. Table = Context->Sections.Frame.Data;
  1126. End = Table + Context->Sections.Frame.Size;
  1127. EhFrame = FALSE;
  1128. } else if (Context->Sections.EhFrame.Size != 0) {
  1129. Table = Context->Sections.EhFrame.Data;
  1130. End = Table + Context->Sections.EhFrame.Size;
  1131. EhFrame = TRUE;
  1132. } else {
  1133. Status = ENOENT;
  1134. goto FindFrameInfoEnd;
  1135. }
  1136. memset(Cie, 0, sizeof(DWARF_CIE));
  1137. memset(Fde, 0, sizeof(DWARF_FDE));
  1138. //
  1139. // Loop through the table until the FDE is found that matches the given PC.
  1140. //
  1141. while (Table < End) {
  1142. Status = DwarfpReadCieOrFde(Context,
  1143. EhFrame,
  1144. &Table,
  1145. End,
  1146. Cie,
  1147. Fde,
  1148. &IsCie);
  1149. if (Status != 0) {
  1150. if (Status == EAGAIN) {
  1151. continue;
  1152. }
  1153. goto FindFrameInfoEnd;
  1154. }
  1155. if (IsCie != FALSE) {
  1156. continue;
  1157. }
  1158. if ((Pc >= Fde->InitialLocation) &&
  1159. (Pc < (Fde->InitialLocation + Fde->Range))) {
  1160. Status = 0;
  1161. goto FindFrameInfoEnd;
  1162. }
  1163. }
  1164. //
  1165. // All the FDEs were read and none of them matched.
  1166. //
  1167. Status = ENOENT;
  1168. FindFrameInfoEnd:
  1169. return Status;
  1170. }
  1171. INT
  1172. DwarfpReadCieOrFde (
  1173. PDWARF_CONTEXT Context,
  1174. BOOL EhFrame,
  1175. PUCHAR *Table,
  1176. PUCHAR End,
  1177. PDWARF_CIE Cie,
  1178. PDWARF_FDE Fde,
  1179. PBOOL IsCie
  1180. )
  1181. /*++
  1182. Routine Description:
  1183. This routine reads either a CIE or an FDE.
  1184. Arguments:
  1185. Context - Supplies a pointer to the DWARF context.
  1186. EhFrame - Supplies a boolean indicating whether this is an EH frame section
  1187. or a .debug_frame section.
  1188. Table - Supplies a pointer that on input contains a pointer to the start of
  1189. the section. On output this pointer will be advanced past the fields
  1190. scanned.
  1191. End - Supplies a pointer to the end of the section.
  1192. Cie - Supplies a pointer where the CIE will be returned. If an FDE is being
  1193. parsed, then this CIE should be its owning CIE.
  1194. Fde - Supplies a pointer where the FDE will be returned.
  1195. IsCie - Supplies a pointer where a boolean will be returned indicating if a
  1196. CIE was parsed (TRUE) or an FDE (FALSE).
  1197. Return Value:
  1198. 0 on success.
  1199. EAGAIN if a zero terminator was found.
  1200. Returns an error number on failure.
  1201. --*/
  1202. {
  1203. PSTR Augmentation;
  1204. LONGLONG CieId;
  1205. BOOL CieIsCie;
  1206. PUCHAR CieStart;
  1207. DWARF_ADDRESS_ENCODING Encoding;
  1208. BOOL Is64Bit;
  1209. PUCHAR Start;
  1210. INT Status;
  1211. PUCHAR UnitEnd;
  1212. ULONGLONG UnitLength;
  1213. Start = *Table;
  1214. DwarfpReadInitialLength(Table, &Is64Bit, &UnitLength);
  1215. if (UnitLength == 0) {
  1216. return EAGAIN;
  1217. }
  1218. UnitEnd = *Table + UnitLength;
  1219. if (UnitEnd > End) {
  1220. return ERANGE;
  1221. }
  1222. CieStart = *Table;
  1223. if (Is64Bit != FALSE) {
  1224. CieId = (LONGLONG)DwarfpRead8(Table);
  1225. } else {
  1226. CieId = (LONG)DwarfpRead4(Table);
  1227. }
  1228. //
  1229. // If the CIE ID is zero or -1, this is a CIE.
  1230. //
  1231. if (((EhFrame != FALSE) && (CieId == 0)) ||
  1232. ((EhFrame == FALSE) && (CieId == -1))) {
  1233. *IsCie = TRUE;
  1234. memset(Cie, 0, sizeof(DWARF_CIE));
  1235. Cie->EhFrame = EhFrame;
  1236. Cie->Is64Bit = Is64Bit;
  1237. Cie->Start = Start;
  1238. Cie->End = UnitEnd;
  1239. Cie->UnitLength = UnitLength;
  1240. Cie->Version = DwarfpRead1(Table);
  1241. Augmentation = (PSTR)(*Table);
  1242. Cie->Augmentation = Augmentation;
  1243. *Table = (PUCHAR)Augmentation + strlen(Augmentation) + 1;
  1244. Cie->AddressSize = 4;
  1245. if (Is64Bit != FALSE) {
  1246. Cie->AddressSize = 8;
  1247. }
  1248. if (EhFrame == FALSE) {
  1249. if (Cie->Version == 4) {
  1250. Cie->AddressSize = DwarfpRead1(Table);
  1251. Cie->SegmentSize = DwarfpRead1(Table);
  1252. }
  1253. }
  1254. Cie->CodeAlignmentFactor = DwarfpReadLeb128(Table);
  1255. Cie->DataAlignmentFactor = DwarfpReadSleb128(Table);
  1256. Cie->ReturnAddressRegister = DwarfpReadLeb128(Table);
  1257. Cie->InitialInstructions = *Table;
  1258. //
  1259. // Read the augmentation format to get the rest of the fields.
  1260. //
  1261. if (*Augmentation == 'z') {
  1262. Augmentation += 1;
  1263. Cie->AugmentationLength = DwarfpReadLeb128(Table);
  1264. Cie->InitialInstructions = *Table + Cie->AugmentationLength;
  1265. while (*Augmentation != '\0') {
  1266. switch (*Augmentation) {
  1267. //
  1268. // L specifies the language specific data area encoding.
  1269. //
  1270. case 'L':
  1271. Cie->LanguageEncoding = DwarfpRead1(Table);
  1272. break;
  1273. //
  1274. // P contains two arguments: the first byte is an encoding of
  1275. // the second argument, which is the address of a personality
  1276. // routine handler.
  1277. //
  1278. case 'P':
  1279. Encoding = DwarfpRead1(Table);
  1280. DwarfpReadEncodedAddress(Context,
  1281. Encoding,
  1282. Cie->AddressSize,
  1283. Table);
  1284. break;
  1285. //
  1286. // S indicates this CIE unwinds a signal handler.
  1287. //
  1288. case 'S':
  1289. break;
  1290. //
  1291. // R contains an argument which is the address encoding of
  1292. // FDE addresses.
  1293. //
  1294. case 'R':
  1295. Cie->FdeEncoding = DwarfpRead1(Table);
  1296. break;
  1297. default:
  1298. DWARF_ERROR("DWARF: Unrecognized augmentation %c in "
  1299. "string %s.\n",
  1300. *Augmentation,
  1301. Cie->Augmentation);
  1302. Status = EINVAL;
  1303. goto ReadCieOrFdeEnd;
  1304. }
  1305. Augmentation += 1;
  1306. }
  1307. }
  1308. //
  1309. // Otherwise, this is an FDE.
  1310. //
  1311. } else {
  1312. *IsCie = FALSE;
  1313. memset(Fde, 0, sizeof(DWARF_FDE));
  1314. Fde->Length = UnitLength;
  1315. Fde->CiePointer = CieId;
  1316. Fde->Start = Start;
  1317. Fde->End = UnitEnd;
  1318. //
  1319. // The FDE points at its owning CIE. If that is not the mostly
  1320. // recently read one (as it almost always is), then go read the CIE.
  1321. //
  1322. if (EhFrame != FALSE) {
  1323. CieStart -= CieId;
  1324. } else {
  1325. CieStart = Context->Sections.Frame.Data + (ULONGLONG)CieId;
  1326. }
  1327. if (CieStart != Cie->Start) {
  1328. Status = DwarfpReadCieOrFde(Context,
  1329. EhFrame,
  1330. &CieStart,
  1331. End,
  1332. Cie,
  1333. Fde,
  1334. &CieIsCie);
  1335. if (Status != 0) {
  1336. DWARF_ERROR("DWARF: Could not read alternate CIE.\n");
  1337. goto ReadCieOrFdeEnd;
  1338. }
  1339. assert(CieIsCie != FALSE);
  1340. }
  1341. Fde->InitialLocation = DwarfpReadEncodedAddress(Context,
  1342. Cie->FdeEncoding,
  1343. Cie->AddressSize,
  1344. Table);
  1345. Fde->Range = DwarfpReadEncodedAddress(
  1346. Context,
  1347. Cie->FdeEncoding & DwarfPeTypeMask,
  1348. Cie->AddressSize,
  1349. Table);
  1350. Fde->Instructions = *Table;
  1351. if (Cie->Augmentation[0] == 'z') {
  1352. Fde->AugmentationLength = DwarfpReadLeb128(Table);
  1353. Fde->Instructions = *Table + Fde->AugmentationLength;
  1354. }
  1355. }
  1356. Status = 0;
  1357. ReadCieOrFdeEnd:
  1358. *Table = UnitEnd;
  1359. return Status;
  1360. }
  1361. ULONGLONG
  1362. DwarfpReadEncodedAddress (
  1363. PDWARF_CONTEXT Context,
  1364. DWARF_ADDRESS_ENCODING Encoding,
  1365. UCHAR AddressSize,
  1366. PUCHAR *Table
  1367. )
  1368. /*++
  1369. Routine Description:
  1370. This routine reads an encoded target address.
  1371. Arguments:
  1372. Context - Supplies a pointer to the DWARF context.
  1373. Encoding - Supplies the address encoding format.
  1374. AddressSize - Supplies the size of a target address.
  1375. Table - Supplies a pointer that on input contains a pointer to the start of
  1376. the section. On output this pointer will be advanced past the fields
  1377. scanned.
  1378. Return Value:
  1379. 0 on success.
  1380. Returns an error number on failure.
  1381. --*/
  1382. {
  1383. ULONGLONG Value;
  1384. if (Encoding == DwarfPeOmit) {
  1385. return 0;
  1386. }
  1387. Value = 0;
  1388. switch (Encoding & DwarfPeModifierMask) {
  1389. case DwarfPeAbsolute:
  1390. break;
  1391. //
  1392. // PC-relative is relative to the current table pointer. It's not actually
  1393. // loaded at it's true VA, so get the offset into the .eh_frame section
  1394. // and then add the .eh_frame VA. The .debug_frame sections do not have
  1395. // pointer encodings, so it only applies to .eh_frame.
  1396. //
  1397. case DwarfPePcRelative:
  1398. Value = *Table - (PUCHAR)(Context->Sections.EhFrame.Data) +
  1399. Context->Sections.EhFrameAddress;
  1400. break;
  1401. //
  1402. // Consider supporting other modifiers as needed.
  1403. //
  1404. default:
  1405. assert(FALSE);
  1406. break;
  1407. }
  1408. switch (Encoding & DwarfPeTypeMask) {
  1409. case DwarfPeAbsolute:
  1410. if (AddressSize == 8) {
  1411. Value += DwarfpRead8(Table);
  1412. } else {
  1413. assert(AddressSize == 4);
  1414. Value += DwarfpRead4(Table);
  1415. }
  1416. break;
  1417. case DwarfPeLeb128:
  1418. Value += DwarfpReadLeb128(Table);
  1419. break;
  1420. case DwarfPeUdata2:
  1421. Value += DwarfpRead2(Table);
  1422. break;
  1423. case DwarfPeUdata4:
  1424. Value += DwarfpRead4(Table);
  1425. break;
  1426. case DwarfPeUdata8:
  1427. Value += DwarfpRead8(Table);
  1428. break;
  1429. case DwarfPeSigned:
  1430. if (AddressSize == 8) {
  1431. Value += (LONGLONG)DwarfpRead8(Table);
  1432. } else {
  1433. assert(AddressSize == 4);
  1434. Value += (LONG)DwarfpRead4(Table);
  1435. }
  1436. break;
  1437. case DwarfPeSleb128:
  1438. Value += DwarfpReadSleb128(Table);
  1439. break;
  1440. case DwarfPeSdata2:
  1441. Value += (SHORT)DwarfpRead2(Table);
  1442. break;
  1443. case DwarfPeSdata4:
  1444. Value += (LONG)DwarfpRead4(Table);
  1445. break;
  1446. case DwarfPeSdata8:
  1447. Value += (LONGLONG)DwarfpRead8(Table);
  1448. break;
  1449. default:
  1450. assert(FALSE);
  1451. Value = 0;
  1452. break;
  1453. }
  1454. //
  1455. // This would be where a dereference occurs.
  1456. //
  1457. if ((Encoding & DwarfPeIndirect) != 0) {
  1458. Value = 0;
  1459. }
  1460. return Value;
  1461. }