dwframe.c 47 KB

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