stabs.c 100 KB

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