stabs.c 99 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. stabs.c
  5. Abstract:
  6. This module implements routines necessary for reading and translating the
  7. STABS debugging symbol information.
  8. Author:
  9. Evan Green 26-Jun-2012
  10. Environment:
  11. Debug client
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <minoca/lib/types.h>
  17. #include <minoca/lib/status.h>
  18. #include <minoca/lib/im.h>
  19. #include <minoca/debug/dbgext.h>
  20. #include "symbols.h"
  21. #include "stabs.h"
  22. #include <assert.h>
  23. #include <errno.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. //
  28. // --------------------------------------------------------------------- Macros
  29. //
  30. #ifdef DEBUG_STABS
  31. #define STABS_DEBUG(...) DbgOut(__VA_ARGS__)
  32. #else
  33. #define STABS_DEBUG(...)
  34. #endif
  35. //
  36. // ---------------------------------------------------------------- Definitions
  37. //
  38. #define BUILTIN_TYPE_BOOL (-16)
  39. #define BUILTIN_TYPE_BOOL_STRING "@s1;r-16;0;1;"
  40. #define STABS_POINTER_SIZE 4
  41. //
  42. // ----------------------------------------------- Internal Function Prototypes
  43. //
  44. VOID
  45. DbgpStabsUnloadSymbols (
  46. PDEBUG_SYMBOLS Symbols
  47. );
  48. BOOL
  49. DbgpLoadRawStabs (
  50. PSTR Filename,
  51. PDEBUG_SYMBOLS Symbols
  52. );
  53. BOOL
  54. DbgpPopulateStabs (
  55. PDEBUG_SYMBOLS Symbols
  56. );
  57. BOOL
  58. DbgpParseLocalSymbolStab (
  59. PDEBUG_SYMBOLS Symbols,
  60. PSTR Name,
  61. PRAW_STAB Stab,
  62. PSTR StabString
  63. );
  64. PSTR
  65. DbgpCreateType (
  66. PDEBUG_SYMBOLS Symbols,
  67. PSTR TypeName,
  68. PSOURCE_FILE_SYMBOL TypeOwner,
  69. LONG TypeNumber,
  70. PSTR String
  71. );
  72. PSTR
  73. DbgpParseEnumerationMember (
  74. PSTR String,
  75. PENUMERATION_MEMBER Member
  76. );
  77. PSTR
  78. DbgpParseStructureMember (
  79. PDEBUG_SYMBOLS Symbols,
  80. PSTR String,
  81. PSTRUCTURE_MEMBER Member
  82. );
  83. PSTR
  84. DbgpParseRange (
  85. PSTR String,
  86. PDATA_RANGE Range
  87. );
  88. BOOL
  89. DbgpRangeToNumericType (
  90. PDATA_RANGE Range,
  91. PDATA_TYPE_NUMERIC Numeric
  92. );
  93. PSTR
  94. DbgpGetTypeNumber (
  95. PDEBUG_SYMBOLS Symbols,
  96. PSTR Name,
  97. PSTR String,
  98. PSOURCE_FILE_SYMBOL *OwningFile,
  99. PLONG TypeNumber
  100. );
  101. BOOL
  102. DbgpParseSourceFileStab (
  103. PDEBUG_SYMBOLS Symbols,
  104. PRAW_STAB Stab,
  105. PSTR StabString,
  106. BOOL Include
  107. );
  108. BOOL
  109. DbgpParseSourceLineStab (
  110. PDEBUG_SYMBOLS Symbols,
  111. PRAW_STAB Stab,
  112. PSTR StabString
  113. );
  114. BOOL
  115. DbgpParseFunctionStab (
  116. PDEBUG_SYMBOLS Symbols,
  117. PSTR Name,
  118. PRAW_STAB Stab,
  119. PSTR StabString
  120. );
  121. BOOL
  122. DbgpParseFunctionParameterStab (
  123. PDEBUG_SYMBOLS Symbols,
  124. PSTR Name,
  125. PRAW_STAB Stab,
  126. PSTR StabString
  127. );
  128. BOOL
  129. DbgpParseRegisterVariableStab (
  130. PDEBUG_SYMBOLS Symbols,
  131. PSTR Name,
  132. PRAW_STAB Stab,
  133. PSTR StabString
  134. );
  135. BOOL
  136. DbgpParseBraceStab (
  137. PDEBUG_SYMBOLS Symbols,
  138. PRAW_STAB Stab,
  139. PSTR StabString
  140. );
  141. BOOL
  142. DbgpParseStaticSymbolStab (
  143. PDEBUG_SYMBOLS Symbols,
  144. PSTR Name,
  145. PRAW_STAB Stab,
  146. PSTR StabString
  147. );
  148. BOOL
  149. DbgpResolveCrossReferences (
  150. PSTAB_CONTEXT State
  151. );
  152. LONG
  153. DbgpGetFileSize (
  154. FILE *File
  155. );
  156. ULONG
  157. DbgpStabsGetFramePointerRegister (
  158. PDEBUG_SYMBOLS Symbols
  159. );
  160. //
  161. // ------------------------------------------------------ Data Type Definitions
  162. //
  163. //
  164. // -------------------------------------------------------------------- Globals
  165. //
  166. DEBUG_SYMBOL_INTERFACE DbgStabsSymbolInterface = {
  167. DbgpStabsLoadSymbols,
  168. DbgpStabsUnloadSymbols,
  169. NULL,
  170. NULL,
  171. NULL
  172. };
  173. //
  174. // Basic memory leak detection code. Disabled by default.
  175. //
  176. #if 0
  177. typedef struct _MEM_ALLOCATION {
  178. BOOL Valid;
  179. PVOID Allocation;
  180. PSTR File;
  181. ULONG Line;
  182. ULONG Size;
  183. } MEM_ALLOCATION, *PMEM_ALLOCATION;
  184. #define MAX_MEMORY_ALLOCATIONS 100000
  185. BOOL LeakStructureInitialized = FALSE;
  186. MEM_ALLOCATION LeakStructure[MAX_MEMORY_ALLOCATIONS];
  187. PVOID
  188. MyMalloc (
  189. ULONG Size,
  190. PSTR File,
  191. ULONG Line
  192. )
  193. {
  194. PVOID Allocation;
  195. ULONG Index;
  196. Allocation = malloc(Size);
  197. if (Allocation == NULL) {
  198. goto MyMallocEnd;
  199. }
  200. if (LeakStructureInitialized == FALSE) {
  201. for (Index = 0; Index < MAX_MEMORY_ALLOCATIONS; Index += 1) {
  202. LeakStructure[Index].Valid = FALSE;
  203. }
  204. LeakStructureInitialized = TRUE;
  205. }
  206. for (Index = 0; Index < MAX_MEMORY_ALLOCATIONS; Index += 1) {
  207. if (LeakStructure[Index].Valid == FALSE) {
  208. LeakStructure[Index].Valid = TRUE;
  209. LeakStructure[Index].Allocation = Allocation;
  210. LeakStructure[Index].File = File;
  211. LeakStructure[Index].Line = Line;
  212. LeakStructure[Index].Size = Size;
  213. break;
  214. }
  215. }
  216. assert(Index != MAX_MEMORY_ALLOCATIONS);
  217. MyMallocEnd:
  218. return Allocation;
  219. }
  220. VOID
  221. MyFree (
  222. PVOID Allocation
  223. )
  224. {
  225. ULONG Index;
  226. assert(LeakStructureInitialized != FALSE);
  227. for (Index = 0; Index < MAX_MEMORY_ALLOCATIONS; Index += 1) {
  228. if ((LeakStructure[Index].Valid != FALSE) &&
  229. (LeakStructure[Index].Allocation == Allocation)) {
  230. LeakStructure[Index].Valid = FALSE;
  231. LeakStructure[Index].Allocation = NULL;
  232. break;
  233. }
  234. }
  235. assert(Index != MAX_MEMORY_ALLOCATIONS);
  236. }
  237. VOID
  238. PrintMemoryLeaks (
  239. )
  240. {
  241. ULONG Index;
  242. for (Index = 0; Index < MAX_MEMORY_ALLOCATIONS; Index += 1) {
  243. if (LeakStructure[Index].Valid != FALSE) {
  244. DbgOut("Leak: %08x Size %d: %s, Line %d\n",
  245. LeakStructure[Index].Allocation,
  246. LeakStructure[Index].Size,
  247. LeakStructure[Index].File,
  248. LeakStructure[Index].Line);
  249. }
  250. }
  251. }
  252. #define MALLOC(_Size) MyMalloc(_Size, __FILE__, __LINE__)
  253. #define FREE(_Allocation) MyFree(_Allocation)
  254. #else
  255. #define MALLOC(_x) malloc(_x)
  256. #define FREE(_x) free(_x)
  257. #endif
  258. //
  259. // ------------------------------------------------------------------ Functions
  260. //
  261. INT
  262. DbgpStabsLoadSymbols (
  263. PSTR Filename,
  264. IMAGE_MACHINE_TYPE MachineType,
  265. ULONG Flags,
  266. PVOID HostContext,
  267. PDEBUG_SYMBOLS *Symbols
  268. )
  269. /*++
  270. Routine Description:
  271. This routine loads debugging symbol information from the specified file.
  272. Arguments:
  273. Filename - Supplies the name of the binary to load symbols from.
  274. MachineType - Supplies the required machine type of the image. Set to
  275. unknown to allow the symbol library to load a file with any machine
  276. type.
  277. Flags - Supplies a bitfield of flags governing the behavior during load.
  278. These flags are specific to each symbol library.
  279. HostContext - Supplies the value to store in the host context field of the
  280. debug symbols.
  281. Symbols - Supplies an optional pointer where a pointer to the symbols will
  282. be returned on success.
  283. Return Value:
  284. 0 on success.
  285. Returns an error number on failure.
  286. --*/
  287. {
  288. UINTN AllocationSize;
  289. BOOL Result;
  290. PSTAB_CONTEXT StabState;
  291. PDEBUG_SYMBOLS StabSymbols;
  292. INT Status;
  293. AllocationSize = sizeof(DEBUG_SYMBOLS) + sizeof(STAB_CONTEXT);
  294. StabSymbols = MALLOC(AllocationSize);
  295. if (StabSymbols == NULL) {
  296. Status = ENOMEM;
  297. goto LoadSymbolsEnd;
  298. }
  299. //
  300. // Load the raw stab data from the file into memory.
  301. //
  302. memset(StabSymbols, 0, AllocationSize);
  303. StabSymbols->Interface = &DbgStabsSymbolInterface;
  304. StabSymbols->SymbolContext = StabSymbols + 1;
  305. StabSymbols->HostContext = HostContext;
  306. StabState = StabSymbols->SymbolContext;
  307. INITIALIZE_LIST_HEAD(&(StabState->CrossReferenceListHead));
  308. StabState->CurrentModule = StabSymbols;
  309. Result = DbgpLoadRawStabs(Filename, StabSymbols);
  310. if (Result == FALSE) {
  311. Status = EINVAL;
  312. goto LoadSymbolsEnd;
  313. }
  314. //
  315. // Verify the machine type, if supplied.
  316. //
  317. if ((MachineType != ImageMachineTypeUnknown) &&
  318. (MachineType != StabSymbols->Machine)) {
  319. DbgOut("Image machine type %d mismatches expected %d.\n",
  320. MachineType,
  321. StabSymbols->Machine);
  322. Status = EINVAL;
  323. goto LoadSymbolsEnd;
  324. }
  325. //
  326. // Parse through the stabs and initialize internal data structures.
  327. //
  328. Result = DbgpPopulateStabs(StabSymbols);
  329. if (Result == FALSE) {
  330. Status = EINVAL;
  331. DbgOut("Failure populating stabs.\n");
  332. goto LoadSymbolsEnd;
  333. }
  334. //
  335. // Attempt to load COFF symbols for PE images, or ELF symbols for ELF
  336. // images.
  337. //
  338. if (StabSymbols->ImageFormat == ImagePe32) {
  339. Result = DbgpLoadCoffSymbols(StabSymbols, Filename);
  340. if (Result == FALSE) {
  341. Status = EINVAL;
  342. goto LoadSymbolsEnd;
  343. }
  344. } else if (StabSymbols->ImageFormat == ImageElf32) {
  345. Result = DbgpLoadElfSymbols(StabSymbols, Filename);
  346. if (Result == FALSE) {
  347. Status = EINVAL;
  348. goto LoadSymbolsEnd;
  349. }
  350. }
  351. Status = 0;
  352. LoadSymbolsEnd:
  353. if (Status != 0) {
  354. if (StabSymbols != NULL) {
  355. DbgpStabsUnloadSymbols(StabSymbols);
  356. StabSymbols = NULL;
  357. }
  358. }
  359. *Symbols = StabSymbols;
  360. return Status;
  361. }
  362. //
  363. // --------------------------------------------------------- Internal Functions
  364. //
  365. VOID
  366. DbgpStabsUnloadSymbols (
  367. PDEBUG_SYMBOLS Symbols
  368. )
  369. /*++
  370. Routine Description:
  371. This routine frees all memory associated with an instance of debugging
  372. symbols. Once called, the pointer passed in should not be dereferenced
  373. again by the caller.
  374. Arguments:
  375. Symbols - Supplies a pointer to the debugging symbols.
  376. Return Value:
  377. None.
  378. --*/
  379. {
  380. PENUMERATION_MEMBER CurrentEnumerationMember;
  381. PLIST_ENTRY CurrentFunctionEntry;
  382. PLIST_ENTRY CurrentGlobalEntry;
  383. PLIST_ENTRY CurrentLineEntry;
  384. PLIST_ENTRY CurrentLocalEntry;
  385. PLIST_ENTRY CurrentParameterEntry;
  386. PLIST_ENTRY CurrentSourceEntry;
  387. PSTRUCTURE_MEMBER CurrentStructureMember;
  388. PLIST_ENTRY CurrentTypeEntry;
  389. PDATA_TYPE_ENUMERATION Enumeration;
  390. PFUNCTION_SYMBOL Function;
  391. PDATA_SYMBOL GlobalVariable;
  392. PDATA_SYMBOL LocalVariable;
  393. PENUMERATION_MEMBER NextEnumerationMember;
  394. PLIST_ENTRY NextFunctionEntry;
  395. PLIST_ENTRY NextLineEntry;
  396. PLIST_ENTRY NextLocalEntry;
  397. PLIST_ENTRY NextParameterEntry;
  398. PSTRUCTURE_MEMBER NextStructureMember;
  399. PDATA_SYMBOL Parameter;
  400. PSOURCE_FILE_SYMBOL SourceFile;
  401. PSOURCE_LINE_SYMBOL SourceLine;
  402. PSTAB_CONTEXT StabState;
  403. PDATA_TYPE_STRUCTURE Structure;
  404. PTYPE_SYMBOL TypeSymbol;
  405. if (Symbols == NULL) {
  406. return;
  407. }
  408. StabState = Symbols->SymbolContext;
  409. assert(LIST_EMPTY(&(StabState->CrossReferenceListHead)));
  410. assert(StabState->IncludeStack == NULL);
  411. if (Symbols->Filename != NULL) {
  412. FREE(Symbols->Filename);
  413. }
  414. if (StabState->RawStabs != NULL) {
  415. FREE(StabState->RawStabs);
  416. }
  417. if (StabState->RawStabStrings != NULL) {
  418. FREE(StabState->RawStabStrings);
  419. }
  420. //
  421. // Free Source files.
  422. //
  423. CurrentSourceEntry = Symbols->SourcesHead.Next;
  424. while ((CurrentSourceEntry != &(Symbols->SourcesHead)) &&
  425. (CurrentSourceEntry != NULL)) {
  426. SourceFile = LIST_VALUE(CurrentSourceEntry,
  427. SOURCE_FILE_SYMBOL,
  428. ListEntry);
  429. //
  430. // Free types.
  431. //
  432. CurrentTypeEntry = SourceFile->TypesHead.Next;
  433. while ((CurrentTypeEntry != &(SourceFile->TypesHead)) &&
  434. (CurrentTypeEntry != NULL)) {
  435. TypeSymbol = LIST_VALUE(CurrentTypeEntry,
  436. TYPE_SYMBOL,
  437. ListEntry);
  438. CurrentTypeEntry = CurrentTypeEntry->Next;
  439. //
  440. // If the type is a structure, free all structure members.
  441. //
  442. if (TypeSymbol->Type == DataTypeStructure) {
  443. Structure = &(TypeSymbol->U.Structure);
  444. CurrentStructureMember = Structure->FirstMember;
  445. while (CurrentStructureMember != NULL) {
  446. NextStructureMember = CurrentStructureMember->NextMember;
  447. if (CurrentStructureMember->Name != NULL) {
  448. FREE(CurrentStructureMember->Name);
  449. }
  450. FREE(CurrentStructureMember);
  451. CurrentStructureMember = NextStructureMember;
  452. }
  453. }
  454. //
  455. // If the type is an enumeration, free all enumeration members.
  456. //
  457. if (TypeSymbol->Type == DataTypeEnumeration) {
  458. Enumeration = &(TypeSymbol->U.Enumeration);
  459. CurrentEnumerationMember = Enumeration->FirstMember;
  460. while (CurrentEnumerationMember != NULL) {
  461. NextEnumerationMember =
  462. CurrentEnumerationMember->NextMember;
  463. if (CurrentEnumerationMember->Name != NULL) {
  464. FREE(CurrentEnumerationMember->Name);
  465. }
  466. FREE(CurrentEnumerationMember);
  467. CurrentEnumerationMember = NextEnumerationMember;
  468. }
  469. }
  470. if (TypeSymbol->Name != NULL) {
  471. FREE(TypeSymbol->Name);
  472. }
  473. FREE(TypeSymbol);
  474. }
  475. //
  476. // Free functions.
  477. //
  478. CurrentFunctionEntry = SourceFile->FunctionsHead.Next;
  479. while (CurrentFunctionEntry != &(SourceFile->FunctionsHead)) {
  480. Function = LIST_VALUE(CurrentFunctionEntry,
  481. FUNCTION_SYMBOL,
  482. ListEntry);
  483. //
  484. // Free function parameters.
  485. //
  486. CurrentParameterEntry = Function->ParametersHead.Next;
  487. while (CurrentParameterEntry != &(Function->ParametersHead)) {
  488. Parameter = LIST_VALUE(CurrentParameterEntry,
  489. DATA_SYMBOL,
  490. ListEntry);
  491. if (Parameter->Name != NULL) {
  492. FREE(Parameter->Name);
  493. }
  494. NextParameterEntry = CurrentParameterEntry->Next;
  495. FREE(Parameter);
  496. CurrentParameterEntry = NextParameterEntry;
  497. }
  498. if (Function->Name != NULL) {
  499. FREE(Function->Name);
  500. }
  501. //
  502. // Free function local variables.
  503. //
  504. CurrentLocalEntry = Function->LocalsHead.Next;
  505. while (CurrentLocalEntry != &(Function->LocalsHead)) {
  506. LocalVariable = LIST_VALUE(CurrentLocalEntry,
  507. DATA_SYMBOL,
  508. ListEntry);
  509. if (LocalVariable->Name != NULL) {
  510. FREE(LocalVariable->Name);
  511. }
  512. NextLocalEntry = CurrentLocalEntry->Next;
  513. assert(NextLocalEntry != NULL);
  514. FREE(LocalVariable);
  515. CurrentLocalEntry = NextLocalEntry;
  516. }
  517. NextFunctionEntry = CurrentFunctionEntry->Next;
  518. FREE(Function);
  519. CurrentFunctionEntry = NextFunctionEntry;
  520. }
  521. //
  522. // Free source lines.
  523. //
  524. CurrentLineEntry = SourceFile->SourceLinesHead.Next;
  525. while (CurrentLineEntry != &(SourceFile->SourceLinesHead)) {
  526. SourceLine = LIST_VALUE(CurrentLineEntry,
  527. SOURCE_LINE_SYMBOL,
  528. ListEntry);
  529. NextLineEntry = CurrentLineEntry->Next;
  530. FREE(SourceLine);
  531. CurrentLineEntry = NextLineEntry;
  532. }
  533. //
  534. // Free global/static symbols.
  535. //
  536. CurrentGlobalEntry = SourceFile->DataSymbolsHead.Next;
  537. while (CurrentGlobalEntry != &(SourceFile->DataSymbolsHead)) {
  538. GlobalVariable = LIST_VALUE(CurrentGlobalEntry,
  539. DATA_SYMBOL,
  540. ListEntry);
  541. if (GlobalVariable->Name != NULL) {
  542. FREE(GlobalVariable->Name);
  543. }
  544. CurrentGlobalEntry = CurrentGlobalEntry->Next;
  545. FREE(GlobalVariable);
  546. }
  547. CurrentSourceEntry = CurrentSourceEntry->Next;
  548. FREE(SourceFile);
  549. }
  550. FREE(Symbols);
  551. return;
  552. }
  553. BOOL
  554. DbgpLoadRawStabs (
  555. PSTR Filename,
  556. PDEBUG_SYMBOLS Symbols
  557. )
  558. /*++
  559. Routine Description:
  560. This routine loads the raw ".stab" and ".stabstr" sections into memory. The
  561. caller must remember to free any memory allocated here.
  562. Arguments:
  563. Filename - Supplies the name of the binary to load STABS sections from.
  564. Symbols - Supplies a pointer to the structure where the buffers and sizes
  565. should be returned.
  566. Return Value:
  567. TRUE on success.
  568. FALSE on failure.
  569. --*/
  570. {
  571. LONG BytesRead;
  572. FILE *File;
  573. PVOID FileBuffer;
  574. LONG FileSize;
  575. IMAGE_BUFFER ImageBuffer;
  576. IMAGE_INFORMATION Information;
  577. BOOL Result;
  578. ULONG SectionSize;
  579. PVOID SectionSource;
  580. PSTAB_CONTEXT StabState;
  581. KSTATUS Status;
  582. FileBuffer = NULL;
  583. StabState = Symbols->SymbolContext;
  584. memset(&ImageBuffer, 0, sizeof(IMAGE_BUFFER));
  585. SectionSource = NULL;
  586. Symbols->Filename = NULL;
  587. StabState->RawStabs = NULL;
  588. StabState->RawStabStrings = NULL;
  589. //
  590. // Determine the file size and load the file into memory.
  591. //
  592. File = fopen(Filename, "rb");
  593. if (File == NULL) {
  594. Result = FALSE;
  595. goto LoadRawStabsEnd;
  596. }
  597. FileSize = DbgpGetFileSize(File);
  598. if (FileSize <= 0) {
  599. Result = FALSE;
  600. goto LoadRawStabsEnd;
  601. }
  602. FileBuffer = MALLOC(FileSize);
  603. if (FileBuffer == NULL) {
  604. Result = FALSE;
  605. goto LoadRawStabsEnd;
  606. }
  607. BytesRead = fread(FileBuffer, 1, FileSize, File);
  608. if (BytesRead != FileSize) {
  609. Result = FALSE;
  610. goto LoadRawStabsEnd;
  611. }
  612. //
  613. // Save the filename into the debug symbols.
  614. //
  615. Symbols->Filename = MALLOC(strlen(Filename) + 1);
  616. if (Symbols->Filename == NULL) {
  617. Result = FALSE;
  618. goto LoadRawStabsEnd;
  619. }
  620. strcpy(Symbols->Filename, Filename);
  621. ImageBuffer.Data = FileBuffer;
  622. ImageBuffer.Size = FileSize;
  623. //
  624. // Get and save the relevant image information.
  625. //
  626. Status = ImGetImageInformation(&ImageBuffer, &Information);
  627. if (!KSUCCESS(Status)) {
  628. Result = FALSE;
  629. goto LoadRawStabsEnd;
  630. }
  631. Symbols->ImageFormat = Information.Format;
  632. Symbols->Machine = Information.Machine;
  633. Symbols->ImageBase = Information.ImageBase;
  634. //
  635. // Attempt to get the stabs section. If successful, allocate a new buffer
  636. // and copy it over.
  637. //
  638. Result = ImGetImageSection(&ImageBuffer,
  639. ".stab",
  640. &SectionSource,
  641. NULL,
  642. &SectionSize,
  643. NULL);
  644. if ((Result == FALSE) || (SectionSize == 0) || (SectionSource == NULL)) {
  645. Result = FALSE;
  646. goto LoadRawStabsEnd;
  647. }
  648. StabState->RawStabs = MALLOC(SectionSize);
  649. if (StabState->RawStabs == NULL) {
  650. Result = FALSE;
  651. goto LoadRawStabsEnd;
  652. }
  653. memcpy(StabState->RawStabs, SectionSource, SectionSize);
  654. StabState->RawStabsSize = SectionSize;
  655. //
  656. // Attempt to get the stab strings section.
  657. //
  658. Result = ImGetImageSection(&ImageBuffer,
  659. ".stabstr",
  660. &SectionSource,
  661. NULL,
  662. &SectionSize,
  663. NULL);
  664. if ((Result == FALSE) || (SectionSize == 0) || (SectionSource == NULL)) {
  665. Result = FALSE;
  666. goto LoadRawStabsEnd;
  667. }
  668. StabState->RawStabStrings = MALLOC(SectionSize);
  669. if (StabState->RawStabStrings == NULL) {
  670. Result = FALSE;
  671. goto LoadRawStabsEnd;
  672. }
  673. memcpy(StabState->RawStabStrings, SectionSource, SectionSize);
  674. StabState->RawStabStringsSize = SectionSize;
  675. Result = TRUE;
  676. LoadRawStabsEnd:
  677. if (Result == FALSE) {
  678. if (StabState->RawStabs != NULL) {
  679. FREE(StabState->RawStabs);
  680. StabState->RawStabs = NULL;
  681. StabState->RawStabsSize = 0;
  682. }
  683. if (StabState->RawStabStrings != NULL) {
  684. FREE(StabState->RawStabStrings);
  685. StabState->RawStabStrings = NULL;
  686. StabState->RawStabStringsSize = 0;
  687. }
  688. if (Symbols->Filename != NULL) {
  689. FREE(Symbols->Filename);
  690. Symbols->Filename = NULL;
  691. }
  692. }
  693. if (FileBuffer != NULL) {
  694. FREE(FileBuffer);
  695. }
  696. if (File != NULL) {
  697. fclose(File);
  698. }
  699. return Result;
  700. }
  701. BOOL
  702. DbgpPopulateStabs (
  703. PDEBUG_SYMBOLS Symbols
  704. )
  705. /*++
  706. Routine Description:
  707. This routine parses through stab data, setting up various data structures
  708. to represent the stabs that the rest of the debugging system can understand.
  709. Arguments:
  710. Symbols - Supplies a pointer to the symbols data. The raw stab data should
  711. already be loaded. Also returns the initialized data.
  712. Return Value:
  713. TRUE on success.
  714. FALSE on failure.
  715. --*/
  716. {
  717. ULONG ByteCount;
  718. PCROSS_REFERENCE_ENTRY CrossReference;
  719. PLIST_ENTRY CurrentCrossReferenceEntry;
  720. BOOL Include;
  721. ULONG Index;
  722. BOOL IsSourceFileStab;
  723. PSTR Name;
  724. PSTR NameEnd;
  725. PRAW_STAB RawStab;
  726. BOOL Result;
  727. PSTAB_CONTEXT StabState;
  728. PSTR StabString;
  729. Name = NULL;
  730. StabState = Symbols->SymbolContext;
  731. //
  732. // Validate parameters.
  733. //
  734. if ((Symbols == NULL) || (StabState->RawStabs == NULL) ||
  735. (StabState->RawStabsSize == 0) || (StabState->RawStabStrings == NULL) ||
  736. (StabState->RawStabStringsSize == 0)) {
  737. Result = FALSE;
  738. goto PopulateStabsEnd;
  739. }
  740. //
  741. // Initialize module structures if not done yet.
  742. //
  743. if ((Symbols->SourcesHead.Next == NULL) ||
  744. (Symbols->SourcesHead.Previous == NULL)) {
  745. INITIALIZE_LIST_HEAD(&(Symbols->SourcesHead));
  746. }
  747. //
  748. // Loop over stabs.
  749. //
  750. ByteCount = sizeof(RAW_STAB);
  751. Index = 0;
  752. RawStab = StabState->RawStabs;
  753. while (ByteCount <= StabState->RawStabsSize) {
  754. Name = NULL;
  755. STABS_DEBUG("%d: Index: 0x%x, Type: %d, Other: %d, Desc: %d, "
  756. "Value: 0x%x\n",
  757. Index,
  758. RawStab->StringIndex,
  759. RawStab->Type,
  760. RawStab->Other,
  761. RawStab->Description,
  762. RawStab->Value);
  763. if ((RawStab->StringIndex > 0) &&
  764. (RawStab->StringIndex < StabState->RawStabStringsSize)) {
  765. StabString = StabState->RawStabStrings + RawStab->StringIndex;
  766. STABS_DEBUG("String: %s\n",
  767. StabState->RawStabStrings + RawStab->StringIndex);
  768. //
  769. // If the stab has a string, it probably starts with a name. Get
  770. // that name here to avoid duplicating that code in each function.
  771. // A source file may have a colon in the drive letter that is not
  772. // the name delimiter, so avoid parsing those.
  773. //
  774. IsSourceFileStab = (RawStab->Type == STAB_SOURCE_FILE) ||
  775. (RawStab->Type == STAB_INCLUDE_BEGIN) ||
  776. (RawStab->Type == STAB_INCLUDE_PLACEHOLDER) ||
  777. (RawStab->Type == STAB_INCLUDE_NAME);
  778. if (IsSourceFileStab == FALSE) {
  779. //
  780. // Get the first single (but not double) colon.
  781. //
  782. NameEnd = StabString;
  783. while (TRUE) {
  784. NameEnd = strchr(NameEnd, ':');
  785. if ((NameEnd == NULL) || (*(NameEnd + 1) != ':')) {
  786. break;
  787. }
  788. NameEnd += 2;
  789. }
  790. if (NameEnd != NULL) {
  791. Name = MALLOC(NameEnd - StabString + 1);
  792. if (Name == NULL) {
  793. Result = FALSE;
  794. goto PopulateStabsEnd;
  795. }
  796. strncpy(Name, StabString, NameEnd - StabString);
  797. Name[NameEnd - StabString] = '\0';
  798. StabString = NameEnd + 1;
  799. }
  800. }
  801. } else {
  802. StabString = NULL;
  803. }
  804. Include = FALSE;
  805. switch (RawStab->Type) {
  806. case STAB_FUNCTION:
  807. Result = DbgpParseFunctionStab(Symbols, Name, RawStab, StabString);
  808. break;
  809. case STAB_FUNCTION_PARAMETER:
  810. Result = DbgpParseFunctionParameterStab(Symbols,
  811. Name,
  812. RawStab,
  813. StabString);
  814. break;
  815. case STAB_REGISTER_VARIABLE:
  816. Result = DbgpParseRegisterVariableStab(Symbols,
  817. Name,
  818. RawStab,
  819. StabString);
  820. break;
  821. case STAB_LOCAL_SYMBOL:
  822. Result = DbgpParseLocalSymbolStab(Symbols,
  823. Name,
  824. RawStab,
  825. StabString);
  826. break;
  827. case STAB_BSS_SYMBOL:
  828. case STAB_GLOBAL_SYMBOL:
  829. case STAB_STATIC:
  830. Result = DbgpParseStaticSymbolStab(Symbols,
  831. Name,
  832. RawStab,
  833. StabString);
  834. break;
  835. case STAB_INCLUDE_BEGIN:
  836. case STAB_INCLUDE_PLACEHOLDER:
  837. //
  838. // Set include to true and fall through to source file processing.
  839. //
  840. Include = TRUE;
  841. case STAB_INCLUDE_NAME:
  842. case STAB_SOURCE_FILE:
  843. //
  844. // A source file has no colon following the name, so the name
  845. // parsing code above will not have found anything.
  846. //
  847. assert(Name == NULL);
  848. Result = DbgpParseSourceFileStab(Symbols,
  849. RawStab,
  850. StabString,
  851. Include);
  852. break;
  853. case STAB_SOURCE_LINE:
  854. assert(Name == NULL);
  855. Result = DbgpParseSourceLineStab(Symbols, RawStab, StabString);
  856. break;
  857. case STAB_LEFT_BRACE:
  858. case STAB_RIGHT_BRACE:
  859. assert(Name == NULL);
  860. Result = DbgpParseBraceStab(Symbols, RawStab, StabString);
  861. break;
  862. default:
  863. if (Name != NULL) {
  864. FREE(Name);
  865. }
  866. Result = TRUE;
  867. break;
  868. }
  869. if (Result == FALSE) {
  870. printf("Failed to load STAB: ");
  871. printf("%d: Index: 0x%x, Type: %x, Other: %d, Desc: %d, "
  872. "Value: 0x%x\n - %s\n",
  873. Index,
  874. RawStab->StringIndex,
  875. RawStab->Type,
  876. RawStab->Other,
  877. RawStab->Description,
  878. RawStab->Value,
  879. StabString);
  880. }
  881. RawStab += 1;
  882. Index += 1;
  883. ByteCount += sizeof(RAW_STAB);
  884. }
  885. //
  886. // Send down a closing source file stab in case the last file was an
  887. // assembly file (they don't always close themselves).
  888. //
  889. Result = DbgpParseSourceFileStab(Symbols, NULL, NULL, FALSE);
  890. if (Result == FALSE) {
  891. goto PopulateStabsEnd;
  892. }
  893. Result = TRUE;
  894. PopulateStabsEnd:
  895. //
  896. // Free any remaining cross references.
  897. //
  898. CurrentCrossReferenceEntry = StabState->CrossReferenceListHead.Next;
  899. while (CurrentCrossReferenceEntry != &(StabState->CrossReferenceListHead)) {
  900. CrossReference = LIST_VALUE(CurrentCrossReferenceEntry,
  901. CROSS_REFERENCE_ENTRY,
  902. ListEntry);
  903. CurrentCrossReferenceEntry = CurrentCrossReferenceEntry->Next;
  904. LIST_REMOVE(&(CrossReference->ListEntry));
  905. FREE(CrossReference);
  906. }
  907. if (Result == FALSE) {
  908. if (Name != NULL) {
  909. FREE(Name);
  910. }
  911. }
  912. return Result;
  913. }
  914. BOOL
  915. DbgpParseLocalSymbolStab (
  916. PDEBUG_SYMBOLS Symbols,
  917. PSTR Name,
  918. PRAW_STAB Stab,
  919. PSTR StabString
  920. )
  921. /*++
  922. Routine Description:
  923. This routine parses through a local symbol stab, updating the output symbol
  924. information as well as the parse state.
  925. Arguments:
  926. Symbols - Supplies a pointer to the symbols data. The raw stab data should
  927. already be loaded. Also returns the initialized data.
  928. Name - Supplies the name of the local symbol, or NULL if a name could not
  929. be parsed.
  930. Stab - Supplies a pointer to the stab of type STAB_SOURCE_FILE.
  931. StabString - Supplies a pointer to the stab's string, or NULL if the stab
  932. has no string.
  933. Return Value:
  934. TRUE on success.
  935. FALSE on failure.
  936. --*/
  937. {
  938. PSTR Contents;
  939. PDATA_SYMBOL NewLocal;
  940. BOOL Result;
  941. PSTAB_CONTEXT State;
  942. LONG TypeNumber;
  943. PSOURCE_FILE_SYMBOL TypeOwner;
  944. NewLocal = NULL;
  945. //
  946. // Parameter checking.
  947. //
  948. if ((StabString == NULL) || (Symbols == NULL) || (Stab == NULL)) {
  949. Result = FALSE;
  950. goto ParseLocalSymbolStabEnd;
  951. }
  952. Contents = StabString;
  953. if ((Contents == NULL) || (strlen(Contents) == 0)) {
  954. Result = FALSE;
  955. goto ParseLocalSymbolStabEnd;
  956. }
  957. //
  958. // A 't' or 'T' next means this symbol is a type. ('T' specifies a typedef,
  959. // struct or union).
  960. //
  961. if ((*Contents == 't') || (*Contents == 'T')) {
  962. Contents += 1;
  963. //
  964. // Sometimes Tt seems to get emitted, which seems to be no different
  965. // really.
  966. //
  967. if (*Contents == 't') {
  968. Contents += 1;
  969. }
  970. Contents = DbgpGetTypeNumber(Symbols,
  971. Name,
  972. Contents,
  973. &TypeOwner,
  974. &TypeNumber);
  975. assert(Contents != NULL);
  976. if (Contents == NULL) {
  977. Result = FALSE;
  978. goto ParseLocalSymbolStabEnd;
  979. }
  980. //
  981. // A digit, -, or ( indicates that a type immediately follows the name. The
  982. // default behavior is to treat this as a local variable.
  983. //
  984. } else if ((*Contents == '-') || (*Contents == '(') ||
  985. ((*Contents >= '0') && (*Contents <= '9'))) {
  986. State = Symbols->SymbolContext;
  987. //
  988. // If there is no current source file or function, then it makes very
  989. // little sense to have a local variable. Fail here if that's the case.
  990. //
  991. if ((State->CurrentSourceFile == NULL) ||
  992. (State->CurrentFunction == NULL)) {
  993. Result = FALSE;
  994. goto ParseLocalSymbolStabEnd;
  995. }
  996. //
  997. // Allocate space for a new local variable symbol.
  998. //
  999. NewLocal = MALLOC(sizeof(DATA_SYMBOL));
  1000. if (NewLocal == NULL) {
  1001. Result = FALSE;
  1002. goto ParseLocalSymbolStabEnd;
  1003. }
  1004. memset(NewLocal, 0, sizeof(DATA_SYMBOL));
  1005. Contents = DbgpGetTypeNumber(Symbols,
  1006. NULL,
  1007. Contents,
  1008. &(NewLocal->TypeOwner),
  1009. &(NewLocal->TypeNumber));
  1010. if (Contents == NULL) {
  1011. Result = FALSE;
  1012. goto ParseLocalSymbolStabEnd;
  1013. }
  1014. //
  1015. // Initialize the new local and insert it into the current function's
  1016. // locals list.
  1017. //
  1018. NewLocal->ParentSource = State->CurrentSourceFile;
  1019. NewLocal->ParentFunction = State->CurrentFunction;
  1020. NewLocal->Name = Name;
  1021. NewLocal->LocationType = DataLocationIndirect;
  1022. NewLocal->Location.Indirect.Offset = (LONG)Stab->Value;
  1023. NewLocal->Location.Indirect.Register =
  1024. DbgpStabsGetFramePointerRegister(Symbols);
  1025. NewLocal->MinimumValidExecutionAddress = State->MaxBraceAddress;
  1026. INSERT_BEFORE(&(NewLocal->ListEntry),
  1027. &(State->CurrentFunction->LocalsHead));
  1028. }
  1029. Result = TRUE;
  1030. ParseLocalSymbolStabEnd:
  1031. if (Result == FALSE) {
  1032. if (NewLocal != NULL) {
  1033. FREE(NewLocal);
  1034. }
  1035. }
  1036. return Result;
  1037. }
  1038. PSTR
  1039. DbgpCreateType (
  1040. PDEBUG_SYMBOLS Symbols,
  1041. PSTR TypeName,
  1042. PSOURCE_FILE_SYMBOL TypeOwner,
  1043. LONG TypeNumber,
  1044. PSTR String
  1045. )
  1046. /*++
  1047. Routine Description:
  1048. This routine creates a new type based on the partial stab string and the
  1049. stab parsing state.
  1050. Arguments:
  1051. Symbols - Supplies a pointer to the current module.
  1052. TypeName - Supplies the name of the type.
  1053. TypeOwner - Supplies a pointer to the source file this type was defined in.
  1054. TypeNumber - Supplies the type number for this type.
  1055. String - Supplies the stab string starting at the type definition.
  1056. Return Value:
  1057. Returns the string advanced beyond the type definition, or NULL on failure.
  1058. --*/
  1059. {
  1060. PCROSS_REFERENCE_ENTRY CrossReference;
  1061. PENUMERATION_MEMBER CurrentEnumerationMember;
  1062. PSTRUCTURE_MEMBER CurrentStructureMember;
  1063. PSTR EndString;
  1064. DATA_TYPE_ENUMERATION Enumeration;
  1065. PSTR EnumerationString;
  1066. LONG FloatSize;
  1067. LONG FloatType;
  1068. PVOID LocalData;
  1069. ULONG LocalDataSize;
  1070. ENUMERATION_MEMBER LocalEnumerationMember;
  1071. STRUCTURE_MEMBER LocalStructureMember;
  1072. PENUMERATION_MEMBER NewEnumerationMember;
  1073. PSTRUCTURE_MEMBER NewStructureMember;
  1074. PTYPE_SYMBOL NewType;
  1075. PENUMERATION_MEMBER NextEnumerationMember;
  1076. PSTRUCTURE_MEMBER NextStructureMember;
  1077. DATA_TYPE_NUMERIC Numeric;
  1078. PSTAB_CONTEXT ParseState;
  1079. DATA_RANGE Range;
  1080. DATA_TYPE_RELATION Relation;
  1081. BOOL Result;
  1082. DATA_TYPE_STRUCTURE Structure;
  1083. PSTR StructureString;
  1084. DATA_TYPE_TYPE Type;
  1085. LONG TypeSize;
  1086. INT ValuesRead;
  1087. CurrentEnumerationMember = NULL;
  1088. CurrentStructureMember = NULL;
  1089. LocalData = NULL;
  1090. LocalDataSize = 0;
  1091. NewType = NULL;
  1092. Type = DataTypeInvalid;
  1093. TypeSize = 0;
  1094. memset(&Enumeration, 0, sizeof(DATA_TYPE_ENUMERATION));
  1095. memset(&Structure, 0, sizeof(DATA_TYPE_STRUCTURE));
  1096. //
  1097. // An '@' means there are attributes that must be parsed.
  1098. //
  1099. if (*String == '@') {
  1100. String += 1;
  1101. switch (*String) {
  1102. //
  1103. // The 's' attribute specifies the type's size in bits.
  1104. //
  1105. case 's':
  1106. String += 1;
  1107. ValuesRead = sscanf(String, "%d", &TypeSize);
  1108. if (ValuesRead != 1) {
  1109. String = NULL;
  1110. goto CreateTypeEnd;
  1111. }
  1112. break;
  1113. default:
  1114. break;
  1115. }
  1116. //
  1117. // Advance the string past the attribute.
  1118. //
  1119. while ((*String != ';') && (*String != '\0')) {
  1120. String += 1;
  1121. }
  1122. if ((*String == '\0') || (*(String + 1) == '\0')) {
  1123. String = NULL;
  1124. goto CreateTypeEnd;
  1125. }
  1126. String += 1;
  1127. }
  1128. //
  1129. // A type descriptor that begins with 'k' indicates a constant value.
  1130. // Constants are ignored and treated like everything else here. Skip the k.
  1131. //
  1132. if (*String == 'k') {
  1133. String += 1;
  1134. }
  1135. //
  1136. // A type descriptor that begins with 'B' indicates a volatile variable.
  1137. // Volatiles are treated the same as any other variable, so swallow this
  1138. // specifier.
  1139. //
  1140. if (*String == 'B') {
  1141. String += 1;
  1142. }
  1143. //
  1144. // A type descriptor that begins with 'x' indicates a cross reference to
  1145. // a type that may or may not be created yet. Create a record of this cross
  1146. // reference that will get resolved once all the symbols in the file have
  1147. // been parsed.
  1148. //
  1149. if (*String == 'x') {
  1150. String += 1;
  1151. CrossReference = MALLOC(sizeof(CROSS_REFERENCE_ENTRY));
  1152. if (CrossReference == NULL) {
  1153. String = NULL;
  1154. goto CreateTypeEnd;
  1155. }
  1156. CrossReference->ReferringTypeName = TypeName;
  1157. CrossReference->ReferringTypeNumber = TypeNumber;
  1158. CrossReference->ReferringTypeSource = TypeOwner;
  1159. CrossReference->ReferenceString = String;
  1160. ParseState = Symbols->SymbolContext;
  1161. INSERT_BEFORE(&(CrossReference->ListEntry),
  1162. &(ParseState->CrossReferenceListHead));
  1163. //
  1164. // Find the end of the cross reference, marked by a single colon (but
  1165. // not a double colon). Sometimes there's not a colon, the string just
  1166. // ends.
  1167. //
  1168. EndString = String;
  1169. while (TRUE) {
  1170. EndString = strchr(EndString, ':');
  1171. if ((EndString == NULL) || (*(EndString + 1) != ':')) {
  1172. break;
  1173. }
  1174. EndString += 2;
  1175. }
  1176. //
  1177. // If there was a colon, get past it. If there was no colon, then just
  1178. // get the end of the string.
  1179. //
  1180. if (EndString != NULL) {
  1181. EndString += 1;
  1182. } else {
  1183. EndString = strchr(String, '\0');
  1184. }
  1185. String = EndString;
  1186. goto CreateTypeEnd;
  1187. }
  1188. //
  1189. // A '*', digit, or '-' indicates that this type is either a pointer or
  1190. // equivalent to another type. An 'a' indicates that this type is an array.
  1191. // An 'f' indicates this variable is a function.
  1192. // & is a C++ reference, # is a C++ method.
  1193. //
  1194. if ((*String == '*') ||
  1195. (*String == '&') ||
  1196. (*String == '-') ||
  1197. (*String == '(') ||
  1198. (*String == 'a') ||
  1199. (*String == 'f') ||
  1200. (*String == '#') ||
  1201. ((*String >= '0') && (*String <= '9'))) {
  1202. memset(&Relation, 0, sizeof(DATA_TYPE_RELATION));
  1203. if ((*String == '*') || (*String == '&')) {
  1204. Relation.Pointer = STABS_POINTER_SIZE;
  1205. String += 1;
  1206. }
  1207. //
  1208. // An array has an 'a', then a range specifying the index range.
  1209. //
  1210. if (*String == 'a') {
  1211. //
  1212. // Advance beyond the 'a', 'r', and get the index type. It's
  1213. // assumed the index type is always an integer of some sort, but
  1214. // additional type definitions could be hidden in here, so it's
  1215. // necessary to kick off that chain if that's the case.
  1216. //
  1217. String += 1;
  1218. if (*String != 'r') {
  1219. String = NULL;
  1220. goto CreateTypeEnd;
  1221. }
  1222. String += 1;
  1223. String = DbgpGetTypeNumber(Symbols,
  1224. NULL,
  1225. String,
  1226. NULL,
  1227. NULL);
  1228. if (String == NULL) {
  1229. goto CreateTypeEnd;
  1230. }
  1231. //
  1232. // Advance past the semicolon and parse the range
  1233. //
  1234. String += 1;
  1235. String = DbgpParseRange(String, &(Relation.Array));
  1236. if (String == NULL) {
  1237. goto CreateTypeEnd;
  1238. }
  1239. //
  1240. // An array of length zero is really just a pointer.
  1241. //
  1242. if ((Relation.Array.Minimum == 0) &&
  1243. (Relation.Array.Maximum == -1)) {
  1244. Relation.Pointer = STABS_POINTER_SIZE;
  1245. Relation.Array.Maximum = 0;
  1246. }
  1247. }
  1248. //
  1249. // An 'f' indicates this type is a function, # is a C++ method.
  1250. //
  1251. if ((*String == 'f') || (*String == '#')) {
  1252. Relation.Function = TRUE;
  1253. String += 1;
  1254. }
  1255. //
  1256. // Get the type that this type relates to.
  1257. //
  1258. String = DbgpGetTypeNumber(Symbols,
  1259. NULL,
  1260. String,
  1261. &(Relation.OwningFile),
  1262. &(Relation.TypeNumber));
  1263. if (String == NULL) {
  1264. goto CreateTypeEnd;
  1265. }
  1266. if ((Relation.Array.Maximum != 0) || (Relation.Array.Minimum != 0)) {
  1267. STABS_DEBUG("New Relational Array Type: %s:(%s,%d). Pointer: %d, "
  1268. "Reference Type: (%s, %d)\n"
  1269. "\tArray Range = [%I64i, %I64i], MaxUlonglong? %d\n",
  1270. TypeName,
  1271. TypeOwner->SourceFile,
  1272. TypeNumber,
  1273. Relation.Pointer,
  1274. Relation.OwningFile->SourceFile,
  1275. Relation.TypeNumber,
  1276. Relation.Array.Minimum,
  1277. Relation.Array.Maximum,
  1278. Relation.Array.MaxUlonglong);
  1279. } else {
  1280. STABS_DEBUG("New Relational Type: %s:(%s,%d). Pointer: %d, "
  1281. "Reference Type: (%s, %d)\n",
  1282. TypeName,
  1283. TypeOwner->SourceFile,
  1284. TypeNumber,
  1285. Relation.Pointer,
  1286. Relation.OwningFile->SourceFile,
  1287. Relation.TypeNumber);
  1288. }
  1289. //
  1290. // Set the local and type pointer.
  1291. //
  1292. Type = DataTypeRelation;
  1293. LocalData = (PVOID)&Relation;
  1294. LocalDataSize = sizeof(DATA_TYPE_RELATION);
  1295. //
  1296. // An 'r' indicates that this type is a subrange of another type, and is an
  1297. // integer type.
  1298. //
  1299. } else if (*String == 'r') {
  1300. //
  1301. // Skip past the type descriptor.
  1302. //
  1303. while ((*String != ';') && (*String != '\0')) {
  1304. String += 1;
  1305. }
  1306. if (*String == '\0') {
  1307. String = NULL;
  1308. goto CreateTypeEnd;
  1309. }
  1310. //
  1311. // Parse the range parameters. Ranges take the form 'rType;min;max;',
  1312. // where Type is the original type the subrange is taken from, min and
  1313. // max are the ranges minimum and maximum, inclusive.
  1314. //
  1315. String += 1;
  1316. String = DbgpParseRange(String, &Range);
  1317. if (String == NULL) {
  1318. goto CreateTypeEnd;
  1319. }
  1320. //
  1321. // Estimate the type based on the range given.
  1322. //
  1323. Result = DbgpRangeToNumericType(&Range, &Numeric);
  1324. if (Result == FALSE) {
  1325. String = NULL;
  1326. goto CreateTypeEnd;
  1327. }
  1328. //
  1329. // If an explicit size was specifed using '@' attributes, plug those in
  1330. // now.
  1331. //
  1332. if (TypeSize != 0) {
  1333. Numeric.BitSize = TypeSize;
  1334. }
  1335. STABS_DEBUG("New Numeric Type: %s:(%s,%d). Float: %d, Signed: %d, "
  1336. "Size: %d\n",
  1337. TypeName,
  1338. TypeOwner->SourceFile,
  1339. TypeNumber,
  1340. Numeric.Float,
  1341. Numeric.Signed,
  1342. Numeric.BitSize);
  1343. //
  1344. // Set the local type and pointer.
  1345. //
  1346. Type = DataTypeNumeric;
  1347. LocalData = (PVOID)&Numeric;
  1348. LocalDataSize = sizeof(DATA_TYPE_NUMERIC);
  1349. //
  1350. // An 'R' indicates a floating point type.
  1351. //
  1352. } else if (*String == 'R') {
  1353. ValuesRead = sscanf(String, "R%d;%d", &FloatType, &FloatSize);
  1354. if (ValuesRead != 2) {
  1355. String = NULL;
  1356. goto CreateTypeEnd;
  1357. }
  1358. //
  1359. // A float type of 1 is a 32-bit single precision, and 2 is a 64-bit
  1360. // double precision. With any other float type, take the next field
  1361. // to be the size of the float in bytes.
  1362. //
  1363. Numeric.Float = TRUE;
  1364. if (FloatType == 1) {
  1365. Numeric.BitSize = 32;
  1366. } else if (FloatType == 2) {
  1367. Numeric.BitSize = 64;
  1368. } else {
  1369. Numeric.BitSize = 8 * FloatSize;
  1370. }
  1371. STABS_DEBUG("New Float Type: %s:(%s,%d). Size: %d\n",
  1372. TypeName,
  1373. TypeOwner->SourceFile,
  1374. TypeNumber,
  1375. Numeric.BitSize);
  1376. //
  1377. // Set the local type and pointer.
  1378. //
  1379. Type = DataTypeNumeric;
  1380. LocalData = (PVOID)&Numeric;
  1381. LocalDataSize = sizeof(DATA_TYPE_NUMERIC);
  1382. //
  1383. // An 's' indicates that this type is a structure. A 'u' indicates a union,
  1384. // which is treated the same as a structure
  1385. //
  1386. } else if ((*String == 's') || (*String == 'u')) {
  1387. //
  1388. // Immediately following the 's' is the size of the structure in bytes.
  1389. //
  1390. String += 1;
  1391. ValuesRead = sscanf(String, "%d", &(Structure.SizeInBytes));
  1392. if (ValuesRead != 1) {
  1393. String = NULL;
  1394. goto CreateTypeEnd;
  1395. }
  1396. //
  1397. // Skip past the 's' and the size in bytes.
  1398. //
  1399. while ((*String >= '0') && (*String <= '9')) {
  1400. String += 1;
  1401. }
  1402. STABS_DEBUG("New Structure Type: %s:(%s,%d). Size: %d\n",
  1403. TypeName,
  1404. TypeOwner->SourceFile,
  1405. TypeNumber,
  1406. Structure.SizeInBytes);
  1407. //
  1408. // Parse through each structure member, updating the main string each
  1409. // time a structure member was successfully found.
  1410. //
  1411. StructureString = String;
  1412. while (StructureString != NULL) {
  1413. StructureString = DbgpParseStructureMember(Symbols,
  1414. StructureString,
  1415. &LocalStructureMember);
  1416. if (StructureString != NULL) {
  1417. //
  1418. // Allocate a new structure member and copy the local data into
  1419. // it.
  1420. //
  1421. NewStructureMember = MALLOC(sizeof(STRUCTURE_MEMBER));
  1422. if (NewStructureMember == NULL) {
  1423. if (LocalStructureMember.Name != NULL) {
  1424. FREE(LocalStructureMember.Name);
  1425. }
  1426. String = NULL;
  1427. goto CreateTypeEnd;
  1428. }
  1429. memcpy(NewStructureMember,
  1430. &LocalStructureMember,
  1431. sizeof(STRUCTURE_MEMBER));
  1432. //
  1433. // Link up the new structure member.
  1434. //
  1435. if (CurrentStructureMember == NULL) {
  1436. Structure.FirstMember = NewStructureMember;
  1437. } else {
  1438. CurrentStructureMember->NextMember = NewStructureMember;
  1439. }
  1440. CurrentStructureMember = NewStructureMember;
  1441. CurrentStructureMember->NextMember = NULL;
  1442. Structure.MemberCount += 1;
  1443. String = StructureString;
  1444. STABS_DEBUG("\t+%d, %d: %s (%s, %d)\n",
  1445. LocalStructureMember.BitOffset,
  1446. LocalStructureMember.BitSize,
  1447. LocalStructureMember.Name,
  1448. LocalStructureMember.TypeFile->SourceFile,
  1449. LocalStructureMember.TypeNumber);
  1450. }
  1451. }
  1452. //
  1453. // Move past the ending semicolon for the structure definition.
  1454. //
  1455. String += 1;
  1456. //
  1457. // Set the local type and data pointer.
  1458. //
  1459. Type = DataTypeStructure;
  1460. LocalData = (PVOID)&Structure;
  1461. LocalDataSize = sizeof(DATA_TYPE_STRUCTURE);
  1462. //
  1463. // An 'e' indicates that this type is an enumeration.
  1464. //
  1465. } else if (*String == 'e') {
  1466. STABS_DEBUG("New Enumeration Type: %s:(%s,%d)\n",
  1467. TypeName,
  1468. TypeOwner->SourceFile,
  1469. TypeNumber);
  1470. String += 1;
  1471. EnumerationString = String;
  1472. while (EnumerationString != NULL) {
  1473. EnumerationString = DbgpParseEnumerationMember(
  1474. EnumerationString,
  1475. &LocalEnumerationMember);
  1476. if (EnumerationString != NULL) {
  1477. //
  1478. // Allocate space for the new member and copy the data to that
  1479. // new buffer.
  1480. //
  1481. NewEnumerationMember = MALLOC(sizeof(ENUMERATION_MEMBER));
  1482. if (NewEnumerationMember == NULL) {
  1483. if (LocalEnumerationMember.Name != NULL) {
  1484. FREE(LocalEnumerationMember.Name);
  1485. }
  1486. String = NULL;
  1487. goto CreateTypeEnd;
  1488. }
  1489. memcpy(NewEnumerationMember,
  1490. &LocalEnumerationMember,
  1491. sizeof(ENUMERATION_MEMBER));
  1492. //
  1493. // Link up the new enumeration member.
  1494. //
  1495. if (CurrentEnumerationMember == NULL) {
  1496. Enumeration.FirstMember = NewEnumerationMember;
  1497. } else {
  1498. CurrentEnumerationMember->NextMember = NewEnumerationMember;
  1499. }
  1500. CurrentEnumerationMember = NewEnumerationMember;
  1501. NewEnumerationMember->NextMember = NULL;
  1502. Enumeration.MemberCount += 1;
  1503. String = EnumerationString;
  1504. STABS_DEBUG("\t%s = %d\n",
  1505. LocalEnumerationMember.Name,
  1506. LocalEnumerationMember.Value);
  1507. }
  1508. }
  1509. //
  1510. // Skip over the ending semicolon.
  1511. //
  1512. String += 1;
  1513. //
  1514. // Assume all enumerations are 4 bytes since there's no other
  1515. // information to go on.
  1516. //
  1517. Enumeration.SizeInBytes = 4;
  1518. //
  1519. // Set the local type and data pointer.
  1520. //
  1521. Type = DataTypeEnumeration;
  1522. LocalData = (PVOID)&Enumeration;
  1523. LocalDataSize = sizeof(DATA_TYPE_ENUMERATION);
  1524. } else {
  1525. //
  1526. // This case indicates an unexpected type descriptor was encountered.
  1527. // Fail the creation here.
  1528. //
  1529. String = NULL;
  1530. goto CreateTypeEnd;
  1531. }
  1532. //
  1533. // If a new type was successfully parsed, create the memory for it and add
  1534. // it to the current module's type list.
  1535. //
  1536. if (Type != DataTypeInvalid) {
  1537. assert(LocalData != NULL);
  1538. assert(LocalDataSize != 0);
  1539. NewType = MALLOC(sizeof(TYPE_SYMBOL));
  1540. if (NewType == NULL) {
  1541. String = NULL;
  1542. goto CreateTypeEnd;
  1543. }
  1544. memset(NewType, 0, sizeof(TYPE_SYMBOL));
  1545. memcpy(&(NewType->U), LocalData, LocalDataSize);
  1546. NewType->ParentSource = TypeOwner;
  1547. NewType->ParentFunction = NULL;
  1548. NewType->Name = TypeName;
  1549. NewType->TypeNumber = TypeNumber;
  1550. NewType->Type = Type;
  1551. INSERT_AFTER(&(NewType->ListEntry),
  1552. &(TypeOwner->TypesHead));
  1553. }
  1554. CreateTypeEnd:
  1555. if (String == NULL) {
  1556. //
  1557. // Clean up partial structure members.
  1558. //
  1559. CurrentStructureMember = Structure.FirstMember;
  1560. while (CurrentStructureMember != NULL) {
  1561. NextStructureMember = CurrentStructureMember->NextMember;
  1562. if (CurrentStructureMember->Name != NULL) {
  1563. FREE(CurrentStructureMember->Name);
  1564. }
  1565. FREE(CurrentStructureMember);
  1566. CurrentStructureMember = NextStructureMember;
  1567. }
  1568. if (NewType != NULL) {
  1569. FREE(NewType);
  1570. }
  1571. //
  1572. // Clean up partial enumeration members.
  1573. //
  1574. CurrentEnumerationMember = Enumeration.FirstMember;
  1575. while (CurrentEnumerationMember != NULL) {
  1576. NextEnumerationMember = CurrentEnumerationMember->NextMember;
  1577. if (CurrentEnumerationMember->Name != NULL) {
  1578. FREE(CurrentEnumerationMember->Name);
  1579. }
  1580. FREE(CurrentEnumerationMember);
  1581. CurrentEnumerationMember = NextEnumerationMember;
  1582. }
  1583. }
  1584. return String;
  1585. }
  1586. PSTR
  1587. DbgpParseEnumerationMember (
  1588. PSTR String,
  1589. PENUMERATION_MEMBER Member
  1590. )
  1591. /*++
  1592. Routine Description:
  1593. This routine parses an enumeration member from a stab string. The caller is
  1594. responsible for freeing memory that will be allocated to hold the name
  1595. parameter for the enumeration member.
  1596. Arguments:
  1597. String - Supplies the string containing the structure member.
  1598. Member - Supplies a pointer to where the enumeration data should be written.
  1599. It is assumed this structure has been allocated by the caller.
  1600. Return Value:
  1601. Returns the String parameter, advanced by as much as the enumeration member
  1602. took up, or NULL on failure.
  1603. --*/
  1604. {
  1605. PSTR CurrentPosition;
  1606. PSTR NameEnd;
  1607. if ((String == NULL) || (Member == NULL)) {
  1608. return NULL;
  1609. }
  1610. //
  1611. // A semicolon indicates the end of the enumeration definition has been
  1612. // reached.
  1613. //
  1614. if (*String == ';') {
  1615. return NULL;
  1616. }
  1617. //
  1618. // Zip past the end of the string. Unlike a structure member, in this case
  1619. // double colons are not a concern, any colon ends the name.
  1620. //
  1621. CurrentPosition = String;
  1622. while ((*CurrentPosition != '\0') && (*CurrentPosition != ':')) {
  1623. CurrentPosition += 1;
  1624. }
  1625. if (*CurrentPosition == '\0') {
  1626. return NULL;
  1627. }
  1628. //
  1629. // Save the location of the end of the name, and get the value.
  1630. //
  1631. NameEnd = CurrentPosition;
  1632. Member->Value = strtoll(NameEnd + 1, NULL, 10);
  1633. //
  1634. // The enumeration member is terminated with a comma. Find the end.
  1635. //
  1636. while ((*CurrentPosition != '\0') && (*CurrentPosition != ',')) {
  1637. CurrentPosition += 1;
  1638. }
  1639. if (*CurrentPosition == '\0') {
  1640. return NULL;
  1641. }
  1642. CurrentPosition += 1;
  1643. Member->Name = MALLOC(NameEnd - String + 1);
  1644. if (Member->Name == NULL) {
  1645. return NULL;
  1646. }
  1647. strncpy(Member->Name, String, NameEnd - String);
  1648. Member->Name[NameEnd - String] = '\0';
  1649. return CurrentPosition;
  1650. }
  1651. PSTR
  1652. DbgpParseStructureMember (
  1653. PDEBUG_SYMBOLS Symbols,
  1654. PSTR String,
  1655. PSTRUCTURE_MEMBER Member
  1656. )
  1657. /*++
  1658. Routine Description:
  1659. This routine parses a structure member from a stab string. The caller is
  1660. responsible for freeing memory that will be allocated to hold the name
  1661. parameter for the structure member.
  1662. Arguments:
  1663. Symbols - Supplies a pointer to the current module.
  1664. String - Supplies the string containing the structure member.
  1665. Member - Supplies a pointer to where the structure data should be written.
  1666. It is assumed this structure has been allocated by the caller.
  1667. Return Value:
  1668. Returns the String parameter, advanced by the amount the structure member
  1669. took up, or NULL on failure.
  1670. --*/
  1671. {
  1672. PSTR CurrentPosition;
  1673. PSTR NameEnd;
  1674. INT ValuesRead;
  1675. CurrentPosition = String;
  1676. //
  1677. // Parameter checking.
  1678. //
  1679. if ((Symbols == NULL) || (String == NULL) || (Member == NULL) ||
  1680. (Symbols == NULL) || (*String == ';')) {
  1681. return NULL;
  1682. }
  1683. //
  1684. // Zip past the string name. Two colons can still be part of a name, so make
  1685. // sure to terminate only on a single colon.
  1686. //
  1687. while (*CurrentPosition != '\0') {
  1688. if (*CurrentPosition == ':') {
  1689. if ((*(CurrentPosition - 1) != ':') &&
  1690. (*(CurrentPosition + 1) != ':')) {
  1691. break;
  1692. }
  1693. }
  1694. CurrentPosition += 1;
  1695. }
  1696. if (*CurrentPosition == '\0') {
  1697. return NULL;
  1698. }
  1699. //
  1700. // Save the location of the end of the Name, and get the type associated
  1701. // with this member.
  1702. //
  1703. NameEnd = CurrentPosition;
  1704. CurrentPosition += 1;
  1705. CurrentPosition = DbgpGetTypeNumber(Symbols,
  1706. NULL,
  1707. CurrentPosition,
  1708. &(Member->TypeFile),
  1709. &(Member->TypeNumber));
  1710. if (CurrentPosition == NULL) {
  1711. return NULL;
  1712. }
  1713. //
  1714. // Get the bit offset into the structure and bit size for this structure
  1715. // member.
  1716. //
  1717. ValuesRead = sscanf(CurrentPosition,
  1718. ",%d,%d",
  1719. &(Member->BitOffset),
  1720. &(Member->BitSize));
  1721. if (ValuesRead != 2) {
  1722. return NULL;
  1723. }
  1724. //
  1725. // Find the end of the string.
  1726. //
  1727. while ((*CurrentPosition != '\0') && (*CurrentPosition != ';')) {
  1728. CurrentPosition += 1;
  1729. }
  1730. if (*CurrentPosition == '\0') {
  1731. return NULL;
  1732. }
  1733. CurrentPosition += 1;
  1734. //
  1735. // Allocate memory for the name string and copy the name over.
  1736. //
  1737. Member->Name = MALLOC(NameEnd - String + 1);
  1738. if (Member->Name == NULL) {
  1739. return NULL;
  1740. }
  1741. strncpy(Member->Name, String, NameEnd - String);
  1742. Member->Name[NameEnd - String] = '\0';
  1743. return CurrentPosition;
  1744. }
  1745. PSTR
  1746. DbgpParseRange (
  1747. PSTR String,
  1748. PDATA_RANGE Range
  1749. )
  1750. /*++
  1751. Routine Description:
  1752. This routine parses a range type from a string and puts it into a structure
  1753. allocated by the caller.
  1754. Arguments:
  1755. String - Supplies the string containing the range.
  1756. Range - Supplies a pointer to the range structure where the information is
  1757. returned.
  1758. Return Value:
  1759. Returns the amount the String parameter was advanced to parse the range, or
  1760. NULL on failure.
  1761. --*/
  1762. {
  1763. PSTR MaximumEnd;
  1764. PSTR MaximumStart;
  1765. CHAR MaximumString[MAX_RANGE_STRING];
  1766. CHAR MinimumString[MAX_RANGE_STRING];
  1767. ULONG StringSize;
  1768. if ((String == NULL) || (Range == NULL)) {
  1769. return NULL;
  1770. }
  1771. //
  1772. // Find the boundaries of the two strings, and copy them into separate
  1773. // buffers.
  1774. //
  1775. MaximumStart = strchr(String, ';');
  1776. if (MaximumStart == NULL) {
  1777. return NULL;
  1778. }
  1779. StringSize = MaximumStart - String;
  1780. if ((StringSize >= MAX_RANGE_STRING) || (StringSize == 0)) {
  1781. return NULL;
  1782. }
  1783. strncpy(MinimumString, String, StringSize);
  1784. MinimumString[StringSize] = '\0';
  1785. MaximumStart += 1;
  1786. MaximumEnd = strchr(MaximumStart, ';');
  1787. if (MaximumEnd == NULL) {
  1788. return NULL;
  1789. }
  1790. StringSize = MaximumEnd - MaximumStart;
  1791. if ((StringSize >= MAX_RANGE_STRING) || (StringSize == 0)) {
  1792. return NULL;
  1793. }
  1794. strncpy(MaximumString, MaximumStart, StringSize);
  1795. MaximumString[StringSize] = '\0';
  1796. //
  1797. // Determine if the maximum is the max of a ULONGLONG, which cannot be
  1798. // stored in the given structure.
  1799. //
  1800. if (strcmp(MaximumString, "01777777777777777777777") == 0) {
  1801. Range->MaxUlonglong = TRUE;
  1802. } else {
  1803. Range->MaxUlonglong = FALSE;
  1804. }
  1805. //
  1806. // Read the values in.
  1807. //
  1808. Range->Minimum = strtoll(MinimumString, NULL, 0);
  1809. Range->Maximum = strtoll(MaximumString, NULL, 0);
  1810. if (Range->MaxUlonglong == TRUE) {
  1811. Range->Maximum = 0;
  1812. }
  1813. //
  1814. // There also seems to be a problem with signed 64 bit extremes. Check those
  1815. // explicitly.
  1816. //
  1817. if (strcmp(MaximumString, "0777777777777777777777") == 0) {
  1818. Range->Maximum = MAX_LONGLONG;
  1819. }
  1820. if (strcmp(MinimumString, "01000000000000000000000") == 0) {
  1821. Range->Minimum = MIN_LONGLONG;
  1822. }
  1823. return MaximumEnd + 1;
  1824. }
  1825. BOOL
  1826. DbgpRangeToNumericType (
  1827. PDATA_RANGE Range,
  1828. PDATA_TYPE_NUMERIC Numeric
  1829. )
  1830. /*++
  1831. Routine Description:
  1832. This routine estimates a numeric type based on the given range by comparing
  1833. the range to well known values.
  1834. Arguments:
  1835. Range - Supplies a pointer to the range structure.
  1836. Numeric - Supplies a pointer to a preallocated structure where the type
  1837. information should be returned.
  1838. Return Value:
  1839. TRUE on success.
  1840. FALSE on failure.
  1841. --*/
  1842. {
  1843. if ((Range == NULL) || (Numeric == NULL)) {
  1844. return FALSE;
  1845. }
  1846. if (Range->Minimum < 0) {
  1847. Numeric->Signed = TRUE;
  1848. } else {
  1849. Numeric->Signed = FALSE;
  1850. }
  1851. //
  1852. // Find the first range that fits.
  1853. //
  1854. if (Range->Maximum <= MAX_UCHAR) {
  1855. Numeric->BitSize = sizeof(UCHAR) * BITS_PER_BYTE;
  1856. } else if (Range->Maximum <= MAX_USHORT) {
  1857. Numeric->BitSize = sizeof(USHORT) * BITS_PER_BYTE;
  1858. } else if (Range->Maximum <= MAX_ULONG) {
  1859. Numeric->BitSize = sizeof(ULONG) * BITS_PER_BYTE;
  1860. } else if (Range->Maximum <= MAX_ULONGLONG) {
  1861. Numeric->BitSize = sizeof(ULONGLONG) * BITS_PER_BYTE;
  1862. }
  1863. //
  1864. // A maximum range of 0 and a positive minimum range indicates that the type
  1865. // is floating point. The size is indicated by the minimum, in bytes.
  1866. //
  1867. if ((Range->Maximum == 0) && (Range->Minimum > 0)) {
  1868. Numeric->Float = TRUE;
  1869. Numeric->BitSize = Range->Minimum * 8;
  1870. } else {
  1871. Numeric->Float = FALSE;
  1872. }
  1873. return TRUE;
  1874. }
  1875. PSTR
  1876. DbgpGetTypeNumber (
  1877. PDEBUG_SYMBOLS Symbols,
  1878. PSTR Name,
  1879. PSTR String,
  1880. PSOURCE_FILE_SYMBOL *OwningFile,
  1881. PLONG TypeNumber
  1882. )
  1883. /*++
  1884. Routine Description:
  1885. This routine parses a type reference string, returning the file number and
  1886. type number. In its parsing it may add new types as it discovers their
  1887. definitions.
  1888. Arguments:
  1889. Symbols - Supplies a pointer to the current module.
  1890. Name - Supplies the name of the type. If the type is about to be defined,
  1891. this parameter is passed along an attributed to the new type. Otherwise
  1892. it is unused.
  1893. String - Supplies the string containing the type number.
  1894. OwningFile - Supplies a pointer where the file owning this symbol is
  1895. returned on success.
  1896. TypeNumber - Supplies a pointer where the type number is returned.
  1897. Return Value:
  1898. Returns the string advanced past the type, or NULL on any failure.
  1899. --*/
  1900. {
  1901. PINCLUDE_STACK_ELEMENT CurrentIncludeElement;
  1902. PSTR EndBuiltinString;
  1903. PSTR EndString;
  1904. ULONG IncludeFileNumber;
  1905. INT MatchedItems;
  1906. PSOURCE_FILE_SYMBOL Owner;
  1907. PSOURCE_FILE_SYMBOL PotentialOwner;
  1908. PSTAB_CONTEXT State;
  1909. LONG Type;
  1910. if ((String == NULL) || (strlen(String) == 0)) {
  1911. return FALSE;
  1912. }
  1913. EndString = String;
  1914. State = Symbols->SymbolContext;
  1915. //
  1916. // The form is either simply a type number or "(x,y)", where x specifies a
  1917. // file number in the include stack, and y is the type number.
  1918. //
  1919. if (String[0] == '(') {
  1920. MatchedItems = sscanf(String,
  1921. "(%d,%d)",
  1922. &IncludeFileNumber,
  1923. &Type);
  1924. if (MatchedItems != 2) {
  1925. return NULL;
  1926. }
  1927. while (*EndString != ')') {
  1928. EndString += 1;
  1929. }
  1930. EndString += 1;
  1931. } else {
  1932. IncludeFileNumber = 0;
  1933. MatchedItems = sscanf(String, "%d", &Type);
  1934. if (MatchedItems != 1) {
  1935. return NULL;
  1936. }
  1937. if (*EndString == '-') {
  1938. EndString += 1;
  1939. }
  1940. while ((*EndString >= '0') && (*EndString <= '9')) {
  1941. EndString += 1;
  1942. }
  1943. if (*EndString == ';') {
  1944. EndString += 1;
  1945. }
  1946. }
  1947. //
  1948. // Based on the include file number, get the owning source file.
  1949. //
  1950. if (IncludeFileNumber == 0) {
  1951. Owner = State->CurrentSourceFile;
  1952. } else if (IncludeFileNumber <= State->MaxIncludeIndex) {
  1953. Owner = NULL;
  1954. CurrentIncludeElement = State->IncludeStack;
  1955. while (CurrentIncludeElement != NULL) {
  1956. PotentialOwner = CurrentIncludeElement->IncludeFile;
  1957. if (CurrentIncludeElement->Index == IncludeFileNumber) {
  1958. Owner = PotentialOwner;
  1959. break;
  1960. }
  1961. CurrentIncludeElement = CurrentIncludeElement->NextElement;
  1962. }
  1963. if (Owner == NULL) {
  1964. return NULL;
  1965. }
  1966. } else {
  1967. DbgOut("Invalid Include Number: (%d, %d), Max include: %d\n",
  1968. IncludeFileNumber,
  1969. Type,
  1970. State->MaxIncludeIndex);
  1971. return NULL;
  1972. }
  1973. //
  1974. // If the type being referenced is also being defined, create that type now.
  1975. //
  1976. if (*EndString == '=') {
  1977. EndString += 1;
  1978. EndString = DbgpCreateType(Symbols,
  1979. Name,
  1980. Owner,
  1981. Type,
  1982. EndString);
  1983. if (EndString == NULL) {
  1984. return NULL;
  1985. }
  1986. }
  1987. //
  1988. // If a builtin type is being referenced, create that builtin type now.
  1989. //
  1990. if (Type < 0) {
  1991. if (Type == BUILTIN_TYPE_BOOL) {
  1992. EndBuiltinString = DbgpCreateType(Symbols,
  1993. NULL,
  1994. Owner,
  1995. BUILTIN_TYPE_BOOL,
  1996. BUILTIN_TYPE_BOOL_STRING);
  1997. assert(EndBuiltinString != NULL);
  1998. }
  1999. }
  2000. //
  2001. // If the owning file and type parameter were passed, set those variables
  2002. // now.
  2003. //
  2004. if (OwningFile != NULL) {
  2005. *OwningFile = Owner;
  2006. }
  2007. if (TypeNumber != NULL) {
  2008. *TypeNumber = Type;
  2009. }
  2010. return EndString;
  2011. }
  2012. BOOL
  2013. DbgpParseSourceFileStab (
  2014. PDEBUG_SYMBOLS Symbols,
  2015. PRAW_STAB Stab,
  2016. PSTR StabString,
  2017. BOOL Include
  2018. )
  2019. /*++
  2020. Routine Description:
  2021. This routine parses through a source or begin include file stab, updating
  2022. the output symbol information as well as the parse state.
  2023. Arguments:
  2024. Symbols - Supplies a pointer to the symbols data. The raw stab data should
  2025. already be loaded, and the parse state pointer should not be null.
  2026. Also returns the initialized data.
  2027. Stab - Supplies a pointer to the stab of type STAB_SOURCE_FILE,
  2028. STAB_INCLUDE_BEGIN, or STAB_INCLUDE_PLACEHOLDER.
  2029. StabString - Supplies a pointer to the stab's string, or NULL if the stab
  2030. has no string.
  2031. Include - Supplies whether or not this is an include file or a main source
  2032. file.
  2033. Return Value:
  2034. TRUE on success.
  2035. FALSE on failure.
  2036. --*/
  2037. {
  2038. PINCLUDE_STACK_ELEMENT CurrentIncludeElement;
  2039. PLIST_ENTRY CurrentSourceEntry;
  2040. ULONGLONG EndAddress;
  2041. LONG FilenameCompare;
  2042. BOOL FoundExistingFile;
  2043. PINCLUDE_STACK_ELEMENT NewIncludeElement;
  2044. PSOURCE_FILE_SYMBOL NewSource;
  2045. PINCLUDE_STACK_ELEMENT NextIncludeElement;
  2046. BOOL PathFullySpecified;
  2047. PSOURCE_FILE_SYMBOL PotentialSource;
  2048. BOOL Result;
  2049. PSTAB_CONTEXT State;
  2050. ULONG StringLength;
  2051. NewSource = NULL;
  2052. PathFullySpecified = FALSE;
  2053. //
  2054. // Parameter checking.
  2055. //
  2056. if ((Symbols == NULL) || (Symbols->SymbolContext == NULL) ||
  2057. ((Stab != NULL) &&
  2058. (Stab->Type != STAB_SOURCE_FILE) &&
  2059. (Stab->Type != STAB_INCLUDE_BEGIN) &&
  2060. (Stab->Type != STAB_INCLUDE_PLACEHOLDER) &&
  2061. (Stab->Type != STAB_INCLUDE_NAME))) {
  2062. return FALSE;
  2063. }
  2064. State = Symbols->SymbolContext;
  2065. //
  2066. // The current source file, line or function may be terminated, so
  2067. // calculate the best estimate to use for where those lines/files/functions
  2068. // end.
  2069. //
  2070. EndAddress = 0;
  2071. if (Stab != NULL) {
  2072. EndAddress = Stab->Value;
  2073. }
  2074. //
  2075. // Figure out if the path was completely specified in the string or if
  2076. // the current directory should be examined as well.
  2077. //
  2078. if ((StabString != NULL) &&
  2079. ((StabString[0] == '/') || (strchr(StabString, ':') != NULL))) {
  2080. PathFullySpecified = TRUE;
  2081. }
  2082. //
  2083. // If the file is an include file, attempt to find it in the existing
  2084. // includes.
  2085. //
  2086. FoundExistingFile = FALSE;
  2087. if (StabString != NULL) {
  2088. CurrentSourceEntry = Symbols->SourcesHead.Next;
  2089. while (CurrentSourceEntry != &(Symbols->SourcesHead)) {
  2090. PotentialSource = LIST_VALUE(CurrentSourceEntry,
  2091. SOURCE_FILE_SYMBOL,
  2092. ListEntry);
  2093. assert(CurrentSourceEntry != NULL);
  2094. assert(PotentialSource->SourceFile != NULL);
  2095. CurrentSourceEntry = CurrentSourceEntry->Next;
  2096. //
  2097. // If the identifiers don't line up, skip it.
  2098. //
  2099. if (Stab->Value != PotentialSource->Identifier) {
  2100. continue;
  2101. }
  2102. //
  2103. // Compare the file names as well.
  2104. //
  2105. FilenameCompare = strcmp(StabString, PotentialSource->SourceFile);
  2106. if (FilenameCompare != 0) {
  2107. continue;
  2108. }
  2109. NewSource = PotentialSource;
  2110. FoundExistingFile = TRUE;
  2111. break;
  2112. }
  2113. }
  2114. //
  2115. // Wrap up the current source file if it's not an include.
  2116. //
  2117. if (Include == FALSE) {
  2118. //
  2119. // Remember how far the current file has come.
  2120. //
  2121. if ((State->CurrentSourceLineFile != NULL) &&
  2122. (EndAddress > State->CurrentSourceLineFile->EndAddress)) {
  2123. State->CurrentSourceLineFile->EndAddress = EndAddress;
  2124. }
  2125. if ((State->CurrentSourceFile != NULL) &&
  2126. (EndAddress > State->CurrentSourceFile->EndAddress)) {
  2127. State->CurrentSourceFile->EndAddress = EndAddress;
  2128. }
  2129. if ((Stab == NULL) || (Stab->Type != STAB_INCLUDE_NAME)) {
  2130. if (State->CurrentSourceFile != NULL) {
  2131. //
  2132. // The source line file should always be valid if the current
  2133. // source file is.
  2134. //
  2135. assert(State->CurrentSourceLineFile != NULL);
  2136. //
  2137. // Start by resolving all the cross references in this file.
  2138. //
  2139. Result = DbgpResolveCrossReferences(State);
  2140. if (Result == FALSE) {
  2141. goto ParseSourceFileStabEnd;
  2142. }
  2143. State->CurrentSourceFile = NULL;
  2144. State->CurrentSourceLineFile = NULL;
  2145. }
  2146. //
  2147. // Wrap up the current function.
  2148. //
  2149. if (State->CurrentFunction != NULL) {
  2150. State->CurrentFunction->EndAddress = EndAddress;
  2151. State->CurrentFunction = NULL;
  2152. }
  2153. //
  2154. // Reset the include stack. Each source file has its own include
  2155. // stack.
  2156. //
  2157. CurrentIncludeElement = State->IncludeStack;
  2158. while (CurrentIncludeElement != NULL) {
  2159. NextIncludeElement = CurrentIncludeElement->NextElement;
  2160. FREE(CurrentIncludeElement);
  2161. CurrentIncludeElement = NextIncludeElement;
  2162. }
  2163. State->IncludeStack = NULL;
  2164. State->MaxBraceAddress = 0;
  2165. State->MaxIncludeIndex = 0;
  2166. }
  2167. //
  2168. // Wrap up the current line, even for include names.
  2169. //
  2170. if (State->CurrentSourceLine != NULL) {
  2171. State->CurrentSourceLine->End = EndAddress;
  2172. if (State->CurrentSourceLine->Start > EndAddress) {
  2173. State->CurrentSourceLine->End = State->CurrentSourceLine->Start;
  2174. }
  2175. State->CurrentSourceLine = NULL;
  2176. }
  2177. }
  2178. //
  2179. // If the stab has no string, it terminates the current source file. Since
  2180. // that's what just happened, there is nothing more to do. Include Name
  2181. // stabs should not use this mechanism.
  2182. //
  2183. if ((StabString == NULL) || (strlen(StabString) == 0)) {
  2184. if ((Stab != NULL) && (Stab->Type == STAB_INCLUDE_NAME)) {
  2185. Result = FALSE;
  2186. } else {
  2187. Result = TRUE;
  2188. }
  2189. goto ParseSourceFileStabEnd;
  2190. }
  2191. //
  2192. // If the stab has a slash at the end, it is a source directory stab.
  2193. // Update the current directory with this new stab's string.
  2194. //
  2195. StringLength = strlen(StabString);
  2196. if (StabString[StringLength - 1] == '/') {
  2197. State->CurrentSourceDirectory = StabString;
  2198. Result = TRUE;
  2199. goto ParseSourceFileStabEnd;
  2200. }
  2201. //
  2202. // If a new source file hasn't been allocated by this point, allocate one
  2203. // now.
  2204. //
  2205. if (NewSource == NULL) {
  2206. NewSource = MALLOC(sizeof(SOURCE_FILE_SYMBOL));
  2207. }
  2208. if (NewSource == NULL) {
  2209. Result = FALSE;
  2210. goto ParseSourceFileStabEnd;
  2211. }
  2212. if (FoundExistingFile == FALSE) {
  2213. memset(NewSource, 0, sizeof(SOURCE_FILE_SYMBOL));
  2214. if (PathFullySpecified == FALSE) {
  2215. NewSource->SourceDirectory = State->CurrentSourceDirectory;
  2216. }
  2217. NewSource->SourceFile = StabString;
  2218. INITIALIZE_LIST_HEAD(&(NewSource->SourceLinesHead));
  2219. INITIALIZE_LIST_HEAD(&(NewSource->DataSymbolsHead));
  2220. INITIALIZE_LIST_HEAD(&(NewSource->FunctionsHead));
  2221. INITIALIZE_LIST_HEAD(&(NewSource->TypesHead));
  2222. NewSource->StartAddress = Stab->Value;
  2223. //
  2224. // The stab value is used to match EXCL stabs to the includes (BINCL)
  2225. // they reference.
  2226. //
  2227. NewSource->Identifier = Stab->Value;
  2228. }
  2229. //
  2230. // If the file is an include, add it to the include stack.
  2231. //
  2232. if (Include != FALSE) {
  2233. State->MaxIncludeIndex += 1;
  2234. if (FoundExistingFile == FALSE) {
  2235. NewSource->StartAddress = 0;
  2236. NewSource->EndAddress = 0;
  2237. }
  2238. NewIncludeElement = MALLOC(sizeof(INCLUDE_STACK_ELEMENT));
  2239. if (NewIncludeElement == NULL) {
  2240. Result = FALSE;
  2241. goto ParseSourceFileStabEnd;
  2242. }
  2243. NewIncludeElement->IncludeFile = NewSource;
  2244. NewIncludeElement->Index = State->MaxIncludeIndex;
  2245. NewIncludeElement->NextElement = State->IncludeStack;
  2246. State->IncludeStack = NewIncludeElement;
  2247. }
  2248. //
  2249. // Add the new source file to the current module at the front of the list.
  2250. //
  2251. assert(State->CurrentModule != NULL);
  2252. if (FoundExistingFile == FALSE) {
  2253. INSERT_AFTER(&(NewSource->ListEntry),
  2254. &(State->CurrentModule->SourcesHead));
  2255. }
  2256. //
  2257. // Include name stabs only affect source lines, not other symbols. All other
  2258. // non-include source file stabs affect the main source file.
  2259. //
  2260. if (Stab->Type == STAB_INCLUDE_NAME) {
  2261. assert(State->CurrentSourceFile != NULL);
  2262. if (NewSource->StartAddress == 0) {
  2263. NewSource->StartAddress = State->CurrentSourceFile->StartAddress;
  2264. }
  2265. State->CurrentSourceLineFile = NewSource;
  2266. } else if (Include == FALSE) {
  2267. State->CurrentSourceFile = NewSource;
  2268. State->CurrentSourceLineFile = NewSource;
  2269. State->MaxBraceAddress = NewSource->StartAddress;
  2270. }
  2271. Result = TRUE;
  2272. ParseSourceFileStabEnd:
  2273. return Result;
  2274. }
  2275. BOOL
  2276. DbgpParseSourceLineStab (
  2277. PDEBUG_SYMBOLS Symbols,
  2278. PRAW_STAB Stab,
  2279. PSTR StabString
  2280. )
  2281. /*++
  2282. Routine Description:
  2283. This routine parses through a source line stab, updating the output symbol
  2284. information as well as the parse state.
  2285. Arguments:
  2286. Symbols - Supplies a pointer to the symbols data. The raw stab data should
  2287. already be loaded, and the parse state pointer should not be null.
  2288. Also returns the initialized data.
  2289. Stab - Supplies a pointer to the stab of type STAB_SOURCE_LINE.
  2290. StabString - Supplies a pointer to the stab's string, or NULL if the stab
  2291. has no string.
  2292. Return Value:
  2293. TRUE on success.
  2294. FALSE on failure.
  2295. --*/
  2296. {
  2297. ULONGLONG Address;
  2298. PSOURCE_LINE_SYMBOL NewLine;
  2299. BOOL Result;
  2300. PSTAB_CONTEXT State;
  2301. //
  2302. // Parameter checking.
  2303. //
  2304. if ((Symbols == NULL) ||
  2305. (Symbols->SymbolContext == NULL) ||
  2306. (Stab == NULL) ||
  2307. (Stab->Type != STAB_SOURCE_LINE)) {
  2308. return FALSE;
  2309. }
  2310. State = Symbols->SymbolContext;
  2311. if (State->CurrentSourceLineFile == NULL) {
  2312. return FALSE;
  2313. }
  2314. //
  2315. // Skip line zero stabs.
  2316. //
  2317. if (Stab->Description == 0) {
  2318. return TRUE;
  2319. }
  2320. //
  2321. // Allocate a new source line.
  2322. //
  2323. NewLine = MALLOC(sizeof(SOURCE_LINE_SYMBOL));
  2324. if (NewLine == NULL) {
  2325. Result = FALSE;
  2326. goto ParseSourceLineEnd;
  2327. }
  2328. memset(NewLine, 0, sizeof(SOURCE_LINE_SYMBOL));
  2329. //
  2330. // Fill in the line information.
  2331. //
  2332. NewLine->ParentSource = State->CurrentSourceLineFile;
  2333. NewLine->LineNumber = Stab->Description;
  2334. Address = Stab->Value;
  2335. if (State->CurrentFunction != NULL) {
  2336. Address += State->CurrentFunction->StartAddress;
  2337. }
  2338. NewLine->Start = Address;
  2339. //
  2340. // If there was a previous source line active, end it here.
  2341. //
  2342. if (State->CurrentSourceLine != NULL) {
  2343. State->CurrentSourceLine->End = Address;
  2344. State->CurrentSourceLine = NULL;
  2345. }
  2346. //
  2347. // Add the line to the list, and set the current state.
  2348. //
  2349. INSERT_BEFORE(&(NewLine->ListEntry),
  2350. &(State->CurrentSourceLineFile->SourceLinesHead));
  2351. State->CurrentSourceLine = NewLine;
  2352. Result = TRUE;
  2353. ParseSourceLineEnd:
  2354. if (Result == FALSE) {
  2355. if (NewLine != NULL) {
  2356. FREE(NewLine);
  2357. }
  2358. }
  2359. return Result;
  2360. }
  2361. BOOL
  2362. DbgpParseFunctionStab (
  2363. PDEBUG_SYMBOLS Symbols,
  2364. PSTR Name,
  2365. PRAW_STAB Stab,
  2366. PSTR StabString
  2367. )
  2368. /*++
  2369. Routine Description:
  2370. This routine parses through a function stab, updating the output symbol
  2371. information as well as the parse state.
  2372. Arguments:
  2373. Symbols - Supplies a pointer to the symbols data. The raw stab data should
  2374. already be loaded, and the parse state pointer should not be null.
  2375. Also returns the initialized data.
  2376. Name - Supplies the name of the new function, or NULL if a name could not be
  2377. parsed.
  2378. Stab - Supplies a pointer to the stab.
  2379. StabString - Supplies a pointer to the stab's string, or NULL if the stab
  2380. has no string.
  2381. Return Value:
  2382. TRUE on success.
  2383. FALSE on failure.
  2384. --*/
  2385. {
  2386. ULONG EndAddress;
  2387. PFUNCTION_SYMBOL NewFunction;
  2388. BOOL Result;
  2389. PSTR ReturnTypeString;
  2390. PSTAB_CONTEXT State;
  2391. NewFunction = NULL;
  2392. //
  2393. // Parameter checking.
  2394. //
  2395. if ((Symbols == NULL) || (Symbols->SymbolContext == NULL) ||
  2396. (Stab == NULL) || (Stab->Type != STAB_FUNCTION)) {
  2397. return FALSE;
  2398. }
  2399. State = Symbols->SymbolContext;
  2400. //
  2401. // If the string is NULL, the current function is ending. Also make sure to
  2402. // end an open source line, if present.
  2403. //
  2404. if ((StabString == NULL) || (strlen(StabString) == 0)) {
  2405. EndAddress = Stab->Value;
  2406. if (State->CurrentFunction != NULL) {
  2407. EndAddress += State->CurrentFunction->StartAddress;
  2408. }
  2409. if (State->CurrentSourceLine != NULL) {
  2410. State->CurrentSourceLine->End = EndAddress;
  2411. State->CurrentSourceLine = NULL;
  2412. }
  2413. if (State->CurrentFunction != NULL) {
  2414. State->CurrentFunction->EndAddress = EndAddress;
  2415. State->CurrentFunction = NULL;
  2416. }
  2417. State->MaxBraceAddress = 0;
  2418. Result = TRUE;
  2419. goto ParseFunctionStabEnd;
  2420. }
  2421. //
  2422. // This is a new function. Allocate space for it and initialize the list
  2423. // heads.
  2424. //
  2425. NewFunction = MALLOC(sizeof(FUNCTION_SYMBOL));
  2426. if (NewFunction == NULL) {
  2427. Result = FALSE;
  2428. goto ParseFunctionStabEnd;
  2429. }
  2430. memset(NewFunction, 0, sizeof(FUNCTION_SYMBOL));
  2431. INITIALIZE_LIST_HEAD(&(NewFunction->ParametersHead));
  2432. INITIALIZE_LIST_HEAD(&(NewFunction->LocalsHead));
  2433. NewFunction->Name = Name;
  2434. //
  2435. // Get the return type.
  2436. //
  2437. ReturnTypeString = StabString;
  2438. if ((*ReturnTypeString != 'F') && (*ReturnTypeString != 'f')) {
  2439. Result = FALSE;
  2440. goto ParseFunctionStabEnd;
  2441. }
  2442. ReturnTypeString += 1;
  2443. ReturnTypeString = DbgpGetTypeNumber(Symbols,
  2444. NULL,
  2445. ReturnTypeString,
  2446. &(NewFunction->ReturnTypeOwner),
  2447. &(NewFunction->ReturnTypeNumber));
  2448. if (ReturnTypeString == NULL) {
  2449. Result = FALSE;
  2450. goto ParseFunctionStabEnd;
  2451. }
  2452. NewFunction->FunctionNumber = Stab->Description;
  2453. NewFunction->ParentSource = State->CurrentSourceFile;
  2454. NewFunction->StartAddress = Stab->Value;
  2455. //
  2456. // Insert the function into the current source file's list of functions.
  2457. //
  2458. INSERT_BEFORE(&(NewFunction->ListEntry),
  2459. &(State->CurrentSourceFile->FunctionsHead));
  2460. State->CurrentFunction = NewFunction;
  2461. State->MaxBraceAddress = NewFunction->StartAddress;
  2462. Result = TRUE;
  2463. ParseFunctionStabEnd:
  2464. if (Result == FALSE) {
  2465. if (NewFunction != NULL) {
  2466. FREE(NewFunction);
  2467. }
  2468. }
  2469. return Result;
  2470. }
  2471. BOOL
  2472. DbgpParseFunctionParameterStab (
  2473. PDEBUG_SYMBOLS Symbols,
  2474. PSTR Name,
  2475. PRAW_STAB Stab,
  2476. PSTR StabString
  2477. )
  2478. /*++
  2479. Routine Description:
  2480. This routine parses through a function parameter stab, updating the output
  2481. symbol information as well as the parse state.
  2482. Arguments:
  2483. Symbols - Supplies a pointer to the symbols data. The raw stab data should
  2484. already be loaded, and the parse state pointer should not be null.
  2485. Also returns the initialized data. The current function in the state
  2486. should also not be NULL.
  2487. Name - Supplies the name of the parameter, or NULL if a name could not be
  2488. parsed.
  2489. Stab - Supplies a pointer to the stab of type STAB_FUNCTION_PARAMETER.
  2490. StabString - Supplies a pointer to the stab's string, or NULL if the stab
  2491. has no string.
  2492. Return Value:
  2493. TRUE on success.
  2494. FALSE on failure.
  2495. --*/
  2496. {
  2497. PDATA_SYMBOL NewParameter;
  2498. PSTR ParameterTypeString;
  2499. BOOL Result;
  2500. PSTAB_CONTEXT State;
  2501. NewParameter = NULL;
  2502. //
  2503. // Parameter checking.
  2504. //
  2505. if ((Symbols == NULL) || (Stab == NULL) ||
  2506. ((Stab->Type != STAB_FUNCTION_PARAMETER) &&
  2507. (Stab->Type != STAB_REGISTER_VARIABLE)) ||
  2508. (Symbols->SymbolContext == NULL)) {
  2509. return FALSE;
  2510. }
  2511. State = Symbols->SymbolContext;
  2512. //
  2513. // Create the new parameter on the heap.
  2514. //
  2515. NewParameter = MALLOC(sizeof(DATA_SYMBOL));
  2516. if (NewParameter == NULL) {
  2517. Result = FALSE;
  2518. goto ParseFunctionParameterStabEnd;
  2519. }
  2520. memset(NewParameter, 0, sizeof(DATA_SYMBOL));
  2521. NewParameter->Name = Name;
  2522. //
  2523. // Get the parameter type.
  2524. //
  2525. ParameterTypeString = StabString;
  2526. if (*ParameterTypeString == 'P') {
  2527. NewParameter->LocationType = DataLocationRegister;
  2528. NewParameter->Location.Register = STAB_REGISTER_TO_GENERAL(Stab->Value);
  2529. } else if (*ParameterTypeString == 'p') {
  2530. NewParameter->LocationType = DataLocationIndirect;
  2531. NewParameter->Location.Indirect.Offset = (LONG)Stab->Value;
  2532. NewParameter->Location.Indirect.Register =
  2533. DbgpStabsGetFramePointerRegister(Symbols);
  2534. } else {
  2535. Result = FALSE;
  2536. goto ParseFunctionParameterStabEnd;
  2537. }
  2538. ParameterTypeString += 1;
  2539. ParameterTypeString = DbgpGetTypeNumber(Symbols,
  2540. NULL,
  2541. ParameterTypeString,
  2542. &(NewParameter->TypeOwner),
  2543. &(NewParameter->TypeNumber));
  2544. if (ParameterTypeString == NULL) {
  2545. Result = FALSE;
  2546. goto ParseFunctionParameterStabEnd;
  2547. }
  2548. NewParameter->ParentFunction = State->CurrentFunction;
  2549. //
  2550. // Insert the parameter into the current function's parameter list.
  2551. //
  2552. if (State->CurrentFunction != NULL) {
  2553. INSERT_BEFORE(&(NewParameter->ListEntry),
  2554. &(State->CurrentFunction->ParametersHead));
  2555. NewParameter = NULL;
  2556. }
  2557. Result = TRUE;
  2558. ParseFunctionParameterStabEnd:
  2559. if (NewParameter != NULL) {
  2560. FREE(NewParameter);
  2561. }
  2562. return Result;
  2563. }
  2564. BOOL
  2565. DbgpParseRegisterVariableStab (
  2566. PDEBUG_SYMBOLS Symbols,
  2567. PSTR Name,
  2568. PRAW_STAB Stab,
  2569. PSTR StabString
  2570. )
  2571. /*++
  2572. Routine Description:
  2573. This routine parses through a register variable stab, updating the output
  2574. symbol information as well as the parse state and current function.
  2575. Arguments:
  2576. Symbols - Supplies a pointer to the symbols data. The raw stab data should
  2577. already be loaded, and the parse state pointer should not be null.
  2578. Also returns the initialized data. The current function in the state
  2579. should also not be NULL.
  2580. Name - Supplies the name of the register variable, or NULL if a name could
  2581. not be parsed.
  2582. Stab - Supplies a pointer to the stab of type STAB_REGISTER_VARIABLE.
  2583. StabString - Supplies a pointer to the stab's string, or NULL if the stab
  2584. has no string.
  2585. Return Value:
  2586. TRUE on success.
  2587. FALSE on failure.
  2588. --*/
  2589. {
  2590. PDATA_SYMBOL NewLocal;
  2591. BOOL Result;
  2592. PSTAB_CONTEXT State;
  2593. CHAR VariableFlavor;
  2594. PSTR VariableType;
  2595. NewLocal = NULL;
  2596. //
  2597. // Parameter checking.
  2598. //
  2599. if ((Symbols == NULL) || (Stab == NULL) ||
  2600. (Stab->Type != STAB_REGISTER_VARIABLE) ||
  2601. (Symbols->SymbolContext == NULL)) {
  2602. return FALSE;
  2603. }
  2604. State = Symbols->SymbolContext;
  2605. if (State->CurrentFunction == NULL) {
  2606. return FALSE;
  2607. }
  2608. //
  2609. // A capital P indicates that this is actually a parameter that was passed
  2610. // solely through a register. Parse this as a parameter if that's the case.
  2611. // A lowercase p indicates that this parameter was passed in through the
  2612. // stack, but is later put into a register. These types get treated as as
  2613. // separate variables, one on the stack and one in a register.
  2614. //
  2615. VariableFlavor = *StabString;
  2616. if (VariableFlavor == 'P') {
  2617. Result = DbgpParseFunctionParameterStab(Symbols,
  2618. Name,
  2619. Stab,
  2620. StabString);
  2621. goto ParseRegisterVariableStabEnd;
  2622. }
  2623. //
  2624. // Create the new local variable on the heap.
  2625. //
  2626. NewLocal = MALLOC(sizeof(DATA_SYMBOL));
  2627. if (NewLocal == NULL) {
  2628. Result = FALSE;
  2629. goto ParseRegisterVariableStabEnd;
  2630. }
  2631. memset(NewLocal, 0, sizeof(DATA_SYMBOL));
  2632. NewLocal->Name = Name;
  2633. //
  2634. // Validate the parameter type.
  2635. //
  2636. if (VariableFlavor != 'r') {
  2637. Result = FALSE;
  2638. goto ParseRegisterVariableStabEnd;
  2639. }
  2640. VariableType = StabString + 1;
  2641. VariableType = DbgpGetTypeNumber(Symbols,
  2642. NULL,
  2643. VariableType,
  2644. &(NewLocal->TypeOwner),
  2645. &(NewLocal->TypeNumber));
  2646. if (VariableType == NULL) {
  2647. Result = FALSE;
  2648. goto ParseRegisterVariableStabEnd;
  2649. }
  2650. NewLocal->ParentFunction = State->CurrentFunction;
  2651. NewLocal->ParentSource = State->CurrentSourceFile;
  2652. NewLocal->LocationType = DataLocationRegister;
  2653. NewLocal->Location.Register = STAB_REGISTER_TO_GENERAL(Stab->Value);
  2654. NewLocal->MinimumValidExecutionAddress = State->MaxBraceAddress;
  2655. //
  2656. // Insert the variable into the current function's locals list.
  2657. //
  2658. INSERT_BEFORE(&(NewLocal->ListEntry),
  2659. &(State->CurrentFunction->LocalsHead));
  2660. Result = TRUE;
  2661. ParseRegisterVariableStabEnd:
  2662. if (Result == FALSE) {
  2663. if (NewLocal != NULL) {
  2664. FREE(NewLocal);
  2665. }
  2666. }
  2667. return Result;
  2668. }
  2669. BOOL
  2670. DbgpParseBraceStab (
  2671. PDEBUG_SYMBOLS Symbols,
  2672. PRAW_STAB Stab,
  2673. PSTR StabString
  2674. )
  2675. /*++
  2676. Routine Description:
  2677. This routine parses through a left or right brace stab, updating the parse
  2678. state. This information is used primarily for repeated local variable
  2679. definitions.
  2680. Arguments:
  2681. Symbols - Supplies a pointer to the symbols data. The raw stab data should
  2682. already be loaded, and the parse state pointer should not be null.
  2683. The current function in the state should also not be NULL.
  2684. Stab - Supplies a pointer to the stab of type STAB_LEFT_BRACE or
  2685. STAB_RIGHT_BRACE.
  2686. StabString - Supplies a pointer to the stab's string, or NULL if the stab
  2687. has no string.
  2688. Return Value:
  2689. TRUE on success.
  2690. FALSE on failure.
  2691. --*/
  2692. {
  2693. ULONGLONG Address;
  2694. PSTAB_CONTEXT State;
  2695. if ((Symbols == NULL) || (Stab == NULL) ||
  2696. (Symbols->SymbolContext == NULL) ||
  2697. ((Stab->Type != STAB_LEFT_BRACE) && (Stab->Type != STAB_RIGHT_BRACE))) {
  2698. return FALSE;
  2699. }
  2700. State = Symbols->SymbolContext;
  2701. if (State->CurrentFunction == NULL) {
  2702. return FALSE;
  2703. }
  2704. Address = State->CurrentFunction->StartAddress + (LONG)Stab->Value;
  2705. if (Address > State->MaxBraceAddress) {
  2706. State->MaxBraceAddress = Address;
  2707. }
  2708. return TRUE;
  2709. }
  2710. BOOL
  2711. DbgpParseStaticSymbolStab (
  2712. PDEBUG_SYMBOLS Symbols,
  2713. PSTR Name,
  2714. PRAW_STAB Stab,
  2715. PSTR StabString
  2716. )
  2717. /*++
  2718. Routine Description:
  2719. This routine parses through a static (global) stab, updating the parse
  2720. state and symbol information.
  2721. Arguments:
  2722. Symbols - Supplies a pointer to the symbols data. The raw stab data should
  2723. already be loaded, and the parse state pointer should not be null.
  2724. Name - Supplies the name of the static symbol, or NULL if a name could not
  2725. be parsed.
  2726. Stab - Supplies a pointer to the stab of type STAB_STATIC.
  2727. StabString - Supplies a pointer to the stab's string, or NULL if the stab
  2728. has no string.
  2729. Return Value:
  2730. TRUE on success.
  2731. FALSE on failure.
  2732. --*/
  2733. {
  2734. PDATA_SYMBOL NewStatic;
  2735. BOOL Result;
  2736. PSTAB_CONTEXT State;
  2737. PSTR StaticScope;
  2738. PSTR StaticType;
  2739. NewStatic = NULL;
  2740. //
  2741. // Parameter checking.
  2742. //
  2743. if ((Symbols == NULL) ||
  2744. (Stab == NULL) ||
  2745. (Symbols->SymbolContext == NULL) ||
  2746. ((Stab->Type != STAB_STATIC) &&
  2747. (Stab->Type != STAB_GLOBAL_SYMBOL) &&
  2748. (Stab->Type != STAB_BSS_SYMBOL)) ) {
  2749. return FALSE;
  2750. }
  2751. State = Symbols->SymbolContext;
  2752. //
  2753. // Create the new static variable on the heap.
  2754. //
  2755. NewStatic = MALLOC(sizeof(DATA_SYMBOL));
  2756. if (NewStatic == NULL) {
  2757. Result = FALSE;
  2758. goto ParseStaticSymbolStabEnd;
  2759. }
  2760. memset(NewStatic, 0, sizeof(DATA_SYMBOL));
  2761. NewStatic->Name = Name;
  2762. //
  2763. // Get the scope of the static variable. S indicates file scope static, V
  2764. // indicates function scope static. G indicates a global variable.
  2765. //
  2766. StaticScope = StabString;
  2767. if ((*StaticScope != 'S') &&
  2768. (*StaticScope != 'V') &&
  2769. (*StaticScope != 'G')) {
  2770. Result = FALSE;
  2771. goto ParseStaticSymbolStabEnd;
  2772. }
  2773. NewStatic->ParentSource = State->CurrentSourceFile;
  2774. NewStatic->LocationType = DataLocationAbsoluteAddress;
  2775. NewStatic->Location.Address = Stab->Value;
  2776. NewStatic->MinimumValidExecutionAddress = 0;
  2777. StaticType = StaticScope + 1;
  2778. StaticType = DbgpGetTypeNumber(Symbols,
  2779. NULL,
  2780. StaticType,
  2781. &(NewStatic->TypeOwner),
  2782. &(NewStatic->TypeNumber));
  2783. if (StaticType == NULL) {
  2784. Result = FALSE;
  2785. goto ParseStaticSymbolStabEnd;
  2786. }
  2787. //
  2788. // Add the file to the correct symbol list, depending on the scope.
  2789. //
  2790. if ((*StaticScope == 'S') || (*StaticScope == 'G')) {
  2791. INSERT_BEFORE(&(NewStatic->ListEntry),
  2792. &(State->CurrentSourceFile->DataSymbolsHead));
  2793. } else {
  2794. assert(*StaticScope == 'V');
  2795. if (State->CurrentFunction != NULL) {
  2796. NewStatic->ParentFunction = State->CurrentFunction;
  2797. NewStatic->MinimumValidExecutionAddress =
  2798. State->CurrentFunction->StartAddress;
  2799. INSERT_BEFORE(&(NewStatic->ListEntry),
  2800. &(State->CurrentFunction->LocalsHead));
  2801. } else {
  2802. INSERT_BEFORE(&(NewStatic->ListEntry),
  2803. &(State->CurrentSourceFile->DataSymbolsHead));
  2804. }
  2805. }
  2806. Result = TRUE;
  2807. ParseStaticSymbolStabEnd:
  2808. if (Result == FALSE) {
  2809. if (NewStatic != NULL) {
  2810. FREE(NewStatic);
  2811. }
  2812. }
  2813. return Result;
  2814. }
  2815. BOOL
  2816. DbgpResolveCrossReferences (
  2817. PSTAB_CONTEXT State
  2818. )
  2819. /*++
  2820. Routine Description:
  2821. This routine loops through the unresolved cross reference list in the
  2822. stab parse state and creates types with resolved references. If the
  2823. reference type cannot be found, an empty one is created.
  2824. Arguments:
  2825. State - Supplies a pointer to the current parse state. The current
  2826. source file should not be NULL.
  2827. Return Value:
  2828. TRUE on success.
  2829. FALSE otherwise.
  2830. --*/
  2831. {
  2832. PCROSS_REFERENCE_ENTRY CrossReference;
  2833. PLIST_ENTRY CurrentEntry;
  2834. PTYPE_SYMBOL CurrentType;
  2835. PLIST_ENTRY CurrentTypeEntry;
  2836. BOOL Match;
  2837. PSTR Name;
  2838. PSTR NameEnd;
  2839. ULONG NameLength;
  2840. PSTR NameStart;
  2841. PTYPE_SYMBOL NewType;
  2842. PDATA_TYPE_ENUMERATION NewTypeEnumeration;
  2843. PDATA_TYPE_RELATION NewTypeRelation;
  2844. PDATA_TYPE_STRUCTURE NewTypeStructure;
  2845. BOOL Result;
  2846. Name = NULL;
  2847. NewType = NULL;
  2848. Result = TRUE;
  2849. CurrentEntry = State->CrossReferenceListHead.Next;
  2850. while (CurrentEntry != &(State->CrossReferenceListHead)) {
  2851. CrossReference = LIST_VALUE(CurrentEntry,
  2852. CROSS_REFERENCE_ENTRY,
  2853. ListEntry);
  2854. //
  2855. // Allocate the new type that will be generated for this reference.
  2856. //
  2857. NewType = MALLOC(sizeof(TYPE_SYMBOL));
  2858. if (NewType == NULL) {
  2859. Result = FALSE;
  2860. goto ResolveCrossReferencesEnd;
  2861. }
  2862. memset(NewType, 0, sizeof(TYPE_SYMBOL));
  2863. //
  2864. // Find the end of the reference name, marked by one colon. Two colons
  2865. // do not mark the end of the reference name.
  2866. //
  2867. NameStart = CrossReference->ReferenceString + 1;
  2868. NameEnd = NameStart;
  2869. while (TRUE) {
  2870. NameEnd = strchr(NameEnd, ':');
  2871. if ((NameEnd == NULL) || (*(NameEnd + 1) != ':')) {
  2872. break;
  2873. }
  2874. NameEnd += 2;
  2875. }
  2876. //
  2877. // Create a copy of the name.
  2878. //
  2879. if (NameEnd != NULL) {
  2880. NameLength = (UINTN)NameEnd - (UINTN)NameStart;
  2881. } else {
  2882. NameLength = strlen(NameStart);
  2883. }
  2884. Name = MALLOC(NameLength + 1);
  2885. if (Name == NULL) {
  2886. Result = FALSE;
  2887. goto ResolveCrossReferencesEnd;
  2888. }
  2889. strncpy(Name, NameStart, NameLength);
  2890. Name[NameLength] = '\0';
  2891. //
  2892. // Loop through all the types in the source file, checking for a match
  2893. // of both the name and type.
  2894. //
  2895. Match = FALSE;
  2896. CurrentTypeEntry = CrossReference->ReferringTypeSource->TypesHead.Next;
  2897. while (CurrentTypeEntry !=
  2898. &(CrossReference->ReferringTypeSource->TypesHead)) {
  2899. CurrentType = LIST_VALUE(CurrentTypeEntry,
  2900. TYPE_SYMBOL,
  2901. ListEntry);
  2902. switch (CrossReference->ReferenceString[0]) {
  2903. case 's':
  2904. case 'u':
  2905. if ((CurrentType->Name != NULL) &&
  2906. (CurrentType->Type == DataTypeStructure) &&
  2907. (strcmp(Name, CurrentType->Name) == 0)) {
  2908. Match = TRUE;
  2909. }
  2910. break;
  2911. case 'e':
  2912. if ((CurrentType->Name != NULL) &&
  2913. (CurrentType->Type == DataTypeEnumeration) &&
  2914. (strcmp(Name, CurrentType->Name) == 0)) {
  2915. Match = TRUE;
  2916. }
  2917. break;
  2918. default:
  2919. //
  2920. // Unknown reference type.
  2921. //
  2922. Result = FALSE;
  2923. goto ResolveCrossReferencesEnd;
  2924. }
  2925. //
  2926. // If a match happened, resolve the reference and stop looping
  2927. // through types.
  2928. //
  2929. if (Match != FALSE) {
  2930. NewType->Type = DataTypeRelation;
  2931. NewTypeRelation = &(NewType->U.Relation);
  2932. NewTypeRelation->Pointer = 0;
  2933. NewTypeRelation->OwningFile = CurrentType->ParentSource;
  2934. NewTypeRelation->TypeNumber = CurrentType->TypeNumber;
  2935. NewTypeRelation->Array.Minimum = 0;
  2936. NewTypeRelation->Array.Maximum = 0;
  2937. NewTypeRelation->Function = FALSE;
  2938. break;
  2939. }
  2940. CurrentTypeEntry = CurrentTypeEntry->Next;
  2941. }
  2942. //
  2943. // Initialize the new type.
  2944. //
  2945. NewType->Name = NULL;
  2946. NewType->ParentSource = CrossReference->ReferringTypeSource;
  2947. NewType->ParentFunction = NULL;
  2948. NewType->TypeNumber = CrossReference->ReferringTypeNumber;
  2949. //
  2950. // If a match was not found, this type is going to have to become the
  2951. // reference itself.
  2952. //
  2953. if (Match == FALSE) {
  2954. NewType->Name = Name;
  2955. Name = NULL;
  2956. switch (CrossReference->ReferenceString[0]) {
  2957. case 'u':
  2958. case 's':
  2959. NewType->Type = DataTypeStructure;
  2960. NewTypeStructure = &(NewType->U.Structure);
  2961. NewTypeStructure->SizeInBytes = 0;
  2962. NewTypeStructure->MemberCount = 0;
  2963. NewTypeStructure->FirstMember = NULL;
  2964. break;
  2965. case 'e':
  2966. NewType->Type = DataTypeEnumeration;
  2967. NewTypeEnumeration = &(NewType->U.Enumeration);
  2968. NewTypeEnumeration->MemberCount = 0;
  2969. NewTypeEnumeration->FirstMember = NULL;
  2970. NewTypeEnumeration->SizeInBytes = 4;
  2971. break;
  2972. default:
  2973. //
  2974. // Unknown type reference.
  2975. //
  2976. Result = FALSE;
  2977. goto ResolveCrossReferencesEnd;
  2978. }
  2979. }
  2980. INSERT_BEFORE(&(NewType->ListEntry),
  2981. &(CrossReference->ReferringTypeSource->TypesHead));
  2982. CurrentEntry = CurrentEntry->Next;
  2983. LIST_REMOVE(&(CrossReference->ListEntry));
  2984. FREE(CrossReference);
  2985. if (Name != NULL) {
  2986. FREE(Name);
  2987. Name = NULL;
  2988. }
  2989. }
  2990. //
  2991. // Assert that the list has been completely emptied.
  2992. //
  2993. assert(State->CrossReferenceListHead.Next ==
  2994. &(State->CrossReferenceListHead));
  2995. ResolveCrossReferencesEnd:
  2996. if (Name != NULL) {
  2997. FREE(Name);
  2998. }
  2999. if (Result == FALSE) {
  3000. if (NewType != NULL) {
  3001. if (NewType->Name != NULL) {
  3002. FREE(NewType->Name);
  3003. }
  3004. FREE(NewType);
  3005. }
  3006. }
  3007. return Result;
  3008. }
  3009. LONG
  3010. DbgpGetFileSize (
  3011. FILE *File
  3012. )
  3013. /*++
  3014. Routine Description:
  3015. This routine determines the size of an opened file.
  3016. Arguments:
  3017. File - Supplies the file handle.
  3018. Return Value:
  3019. Returns the file length.
  3020. --*/
  3021. {
  3022. INT CurrentPosition;
  3023. LONG FileSize;
  3024. CurrentPosition = ftell(File);
  3025. fseek(File, 0, SEEK_END);
  3026. FileSize = ftell(File);
  3027. fseek(File, CurrentPosition, SEEK_SET);
  3028. return FileSize;
  3029. }
  3030. ULONG
  3031. DbgpStabsGetFramePointerRegister (
  3032. PDEBUG_SYMBOLS Symbols
  3033. )
  3034. /*++
  3035. Routine Description:
  3036. This routine returns the frame pointer register for use in indirect
  3037. addresses.
  3038. Arguments:
  3039. Symbols - Supplies a pointer to the symbols.
  3040. Return Value:
  3041. Returns the machine-dependent frame pointer register.
  3042. --*/
  3043. {
  3044. PSTAB_CONTEXT ParseState;
  3045. if (Symbols->Machine == ImageMachineTypeX86) {
  3046. return X86RegisterEbp;
  3047. } else if (Symbols->Machine == ImageMachineTypeArm32) {
  3048. ParseState = Symbols->SymbolContext;
  3049. //
  3050. // If the current function has the thumb bit set, then use the thumb
  3051. // frame pointer register.
  3052. //
  3053. if ((ParseState != NULL) && (ParseState->CurrentFunction != NULL) &&
  3054. ((ParseState->CurrentFunction->StartAddress & 0x1) != 0)) {
  3055. return ArmRegisterR7;
  3056. }
  3057. //
  3058. // Return R11, the ARM frame pointer register.
  3059. //
  3060. return ArmRegisterR11;
  3061. }
  3062. assert(FALSE);
  3063. return 0;
  3064. }