1
0

dwread.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200
  1. /*++
  2. Copyright (c) 2015 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. dwread.c
  5. Abstract:
  6. This module implements support for reading DWARF structures.
  7. Author:
  8. Evan Green 4-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. // --------------------------------------------------------------------- Macros
  26. //
  27. //
  28. // ---------------------------------------------------------------- Definitions
  29. //
  30. //
  31. // ------------------------------------------------------ Data Type Definitions
  32. //
  33. //
  34. // ----------------------------------------------- Internal Function Prototypes
  35. //
  36. INT
  37. DwarfpIndexAbbreviations (
  38. PDWARF_CONTEXT Context,
  39. ULONGLONG Offset,
  40. PUCHAR **AbbreviationsIndex,
  41. PUINTN IndexSize,
  42. PUINTN MaxAttributes
  43. );
  44. INT
  45. DwarfpReadDie (
  46. PDWARF_CONTEXT Context,
  47. PDWARF_COMPILATION_UNIT Unit,
  48. PUCHAR *Data,
  49. PUCHAR Abbreviation,
  50. PDWARF_DIE Die
  51. );
  52. INT
  53. DwarfpReadFormValue (
  54. PDWARF_CONTEXT Context,
  55. PDWARF_COMPILATION_UNIT Unit,
  56. PUCHAR *Data,
  57. PDWARF_ATTRIBUTE_VALUE Attribute
  58. );
  59. VOID
  60. DwarfpPrintFormValue (
  61. PDWARF_ATTRIBUTE_VALUE Attribute
  62. );
  63. PSTR
  64. DwarfpGetTagName (
  65. DWARF_TAG Tag
  66. );
  67. PSTR
  68. DwarfpGetAttributeName (
  69. DWARF_ATTRIBUTE Attribute
  70. );
  71. PSTR
  72. DwarfpGetFormName (
  73. DWARF_FORM Form
  74. );
  75. PSTR
  76. DwarfpGetHasChildrenName (
  77. DWARF_CHILDREN_VALUE Value
  78. );
  79. //
  80. // -------------------------------------------------------------------- Globals
  81. //
  82. PSTR DwarfTagNames[] = {
  83. "NullTag",
  84. "DwarfTagArrayType",
  85. "DwarfTagClassType",
  86. "DwarfTagEntryPoint",
  87. "DwarfTagEnumerationType",
  88. "DwarfTagFormalParameter",
  89. NULL,
  90. NULL,
  91. "DwarfTagImportedDeclaration",
  92. NULL,
  93. "DwarfTagLabel",
  94. "DwarfTagLexicalBlock",
  95. NULL,
  96. "DwarfTagMember",
  97. NULL,
  98. "DwarfTagPointerType",
  99. "DwarfTagReferenceType",
  100. "DwarfTagCompileUnit",
  101. "DwarfTagStringType",
  102. "DwarfTagStructureType",
  103. NULL,
  104. "DwarfTagSubroutineType",
  105. "DwarfTagTypedef",
  106. "DwarfTagUnionType",
  107. "DwarfTagUnspecifiedParameters",
  108. "DwarfTagVariant",
  109. "DwarfTagCommonBlock",
  110. "DwarfTagCommonInclusion",
  111. "DwarfTagInheritance",
  112. "DwarfTagInlinedSubroutine",
  113. "DwarfTagModule",
  114. "DwarfTagPointerToMemberType",
  115. "DwarfTagSetType",
  116. "DwarfTagSubrangeType",
  117. "DwarfTagWithStatement",
  118. "DwarfTagAccessDeclaration",
  119. "DwarfTagBaseType",
  120. "DwarfTagCatchBlock",
  121. "DwarfTagConstType",
  122. "DwarfTagConstant",
  123. "DwarfTagEnumerator",
  124. "DwarfTagFileType",
  125. "DwarfTagFriend",
  126. "DwarfTagNameList",
  127. "DwarfTagNameListItem",
  128. "DwarfTagPackedType",
  129. "DwarfTagSubprogram",
  130. "DwarfTagTemplateTypeParameter",
  131. "DwarfTagTemplateValueParameter",
  132. "DwarfTagThrownType",
  133. "DwarfTagTryBlock",
  134. "DwarfTagVariantPart",
  135. "DwarfTagVariable",
  136. "DwarfTagVolatileType",
  137. "DwarfTagDwarfProcedure",
  138. "DwarfTagRestrictType",
  139. "DwarfTagInterfaceType",
  140. "DwarfTagNamespace",
  141. "DwarfTagImportedModule",
  142. "DwarfTagUnspecifiedType",
  143. "DwarfTagPartialUnit",
  144. "DwarfTagImportedUnit",
  145. NULL,
  146. "DwarfTagCondition",
  147. "DwarfTagSharedType",
  148. "DwarfTagTypeUnit",
  149. "DwarfTagRvalueReferenceType",
  150. "DwarfTagTemplateAlias",
  151. };
  152. PSTR DwarfHasChildrenNames[] = {
  153. "NoChildren",
  154. "HasChildren",
  155. };
  156. PSTR DwarfAttributeNames[] = {
  157. "DwarfAtNull",
  158. "DwarfAtSibling",
  159. "DwarfAtLocation",
  160. "DwarfAtName",
  161. NULL,
  162. NULL,
  163. NULL,
  164. NULL,
  165. NULL,
  166. "DwarfAtOrdering",
  167. NULL,
  168. "DwarfAtByteSize",
  169. "DwarfAtBitOffset",
  170. "DwarfAtBitSize",
  171. NULL,
  172. NULL,
  173. "DwarfAtStatementList",
  174. "DwarfAtLowPc",
  175. "DwarfAtHighPc",
  176. "DwarfAtLanguage",
  177. NULL,
  178. "DwarfAtDiscr",
  179. "DwarfAtDiscrValue",
  180. "DwarfAtVisibility",
  181. "DwarfAtImport",
  182. "DwarfAtStringLength",
  183. "DwarfAtCommonReference",
  184. "DwarfAtCompDir",
  185. "DwarfAtConstValue",
  186. "DwarfAtContainingType",
  187. "DwarfAtDefaultValue",
  188. NULL,
  189. "DwarfAtInline",
  190. "DwarfAtIsOptional",
  191. "DwarfAtLowerBound",
  192. NULL,
  193. NULL,
  194. "DwarfAtProducer",
  195. NULL,
  196. "DwarfAtPrototyped",
  197. NULL,
  198. NULL,
  199. "DwarfAtReturnAddress",
  200. NULL,
  201. "DwarfAtStartScope",
  202. NULL,
  203. "DwarfAtBitStride",
  204. "DwarfAtUpperBound",
  205. NULL,
  206. "DwarfAtAbstractOrigin",
  207. "DwarfAtAccessibility",
  208. "DwarfAtAddressClass",
  209. "DwarfAtArtificial",
  210. "DwarfAtBaseTypes",
  211. "DwarfAtCallingConvention",
  212. "DwarfAtCount",
  213. "DwarfAtDataMemberLocation",
  214. "DwarfAtDeclColumn",
  215. "DwarfAtDeclFile",
  216. "DwarfAtDeclLine",
  217. "DwarfAtDeclaration",
  218. "DwarfAtDiscrList",
  219. "DwarfAtEncoding",
  220. "DwarfAtExternal",
  221. "DwarfAtFrameBase",
  222. "DwarfAtFriend",
  223. "DwarfAtIdentifierCase",
  224. "DwarfAtMacroInfo",
  225. "DwarfAtNameListItem",
  226. "DwarfAtPriority",
  227. "DwarfAtSegment",
  228. "DwarfAtSpecification",
  229. "DwarfAtStaticLink",
  230. "DwarfAtType",
  231. "DwarfAtUseLocation",
  232. "DwarfAtVariableParameter",
  233. "DwarfAtVirtuality",
  234. "DwarfAtVtableElementLocation",
  235. "DwarfAtAllocated",
  236. "DwarfAtAssociated",
  237. "DwarfAtDataLocation",
  238. "DwarfAtByteStride",
  239. "DwarfAtEntryPc",
  240. "DwarfAtUseUtf8",
  241. "DwarfAtExtension",
  242. "DwarfAtRanges",
  243. "DwarfAtTrampoline",
  244. "DwarfAtCallColumn",
  245. "DwarfAtCallFile",
  246. "DwarfAtCallLine",
  247. "DwarfAtDescription",
  248. "DwarfAtBinaryScale",
  249. "DwarfAtDecimalScale",
  250. "DwarfAtSmall",
  251. "DwarfAtDecimalSign",
  252. "DwarfAtDigitCount",
  253. "DwarfAtPictureString",
  254. "DwarfAtMutable",
  255. "DwarfAtThreadsScaled",
  256. "DwarfAtExplicit",
  257. "DwarfAtObjectPointer",
  258. "DwarfAtEndianity",
  259. "DwarfAtElemental",
  260. "DwarfAtPure",
  261. "DwarfAtRecursive",
  262. "DwarfAtSignature",
  263. "DwarfAtMainSubprogram",
  264. "DwarfAtDataBitOffset",
  265. "DwarfAtConstExpression",
  266. "DwarfAtEnumClass",
  267. "DwarfAtLinkageName",
  268. };
  269. PSTR DwarfFormNames[] = {
  270. "DwarfFormNull",
  271. "DwarfFormAddress",
  272. NULL,
  273. "DwarfFormBlock2",
  274. "DwarfFormBlock4",
  275. "DwarfFormData2",
  276. "DwarfFormData4",
  277. "DwarfFormData8",
  278. "DwarfFormString",
  279. "DwarfFormBlock",
  280. "DwarfFormBlock1",
  281. "DwarfFormData1",
  282. "DwarfFormFlag",
  283. "DwarfFormSData",
  284. "DwarfFormStringPointer",
  285. "DwarfFormUData",
  286. "DwarfFormRefAddress",
  287. "DwarfFormRef1",
  288. "DwarfFormRef2",
  289. "DwarfFormRef4",
  290. "DwarfFormRef8",
  291. "DwarfFormRefUData",
  292. "DwarfFormIndirect",
  293. "DwarfFormSecOffset",
  294. "DwarfFormExprLoc",
  295. "DwarfFormFlagPresent",
  296. NULL,
  297. NULL,
  298. NULL,
  299. NULL,
  300. NULL,
  301. NULL,
  302. "DwarfFormRefSig8"
  303. };
  304. //
  305. // ------------------------------------------------------------------ Functions
  306. //
  307. VOID
  308. DwarfpReadCompilationUnit (
  309. PUCHAR *Data,
  310. PULONGLONG Size,
  311. PDWARF_COMPILATION_UNIT Unit
  312. )
  313. /*++
  314. Routine Description:
  315. This routine reads a DWARF compilation unit header, and pieces it out into
  316. a structure.
  317. Arguments:
  318. Data - Supplies a pointer that on input contains a pointer to the header.
  319. On output this pointer will be advanced past the header and the DIEs,
  320. meaning it will point at the next compilation unit.
  321. Size - Supplies a pointer that on input contains the size of the section.
  322. On output this will be decreased by the amount that the data was
  323. advanced.
  324. Unit - Supplies a pointer where the header information will be filled in.
  325. Return Value:
  326. None.
  327. --*/
  328. {
  329. ULONGLONG Delta;
  330. ULONGLONG RemainingSize;
  331. Unit->Start = *Data;
  332. RemainingSize = *Size;
  333. DwarfpReadInitialLength(Data, &(Unit->Is64Bit), &(Unit->UnitLength));
  334. Unit->Version = DwarfpRead2(Data);
  335. Unit->AbbreviationOffset = DWARF_READN(Data, Unit->Is64Bit);
  336. Unit->AddressSize = DwarfpRead1(Data);
  337. Unit->Dies = *Data;
  338. //
  339. // Advance past the DIEs themselves as well.
  340. //
  341. *Data = Unit->Start + Unit->UnitLength + sizeof(ULONG);
  342. if (Unit->Is64Bit != FALSE) {
  343. *Data += sizeof(ULONGLONG);
  344. }
  345. Unit->DiesEnd = *Data;
  346. Delta = *Data - Unit->Start;
  347. assert(Delta <= RemainingSize);
  348. RemainingSize -= Delta;
  349. *Size = RemainingSize;
  350. return;
  351. }
  352. INT
  353. DwarfpLoadCompilationUnit (
  354. PDWARF_CONTEXT Context,
  355. PDWARF_COMPILATION_UNIT Unit
  356. )
  357. /*++
  358. Routine Description:
  359. This routine processes all the DIEs within a DWARF compilation unit.
  360. Arguments:
  361. Context - Supplies a pointer to the application context.
  362. Unit - Supplies a pointer to the compilation unit.
  363. Return Value:
  364. 0 on success.
  365. Returns an error number on failure.
  366. --*/
  367. {
  368. PUCHAR Abbreviation;
  369. DWARF_LEB128 AbbreviationNumber;
  370. PUCHAR *Abbreviations;
  371. UINTN AbbreviationsCount;
  372. UINTN AllocationSize;
  373. ULONG Depth;
  374. PDWARF_DIE Die;
  375. PUCHAR DieBytes;
  376. PUCHAR End;
  377. UINTN MaxAttributes;
  378. PDWARF_DIE Parent;
  379. INT Status;
  380. Abbreviations = NULL;
  381. Depth = 0;
  382. Die = NULL;
  383. End = Unit->DiesEnd;
  384. Parent = NULL;
  385. //
  386. // Index the abbreviations for this compilation unit.
  387. //
  388. Status = DwarfpIndexAbbreviations(Context,
  389. Unit->AbbreviationOffset,
  390. &Abbreviations,
  391. &AbbreviationsCount,
  392. &MaxAttributes);
  393. if (Status != 0) {
  394. goto ProcessCompilationUnitEnd;
  395. }
  396. AllocationSize = sizeof(DWARF_DIE) +
  397. (MaxAttributes * sizeof(DWARF_ATTRIBUTE_VALUE));
  398. //
  399. // Loop through all the DIEs.
  400. //
  401. DieBytes = Unit->Dies;
  402. while (DieBytes < End) {
  403. Die = malloc(AllocationSize);
  404. if (Die == NULL) {
  405. Status = errno;
  406. goto ProcessCompilationUnitEnd;
  407. }
  408. memset(Die, 0, AllocationSize);
  409. INITIALIZE_LIST_HEAD(&(Die->ChildList));
  410. Die->Capacity = MaxAttributes;
  411. Die->Attributes = (PDWARF_ATTRIBUTE_VALUE)(Die + 1);
  412. Die->Start = DieBytes;
  413. Die->Depth = Depth;
  414. AbbreviationNumber = DwarfpReadLeb128(&DieBytes);
  415. Die->AbbreviationNumber = AbbreviationNumber;
  416. Die->Parent = Parent;
  417. //
  418. // Skip null entries.
  419. //
  420. if (AbbreviationNumber == 0) {
  421. if ((Context->Flags & DWARF_CONTEXT_DEBUG) != 0) {
  422. DWARF_PRINT(" <%x> Null Entry\n",
  423. Die->Start - (PUCHAR)(Context->Sections.Info.Data));
  424. }
  425. if (Depth != 0) {
  426. Depth -= 1;
  427. Parent = Parent->Parent;
  428. }
  429. continue;
  430. }
  431. if ((AbbreviationNumber >= AbbreviationsCount) ||
  432. (Abbreviations[AbbreviationNumber] == NULL)) {
  433. DWARF_ERROR("DWARF: Bad abbreviation number %I64d\n",
  434. AbbreviationNumber);
  435. Status = EINVAL;
  436. goto ProcessCompilationUnitEnd;
  437. }
  438. Abbreviation = Abbreviations[AbbreviationNumber];
  439. Status = DwarfpReadDie(Context,
  440. Unit,
  441. &DieBytes,
  442. Abbreviation,
  443. Die);
  444. if (Status != 0) {
  445. DWARF_ERROR("DWARF: Invalid DIE.\n");
  446. goto ProcessCompilationUnitEnd;
  447. }
  448. if (Parent != NULL) {
  449. INSERT_BEFORE(&(Die->ListEntry), &(Parent->ChildList));
  450. } else {
  451. INSERT_BEFORE(&(Die->ListEntry), &(Unit->DieList));
  452. }
  453. if ((Die->Flags & DWARF_DIE_HAS_CHILDREN) != 0) {
  454. Depth += 1;
  455. Parent = Die;
  456. }
  457. }
  458. Die = NULL;
  459. Status = 0;
  460. ProcessCompilationUnitEnd:
  461. if (Abbreviations != NULL) {
  462. free(Abbreviations);
  463. }
  464. if (Die != NULL) {
  465. DwarfpDestroyDie(Context, Die);
  466. }
  467. return Status;
  468. }
  469. VOID
  470. DwarfpDestroyCompilationUnit (
  471. PDWARF_CONTEXT Context,
  472. PDWARF_COMPILATION_UNIT Unit
  473. )
  474. /*++
  475. Routine Description:
  476. This routine destroys a compilation unit. It's assumed it's already off the
  477. list.
  478. Arguments:
  479. Context - Supplies a pointer to the application context.
  480. Unit - Supplies a pointer to the compilation unit to destroy.
  481. Return Value:
  482. None.
  483. --*/
  484. {
  485. PDWARF_DIE Die;
  486. assert(Unit->ListEntry.Next == NULL);
  487. while (!LIST_EMPTY(&(Unit->DieList))) {
  488. Die = LIST_VALUE(Unit->DieList.Next, DWARF_DIE, ListEntry);
  489. LIST_REMOVE(&(Die->ListEntry));
  490. Die->ListEntry.Next = NULL;
  491. DwarfpDestroyDie(Context, Die);
  492. }
  493. free(Unit);
  494. return;
  495. }
  496. VOID
  497. DwarfpDestroyDie (
  498. PDWARF_CONTEXT Context,
  499. PDWARF_DIE Die
  500. )
  501. /*++
  502. Routine Description:
  503. This routine destroys a Debug Information Entry.
  504. Arguments:
  505. Context - Supplies a pointer to the application context.
  506. Die - Supplies a pointer to the DIE to destroy.
  507. Return Value:
  508. None.
  509. --*/
  510. {
  511. PDWARF_DIE Child;
  512. assert(Die->ListEntry.Next == NULL);
  513. while (!LIST_EMPTY(&(Die->ChildList))) {
  514. Child = LIST_VALUE(Die->ChildList.Next, DWARF_DIE, ListEntry);
  515. LIST_REMOVE(&(Child->ListEntry));
  516. Child->ListEntry.Next = NULL;
  517. DwarfpDestroyDie(Context, Child);
  518. }
  519. free(Die);
  520. return;
  521. }
  522. PSTR
  523. DwarfpGetStringAttribute (
  524. PDWARF_DIE Die,
  525. DWARF_ATTRIBUTE Attribute
  526. )
  527. /*++
  528. Routine Description:
  529. This routine returns the given attribute with type string.
  530. Arguments:
  531. Die - Supplies a pointer to the DIE to get the attribute from.
  532. Attribute - Supplies the attribute to retrieve.
  533. Return Value:
  534. Returns a pointer to the string on success.
  535. NULL if no such attribute exists, or its type is not a string.
  536. --*/
  537. {
  538. PDWARF_ATTRIBUTE_VALUE Value;
  539. Value = DwarfpGetAttribute(Die, Attribute);
  540. if ((Value != NULL) &&
  541. ((Value->Form == DwarfFormString) ||
  542. (Value->Form == DwarfFormStringPointer))) {
  543. return Value->Value.String;
  544. }
  545. return NULL;
  546. }
  547. BOOL
  548. DwarfpGetAddressAttribute (
  549. PDWARF_DIE Die,
  550. DWARF_ATTRIBUTE Attribute,
  551. PULONGLONG Address
  552. )
  553. /*++
  554. Routine Description:
  555. This routine returns the given attribute, ensuring it is of type address.
  556. Arguments:
  557. Die - Supplies a pointer to the DIE to get the attribute from.
  558. Attribute - Supplies the attribute to retrieve.
  559. Address - Supplies a pointer where the address is returned on success.
  560. Return Value:
  561. TRUE if an address was retrieved.
  562. FALSE if no address was retrieved or it was not of type address.
  563. --*/
  564. {
  565. PDWARF_ATTRIBUTE_VALUE Value;
  566. Value = DwarfpGetAttribute(Die, Attribute);
  567. if ((Value != NULL) && (Value->Form == DwarfFormAddress)) {
  568. *Address = Value->Value.Address;
  569. return TRUE;
  570. }
  571. return FALSE;
  572. }
  573. BOOL
  574. DwarfpGetIntegerAttribute (
  575. PDWARF_DIE Die,
  576. DWARF_ATTRIBUTE Attribute,
  577. PULONGLONG Integer
  578. )
  579. /*++
  580. Routine Description:
  581. This routine returns the given attribute, ensuring it is of type integer
  582. (data or flag).
  583. Arguments:
  584. Die - Supplies a pointer to the DIE to get the attribute from.
  585. Attribute - Supplies the attribute to retrieve.
  586. Integer - Supplies a pointer where the integer is returned on success.
  587. Return Value:
  588. TRUE if an address was retrieved.
  589. FALSE if no address was retrieved or it was not of type address.
  590. --*/
  591. {
  592. BOOL Result;
  593. PDWARF_ATTRIBUTE_VALUE Value;
  594. Result = FALSE;
  595. Value = DwarfpGetAttribute(Die, Attribute);
  596. if (Value != NULL) {
  597. Result = TRUE;
  598. switch (Value->Form) {
  599. case DwarfFormData1:
  600. case DwarfFormData2:
  601. case DwarfFormData4:
  602. case DwarfFormData8:
  603. case DwarfFormSData:
  604. case DwarfFormUData:
  605. *Integer = Value->Value.UnsignedConstant;
  606. break;
  607. case DwarfFormFlag:
  608. case DwarfFormFlagPresent:
  609. *Integer = Value->Value.Flag;
  610. break;
  611. default:
  612. Result = FALSE;
  613. break;
  614. }
  615. }
  616. return Result;
  617. }
  618. BOOL
  619. DwarfpGetTypeReferenceAttribute (
  620. PDWARF_CONTEXT Context,
  621. PDWARF_DIE Die,
  622. DWARF_ATTRIBUTE Attribute,
  623. PSOURCE_FILE_SYMBOL *File,
  624. PLONG Identifier
  625. )
  626. /*++
  627. Routine Description:
  628. This routine reads a given attribute and converts that reference into a
  629. symbol type reference tuple.
  630. Arguments:
  631. Context - Supplies a pointer to the parsing context.
  632. Die - Supplies a pointer to the DIE to get the attribute from.
  633. Attribute - Supplies the attribute to retrieve.
  634. File - Supplies a pointer where a pointer to the file will be returned on
  635. success.
  636. Identifier - Supplies a pointer where the type identifier will be returned
  637. on success.
  638. Return Value:
  639. TRUE if a value was retrieved.
  640. FALSE if no value was retrieved or it was not of type reference.
  641. --*/
  642. {
  643. PDWARF_LOADING_CONTEXT LoadingContext;
  644. BOOL Result;
  645. ULONGLONG TypeOffset;
  646. LoadingContext = Context->LoadingContext;
  647. assert(LoadingContext != NULL);
  648. Result = DwarfpGetLocalReferenceAttribute(Die, Attribute, &TypeOffset);
  649. if (Result != FALSE) {
  650. assert(LoadingContext->CurrentFile != NULL);
  651. *File = LoadingContext->CurrentFile;
  652. //
  653. // Make the local reference, which is an offset from the start of the
  654. // compilation unit header, global to the entire debug info section.
  655. //
  656. TypeOffset += (PVOID)(LoadingContext->CurrentUnit->Start) -
  657. Context->Sections.Info.Data;
  658. *Identifier = TypeOffset;
  659. } else {
  660. Result = DwarfpGetGlobalReferenceAttribute(Die,
  661. DwarfAtType,
  662. &TypeOffset);
  663. if (Result == FALSE) {
  664. //
  665. // Void types don't have a type attribute.
  666. //
  667. *File = NULL;
  668. *Identifier = -1;
  669. return TRUE;
  670. }
  671. //
  672. // Consider supporting this type that is global to the whole .debug_info
  673. // section. The tricky bit is figuring out which source file
  674. // (compilation unit) the offset belongs to.
  675. //
  676. assert(FALSE);
  677. return FALSE;
  678. }
  679. return TRUE;
  680. }
  681. BOOL
  682. DwarfpGetLocalReferenceAttribute (
  683. PDWARF_DIE Die,
  684. DWARF_ATTRIBUTE Attribute,
  685. PULONGLONG Offset
  686. )
  687. /*++
  688. Routine Description:
  689. This routine returns the given attribute, ensuring it is of type reference.
  690. Arguments:
  691. Die - Supplies a pointer to the DIE to get the attribute from.
  692. Attribute - Supplies the attribute to retrieve.
  693. Offset - Supplies a pointer where the DIE offset is returned on success.
  694. Return Value:
  695. TRUE if a value was retrieved.
  696. FALSE if no value was retrieved or it was not of type reference.
  697. --*/
  698. {
  699. BOOL Result;
  700. PDWARF_ATTRIBUTE_VALUE Value;
  701. Result = FALSE;
  702. Value = DwarfpGetAttribute(Die, Attribute);
  703. if (Value != NULL) {
  704. Result = TRUE;
  705. switch (Value->Form) {
  706. case DwarfFormRef1:
  707. case DwarfFormRef2:
  708. case DwarfFormRef4:
  709. case DwarfFormRef8:
  710. case DwarfFormRefUData:
  711. case DwarfFormData1:
  712. case DwarfFormData2:
  713. case DwarfFormData4:
  714. case DwarfFormData8:
  715. case DwarfFormUData:
  716. *Offset = Value->Value.Offset;
  717. break;
  718. default:
  719. Result = FALSE;
  720. break;
  721. }
  722. }
  723. return Result;
  724. }
  725. BOOL
  726. DwarfpGetGlobalReferenceAttribute (
  727. PDWARF_DIE Die,
  728. DWARF_ATTRIBUTE Attribute,
  729. PULONGLONG Offset
  730. )
  731. /*++
  732. Routine Description:
  733. This routine returns the given attribute, ensuring it is of type reference
  734. address.
  735. Arguments:
  736. Die - Supplies a pointer to the DIE to get the attribute from.
  737. Attribute - Supplies the attribute to retrieve.
  738. Offset - Supplies a pointer where the DIE offset is returned on success.
  739. Return Value:
  740. TRUE if a value was retrieved.
  741. FALSE if no value was retrieved or it was not of type reference.
  742. --*/
  743. {
  744. PDWARF_ATTRIBUTE_VALUE Value;
  745. Value = DwarfpGetAttribute(Die, Attribute);
  746. if ((Value != NULL) && (Value->Form == DwarfFormRefAddress)) {
  747. *Offset = Value->Value.Offset;
  748. return TRUE;
  749. }
  750. return FALSE;
  751. }
  752. PDWARF_ATTRIBUTE_VALUE
  753. DwarfpGetAttribute (
  754. PDWARF_DIE Die,
  755. DWARF_ATTRIBUTE Attribute
  756. )
  757. /*++
  758. Routine Description:
  759. This routine returns the requested attribute from a DIE.
  760. Arguments:
  761. Die - Supplies a pointer to the DIE to get the attribute from.
  762. Attribute - Supplies the attribute to retrieve.
  763. Return Value:
  764. Returns a pointer to the attribute value on success.
  765. NULL if no such attribute exists.
  766. --*/
  767. {
  768. UINTN Index;
  769. for (Index = 0; Index < Die->Count; Index += 1) {
  770. if (Die->Attributes[Index].Name == Attribute) {
  771. return &(Die->Attributes[Index]);
  772. }
  773. }
  774. return NULL;
  775. }
  776. INT
  777. DwarfpSearchLocationList (
  778. PDWARF_CONTEXT Context,
  779. PDWARF_COMPILATION_UNIT Unit,
  780. UINTN Offset,
  781. ULONGLONG Pc,
  782. PUCHAR *LocationExpression,
  783. PUINTN LocationExpressionSize
  784. )
  785. /*++
  786. Routine Description:
  787. This routine searches a location list and returns the expression that
  788. matches the given PC value.
  789. Arguments:
  790. Context - Supplies a pointer to the DWARF symbol context.
  791. Unit - Supplies a pointer to the current compilation unit.
  792. Offset - Supplies the byte offset into the location list section of the
  793. list to search.
  794. Pc - Supplies the current PC value to match against.
  795. LocationExpression - Supplies a pointer where a pointer to the location
  796. expression that matched will be returned.
  797. LocationExpressionSize - Supplies a pointer where the size of the location
  798. expression will be returned on success.
  799. Return Value:
  800. 0 if an expression matched.
  801. EAGAIN if the locations section is missing.
  802. ENOENT if none of the entries matched the current PC value.
  803. --*/
  804. {
  805. ULONGLONG Base;
  806. PUCHAR Bytes;
  807. ULONGLONG End;
  808. USHORT Length;
  809. ULONGLONG Start;
  810. Base = Unit->LowPc;
  811. if (Context->Sections.Locations.Size == 0) {
  812. DWARF_ERROR("DWARF: Missing .debug_loc section.\n");
  813. return EAGAIN;
  814. }
  815. assert(Context->Sections.Locations.Size > Offset);
  816. Bytes = Context->Sections.Locations.Data + Offset;
  817. while (TRUE) {
  818. if (Unit->AddressSize == 8) {
  819. Start = DwarfpRead8(&Bytes);
  820. End = DwarfpRead8(&Bytes);
  821. //
  822. // If the start is the max address, then it's a base address update.
  823. //
  824. if (Start == MAX_ULONGLONG) {
  825. Base = End;
  826. continue;
  827. }
  828. } else {
  829. assert(Unit->AddressSize == 4);
  830. Start = DwarfpRead4(&Bytes);
  831. End = DwarfpRead4(&Bytes);
  832. if (Start == MAX_ULONG) {
  833. Base = End;
  834. continue;
  835. }
  836. }
  837. //
  838. // If the start and end are both zero, this is a termination entry.
  839. //
  840. if ((Start == 0) && (End == 0)) {
  841. break;
  842. }
  843. Length = DwarfpRead2(&Bytes);
  844. //
  845. // If the PC fits in these bounds, then return the entry contents.
  846. //
  847. if ((Pc >= Start + Base) && (Pc < End + Base)) {
  848. *LocationExpression = Bytes;
  849. *LocationExpressionSize = Length;
  850. return 0;
  851. }
  852. Bytes += Length;
  853. }
  854. return ENOENT;
  855. }
  856. DWARF_LEB128
  857. DwarfpReadLeb128 (
  858. PUCHAR *Data
  859. )
  860. /*++
  861. Routine Description:
  862. This routine reads a DWARF unsigned LEB128 variable length encoded value.
  863. Arguments:
  864. Data - Supplies a pointer that on input contains a pointer to the data.
  865. On output this pointer will be advanced past the value read.
  866. Return Value:
  867. Returns the read value.
  868. --*/
  869. {
  870. UCHAR Byte;
  871. DWARF_LEB128 Result;
  872. ULONG Shift;
  873. //
  874. // LEB128 numbers encode 7 bits in each byte, with the upper bit signifying
  875. // whether there are more bytes (1) or this is the last byte (0).
  876. //
  877. Result = 0;
  878. Shift = 0;
  879. while (TRUE) {
  880. Byte = DwarfpRead1(Data);
  881. Result |= ((ULONGLONG)(Byte & 0x7F)) << Shift;
  882. Shift += 7;
  883. if ((Byte & 0x80) == 0) {
  884. break;
  885. }
  886. }
  887. //
  888. // Anything larger than a 64-bit integer would overflow the current
  889. // data representation.
  890. //
  891. assert(Shift <= 64);
  892. return Result;
  893. }
  894. DWARF_SLEB128
  895. DwarfpReadSleb128 (
  896. PUCHAR *Data
  897. )
  898. /*++
  899. Routine Description:
  900. This routine reads a DWARF signed LEB128 variable length encoded value.
  901. Arguments:
  902. Data - Supplies a pointer that on input contains a pointer to the data.
  903. On output this pointer will be advanced past the value read.
  904. Return Value:
  905. Returns the read value.
  906. --*/
  907. {
  908. UCHAR Byte;
  909. DWARF_SLEB128 Result;
  910. ULONG Shift;
  911. //
  912. // LEB128 numbers encode 7 bits in each byte, with the upper bit signifying
  913. // whether there are more bytes (1) or this is the last byte (0).
  914. //
  915. Result = 0;
  916. Shift = 0;
  917. while (TRUE) {
  918. Byte = DwarfpRead1(Data);
  919. Result |= ((ULONGLONG)(Byte & 0x7F)) << Shift;
  920. Shift += 7;
  921. if ((Byte & 0x80) == 0) {
  922. break;
  923. }
  924. }
  925. //
  926. // If the high order bit of the last byte is set, sign extend to the
  927. // remainder of the value.
  928. //
  929. if ((Shift < (sizeof(DWARF_SLEB128) * BITS_PER_BYTE)) &&
  930. ((Byte & 0x40) != 0)) {
  931. Result |= -(1LL << Shift);
  932. }
  933. //
  934. // Anything larger than a 64-bit integer would overflow the current
  935. // data representation.
  936. //
  937. assert(Shift <= 64);
  938. return Result;
  939. }
  940. VOID
  941. DwarfpReadInitialLength (
  942. PUCHAR *Data,
  943. PBOOL Is64Bit,
  944. PULONGLONG Value
  945. )
  946. /*++
  947. Routine Description:
  948. This routine reads an initial length member from a DWARF header. The
  949. initial length is either 32-bits for 32-bit sections, or 96-bits for
  950. 64-bit sections.
  951. Arguments:
  952. Data - Supplies a pointer that on input contains a pointer to the header.
  953. On output this pointer will be advanced past the initial length.
  954. Is64Bit - Supplies a pointer where a boolean will be returned indicating
  955. whether or not this is a 64-bit section. Most sections, even in 64-bit
  956. code, are not.
  957. Value - Supplies a pointer where the actual initial length value will be
  958. returned.
  959. Return Value:
  960. None.
  961. --*/
  962. {
  963. *Is64Bit = FALSE;
  964. *Value = DwarfpRead4(Data);
  965. if (*Value == 0xFFFFFFFF) {
  966. *Is64Bit = TRUE;
  967. *Value = DwarfpRead8(Data);
  968. }
  969. return;
  970. }
  971. UCHAR
  972. DwarfpRead1 (
  973. PUCHAR *Data
  974. )
  975. /*++
  976. Routine Description:
  977. This routine reads a byte from the DWARF data stream and advances the
  978. stream.
  979. Arguments:
  980. Data - Supplies a pointer that on input contains a pointer to the data.
  981. On output this pointer will be advanced past the value read.
  982. Return Value:
  983. Returns the read value.
  984. --*/
  985. {
  986. UCHAR Value;
  987. Value = *(*Data);
  988. *Data += sizeof(UCHAR);
  989. return Value;
  990. }
  991. USHORT
  992. DwarfpRead2 (
  993. PUCHAR *Data
  994. )
  995. /*++
  996. Routine Description:
  997. This routine reads two bytes from the DWARF data stream and advances the
  998. stream.
  999. Arguments:
  1000. Data - Supplies a pointer that on input contains a pointer to the data.
  1001. On output this pointer will be advanced past the value read.
  1002. Return Value:
  1003. Returns the read value.
  1004. --*/
  1005. {
  1006. USHORT Value;
  1007. Value = *((PUSHORT)*Data);
  1008. *Data += sizeof(USHORT);
  1009. return Value;
  1010. }
  1011. ULONG
  1012. DwarfpRead4 (
  1013. PUCHAR *Data
  1014. )
  1015. /*++
  1016. Routine Description:
  1017. This routine reads four bytes from the DWARF data stream and advances the
  1018. stream.
  1019. Arguments:
  1020. Data - Supplies a pointer that on input contains a pointer to the data.
  1021. On output this pointer will be advanced past the value read.
  1022. Return Value:
  1023. Returns the read value.
  1024. --*/
  1025. {
  1026. ULONG Value;
  1027. Value = *((PULONG)*Data);
  1028. *Data += sizeof(ULONG);
  1029. return Value;
  1030. }
  1031. ULONGLONG
  1032. DwarfpRead8 (
  1033. PUCHAR *Data
  1034. )
  1035. /*++
  1036. Routine Description:
  1037. This routine reads eight bytes from the DWARF data stream and advances the
  1038. stream.
  1039. Arguments:
  1040. Data - Supplies a pointer that on input contains a pointer to the data.
  1041. On output this pointer will be advanced past the value read.
  1042. Return Value:
  1043. Returns the read value.
  1044. --*/
  1045. {
  1046. ULONGLONG Value;
  1047. Value = *((PULONGLONG)*Data);
  1048. *Data += sizeof(ULONGLONG);
  1049. return Value;
  1050. }
  1051. //
  1052. // --------------------------------------------------------- Internal Functions
  1053. //
  1054. INT
  1055. DwarfpIndexAbbreviations (
  1056. PDWARF_CONTEXT Context,
  1057. ULONGLONG Offset,
  1058. PUCHAR **AbbreviationsIndex,
  1059. PUINTN IndexSize,
  1060. PUINTN MaxAttributes
  1061. )
  1062. /*++
  1063. Routine Description:
  1064. This routine creates an array of pointers to abbreviation numbers for
  1065. the abbreviations in a compilation unit. The index makes abbreviation
  1066. lookup instant instead of O(N).
  1067. Arguments:
  1068. Context - Supplies a pointer to tha parsing context.
  1069. Offset - Supplies the offset into the abbreviation section where
  1070. abbreviations for this compilation unit begin.
  1071. AbbreviationsIndex - Supplies a pointer where an array of pointers will be
  1072. returned, indexed by abbreviation number. The caller is responsible
  1073. for freeing this memory.
  1074. IndexSize - Supplies a pointer where the number of elements in the array
  1075. will be returned.
  1076. MaxAttributes - Supplies a pointer where the maximum number of attributes
  1077. in any DIE template found will be returned.
  1078. Return Value:
  1079. 0 on success.
  1080. ENOMEM on failure.
  1081. --*/
  1082. {
  1083. PUCHAR *Array;
  1084. PUCHAR Bytes;
  1085. UINTN Count;
  1086. DWARF_LEB128 Form;
  1087. UCHAR HasChildren;
  1088. UINTN MaxIndex;
  1089. DWARF_LEB128 Name;
  1090. PVOID NewArray;
  1091. UINTN NewSize;
  1092. DWARF_LEB128 Number;
  1093. UINTN Size;
  1094. DWARF_LEB128 Tag;
  1095. *MaxAttributes = 0;
  1096. Bytes = Context->Sections.Abbreviations.Data + Offset;
  1097. if (Offset >= Context->Sections.Abbreviations.Size) {
  1098. return ERANGE;
  1099. }
  1100. MaxIndex = 0;
  1101. Size = 64;
  1102. Array = malloc(Size * sizeof(PVOID));
  1103. if (Array == NULL) {
  1104. return ENOMEM;
  1105. }
  1106. memset(Array, 0, Size * sizeof(PVOID));
  1107. if ((Context->Flags & DWARF_CONTEXT_DEBUG_ABBREVIATIONS) != 0) {
  1108. DWARF_PRINT("Abbreviations at offset %I64x:\n", Offset);
  1109. }
  1110. //
  1111. // Loop processing abbreviations.
  1112. //
  1113. while (TRUE) {
  1114. Number = DwarfpReadLeb128(&Bytes);
  1115. if (Number == 0) {
  1116. break;
  1117. }
  1118. //
  1119. // Reallocate the array if needed.
  1120. //
  1121. if (Number >= Size) {
  1122. NewSize = Size * 2;
  1123. while (NewSize <= Number) {
  1124. NewSize *= 2;
  1125. }
  1126. NewArray = realloc(Array, NewSize * sizeof(PVOID));
  1127. if (NewArray == NULL) {
  1128. free(Array);
  1129. return ENOMEM;
  1130. }
  1131. memset(NewArray + (Size * sizeof(PVOID)),
  1132. 0,
  1133. (NewSize - Size) * sizeof(PVOID));
  1134. Size = NewSize;
  1135. Array = NewArray;
  1136. }
  1137. //
  1138. // Abbreviations should not collide.
  1139. //
  1140. assert(Array[Number] == NULL);
  1141. Array[Number] = Bytes;
  1142. if (Number > MaxIndex) {
  1143. MaxIndex = Number;
  1144. }
  1145. //
  1146. // Get past the tag and the children byte.
  1147. //
  1148. Tag = DwarfpReadLeb128(&Bytes);
  1149. HasChildren = DwarfpRead1(&Bytes);
  1150. if ((Context->Flags & DWARF_CONTEXT_DEBUG_ABBREVIATIONS) != 0) {
  1151. DWARF_PRINT(" %I64d: %s %s\n",
  1152. Number,
  1153. DwarfpGetTagName(Tag),
  1154. DwarfpGetHasChildrenName(HasChildren));
  1155. }
  1156. //
  1157. // Now get past the attributes specifications.
  1158. //
  1159. Count = 0;
  1160. while (TRUE) {
  1161. Name = DwarfpReadLeb128(&Bytes);
  1162. Form = DwarfpReadLeb128(&Bytes);
  1163. if ((Name == 0) && (Form == 0)) {
  1164. break;
  1165. }
  1166. if ((Context->Flags & DWARF_CONTEXT_DEBUG_ABBREVIATIONS) != 0) {
  1167. DWARF_PRINT(" %s %s\n",
  1168. DwarfpGetAttributeName(Name),
  1169. DwarfpGetFormName(Form));
  1170. }
  1171. Count += 1;
  1172. }
  1173. if (Count > *MaxAttributes) {
  1174. *MaxAttributes = Count;
  1175. }
  1176. }
  1177. *AbbreviationsIndex = Array;
  1178. *IndexSize = MaxIndex + 1;
  1179. return 0;
  1180. }
  1181. INT
  1182. DwarfpReadDie (
  1183. PDWARF_CONTEXT Context,
  1184. PDWARF_COMPILATION_UNIT Unit,
  1185. PUCHAR *Data,
  1186. PUCHAR Abbreviation,
  1187. PDWARF_DIE Die
  1188. )
  1189. /*++
  1190. Routine Description:
  1191. This routine reads a single Debug Information Unit using the abbreviation
  1192. template.
  1193. Arguments:
  1194. Context - Supplies a pointer to the application context.
  1195. Unit - Supplies a pointer to the compilation unit.
  1196. Data - Supplies a pointer that on input contains a pointer to the values.
  1197. On output this pointer will be advanced past the contents.
  1198. Abbreviation - Supplies a pointer to the abbreviation, which marks out the
  1199. form of the data.
  1200. Die - Supplies a pointer where the DIE is returned on success.
  1201. Return Value:
  1202. 0 on success.
  1203. Returns an error number on failure.
  1204. --*/
  1205. {
  1206. PDWARF_ATTRIBUTE_VALUE Attribute;
  1207. DWARF_FORM Form;
  1208. DWARF_CHILDREN_VALUE HasChildren;
  1209. DWARF_ATTRIBUTE Name;
  1210. INT Status;
  1211. DWARF_LEB128 Tag;
  1212. //
  1213. // Get past the tag and the children byte.
  1214. //
  1215. Tag = DwarfpReadLeb128(&Abbreviation);
  1216. Die->Tag = Tag;
  1217. HasChildren = DwarfpRead1(&Abbreviation);
  1218. if ((Context->Flags & DWARF_CONTEXT_DEBUG) != 0) {
  1219. DWARF_PRINT(" <%x><%x> %s %s Abbrev. %I64d\n",
  1220. Die->Depth,
  1221. (PVOID)(Die->Start) - Context->Sections.Info.Data,
  1222. DwarfpGetTagName(Tag),
  1223. DwarfpGetHasChildrenName(HasChildren),
  1224. Die->AbbreviationNumber);
  1225. }
  1226. if (HasChildren == DwarfChildrenYes) {
  1227. Die->Flags |= DWARF_DIE_HAS_CHILDREN;
  1228. }
  1229. Attribute = &(Die->Attributes[Die->Count]);
  1230. //
  1231. // Read in each attribute value.
  1232. //
  1233. while (TRUE) {
  1234. Name = DwarfpReadLeb128(&Abbreviation);
  1235. Form = DwarfpReadLeb128(&Abbreviation);
  1236. if ((Name == 0) && (Form == 0)) {
  1237. break;
  1238. }
  1239. assert(Die->Count < Die->Capacity);
  1240. Attribute->Name = Name;
  1241. Attribute->Form = Form;
  1242. if ((Context->Flags & DWARF_CONTEXT_DEBUG) != 0) {
  1243. DWARF_PRINT(" <%x> %s : ",
  1244. *Data - (PUCHAR)(Context->Sections.Info.Data),
  1245. DwarfpGetAttributeName(Name));
  1246. }
  1247. Status = DwarfpReadFormValue(Context, Unit, Data, Attribute);
  1248. if (Status != 0) {
  1249. DWARF_ERROR("DWARF: Failed to read attribute.\n");
  1250. continue;
  1251. }
  1252. if ((Context->Flags & DWARF_CONTEXT_DEBUG) != 0) {
  1253. DwarfpPrintFormValue(Attribute);
  1254. //
  1255. // Print the expression if it's an expression or it's a block and
  1256. // has a known name.
  1257. //
  1258. if ((Attribute->Form == DwarfFormExprLoc) ||
  1259. ((DWARF_BLOCK_FORM(Attribute->Form)) &&
  1260. ((Attribute->Name == DwarfAtDataLocation) ||
  1261. (Attribute->Name == DwarfAtDataMemberLocation)))) {
  1262. DWARF_PRINT(" (");
  1263. DwarfpPrintExpression(Context,
  1264. Unit->AddressSize,
  1265. Unit,
  1266. Attribute->Value.Block.Data,
  1267. Attribute->Value.Block.Size);
  1268. DWARF_PRINT(")");
  1269. }
  1270. DWARF_PRINT("\n");
  1271. }
  1272. Die->Count += 1;
  1273. Attribute += 1;
  1274. }
  1275. return 0;
  1276. }
  1277. INT
  1278. DwarfpReadFormValue (
  1279. PDWARF_CONTEXT Context,
  1280. PDWARF_COMPILATION_UNIT Unit,
  1281. PUCHAR *Data,
  1282. PDWARF_ATTRIBUTE_VALUE Attribute
  1283. )
  1284. /*++
  1285. Routine Description:
  1286. This routine reads a DWARF attribute based on its form.
  1287. Arguments:
  1288. Context - Supplies a pointer to the application context.
  1289. Unit - Supplies a pointer to the compilation unit.
  1290. Data - Supplies a pointer that on input contains a pointer to the values.
  1291. On output this pointer will be advanced past the contents.
  1292. Attribute - Supplies a pointer to the attribute to read the value for. The
  1293. form is expected to have already been filled in.
  1294. Return Value:
  1295. 0 on success.
  1296. Returns an error number on failure.
  1297. --*/
  1298. {
  1299. INT Status;
  1300. PDWARF_FORM_VALUE Value;
  1301. Status = 0;
  1302. Value = &(Attribute->Value);
  1303. switch (Attribute->Form) {
  1304. case DwarfFormAddress:
  1305. if (Unit->AddressSize == 8) {
  1306. Value->Address = DwarfpRead8(Data);
  1307. } else {
  1308. assert(Unit->AddressSize == 4);
  1309. Value->Address = DwarfpRead4(Data);
  1310. }
  1311. break;
  1312. //
  1313. // This form is just a generic block of bytes, but its size can be defined
  1314. // in a number of different ways.
  1315. //
  1316. case DwarfFormBlock1:
  1317. case DwarfFormBlock2:
  1318. case DwarfFormBlock4:
  1319. case DwarfFormBlock:
  1320. switch (Attribute->Form) {
  1321. case DwarfFormBlock1:
  1322. Value->Block.Size = DwarfpRead1(Data);
  1323. break;
  1324. case DwarfFormBlock2:
  1325. Value->Block.Size = DwarfpRead2(Data);
  1326. break;
  1327. case DwarfFormBlock4:
  1328. Value->Block.Size = DwarfpRead4(Data);
  1329. break;
  1330. case DwarfFormBlock:
  1331. Value->Block.Size = DwarfpReadLeb128(Data);
  1332. break;
  1333. default:
  1334. assert(FALSE);
  1335. break;
  1336. }
  1337. Value->Block.Data = *Data;
  1338. *Data += Value->Block.Size;
  1339. break;
  1340. //
  1341. // Then there are the constants.
  1342. //
  1343. case DwarfFormData1:
  1344. Value->UnsignedConstant = DwarfpRead1(Data);
  1345. break;
  1346. case DwarfFormData2:
  1347. Value->UnsignedConstant = DwarfpRead2(Data);
  1348. break;
  1349. case DwarfFormData4:
  1350. Value->UnsignedConstant = DwarfpRead4(Data);
  1351. break;
  1352. case DwarfFormData8:
  1353. case DwarfFormRefSig8:
  1354. Value->UnsignedConstant = DwarfpRead8(Data);
  1355. break;
  1356. case DwarfFormSData:
  1357. Value->SignedConstant = DwarfpReadSleb128(Data);
  1358. break;
  1359. case DwarfFormUData:
  1360. Value->UnsignedConstant = DwarfpReadLeb128(Data);
  1361. break;
  1362. //
  1363. // The expression location form uses the same members as the block. It
  1364. // represents a DWARF expression.
  1365. //
  1366. case DwarfFormExprLoc:
  1367. Value->Block.Size = DwarfpReadLeb128(Data);
  1368. Value->Block.Data = *Data;
  1369. *Data += Value->Block.Size;
  1370. break;
  1371. //
  1372. // Handle the flag forms.
  1373. //
  1374. case DwarfFormFlag:
  1375. Value->Flag = DwarfpRead1(Data);
  1376. break;
  1377. case DwarfFormFlagPresent:
  1378. Value->Flag = TRUE;
  1379. break;
  1380. //
  1381. // The pointers to other sections all look the same from a data perspective.
  1382. //
  1383. case DwarfFormSecOffset:
  1384. case DwarfFormRefAddress:
  1385. Value->Offset = DWARF_READN(Data, Unit->Is64Bit);
  1386. break;
  1387. //
  1388. // Handle references to other DIEs within this compilation unit.
  1389. //
  1390. case DwarfFormRef1:
  1391. Value->Offset = DwarfpRead1(Data);
  1392. break;
  1393. case DwarfFormRef2:
  1394. Value->Offset = DwarfpRead2(Data);
  1395. break;
  1396. case DwarfFormRef4:
  1397. Value->Offset = DwarfpRead4(Data);
  1398. break;
  1399. case DwarfFormRef8:
  1400. Value->Offset = DwarfpReadLeb128(Data);
  1401. break;
  1402. case DwarfFormRefUData:
  1403. Value->Offset = DwarfpReadLeb128(Data);
  1404. break;
  1405. case DwarfFormString:
  1406. Value->String = (PSTR)*Data;
  1407. *Data += strlen((PSTR)*Data) + 1;
  1408. break;
  1409. case DwarfFormStringPointer:
  1410. Value->Offset = DWARF_READN(Data, Unit->Is64Bit);
  1411. assert(Value->Offset < Context->Sections.Strings.Size);
  1412. Value->String = Context->Sections.Strings.Data + Value->Offset;
  1413. break;
  1414. default:
  1415. DWARF_ERROR("DWARF: Unknown form %d.\n", Attribute->Form);
  1416. Status = EINVAL;
  1417. break;
  1418. }
  1419. return Status;
  1420. }
  1421. VOID
  1422. DwarfpPrintFormValue (
  1423. PDWARF_ATTRIBUTE_VALUE Attribute
  1424. )
  1425. /*++
  1426. Routine Description:
  1427. This routine prints a form value.
  1428. Arguments:
  1429. Attribute - Supplies a pointer to the attribute, whose form and value
  1430. should already be filled in.
  1431. Return Value:
  1432. None.
  1433. --*/
  1434. {
  1435. PUCHAR Bytes;
  1436. UINTN Index;
  1437. PDWARF_FORM_VALUE Value;
  1438. Value = &(Attribute->Value);
  1439. switch (Attribute->Form) {
  1440. case DwarfFormAddress:
  1441. DWARF_PRINT("%I64x", Value->Address);
  1442. break;
  1443. //
  1444. // This form is just a generic block of bytes, but its size can be defined
  1445. // in a number of different ways.
  1446. //
  1447. case DwarfFormBlock1:
  1448. case DwarfFormBlock2:
  1449. case DwarfFormBlock4:
  1450. case DwarfFormBlock:
  1451. DWARF_PRINT("%I64u byte block: ", Value->Block.Size);
  1452. Bytes = Value->Block.Data;
  1453. for (Index = 0; Index < Value->Block.Size; Index += 1) {
  1454. DWARF_PRINT("%02x ", Bytes[Index]);
  1455. }
  1456. break;
  1457. //
  1458. // Then there are the constants.
  1459. //
  1460. case DwarfFormData1:
  1461. case DwarfFormData2:
  1462. case DwarfFormData4:
  1463. case DwarfFormData8:
  1464. case DwarfFormUData:
  1465. DWARF_PRINT("%I64u", Value->UnsignedConstant);
  1466. break;
  1467. case DwarfFormRefSig8:
  1468. DWARF_PRINT("TypeSig %I64x", Value->TypeSignature);
  1469. break;
  1470. case DwarfFormSData:
  1471. DWARF_PRINT("%+I64d", Value->SignedConstant);
  1472. break;
  1473. //
  1474. // The expression location form uses the same members as the block. It
  1475. // represents a DWARF expression.
  1476. //
  1477. case DwarfFormExprLoc:
  1478. DWARF_PRINT("%I64u byte expression: ", Value->Block.Size);
  1479. Bytes = Value->Block.Data;
  1480. for (Index = 0; Index < Value->Block.Size; Index += 1) {
  1481. DWARF_PRINT("%02x ", Bytes[Index]);
  1482. }
  1483. break;
  1484. //
  1485. // Handle the flag forms.
  1486. //
  1487. case DwarfFormFlag:
  1488. case DwarfFormFlagPresent:
  1489. DWARF_PRINT("%d", Value->Flag);
  1490. break;
  1491. //
  1492. // The pointers to other sections all look the same from a data perspective.
  1493. //
  1494. case DwarfFormSecOffset:
  1495. DWARF_PRINT("SectionOffset %I64x", Value->Offset);
  1496. break;
  1497. case DwarfFormRefAddress:
  1498. DWARF_PRINT("RefAddress %I64x", Value->Offset);
  1499. break;
  1500. case DwarfFormRef1:
  1501. case DwarfFormRef2:
  1502. case DwarfFormRef4:
  1503. case DwarfFormRef8:
  1504. case DwarfFormRefUData:
  1505. DWARF_PRINT("<%I64x>", Value->Offset);
  1506. break;
  1507. case DwarfFormString:
  1508. case DwarfFormStringPointer:
  1509. DWARF_PRINT("\"%s\"", Value->String);
  1510. break;
  1511. default:
  1512. DWARF_ERROR("DWARF: Unknown form %d.\n", Attribute->Form);
  1513. break;
  1514. }
  1515. return;
  1516. }
  1517. PSTR
  1518. DwarfpGetTagName (
  1519. DWARF_TAG Tag
  1520. )
  1521. /*++
  1522. Routine Description:
  1523. This routine returns the string description of a given dwarf tag.
  1524. Arguments:
  1525. Tag - Supplies the tag to convert.
  1526. Return Value:
  1527. Returns the tag name string.
  1528. --*/
  1529. {
  1530. PSTR Name;
  1531. Name = NULL;
  1532. if (Tag <= DwarfTagTemplateAlias) {
  1533. Name = DwarfTagNames[Tag];
  1534. } else if ((Tag >= DwarfTagLowUser) && (Tag <= DwarfTagHighUser)) {
  1535. Name = "DwarfTagUser";
  1536. }
  1537. if (Name == NULL) {
  1538. Name = "DwarfTagUNKNOWN";
  1539. }
  1540. return Name;
  1541. }
  1542. PSTR
  1543. DwarfpGetAttributeName (
  1544. DWARF_ATTRIBUTE Attribute
  1545. )
  1546. /*++
  1547. Routine Description:
  1548. This routine returns the string description of a given dwarf attribute.
  1549. Arguments:
  1550. Attribute - Supplies the attribute to convert.
  1551. Return Value:
  1552. Returns the attribute name string.
  1553. --*/
  1554. {
  1555. PSTR Name;
  1556. Name = NULL;
  1557. if (Attribute <= DwarfAtLinkageName) {
  1558. Name = DwarfAttributeNames[Attribute];
  1559. } else if ((Attribute >= DwarfAtLowUser) &&
  1560. (Attribute <= DwarfAtHighUser)) {
  1561. Name = "DwarfAtUser";
  1562. }
  1563. if (Name == NULL) {
  1564. Name = "DwarfAtUNKNOWN";
  1565. }
  1566. return Name;
  1567. }
  1568. PSTR
  1569. DwarfpGetFormName (
  1570. DWARF_FORM Form
  1571. )
  1572. /*++
  1573. Routine Description:
  1574. This routine returns the string description of a given dwarf form.
  1575. Arguments:
  1576. Form - Supplies the form to convert.
  1577. Return Value:
  1578. Returns the form name string.
  1579. --*/
  1580. {
  1581. PSTR Name;
  1582. Name = NULL;
  1583. if (Form <= DwarfFormRefSig8) {
  1584. Name = DwarfFormNames[Form];
  1585. }
  1586. if (Name == NULL) {
  1587. Name = "DwarfFormUNKNOWN";
  1588. }
  1589. return Name;
  1590. }
  1591. PSTR
  1592. DwarfpGetHasChildrenName (
  1593. DWARF_CHILDREN_VALUE Value
  1594. )
  1595. /*++
  1596. Routine Description:
  1597. This routine returns the string description of a given dwarf form.
  1598. Arguments:
  1599. Value - Supplies the value to convert.
  1600. Return Value:
  1601. Returns the has children name string.
  1602. --*/
  1603. {
  1604. if (Value <= DwarfChildrenYes) {
  1605. return DwarfHasChildrenNames[Value];
  1606. }
  1607. return "DwarfChildrenINVALID";
  1608. }