123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488 |
- #pragma warning(push)
- #pragma warning(disable:4146)
- #pragma warning(disable:4996)
- #pragma warning(disable:4800)
- #pragma warning(disable:4244)
- #include "DbgModule.h"
- #include "DWARFInfo.h"
- #include <windows.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <string>
- #include <inttypes.h>
- #include <assert.h>
- #include <vector>
- #include "WinDebugger.h"
- #include "DebugManager.h"
- #include "DebugTarget.h"
- #include "COFFData.h"
- #include "Compiler/BfDemangler.h"
- #include "BeefySysLib/util/Hash.h"
- #include "BeefySysLib/util/BeefPerf.h"
- #include "DbgSymSrv.h"
- #include "MiniDumpDebugger.h"
- #pragma warning(pop)
- #pragma warning(disable:4996)
- #include "BeefySysLib/util/AllocDebug.h"
- USING_NS_BF_DBG;
- void SetBreakpoint(int64_t address);
- NS_BF_DBG_BEGIN
- #ifdef BF_DBG_32
- typedef PEOptionalHeader32 PEOptionalHeader;
- typedef PE_NTHeaders32 PE_NTHeaders;
- #else
- typedef PEOptionalHeader64 PEOptionalHeader;
- typedef PE_NTHeaders64 PE_NTHeaders;
- #endif
- #define GET(T) *((T*)(data += sizeof(T)) - 1)
- #define GET_FROM(ptr, T) *((T*)(ptr += sizeof(T)) - 1)
- //////////////////////////////////////////////////////////////////////////
- DbgCompileUnit::DbgCompileUnit(DbgModule* dbgModule)
- {
- mDbgModule = dbgModule;
- mLanguage = DbgLanguage_Unknown;
- mGlobalBlock = mDbgModule->mAlloc.Alloc<DbgBlock>();
- mGlobalType = mDbgModule->mAlloc.Alloc<DbgType>();
- mGlobalType->mTypeCode = DbgType_Root;
- mGlobalType->mPriority = DbgTypePriority_Primary_Explicit;
- mGlobalType->mCompileUnit = this;
- mLowPC = (addr_target)-1;
- mHighPC = 0;
- //mDoPrimaryRemapping = true;
- mNeedsLineDataFixup = true;
- mWasHotReplaced = false;
- mIsMaster = false;
- }
- //////////////////////////////////////////////////////////////////////////
- addr_target DbgLineDataEx::GetAddress()
- {
- return mSubprogram->GetLineAddr(*mLineData);
- }
- DbgSrcFile* DbgLineDataEx::GetSrcFile()
- {
- auto inlineRoot = mSubprogram->GetRootInlineParent();
- return inlineRoot->mLineInfo->mContexts[mLineData->mCtxIdx].mSrcFile;
- }
- addr_target DbgSubprogram::GetLineAddr(const DbgLineData& lineData)
- {
- return (addr_target)(lineData.mRelAddress + mCompileUnit->mDbgModule->mImageBase);
- }
- DbgSubprogram* DbgSubprogram::GetLineInlinee(const DbgLineData& lineData)
- {
- auto inlineRoot = GetRootInlineParent();
- return inlineRoot->mLineInfo->mContexts[lineData.mCtxIdx].mInlinee;
- }
- DbgSrcFile* DbgSubprogram::GetLineSrcFile(const DbgLineData& lineData)
- {
- auto inlineRoot = GetRootInlineParent();
- return inlineRoot->mLineInfo->mContexts[lineData.mCtxIdx].mSrcFile;
- }
- bool DbgSubprogram::HasValidLines()
- {
- auto inlineRoot = GetRootInlineParent();
- for (int lineIdx = 0; lineIdx < (int)inlineRoot->mLineInfo->mLines.size(); lineIdx++)
- {
- auto& lineInfo = inlineRoot->mLineInfo->mLines[lineIdx];
- if (lineInfo.mColumn >= 0)
- return true;
- }
- return false;
- }
- void DbgSubprogram::PopulateSubprogram()
- {
- if (mDeferredInternalsSize == 0)
- return;
- mCompileUnit->mDbgModule->PopulateSubprogram(this);
- }
- //////////////////////////////////////////////////////////////////////////
- DbgLineDataBuilder::DbgLineDataBuilder(DbgModule* dbgModule)
- {
- mDbgModule = dbgModule;
- mCurSubprogram = NULL;
- mCurRecord = NULL;
- }
- DbgLineData* DbgLineDataBuilder::Add(DbgCompileUnit* compileUnit, DbgLineData& lineData, DbgSrcFile* srcFile, DbgSubprogram* inlinee)
- {
- addr_target address = (addr_target)(lineData.mRelAddress + mDbgModule->mImageBase);
- if ((compileUnit->mLowPC != (addr_target)-1) && ((address < (addr_target)compileUnit->mLowPC) || (address >= (addr_target)compileUnit->mHighPC)))
- return NULL;
-
- if ((mCurSubprogram == NULL) || (address < mCurSubprogram->mBlock.mLowPC) || (address >= mCurSubprogram->mBlock.mHighPC))
- {
- DbgSubprogramMapEntry* mapEntry = mDbgModule->mDebugTarget->mSubprogramMap.Get(address, DBG_MAX_LOOKBACK);
- if (mapEntry != NULL)
- {
- mCurSubprogram = mapEntry->mEntry;
-
- if (address > mCurSubprogram->mBlock.mHighPC)
- mCurSubprogram = NULL;
- if (mCurSubprogram != NULL)
- {
- SubprogramRecord** recordPtr = NULL;
- if (mRecords.TryAdd(mCurSubprogram, NULL, &recordPtr))
- {
- // It's not too expensive to over-reserve here, because these are just temporary structures that get copied
- // exactly sized when we Commit
- mCurRecord = mAlloc.Alloc<SubprogramRecord>();
- *recordPtr = mCurRecord;
- mCurRecord->mContexts.mAlloc = &mAlloc;
- mCurRecord->mContexts.Reserve(16);
- mCurRecord->mLines.mAlloc = &mAlloc;
- mCurRecord->mLines.Reserve(128);
- mCurRecord->mCurContext = -1;
- mCurRecord->mHasInlinees = false;
- }
- else
- mCurRecord = *recordPtr;
- }
- else
- mCurRecord = NULL;
- }
- }
- if (mCurSubprogram == NULL)
- return NULL;
-
- bool needsNewCtx = false;
- if (mCurRecord->mCurContext == -1)
- {
- needsNewCtx = true;
- }
- else
- {
- auto& curContext = mCurRecord->mContexts[mCurRecord->mCurContext];
- if ((curContext.mInlinee != inlinee) || (curContext.mSrcFile != srcFile))
- {
- needsNewCtx = true;
- for (int ctxIdx = 0; ctxIdx < (int)mCurRecord->mContexts.size(); ctxIdx++)
- {
- auto& ctx = mCurRecord->mContexts[ctxIdx];
- if ((ctx.mInlinee == inlinee) && (ctx.mSrcFile == srcFile))
- {
- needsNewCtx = false;
- mCurRecord->mCurContext = ctxIdx;
- break;
- }
- }
- }
- }
-
- if (needsNewCtx)
- {
- DbgLineInfoCtx ctx;
- ctx.mInlinee = inlinee;
- ctx.mSrcFile = srcFile;
- if (inlinee != NULL)
- mCurRecord->mHasInlinees = true;
- mCurRecord->mContexts.Add(ctx);
- mCurRecord->mCurContext = (int)mCurRecord->mContexts.size() - 1;
- }
- lineData.mCtxIdx = mCurRecord->mCurContext;
- if ((mCurSubprogram->mPrologueSize > 0) && (mCurRecord->mLines.size() == 1) && (inlinee == NULL))
- {
- auto& firstLine = mCurRecord->mLines[0];
- auto dbgStartAddr = firstLine.mRelAddress + mCurSubprogram->mPrologueSize;
- if (lineData.mRelAddress != dbgStartAddr)
- {
- DbgLineData dbgStartLine = firstLine;
- dbgStartLine.mRelAddress = dbgStartAddr;
- mCurRecord->mLines.Add(dbgStartLine);
- }
- firstLine.mColumn = -2; // Marker for 'in prologue'
- }
- if (inlinee != NULL)
- {
- if (inlinee->mInlineeInfo->mFirstLineData.mRelAddress == 0)
- inlinee->mInlineeInfo->mFirstLineData = lineData;
- inlinee->mInlineeInfo->mLastLineData = lineData;
- }
- mCurRecord->mLines.Add(lineData);
- return &mCurRecord->mLines.back();
- }
- void DbgLineDataBuilder::Commit()
- {
- HashSet<DbgSrcFile*> usedSrcFiles;
-
- for (auto& recordKV : mRecords)
- {
- auto dbgSubprogram = recordKV.mKey;
- auto record = recordKV.mValue;
- usedSrcFiles.Clear();
- for (auto& ctx : record->mContexts)
- {
- if (usedSrcFiles.Add(ctx.mSrcFile))
- {
- ctx.mSrcFile->mLineDataRefs.Add(dbgSubprogram);
- }
- }
-
- for (int lineIdx = 0; lineIdx < (int)record->mLines.size() - 1; lineIdx++)
- {
- auto& lineData = record->mLines[lineIdx];
- auto& nextLineData = record->mLines[lineIdx + 1];
- if ((lineData.mContribSize == 0) && (lineData.mCtxIdx == nextLineData.mCtxIdx))
- {
- lineData.mContribSize = (uint32)(nextLineData.mRelAddress - lineData.mRelAddress);
- }
- bool sameInliner = lineData.mCtxIdx == nextLineData.mCtxIdx;
- if (!sameInliner)
- {
- auto ctx = record->mContexts[lineData.mCtxIdx];
- auto nextCtx = record->mContexts[lineData.mCtxIdx];
- sameInliner = ctx.mInlinee == nextCtx.mInlinee;
- }
- if ((sameInliner) && (lineData.mRelAddress + lineData.mContribSize < nextLineData.mRelAddress))
- {
- auto ctx = record->mContexts[lineData.mCtxIdx];
- if (ctx.mInlinee != NULL)
- ctx.mInlinee->mHasLineAddrGaps = true;
- }
- }
- DbgLineData* lastLine = NULL;
- for (int lineIdx = 0; lineIdx < (int)record->mLines.size(); lineIdx++)
- {
- auto& lineData = record->mLines[lineIdx];
- if (lineData.mContribSize == 0)
- {
- auto ctx = record->mContexts[lineData.mCtxIdx];
- if (ctx.mInlinee == NULL)
- lastLine = &lineData;
- }
- }
- if (lastLine != NULL)
- lastLine->mContribSize = (uint32)(dbgSubprogram->mBlock.mHighPC - (mDbgModule->mImageBase + lastLine->mRelAddress));
- BF_ASSERT(dbgSubprogram->mLineInfo == NULL);
- dbgSubprogram->mLineInfo = mDbgModule->mAlloc.Alloc<DbgLineInfo>();
- dbgSubprogram->mLineInfo->mLines.CopyFrom(&record->mLines[0], (int)record->mLines.size(), mDbgModule->mAlloc);
- BfSizedArray<DbgLineInfoCtx> contexts;
- contexts.CopyFrom(&record->mContexts[0], (int)record->mContexts.size(), mDbgModule->mAlloc);
- dbgSubprogram->mLineInfo->mContexts = contexts.mVals;
- dbgSubprogram->mLineInfo->mHasInlinees = record->mHasInlinees;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- static const char* DataGetString(const uint8*& data)
- {
- const char* prevVal = (const char*)data;
- while (*data != 0)
- data++;
- data++;
- return prevVal;
- }
- struct AbstractOriginEntry
- {
- public:
- int mClassType;
- DbgDebugData* mDestination;
- DbgDebugData* mAbstractOrigin;
- private:
- AbstractOriginEntry()
- {
- }
- public:
- static AbstractOriginEntry Create(int classType, DbgDebugData* destination, DbgDebugData* abstractOrigin)
- {
- AbstractOriginEntry abstractOriginEntry;
- abstractOriginEntry.mClassType = classType;
- abstractOriginEntry.mDestination = destination;
- abstractOriginEntry.mAbstractOrigin = abstractOrigin;
- return abstractOriginEntry;
- }
- void Replace()
- {
- if (mClassType == DbgSubprogram::ClassType)
- {
- DbgSubprogram* destSubprogram = (DbgSubprogram*)mDestination;
- DbgSubprogram* originSubprogram = (DbgSubprogram*)mAbstractOrigin;
- if (destSubprogram->mName == NULL)
- {
- destSubprogram->mName = originSubprogram->mName;
- destSubprogram->mParentType = originSubprogram->mParentType;
- }
- destSubprogram->mHasThis = originSubprogram->mHasThis;
- if (destSubprogram->mFrameBaseData == NULL)
- {
- destSubprogram->mFrameBaseData = originSubprogram->mFrameBaseData;
- destSubprogram->mFrameBaseLen = originSubprogram->mFrameBaseLen;
- }
- destSubprogram->mReturnType = originSubprogram->mReturnType;
- auto originItr = originSubprogram->mParams.begin();
- for (auto destParam : destSubprogram->mParams)
- {
- DbgVariable* originParam = *originItr;
- if (originParam != NULL)
- {
- if (destParam->mName == NULL)
- destParam->mName = originParam->mName;
- if (destParam->mType == NULL)
- destParam->mType = originParam->mType;
- }
- ++originItr;
- }
- //BF_ASSERT(originItr == originSubprogram->mParams.end());
- }
- else if (mClassType == DbgVariable::ClassType)
- {
- DbgVariable* destVariable = (DbgVariable*)mDestination;
- DbgVariable* originVariable = (DbgVariable*)mAbstractOrigin;
- if (destVariable->mName == NULL)
- destVariable->mName = originVariable->mName;
- if (destVariable->mType == NULL)
- destVariable->mType = originVariable->mType;
- }
- else
- {
- BF_FATAL("Unhandled");
- }
- }
- };
- NS_BF_DBG_END
- //////////////////////////////////////////////////////////////////////////
- void DbgSubprogram::ToString(StringImpl& str, bool internalName)
- {
- if ((mInlineeInfo != NULL) && (mInlineeInfo->mInlineeId != 0))
- mCompileUnit->mDbgModule->FixupInlinee(this);
- PopulateSubprogram();
-
- if (mCheckedKind == BfCheckedKind_Checked)
- str += "[Checked] ";
- else if (mCheckedKind == BfCheckedKind_Unchecked)
- str += "[Unchecked] ";
- auto language = GetLanguage();
- if (mName == NULL)
- {
- if (mLinkName[0] == '<')
- {
- str += mLinkName;
- return;
- }
- str = BfDemangler::Demangle(StringImpl::MakeRef(mLinkName), language);
- // Strip off the params since we need to generate those ourselves
- int parenPos = (int)str.IndexOf('(');
- if (parenPos != -1)
- str = str.Substring(0, parenPos);
- }
- else if ((mHasQualifiedName) && (!internalName))
- {
- const char* cPtr = mName;
- if (strncmp(cPtr, "_bf::", 5) == 0)
- {
- cPtr += 5;
- for ( ; true; cPtr++)
- {
- char c = *cPtr;
- if (c == 0)
- break;
- if ((c == '_') && (cPtr[-1] == ':'))
- {
- if (strcmp(cPtr, "__BfCtor") == 0)
- {
- str += "this";
- break;
- }
- if (strcmp(cPtr, "__BfStaticCtor") == 0)
- {
- str += "this$static";
- break;
- }
- if (strcmp(cPtr, "__BfCtorClear") == 0)
- {
- str += "this$clear";
- break;
- }
- }
- if ((c == ':') && (cPtr[1] == ':'))
- {
- str.Append('.');
- cPtr++;
- }
- else
- str.Append(c);
- }
- }
- else
- str += mName;
- }
- else
- {
- if (mParentType != NULL)
- {
- mParentType->ToString(str, language, true, internalName);
- if (!str.empty())
- {
- if (language == DbgLanguage_Beef)
- str += ".";
- else
- str += "::";
- }
- }
- const char* name = mName;
- if (mHasQualifiedName)
- {
- const char* cPtr = name;
- for (; true; cPtr++)
- {
- char c = *cPtr;
- if (c == 0)
- break;
- if ((c == ':') && (cPtr[1] == ':'))
- {
- name = cPtr + 2;
- }
- }
- }
- if ((language == DbgLanguage_Beef) && (mParentType != NULL) && (mParentType->mTypeName != NULL) && (strcmp(name, mParentType->mTypeName) == 0))
- str += "this";
- else if ((language == DbgLanguage_Beef) && (name[0] == '~'))
- str += "~this";
- else if (strncmp(name, "_bf::", 5) == 0)
- str += name + 5;
- else
- {
- bool handled = false;
- if ((language == DbgLanguage_Beef) && (name[0] == '_'))
- {
- if (strcmp(name, "__BfCtor") == 0)
- {
- str += "this";
- handled = true;
- }
- else if (strcmp(name, "__BfStaticCtor") == 0)
- {
- str += "this";
- handled = true;
- }
- else if (strcmp(name, "__BfCtorClear") == 0)
- {
- str += "this$clear";
- handled = true;
- }
- }
- if (!handled)
- str += name;
- }
- }
- //if (mTemplateName != NULL)
- //str += mTemplateName;
- if (str.empty())
- str += "`anon";
- if ((str[str.length() - 1] == '!') || (str[0] == '<'))
- {
- if (language == DbgLanguage_Beef)
- {
- // It's a mixin - assert that there's no params
- //BF_ASSERT(mParams.Size() == 0);
- }
- //return str;
- }
- str += "(";
- bool showedParam = false;
- int i = 0;
- for (auto variable : mParams)
- {
- if ((variable->mName != NULL) && (strcmp(variable->mName, "this") == 0))
- continue;
- if (showedParam)
- str += ", ";
- if (variable->mType != NULL)
- {
- auto varType = variable->mType;
- if (varType->mTypeCode == DbgType_Const)
- varType = varType->mTypeParam;
- if (variable->mSigNoPointer)
- {
- BF_ASSERT(varType->IsPointer());
- varType = varType->mTypeParam;
- }
- varType->ToString(str, language, false, internalName);
- if (variable->mName != NULL)
- str += " ";
- }
- if (variable->mName != NULL)
- str += variable->mName;
- showedParam = true;
- i++;
- }
- str += ")";
- }
- String DbgSubprogram::ToString()
- {
- String str;
- ToString(str, false);
- return str;
- }
- // For inlined subprograms, the "root" inliner means the bottom-most non-inlined function. This subprogram contains
- // all the line data for it's own non-inlined instructions, PLUS line data for all inlined functions that it calls.
- // The inlined functions has empty mLineInfo structures.
- //
- // When we pass a non-NULL value into inlinedSubprogram, we are requesting to ONLY return lines that were emitted from
- // that subprogram (inlined or not).
- //
- // If we call FindClosestLine on an inlined subprogram, we only want results of functions that are inside or inlined by
- // the 'this' subprogram. Thus, we do a "get any line" call on the root inliner and then filter the results based
- // on whether they are relevant.
- DbgLineData* DbgSubprogram::FindClosestLine(addr_target addr, DbgSubprogram** inlinedSubprogram, DbgSrcFile** srcFile, int* outLineIdx)
- {
- if (mLineInfo == NULL)
- {
- if (mInlineeInfo == NULL)
- return NULL;
-
- if ((inlinedSubprogram != NULL) && (*inlinedSubprogram != NULL))
- {
- // Keep explicit inlinee requirement
- return mInlineeInfo->mRootInliner->FindClosestLine(addr, inlinedSubprogram, srcFile, outLineIdx);
- }
- else
- {
- DbgSubprogram* rootInlinedSubprogram = NULL;
- auto result = mInlineeInfo->mRootInliner->FindClosestLine(addr, &rootInlinedSubprogram, srcFile, outLineIdx);
- if (result == NULL)
- return NULL;
- if (rootInlinedSubprogram == NULL) // Do not allow root parent, as we cannot be a parent to the root parent (duh)
- return NULL;
- // We need to check to see if we are a parent of the found line
- auto checkSubprogram = rootInlinedSubprogram;
- while ((checkSubprogram != NULL) && (checkSubprogram->mInlineeInfo != NULL))
- {
- if (checkSubprogram == this)
- {
- if (inlinedSubprogram != NULL)
- *inlinedSubprogram = rootInlinedSubprogram;
- return result;
- }
- checkSubprogram = checkSubprogram->mInlineeInfo->mInlineParent;
- }
- return NULL;
- }
- }
- // Binary search - lineData is sorted
- int first = 0;
- int last = (int)mLineInfo->mLines.mSize - 1;
- int middle = (first + last) / 2;
- int useIdx = -1;
- while (first <= last)
- {
- addr_target midAddr = (addr_target)(mLineInfo->mLines.mVals[middle].mRelAddress + mCompileUnit->mDbgModule->mImageBase);
- if (midAddr < addr)
- first = middle + 1;
- else if (midAddr == addr)
- {
- useIdx = middle;
- break;
- }
- else
- last = middle - 1;
- middle = (first + last) / 2;
- }
- if (useIdx == -1)
- useIdx = last;
- if (last == -1)
- return NULL;
-
- // If we have lines with the same addr, take the more inner one
- while (true)
- {
- auto lineData = &mLineInfo->mLines.mVals[useIdx];
- if (useIdx + 1 < mLineInfo->mLines.mSize)
- {
- auto peekNext = &mLineInfo->mLines.mVals[useIdx + 1];
- if (lineData->mRelAddress != peekNext->mRelAddress)
- break;
- useIdx++;
- }
- else
- {
- break;
- }
- }
- while (true)
- {
- auto lineData = &mLineInfo->mLines.mVals[useIdx];
- if (addr < lineData->mRelAddress + lineData->mContribSize + mCompileUnit->mDbgModule->mImageBase)
- {
- auto& ctx = mLineInfo->mContexts[lineData->mCtxIdx];
- if (srcFile != NULL)
- *srcFile = ctx.mSrcFile;
- if (inlinedSubprogram != NULL)
- {
- auto subprogram = (ctx.mInlinee != NULL) ? ctx.mInlinee : this;
- if (*inlinedSubprogram != NULL)
- {
- // Strictness check
- if (subprogram == *inlinedSubprogram)
- {
- if (outLineIdx != NULL)
- *outLineIdx = useIdx;
- return lineData;
- }
- }
- else
- {
- *inlinedSubprogram = subprogram;
- if (outLineIdx != NULL)
- *outLineIdx = useIdx;
- return lineData;
- }
- }
- else
- {
- if (outLineIdx != NULL)
- *outLineIdx = useIdx;
- return lineData;
- }
- }
- // Hope we can find an earlier entry whose "contribution" is still valid
- if (--useIdx < 0)
- break;
- }
- return NULL;
- }
- DbgType* DbgSubprogram::GetParent()
- {
- if ((mParentType == NULL) && (mCompileUnit != NULL))
- mCompileUnit->mDbgModule->MapCompileUnitMethods(mCompileUnit);
- return mParentType;
- }
- DbgType* DbgSubprogram::GetTargetType()
- {
- if (!mHasThis)
- return mParentType;
- auto thisType = mParams.mHead->mType;
- if (thisType == NULL)
- return mParentType;
- if (thisType->IsPointer())
- return thisType->mTypeParam;
- return thisType;
- }
- DbgLanguage DbgSubprogram::GetLanguage()
- {
- if (mParentType != NULL)
- return mParentType->GetLanguage();
- if (mCompileUnit->mLanguage != DbgLanguage_Unknown)
- return mCompileUnit->mLanguage;
- return DbgLanguage_C; // Parent type would have been set for Beef, so it must be C
- }
- bool DbgSubprogram::Equals(DbgSubprogram* checkMethod, bool allowThisMismatch)
- {
- if ((mLinkName != NULL) && (checkMethod->mLinkName != NULL))
- {
- return strcmp(mLinkName, checkMethod->mLinkName) == 0;
- }
-
- if (strcmp(mName, checkMethod->mName) != 0)
- return false;
- if (mHasThis != checkMethod->mHasThis)
- return false;
- int paramIdx = 0;
- auto param = mParams.mHead;
- auto checkParam = checkMethod->mParams.mHead;
- while ((param != NULL) && (checkParam != NULL))
- {
- if ((paramIdx == 0) && (allowThisMismatch))
- {
- // Allow
- }
- else if ((param->mType != checkParam->mType) && (!param->mType->Equals(checkParam->mType)))
- return false;
- param = param->mNext;
- checkParam = checkParam->mNext;
- paramIdx++;
- }
- if ((param != NULL) || (checkParam != NULL))
- return false;
- if (!mReturnType->Equals(checkMethod->mReturnType))
- return false;
- return true;
- }
- int DbgSubprogram::GetParamCount()
- {
- int paramCount = mParams.Size();
- if (mHasThis)
- paramCount--;
- return paramCount;
- }
- String DbgSubprogram::GetParamName(int paramIdx)
- {
- auto param = mParams[paramIdx];
- if (param->mName != NULL)
- {
- String name = "'";
- name += param->mName;
- name += "'";
- return name;
- }
- return StrFormat("%d", paramIdx + 1);
- }
- bool DbgSubprogram::IsGenericMethod()
- {
- if (mName == NULL)
- return false;
- for (const char* cPtr = mName; true; cPtr++)
- {
- char c = *cPtr;
- if (c == '\0')
- break;
- if (c == '<')
- return true;
- }
- return false;
- }
- bool DbgSubprogram::ThisIsSplat()
- {
- if (mBlock.mVariables.mHead == NULL)
- return false;
- return strncmp(mBlock.mVariables.mHead->mName, "$this$", 6) == 0;
- }
- bool DbgSubprogram::IsLambda()
- {
- if (mName == NULL)
- return false;
- return StringView(mName).Contains('$');
- }
- //////////////////////////////////////////////////////////////////////////
- DbgSubprogram::~DbgSubprogram()
- {
- BfLogDbg("DbgSubprogram::~DbgSubprogram %p\n", this);
- }
- ////////////////////
- bool DbgSrcFile::IsBeef()
- {
- int dotPos = (int)mFilePath.LastIndexOf('.');
- if (dotPos == -1)
- return false;
- const char* ext = mFilePath.c_str() + dotPos;
- // The ".cs" is legacy. Remove that eventually.
- return (stricmp(ext, ".bf") == 0) || (stricmp(ext, ".cs") == 0);
- }
- DbgSrcFile::~DbgSrcFile()
- {
- for (auto replacedLineInfo : mHotReplacedDbgLineInfo)
- delete replacedLineInfo;
- }
- void DbgSrcFile::RemoveDeferredRefs(DbgModule* debugModule)
- {
- for (int deferredIdx = 0; deferredIdx < (int)mDeferredRefs.size(); )
- {
- if (mDeferredRefs[deferredIdx].mDbgModule == debugModule)
- {
- // Fast remove
- mDeferredRefs[deferredIdx] = mDeferredRefs.back();
- mDeferredRefs.pop_back();
- }
- else
- deferredIdx++;
- }
- }
- void DbgSrcFile::RemoveLines(DbgModule* debugModule)
- {
- if (!mHasLineDataFromMultipleModules)
- {
- // Fast-out case
- mLineDataRefs.Clear();
- mFirstLineDataDbgModule = NULL;
- return;
- }
- for (int idx = 0; idx < (int)mLineDataRefs.size(); idx++)
- {
- auto dbgSubprogram = mLineDataRefs[idx];
- if (dbgSubprogram->mCompileUnit->mDbgModule == debugModule)
- {
- mLineDataRefs.RemoveAtFast(idx);
- idx--;
- }
- }
- }
- void DbgSrcFile::RemoveLines(DbgModule* debugModule, DbgSubprogram* dbgSubprogram, bool isHotReplaced)
- {
- debugModule->mDebugTarget->mPendingSrcFileRehup.Add(this);
- if (isHotReplaced)
- {
- int vecIdx = dbgSubprogram->mCompileUnit->mDbgModule->mHotIdx;
- BF_ASSERT(vecIdx >= 0);
- while (vecIdx >= (int)mHotReplacedDbgLineInfo.size())
- mHotReplacedDbgLineInfo.push_back(new HotReplacedLineInfo());
- auto hotReplacedLineInfo = mHotReplacedDbgLineInfo[vecIdx];
- HotReplacedLineInfo::Entry entry;
- entry.mSubprogram = dbgSubprogram;
- entry.mLineInfo = dbgSubprogram->mLineInfo;
- hotReplacedLineInfo->mEntries.Add(entry);
- }
- }
- void DbgSrcFile::RehupLineData()
- {
- for (int idx = 0; idx < (int)mLineDataRefs.size(); idx++)
- {
- auto dbgSubprogram = mLineDataRefs[idx];
- if (dbgSubprogram->mHotReplaceKind != DbgSubprogram::HotReplaceKind_None)
- {
- mLineDataRefs.RemoveAtFast(idx);
- idx--;
- }
- }
- }
- const String& DbgSrcFile::GetLocalPath()
- {
- return (!mLocalPath.IsEmpty()) ? mLocalPath : mFilePath;
- }
- void DbgSrcFile::GetHash(String& outStr)
- {
- if (mHashKind == DbgHashKind_MD5)
- {
- for (int i = 0; i < 16; i++)
- {
- outStr += StrFormat("%02X", mHash[i]);
- }
- }
- else if (mHashKind == DbgHashKind_SHA256)
- {
- for (int i = 0; i < 32; i++)
- {
- outStr += StrFormat("%02X", mHash[i]);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- DbgType::DbgType()
- {
- mTypeIdx = -1;
- mIsDeclaration = false;
- mParent = NULL;
- mTypeName = NULL;
- mTypeCode = DbgType_Null;
- mSize = 0;
- mPtrType = NULL;
- mTypeParam = NULL;
- mBlockParam = NULL;
- mNext = NULL;
- mPriority = DbgTypePriority_Normal;
- }
- DbgType::~DbgType()
- {
- BfLogDbg("DbgType::~DWType %p\n", this);
- }
- DbgType* DbgType::ResolveTypeDef()
- {
- if (mTypeCode == DbgType_TypeDef)
- return mTypeParam->ResolveTypeDef();
- return this;
- }
- bool DbgType::Equals(DbgType* dbgType)
- {
- if (dbgType == NULL)
- return false;
- if (mTypeCode != dbgType->mTypeCode)
- {
- if ((mTypeCode == DbgType_Enum) || (dbgType->mTypeCode == DbgType_Enum))
- {
- // These may change mTypeCode, so redo the check afterward
- GetPrimaryType();
- dbgType->GetPrimaryType();
- }
- if (mTypeCode != dbgType->mTypeCode)
- return false;
- }
- if ((mName == NULL) != (dbgType->mName == NULL))
- return false;
- if (mName != NULL)
- {
- if (dbgType->mFixedName)
- FixName();
- else if (mFixedName)
- dbgType->FixName();
- if (strcmp(mName, dbgType->mName) != 0)
- return false;
- }
- if ((mTypeParam != NULL) && (!mTypeParam->Equals(dbgType->mTypeParam)))
- return false;
-
- // Did mName already include the parent name?
- if (mCompileUnit->mDbgModule->mDbgFlavor == DbgFlavor_MS)
- return true;
- if ((mParent != NULL) != (dbgType->mParent != NULL))
- return false;
- if (mParent != NULL)
- return mParent->Equals(dbgType->mParent);
- return true;
- }
- bool DbgType::IsStruct()
- {
- return mTypeCode == DbgType_Struct;
- }
- bool DbgType::IsPrimitiveType()
- {
- return (mTypeCode >= DbgType_i8) && (mTypeCode <= DbgType_Bool);
- }
- bool DbgType::IsNull()
- {
- return mTypeCode == DbgType_Null;
- }
- bool DbgType::IsVoid()
- {
- return (mTypeCode == DbgType_Void);
- }
- bool DbgType::IsValuelessType()
- {
- return ((mTypeCode == DbgType_Struct) && (GetByteCount() == 0)) || (mTypeCode == DbgType_Void);
- }
- bool DbgType::IsValueType()
- {
- return (mTypeCode <= DbgType_DefinitionEnd);
- }
- bool DbgType::IsTypedPrimitive()
- {
- PopulateType();
- if (mTypeCode != DbgType_Struct)
- return false;
- if (mTypeParam != NULL)
- return true;
- auto baseType = GetBaseType();
- if (baseType == NULL)
- return false;
- if (!baseType->IsTypedPrimitive())
- return false;
-
- mTypeParam = baseType->mTypeParam;
- return true;
- }
- bool DbgType::IsBoolean()
- {
- return mTypeCode == DbgType_Bool;
- }
- bool DbgType::IsInteger()
- {
- return (mTypeCode >= DbgType_i8) && (mTypeCode <= DbgType_u64);
- }
- bool DbgType::IsIntegral()
- {
- return ((mTypeCode >= DbgType_i8) && (mTypeCode <= DbgType_u64)) ||
- ((mTypeCode >= DbgType_SChar) && (mTypeCode <= DbgType_UChar32));
- }
- bool DbgType::IsChar()
- {
- return (mTypeCode >= DbgType_SChar) && (mTypeCode <= DbgType_UChar32);
- }
- bool DbgType::IsChar(DbgLanguage language)
- {
- if (language == DbgLanguage_Beef)
- return (mTypeCode >= DbgType_UChar) && (mTypeCode <= DbgType_UChar32);
- return (mTypeCode >= DbgType_SChar) && (mTypeCode <= DbgType_SChar32);
- }
- bool DbgType::IsFloat()
- {
- return (mTypeCode == DbgType_Single) || (mTypeCode == DbgType_Double);
- }
- // "Struct" in this sense means that we do NOT have a pointer to this value, but it may or may not be a Beef Struct
- bool DbgType::IsCompositeType()
- {
- if (((mTypeCode == DbgType_TypeDef) || (mTypeCode == DbgType_Const)) && (mTypeParam != NULL))
- return mTypeParam->IsCompositeType();
- return ((mTypeCode == DbgType_Struct) || (mTypeCode == DbgType_Class) || (mTypeCode == DbgType_SizedArray));
- }
- bool DbgType::WantsRefThis()
- {
- return (GetLanguage() == DbgLanguage_Beef) && (!IsBfObject());
- }
- bool DbgType::IsBfObjectPtr()
- {
- if ((mTypeCode == DbgType_Ptr) && (mTypeParam != NULL))
- return mTypeParam->IsBfObject();
- return false;
- }
- DbgExtType DbgType::CalcExtType()
- {
- auto language = GetLanguage();
- if ((!mFixedName) && (language == DbgLanguage_Beef))
- {
- FixName();
- }
- auto primaryType = GetPrimaryType();
- if (this != primaryType)
- {
- return primaryType->CalcExtType();
- }
- if (mCompileUnit == NULL)
- return DbgExtType_Normal;
- if (language != DbgLanguage_Beef)
- return DbgExtType_Normal;
- if ((mTypeCode != DbgType_Struct) && (mTypeCode != DbgType_Class))
- return DbgExtType_Normal;
- PopulateType();
- if (mExtType != DbgExtType_Unknown)
- return mExtType;
- auto baseType = GetBaseType();
- if (baseType == NULL)
- {
- if (mParent == NULL)
- return DbgExtType_Normal;
- if (mParent->mTypeCode != DbgType_Namespace)
- return DbgExtType_Normal;
- if (mParent->mParent != NULL)
- return DbgExtType_Normal;
- if (strcmp(mParent->mTypeName, "System") != 0)
- return DbgExtType_Normal;
- if (strcmp(mTypeName, "Object") != 0)
- return DbgExtType_Normal;
- return DbgExtType_BfObject;
- }
- else
- {
- if (strcmp(baseType->mTypeName, "Enum") == 0)
- {
- for (auto member : mMemberList)
- {
- if (strcmp(member->mName, "__bftag") == 0)
- return DbgExtType_BfPayloadEnum;
- }
- return DbgExtType_Normal;
- }
- else if (strcmp(baseType->mTypeName, "ValueType") == 0)
- {
- for (auto member : mMemberList)
- {
- if (strcmp(member->mName, "$bfunion") == 0)
- return DbgExtType_BfUnion;
- }
- }
- }
- auto baseExtType = baseType->CalcExtType();
- if ((baseExtType == DbgExtType_BfObject) && (GetByteCount() == 0))
- baseExtType = DbgExtType_Interface;
- return baseExtType;
- }
- DbgLanguage DbgType::GetLanguage()
- {
- return mLanguage;
- }
- void DbgType::FixName()
- {
- if (mFixedName)
- return;
-
- int depthCount = 0;
- auto dbgModule = mCompileUnit->mDbgModule;
- if ((dbgModule->mDbgFlavor == DbgFlavor_MS) && (mName != NULL) && (strlen(mName) > 0))
- {
- bool modified = false;
- if (!dbgModule->DbgIsStrMutable(mName))
- mName = dbgModule->DbgDupString(mName);
- const char* typeNamePtr = mTypeName;
- char* nameP = (char*)mName;
- // Fix the name
- char* inPtr = nameP;
- char* outPtr = nameP;
- while (true)
- {
- char c = *(inPtr++);
- if ((c == '<') || (c == '('))
- depthCount++;
- else if ((c == '>') || (c == ')'))
- depthCount--;
- if ((c == ':') && (inPtr[0] == ':'))
- {
- if (mLanguage == DbgLanguage_Beef)
- {
- modified = true;
- inPtr++;
- *(outPtr++) = '.';
- if (depthCount == 0)
- typeNamePtr = outPtr;
- }
- else if (depthCount == 0)
- mTypeName = inPtr + 1;
- }
- else if (modified)
- *(outPtr++) = c;
- else
- outPtr++;
- if (c == 0)
- break;
- }
- if ((modified) && (mName != mTypeName) && (typeNamePtr != NULL))
- {
- mTypeName = typeNamePtr;
- }
- }
- mFixedName = true;
- }
- bool DbgType::IsBfObject()
- {
- if (mExtType == DbgExtType_Unknown)
- mExtType = CalcExtType();
- return (mExtType == DbgExtType_BfObject) || (mExtType == DbgExtType_Interface);
- }
- bool DbgType::IsBfPayloadEnum()
- {
- if (mExtType == DbgExtType_Unknown)
- mExtType = CalcExtType();
- return mExtType == DbgExtType_BfPayloadEnum;
- }
- bool DbgType::IsBfUnion()
- {
- if (mExtType == DbgExtType_Unknown)
- mExtType = CalcExtType();
- return mExtType == DbgExtType_BfUnion;
- }
- bool DbgType::IsBfEnum()
- {
- if (mTypeCode != DbgType_Struct)
- return false;
- auto baseType = GetBaseType();
- if (baseType == NULL)
- {
- if (mParent == NULL)
- return false;
- if (mParent->mTypeCode != DbgType_Namespace)
- return false;
- if (mParent->mParent != NULL)
- return false;
- if (strcmp(mParent->mTypeName, "System") != 0)
- return false;
- return strcmp(mTypeName, "Enum") == 0;
- }
- return baseType->IsBfEnum();
- }
- bool DbgType::IsBfTuple()
- {
- if (mTypeCode != DbgType_Struct)
- return false;
- if (GetLanguage() != DbgLanguage_Beef)
- return false;
- if (mName == NULL)
- return false;
- return mName[0] == '(';
- }
- bool DbgType::HasCPPVTable()
- {
- if ((mTypeCode != DbgType_Struct) && (mTypeCode != DbgType_Class))
- return false;
- /*if (!mMemberList.IsEmpty())
- {
- //TODO: We commented this out at some point- why did we do that?
- if ((mMemberList.mHead->mName != NULL) && (strncmp(mMemberList.mHead->mName, "_vptr$", 6) == 0))
- return true;
- }*/
- if (mHasVTable)
- return true;
-
- if (GetLanguage() == DbgLanguage_Beef)
- return false;
- for (auto checkBaseType : mBaseTypes)
- {
- if (checkBaseType->mBaseType->HasCPPVTable())
- return true;
- }
- return false;
- }
- bool DbgType::IsBaseBfObject()
- {
- auto baseType = GetBaseType();
- return (baseType == NULL) && (IsBfObject());
- }
- bool DbgType::IsInterface()
- {
- if (mExtType == DbgExtType_Unknown)
- mExtType = CalcExtType();
- return mExtType == DbgExtType_Interface;
- }
- bool DbgType::IsNamespace()
- {
- return mTypeCode == DbgType_Namespace;
- }
- bool DbgType::IsEnum()
- {
- return (mTypeCode == DbgType_Enum);
- }
- bool DbgType::IsRoot()
- {
- return (mTypeCode == DbgType_Root);
- }
- bool DbgType::IsRef()
- {
- return
- (mTypeCode == DbgType_Ref) ||
- (mTypeCode == DbgType_RValueReference);
- }
- bool DbgType::IsSigned()
- {
- return
- (mTypeCode == DbgType_i8) ||
- (mTypeCode == DbgType_i16) ||
- (mTypeCode == DbgType_i32) ||
- (mTypeCode == DbgType_i64);
- }
- bool DbgType::IsConst()
- {
- if ((mTypeCode == DbgType_Ptr) || (mTypeCode == DbgType_Ref))
- {
- if (mTypeParam != NULL)
- return mTypeParam->IsConst();
- }
- return mTypeCode == DbgType_Const;
- }
- bool DbgType::IsPointer(bool includeBfObjectPointer)
- {
- if (mTypeCode != DbgType_Ptr)
- return false;
- if ((!includeBfObjectPointer) && (mTypeParam != NULL) && (mTypeParam->IsBfObject()))
- return false;
- return true;
- }
- bool DbgType::HasPointer(bool includeBfObjectPointer)
- {
- if (((mTypeCode == DbgType_Const) || (mTypeCode == DbgType_Ref)) && (mTypeParam != NULL))
- return mTypeParam->IsPointer(includeBfObjectPointer);
- return IsPointer(includeBfObjectPointer);
- }
- bool DbgType::IsPointerOrRef(bool includeBfObjectPointer)
- {
- if ((mTypeCode != DbgType_Ptr) && (mTypeCode != DbgType_Ref) && (mTypeCode != DbgType_RValueReference))
- return false;
- if ((!includeBfObjectPointer) && (mTypeParam != NULL) && (mTypeParam->IsBfObject()))
- return false;
- return true;
- }
- bool DbgType::IsSizedArray()
- {
- return (mTypeCode == DbgType_SizedArray);
- }
- bool DbgType::IsAnonymous()
- {
- return (mTypeName == NULL) || (mTypeName[0] == '<');
- }
- bool DbgType::IsGlobalsContainer()
- {
- return (mTypeName != NULL) && (mTypeName[0] == 'G') && (mTypeName[1] == '$');
- }
- DbgType* DbgType::GetUnderlyingType()
- {
- return mTypeParam;
- }
- void DbgType::PopulateType()
- {
- if (mIsIncomplete)
- {
- mCompileUnit->mDbgModule->PopulateType(this);
- mIsIncomplete = false;
- }
- }
- DbgModule* DbgType::GetDbgModule()
- {
- if (mCompileUnit == NULL)
- return NULL;
- return mCompileUnit->mDbgModule;
- }
- DbgType* DbgType::GetPrimaryType()
- {
- if (mPrimaryType != NULL)
- return mPrimaryType;
- mPrimaryType = this;
- if (mPriority <= DbgTypePriority_Normal)
- {
- if ((mCompileUnit != NULL) &&
- ((mCompileUnit->mLanguage == DbgLanguage_Beef)|| (mLanguage == DbgLanguage_Beef) ||
- (mTypeCode == DbgType_Namespace) || (mIsDeclaration)))
- {
- mPrimaryType = mCompileUnit->mDbgModule->GetPrimaryType(this);
- mPrimaryType->PopulateType();
- mTypeCode = mPrimaryType->mTypeCode;
- mTypeParam = mPrimaryType->mTypeParam;
- }
- }
-
- return mPrimaryType;
- }
- DbgType* DbgType::GetBaseType()
- {
- auto primaryType = GetPrimaryType();
- if (primaryType != this)
- return primaryType->GetBaseType();
- PopulateType();
- if (mBaseTypes.mHead == NULL)
- return NULL;
- if (GetLanguage() != DbgLanguage_Beef)
- return NULL;
- auto baseType = mBaseTypes.mHead->mBaseType;
- BF_ASSERT(!baseType->IsInterface());
-
- if ((baseType == NULL) || (baseType->mPriority > DbgTypePriority_Normal))
- return baseType;
- baseType = mCompileUnit->mDbgModule->GetPrimaryType(baseType);
- mBaseTypes.mHead->mBaseType = baseType;
- if (baseType->mIsDeclaration)
- {
- // That's no good, try to fix it up
- if (baseType->GetLanguage() == DbgLanguage_Beef)
- {
- if (baseType->GetBaseType() == NULL)
- {
- if (baseType->ToString() == "System.Function")
- {
- DbgBaseTypeEntry* baseTypeEntry = mCompileUnit->mDbgModule->mAlloc.Alloc<DbgBaseTypeEntry>();
- baseTypeEntry->mBaseType = mCompileUnit->mDbgModule->GetPrimitiveType(DbgType_IntPtr_Alias, DbgLanguage_Beef);
- baseType->mBaseTypes.PushBack(baseTypeEntry);
- }
- }
- }
- }
- return baseType;
- }
- DbgType* DbgType::GetRootBaseType()
- {
- auto baseType = GetBaseType();
- if (baseType != NULL)
- return baseType->GetRootBaseType();
- return this;
- }
- DbgType* DbgType::RemoveModifiers(bool* hadRef)
- {
- DbgType* dbgType = this;
- while (dbgType != NULL)
- {
- bool curHadRef = (dbgType->mTypeCode == DbgType_Ref) || (dbgType->mTypeCode == DbgType_RValueReference);
- if ((curHadRef) && (hadRef != NULL))
- *hadRef = true;
- if ((dbgType->mTypeCode == DbgType_Const) || (dbgType->mTypeCode == DbgType_TypeDef) || (dbgType->mTypeCode == DbgType_Volatile) || (dbgType->mTypeCode == DbgType_Bitfield) ||
- (dbgType->mTypeCode == DbgType_Unaligned) || (curHadRef))
- {
- if (dbgType->mTypeParam == NULL)
- break;
- dbgType = dbgType->mTypeParam;
- }
- else
- break;
- }
- return dbgType;
- }
- String DbgType::ToStringRaw(DbgLanguage language)
- {
- if (mTypeIdx != -1)
- return StrFormat("_T_%d", mTypeIdx);
- return ToString(language);
- }
- void DbgType::ToString(StringImpl& str, DbgLanguage language, bool allowDirectBfObject, bool internalName)
- {
- if (language == DbgLanguage_Unknown)
- language = GetLanguage();
- if (language == DbgLanguage_Beef)
- {
- switch (mTypeCode)
- {
- case DbgType_UChar:
- str += "char8";
- return;
- case DbgType_UChar16:
- str += "char16";
- return;
- case DbgType_UChar32:
- str += "char32";
- return;
- case DbgType_i8:
- str += "int8";
- return;
- case DbgType_u8:
- str += "uint8";
- return;
- case DbgType_i16:
- str += "int16";
- return;
- case DbgType_u16:
- str += "uint16";
- return;
- case DbgType_i32:
- str += "int32";
- return;
- case DbgType_u32:
- str += "uint32";
- return;
- case DbgType_i64:
- str += "int64";
- return;
- case DbgType_u64:
- str += "uint64";
- return;
- }
- }
- else
- {
- switch (mTypeCode)
- {
- case DbgType_SChar:
- str += "char";
- return;
- case DbgType_SChar16:
- str += "wchar_t";
- return;
- case DbgType_SChar32:
- str += "int32_t";
- return;
- case DbgType_UChar:
- str += "uint8_t";
- return;
- case DbgType_UChar16:
- str += "uint16_t";
- return;
- case DbgType_UChar32:
- str += "uint32_t";
- return;
- case DbgType_i8:
- str += "char";
- return;
- case DbgType_u8:
- str += "uint8_t";
- return;
- case DbgType_i16:
- str += "short";
- return;
- case DbgType_u16:
- str += "uint16_t";
- return;
- case DbgType_i32:
- str += "int";
- return;
- case DbgType_u32:
- str += "uint32_t";
- return;
- case DbgType_i64:
- str += "int64_t";
- return;
- case DbgType_u64:
- str += "uint64_t";
- return;
- }
- }
- if (mTypeCode == DbgType_Namespace)
- internalName = false;
- auto parent = mParent;
- if ((parent == NULL) && (internalName))
- {
- auto primaryType = GetPrimaryType();
- parent = primaryType->mParent;
- }
- if (mTypeName != NULL)
- {
- if ((!allowDirectBfObject) && (IsBfObject()))
- {
- // Only use the '#' for testing
- //return ToString(true) + "#";
- ToString(str, DbgLanguage_Unknown, true, internalName);
- return;
- }
- if (IsGlobalsContainer())
- {
- if (mParent != NULL)
- {
- mParent->ToString(str, language, false, internalName);
- return;
- }
- return;
- }
-
- //String combName;
- /*if (mTemplateParams != NULL)
- {
- combName = nameP;
- combName += mTemplateParams;
- nameP = combName.c_str();
- }*/
- if ((!mFixedName) /*&& (language == DbgLanguage_Beef)*/)
- {
- FixName();
- }
- char* nameP = (char*)mTypeName;
- if (parent == NULL)
- {
- if (strncmp(nameP, "Box<", 4) == 0)
- {
- str += String(nameP + 4, nameP + strlen(nameP) - 1);
- str += "^";
- return;
- }
- // For declarations, may also include namespaces
- str += mName;
- return;
- }
- if (GetLanguage() == DbgLanguage_Beef)
- {
- parent->ToString(str, language, allowDirectBfObject, internalName);
- if ((internalName) && (parent->mTypeCode != DbgType_Namespace))
- str += "+";
- else
- str += ".";
- str += nameP;
- }
- else
- {
- parent->ToString(str, language, allowDirectBfObject, internalName);
- if ((internalName) && (parent->mTypeCode != DbgType_Namespace))
- str += "+";
- else
- str += "::";
- str += nameP;
- }
- return;
- }
- switch (mTypeCode)
- {
- case DbgType_Struct:
- {
- if ((mTypeName == NULL) && (parent != NULL))
- {
- parent->ToString(str, language, allowDirectBfObject, internalName);
- return;
- }
- str += "@struct";
- return;
- }
- case DbgType_Class:
- {
- str += "@class";
- return;
- }
- case DbgType_TypeDef:
- {
- str += "@typedef";
- return;
- }
- case DbgType_Const:
- {
- if (language == DbgLanguage_Beef)
- {
- str += "readonly";
- if (mTypeParam != NULL)
- {
- str += " ";
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- }
- return;
- }
- str += "const";
- if (mTypeParam != NULL)
- {
- str += " ";
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- }
- return;
- }
- case DbgType_Volatile:
- {
- str += "volatile";
- if (mTypeParam != NULL)
- {
- str += " ";
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- }
- return;
- }
- case DbgType_Unaligned:
- {
- str += "unaligned";
- if (mTypeParam != NULL)
- {
- str += " ";
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- }
- }
- case DbgType_Restrict:
- {
- str += "restrict";
- if (mTypeParam != NULL)
- {
- str += " ";
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- }
- }
- case DbgType_Ptr:
- {
- if (mTypeParam == NULL)
- {
- str += "void*";
- return;
- }
- if (mTypeParam->IsBfObject())
- {
- mTypeParam->ToString(str, DbgLanguage_Unknown, true, internalName);
- return;
- }
- // Don't put a "*" on the end of a function type, it's implicit
- if (mTypeParam->mTypeCode == DbgType_Subroutine)
- {
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- return;
- }
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- str += "*";
- return;
- }
- case DbgType_Ref:
- {
- if (language == DbgLanguage_Beef)
- {
- str += "ref";
- if (mTypeParam != NULL)
- {
- str += " ";
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- }
- return;
- }
- if (mTypeParam == NULL)
- {
- str += "&";
- return;
- }
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- str += "&";
- return;
- }
- case DbgType_RValueReference:
- {
- if (language == DbgLanguage_Beef)
- {
- // Ignore this - this is used for passing structs when we're not using the 'byval' attribute
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- return;
- }
- if (mTypeParam == NULL)
- {
- str += "&&";
- return;
- }
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- str += "&&";
- return;
- }
- case DbgType_Unspecified:
- str += mTypeName;
- return;
- case DbgType_SizedArray:
- {
- StringT<128> name;
- auto checkType = this;
- while (checkType->mTypeCode == DbgType_SizedArray)
- {
- intptr innerSize = checkType->mTypeParam->GetStride();
- intptr arrSize = 0;
- if (innerSize > 0)
- {
- arrSize = checkType->GetStride() / innerSize;
- }
- name += StrFormat("[%lld]", arrSize);
- checkType = checkType->mTypeParam;
- }
- checkType->ToString(str, language, allowDirectBfObject, internalName);
- str += name;
- return;
- }
- case DbgType_Union:
- {
- str += "union";
- if (mTypeParam != NULL)
- {
- str += " ";
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- }
- return;
- }
- case DbgType_Single:
- str += "float";
- return;
- case DbgType_Double:
- str += "double";
- return;
- case DbgType_Null:
- str += "void";
- return;
- case DbgType_Subroutine:
- {
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- str += " (";
- int paramIdx = 0;
- for (auto param : mBlockParam->mVariables)
- {
- if (paramIdx > 0)
- str += ", ";
- param->mType->ToString(str, language, allowDirectBfObject, internalName);
- paramIdx++;
- }
- str += ")";
- return;
- }
- case DbgType_VTable:
- str += "@vtable";
- return;
- case DbgType_Enum:
- str += "@enum";
- return;
- case DbgType_Namespace:
- {
- // Anonymous
- str += "`anon`";
- return;
- }
- case DbgType_PtrToMember:
- str += "@ptrToMember";
- return;
- case DbgType_Bitfield:
- {
- auto dbgBitfieldType = (DbgBitfieldType*)this;
- mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
- str += StrFormat("{%d:%d}", dbgBitfieldType->mPosition, dbgBitfieldType->mLength);
- return;
- }
- default:
- break;
- }
- BF_FATAL("Unhandled type");
- str += "???";
- }
- String DbgType::ToString(DbgLanguage language, bool allowDirectBfObject)
- {
- String str;
- ToString(str, language, allowDirectBfObject, false);
- return str;
- }
- intptr DbgType::GetByteCount()
- {
- if (!mSizeCalculated)
- {
- PopulateType();
- if ((mSize == 0) && (GetLanguage() == DbgLanguage_Beef))
- CalcExtType();
- if ((mTypeCode == DbgType_Struct) || (mTypeCode == DbgType_Class) || (mTypeCode == DbgType_Union))
- {
- if (mPriority <= DbgTypePriority_Normal)
- {
- auto primaryType = GetPrimaryType();
- if (primaryType != this)
- {
- mSize = primaryType->GetByteCount();
- mAlign = primaryType->mAlign;
- }
- }
- }
- else if ((mTypeCode == DbgType_Ref) || (mTypeCode == DbgType_Ptr) || (mTypeCode == DbgType_PtrToMember))
- {
- #ifdef BF_DBG_32
- mSize = 4;
- #else
- mSize = 8;
- #endif
- }
- else if (mTypeCode == DbgType_SizedArray)
- {
- auto language = GetLanguage();
- if (language == DbgLanguage_Beef)
- {
- if (mTypeParam->mAlign == 0)
- {
- NOP;
- }
- auto primaryType = mTypeParam->GetPrimaryType();
- if (primaryType->mAlign == 0)
- {
- NOP;
- }
- else
- {
- intptr elemCount = BF_ALIGN(mSize, primaryType->mAlign) / primaryType->GetStride();
- if (elemCount > 0)
- {
- mSize = ((elemCount - 1) * primaryType->GetStride()) + primaryType->GetByteCount();
- }
- }
- mAlign = primaryType->mAlign;
- }
- }
- else if (mTypeParam != NULL) // typedef, const, volatile, restrict, etc
- mSize = mTypeParam->GetByteCount();
- mSizeCalculated = true;
- }
- return mSize;
- }
- intptr DbgType::GetStride()
- {
- return BF_ALIGN(GetByteCount(), GetAlign());
- }
- int DbgType::GetAlign()
- {
- if (mAlign == 0)
- {
- auto primaryType = GetPrimaryType();
- if (primaryType != this)
- return primaryType->GetAlign();
- if (IsCompositeType())
- {
- PopulateType();
- }
- }
- if (mAlign != 0)
- return mAlign;
- return 1;
- }
- void DbgType::EnsureMethodsMapped()
- {
- for (auto methodNameEntry : mMethodNameList)
- {
- if (methodNameEntry->mCompileUnitId != -1)
- {
- mCompileUnit->mDbgModule->MapCompileUnitMethods(methodNameEntry->mCompileUnitId);
- methodNameEntry->mCompileUnitId = -1;
- }
- }
- }
- #define CREATE_PRIMITIVE_C(typeCode, cTypeName, type) \
- dbgType = mAlloc.Alloc<DbgType>(); \
- dbgType->mCompileUnit = &mDefaultCompileUnit; \
- dbgType->mName = cTypeName; \
- dbgType->mLanguage = DbgLanguage_C;\
- dbgType->mTypeName = cTypeName; \
- dbgType->mTypeCode = typeCode; \
- dbgType->mSize = sizeof(type); \
- dbgType->mAlign = sizeof(type); \
- mCPrimitiveTypes[typeCode] = dbgType; \
- mTypeMap.Insert(dbgType);
- #define CREATE_PRIMITIVE(typeCode, cTypeName, bfTypeName, structName, type) \
- dbgType = mAlloc.Alloc<DbgType>(); \
- dbgType->mCompileUnit = &mDefaultCompileUnit; \
- dbgType->mName = cTypeName; \
- dbgType->mLanguage = DbgLanguage_C;\
- dbgType->mTypeName = cTypeName; \
- dbgType->mTypeCode = typeCode; \
- dbgType->mSize = sizeof(type); \
- dbgType->mAlign = sizeof(type); \
- mCPrimitiveTypes[typeCode] = dbgType; \
- mTypeMap.Insert(dbgType); \
- dbgType = mAlloc.Alloc<DbgType>(); \
- dbgType->mCompileUnit = &mDefaultCompileUnit; \
- dbgType->mName = bfTypeName; \
- dbgType->mLanguage = DbgLanguage_Beef;\
- dbgType->mTypeName = bfTypeName; \
- dbgType->mTypeCode = typeCode; \
- dbgType->mSize = sizeof(type); \
- dbgType->mAlign = sizeof(type); \
- mBfPrimitiveTypes[typeCode] = dbgType; \
- mPrimitiveStructNames[typeCode] = structName; \
- mTypeMap.Insert(dbgType);
- DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this)
- {
- mMemReporter = NULL;
- mLoadState = DbgModuleLoadState_NotLoaded;
- mMappedImageFile = NULL;
- mEntryPoint = 0;
- mFailMsgPtr = NULL;
- mFailed = false;
- for (int i = 0; i < DbgType_COUNT; i++)
- {
- mBfPrimitiveTypes[i] = NULL;
- mCPrimitiveTypes[i] = NULL;
- mPrimitiveStructNames[i] = NULL;
- }
- DbgType* dbgType;
- mDefaultCompileUnit.mLanguage = DbgLanguage_Beef;
- mDefaultCompileUnit.mDbgModule = this;
- if (debugTarget != NULL)
- {
- // These are 'alias' definitions for C, but get overwritten by their official
- // stdint.h versions (ie: int8_t)
- CREATE_PRIMITIVE_C(DbgType_i8, "int8", int8);
- CREATE_PRIMITIVE_C(DbgType_i16, "int16", int16);
- CREATE_PRIMITIVE_C(DbgType_i32, "int32", int32);
- CREATE_PRIMITIVE_C(DbgType_i64, "int64", int64);
- CREATE_PRIMITIVE_C(DbgType_i8, "uint8", uint8);
- CREATE_PRIMITIVE_C(DbgType_i16, "uint16", uint16);
- CREATE_PRIMITIVE_C(DbgType_i32, "uint32", uint32);
- CREATE_PRIMITIVE_C(DbgType_i64, "uint64", uint64);
- CREATE_PRIMITIVE(DbgType_Void, "void", "void", "void", void*);
- dbgType->mSize = 0;
- dbgType->mAlign = 0;
- CREATE_PRIMITIVE(DbgType_Null, "null", "null", "null", void*);
- CREATE_PRIMITIVE(DbgType_IntPtr_Alias, "intptr_t", "int", "System.Int", intptr_target);
- CREATE_PRIMITIVE(DbgType_UIntPtr_Alias, "uintptr_t", "uint", "System.UInt", addr_target);
- CREATE_PRIMITIVE(DbgType_SChar, "char", "char", "System.Char", char);
- CREATE_PRIMITIVE(DbgType_SChar16, "wchar_t", "wchar", "System.Char16", wchar_t);
- CREATE_PRIMITIVE(DbgType_i8, "int8_t", "int8", "System.SByte", int8);
- CREATE_PRIMITIVE(DbgType_i16, "short", "int16", "System.Int16", int16);
- CREATE_PRIMITIVE(DbgType_i32, "int", "int32", "System.Int32", int32);
- CREATE_PRIMITIVE(DbgType_i64, "int64_t", "int64", "System.Int64", int64);
- CREATE_PRIMITIVE(DbgType_u8, "uint8_t", "uint8", "System.UInt8", uint8);
- CREATE_PRIMITIVE(DbgType_u16, "uint16_t", "uint16", "System.UInt16", uint16);
- CREATE_PRIMITIVE(DbgType_u32, "uint32_t", "uint32", "System.UInt32", uint32);
- CREATE_PRIMITIVE(DbgType_u64, "uint64_t", "uint64", "System.UInt64", uint64);
- CREATE_PRIMITIVE(DbgType_Single, "float", "float", "System.Single", float);
- CREATE_PRIMITIVE(DbgType_Double, "double", "double", "System.Double", double);
- CREATE_PRIMITIVE(DbgType_UChar, "char8", "char8", "System.Char", char);
- CREATE_PRIMITIVE(DbgType_UChar16, "char16", "char16", "System.Char16", short);
- CREATE_PRIMITIVE(DbgType_UChar32, "char32", "char32", "System.Char32", int);
- CREATE_PRIMITIVE(DbgType_Bool, "bool", "bool", "System.Boolean", bool);
- CREATE_PRIMITIVE(DbgType_Subroutine, "@Func", "@Func", "@Func", bool);
- CREATE_PRIMITIVE(DbgType_RawText, "@RawText", "@RawText", "@RawText", bool);
- CREATE_PRIMITIVE(DbgType_RegGroup, "@RegGroup", "@RegGroup", "@RegGroup", void*);
-
- CREATE_PRIMITIVE_C(DbgType_i16, "int16_t", int16_t);
- CREATE_PRIMITIVE_C(DbgType_i32, "int32_t", int32_t);
- CREATE_PRIMITIVE_C(DbgType_i64, "__int64", int64);
- CREATE_PRIMITIVE_C(DbgType_u64, "unsigned __int64", uint64);
- CREATE_PRIMITIVE_C(DbgType_u8, "unsigned char", uint8);
- CREATE_PRIMITIVE_C(DbgType_u16, "unsigned short", uint16);
- CREATE_PRIMITIVE_C(DbgType_u32, "unsigned int", uint32);
- CREATE_PRIMITIVE_C(DbgType_u32, "unsigned int32_t", uint32_t);
- CREATE_PRIMITIVE_C(DbgType_u32, "unsigned long", uint32);
- CREATE_PRIMITIVE_C(DbgType_u64, "unsigned int64_t", uint64);
- }
- mIsDwarf64 = false;
- mDebugTarget = debugTarget;
- if (debugTarget != NULL)
- mDebugger = debugTarget->mDebugger;
- else
- mDebugger = NULL;
- mDebugLineData = NULL;
- mDebugInfoData = NULL;
- mDebugPubNames = NULL;
- mDebugFrameAddress = 0;
- mDebugFrameData = NULL;
- mDebugLocationData = NULL;
- mDebugRangesData = NULL;
- mDebugAbbrevData = NULL;
- mDebugStrData = NULL;
- mDebugAbbrevPtrData = NULL;
- mEHFrameData = NULL;
- mEHFrameAddress = 0;
- mStringTable = NULL;
- mSymbolData = NULL;
- mCheckedBfObject = false;
- mBfObjectHasFlags = false;
- mModuleKind = DbgModuleKind_Module;
- mStartTypeIdx = 0;
- mEndTypeIdx = 0;
- mHotIdx = 0;
- mStartSubprogramIdx = 0;
- mEndSubprogramIdx = 0;
- mCodeAddress = NULL;
- mMayBeOld = false;
- mTimeStamp = 0;
- mExpectedFileSize = 0;
- mBfTypeType = NULL;
- mBfTypesInfoAddr = 0;
-
- mImageBase = 0;
- mPreferredImageBase = 0;
- mImageSize = 0;
- mOrigImageData = NULL;
- mDeleting = false;
- mAllocSizeData = 0;
- mParsedSymbolData = false;
- mParsedTypeData = false;
- mParsedGlobalsData = false;
- mPopulatedStaticVariables = false;
- mParsedFrameDescriptors = false;
- mTLSAddr = 0;
- mTLSSize = 0;
- mTLSExtraAddr = 0;
- mTLSExtraSize = 0;
- mTLSIndexAddr = 0;
- mDbgFlavor = DbgFlavor_Unknown;
- mMasterCompileUnit = NULL;
- }
- DbgModule::~DbgModule()
- {
- delete mMemReporter;
- for (auto dwSrcFile : mEmptySrcFiles)
- delete dwSrcFile;
- for (auto dwCompileUnit : mCompileUnits)
- delete dwCompileUnit;
-
- delete mSymbolData;
- delete mStringTable;
- delete mDebugLineData;
- delete mDebugInfoData;
- delete mDebugPubNames;
- delete mDebugFrameData;
- delete mDebugLocationData;
- delete mDebugRangesData;
- delete mDebugAbbrevData;
- delete mDebugAbbrevPtrData;
- delete mDebugStrData;
- for (auto entry : mExceptionDirectory)
- delete entry.mData;
- delete mEHFrameData;
-
- delete mOrigImageData;
- if ((IsObjectFile()) && (mImageBase != 0))
- {
- mDebugger->ReleaseHotTargetMemory((addr_target)mImageBase, (int)mImageSize);
- }
- for (auto data : mOwnedSectionData)
- delete data;
- }
- DbgSubprogram* DbgModule::FindSubprogram(DbgType* dbgType, const char * methodName)
- {
- dbgType = dbgType->GetPrimaryType();
- dbgType->PopulateType();
- if (dbgType->mNeedsGlobalsPopulated)
- PopulateTypeGlobals(dbgType);
- for (auto methodNameEntry : dbgType->mMethodNameList)
- {
- if ((methodNameEntry->mCompileUnitId != -1) && (strcmp(methodNameEntry->mName, methodName) == 0))
- {
- // If we hot-replaced this type then we replaced and parsed all the methods too
- if (!dbgType->mCompileUnit->mDbgModule->IsObjectFile())
- dbgType->mCompileUnit->mDbgModule->MapCompileUnitMethods(methodNameEntry->mCompileUnitId);
- methodNameEntry->mCompileUnitId = -1;
- }
- }
- DbgSubprogram* result = NULL;
- for (auto method : dbgType->mMethodList)
- {
- if (strcmp(method->mName, methodName) == 0)
- {
- method->PopulateSubprogram();
- if ((result == NULL) || (method->mBlock.mLowPC != 0))
- result = method;
- }
- }
- return result;
- }
- void DbgModule::Fail(const StringImpl& error)
- {
- if (mFailMsgPtr != NULL)
- {
- if (mFailMsgPtr->IsEmpty())
- *mFailMsgPtr = error;
- }
- String errorStr = "error ";
- if (!mFilePath.IsEmpty())
- {
- errorStr += "Error in ";
- errorStr += mFilePath;
- errorStr += ": ";
- }
- errorStr += error;
- errorStr += "\n";
- mDebugger->OutputRawMessage(errorStr);
- mFailed = true;
- }
- char* DbgModule::DbgDupString(const char* str, const char* allocName)
- {
- int strLen = (int)strlen(str);
- if (strLen == 0)
- return NULL;
- char* dupStr = (char*)mAlloc.AllocBytes(strLen + 1, (allocName != NULL) ? allocName : "DbgDupString");
- memcpy(dupStr, str, strLen);
- return dupStr;
- }
- DbgModule* DbgModule::GetLinkedModule()
- {
- if (IsObjectFile())
- return mDebugTarget->mTargetBinary;
- return this;
- }
- addr_target DbgModule::GetTargetImageBase()
- {
- if (IsObjectFile())
- return (addr_target)mDebugTarget->mTargetBinary->mImageBase;
- return (addr_target)mImageBase;
- }
- void DbgModule::ParseGlobalsData()
- {
- mParsedGlobalsData = true;
- }
- void DbgModule::ParseSymbolData()
- {
- mParsedSymbolData = true;
- }
- void DbgModule::ParseTypeData()
- {
- mParsedTypeData = true;
- }
- DbgCompileUnit* DbgModule::ParseCompileUnit(int compileUnitId)
- {
- return NULL;
- }
- void DbgModule::MapCompileUnitMethods(DbgCompileUnit * compileUnit)
- {
- }
- void DbgModule::MapCompileUnitMethods(int compileUnitId)
- {
- }
- void DbgModule::PopulateType(DbgType* dbgType)
- {
- }
- void DbgModule::PopulateTypeGlobals(DbgType* dbgType)
- {
- }
- void DbgModule::PopulateStaticVariableMap()
- {
- if (mPopulatedStaticVariables)
- return;
- for (auto staticVariable : mStaticVariables)
- {
- mStaticVariableMap[staticVariable->GetMappedName()] = staticVariable;
- }
- mPopulatedStaticVariables = true;
- }
- void DbgModule::ProcessDebugInfo()
- {
- }
- addr_target DbgModule::RemapAddr(addr_target addr)
- {
- if ((addr != 0) && (mPreferredImageBase != 0) && (mImageBase != 0))
- return addr + (intptr_target)(mImageBase - mPreferredImageBase);
- return addr;
- }
- void DbgModule::ParseAbbrevData(const uint8* data)
- {
- while (true)
- {
- int abbrevIdx = (int)DecodeULEB128(data);
- mDebugAbbrevPtrData[abbrevIdx] = data;
- if (abbrevIdx == 0)
- break;
- int entryTag = (int)DecodeULEB128(data);
- bool hasChildren = GET(char) == DW_CHILDREN_yes;
- while (true)
- {
- int attrName = (int)DecodeULEB128(data);
- int form = (int)DecodeULEB128(data);
- if ((attrName == 0) && (form == 0))
- break;
- }
- }
- }
- void DbgModule::ParseExceptionData()
- {
- if (mExceptionDirectory.IsEmpty())
- return;
- BP_ZONE("DbgModule::ParseExceptionData");
- for (auto entry : mExceptionDirectory)
- {
- const uint8* data = entry.mData;
- const uint8* dataEnd = data + entry.mSize;
- static int entryCount = 0;
- addr_target imageBase = GetTargetImageBase();
- while (data < dataEnd)
- {
- addr_target beginAddress = GET(uint32);
- addr_target endAddress = GET(uint32);
- uint32 unwindData = GET(uint32);
- //TODO: Apparently unwindData can refer to another runtime entry in the .pdata if the LSB is set to 1?
- beginAddress += (addr_target)imageBase;
- endAddress += (addr_target)imageBase;
- int exSize = (int)(endAddress - beginAddress);
- for (int exOffset = 0; true; exOffset += DBG_MAX_LOOKBACK)
- {
- int curSize = exSize - exOffset;
- if (curSize <= 0)
- break;
- BP_ALLOC_T(DbgExceptionDirectoryEntry);
- DbgExceptionDirectoryEntry* exceptionDirectoryEntry = mAlloc.Alloc<DbgExceptionDirectoryEntry>();
- exceptionDirectoryEntry->mAddress = beginAddress + exOffset;
- exceptionDirectoryEntry->mOrigAddressOffset = exOffset;
- exceptionDirectoryEntry->mAddressLength = curSize;
- exceptionDirectoryEntry->mExceptionPos = (int)unwindData;
- exceptionDirectoryEntry->mDbgModule = this;
- mDebugTarget->mExceptionDirectoryMap.Insert(exceptionDirectoryEntry);
- entryCount++;
- }
- }
- }
- }
- static int gIdx = 0;
- template <typename T> static bool IsTypeSigned() { return false; }
- template <> bool IsTypeSigned<int8>() { return true; }
- template <> bool IsTypeSigned<int16>() { return true; }
- template <> bool IsTypeSigned<int32>() { return true; }
- template <> bool IsTypeSigned<int64>() { return true; }
- #pragma warning(push)
- #pragma warning(disable:4302)
- #pragma warning(disable:4311)
- #pragma warning(disable:4312)
- #pragma warning(disable:4800)
- #pragma warning(disable:4800)
- template <typename T>
- T DbgModule::ReadValue(const uint8*& data, int form, int refOffset, const uint8** extraData, const uint8* startData)
- {
- gIdx++;
- switch (form)
- {
- case DW_FORM_strp:
- {
- int strOffset = GET(int);
- BF_ASSERT(mDebugStrData != NULL);
- const char* str = (const char*)mDebugStrData + strOffset;
- return (T)(intptr)str;
- }
- break;
- case DW_FORM_data1:
- {
- if (IsTypeSigned<T>())
- return (T)(intptr)GET(int8);
- else
- return (T)(uintptr)GET(uint8);
- }
- break;
- case DW_FORM_data2:
- {
- if (IsTypeSigned<T>())
- return (T)(intptr)GET(int16);
- else
- return (T)(uintptr)GET(uint16);
- }
- break;
- case DW_FORM_data4:
- {
- if (IsTypeSigned<T>())
- return (T)(intptr)GET(int32);
- else
- return (T)(uintptr)GET(uint32);
- }
- break;
- case DW_FORM_data8:
- {
- if (IsTypeSigned<T>())
- return (T)GET(int64);
- else
- return (T)GET(uint64);
- }
- break;
- case DW_FORM_ref1:
- {
- return (T)(intptr)GET(int8) + refOffset;
- }
- break;
- case DW_FORM_ref2:
- {
- return (T)(intptr)GET(int16) + refOffset;
- }
- break;
- case DW_FORM_ref4:
- {
- return (T)(intptr)GET(int32) + refOffset;
- }
- break;
- case DW_FORM_sec_offset:
- {
- intptr_target offset;
- if (mIsDwarf64)
- offset = (intptr_target)GET(int64);
- else
- offset = GET(int32);
- if (extraData != NULL)
- {
- *extraData = mDebugLocationData + offset;
- return 0;
- }
- return (T)offset;
- }
- break;
- case DW_FORM_addr:
- {
- return (T)GET(addr_target);
- }
- break;
- case DW_FORM_exprloc:
- {
- int64_t exprLen = DecodeULEB128(data);
- const uint8* endData = data + exprLen;
-
- if (extraData != NULL)
- *extraData = data;
-
- data = endData;
- return (T)exprLen;
- }
- break;
- case DW_FORM_flag_present:
- {
- //
- return (T)1;
- }
- break;
- case DW_FORM_flag:
- {
- //
- return (T)(intptr)GET(char);
- }
- break;
- case DW_FORM_sdata:
- return (T)DecodeSLEB128(data);
- case DW_FORM_udata:
- return (T)DecodeULEB128(data);
- case DW_FORM_string:
- {
- const char* str = (const char*)data;
- while (true)
- {
- uint8 val = *data;
- data++;
- if (val == 0)
- return (T)(intptr)str;
- }
- }
- case DW_FORM_block:
- {
- int blockLen = (int)DecodeULEB128(data);
- const uint8* retVal = data;
- data += blockLen;
- return (T)(intptr)retVal;
- }
- case DW_FORM_block1:
- {
- int blockLen = (int)*((uint8*)data);
- data += sizeof(uint8);
- const uint8* retVal = data;
- data += blockLen;
- return (T)(intptr)retVal;
- }
- default:
- assert("Not covered!" == 0);
- break;
- }
- return (T)0;
- }
- #pragma warning(pop)
- static int gAbbrevNum = 0;
- DbgType* DbgModule::GetOrCreateType(int typeIdx, DbgDataMap& dataMap)
- {
- if (typeIdx == 0)
- return NULL;
- DbgModule* linkedModule = GetLinkedModule();
- DbgType* dbgType = dataMap.Get<DbgType*>(typeIdx);
- if (dbgType != NULL)
- return dbgType;
- dbgType = mAlloc.Alloc<DbgType>();
- dbgType->mTypeIdx = (int)linkedModule->mTypes.size();
- linkedModule->mTypes.push_back(dbgType);
- dataMap.Set(typeIdx, dbgType);
- return dbgType;
- }
- typedef std::pair<DbgClassType, void*> DataPair;
- typedef llvm::SmallVector<DataPair, 16> DataStack;
- template <typename T>
- T DbgModule::GetOrCreate(int idx, DbgDataMap& dataMap)
- {
- if (idx == 0)
- return NULL;
- T val = dataMap.Get<T>(idx);
- if (val != NULL)
- return val;
- val = mAlloc.Alloc<typename RemoveTypePointer<T>::type >();
- dataMap.Set(idx, val);
- return val;
- }
- template <typename T>
- static T GetStackTop(DataStack* dataStack)
- {
- auto dataPair = dataStack->back();
- if (dataPair.first == RemoveTypePointer<T>::type::ClassType)
- return (T)dataPair.second;
- return NULL;
- }
- template <>
- DbgBlock* GetStackTop<DbgBlock*>(DataStack* dataStack)
- {
- auto dataPair = dataStack->back();
- if (dataPair.first == DbgBlock::ClassType)
- return (DbgBlock*)dataPair.second;
- if (dataPair.first == DbgSubprogram::ClassType)
- return &((DbgSubprogram*)dataPair.second)->mBlock;
- if (dataPair.first == DbgType::ClassType)
- return ((DbgType*)dataPair.second)->mBlockParam;
- return NULL;
- }
- template <typename T>
- static bool StackHasType(DataStack* dataStack)
- {
- for (auto itr : *dataStack)
- if (itr.first == RemoveTypePointer<T>::type::ClassType)
- return true;
- return false;
- }
- template <typename T>
- static T GetStackLast(DataStack* dataStack)
- {
- for (int i = (int)dataStack->size() - 1; i >= 0; i--)
- {
- if ((*dataStack)[i].first == RemoveTypePointer<T>::type::ClassType)
- return (T)(*dataStack)[i].second;
- }
- return NULL;
- }
- template <typename T>
- static DataPair MakeDataPair(T* data)
- {
- return DataPair(T::ClassType, data);
- }
- void DbgModule::FixupInnerTypes(int startingTypeIdx)
- {
- BP_ZONE("DbgModule_FixupInnerTypes");
- for (int typeIdx = startingTypeIdx; typeIdx < (int)mTypes.size(); typeIdx++)
- {
- DbgType* dbgType = mTypes[typeIdx];
- if ((dbgType->mPriority == DbgTypePriority_Primary_Implicit) && (dbgType->mParent != NULL) && (dbgType->mParent->mTypeCode != DbgType_Namespace) &&
- (dbgType->mParent->mPriority <= DbgTypePriority_Primary_Implicit))
- {
- auto primaryParent = dbgType->mParent->GetPrimaryType();
- dbgType->mParent->mSubTypeList.Clear();
- dbgType->mParent = primaryParent;
- primaryParent->mSubTypeList.PushBack(dbgType);
- }
- }
- }
- void DbgModule::MapTypes(int startingTypeIdx)
- {
- BP_ZONE("DbgModule_MapTypes");
-
- bool needsInnerFixups = false;
- for (int typeIdx = startingTypeIdx; typeIdx < (int)mTypes.size(); typeIdx++)
- {
- DbgType* dbgType = mTypes[typeIdx];
- BF_ASSERT(dbgType->mTypeCode != DbgType_Null);
-
- if ((dbgType->mTypeCode == DbgType_Namespace) && (dbgType->mPriority < DbgTypePriority_Primary_Implicit))
- continue;
-
- //TODO: Always valid?
- if (dbgType->mIsDeclaration)
- continue;
- // We were avoiding adding '<' names before, but that made it impossible to look up auto-named primary types ,
- // like in-place unions like '<unnamed-type-u>'
- if ((dbgType->mTypeName == NULL) || (dbgType->mName == NULL) /*|| (dbgType->mTypeName[0] == '<')*/)
- continue;
- if (dbgType->mTypeCode > DbgType_DefinitionEnd)
- {
- // Only add "definition types"
- continue;
- }
- if (dbgType->mTypeCode == DbgType_Namespace)
- {
- bool isQualifiedNamespace = false;
- for (const char* cPtr = dbgType->mTypeName; *cPtr != '\0'; cPtr++)
- if (*cPtr == '.')
- isQualifiedNamespace = true;
- if (isQualifiedNamespace)
- continue; // Don't add fully qualified namespaces (they come from the 'using' implementation)*
- }
- if (dbgType->mHasStaticMembers)
- {
- for (auto member : dbgType->mMemberList)
- if ((member->mIsStatic) && (member->mLocationData != NULL))
- dbgType->mDefinedMembersSize++;
- }
-
- if ((dbgType->mTypeName != NULL) && (strcmp(dbgType->mTypeName, "@") == 0))
- {
- // Globals type.
- continue;
- }
- auto prevTypeEntry = FindType(dbgType->mName, dbgType->mLanguage);
- // Only replace previous instance if its a declaration
- if (prevTypeEntry != NULL)
- {
- auto prevType = prevTypeEntry->mValue;
- if (dbgType->mCompileUnit->mDbgModule != prevType->mCompileUnit->mDbgModule)
- {
- // Don't replace original types with hot types -- those need to be inserted in the the hot alternates list
- BF_ASSERT(dbgType->mCompileUnit->mDbgModule->IsObjectFile());
- prevType->mHotNewType = dbgType;
- continue;
- }
- // Never override explicit primaries
- if (prevType->mPriority == DbgTypePriority_Primary_Explicit)
- continue;
- if (dbgType->mTypeCode == DbgType_TypeDef)
- {
- // Typedef can never override anything
- continue;
- }
- if (prevType->mTypeCode == DbgType_TypeDef)
- {
- if (dbgType->mTypeCode != DbgType_TypeDef)
- {
- // Allow this to override
- prevTypeEntry->mValue = dbgType;
- }
- continue;
- }
- // Don't replace a ptr to an BfObject with a BfObject
- if ((prevType->mTypeCode == DbgType_Ptr) && (dbgType->mTypeCode == DbgType_Struct))
- continue;
- if ((prevType->mTypeCode == DbgType_Struct) && (dbgType->mTypeCode == DbgType_Ptr))
- {
- // Allow this to override
- prevTypeEntry->mValue = dbgType;
- continue;
- }
- if (prevType->mTypeCode == DbgType_Namespace)
- {
- if (dbgType->mTypeCode != DbgType_Namespace)
- {
- // Old type was namespace but new isn't? Replace old type.
- while (!prevType->mSubTypeList.IsEmpty())
- {
- DbgType* subType = prevType->mSubTypeList.PopFront();
- subType->mParent = dbgType;
- dbgType->mSubTypeList.PushBack(subType);
- }
- prevType->mPriority = DbgTypePriority_Normal;
- if (dbgType->mPriority < DbgTypePriority_Primary_Implicit)
- dbgType->mPriority = DbgTypePriority_Primary_Implicit;
- prevTypeEntry->mValue = dbgType;
- continue;
- }
- // We definitely didn't want to do this for MS. For DWARF?
- //prevType->mAlternates.PushFront(dbgType, &mAlloc);
- continue;
- }
- else
- {
- // New type is namespace but old wasn't? Ignore new type.
- if (dbgType->mTypeCode == DbgType_Namespace)
- continue;
- if (dbgType->mIsDeclaration)
- continue;
- if (!prevType->mIsDeclaration)
- {
- if ((prevType->mCompileUnit == NULL) || (dbgType->mLanguage < prevType->mLanguage))
- {
- // We always want 'Beef' types to supersede 'C' types, but don't override the built-in primitive types
- continue;
- }
-
- if (prevType->mDefinedMembersSize > 0)
- {
- if (dbgType->mDefinedMembersSize > 0)
- {
- // We create an 'alternates' list for all types that define at least one static field
- if (prevType->mHasStaticMembers)
- prevType->mAlternates.PushFront(dbgType, &mAlloc);
- }
- continue;
- }
- // if (prevType->mDefinedMembersSize > dbgType->mDefinedMembersSize)
- // {
- // continue;
- // }
- if (prevType->mMethodsWithParamsCount > dbgType->mMethodsWithParamsCount)
- {
- // This handles a special case where methods without line data like <Enum>.HasFlags doesn't show containing
- // params in cases where it gets inlined
- continue;
- }
- // Types with method lists are preferred
- if ((!prevType->mMethodList.IsEmpty()) && (dbgType->mMethodList.IsEmpty()))
- continue;
- if ((prevType->mTypeCode == DbgType_Ptr) && (prevType->mTypeParam != NULL) && (!prevType->mTypeParam->mMethodList.IsEmpty()))
- continue;
- }
- // Replace type
- if (!prevType->mSubTypeList.IsEmpty())
- needsInnerFixups = true;
- prevType->mPriority = DbgTypePriority_Normal;
- if (dbgType->mPriority == DbgTypePriority_Normal)
- dbgType->mPriority = DbgTypePriority_Primary_Implicit;
- prevTypeEntry->mValue = dbgType;
- continue;
- }
- }
- if ((dbgType->mParent != NULL) && (dbgType->mParent->mTypeCode != DbgType_Namespace) && (dbgType->mParent->mPriority <= DbgTypePriority_Primary_Implicit))
- needsInnerFixups = true;
- if (dbgType->mPriority == DbgTypePriority_Normal)
- dbgType->mPriority = DbgTypePriority_Primary_Implicit;
- mTypeMap.Insert(dbgType);
- }
- if (needsInnerFixups)
- FixupInnerTypes(startingTypeIdx);
- }
- void DbgModule::CreateNamespaces()
- {
- BP_ZONE("DbgModule::CreateNamespaces");
- int startLength = (int)mTypes.size();
- for (int typeIdx = 0; typeIdx < startLength; typeIdx++)
- {
- DbgType* dbgType = mTypes[typeIdx];
-
- if (dbgType->mName == NULL)
- continue;
- if ((dbgType->mTypeCode == DbgType_Namespace) && (dbgType->mTagIdx != 0))
- {
- auto namespaceTypeEntry = FindType(dbgType->mName, dbgType->GetLanguage());
- DbgType* namespaceType;
- if (namespaceTypeEntry == NULL)
- {
- namespaceType = mAlloc.Alloc<DbgType>();
- namespaceType->mTypeCode = DbgType_Namespace;
- namespaceType->mLanguage = dbgType->mLanguage;
- namespaceType->mCompileUnit = dbgType->mCompileUnit;
- namespaceType->mTypeIdx = (int)mTypes.size();
- namespaceType->mPriority = DbgTypePriority_Primary_Explicit;
- namespaceType->mName = dbgType->mName;
- namespaceType->mTypeName = dbgType->mTypeName;
- if (dbgType->mParent != NULL)
- {
- namespaceType->mParent = dbgType->mParent->GetPrimaryType();
- namespaceType->mParent->mSubTypeList.PushBack(namespaceType);
- }
- else
- {
- namespaceType->mCompileUnit->mGlobalType->mSubTypeList.PushBack(namespaceType);
- }
- mTypes.push_back(namespaceType);
- mTypeMap.Insert(namespaceType);
- }
- else
- namespaceType = namespaceTypeEntry->mValue;
-
- while (!dbgType->mMemberList.IsEmpty())
- {
- DbgVariable* curVar = dbgType->mMemberList.PopFront();
- namespaceType->mMemberList.PushBack(curVar);
- }
- DbgType* prevType = NULL;
- DbgType* curType = dbgType->mSubTypeList.mHead;
- while (curType != NULL)
- {
- DbgType* nextType = curType->mNext;
- if (curType->mPriority >= DbgTypePriority_Primary_Implicit)
- {
- dbgType->mSubTypeList.Remove(curType, prevType);
- namespaceType->mSubTypeList.PushBack(curType);
- }
- prevType = curType;
- curType = nextType;
- }
- continue;
- }
- }
- // If we didn't have a parent type for a namespace (ie: if System.Collections wasn't linked to System) then we wait
- // until the end and move those from the global list to the parent list
- for (int typeIdx = startLength; typeIdx < (int)mTypes.size(); typeIdx++)
- {
- DbgType* dbgType = mTypes[typeIdx];
- if (dbgType->mParent != NULL)
- continue;
-
- char* typeName = (char*)dbgType->mTypeName;
- int lastDotIdx = -1;
- for (int i = 0; true; i++)
- {
- char c = typeName[i];
- if (c == 0)
- break;
- if (c == '.')
- lastDotIdx = i;
- }
- if (lastDotIdx == -1)
- continue;
- typeName[lastDotIdx] = 0;
- dbgType->mTypeName = typeName + lastDotIdx + 1;
- auto parentEntry = FindType(typeName, dbgType->GetLanguage());
- typeName[lastDotIdx] = '.';
- if (parentEntry == NULL)
- continue;
- auto parentType = parentEntry->mValue;
- dbgType->mCompileUnit->mGlobalType->mSubTypeList.Remove(dbgType);
- dbgType->mParent = parentType;
- parentType->mSubTypeList.PushBack(dbgType);
- }
- }
- void DbgModule::FindTemplateStr(const char*& name, int& templateNameIdx)
- {
- if (templateNameIdx == 0)
- {
- for (int i = 0; name[i] != 0; i++)
- {
- if (name[i] == '<')
- {
- templateNameIdx = i;
- return;
- }
- }
- templateNameIdx = -1;
- }
- }
- void DbgModule::TempRemoveTemplateStr(const char*& name, int& templateNameIdx)
- {
- if (templateNameIdx == 0)
- FindTemplateStr(name, templateNameIdx);
- if (templateNameIdx == -1)
- return;
- if (!DbgIsStrMutable(name))
- name = DbgDupString(name);
- ((char*)name)[templateNameIdx] = 0;
- }
- void DbgModule::ReplaceTemplateStr(const char*& name, int& templateNameIdx)
- {
- if (templateNameIdx > 0)
- ((char*)name)[templateNameIdx] = '<';
- }
- void DbgModule::MapSubprogram(DbgSubprogram* dbgSubprogram)
- {
- if (dbgSubprogram->mBlock.IsEmpty())
- return;
- int progSize = (int)(dbgSubprogram->mBlock.mHighPC - dbgSubprogram->mBlock.mLowPC);
- for (int progOffset = 0; true; progOffset += DBG_MAX_LOOKBACK)
- {
- int curSize = progSize - progOffset;
- if (curSize <= 0)
- break;
-
- BP_ALLOC_T(DbgSubprogramMapEntry);
- DbgSubprogramMapEntry* subprogramMapEntry = mAlloc.Alloc<DbgSubprogramMapEntry>();
- subprogramMapEntry->mAddress = dbgSubprogram->mBlock.mLowPC + progOffset;
- subprogramMapEntry->mEntry = dbgSubprogram;
- mDebugTarget->mSubprogramMap.Insert(subprogramMapEntry);
- }
- }
- bool DbgModule::ParseDWARF(const uint8*& dataPtr)
- {
- BP_ZONE("ParseDWARF");
- const uint8* data = dataPtr;
- const uint8* startData = mDebugInfoData;
- int dataOfs = (int)(data - mDebugInfoData);
- intptr_target length = GET(int);
-
- DbgModule* linkedModule = GetLinkedModule();
- if (length == -1)
- {
- mIsDwarf64 = true;
- length = (intptr_target)GET(int64);
- }
- else
- mIsDwarf64 = false;
- if (length == 0)
- return false;
- const uint8* dataEnd = data + length;
- int version = GET(short);
- int abbrevOffset = GET(int);
- char pointerSize = GET(char);
- ParseAbbrevData(mDebugAbbrevData + abbrevOffset);
- DbgCompileUnit* compileUnit = new DbgCompileUnit(this);
- mDbgFlavor = DbgFlavor_GNU;
- compileUnit->mDbgModule = this;
- mCompileUnits.push_back(compileUnit);
-
- DbgSubprogram* subProgram = NULL;
-
- //std::map<int, DbgType*> typeMap;
- //std::map<int, DbgSubprogram*> subprogramMap;
- int tagStart = (int)(data - startData);
- int tagEnd = (int)(dataEnd - startData);
- DbgDataMap dataMap(tagStart, tagEnd);
- DataStack dataStack;
- Array<AbstractOriginEntry> abstractOriginReplaceList;
-
- Array<int> deferredArrayDims;
- int startingTypeIdx = (int)linkedModule->mTypes.size();
- while (data < dataEnd)
- {
- gAbbrevNum++;
- const uint8* tagDataStart = data;
- int tagIdx = (int)(tagDataStart - startData);
-
- int abbrevIdx = (int)DecodeULEB128(data);
- const uint8* abbrevData = mDebugAbbrevPtrData[abbrevIdx];
-
- if (abbrevIdx == 0)
- {
- if (deferredArrayDims.size() > 0)
- {
- DbgType* arrType = GetStackTop<DbgType*>(&dataStack);
- BF_ASSERT(arrType->mTypeCode == DbgType_SizedArray);
- arrType->mSize = deferredArrayDims[0]; // Byte count still needs to be multiplied by the underlying type size
-
- DbgType* rootArrType = arrType;
- for (int dimIdx = 0; dimIdx < (int)deferredArrayDims.size() - 1; dimIdx++)
- {
- int dimSize = deferredArrayDims[dimIdx];
-
- DbgType* subArrType = mAlloc.Alloc<DbgType>();
- subArrType->mCompileUnit = compileUnit;
- subArrType->mLanguage = compileUnit->mLanguage;
- subArrType->mTypeIdx = (int)linkedModule->mTypes.size();
- linkedModule->mTypes.push_back(subArrType);
-
- subArrType->mTypeCode = DbgType_SizedArray;
- subArrType->mTypeParam = arrType->mTypeParam;
- subArrType->mSize = deferredArrayDims[dimIdx + 1];
- arrType->mTypeParam = subArrType;
- arrType = subArrType;
- }
- deferredArrayDims.Clear();
- }
- dataStack.pop_back();
- continue;
- }
-
- int entryTag = (int) DecodeULEB128(abbrevData);
- bool hasChildren = GET_FROM(abbrevData, char) == DW_CHILDREN_yes;
- int64 atLowPC = 0;
- int64 atHighPC = 0;
- int64 atRanges = 0;
- bool hasRanges = false;
- const uint8* atFrameBase = NULL;
- int64_t atFrameBaseLength = 0;
- int64 atLocationLen = 0;
- const uint8* atLocationData = 0;
- const char* atProducer = NULL;
- const char* atName = NULL;
- const char* atCompDir = NULL;
- const char* atLinkageName = NULL;
- int64 atConstValue = 0;
- int atDataMemberLocation = 0;
- const uint8* atDataMemberData = NULL;
- int atDeclFile = 0;
- int atDeclLine = 0;
- int atCallFile = 0;
- int atCallLine = 0;
- int atCount = 0;
- int atType = 0;
- int atImport = 0;
- int atInline = 0;
- int atArtificial = 0;
- int atExternal = 0;
- int atByteSize = -1;
- int atEncoding = 0;
- int atSpecification = 0;
- int atObjectPointer = 0;
- int atBitOffset = 0;
- int atBitSize = 0;
- int atAbstractOrigin = 0;
- const uint8* atVirtualLocData = NULL;
- bool atDeclaration = false;
- bool atVirtual = false;
- bool hadConstValue = false;
- bool hadMemberLocation = false;
- bool isOptimized = false;
- DataPair newDataPair;
- while (true)
- {
- int attrName = (int)DecodeULEB128(abbrevData);
- int form = (int)DecodeULEB128(abbrevData);
- if ((attrName == 0) && (form == 0))
- break;
- switch (attrName)
- {
- case DW_AT_sibling:
- ReadValue<char>(data, form);
- break;
- case DW_AT_location:
- atLocationLen = (int)ReadValue<uint>(data, form, dataOfs, &atLocationData, startData);
- break;
- case DW_AT_name:
- atName = ReadValue<const char*>(data, form);
- break;
- case DW_AT_ordering:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_byte_size:
- atByteSize = ReadValue<int>(data, form);
- break;
- case DW_AT_bit_offset:
- atBitOffset = ReadValue<int>(data, form);
- break;
- case DW_AT_bit_size:
- atBitSize = ReadValue<int>(data, form);
- break;
- case DW_AT_stmt_list:
- ReadValue<int64_t>(data, form);
- break;
- case DW_AT_low_pc:
- atLowPC = RemapAddr((addr_target)ReadValue<int64_t>(data, form));
- break;
- case DW_AT_high_pc:
- atHighPC = ReadValue<int64_t>(data, form);
- break;
- case DW_AT_language:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_discr:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_discr_value:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_visibility:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_import:
- atImport = ReadValue<int>(data, form) + dataOfs;
- break;
- case DW_AT_string_length:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_common_reference:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_comp_dir:
- atCompDir = ReadValue<const char*>(data, form);
- break;
- case DW_AT_const_value:
- atConstValue = ReadValue<int64>(data, form);
- hadConstValue = true;
- break;
- case DW_AT_containing_type:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_default_value:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_inline:
- atInline = ReadValue<int>(data, form);
- break;
- case DW_AT_is_optional:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_lower_bound:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_producer:
- atProducer = ReadValue<const char*>(data, form);
- break;
- case DW_AT_prototyped:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_return_addr:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_start_scope:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_bit_stride:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_upper_bound:
- // Lower bound not supported
- atCount = ReadValue<int>(data, form);
- break;
- case DW_AT_abstract_origin:
- atAbstractOrigin = ReadValue<int>(data, form, dataOfs);
- break;
- case DW_AT_accessibility:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_address_class:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_artificial:
- atArtificial = ReadValue<int>(data, form);
- break;
- case DW_AT_base_types:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_calling_convention:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_count:
- atCount = ReadValue<uint>(data, form);
- break;
- case DW_AT_data_member_location:
- if (form == DW_FORM_exprloc)
- {
- atDataMemberLocation = (int)ReadValue<uint>(data, form, dataOfs, &atDataMemberData);
- hadMemberLocation = true;
- }
- else
- {
- atDataMemberLocation = (int)ReadValue<uint>(data, form);
- hadMemberLocation = true;
- }
- break;
- case DW_AT_decl_column:
- /*TODO:*/ ReadValue<uint32>(data, form);
- break;
- case DW_AT_decl_file:
- atDeclFile = ReadValue<uint32>(data, form);
- break;
- case DW_AT_decl_line:
- atDeclLine = ReadValue<uint32>(data, form);
- break;
- case DW_AT_declaration:
- atDeclaration = ReadValue<bool>(data, form);
- break;
- case DW_AT_discr_list:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_encoding:
- atEncoding = ReadValue<int>(data, form);
- break;
- case DW_AT_external:
- atExternal = ReadValue<int>(data, form);
- break;
- case DW_AT_frame_base:
- atFrameBaseLength = (int64_t)ReadValue<uint64_t>(data, form, dataOfs, &atFrameBase);
- break;
- case DW_AT_friend:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_identifier_case:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_macro_info:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_namelist_item:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_priority:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_segment:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_specification:
- atSpecification = ReadValue<int>(data, form, dataOfs);
- break;
- case DW_AT_static_link:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_type:
- atType = ReadValue<int>(data, form, dataOfs);
- break;
- case DW_AT_use_location:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_variable_parameter:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_virtuality:
- atVirtual = ReadValue<int>(data, form) != 0;
- break;
- case DW_AT_vtable_elem_location:
- ReadValue<uint64_t>(data, form, dataOfs, &atVirtualLocData);
- break;
- case DW_AT_allocated:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_associated:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_data_location:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_byte_stride:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_entry_pc:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_use_UTF8:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_extension:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_ranges:
- atRanges = (int)ReadValue<uint>(data, form);
- hasRanges = true;
- break;
- case DW_AT_trampoline:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_call_column:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_call_file:
- atCallFile = ReadValue<uint32>(data, form);
- break;
- case DW_AT_call_line:
- atCallLine = ReadValue<uint32>(data, form);
- break;
- case DW_AT_description:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_binary_scale:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_decimal_scale:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_small:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_decimal_sign:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_digit_count:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_picture_string:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_mutable:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_threads_scaled:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_explicit:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_object_pointer:
- atObjectPointer = ReadValue<int>(data, form);
- break;
- case DW_AT_endianity:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_elemental:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_pure:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_recursive:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_signature:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_main_subprogram:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_data_bit_offset:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_const_expr:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_enum_class:
- /*TODO:*/ ReadValue<int>(data, form);
- break;
- case DW_AT_linkage_name:
- atLinkageName = ReadValue<const char*>(data, form);
- break;
- //
- case DW_AT_MIPS_linkage_name:
- atLinkageName = ReadValue<const char*>(data, form);
- break;
- case DW_AT_APPLE_optimized:
- isOptimized = ReadValue<bool>(data, form);
- break;
- default:
- ReadValue<int>(data, form);
- break;
- }
- }
- if ((hasRanges) && (atLowPC == 0))
- {
- addr_target* rangeData = (addr_target*)(mDebugRangesData + atRanges);
- while (true)
- {
- addr_target lowPC = *(rangeData++);
- if (lowPC == 0)
- break;
- addr_target highPC = *(rangeData++);
- if (compileUnit->mLowPC != (addr_target)-1)
- {
- // These are sometimes relative to the compile unit and sometimes absolute
- if (highPC + compileUnit->mLowPC <= compileUnit->mHighPC)
- {
- lowPC += compileUnit->mLowPC;
- highPC += compileUnit->mLowPC;
- }
- }
- highPC -= lowPC;
- // Select the largest range. We have some cases where some hoisting and such will
- // give us a small inlining aberration much earlier than expected so this ignores that
- if ((int64)highPC > atHighPC)
- {
- atLowPC = lowPC;
- atHighPC = highPC;
- }
- /*if ((atLowPC == 0) || (lowPC < (addr_target)atLowPC))
- atLowPC = lowPC;
- if (highPC > (addr_target)atHighPC)
- atHighPC = highPC;*/
- }
-
- }
- switch (entryTag)
- {
- case DW_TAG_compile_unit:
- {
- newDataPair = MakeDataPair(compileUnit);
- compileUnit->mName = atName;
- compileUnit->mProducer = atProducer;
- if (atCompDir != NULL)
- compileUnit->mCompileDir = atCompDir;
- if (atLowPC != 0)
- {
- compileUnit->mLowPC = (addr_target)atLowPC;
- compileUnit->mHighPC = (addr_target)(atLowPC + atHighPC);
- }
- if (compileUnit->mProducer.IndexOf("Beef") != -1)
- {
- compileUnit->mLanguage = DbgLanguage_Beef;
- }
- else
- {
- compileUnit->mLanguage = DbgLanguage_C;
- }
- compileUnit->mGlobalType->mLanguage = compileUnit->mLanguage;
- }
- break;
- case DW_TAG_imported_module:
- {
- DbgType* parentType = GetStackTop<DbgType*>(&dataStack);
- DbgType* importType = GetOrCreateType(atImport, dataMap);
- if (parentType != NULL) // Parent type is NULL for Clang DbgModule info
- parentType->mUsingNamespaces.PushFront(importType, &mAlloc);
- }
- break;
- case DW_TAG_inlined_subroutine:
- case DW_TAG_subprogram:
- {
- /*//TODO: This is a test. See if it breaks anything.
- if ((atExternal != 0) && (atLowPC == 0))
- break;*/
- if (atSpecification == 0)
- {
- subProgram = GetOrCreate<DbgSubprogram*>(tagIdx, dataMap);
- subProgram->mCompileUnit = compileUnit;
- subProgram->mVirtual = atVirtual;
- subProgram->mIsOptimized = isOptimized;
- if (atVirtualLocData != NULL)
- {
- const uint8* opPtr = atVirtualLocData;
- if (*(opPtr++) == DW_OP_constu)
- {
- subProgram->mVTableLoc = (int)DecodeSLEB128(opPtr) * sizeof(addr_target);
- }
- }
- //subProgram->mVTableLoc = atVirtualLoc * sizeof(addr_target);
- //SplitName(atName, subProgram->mName, subProgram->mTemplateName);
- subProgram->mName = atName;
- subProgram->mLinkName = atLinkageName;
- if (atAbstractOrigin != NULL)
- {
- DbgSubprogram* originSubProgram = GetOrCreate<DbgSubprogram*>(atAbstractOrigin, dataMap);
- auto abstractOriginEntry = AbstractOriginEntry::Create(DbgSubprogram::ClassType, subProgram, originSubProgram);
- abstractOriginReplaceList.push_back(abstractOriginEntry);
- }
- subProgram->mParentType = GetStackTop<DbgType*>(&dataStack);
- newDataPair = MakeDataPair(subProgram);
-
- //if ((atLinkageName != NULL) && (subProgram->mParentType != NULL))
- //subProgram->mParentType->mDefinedMembersCount++;
- mSubprograms.push_back(subProgram);
- if (subProgram->mParentType != NULL)
- {
- subProgram->mParentType->mMethodList.PushBack(subProgram);
- }
- else
- {
- compileUnit->mGlobalType->mMethodList.PushBack(subProgram);
- }
- }
- else
- {
- subProgram = dataMap.Get<DbgSubprogram*>(atSpecification);
- BF_ASSERT(subProgram != NULL);
- // We remove params form the declaration and re-add the real ones here
- subProgram->mParams.Clear();
- }
-
- newDataPair = MakeDataPair(subProgram);
- DbgBlock* dwBlock = &subProgram->mBlock;
-
- if (atType != 0)
- subProgram->mReturnType = GetOrCreateType(atType, dataMap);
- if (!atDeclaration)
- {
- dwBlock->mLowPC = (addr_target)atLowPC;
- dwBlock->mHighPC = (addr_target)(atLowPC + atHighPC);
- if (dwBlock->mLowPC != 0)
- {
- compileUnit->mLowPC = std::min(compileUnit->mLowPC, dwBlock->mLowPC);
- compileUnit->mHighPC = std::max(compileUnit->mHighPC, dwBlock->mHighPC);
- }
- if (atObjectPointer != 0)
- subProgram->mHasThis = true;
- subProgram->mFrameBaseLen = (int)atFrameBaseLength;
- subProgram->mFrameBaseData = atFrameBase;
-
- if (atHighPC > 0)
- {
- MapSubprogram(subProgram);
- }
- }
- if (entryTag == DW_TAG_inlined_subroutine)
- {
- DbgSubprogram* parentSubProgram = GetStackLast<DbgSubprogram*>(&dataStack);
- subProgram->mInlineeInfo = mAlloc.Alloc<DbgInlineeInfo>();
- subProgram->mInlineeInfo->mInlineParent = parentSubProgram;
- subProgram->mInlineeInfo->mRootInliner = parentSubProgram->GetRootInlineParent();
- subProgram->mFrameBaseData = parentSubProgram->mFrameBaseData;
- subProgram->mFrameBaseLen = parentSubProgram->mFrameBaseLen;
- }
-
- //if (subProgram->mParentType != NULL)
- //subProgram->mParentType->mDefinedMembersCount++;
- }
- break;
- case DW_TAG_lexical_block:
- {
- DbgBlock* prevBlock = GetStackTop<DbgBlock*>(&dataStack);
- DbgBlock* dwBlock = mAlloc.Alloc<DbgBlock>();
- if (hasRanges)
- {
- dwBlock->mLowPC = -1;
- dwBlock->mHighPC = (addr_target)atRanges;
- }
- else
- {
- dwBlock->mLowPC = (addr_target)atLowPC;
- dwBlock->mHighPC = (addr_target)(atLowPC + atHighPC);
- }
- newDataPair = MakeDataPair(dwBlock);
- prevBlock->mSubBlocks.PushBack(dwBlock);
- }
- break;
- case DW_TAG_variable:
- {
- DbgBlock* dwBlock = GetStackTop<DbgBlock*>(&dataStack);
- if (atName && !strncmp(atName, "__asmLines", 10))
- {
- const char* ptr = strchr(atName, '.');
- if (!ptr)
- break;
- int declLine = atDeclLine;
- Array<int> asmLines;
- int curAsmLine = 0;
- int curRunCount = 1; // initial value is starting line, with an assumed run count of 1
- bool parity = true; // starting line is standalone; everything afterwards is in pairs
- while (true)
- {
- ++ptr;
- if (!*ptr)
- break;
- String s;
- if (*ptr == '$')
- {
- ++ptr;
- const char* dollarPtr = strchr(ptr, '$');
- if (!dollarPtr)
- break;
- s = String(ptr, (int)(dollarPtr - ptr));
- ptr = dollarPtr;
- }
- else
- {
- s += *ptr;
- }
-
- //int asmLine = atoi(s.c_str());
- //asmLines.push_back(asmLine);
- const char* sPtr = s.c_str();
- int decodedValue = (int)DecodeULEB32(sPtr);
- if (!parity)
- {
- curRunCount = decodedValue;
- }
- else
- {
- for (int iLine=0; iLine<curRunCount; ++iLine)
- {
- curAsmLine += decodedValue;
- asmLines.push_back(curAsmLine);
- }
- }
- parity = !parity;
- }
- BF_ASSERT(!parity);
- if (dwBlock->mAsmDebugLineMap == NULL)
- {
- mAsmDebugLineMaps.resize(mAsmDebugLineMaps.size() + 1);
- dwBlock->mAsmDebugLineMap = &mAsmDebugLineMaps.back();
- }
- auto mapIter = dwBlock->mAsmDebugLineMap->find(declLine);
- if (mapIter != dwBlock->mAsmDebugLineMap->end())
- {
- auto& dstVec = mapIter->second;
- dstVec.Reserve(dstVec.size() + asmLines.size());
- //dstVec.insert(dstVec.end(), asmLines.begin(), asmLines.end());
- if (!asmLines.IsEmpty())
- dstVec.Insert(dstVec.size(), &asmLines[0], asmLines.size());
- }
- else
- {
- (*dwBlock->mAsmDebugLineMap)[declLine] = std::move(asmLines);
- }
- break;
- }
- bool addToGlobalVarMap = false;
- bool isNewVariable = true;
- DbgVariable* dbgVariable = NULL;
- if (atSpecification != 0)
- {
- //dbgVariable = dataMap.Get<DbgVariable*>(atSpecification);
- //BF_ASSERT(dbgVariable != NULL);
- dbgVariable = GetOrCreate<DbgVariable*>(atSpecification, dataMap);
- //dbgVariable = dataMap.Get<DbgVariable*>(atSpecification);
- //BF_ASSERT(dbgVariable != NULL);
- }
- else if (dwBlock != NULL)
- {
- dbgVariable = GetOrCreate<DbgVariable*>(tagIdx, dataMap);
- dwBlock->mVariables.PushBack(dbgVariable);
- }
- else
- {
- DbgType* dbgType = GetStackTop<DbgType*>(&dataStack);
- bool wantGlobal = true;
- if (compileUnit->mLanguage == DbgLanguage_Beef)
- {
- // Don't show certain global variables in Beef -- that includes things like VTable data
- if (atName[0] == '_')
- wantGlobal = false;
- }
- if ((dbgType == NULL) && (wantGlobal))
- {
- /*DbgCompileUnit* topCompileUnit = GetStackTop<DbgCompileUnit*>(&dataStack);
- if (topCompileUnit != NULL)
- dbgType = &topCompileUnit->mGlobalType;*/
- dbgType = linkedModule->mMasterCompileUnit->mGlobalType;
- auto foundEntry = mGlobalVarMap.Find(atName);
- if (foundEntry != NULL)
- {
- isNewVariable = false;
- dbgVariable = foundEntry->mValue;
- }
- else
- {
- addToGlobalVarMap = true;
- }
- }
- if (dbgVariable == NULL)
- dbgVariable = GetOrCreate<DbgVariable*>(tagIdx, dataMap);
- dbgVariable->mIsStatic = true;
- //TODO: dbgType can be NULL. This only (apparently?) happens for DW_TAG_inlined_subroutine, which we don't handle right now...
- if (dbgType != NULL)
- {
- BF_ASSERT(dbgType->IsNamespace() || (dbgType->mTypeCode == DbgType_Root));
-
- if (isNewVariable)
- dbgType->mMemberList.PushBack(dbgVariable);
- }
- }
- if (dbgVariable != NULL)
- {
- if (atSpecification == 0)
- {
- dbgVariable->mIsParam = false;
- dbgVariable->mName = atName;
- dbgVariable->mConstValue = atConstValue;
- dbgVariable->mType = GetOrCreateType(atType, dataMap);
- dbgVariable->mIsConst = hadConstValue;
- dbgVariable->mIsStatic = !hadMemberLocation;
- dbgVariable->mIsExtern = atExternal != 0;
- }
- if (atLinkageName != NULL)
- dbgVariable->mLinkName = atLinkageName;
- dbgVariable->mLocationLen = (int8)atLocationLen;
- dbgVariable->mLocationData = atLocationData;
- dbgVariable->mCompileUnit = compileUnit;
- /*if (dbgVariable->mIsStatic && !dbgVariable->mIsConst && (dbgVariable->mLocationLen > 0) && (dbgVariable->mIsExtern))
- {
- DbgAddrType addrType = DbgAddrType_Value;
- //
- addr_target valAddr = mDebugTarget->EvaluateLocation(dbgVariable->mCompileUnit->mDbgModule, NULL, dbgVariable->mLocationData, dbgVariable->mLocationLen, NULL, &addrType);
- if ((addrType == DbgAddrType_Target) && (valAddr != 0))
- {
- dbgVariable->mStaticCachedAddr = valAddr;
- if (dbgVariable->mLinkName != NULL)
- mStaticVariables.push_back(dbgVariable);
- }
- else
- dbgVariable->mIsStatic = false;
- }*/
- // We had to remove the above for hot loading, calculate the mStaticCachedAddr later. Just put into mStaticVariables for now
- mStaticVariables.push_back(dbgVariable);
- if (atAbstractOrigin != NULL)
- {
- DbgVariable* originVariable = GetOrCreate<DbgVariable*>(atAbstractOrigin, dataMap);
- auto abstractOriginEntry = AbstractOriginEntry::Create(DbgVariable::ClassType, dbgVariable, originVariable);
- if (atAbstractOrigin < tagIdx)
- abstractOriginEntry.Replace();
- else
- abstractOriginReplaceList.push_back(abstractOriginEntry);
- }
- else if (dbgVariable->mName == NULL)
- dbgVariable->mName = "_unnamed";
- if (addToGlobalVarMap)
- mGlobalVarMap.Insert(dbgVariable);
- newDataPair = MakeDataPair(dbgVariable);
- }
- }
- break;
- case DW_TAG_formal_parameter:
- {
- DbgSubprogram* dwSubprogram = GetStackTop<DbgSubprogram*>(&dataStack);
- if (dwSubprogram == NULL)
- {
- if ((atName == NULL) && (atAbstractOrigin == 0))
- {
- DbgType* dbgType = GetStackTop<DbgType*>(&dataStack);
- if ((dbgType == NULL) || (dbgType->mTypeCode != DbgType_Subroutine))
- break;
- //TODO: Add params to subroutine type
- break;
- }
- break;
- }
-
- if ((dwSubprogram->mParams.IsEmpty()) && (dwSubprogram->mParentType != 0))
- dwSubprogram->mParentType->mMethodsWithParamsCount++;
- //DbgVariable* dbgVariable = mAlloc.Alloc<DbgVariable>();
- DbgVariable* dwVariable = GetOrCreate<DbgVariable*>(tagIdx, dataMap);
- dwSubprogram->mParams.PushBack(dwVariable);
- if (atArtificial != 0)
- {
- dwSubprogram->mHasThis = true;
- if (atName == NULL)
- atName = "this";
- }
- dwVariable->mCompileUnit = compileUnit;
- dwVariable->mIsParam = true;
- dwVariable->mName = atName;
- dwVariable->mLocationLen = (int)atLocationLen;
- dwVariable->mLocationData = atLocationData;
- dwVariable->mType = GetOrCreateType(atType, dataMap);
- if (atAbstractOrigin != 0)
- {
-
- }
- }
- break;
- case DW_TAG_enumerator:
- {
- DbgVariable* member = mAlloc.Alloc<DbgVariable>();
- member->mCompileUnit = compileUnit;
- member->mConstValue = atConstValue;
- member->mName = atName;
- member->mIsStatic = true;
- member->mIsConst = true;
- DbgType* parentType = GetStackTop<DbgType*>(&dataStack);
- parentType->mMemberList.PushBack(member);
- member->mMemberOffset = atDataMemberLocation;
- //member->mType = parentType->mTypeParam;
- member->mType = parentType;
-
- // Insert into parent's namespace
- auto prevTop = dataStack.back();
- dataStack.pop_back();
- DbgBlock* dwBlock = GetStackTop<DbgBlock*>(&dataStack);
- dataStack.push_back(prevTop);
- if (dwBlock != NULL)
- {
- DbgVariable* dwVariable = mAlloc.Alloc<DbgVariable>();
- dwBlock->mVariables.PushBack(dwVariable);
- if (atSpecification == 0)
- {
- dwVariable->mIsParam = false;
- dwVariable->mName = atName;
- dwVariable->mConstValue = atConstValue;
- dwVariable->mType = parentType->mTypeParam;
- dwVariable->mIsConst = hadConstValue;
- dwVariable->mIsStatic = !hadMemberLocation;
- }
- dwVariable->mLocationLen = (int)atLocationLen;
- dwVariable->mLocationData = atLocationData;
- dwVariable->mCompileUnit = compileUnit;
- BF_ASSERT(dwVariable->mName != 0);
- newDataPair = MakeDataPair(dwVariable);
- }
- }
- break;
- /*case DW_TAG_subrange_type:
- {
- DbgType* parentType = GetStackTop<DbgType*>(&dataStack);
- parentType->mArraySize = atUpperBound;
- }
- break;*/
- case DW_TAG_inheritance:
- {
- DbgType* derivedType = GetStackTop<DbgType*>(&dataStack);
- DbgBaseTypeEntry* baseTypeEntry = mAlloc.Alloc<DbgBaseTypeEntry>();
- baseTypeEntry->mBaseType = GetOrCreateType(atType, dataMap);
- if (atDataMemberData != NULL)
- {
- bool foundVirtOffset = false;
- const uint8* opPtr = atDataMemberData;
- if (*(opPtr++) == DW_OP_dup)
- {
- if (*(opPtr++) == DW_OP_deref)
- {
- if (*(opPtr++) == DW_OP_constu)
- {
- baseTypeEntry->mVTableOffset = (int)DecodeSLEB128(opPtr) / sizeof(int32);
- foundVirtOffset = true;
- if (*(opPtr++) == DW_OP_minus)
- baseTypeEntry->mVTableOffset = -baseTypeEntry->mVTableOffset;
- }
- }
- }
-
- BF_ASSERT(foundVirtOffset);
- }
- else
- baseTypeEntry->mThisOffset = atDataMemberLocation;
- derivedType->mBaseTypes.PushBack(baseTypeEntry);
- }
- break;
- case DW_TAG_member:
- {
- DbgType* parentType = GetStackTop<DbgType*>(&dataStack);
- if ((atName != NULL) && (strncmp(atName, "_vptr$", 6) == 0))
- {
- parentType->mHasVTable = true;
- break;
- }
- //DbgVariable* member = mAlloc.Alloc<DbgVariable>();
- DbgVariable* member = GetOrCreate<DbgVariable*>(tagIdx, dataMap);
- member->mIsMember = true;
- member->mCompileUnit = compileUnit;
- member->mName = atName;
- member->mType = GetOrCreateType(atType, dataMap);
- member->mConstValue = atConstValue;
- member->mIsConst = hadConstValue;
- member->mIsStatic = !hadMemberLocation;
- member->mBitSize = atBitSize;
- member->mBitOffset = atBitOffset;
- member->mIsExtern = atExternal != 0;
-
- parentType->mMemberList.PushBack(member);
- member->mMemberOffset = atDataMemberLocation;
-
- if ((member->mIsStatic) && (!member->mIsConst))
- parentType->mHasStaticMembers = true;
- /*if ((member->mIsStatic) && (!member->mIsConst))
- mStaticVariables.push_back(member);*/
- newDataPair = MakeDataPair(member);
- //dataMap.Set(tagIdx, member);
- }
- break;
- case DW_TAG_subrange_type:
- {
- int typeIdx = (int)(tagDataStart - startData);
- DbgType* parentType = GetStackTop<DbgType*>(&dataStack);
- int arrSize = atCount;
- deferredArrayDims.push_back(arrSize);
- }
- break;
- case DW_TAG_namespace:
- case DW_TAG_const_type:
- case DW_TAG_base_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
- case DW_TAG_array_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_unspecified_type:
- case DW_TAG_class_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_typedef:
- case DW_TAG_volatile_type:
- case DW_TAG_subroutine_type:
- //case DW_TAG_subrange_type:
- case DW_TAG_restrict_type:
- {
- int typeIdx = (int)(tagDataStart - startData);
- DbgType* dbgType = GetOrCreateType(typeIdx, dataMap);
- const char* nameSep = (compileUnit->mLanguage == DbgLanguage_Beef) ? "." : "::";
- if ((atName != NULL) &&
- ((entryTag == DW_TAG_structure_type) || (entryTag == DW_TAG_class_type) ||
- (entryTag == DW_TAG_typedef) || (entryTag == DW_TAG_union_type) || (entryTag == DW_TAG_enumeration_type) ||
- (entryTag == DW_TAG_namespace)))
- {
- BF_ASSERT(dbgType->mTypeCode == DbgType_Null);
- DbgType* parentType = GetStackTop<DbgType*>(&dataStack);
-
- if (parentType != NULL)
- {
- dbgType->mParent = parentType;
- dbgType->mParent->mSubTypeList.PushBack(dbgType);
- /*if (dbgType->mParent->mName != NULL)
- {
- if (atName == NULL)
- {
- dbgType->mName = dbgType->mParent->mName; // Extend from name of parent if we're anonymous
- }
- else
- {
- int nameSepLen = strlen(nameSep);
- int parentNameLen = strlen(dbgType->mParent->mName);
- int nameLen = strlen(atName);
- char* name = (char*)mAlloc.AllocBytes(parentNameLen + nameSepLen + nameLen + 1);
- memcpy(name, dbgType->mParent->mName, parentNameLen);
- memcpy(name + parentNameLen, nameSep, nameSepLen);
- memcpy(name + parentNameLen + nameSepLen, atName, nameLen);
- dbgType->mName = name;
- }
- }*/
- }
- else
- {
- // Add to global subtype list but don't set dbgType->mParent
- compileUnit->mGlobalType->mSubTypeList.PushBack(dbgType);
- }
- }
-
- const char* useName = atName;
- /*if ((useName != NULL) && (strcmp(useName, "@") == 0))
- useName = NULL;*/
- dbgType->mCompileUnit = compileUnit;
- dbgType->mLanguage = compileUnit->mLanguage;
- //SplitName(atName, dbgType->mTypeName, dbgType->mTemplateParams);
- dbgType->mName = useName;
- if (dbgType->mTypeName == NULL)
- dbgType->mTypeName = useName;
- //if (dbgType->mName == NULL)
- //dbgType->mName = atName;
- int parentNameLen = ((dbgType->mParent != NULL) && (dbgType->mParent->mName != NULL)) ? (int)strlen(dbgType->mParent->mName) : 0;
- int typeNameLen = (dbgType->mTypeName != NULL) ? (int)strlen(dbgType->mTypeName) : 0;
- //int templateParamsLen = (dbgType->mTemplateParams != NULL) ? strlen(dbgType->mTemplateParams) : 0;
- if ((parentNameLen != 0) /*&& (templateParamsLen == 0)*/)
- {
- int nameSepLen = (int)strlen(nameSep);
-
- int nameLen = parentNameLen + typeNameLen /*+ templateParamsLen*/;
- if ((parentNameLen > 0) && (nameLen > 0))
- nameLen += nameSepLen;
- char* namePtr = (char*)mAlloc.AllocBytes(nameLen + 1, "DWARF");
- dbgType->mName = namePtr;
- if (parentNameLen > 0)
- {
- memcpy(namePtr, dbgType->mParent->mName, parentNameLen);
- namePtr += parentNameLen;
- if (nameLen > 0)
- {
- memcpy(namePtr, nameSep, nameSepLen);
- namePtr += nameSepLen;
- }
- }
- if (nameLen > 0)
- {
- memcpy(namePtr, useName, typeNameLen);
- namePtr += typeNameLen;
- }
- /*if (templateParamsLen > 0)
- {
- memcpy(namePtr, dbgType->mTemplateParams, templateParamsLen);
- namePtr += templateParamsLen;
- }*/
- }
-
- dbgType->mTypeCode = DbgType_Null;
- dbgType->mIsDeclaration = atDeclaration;
- if (atByteSize != -1)
- {
- dbgType->mSize = atByteSize;
- dbgType->mSizeCalculated = true;
- }
-
- switch (entryTag)
- {
- case DW_TAG_base_type:
- // Types that may do fallover to int/uints on size mismatch
- switch (atEncoding)
- {
- case DW_ATE_UTF:
- if (atByteSize == 1)
- dbgType->mTypeCode = DbgType_Utf8;
- else if (atByteSize == 2)
- dbgType->mTypeCode = DbgType_Utf16;
- else
- dbgType->mTypeCode = DbgType_Utf32;
- break;
- case DW_ATE_signed_char:
- if (atByteSize == 1)
- dbgType->mTypeCode = DbgType_SChar;
- else if (atByteSize == 2)
- dbgType->mTypeCode = DbgType_SChar16;
- else if (atByteSize == 4)
- dbgType->mTypeCode = DbgType_SChar32;
- else
- atEncoding = DW_ATE_signed;
- break;
- case DW_ATE_unsigned_char:
- if (atByteSize == 1)
- dbgType->mTypeCode = DbgType_UChar;
- else if (atByteSize == 2)
- dbgType->mTypeCode = DbgType_UChar16;
- else if (atByteSize == 4)
- dbgType->mTypeCode = DbgType_UChar32;
- atEncoding = DW_ATE_unsigned;
- break;
- case DW_ATE_boolean:
- if (atByteSize == 1)
- dbgType->mTypeCode = DbgType_Bool;
- else
- atEncoding = DW_ATE_unsigned;
- break;
- }
- if (dbgType->mTypeCode == DbgType_Null)
- {
- switch (atEncoding)
- {
- case DW_ATE_address:
- if (atByteSize == 0)
- dbgType->mTypeCode = DbgType_Void;
- break;
- case DW_ATE_boolean:
- if (atByteSize == 1)
- {
- dbgType->mTypeCode = DbgType_Bool;
- break;
- }
- //Fall through
- case DW_ATE_signed:
- switch (atByteSize)
- {
- case 1:
- dbgType->mTypeCode = DbgType_i8;
- break;
- case 2:
- dbgType->mTypeCode = DbgType_i16;
- break;
- case 4:
- dbgType->mTypeCode = DbgType_i32;
- break;
- case 8:
- dbgType->mTypeCode = DbgType_i64;
- break;
- case 16:
- dbgType->mTypeCode = DbgType_i128;
- break;
- }
- break;
- case DW_ATE_unsigned:
- switch (atByteSize)
- {
- case 1:
- dbgType->mTypeCode = DbgType_u8;
- break;
- case 2:
- if ((atName != NULL) && (strcmp(atName, "wchar_t") == 0))
- dbgType->mTypeCode = DbgType_UChar16;
- else
- dbgType->mTypeCode = DbgType_u16;
- break;
- case 4:
- dbgType->mTypeCode = DbgType_u32;
- break;
- case 8:
- dbgType->mTypeCode = DbgType_u64;
- break;
- case 16:
- dbgType->mTypeCode = DbgType_u128;
- break;
- }
- break;
- case DW_ATE_float:
- if (atByteSize == 4)
- dbgType->mTypeCode = DbgType_Single;
- else if (atByteSize == 8)
- dbgType->mTypeCode = DbgType_Double;
- else if (atByteSize == 12)
- dbgType->mTypeCode = DbgType_Float96;
- else if (atByteSize == 16)
- dbgType->mTypeCode = DbgType_Float128;
- break;
- case DW_ATE_complex_float:
- if (atByteSize == 8)
- dbgType->mTypeCode = DbgType_ComplexFloat;
- else if (atByteSize == 16)
- dbgType->mTypeCode = DbgType_ComplexDouble;
- else if (atByteSize == 24)
- dbgType->mTypeCode = DbgType_ComplexDouble96;
- else if (atByteSize == 32)
- dbgType->mTypeCode = DbgType_ComplexDouble128;
- break;
- default:
- BF_FATAL("Unknown DW_ATE type");
- break;
- }
- }
- break;
- case DW_TAG_enumeration_type: //TODO: Handle these differently
- dbgType->mTypeCode = DbgType_Enum;
- dbgType->mTypeParam = mAlloc.Alloc<DbgType>();
- if (atByteSize == 8)
- dbgType->mTypeParam->mTypeCode = DbgType_i64;
- else if (atByteSize == 4)
- dbgType->mTypeParam->mTypeCode = DbgType_i32;
- else if (atByteSize == 2)
- dbgType->mTypeParam->mTypeCode = DbgType_i16;
- else if (atByteSize == 1)
- dbgType->mTypeParam->mTypeCode = DbgType_i8;
- else
- {
- BF_DBG_FATAL("Invalid enum type");
- }
- break;
- case DW_TAG_namespace:
- dbgType->mTypeCode = DbgType_Namespace;
- break;
- case DW_TAG_const_type:
- dbgType->mTypeCode = DbgType_Const;
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- break;
- case DW_TAG_rvalue_reference_type:
- dbgType->mTypeCode = DbgType_RValueReference;
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- break;
- case DW_TAG_unspecified_type:
- dbgType->mTypeCode = DbgType_Unspecified;
- dbgType->mTypeName = atName;
- break;
- case DW_TAG_reference_type:
- dbgType->mTypeCode = DbgType_Ref;
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- break;
- case DW_TAG_pointer_type:
- dbgType->mTypeCode = DbgType_Ptr;
- dbgType->mSize = sizeof(addr_target);
- dbgType->mSizeCalculated = true;
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- if (dbgType->mTypeParam != NULL)
- dbgType->mTypeParam->mPtrType = dbgType;
- break;
- case DW_TAG_ptr_to_member_type:
- dbgType->mTypeCode = DbgType_PtrToMember;
- dbgType->mSize = sizeof(addr_target);
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- if (dbgType->mTypeParam != NULL)
- dbgType->mTypeParam->mPtrType = dbgType;
- break;
- case DW_TAG_array_type:
- dbgType->mTypeCode = DbgType_SizedArray;
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- break;
- case DW_TAG_structure_type:
- dbgType->mTypeCode = DbgType_Struct;
- break;
- case DW_TAG_class_type:
- dbgType->mTypeCode = DbgType_Class;
- break;
- case DW_TAG_union_type:
- dbgType->mTypeCode = DbgType_Union;
- break;
- case DW_TAG_typedef:
- dbgType->mTypeCode = DbgType_TypeDef;
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- break;
- case DW_TAG_volatile_type:
- dbgType->mTypeCode = DbgType_Volatile;
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- break;
- case DW_TAG_subroutine_type:
- dbgType->mTypeCode = DbgType_Subroutine;
- if (atType != 0) // Return value
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- dbgType->mBlockParam = mAlloc.Alloc<DbgBlock>();
- break;
- case DW_TAG_restrict_type:
- dbgType->mTypeCode = DbgType_Restrict;
- dbgType->mTypeParam = GetOrCreateType(atType, dataMap);
- break;
- }
-
- newDataPair = MakeDataPair(dbgType);
- }
- break;
- }
-
- if (hasChildren)
- dataStack.push_back(newDataPair);
- }
- for (auto& abstractOriginEntry : abstractOriginReplaceList)
- abstractOriginEntry.Replace();
- GetLinkedModule()->MapTypes(startingTypeIdx);
-
- dataPtr = dataEnd;
- return true;
- }
- void DbgModule::ParseDebugFrameData()
- {
- BP_ZONE("ParseDebugFrameData");
- const uint8* data = mDebugFrameData;
- if (data == NULL)
- return;
- mParsedFrameDescriptors = true;
- Dictionary<addr_target, DwCommonFrameDescriptor*> commonFrameDescriptorMap;
- while (true)
- {
- addr_target relSectionAddr = (addr_target)(data - mDebugFrameData);
- int length = GET(int);
- if (length == 0)
- break;
-
- const uint8* dataEnd = data + length;
- int cieID = GET(int);
-
- if (cieID < 0)
- {
- BP_ALLOC_T(DwCommonFrameDescriptor);
- DwCommonFrameDescriptor* commonFrameDescriptor = mAlloc.Alloc<DwCommonFrameDescriptor>();
- char version = GET(char);
- commonFrameDescriptor->mDbgModule = this;
- commonFrameDescriptor->mAugmentation = DataGetString(data);
-
- if (version >= 4)
- {
- commonFrameDescriptor->mPointerSize = GET(int8);
- commonFrameDescriptor->mSegmentSize = GET(int8);
- }
- commonFrameDescriptor->mCodeAlignmentFactor = (int)DecodeULEB128(data);
- commonFrameDescriptor->mDataAlignmentFactor = (int)DecodeSLEB128(data);
- commonFrameDescriptor->mReturnAddressColumn = (int)DecodeULEB128(data);
- commonFrameDescriptor->mInstData = data;
- commonFrameDescriptor->mInstLen = (int)(dataEnd - data);
- mDebugTarget->mCommonFrameDescriptors.push_back(commonFrameDescriptor);
- if (version < 3)
- commonFrameDescriptorMap[relSectionAddr] = commonFrameDescriptor;
- else
- commonFrameDescriptorMap[mDebugFrameAddress + relSectionAddr] = commonFrameDescriptor;
- }
- else
- {
- addr_target lowPC = GET(addr_target);
- addr_target highPC = lowPC + GET(addr_target);
- DwCommonFrameDescriptor* commonFrameDescriptor = commonFrameDescriptorMap[(addr_target)cieID];
- BF_ASSERT(commonFrameDescriptor != NULL);
- typedef decltype(mDebugTarget->mDwFrameDescriptorMap) MapType;
- auto resultPair = mDebugTarget->mDwFrameDescriptorMap.insert(MapType::value_type(lowPC, DwFrameDescriptor()));
- auto frameDescriptor = &resultPair.first->second;
- //frameDescriptor->
- frameDescriptor->mLowPC = lowPC;
- frameDescriptor->mHighPC = highPC;
- frameDescriptor->mInstData = data;
- frameDescriptor->mInstLen = (int)(dataEnd - data);
- frameDescriptor->mCommonFrameDescriptor = commonFrameDescriptor;
- }
- data = dataEnd;
- }
- }
- void DbgModule::ParseEHFrameData()
- {
- const uint8* data = mEHFrameData;
- if (data == NULL)
- return;
- Dictionary<addr_target, DwCommonFrameDescriptor*> commonFrameDescriptorMap;
- while (true)
- {
- addr_target sectionAddress = (addr_target)(data - mEHFrameData);
- int length = GET(int);
- if (length == 0)
- break;
- const uint8* dataEnd = data + length;
- int cieID = GET(int);
- if (cieID <= 0)
- {
- BP_ALLOC_T(DwCommonFrameDescriptor);
- DwCommonFrameDescriptor* commonFrameDescriptor = mAlloc.Alloc<DwCommonFrameDescriptor>();
- char version = GET(char);
- const char* augmentation = DataGetString(data);
- commonFrameDescriptor->mDbgModule = this;
- commonFrameDescriptor->mCodeAlignmentFactor = (int)DecodeULEB128(data);
- commonFrameDescriptor->mDataAlignmentFactor = (int)DecodeSLEB128(data);
- commonFrameDescriptor->mReturnAddressColumn = (int)DecodeULEB128(data);
- commonFrameDescriptor->mAugmentation = augmentation;
-
- if (*augmentation == 'z')
- {
- ++augmentation;
- int augLen = (int)DecodeULEB128(data);
- commonFrameDescriptor->mAugmentationLength = augLen;
- const uint8* augEnd = data + augLen;
- while (*augmentation != '\0')
- {
- if (*augmentation == 'R')
- commonFrameDescriptor->mAddressPointerEncoding = (int) GET(uint8);
- else if (*augmentation == 'P')
- {
- int encodingType = GET(uint8);
- BF_ASSERT(encodingType == 0);
- commonFrameDescriptor->mLSDARoutine = GET(addr_target);
- }
- else if (*augmentation == 'L')
- commonFrameDescriptor->mLSDAPointerEncodingFDE = GET(uint8);
- else if (*augmentation == 'S')
- {
- // mIsSignalHandler - on return from stack frame, CFA is before next instruction rather than after it
- }
- else
- BF_FATAL("Unknown CIE augmentation");
- ++augmentation;
- }
- data = augEnd;
- }
- commonFrameDescriptor->mInstData = data;
- commonFrameDescriptor->mInstLen = (int)(dataEnd - data);
-
- mDebugTarget->mCommonFrameDescriptors.push_back(commonFrameDescriptor);
- commonFrameDescriptorMap[sectionAddress] = commonFrameDescriptor;
- }
- else
- {
- int ciePos = (int)(sectionAddress - cieID) + 4;
- DwCommonFrameDescriptor* commonFrameDescriptor = commonFrameDescriptorMap[(addr_target)ciePos];
- addr_target lowPC;
- addr_target highPC;
-
- if (commonFrameDescriptor->mAddressPointerEncoding == (DW_EH_PE_pcrel | DW_EH_PE_sdata4))
- {
- lowPC = GET(int);
- lowPC += mEHFrameAddress + sectionAddress + 8;
- highPC = lowPC + GET(int);
- }
- else
- {
- lowPC = GET(int);
- highPC = lowPC + GET(int);
- }
- typedef decltype(mDebugTarget->mDwFrameDescriptorMap) MapType;
- auto resultPair = mDebugTarget->mDwFrameDescriptorMap.insert(MapType::value_type(lowPC, DwFrameDescriptor()));
- auto frameDescriptor = &resultPair.first->second;
- frameDescriptor->mLSDARoutine = commonFrameDescriptor->mLSDARoutine;
- const char* augmentation = commonFrameDescriptor->mAugmentation;
- if (*augmentation == 'z')
- {
- int augLen = GET(uint8);
- const uint8* augEnd = data + augLen;
- ++augmentation;
- while (*augmentation != '\0')
- {
- if (*augmentation == 'R')
- {
- }
- else if (*augmentation == 'P')
- {
- }
- else if (*augmentation == 'L')
- {
- BF_ASSERT(commonFrameDescriptor->mLSDAPointerEncodingFDE == 0);
- frameDescriptor->mLSDARoutine = GET(addr_target);
- }
- else if (*augmentation == 'S')
- {
- }
- else
- BF_FATAL("Unknown CIE augmentation");
- augmentation++;
- }
- data = augEnd;
- }
-
- frameDescriptor->mLowPC = lowPC;
- frameDescriptor->mHighPC = highPC;
- frameDescriptor->mInstData = data;
- frameDescriptor->mInstLen = (int)(dataEnd - data);
- frameDescriptor->mCommonFrameDescriptor = commonFrameDescriptor;
- }
- data = dataEnd;
- }
- }
- void DbgModule::FlushLineData(DbgSubprogram* curSubprogram, std::list<DbgLineData>& queuedLineData)
- {
-
- }
- DbgSrcFile* DbgModule::AddSrcFile(DbgCompileUnit* compileUnit, const String& srcFilePath)
- {
- DbgSrcFile* dwSrcFile = mDebugTarget->AddSrcFile(srcFilePath);
- if (compileUnit != NULL)
- {
- DbgSrcFileReference srcFileRef;
- srcFileRef.mSrcFile = dwSrcFile;
- srcFileRef.mCompileUnit = compileUnit;
- compileUnit->mSrcFileRefs.push_back(srcFileRef);
- }
- return dwSrcFile;
- }
- bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx)
- {
- BP_ZONE("ParseDebugLineInfo");
-
- const uint8* data = dataPtr;
- const int startOffset = (int)(data - mDebugLineData);
- int length = GET(int);
- if (length == 0)
- return false;
- DbgCompileUnit* dwCompileUnit = mCompileUnits[compileUnitIdx];
- const uint8* dataEnd = data + length;
- short version = GET(short);
- int headerLength = GET(int);
- char minimumInstructionLength = GET(char);
- int maximumOperationsPerInstruction = 1;
- char defaultIsStmt = GET(char);
- char lineBase = GET(char);
- char lineRange = GET(char);
- char opcodeBase = GET(char);
- for (int i = 0; i < opcodeBase - 1; i++)
- {
- char standardOpcodeLengths = GET(char);
- }
- Array<const char*> directoryNames;
- while (true)
- {
- const char* name = DataGetString(data);
- if (name[0] == 0)
- break;
- directoryNames.push_back(name);
- }
- DbgSrcFileReference* dwSrcFileRef = NULL;
- HashSet<String> foundPathSet;
- int curFileIdx = 0;
- DbgSubprogram* curSubprogram = NULL;
-
- #define ADD_LINEDATA(lineData) \
- lineBuilder.Add(dwCompileUnit, lineData, dwSrcFileRef->mSrcFile, NULL);
- while (true)
- {
- const char* path = DataGetString(data);
- if (path[0] == 0)
- break;
- int directoryIdx = (int)DecodeULEB128(data);
- int lastModificationTime = (int)DecodeULEB128(data);
- int fileLength = (int)DecodeULEB128(data);
- String filePath;
- if (directoryIdx > 0)
- filePath = String(directoryNames[directoryIdx - 1]) + "/";
- filePath += path;
- filePath = GetAbsPath(filePath, dwCompileUnit->mCompileDir);
- AddSrcFile(dwCompileUnit, filePath.c_str());
- }
- if (dwCompileUnit->mSrcFileRefs.size() > 0)
- dwSrcFileRef = &dwCompileUnit->mSrcFileRefs.front();
-
- DbgLineDataBuilder lineBuilder(this);
- bool queuedPostPrologue = false;
- DbgLineDataState dwLineData;
- dwLineData.mLine = 0;
- dwLineData.mRelAddress = 0;
- dwLineData.mOpIndex = 0;
- dwLineData.mBasicBlock = false;
- dwLineData.mDiscriminator = 0;
- dwLineData.mIsStmt = defaultIsStmt != 0;
- dwLineData.mIsa = 0;
- dwLineData.mColumn = -2;
- while (data < dataEnd)
- {
- uint8_t opcode = GET(uint8_t);
- switch (opcode)
- {
- case DW_LNS_extended_op:
- {
- int len = (int)DecodeULEB128(data);
- uint8_t exOpcode = GET(uint8_t);
- switch (exOpcode)
- {
- case DW_LNE_end_sequence:
- {
- ADD_LINEDATA(dwLineData);
-
- dwSrcFileRef = &dwCompileUnit->mSrcFileRefs[0];
- dwLineData.mLine = 0;
- dwLineData.mRelAddress = 0;
- dwLineData.mOpIndex = 0;
- dwLineData.mBasicBlock = false;
- dwLineData.mDiscriminator = 0;
- dwLineData.mIsStmt = defaultIsStmt != 0;
- dwLineData.mIsa = 0;
- dwLineData.mColumn = -2;
- }
- break;
- case DW_LNE_set_address:
- dwLineData.mRelAddress = (uint32)(RemapAddr(GET(addr_target)) - mImageBase);
- break;
- case DW_LNE_define_file:
- {
- const char* path = DataGetString(data);
- int directoryIdx = (int)DecodeULEB128(data);
- int lastModificationTime = (int)DecodeULEB128(data);
- int fileLength = (int)DecodeULEB128(data);
- }
- break;
- case DW_LNE_set_discriminator:
- dwLineData.mDiscriminator = (int)DecodeULEB128(data);
- break;
- }
- }
- break;
- case DW_LNS_copy:
- ADD_LINEDATA(dwLineData);
-
- dwLineData.mDiscriminator = 0;
- dwLineData.mBasicBlock = false;
- break;
- case DW_LNS_advance_pc:
- {
- int advance = (int)DecodeULEB128(data);
- dwLineData.mRelAddress += advance;
- // How to advance opCode addr?
- }
- break;
- case DW_LNS_advance_line:
- {
- int advance = (int)DecodeSLEB128(data);
- dwLineData.mLine += advance;
- }
- break;
- case DW_LNS_set_file:
- {
- curFileIdx = (int)DecodeULEB128(data) - 1;
- dwSrcFileRef = &dwCompileUnit->mSrcFileRefs[curFileIdx];
- //dwLineData.mSrcFileRef = dwSrcFileRef;
- }
- break;
- case DW_LNS_set_column:
- {
- dwLineData.mColumn = (int)DecodeULEB128(data) - 1;
- }
- break;
- case DW_LNS_negate_stmt:
- {
- dwLineData.mIsStmt = !dwLineData.mIsStmt;
- }
- break;
- case DW_LNS_set_basic_block:
- {
- dwLineData.mBasicBlock = true;
- }
- break;
- case DW_LNS_const_add_pc:
- {
- int adjustedOpcode = 255 - opcodeBase;
- int opAdvance = adjustedOpcode / lineRange;
- uint32 newAddress = dwLineData.mRelAddress + minimumInstructionLength * ((dwLineData.mOpIndex + opAdvance) / maximumOperationsPerInstruction);
- int newOpIndex = (dwLineData.mOpIndex + opAdvance) % maximumOperationsPerInstruction;
-
- dwLineData.mRelAddress = newAddress;
- dwLineData.mOpIndex = newOpIndex;
- }
- break;
- case DW_LNS_fixed_advance_pc:
- {
- uint16_t advance = GET(uint16_t);
- dwLineData.mRelAddress += advance;
- dwLineData.mOpIndex = 0;
- }
- break;
- case DW_LNS_set_prologue_end:
- {
- queuedPostPrologue = true;
- }
- break;
- case DW_LNS_set_epilogue_begin:
- {
- dwLineData.mColumn = -2;
- }
- break;
- case DW_LNS_set_isa:
- {
- dwLineData.mIsa = (int)DecodeULEB128(data);
- }
- break;
- default:
- {
- // Special opcode
- int adjustedOpcode = opcode - opcodeBase;
- int opAdvance = adjustedOpcode / lineRange;
- uint32 oldAddress = dwLineData.mRelAddress;
- uint32 newAddress = dwLineData.mRelAddress + minimumInstructionLength * ((dwLineData.mOpIndex + opAdvance) / maximumOperationsPerInstruction);
- int newOpIndex = (dwLineData.mOpIndex + opAdvance) % maximumOperationsPerInstruction;
- int lineIncrement = lineBase + (adjustedOpcode % lineRange);
- dwLineData.mLine += lineIncrement;
- dwLineData.mRelAddress = newAddress;
- dwLineData.mOpIndex = newOpIndex;
- DbgLineData* lastLineData = NULL;
-
- if ((newAddress == oldAddress) && (queuedPostPrologue) && (curSubprogram != NULL) && (curSubprogram->mBlock.mLowPC == newAddress))
- {
- // Adjust this line later
- ADD_LINEDATA(dwLineData);
- }
- queuedPostPrologue = false;
-
- }
- break;
- }
- }
- lineBuilder.Commit();
- dataPtr = data;
- return true;
- }
- addr_target DbgModule::GetHotTargetAddress(DbgHotTargetSection* hotTargetSection)
- {
- if ((hotTargetSection->mTargetSectionAddr == NULL) && (hotTargetSection->mDataSize > 0))
- {
- if (hotTargetSection->mNoTargetAlloc)
- return 0;
- hotTargetSection->mTargetSectionAddr = mDebugger->AllocHotTargetMemory(hotTargetSection->mDataSize, hotTargetSection->mCanExecute, hotTargetSection->mCanWrite, &hotTargetSection->mTargetSectionSize);
- hotTargetSection->mImageOffset = (int)mImageSize;
- if (mImageBase == NULL)
- {
- mImageBase = hotTargetSection->mTargetSectionAddr;
- mOrigImageData->mAddr = mImageBase;
- }
- mImageSize += hotTargetSection->mTargetSectionSize;
- /*if (mExceptionData == hotTargetSection->mData)
- mExceptionDataRVA = (addr_target)(hotTargetSection->mTargetSectionAddr - mImageBase);*/
- }
- return hotTargetSection->mTargetSectionAddr;
- }
- uint8* DbgModule::GetHotTargetData(addr_target address)
- {
- for (int sectNum = 0; sectNum < (int)mHotTargetSections.size(); sectNum++)
- {
- if (mHotTargetSections[sectNum] != NULL)
- {
- DbgHotTargetSection* hotTargetSection = mHotTargetSections[sectNum];
- if ((address >= hotTargetSection->mTargetSectionAddr) && (address < hotTargetSection->mTargetSectionAddr + hotTargetSection->mTargetSectionSize))
- {
- return hotTargetSection->mData + (address - hotTargetSection->mTargetSectionAddr);
- }
- }
- }
- return NULL;
- }
- void DbgModule::DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& coffReloc, addr_target resolvedSymbolAddr, PE_SymInfo* symInfo)
- {
- #ifdef BF_DBG_32
- if (coffReloc.mType == IMAGE_REL_I386_DIR32)
- {
- *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += resolvedSymbolAddr;
- }
- else if (coffReloc.mType == IMAGE_REL_I386_DIR32NB)
- {
- GetHotTargetAddress(hotTargetSection); // Just to make sure we have mImageBase
- // We were previously using mImageBase instead of mDebugTarget->mTargetBinary->mImageBase. Was there a reason for that?
- // It was causing hot-loaded jump tables to have invalid addresses since the need to be relative to __ImageBase
- *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += (uint32)(resolvedSymbolAddr - GetTargetImageBase());
- }
- else if (coffReloc.mType == IMAGE_REL_I386_REL32)
- {
- addr_target myAddr = GetHotTargetAddress(hotTargetSection) + coffReloc.mVirtualAddress;
- *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += resolvedSymbolAddr - myAddr - sizeof(int32);
- }
- else if (coffReloc.mType == IMAGE_REL_I386_SECTION)
- {
- // auto linkedModule = GetLinkedModule();
- // addr_target mappedAddr = resolvedSymbolAddr & ~0x7FFFFFF;
- // int* encodingPtr = NULL;
- // if (linkedModule->mSecRelEncodingMap.TryAdd(mappedAddr, NULL, &encodingPtr))
- // {
- // *encodingPtr = (int)linkedModule->mSecRelEncodingVec.size();
- // linkedModule->mSecRelEncodingVec.push_back(mappedAddr);
- // }
- // *(uint16*)(hotTargetSection->mData + coffReloc.mVirtualAddress) = 0x8000 | *encodingPtr;
- *(uint16*)(hotTargetSection->mData + coffReloc.mVirtualAddress) = 0;
- }
- else if (coffReloc.mType == IMAGE_REL_I386_SECREL)
- {
- //*(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += symInfo->mValue;
- *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += resolvedSymbolAddr;
- }
- else
- {
- BF_ASSERT(0=="Invalid COFF reloc type");
- }
- #else
- // CodeView uses SECTION:SECREL locations, and we just want to find a mapping such that
- // COFF::GetSectionAddr can map it to the 64-bit address. We do this by encoding the
- // lower 31 bits in the SECREL (allowing a 31-bit offset at the destination as well)
- // and then we use a 15-bit key to map the upper bits
- if (coffReloc.mType == IMAGE_REL_AMD64_REL32)
- {
- addr_target myAddr = GetHotTargetAddress(hotTargetSection) + coffReloc.mVirtualAddress;
- intptr_target addrOffset = resolvedSymbolAddr - myAddr - sizeof(int32);
- BF_ASSERT((int64)(int32)addrOffset == addrOffset);
- *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += (int32)addrOffset;
- }
- else if (coffReloc.mType == IMAGE_REL_AMD64_SECTION)
- {
- /*if (symInfo != NULL)
- {
- *(uint16*)(hotTargetSection->mData + coffReloc.mVirtualAddress) = symInfo->mSectionNum;
- }
- else*/
- {
- auto linkedModule = GetLinkedModule();
- addr_target mappedAddr = resolvedSymbolAddr & ~0x7FFFFFF;
- /*auto pair = linkedModule->mSecRelEncodingMap.insert(std::make_pair(mappedAddr, (int)linkedModule->mSecRelEncodingMap.size()));
- if (pair.second)
- linkedModule->mSecRelEncodingVec.push_back(mappedAddr);*/
- int* encodingPtr = NULL;
- if (linkedModule->mSecRelEncodingMap.TryAdd(mappedAddr, NULL, &encodingPtr))
- {
- *encodingPtr = (int)linkedModule->mSecRelEncodingVec.size();
- linkedModule->mSecRelEncodingVec.push_back(mappedAddr);
- }
- //*(uint16*)(hotTargetSection->mData + coffReloc.mVirtualAddress) = 0x8000 | pair.first->second;
- *(uint16*)(hotTargetSection->mData + coffReloc.mVirtualAddress) = 0x8000 | *encodingPtr;
- }
- }
- else if (coffReloc.mType == IMAGE_REL_AMD64_SECREL)
- {
- auto linkedModule = GetLinkedModule();
- if ((resolvedSymbolAddr >= linkedModule->mTLSAddr) && (resolvedSymbolAddr < linkedModule->mTLSAddr + linkedModule->mTLSSize))
- {
- // Make relative to actual TLS data
- resolvedSymbolAddr -= linkedModule->mTLSAddr;
- }
-
- *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += (uint32)(resolvedSymbolAddr & 0x7FFFFFF);
-
- }
- else if (coffReloc.mType == IMAGE_REL_AMD64_ADDR64)
- {
- *(uint64*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += resolvedSymbolAddr;
- }
- else if (coffReloc.mType == IMAGE_REL_AMD64_ADDR32NB)
- {
- GetHotTargetAddress(hotTargetSection); // Just to make sure we have mImageBase
- // We were previously using mImageBase instead of mDebugTarget->mTargetBinary->mImageBase. Was there a reason for that?
- // It was causing hot-loaded jump tables to have invalid addresses since the need to be relative to __ImageBase
- *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += (uint32)(resolvedSymbolAddr - GetTargetImageBase());
- //*(int32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += secRelAddr;
- }
- else
- {
- BF_ASSERT(0=="Invalid COFF reloc type");
- }
- #endif
- }
- bool DbgModule::IsHotSwapPreserve(const String& name)
- {
- // We have different rules for overwriting symbols in DWARF vs CodeView
- // Since MS mangling includes return types, we know that a type change of a static
- // member will mangle to a new name whereas with DWARF we DO want a new
- // address if the type changes but we can't tell that based on the mangle alone,
- // thus the reliance on the side table of mStaticVariables. We still do need
- // to determine whether the symbol is data (and thus we do preserve) or a method
- // (in which case we don't)
- if ((mDbgFlavor == DbgFlavor_MS) && (BfDemangler::IsData(name)))
- {
- if ((!name.StartsWith("?")) && (name.Contains("sBfTypeData"))) // We DO need to replace the fields/methods/etc but not the base sBfTypeData
- return false;
- if (name.StartsWith("?bf_hs_replace_"))
- return false;
- return true;
- }
- const char* prefix = "bf_hs_preserve@";
- return strncmp(name.c_str(), prefix, strlen(prefix)) == 0;
- }
- void DbgModule::ParseHotTargetSections(DataStream* stream, addr_target* resolvedSymbolAddrs)
- {
- auto mainModule = mDebugTarget->mTargetBinary;
- mainModule->ParseSymbolData();
- String name;
- for (int sectNum = 0; sectNum < (int)mHotTargetSections.size(); sectNum++)
- {
- if (mHotTargetSections[sectNum] != NULL)
- {
- DbgHotTargetSection* hotTargetSection = mHotTargetSections[sectNum];
- stream->SetPos(hotTargetSection->mPointerToRelocations);
- for (int relocIdx = 0; relocIdx < hotTargetSection->mNumberOfRelocations; relocIdx++)
- {
- COFFRelocation coffReloc;
- stream->Read(&coffReloc, sizeof(COFFRelocation));
- PE_SymInfo* symInfo = (PE_SymInfo*)&mSymbolData[coffReloc.mSymbolTableIndex * 18];
- //const char* symName = mSymbolData[coffReloc.mSymbolTableIndex];
- bool isStaticSymbol = symInfo->mStorageClass == COFF_SYM_CLASS_STATIC;
- if (symInfo->mNameOfs[0] != 0)
- {
- if (symInfo->mName[7] != 0)
- {
- // Name is exactly 8 chars, not null terminated yet
- name = String(symInfo->mName, symInfo->mName + 8);
- }
- else
- name = symInfo->mName;
- }
- else
- name = mStringTable + symInfo->mNameOfs[1];
- bool didNameMatch = false;
-
- addr_target resolvedSymbolAddr = resolvedSymbolAddrs[coffReloc.mSymbolTableIndex];
- #ifdef BF_DBG_32
- bool needsSymbolAddr = (coffReloc.mType == IMAGE_REL_I386_DIR32) || (coffReloc.mType == IMAGE_REL_I386_REL32) || (coffReloc.mType == IMAGE_REL_I386_SECREL) || (coffReloc.mType == IMAGE_REL_I386_SECTION);
- if (name[0] == '_')
- name.Remove(0, 1);
- #else
- bool needsSymbolAddr = (coffReloc.mType == IMAGE_REL_AMD64_ADDR64) || (coffReloc.mType == IMAGE_REL_AMD64_ADDR32) || (coffReloc.mType == IMAGE_REL_AMD64_ADDR32NB) ||
- ((coffReloc.mType >= IMAGE_REL_AMD64_REL32) || (coffReloc.mType <= IMAGE_REL_AMD64_REL32_5));
- #endif
- bool isHsPrev = false;
- if (name.StartsWith("bf_hs_prev@"))
- {
- isHsPrev = true;
- name.Remove(0, 11);
- }
- bool deferResolve = false;
- if ((resolvedSymbolAddr == 0) && (needsSymbolAddr))
- {
- bool isHotSwapPreserve = IsHotSwapPreserve(name);
- if ((symInfo->mSectionNum == 0) || (isHotSwapPreserve) || (isHsPrev))
- {
- auto origSymbolEntry = mainModule->mSymbolNameMap.Find(name.c_str());
- if (origSymbolEntry != NULL)
- {
- resolvedSymbolAddr = origSymbolEntry->mValue->mAddress;
- }
- else
- {
- //BF_FATAL("Symbol lookup error");
- deferResolve = true;
- }
- }
-
- if ((symInfo->mSectionNum != 0) && (resolvedSymbolAddr == NULL))
- {
- DbgHotTargetSection* refHotTargetSection = mHotTargetSections[symInfo->mSectionNum - 1];
- resolvedSymbolAddr = GetHotTargetAddress(refHotTargetSection) + symInfo->mValue;
- // Using the !hotTargetSection->mNoTargetAlloc check down here caused us to not properly remap reloaded
- // static members in the debug info. Even though we parse the debug info before we apply the deferred
- // resolves, the mLocData points into the original data so we still get it remapped when we use that
- // mLocData
- if (/*(!hotTargetSection->mNoTargetAlloc) &&*/ ((refHotTargetSection->mData == NULL) || (refHotTargetSection->mNoTargetAlloc)) &&
- (!isStaticSymbol))
- deferResolve = true;
- else
- deferResolve = false;
- }
- }
- if (deferResolve)
- {
- // It's a static field, defer resolution, but don't bother replacing for debug info sections
- DbgDeferredHotResolve* deferredResolve = mDeferredHotResolveList.Alloc();
- deferredResolve->mHotTargetSection = hotTargetSection;
- deferredResolve->mName = name;
- deferredResolve->mNewAddr = resolvedSymbolAddr;
- deferredResolve->mReloc = coffReloc;
- continue;
- }
- else
- {
- resolvedSymbolAddrs[coffReloc.mSymbolTableIndex] = resolvedSymbolAddr;
- DoReloc(hotTargetSection, coffReloc, resolvedSymbolAddr, symInfo);
- }
- }
- }
- }
- }
- void DbgModule::CommitHotTargetSections()
- {
- for (int sectNum = 0; sectNum < (int)mHotTargetSections.size(); sectNum++)
- {
- if (mHotTargetSections[sectNum] != NULL)
- {
- DbgHotTargetSection* hotTargetSection = mHotTargetSections[sectNum];
- addr_target hotAddr = GetHotTargetAddress(hotTargetSection);
- if (hotAddr != 0)
- {
- // void* imageDestPtr = mOrigImageData->mBlocks[0] + hotTargetSection->mImageOffset;
- // if (hotTargetSection->mData != NULL)
- // memcpy(imageDestPtr, hotTargetSection->mData, hotTargetSection->mDataSize);
- // else
- // memset(imageDestPtr, 0, hotTargetSection->mDataSize);
- BF_ASSERT(mOrigImageData->mAddr != 0);
- void* imageDestPtr = hotTargetSection->mData;
- bool isTemp = false;
- if (imageDestPtr == NULL)
- {
- imageDestPtr = new uint8[hotTargetSection->mDataSize];
- memset(imageDestPtr, 0, hotTargetSection->mDataSize);
- isTemp = true;
- }
- if (hotTargetSection->mCanExecute)
- {
- bool success = mDebugger->WriteInstructions(hotAddr, imageDestPtr, hotTargetSection->mDataSize);
- BF_ASSERT(success);
- }
- else
- {
- bool success = mDebugger->WriteMemory(hotAddr, imageDestPtr, hotTargetSection->mDataSize);
- BF_ASSERT(success);
- }
- if (isTemp)
- delete imageDestPtr;
- }
- }
- }
- }
- void DbgModule::HotReplaceType(DbgType* newType)
- {
- auto linkedModule = GetLinkedModule();
- newType->PopulateType();
- DbgType* primaryType = linkedModule->GetPrimaryType(newType);
- if (primaryType == newType)
- {
- // There was no previous type
- BF_ASSERT(primaryType->mHotNewType == NULL);
- return;
- }
- if (primaryType->mHotNewType != newType)
- {
- // We have already pulled in the new data from a previous new type
- BF_ASSERT(primaryType->mHotNewType == NULL);
- return;
- }
- primaryType->mHotNewType = NULL;
- primaryType->PopulateType();
- linkedModule->ParseGlobalsData();
- linkedModule->ParseSymbolData();
- if (primaryType->mNeedsGlobalsPopulated)
- {
- // These aren't proper TPI types so we don't have any method declarations until we PopulateTypeGlobals
- linkedModule->PopulateTypeGlobals(primaryType);
- }
- for (auto methodNameEntry : primaryType->mMethodNameList)
- {
- if (methodNameEntry->mCompileUnitId != -1)
- {
- linkedModule->MapCompileUnitMethods(methodNameEntry->mCompileUnitId);
- methodNameEntry->mCompileUnitId = -1;
- }
- }
-
- // Now actually remove the linedata from the defining module
- HashSet<DbgSrcFile*> checkedFiles;
- for (auto method : primaryType->mMethodList)
- {
- //method->mWasModuleHotReplaced = true;
- method->mHotReplaceKind = DbgSubprogram::HotReplaceKind_Orphaned; // May be temporarily orphaned
- if (method->mLineInfo == NULL)
- continue;
- //FIXME: Hot replacing lines
- DbgSrcFile* lastSrcFile = NULL;
- checkedFiles.Clear();
- int prevCtx = -1;
- auto inlineRoot = method->GetRootInlineParent();
- for (int lineIdx = 0; lineIdx < method->mLineInfo->mLines.mSize; lineIdx++)
- {
- auto& lineData = method->mLineInfo->mLines[lineIdx];
- if (lineData.mCtxIdx != prevCtx)
- {
- auto ctxInfo = inlineRoot->mLineInfo->mContexts[lineData.mCtxIdx];
- auto srcFile = ctxInfo.mSrcFile;
- prevCtx = lineData.mCtxIdx;
- if (srcFile != lastSrcFile)
- {
- if (checkedFiles.Add(srcFile))
- {
- // Remove linedata for old type
- // These go into a hot-replaced list so we can still bind to them -- that is necessary because
- // we may still have old versions of this method running (and may forever, if its in a loop on some thread)
- // since we only patch entry points
- //srcFile->RemoveLines(primaryType->mCompileUnit->mDbgModule, primaryType->mCompileUnit, true);
- //srcFile->RemoveLines(primaryType->mCompileUnit->mDbgModule, method, true);
- srcFile->RemoveLines(method->mCompileUnit->mDbgModule, method, true);
- }
- lastSrcFile = srcFile;
- }
- }
- }
- }
- //DbgType* primaryType = newType->GetPrimaryType();
- // We need to keep a persistent list of hot replaced methods so we can set hot jumps
- // in old methods that may still be on the callstack. These entries get removed when
- // we unload unused hot files in
- while (!primaryType->mMethodList.IsEmpty())
- {
- auto method = primaryType->mMethodList.PopFront();
- method->PopulateSubprogram();
- primaryType->mHotReplacedMethodList.PushFront(method);
- mHotPrimaryTypes.Add(primaryType);
- }
-
- Dictionary<StringView, DbgSubprogram*> oldProgramMap;
- for (auto oldMethod : primaryType->mHotReplacedMethodList)
- {
- oldMethod->PopulateSubprogram();
- if (oldMethod->mBlock.IsEmpty())
- continue;
- auto symInfo = mDebugTarget->mSymbolMap.Get(oldMethod->mBlock.mLowPC);
- if (symInfo != NULL)
- {
- oldProgramMap.TryAdd(symInfo->mName, oldMethod);
- }
- }
- bool setHotJumpFailed = false;
- while (!newType->mMethodList.IsEmpty())
- {
- DbgSubprogram* newMethod = newType->mMethodList.PopFront();
- if (!newMethod->mBlock.IsEmpty())
- {
- BfLogDbg("Hot added new method %p %s Address:%p\n", newMethod, newMethod->mName, newMethod->mBlock.mLowPC);
- newMethod->PopulateSubprogram();
- auto symInfo = mDebugTarget->mSymbolMap.Get(newMethod->mBlock.mLowPC);
- if (symInfo != NULL)
- {
- DbgSubprogram* oldMethod = NULL;
- if (oldProgramMap.TryGetValue(symInfo->mName, &oldMethod))
- {
- bool doHotJump = false;
- if (oldMethod->Equals(newMethod))
- {
- doHotJump = true;
- }
- else
- {
- // When mangles match but the actual signatures don't match, that can mean that the call signature was changed
- // and thus it's actually a different method and shouldn't hot jump OR it could be lambda whose captures changed.
- // When the lambda captures change, the user didn't actually enter a different signature so we want to do a hard
- // fail if the old code gets called to avoid confusion of "why aren't my changes working?"
- // If we removed captures then we can still do the hot jump. Otherwise we have to fail...
- doHotJump = false;
- if ((oldMethod->IsLambda()) && (oldMethod->Equals(newMethod, true)) &&
- (oldMethod->mHasThis) && (newMethod->mHasThis))
- {
- auto oldParam = oldMethod->mParams.front();
- auto newParam = newMethod->mParams.front();
- if ((oldParam->mType->IsPointer()) && (newParam->mType->IsPointer()))
- {
- auto oldType = oldParam->mType->mTypeParam->GetPrimaryType();
- oldType->PopulateType();
- auto newType = newParam->mType->mTypeParam->GetPrimaryType();
- newType->PopulateType();
- if ((oldType->IsStruct()) && (newType->IsStruct()))
- {
- bool wasMatch = true;
- auto oldMember = oldType->mMemberList.front();
- auto newMember = newType->mMemberList.front();
- while (newMember != NULL)
- {
- if (oldMember == NULL)
- {
- wasMatch = false;
- break;
- }
- if ((oldMember->mName == NULL) || (newMember->mName == NULL))
- {
- wasMatch = false;
- break;
- }
- if (strcmp(oldMember->mName, newMember->mName) != 0)
- {
- wasMatch = false;
- break;
- }
- if (!oldMember->mType->Equals(newMember->mType))
- {
- wasMatch = false;
- break;
- }
-
- oldMember = oldMember->mNext;
- newMember = newMember->mNext;
- }
- if (wasMatch)
- doHotJump = true;
- }
- }
- if (!doHotJump)
- {
- mDebugTarget->mDebugger->PhysSetBreakpoint(oldMethod->mBlock.mLowPC);
- oldMethod->mHotReplaceKind = DbgSubprogram::HotReplaceKind_Invalid;
- }
- }
- }
- if (doHotJump)
- {
- if (!setHotJumpFailed)
- {
- if (!mDebugger->SetHotJump(oldMethod, newMethod->mBlock.mLowPC, (int)(newMethod->mBlock.mHighPC - newMethod->mBlock.mLowPC)))
- setHotJumpFailed = true;
- }
- oldMethod->mHotReplaceKind = DbgSubprogram::HotReplaceKind_Replaced;
- }
- }
- }
- }
- newMethod->mParentType = primaryType;
- primaryType->mMethodList.PushBack(newMethod);
- }
- //mDebugTarget->mSymbolMap.Get()
- // bool setHotJumpFailed = false;
- // while (!newType->mMethodList.IsEmpty())
- // {
- // DbgSubprogram* newMethod = newType->mMethodList.PopFront();
- // if (!newMethod->mBlock.IsEmpty())
- // {
- // newMethod->PopulateSubprogram();
- //
- // bool found = false;
- // for (auto oldMethod : primaryType->mHotReplacedMethodList)
- // {
- // if (oldMethod->mBlock.IsEmpty())
- // continue;
- // if (oldMethod->Equals(newMethod))
- // {
- // if (!setHotJumpFailed)
- // {
- // if (!mDebugger->SetHotJump(oldMethod, newMethod))
- // setHotJumpFailed = true;
- // oldMethod->mWasHotReplaced = true;
- // }
- // }
- // }
- // }
- // newMethod->mParentType = primaryType;
- // primaryType->mMethodList.PushBack(newMethod);
- // }
- primaryType->mCompileUnit->mWasHotReplaced = true;
- primaryType->mNeedsGlobalsPopulated = newType->mNeedsGlobalsPopulated;
- primaryType->mUsingNamespaces = newType->mUsingNamespaces;
- primaryType->mMemberList = newType->mMemberList;
- primaryType->mCompileUnit = newType->mCompileUnit;
- }
- bool DbgModule::CanRead(DataStream* stream, DebuggerResult* outResult)
- {
- PEHeader hdr;
- memset(&hdr, 0, sizeof(hdr));
- PE_NTHeaders ntHdr;
- memset(&ntHdr, 0, sizeof(ntHdr));
- stream->Read(&hdr, sizeof(PEHeader));
- stream->SetPos(hdr.e_lfanew);
- stream->Read(&ntHdr, sizeof(PE_NTHeaders));
- if ((hdr.e_magic != PE_DOS_SIGNATURE) || (ntHdr.mSignature != PE_NT_SIGNATURE))
- {
- *outResult = DebuggerResult_UnknownError;
- return false;
- }
- #ifdef BF_DBG_32
- if (ntHdr.mFileHeader.mMachine != PE_MACHINE_X86)
- {
- if (ntHdr.mFileHeader.mMachine == PE_MACHINE_X64)
- *outResult = DebuggerResult_WrongBitSize;
- else
- *outResult = DebuggerResult_UnknownError;
- return false;
- }
- #else
- if (ntHdr.mFileHeader.mMachine != PE_MACHINE_X64)
- {
- if (ntHdr.mFileHeader.mMachine == PE_MACHINE_X86)
- *outResult = DebuggerResult_WrongBitSize;
- else
- *outResult = DebuggerResult_UnknownError;
- return false;
- }
- #endif
- return true;
- }
- const char* DbgModule::GetStringTable(DataStream* stream, int stringTablePos)
- {
- if (mStringTable == NULL)
- {
- int prevPos = stream->GetPos();
- stream->SetPos(stringTablePos);
- int strTableSize = 0;
- stream->Read(&strTableSize, 4);
- if (strTableSize != 0)
- {
- strTableSize -= 4;
- char* strTableData = new char[strTableSize + 4];
- memcpy(strTableData, &strTableSize, 4);
- stream->Read(strTableData + 4, strTableSize);
- mStringTable = strTableData;
- }
- stream->SetPos(prevPos);
- }
- return mStringTable;
- }
- bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind)
- {
- BP_ZONE("DbgModule::ReadCOFF");
- //if (this == mDebugTarget->mTargetBinary)
- //mMemReporter = new MemReporter();
- BfLogDbg("DbgModule::ReadCOFF %s\n", mFilePath.c_str());
- if (mMemReporter != NULL)
- {
- mMemReporter->BeginSection(StrFormat("Module: %s", mFilePath.c_str()));
- mMemReporter->Add(mImageSize);
- }
- defer
- (
- if (mMemReporter != NULL)
- mMemReporter->EndSection();
- );
-
- DbgModule* mainModule = mDebugTarget->mTargetBinary;
-
- MiniDumpDebugger* miniDumpDebugger = NULL;
- if (mDebugger->IsMiniDumpDebugger())
- {
- miniDumpDebugger = (MiniDumpDebugger*)mDebugger;
- }
- mModuleKind = moduleKind;
- bool isHotSwap = mModuleKind == DbgModuleKind_HotObject;
- bool isObjectFile = mModuleKind != DbgModuleKind_Module;
-
- auto linkedModule = GetLinkedModule();
- if (isObjectFile)
- linkedModule->PopulateStaticVariableMap();
-
- mStartTypeIdx = (int)linkedModule->mTypes.size();
- int startSrcFile = (int)mDebugTarget->mSrcFiles.size();
- mStartSubprogramIdx = (int)mSubprograms.size();
-
- PEHeader hdr;
- memset(&hdr, 0, sizeof(hdr));
- PE_NTHeaders ntHdr;
- memset(&ntHdr, 0, sizeof(ntHdr));
- if (!isObjectFile)
- {
- stream->Read(&hdr, sizeof(PEHeader));
- stream->SetPos(hdr.e_lfanew);
-
- stream->Read(&ntHdr, sizeof(PE_NTHeaders));
- mPreferredImageBase = ntHdr.mOptionalHeader.mImageBase;
- if (mImageBase == 0)
- {
- BF_ASSERT(this == mainModule);
- mImageBase = mPreferredImageBase;
- }
- if ((hdr.e_magic != PE_DOS_SIGNATURE) || (ntHdr.mSignature != PE_NT_SIGNATURE))
- {
- mLoadState = DbgModuleLoadState_Failed;
- return false;
- }
- #ifdef BF_DBG_32
- if (ntHdr.mFileHeader.mMachine != PE_MACHINE_X86)
- return false;
- #else
- if (ntHdr.mFileHeader.mMachine != PE_MACHINE_X64)
- {
- mLoadState = DbgModuleLoadState_Failed;
- return false;
- }
- #endif
- int pos = hdr.e_lfanew + FIELD_OFFSET(PE_NTHeaders, mOptionalHeader) + ntHdr.mFileHeader.mSizeOfOptionalHeader;
- stream->SetPos(pos);
- }
- else
- {
- stream->Read(&ntHdr.mFileHeader, sizeof(PEFileHeader));
- if (mMemReporter != NULL)
- mMemReporter->Add("PEFileHeader", sizeof(PEFileHeader));
- #ifdef BF_DBG_32
- if (ntHdr.mFileHeader.mMachine != PE_MACHINE_X86)
- return false;
- #else
- if (ntHdr.mFileHeader.mMachine != PE_MACHINE_X64)
- {
- mLoadState = DbgModuleLoadState_Failed;
- return false;
- }
- #endif
- }
-
- int sectionStartPos = stream->GetPos();
- int sectionDataEndPos = 0;
- if (miniDumpDebugger != NULL)
- {
- // Map header
- miniDumpDebugger->MapMemory((addr_target)mImageBase, (uint8*)mMappedImageFile->mData, 0x1000);
- }
- bool wantStringTable = isObjectFile;
- stream->SetPos(sectionStartPos);
- for (int dirNum = 0; dirNum < (int) ntHdr.mFileHeader.mNumberOfSections; dirNum++)
- {
- PESectionHeader sectHdr;
- char* name = sectHdr.mName;
- stream->Read(§Hdr, sizeof(PESectionHeader));
- if (sectHdr.mSizeOfRawData > 0)
- sectionDataEndPos = BF_MAX(sectionDataEndPos, (int)(sectHdr.mPointerToRawData + sectHdr.mSizeOfRawData));
- if (sectHdr.mNumberOfRelocations > 0)
- sectionDataEndPos = BF_MAX(sectionDataEndPos, (int)(sectHdr.mPointerToRelocations + sectHdr.mNumberOfRelocations * sizeof(COFFRelocation)));
-
- if (miniDumpDebugger != NULL)
- {
- miniDumpDebugger->MapMemory((addr_target)(mImageBase + sectHdr.mVirtualAddress), (uint8*)mMappedImageFile->mData + sectHdr.mPointerToRawData, sectHdr.mSizeOfRawData);
- }
- }
-
- //fseek(fp, sectionDataEndPos + ntHdr.mFileHeader.mNumberOfSymbols * 18, SEEK_SET);
- stream->SetPos(sectionDataEndPos);
- uint8* symbolData = new uint8[ntHdr.mFileHeader.mNumberOfSymbols * 18];
- mAllocSizeData += ntHdr.mFileHeader.mNumberOfSymbols * 18;
- mSymbolData = symbolData;
- stream->Read(symbolData, ntHdr.mFileHeader.mNumberOfSymbols * 18);
- int curPos = stream->GetPos();
- int stringTablePos = curPos;
- if (isObjectFile)
- GetStringTable(stream, stringTablePos);
-
- int mDebugFrameDataLen = 0;
-
- stream->SetPos(sectionStartPos);
-
- PEDataDirectory* exportDataDir = &ntHdr.mOptionalHeader.mDataDirectory[0];
-
- mHotTargetSections.Resize(ntHdr.mFileHeader.mNumberOfSections);
-
- Array<PESectionHeader> sectionHeaders;
- sectionHeaders.Resize(ntHdr.mFileHeader.mNumberOfSections);
- mSectionRVAs.Resize(sectionHeaders.size() + 1);
- Array<String> sectionNames;
- sectionNames.Resize(ntHdr.mFileHeader.mNumberOfSections);
- stream->Read(§ionHeaders[0], sizeof(PESectionHeader) * ntHdr.mFileHeader.mNumberOfSections);
- for (int sectNum = 0; sectNum < ntHdr.mFileHeader.mNumberOfSections; sectNum++)
- {
- mSectionRVAs[sectNum] = sectionHeaders[sectNum].mVirtualAddress;
- }
-
- int tlsSection = -1;
- for (int sectNum = 0; sectNum < ntHdr.mFileHeader.mNumberOfSections; sectNum++)
- {
- //PEDataDirectory* dataDir = &ntHdr.mOptionalHeader.mDataDirectory[dirNum];
- PESectionHeader& sectHdr = sectionHeaders[sectNum];
- //stream->Read(§Hdr, sizeof(PESectionHeader));
- const char* name = sectHdr.mName;
- if (name[0] == '/')
- {
- int strIdx = atoi(name + 1);
- name = &GetStringTable(stream, stringTablePos)[strIdx];
- }
- sectionNames[sectNum] = name;
- DbgHotTargetSection* targetSection = NULL;
- if (IsObjectFile())
- {
- targetSection = new DbgHotTargetSection();
- targetSection->mDataSize = sectHdr.mSizeOfRawData;
- targetSection->mPointerToRelocations = sectHdr.mPointerToRelocations;
- targetSection->mNumberOfRelocations = sectHdr.mNumberOfRelocations;
- targetSection->mTargetSectionAddr = 0; // TODO: Allocate!
- targetSection->mCanExecute = (sectHdr.mCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
- targetSection->mCanWrite = (sectHdr.mCharacteristics & IMAGE_SCN_MEM_WRITE) != 0;
- targetSection->mNoTargetAlloc = (sectHdr.mCharacteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0;
- mHotTargetSections[sectNum] = targetSection;
- }
-
- DbgSection dwSection;
- dwSection.mIsExecutable = (sectHdr.mCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
- dwSection.mAddrStart = sectHdr.mVirtualAddress;
- dwSection.mAddrLength = BF_MAX(sectHdr.mSizeOfRawData, sectHdr.mVirtualSize);
- mSections.push_back(dwSection);
- if (sectHdr.mPointerToRawData == 0)
- continue;
- if (strcmp(name, ".tls") == 0)
- mTLSAddr = (addr_target)(sectHdr.mVirtualAddress + mImageBase);
- if ((IsObjectFile()) && (strcmp(name, ".tls$") == 0))
- {
- tlsSection = sectNum;
- mTLSSize = sectHdr.mSizeOfRawData;
- targetSection->mNoTargetAlloc = true;
- }
- bool isExportDataDir = ((exportDataDir->mVirtualAddress != 0) && (exportDataDir->mVirtualAddress >= sectHdr.mVirtualAddress) && (exportDataDir->mVirtualAddress < sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData));
- if ((!IsObjectFile()) && (!isExportDataDir))
- {
- if (((strcmp(name, ".text")) == 0) ||
- ((strcmp(name, ".textbss")) == 0) ||
- ((strcmp(name, ".reloc")) == 0)/* ||
- ((strcmp(name, ".data")) == 0)*/)
- {
- // Big unneeded sections
- continue;
- }
- }
- stream->SetPos(sectHdr.mPointerToRawData);
- int dataSize = sectHdr.mSizeOfRawData + 8;
- mAllocSizeData += dataSize;
- uint8* data = new uint8[dataSize];
- {
- BP_ZONE("DbgModule::ReadCOFF_ReadSectionData");
- stream->Read(data, sectHdr.mSizeOfRawData);
- }
- BfLogDbg("Read section data %s %p\n", name, data);
- memset(data + sectHdr.mSizeOfRawData, 0, 8);
- if (IsObjectFile())
- targetSection->mData = data;
- addr_target addrOffset = sectHdr.mVirtualAddress;
- if (isExportDataDir)
- {
- BP_ZONE("DbgModule::ReadCOFF_SymbolMap");
- IMAGE_EXPORT_DIRECTORY* imageExportDir = (IMAGE_EXPORT_DIRECTORY*)(data + (exportDataDir->mVirtualAddress - addrOffset));
- for (int funcIdx = 0; funcIdx < (int)imageExportDir->NumberOfNames; funcIdx++)
- {
- //addr_target strAddr = *(addr_target*)(data + (imageExportDir->AddressOfNames - addrOffset) + funcIdx * sizeof(addr_target));
- int32 strAddr = *(int32*)(data + (imageExportDir->AddressOfNames - addrOffset) + funcIdx * sizeof(int32));
- const char* name = (const char*)(data + (strAddr - addrOffset));
- #ifdef BF_DBG_32
- if (name[0] == '_')
- name++;
- #endif
- int funcOrd = *(uint16*)(data + (imageExportDir->AddressOfNameOrdinals - addrOffset) + funcIdx * sizeof(uint16));
- addr_target funcAddr = *(uint32*)(data + (imageExportDir->AddressOfFunctions - addrOffset) + funcOrd * sizeof(int32));
- int strLen = (int)strlen(name);
- BP_ALLOC("ReadCOFF_SymbolMap", strLen + 1);
- char* allocStr = (char*)mAlloc.AllocBytes(strLen + 1, "ReadCOFF_SymbolMap");
- memcpy(allocStr, name, strLen);
- BP_ALLOC_T(DbgSymbol);
- DbgSymbol* dwSymbol = mAlloc.Alloc<DbgSymbol>();
- dwSymbol->mDbgModule = this;
- dwSymbol->mName = allocStr;
- dwSymbol->mAddress = funcAddr;
- if (strcmp(name, "_tls_index") == 0)
- {
- mTLSIndexAddr = funcAddr;
- }
- //TODO:
- //mDeferredSymbols.PushFront(dwSymbol);
- dwSymbol->mAddress = (addr_target)(dwSymbol->mAddress + mImageBase);
- mDebugTarget->mSymbolMap.Insert(dwSymbol);
- linkedModule->mSymbolNameMap.Insert(dwSymbol);
- }
- }
- if ((IsObjectFile()) && (sectHdr.mNumberOfRelocations > 0))
- {
- //mDebugger->AllocTargetMemory(sectHdr.mSizeOfRawData, true, true);
- }
- if (strcmp(name, ".text") == 0)
- {
- if (!IsObjectFile())
- mCodeAddress = ntHdr.mOptionalHeader.mImageBase + sectHdr.mVirtualAddress;
- }
- //if (strcmp(name, ".rdata") == 0)
- {
- PEDataDirectory& debugDirEntry = ntHdr.mOptionalHeader.mDataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
- if (debugDirEntry.mSize > 0)
- {
- if (mMemReporter != NULL)
- mMemReporter->Add("DataDirectory", debugDirEntry.mSize);
- if ((debugDirEntry.mVirtualAddress >= sectHdr.mVirtualAddress) && (debugDirEntry.mVirtualAddress < sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData))
- {
- int count = debugDirEntry.mSize / sizeof(IMAGE_DEBUG_DIRECTORY);
- for (int dirIdx = 0; dirIdx < count; dirIdx++)
- {
- IMAGE_DEBUG_DIRECTORY* debugDirectory = (IMAGE_DEBUG_DIRECTORY*)(data + debugDirEntry.mVirtualAddress - sectHdr.mVirtualAddress) + dirIdx;
- if (debugDirectory->Type == IMAGE_DEBUG_TYPE_CODEVIEW)
- {
- struct _CodeViewEntry
- {
- public:
- int32 mSig;
- uint8 mGUID[16];
- int32 mAge;
- const char mPDBPath[1];
- };
- if (debugDirectory->AddressOfRawData != 0)
- {
- _CodeViewEntry* codeViewEntry = (_CodeViewEntry*)(data + debugDirectory->AddressOfRawData - sectHdr.mVirtualAddress);
- if (codeViewEntry->mSig == 'SDSR')
- {
- LoadPDB(codeViewEntry->mPDBPath, codeViewEntry->mGUID, codeViewEntry->mAge);
- }
- }
- }
- }
- }
- //stream->SetPos(debugDirEntry.mVirtualAddress);
- }
- }
- //
- {
- PEDataDirectory& tlsDirEntry = ntHdr.mOptionalHeader.mDataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
- if (tlsDirEntry.mSize > 0)
- {
- if ((tlsDirEntry.mVirtualAddress >= sectHdr.mVirtualAddress) && (tlsDirEntry.mVirtualAddress < sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData))
- {
- uint8* relPtr = data + tlsDirEntry.mVirtualAddress - sectHdr.mVirtualAddress;
- uint8* endPtr = relPtr + tlsDirEntry.mSize;
- addr_target tlsDataStart = GET_FROM(relPtr, addr_target) - ntHdr.mOptionalHeader.mImageBase;
- addr_target tlsDataEnd = GET_FROM(relPtr, addr_target) - ntHdr.mOptionalHeader.mImageBase;
- mTLSAddr = (addr_target)(tlsDataStart + mImageBase);
- mTLSSize = (int)(tlsDataEnd - tlsDataStart);
- }
- }
- }
- //
- {
- PEDataDirectory& debugDirEntry = ntHdr.mOptionalHeader.mDataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
- if (debugDirEntry.mSize > 0)
- {
- if ((debugDirEntry.mVirtualAddress >= sectHdr.mVirtualAddress) && (debugDirEntry.mVirtualAddress < sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData))
- {
- uint8* relPtr = data + debugDirEntry.mVirtualAddress - sectHdr.mVirtualAddress;
- uint8* endPtr = relPtr + debugDirEntry.mSize;
- IMAGE_RESOURCE_DIRECTORY* typeDir = (IMAGE_RESOURCE_DIRECTORY*)(relPtr);
-
- // Skip named entries
- for (int typeIdx = 0; typeIdx < typeDir->NumberOfIdEntries; typeIdx++)
- {
- IMAGE_RESOURCE_DIRECTORY_ENTRY* typeEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((uint8*)typeDir + sizeof(IMAGE_RESOURCE_DIRECTORY) +
- (typeDir->NumberOfNamedEntries + typeIdx)*sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
- if (typeEntry->Id == 0x10) //VERSION
- {
- IMAGE_RESOURCE_DIRECTORY* idDir = (IMAGE_RESOURCE_DIRECTORY*)(relPtr + (typeEntry->OffsetToData & 0x7FFFFFFF));
- if (idDir->NumberOfIdEntries < 1)
- break;
- IMAGE_RESOURCE_DIRECTORY_ENTRY* idEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((uint8*)idDir + sizeof(IMAGE_RESOURCE_DIRECTORY) +
- (idDir->NumberOfNamedEntries + 0) * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
- IMAGE_RESOURCE_DIRECTORY* langDir = (IMAGE_RESOURCE_DIRECTORY*)(relPtr + (idEntry->OffsetToData & 0x7FFFFFFF));
- if (langDir->NumberOfIdEntries < 1)
- break;
- IMAGE_RESOURCE_DIRECTORY_ENTRY* langEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((uint8*)langDir + sizeof(IMAGE_RESOURCE_DIRECTORY) +
- (langDir->NumberOfNamedEntries + 0) * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
- IMAGE_RESOURCE_DATA_ENTRY* dataEntry = (IMAGE_RESOURCE_DATA_ENTRY*)(relPtr + (langEntry->OffsetToData & 0x7FFFFFFF));
- uint8* versionData = data + dataEntry->OffsetToData - sectHdr.mVirtualAddress;
- uint8* vPtr = versionData;
-
- auto vSize = GET_FROM(vPtr, uint16);
- auto verEnd = vPtr + vSize;
- auto vLength = GET_FROM(vPtr, uint16);
- vPtr += 36; // "VS_VERSION_INFO"
- auto fixedFileInfo = GET_FROM(vPtr, VS_FIXEDFILEINFO);
- auto _GetString = [&]()
- {
- wchar_t* cPtr = (wchar_t*)vPtr;
- int len = (int)wcslen(cPtr);
- vPtr += (len + 1) * 2;
-
- if (((intptr)vPtr & 3) != 0)
- vPtr += 2;
- UTF16String str16(cPtr, len);
- return UTF8Encode(str16);
- };
- while (vPtr < verEnd)
- {
- auto size = GET_FROM(vPtr, uint16);
- auto childEnd = vPtr + size;
- auto valueLength = GET_FROM(vPtr, uint16);
- auto type = GET_FROM(vPtr, uint16);
- String infoType = _GetString();
- if (infoType == "StringFileInfo")
- {
- while (vPtr < childEnd)
- {
- auto strsSize = GET_FROM(vPtr, uint16);
- auto strsEnd = vPtr + strsSize;
- auto strsLength = GET_FROM(vPtr, uint16);
- auto strsType = GET_FROM(vPtr, uint16);
- String hexNum = _GetString();
- while (vPtr < strsEnd)
- {
- auto strSize = GET_FROM(vPtr, uint16);
- auto strEnd = vPtr + strSize;
- auto strLength = GET_FROM(vPtr, uint16);
- auto strType = GET_FROM(vPtr, uint16);
- String key = _GetString();
- String value = _GetString();
- if (key == "FileVersion")
- mVersion = value;
- }
- }
- }
- vPtr = childEnd;
- }
- }
- }
- }
- //stream->SetPos(debugDirEntry.mVirtualAddress);
- }
- }
-
- bool usedData = true;
- /*if (isUnwindSection)
- {
- mExceptionData = data;
- mExceptionDataRVA = sectHdr.mVirtualAddress;
- }*/
- if (strcmp(name, ".pdata") == 0)
- {
- DbgSectionData entry;
- entry.mData = data;
- entry.mSize = sectHdr.mSizeOfRawData;
- mExceptionDirectory.Add(entry);
- }
- /*else if (strcmp(name, ".rdata") == 0)
- {
- if (mExceptionData == NULL)
- {
- mExceptionData = data;
- mExceptionDataRVA = sectHdr.mVirtualAddress;
- }
- else
- {
- usedData = false;
- }
- }
- else if (strcmp(name, ".xdata") == 0)
- {
- if (mExceptionData != NULL)
- {
- if (IsObjectFile())
- {
- mOwnedSectionData.push_back(mExceptionData);
- }
- else
- {
- // xdata section overrides rdata exception data
- delete[] mExceptionData;
- }
- }
- mExceptionData = data;
- mExceptionDataRVA = sectHdr.mVirtualAddress;
- }*/
- else if (strcmp(name, ".debug_info") == 0)
- {
- mDebugInfoData = data;
- }
- else if (strcmp(name, ".debug_line") == 0)
- {
- mDebugLineData = data;
- }
- else if (strcmp(name, ".debug_str") == 0)
- {
- mDebugStrData = data;
- }
- else if (strcmp(name, ".debug_frame") == 0)
- {
- mDebugFrameAddress = ntHdr.mOptionalHeader.mImageBase + sectHdr.mVirtualAddress;
- mDebugFrameData = data;
- mDebugFrameDataLen = sectHdr.mSizeOfRawData;
- }
- else if (strcmp(name, ".eh_frame") == 0)
- {
- mEHFrameAddress = ntHdr.mOptionalHeader.mImageBase + sectHdr.mVirtualAddress;
- mEHFrameData = data;
- }
- else if (strcmp(name, ".debug_abbrev") == 0)
- {
- mDebugAbbrevData = data;
- mDebugAbbrevPtrData = new const uint8*[sectHdr.mSizeOfRawData];
- }
- else if (strcmp(name, ".debug_loc") == 0)
- {
- mDebugLocationData = data;
- }
- else if (strcmp(name, ".debug_ranges") == 0)
- {
- mDebugRangesData = data;
- }
- // else if (strcmp(name, ".rsrc") == 0)
- // {
- // //IMAGE_DIRECTORY_ENTRY_RESOURCE
- // }
- else if (CheckSection(name, data, sectHdr.mSizeOfRawData))
- {
- // Was used
- }
- else
- {
- /*if (isUnwindSection)
- mOwnsExceptionData = true;
- else*/
- usedData = false;
- }
- if (!usedData)
- {
- if (IsObjectFile())
- {
- mOwnedSectionData.push_back(data);
- }
- else
- {
- mAllocSizeData -= dataSize;
- delete [] data;
- }
- }
- //stream->SetPos(prevPos);
- }
- int needHotTargetMemory = 0;
- if (isObjectFile)
- {
- for (int sectNum = 0; sectNum < ntHdr.mFileHeader.mNumberOfSections; sectNum++)
- {
- auto targetSection = mHotTargetSections[sectNum];
- if (!targetSection->mNoTargetAlloc)
- needHotTargetMemory += (targetSection->mDataSize + (mDebugger->mPageSize - 1)) & ~(mDebugger->mPageSize - 1);
- }
- mDebugger->ReserveHotTargetMemory(needHotTargetMemory);
-
- // '0' address is temporary
- //mOrigImageData = new DbgModuleMemoryCache(0, NULL, needHotTargetMemory, true);
- mOrigImageData = new DbgModuleMemoryCache(0, needHotTargetMemory);
- }
- int numSections = ntHdr.mFileHeader.mNumberOfSections;
- if (isObjectFile)
- {
- addr_target* resolvedSymbolAddrs = new addr_target[ntHdr.mFileHeader.mNumberOfSymbols];
- memset(resolvedSymbolAddrs, 0, ntHdr.mFileHeader.mNumberOfSymbols * sizeof(addr_target));
- ParseHotTargetSections(stream, resolvedSymbolAddrs);
- delete [] resolvedSymbolAddrs;
- }
- ProcessDebugInfo();
- if (mDebugInfoData != NULL)
- {
- mDbgFlavor = DbgFlavor_GNU;
- mMasterCompileUnit = new DbgCompileUnit(this);
- mMasterCompileUnit->mDbgModule = this;
- mMasterCompileUnit->mIsMaster = true;
- const uint8* data = mDebugInfoData;
- while (ParseDWARF(data)) {}
- CreateNamespaces();
- // Must be added last so module reference indices still map correctly
- mCompileUnits.push_back(mMasterCompileUnit);
- }
- ParseDebugFrameData();
- ParseEHFrameData();
- mEndTypeIdx = (int)linkedModule->mTypes.size();
- mEndSubprogramIdx = (int)mSubprograms.size();
- if (mDebugLineData != NULL)
- {
- const uint8* data = mDebugLineData;
- for (int compileUnitIdx = 0; true; compileUnitIdx++)
- if (!ParseDebugLineInfo(data, compileUnitIdx))
- break;
- }
-
- {
- BP_ZONE("ReadPE_ReadSymbols");
- //linkedModule->mSymbolNameMap.reserve(linkedModule->mSymbolNameMap.size() + ntHdr.mFileHeader.mNumberOfSymbols * 2);
- bool tlsFailed = false;
- addr_target tlsMappingAddr = 0;
- for (int symNum = 0; symNum < (int)ntHdr.mFileHeader.mNumberOfSymbols; symNum++)
- {
- PE_SymInfo* symInfo = (PE_SymInfo*)&mSymbolData[symNum * 18];
- char* name = symInfo->mName;
- if (symInfo->mNameOfs[0] != 0)
- {
- if (name[7] != 0)
- {
- // Name is exactly 8 chars, not null terminated yet
- name = (char*)mAlloc.AllocBytes(9, "PESymbol");
- memcpy(name, symInfo->mName, 8);
- name[8] = 0;
- }
- }
- else
- name = (char*)GetStringTable(stream, stringTablePos) + symInfo->mNameOfs[1];
- if ((symInfo->mStorageClass == COFF_SYM_CLASS_EXTERNAL) ||
- (symInfo->mStorageClass == COFF_SYM_CLASS_STATIC))
- {
- // 'static' in the C sense.
- // It means local to the compile unit, so may have multiple copies of the same symbol name.
- bool isStaticSymbol = symInfo->mStorageClass == COFF_SYM_CLASS_STATIC;
- if (symInfo->mSectionNum == 0xFFFF)
- continue;
- if (symInfo->mSectionNum > 0)
- {
- bool isTLS = false;
- addr_target targetAddr = 0;
- if (isObjectFile)
- {
- if (symInfo->mSectionNum - 1 == tlsSection)
- {
- isTLS = true;
- }
- else
- {
- auto hotTargetSection = mHotTargetSections[symInfo->mSectionNum - 1];
- if (hotTargetSection != NULL)
- targetAddr = GetHotTargetAddress(hotTargetSection) + symInfo->mValue;
- }
- }
- else
- targetAddr = mSectionRVAs[symInfo->mSectionNum - 1] + symInfo->mValue;
-
- if (((targetAddr != 0) || (isTLS)) &&
- (name[0] != '.'))
- {
- const char* symbolName = name;
- #ifdef BF_DBG_32
- if (symbolName[0] == '_')
- symbolName++;
- #endif
- if (strcmp(symbolName, "_tls_index") == 0)
- {
- mTLSIndexAddr = (addr_target)(targetAddr + mImageBase);
- }
-
- if ((isStaticSymbol) && (IsHotSwapPreserve(symbolName)))
- isStaticSymbol = false;
- if ((isObjectFile) && (!isStaticSymbol))
- {
- DbgSymbol* dwSymbol = NULL;
- linkedModule->ParseSymbolData() ;
- BP_ALLOC_T(DbgSymbol);
- dwSymbol = mAlloc.Alloc<DbgSymbol>();
- dwSymbol->mDbgModule = this;
- dwSymbol->mName = symbolName;
- dwSymbol->mAddress = targetAddr;
- if (dwSymbol != NULL)
- {
- bool isHotSwapPreserve = IsHotSwapPreserve(dwSymbol->mName);
- bool insertIntoNameMap = true;
-
- bool oldFound = false;
-
- auto nameMapEntry = linkedModule->mSymbolNameMap.Find(dwSymbol->mName);
- if (nameMapEntry != NULL)
- {
- oldFound = true;
- if (!isHotSwapPreserve)
- {
- nameMapEntry->mValue = dwSymbol;
- }
- else if (mDbgFlavor == DbgFlavor_MS)
- {
- // Store in our own map - this is needed for storing address of the new vdata
- // so the new values can be copied in
- mSymbolNameMap.Insert(dwSymbol);
- }
- }
- else
- {
- if (isTLS)
- {
- if (mainModule->mTLSExtraAddr == 0)
- {
- auto extraSym = mainModule->mSymbolNameMap.Find("__BFTLS_EXTRA");
- if (extraSym != NULL)
- {
- mainModule->ParseGlobalsData();
- auto itr = mainModule->mStaticVariableMap.find("__BFTLS_EXTRA");
- if (itr != mainModule->mStaticVariableMap.end())
- {
- auto staticVar = itr->second;
- mainModule->mTLSExtraAddr = extraSym->mValue->mAddress;
- mainModule->mTLSExtraSize = (int)staticVar->mType->GetByteCount();
- }
- }
- }
- if ((mainModule->mTLSExtraAddr != 0) && (tlsMappingAddr == 0))
- {
- // Take a chunk out of __BFTLS_EXTRA
- if (mTLSSize <= mainModule->mTLSExtraSize)
- {
- tlsMappingAddr = mainModule->mTLSExtraAddr;
- mainModule->mTLSExtraAddr += mTLSSize;
- mainModule->mTLSExtraSize -= mTLSSize;
- }
- }
- if (tlsMappingAddr != 0)
- {
- BF_ASSERT(symInfo->mValue < mTLSSize);
- dwSymbol->mAddress = tlsMappingAddr + symInfo->mValue;
- }
- if (dwSymbol->mAddress == 0)
- {
- if (!tlsFailed)
- {
- Fail(StrFormat("Hot swapping failed to allocate TLS address for '%s'. Program restart required.", name));
- }
- dwSymbol->mAddress = (addr_target)0xCDCDCDCD;
- tlsFailed = true;
- }
- }
- }
-
- if (dwSymbol->mAddress != 0)
- {
- if (!oldFound)
- linkedModule->mSymbolNameMap.Insert(dwSymbol);
- mDebugTarget->mSymbolMap.Insert(dwSymbol);
- }
- }
- }
- else
- {
- //TODO: We don't need to defer symbols anymore... we can just do a Fixup on their addr
- //mDeferredSymbols.PushFront(dwSymbol);
- BP_ALLOC_T(DbgSymbol);
- DbgSymbol* dwSymbol = mAlloc.Alloc<DbgSymbol>();
- dwSymbol->mDbgModule = this;
- dwSymbol->mName = symbolName;
- dwSymbol->mAddress = targetAddr;
- if (!IsObjectFile())
- dwSymbol->mAddress += (addr_target)mImageBase;
- if (IsObjectFile())
- BF_ASSERT((dwSymbol->mAddress >= mImageBase) && (dwSymbol->mAddress < mImageBase + mImageSize));
- mDebugTarget->mSymbolMap.Insert(dwSymbol);
- if (!isStaticSymbol)
- linkedModule->mSymbolNameMap.Insert(dwSymbol);
- }
- }
- }
- }
- if (symInfo->mStorageClass == COFF_SYM_CLASS_FILE)
- {
- const char* fileName = (const char*)&mSymbolData[(symNum + 1) * 18];
- }
- symNum += symInfo->mNumOfAuxSymbols;
- }
- }
- int subProgramSizes = 0;
- for (int subProgramIdx = mStartSubprogramIdx; subProgramIdx < mEndSubprogramIdx; subProgramIdx++)
- {
- auto dwSubprogram = mSubprograms[subProgramIdx];
- subProgramSizes += (int)(dwSubprogram->mBlock.mHighPC - dwSubprogram->mBlock.mLowPC);
-
- /*for (int i = 0; i < dwSubprogram->mLineDataArray.mSize; i++)
- {
- auto lineData = dwSubprogram->mLineDataArray.mData[i];
- auto srcFile = lineData->mSrcFileRef->mSrcFile;
- srcFile->mLineData.push_back(lineData);
- srcFile->mHadLineData = true;
- if ((srcFile->mFirstLineDataDbgModule == NULL) || (srcFile->mFirstLineDataDbgModule == this))
- srcFile->mFirstLineDataDbgModule = this;
- else
- srcFile->mHasLineDataFromMultipleModules = true;
- }*/
- }
- // Delete srcFiles without line data
- int lineDataCount = 0;
- /*for (int srcFileIdx = startSrcFile; srcFileIdx < (int)mDebugTarget->mSrcFiles.size(); srcFileIdx++)
- {
- if (!mDebugTarget->mSrcFiles[srcFileIdx]->mHadLineData)
- {
- mEmptySrcFiles.push_back(mDebugTarget->mSrcFiles[srcFileIdx]);
- mDebugTarget->mSrcFiles.erase(mDebugTarget->mSrcFiles.begin() + srcFileIdx);
- }
- else
- lineDataCount += (int)mDebugTarget->mSrcFiles[srcFileIdx]->mLineData.size();
- }*/
- auto srcFilesItr = mDebugTarget->mSrcFiles.begin();
- while (srcFilesItr != mDebugTarget->mSrcFiles.end())
- {
- DbgSrcFile* srcFile = srcFilesItr->mValue;
- if ((!srcFile->mHadLineData) && (srcFile->mLocalPath.IsEmpty()))
- {
- mEmptySrcFiles.push_back(srcFile);
- srcFilesItr = mDebugTarget->mSrcFiles.Remove(srcFilesItr);
- }
- else
- {
- ++srcFilesItr;
- }
- }
- if (!isObjectFile)
- {
- mImageSize = ntHdr.mOptionalHeader.mSizeOfImage;
- mEntryPoint = ntHdr.mOptionalHeader.mAddressOfEntryPoint;
- }
-
- /*OutputDebugStrF("%s:\n CompileUnits:%d DebugLines: %d Types: %d (%d in map) SubPrograms: %d (%dk) AllocSize:%dk\n", mFilePath.c_str(), mCompileUnits.size(),
- lineDataCount, mEndTypeIdx - mStartTypeIdx, (int)linkedModule->mTypes.size() - mStartTypeIdx, mEndSubprogramIdx - mStartSubprogramIdx, subProgramSizes / 1024, mAlloc.GetAllocSize() / 1024);*/
-
- if (isHotSwap)
- {
- // In COFF, we don't necessarily add an actual primary type during MapCompileUnitMethods, so this fixes that
- while (true)
- {
- bool didReplaceType = false;
- for (auto itr = mHotPrimaryTypes.begin(); itr != mHotPrimaryTypes.end(); ++itr)
- {
- auto dbgType = *itr;
- auto primaryType = dbgType->GetPrimaryType();
- if (primaryType != dbgType)
- {
- mHotPrimaryTypes.Remove(itr);
- mHotPrimaryTypes.Add(primaryType);
- didReplaceType = true;
- break;
- }
- }
- if (!didReplaceType)
- break;
- }
- BF_ASSERT(mTypes.size() == 0);
- for (int typeIdx = mStartTypeIdx; typeIdx < (int)linkedModule->mTypes.size(); typeIdx++)
- {
- DbgType* newType = linkedModule->mTypes[typeIdx];
- //if (!newType->mMethodList.IsEmpty())
- if (!newType->mIsDeclaration)
- HotReplaceType(newType);
- }
- }
-
- if (needHotTargetMemory != 0)
- {
- BF_ASSERT(needHotTargetMemory >= (int)mImageSize);
- }
- //BF_ASSERT(mEndTypeIdx == (int)linkedModule->mTypes.size());
- //BF_ASSERT(mEndSubprogramIdx == (int)mSubprograms.size());
- ParseExceptionData();
- mLoadState = DbgModuleLoadState_Loaded;
- if (mMemReporter != NULL)
- {
- mMemReporter->BeginSection("Sections");
- ParseSymbolData();
- Array<DbgSymbol*> orderedSyms;
- for (auto sym : mSymbolNameMap)
- {
- auto dbgSym = sym->mValue;
- orderedSyms.Add(dbgSym);
- }
- orderedSyms.Sort([](DbgSymbol* lhs, DbgSymbol* rhs) { return lhs->mAddress < rhs->mAddress; });
-
- for (int sectNum = 0; sectNum < ntHdr.mFileHeader.mNumberOfSections; sectNum++)
- {
- PESectionHeader& sectHdr = sectionHeaders[sectNum];
-
- mMemReporter->BeginSection(sectionNames[sectNum]);
- DbgSymbol* lastSym = NULL;
- for (auto dbgSym : orderedSyms)
- {
- if (dbgSym->mAddress < mImageBase + sectHdr.mVirtualAddress)
- continue;
- if (dbgSym->mAddress >= mImageBase + sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData)
- break;
-
- if (lastSym != NULL)
- {
- mMemReporter->Add(lastSym->mName, (int)(dbgSym->mAddress - lastSym->mAddress));
- }
- else
- {
- int startingOffset = (int)(dbgSym->mAddress - (mImageBase + sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData));
- if (startingOffset > 0)
- mMemReporter->Add("<StartData>", startingOffset);
- }
- lastSym = dbgSym;
- }
- if (lastSym != NULL)
- mMemReporter->Add(lastSym->mName, (int)((mImageBase + sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData) - lastSym->mAddress));
- else
- {
- mMemReporter->Add("<Unaccounted>", (int)(sectHdr.mSizeOfRawData));
- }
- mMemReporter->EndSection();
- }
- mMemReporter->EndSection();
- mMemReporter->mShowInKB = false;
- mMemReporter->Report();
- }
- return true;
- }
- void DbgModule::FinishHotSwap()
- {
- BF_ASSERT(IsObjectFile());
- auto linkedModule = GetLinkedModule();
- auto mainModule = mDebugTarget->mTargetBinary;
- HashSet<String> failSet;
- String findName;
- for (auto deferredHotResolve : mDeferredHotResolveList)
- {
- addr_target resolveTargetAddr = deferredHotResolve->mNewAddr;
- findName = deferredHotResolve->mName;
- if (mDbgFlavor == DbgFlavor_MS)
- {
- // ... why do we need to find these variables in the variable map instead of the symbol name map?
- }
- auto itr = mainModule->mStaticVariableMap.find(findName.c_str());
- if (itr != mainModule->mStaticVariableMap.end())
- {
- DbgVariable* variable = itr->second;
- resolveTargetAddr = mDebugTarget->GetStaticAddress(variable);
- }
- else
- {
- auto symbolEntry = mainModule->mSymbolNameMap.Find(findName.c_str());
- if (symbolEntry != NULL)
- {
- resolveTargetAddr = symbolEntry->mValue->mAddress;
- }
- else
- {
- if (deferredHotResolve->mName == "__ImageBase")
- {
- resolveTargetAddr = (addr_target)mainModule->mImageBase;
- }
- else
- {
- resolveTargetAddr = mainModule->LocateSymbol(deferredHotResolve->mName);
- if (resolveTargetAddr == 0)
- {
- failSet.Add(deferredHotResolve->mName);
- continue;
- }
- }
- }
- }
- DoReloc(deferredHotResolve->mHotTargetSection, deferredHotResolve->mReloc, resolveTargetAddr, NULL);
- }
- mDeferredHotResolveList.Clear();
- if (!failSet.IsEmpty())
- {
- bool handled = false;
- if (!mDebugger->mDebugManager->mOutMessages.empty())
- {
- auto& str = mDebugger->mDebugManager->mOutMessages.back();
- if (str.Contains("failed to resolve"))
- {
- for (auto& sym : failSet)
- {
- str += ", ";
- str += sym;
- }
- handled = true;
- }
- }
- if (!handled)
- {
- int symIdx = 0;
- String str;
- if (failSet.size() == 1)
- str = "Hot swapping failed to resolve symbol: ";
- else
- str = "Hot swapping failed to resolve symbols: ";
- for (auto& sym : failSet)
- {
- if (symIdx != 0)
- str += ", ";
- str += sym;
- symIdx++;
- }
- mDebugger->Fail(str);
- }
- }
- CommitHotTargetSections();
- // We need this here because vdata gets loaded first, so we need to wait until we have the addrs for the new methods (from other modules)
- // before we can finalize the class vdata.
- ProcessHotSwapVariables();
- for (auto hotTargetSection : mHotTargetSections)
- delete hotTargetSection;
- mHotTargetSections.Clear();
- mSymbolNameMap.Clear();
- }
- addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, DbgEvalLocFlags flags, addr_target* pushValue)
- {
- bool allowReg = (flags & DbgEvalLocFlag_IsParam) == 0;
- const uint8* locDataEnd = locData + locDataLen;
- int regNum = -1;
- addr_target stackFrameData[256];
- int stackIdx = 0;
- if (pushValue != NULL)
- stackFrameData[stackIdx++] = *pushValue;
- while (locData < locDataEnd)
- {
- uint8 opCode = GET_FROM(locData, uint8);
- switch (opCode)
- {
- case DW_OP_piece:
- {
- if (*outAddrType == DbgAddrType_Register)
- *outAddrType = DbgAddrType_Value;
- addr_target val = stackFrameData[--stackIdx];
- int pieceSize = (int)DecodeULEB128(locData);
- if (pieceSize == 4)
- val &= 0xFFFFFFFF;
- else if (pieceSize == 2)
- val &= 0xFFFF;
- else if (pieceSize == 1)
- val &= 0xFF;
- stackFrameData[stackIdx++] = val;
- }
- break;
- case DW_OP_consts:
- {
- int64 val = DecodeSLEB128(locData);
- stackFrameData[stackIdx++] = (addr_target)val;
- }
- break;
- case DW_OP_stack_value:
- {
- *outAddrType = DbgAddrType_Value;
- }
- break;
- case DW_OP_addr_noRemap:
- {
- addr_target addr = GET_FROM(locData, addr_target);
- stackFrameData[stackIdx++] = addr;
- //*outIsAddr = true;
- *outAddrType = DbgAddrType_Target;
- }
- break;
- case DW_OP_addr:
- {
- addr_target addr = GET_FROM(locData, addr_target);
- //if (dwarf != NULL)
- addr = RemapAddr(addr);
- stackFrameData[stackIdx++] = addr;
- //*outIsAddr = true;
- *outAddrType = DbgAddrType_Target;
- }
- break;
- case DW_OP_deref:
- {
- addr_target addr = stackFrameData[--stackIdx];
- addr_target value = mDebugger->ReadMemory<addr_target>(addr);
- stackFrameData[stackIdx++] = value;
- }
- break;
- case DW_OP_fbreg:
- {
- if (registers == NULL)
- return 0;
- BF_ASSERT(dwSubprogram != NULL);
- DbgSubprogram* nonInlinedSubProgram = dwSubprogram->GetRootInlineParent();
-
- if (nonInlinedSubProgram->mFrameBaseData == NULL)
- {
- *outAddrType = DbgAddrType_Target; //TODO: why?
- return 0;
- }
- BF_ASSERT(nonInlinedSubProgram->mFrameBaseData != NULL);
- intptr loc = EvaluateLocation(nonInlinedSubProgram, nonInlinedSubProgram->mFrameBaseData, nonInlinedSubProgram->mFrameBaseLen, stackFrame, outAddrType, DbgEvalLocFlag_DisallowReg);
- int64 offset = DecodeSLEB128(locData);
- loc += offset;
- //loc = BfDebuggerReadMemory(loc);
- //*outIsAddr = true;
- *outAddrType = DbgAddrType_Target;
- stackFrameData[stackIdx++] = (addr_target)loc;
- }
- break;
- case DW_OP_reg0:
- case DW_OP_reg1:
- case DW_OP_reg2:
- case DW_OP_reg3:
- case DW_OP_reg4:
- case DW_OP_reg5:
- case DW_OP_reg6:
- case DW_OP_reg7:
- case DW_OP_reg8:
- case DW_OP_reg9:
- case DW_OP_reg10:
- case DW_OP_reg11:
- case DW_OP_reg12:
- case DW_OP_reg13:
- case DW_OP_reg14:
- case DW_OP_reg15:
- if (registers == NULL)
- return 0;
- BF_ASSERT((opCode - DW_OP_reg0) < CPURegisters::kNumIntRegs);
- regNum = opCode - DW_OP_reg0;
- stackFrameData[stackIdx++] = registers->mIntRegsArray[regNum];
- *outAddrType = DbgAddrType_Register;
- break;
- case DW_OP_reg21: //XMM0
- BF_FATAL("XMM registers not supported yet");
- break;
- case DW_OP_breg0:
- case DW_OP_breg1:
- case DW_OP_breg2:
- case DW_OP_breg3:
- case DW_OP_breg4:
- case DW_OP_breg5:
- case DW_OP_breg6:
- case DW_OP_breg7:
- case DW_OP_breg8:
- case DW_OP_breg9:
- case DW_OP_breg10:
- case DW_OP_breg11:
- case DW_OP_breg12:
- case DW_OP_breg13:
- case DW_OP_breg14:
- case DW_OP_breg15:
- {
- if (registers == NULL)
- return 0;
- int64 offset = DecodeSLEB128(locData);
- BF_ASSERT((opCode - DW_OP_breg0) < CPURegisters::kNumIntRegs);
- auto loc = registers->mIntRegsArray[opCode - DW_OP_breg0] + offset;
- //loc = BfDebuggerReadMemory(loc);
- //*outIsAddr = true;
- *outAddrType = DbgAddrType_Target;
- stackFrameData[stackIdx++] = (addr_target)loc;
- }
- break;
- case DW_OP_bregx:
- {
- if (registers == NULL)
- return 0;
- int regNum = (int)DecodeULEB128(locData);
- int64 offset = DecodeSLEB128(locData);
- BF_ASSERT(regNum < CPURegisters::kNumIntRegs);
- auto loc = registers->mIntRegsArray[regNum] + offset;
- //loc = BfDebuggerReadMemory(loc);
- //*outIsAddr = true;
- *outAddrType = DbgAddrType_Target;
- stackFrameData[stackIdx++] = (addr_target)loc;
- }
- break;
- case DW_OP_const4u:
- {
- uint32 val = GET_FROM(locData, uint32);
- stackFrameData[stackIdx++] = val;
- }
- break;
- case DW_OP_const8u:
- {
- uint64 val = GET_FROM(locData, uint64);
- stackFrameData[stackIdx++] = (addr_target)val;
- }
- break;
- case DW_OP_GNU_push_tls_address:
- {
- if ((mTLSAddr == 0) || (mTLSIndexAddr == 0))
- return 0;
- int tlsIndex = mDebugger->ReadMemory<int>(mTLSIndexAddr);
- addr_target tlsEntry = mDebugger->GetTLSOffset(tlsIndex);
- intptr_target tlsValueIndex = stackFrameData[--stackIdx];
- stackFrameData[stackIdx++] = (tlsValueIndex - mTLSAddr) + tlsEntry;
- *outAddrType = DbgAddrType_Target;
- }
- break;
- case DW_OP_nop:
- break;
- default:
- BF_FATAL("Unknown DW_OP");
- break;
- }
- }
- if (*outAddrType == DbgAddrType_Register)
- {
- if (allowReg)
- return regNum;
- *outAddrType = DbgAddrType_Value;
- }
- //BF_ASSERT(stackIdx == 1);
- return stackFrameData[--stackIdx];
- }
- intptr DbgModule::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags)
- {
- BP_ZONE("DebugTarget::EvaluateLocation");
-
- auto dbgModule = this;
- if (locDataLen == DbgLocationLenKind_SegPlusOffset)
- {
- BF_ASSERT(dbgModule->mDbgFlavor == DbgFlavor_MS);
- if (dbgModule->mDbgFlavor == DbgFlavor_MS)
- {
- COFF* coff = (COFF*)dbgModule;
- struct SegOfsData
- {
- uint32 mOfs;
- uint16 mSeg;
- };
- SegOfsData* segOfsData = (SegOfsData*)locData;
- *outAddrType = DbgAddrType_Target;
- return coff->GetSectionAddr(segOfsData->mSeg, segOfsData->mOfs);
- }
- else
- {
- *outAddrType = DbgAddrType_Target;
- return 0;
- }
- }
- CPURegisters* registers = NULL;
- if (stackFrame != NULL)
- registers = &stackFrame->mRegisters;
- if (locDataLen < 0)
- {
- if (registers == NULL)
- return 0;
- int64 ipAddr = stackFrame->GetSourcePC();
- const uint8* checkLocData = locData;
- int64 startLoc = (int64)GET_FROM(checkLocData, addr_target);
- int64 endLoc = startLoc + GET_FROM(checkLocData, uint16);
- BF_ASSERT(dwSubprogram != NULL);
- startLoc += dwSubprogram->mCompileUnit->mLowPC;
- endLoc += dwSubprogram->mCompileUnit->mLowPC;
- if ((ipAddr >= startLoc) && (ipAddr < endLoc))
- {
- locDataLen = -locDataLen - sizeof(addr_target) - sizeof(uint16);
- locData = checkLocData;
- }
- else
- {
- *outAddrType = DbgAddrType_OptimizedOut;
- return 0;
- }
- }
- else if (locDataLen == 0)
- {
- if (registers == NULL)
- return 0;
- int64 ipAddr = stackFrame->GetSourcePC();
- const uint8* checkLocData = locData;
- while (true)
- {
- int64 startLoc = (int64)GET_FROM(checkLocData, addr_target);
- int64 endLoc = (int64)GET_FROM(checkLocData, addr_target);
- if ((startLoc == 0) && (endLoc == 0))
- {
- *outAddrType = DbgAddrType_OptimizedOut;
- return 0;
- }
- BF_ASSERT(dwSubprogram != NULL);
- startLoc += dwSubprogram->mCompileUnit->mLowPC;
- endLoc += dwSubprogram->mCompileUnit->mLowPC;
- if ((ipAddr >= startLoc) && (ipAddr < endLoc))
- {
- locDataLen = GET_FROM(checkLocData, int16);
- locData = checkLocData;
- break;
- }
- else
- {
- int len = GET_FROM(checkLocData, int16);;
- checkLocData += len;
- }
- }
- }
- return ExecuteOps(dwSubprogram, locData, locDataLen, stackFrame, registers, outAddrType, flags);
- }
- void DbgModule::ProcessHotSwapVariables()
- {
- BP_ZONE("DbgModule::ProcessHotSwapVariables");
- auto linkedModule = GetLinkedModule();
- for (auto staticVariable : mStaticVariables)
- {
- bool replaceVariable = false;
-
- const char* findName = staticVariable->GetMappedName();
- auto itr = linkedModule->mStaticVariableMap.find(findName);
- if (itr != linkedModule->mStaticVariableMap.end())
- {
- DbgVariable* oldVariable = itr->second;
- // If the old static field has the same type as the new static field then we keep the same
- // address, otherwise we use the new (zeroed-out) allocated space
- auto _GetNewAddress = [&]()
- {
- addr_target newAddress = 0;
- if (mDbgFlavor == DbgFlavor_GNU)
- {
- newAddress = mDebugTarget->GetStaticAddress(staticVariable);
- }
- else
- {
- // In CodeView, the newVariable ends up pointing to the old address, so we need to store
- // the location in our own mSymbolNameMap
- auto entry = mSymbolNameMap.Find(oldVariable->mLinkName);
- if (entry != NULL)
- newAddress = entry->mValue->mAddress;
- }
- return newAddress;
- };
- if (oldVariable->mType->IsSizedArray())
- {
- mDebugTarget->GetCompilerSettings();
-
- bool doMerge = strstr(oldVariable->mName, "sBfClassVData") != NULL;
- bool keepInPlace = (doMerge) && (strstr(oldVariable->mName, ".vext") == NULL);
- if (doMerge)
- {
- addr_target oldAddress = mDebugTarget->GetStaticAddress(oldVariable);
- addr_target newAddress = _GetNewAddress();
- if (newAddress == 0)
- continue;
-
- uint8* newData = GetHotTargetData(newAddress);
- int newArraySize = (int)staticVariable->mType->GetByteCount();
- int oldArraySize = (int)oldVariable->mType->GetByteCount();
- int copySize = std::min(newArraySize, oldArraySize);
- BF_ASSERT((oldArraySize & (sizeof(addr_target) - 1)) == 0);
- DbgModule* defModule = oldVariable->mType->mCompileUnit->mDbgModule;
- defModule->EnableWriting(oldAddress);
- uint8* mergedData = new uint8[copySize];
- mDebugger->ReadMemory(oldAddress, copySize, mergedData);
- // The new vtable may have 0's in it when virtual methods are removed. Keep the old virtual addresses in those.
- addr_target* newDataPtr = (addr_target*)newData;
- addr_target* mergedPtr = (addr_target*)mergedData;
- while (mergedPtr < (addr_target*)(mergedData + copySize))
- {
- if (*newDataPtr != 0)
- *mergedPtr = *newDataPtr;
- mergedPtr++;
- newDataPtr++;
- }
- bool success;
- success = mDebugger->WriteMemory(oldAddress, mergedData, copySize);
- BF_ASSERT(success);
- memcpy(newData, mergedData, copySize);
- delete mergedData;
- }
- else if (strstr(oldVariable->mName, "sStringLiterals") != NULL)
- {
- addr_target oldAddress = mDebugTarget->GetStaticAddress(oldVariable);
- addr_target newAddress = NULL;
- if (mDbgFlavor == DbgFlavor_GNU)
- {
- newAddress = mDebugTarget->GetStaticAddress(staticVariable);
- }
- else
- {
- // In CodeView, the newVariable ends up pointing to the old address, so we need to store
- // the location in our own mSymbolNameMap
- auto entry = mSymbolNameMap.Find(oldVariable->mLinkName);
- if (entry == NULL)
- continue;
- newAddress = entry->mValue->mAddress;
- }
- // Make sure newAddress doesn't have anything linked to it
- addr_target val = 0;
- bool success = mDebugger->ReadMemory((intptr)newAddress, sizeof(addr_target), &val);
- BF_ASSERT(success);
- BF_ASSERT(val == 0);
- // Link the new table to the old extended table
- addr_target prevLinkage = 0;
- success = mDebugger->ReadMemory((intptr)oldAddress, sizeof(addr_target), &prevLinkage);
- BF_ASSERT(success);
- success = mDebugger->WriteMemory((intptr)newAddress, &prevLinkage, sizeof(addr_target));
- BF_ASSERT(success);
- mDebugger->EnableWriting((intptr)oldAddress, sizeof(addr_target));
- success = mDebugger->WriteMemory((intptr)oldAddress, &newAddress, sizeof(addr_target));
- BF_ASSERT(success);
- keepInPlace = true;
- }
-
- if (keepInPlace)
- {
- // We have to maintain the OLD size because we can't overwrite the original bounds
- staticVariable->mType = oldVariable->mType;
- staticVariable->mLocationLen = oldVariable->mLocationLen;
- staticVariable->mLocationData = oldVariable->mLocationData;
- staticVariable->mCompileUnit = oldVariable->mCompileUnit;
- }
- }
- else if (oldVariable->mType->Equals(staticVariable->mType))
- {
- if (oldVariable->mType->IsStruct())
- {
- if ((strncmp(oldVariable->mName, "?sBfTypeData@", 13) == 0) || (strncmp(oldVariable->mName, "sBfTypeData.", 12) == 0))
- {
- int size = (int)staticVariable->mType->GetByteCount();
- addr_target oldAddress = mDebugTarget->GetStaticAddress(oldVariable);
- addr_target newAddress = _GetNewAddress();
- if (newAddress == 0)
- continue;
- uint8* data = new uint8[size];
- bool success = mDebugger->ReadMemory(newAddress, size, data);
- if (success)
- {
- mDebugger->EnableWriting((intptr)oldAddress, size);
- success = mDebugger->WriteMemory(oldAddress, data, size);
- }
- delete data;
- BF_ASSERT(success);
- staticVariable->mLocationLen = oldVariable->mLocationLen;
- staticVariable->mLocationData = oldVariable->mLocationData;
- }
- }
- //staticVariable->mLocationLen = oldVariable->mLocationLen;
- //staticVariable->mLocationData = oldVariable->mLocationData;
- replaceVariable = false;
- }
- else
- {
- BF_ASSERT(!oldVariable->mType->IsSizedArray());
- }
- if (!replaceVariable)
- {
- auto symbolVal = linkedModule->mSymbolNameMap.Find(staticVariable->GetMappedName());
- if (symbolVal != NULL)
- {
- addr_target oldAddress = mDebugTarget->GetStaticAddress(oldVariable);
- DbgSymbol* oldSymbol = mDebugTarget->mSymbolMap.Get(oldAddress);
- if (oldSymbol != NULL)
- symbolVal->mValue = oldSymbol;
- }
- }
- }
- else // Not found - new variable
- replaceVariable = true;
- if (replaceVariable)
- {
- linkedModule->mStaticVariableMap[staticVariable->GetMappedName()] = staticVariable;
- }
- }
- }
- int64 DbgModule::GetImageSize()
- {
- return mImageSize;
- }
- /*const uint8* DbgModule::GetOrigImageData(addr_target address)
- {
- return mOrigImageData + (address - mImageBase);
- }*/
- DbgFileExistKind DbgModule::CheckSourceFileExist(const StringImpl& path)
- {
- DbgFileExistKind existsKind = DbgFileExistKind_NotFound;
- if (FileExists(path))
- existsKind = DbgFileExistKind_Found;
- String oldSourceCommand = GetOldSourceCommand(path);
- if (!oldSourceCommand.IsEmpty())
- {
- int crPos = (int)oldSourceCommand.IndexOf('\n');
- if (crPos != -1)
- {
- String targetPath = oldSourceCommand.Substring(0, crPos);
- if (FileExists(targetPath))
- existsKind = DbgFileExistKind_Found;
- else
- existsKind = DbgFileExistKind_HasOldSourceCommand;
- }
- }
- return existsKind;
- }
- void DbgModule::EnableWriting(addr_target address)
- {
- for (int sectionIdx = 0; sectionIdx < (int)mSections.size(); sectionIdx++)
- {
- DbgSection* section = &mSections[sectionIdx];
- if ((address >= mImageBase + section->mAddrStart) && (address < mImageBase + section->mAddrStart + section->mAddrLength))
- {
- if (!section->mWritingEnabled)
- {
- section->mOldProt = mDebugger->EnableWriting(mImageBase + section->mAddrStart, (int32)section->mAddrLength);
- section->mWritingEnabled = true;
- }
- }
- }
- }
- void DbgModule::RevertWritingEnable()
- {
- for (int sectionIdx = 0; sectionIdx < (int)mSections.size(); sectionIdx++)
- {
- DbgSection* section = &mSections[sectionIdx];
- if (section->mWritingEnabled)
- {
- mDebugger->SetProtection(mImageBase + section->mAddrStart, (int32)section->mAddrLength, section->mOldProt);
- section->mWritingEnabled = false;
- }
- }
- }
- template <typename TRadixMap>
- static void RemoveInvalidRange(TRadixMap& radixMap, addr_target startAddr, int addrLength)
- {
- radixMap.RemoveRange(startAddr, addrLength);
- }
- template <typename TMap>
- static void RemoveInvalidMapRange(TMap& map, addr_target startAddr, int addrLength)
- {
- auto itr = map.lower_bound(startAddr);
- while (itr != map.end())
- {
- auto val = itr->first;
- if (val >= startAddr + addrLength)
- return;
- itr = map.erase(itr);
- }
- }
- void DbgModule::RemoveTargetData()
- {
- BP_ZONE("DbgModule::RemoveTargetData");
- for (auto srcFileRef : mSrcFileDeferredRefs)
- srcFileRef->RemoveDeferredRefs(this);
- HashSet<DbgSrcFile*> visitedFiles;
- for (auto compileUnit : mCompileUnits)
- {
- for (auto& fileRef : compileUnit->mSrcFileRefs)
- {
- if (visitedFiles.Add(fileRef.mSrcFile))
- {
- fileRef.mSrcFile->RemoveLines(this);
- }
- }
- }
- RemoveInvalidRange(mDebugTarget->mSymbolMap, (addr_target)mImageBase, (int32)mImageSize);
- RemoveInvalidRange(mDebugTarget->mSubprogramMap, (addr_target)mImageBase, (int32)mImageSize);
- RemoveInvalidRange(mDebugTarget->mExceptionDirectoryMap, (addr_target)mImageBase, (int32)mImageSize);
- RemoveInvalidRange(mDebugTarget->mContribMap, (addr_target)mImageBase, (int32)mImageSize);
- RemoveInvalidMapRange(mDebugTarget->mDwFrameDescriptorMap, (addr_target)mImageBase, (int32)mImageSize);
- RemoveInvalidMapRange(mDebugTarget->mCOFFFrameDescriptorMap, (addr_target)mImageBase, (int32)mImageSize);
- //mDebugTarget->mDwFrameDescriptorMap.erase()
- // Remove any of our entries from the mHotReplacedMethodList from 'primary modules' that are not going away
- for (auto dbgType : mHotPrimaryTypes)
- {
- DbgSubprogram** nextSrc = &dbgType->mHotReplacedMethodList.mHead;
- while (*nextSrc != NULL)
- {
- auto* subprogram = *nextSrc;
- if (subprogram->mCompileUnit->mDbgModule == this)
- *nextSrc = subprogram->mNext;
- else
- nextSrc = &(*nextSrc)->mNext;;
- }
- }
- }
- void DbgModule::ReportMemory(MemReporter* memReporter)
- {
- //memReporter->Add("BumpAlloc_Used", mAlloc.GetAllocSize());
- //memReporter->Add("BumpAlloc_Unused", mAlloc.GetTotalAllocSize() - mAlloc.GetAllocSize());
- memReporter->AddBumpAlloc("BumpAlloc", mAlloc);
- memReporter->AddVec(mTypes);
- memReporter->AddVec(mSubprograms);
- //memReporter->Add("TypeMap", mTypeMap.mAlloc.GetTotalAllocSize() + sizeof(StrHashMap<DbgType*>));
- memReporter->AddHashSet("TypeMap", mTypeMap.mMap);
- memReporter->Add("SymbolNameMap", mSymbolNameMap.mAlloc.GetTotalAllocSize() + sizeof(StrHashMap<DbgType*>));
- if (mOrigImageData != NULL)
- {
- memReporter->BeginSection("OrigImageData");
- mOrigImageData->ReportMemory(memReporter);
- memReporter->EndSection();
- }
- }
- DbgType* DbgModule::GetPointerType(DbgType* innerType)
- {
- auto linkedModule = GetLinkedModule();
- BF_ASSERT(innerType->GetDbgModule()->GetLinkedModule() == linkedModule);
- if (innerType->mPtrType == NULL)
- {
- BP_ALLOC_T(DbgType);
- auto ptrType = mAlloc.Alloc<DbgType>();
- ptrType->mCompileUnit = innerType->mCompileUnit;
- ptrType->mLanguage = innerType->mLanguage;
- ptrType->mTypeCode = DbgType_Ptr;
- ptrType->mTypeParam = innerType;
- ptrType->mSize = sizeof(addr_target);
- ptrType->mAlign = (int)ptrType->mSize;
- ptrType->mTypeIdx = (int32)linkedModule->mTypes.size();
- linkedModule->mTypes.push_back(ptrType);
- innerType->mPtrType = ptrType;
- }
- return innerType->mPtrType;
- }
- DbgType* DbgModule::GetConstType(DbgType* innerType)
- {
- auto linkedModule = GetLinkedModule();
- BF_ASSERT(innerType->GetDbgModule()->GetLinkedModule() == linkedModule);
-
- /*auto itr = linkedModule->mConstTypes.find(innerType);
- if (itr != linkedModule->mConstTypes.end())
- return itr->second;*/
- DbgType* constType = NULL;
- if (linkedModule->mConstTypes.TryGetValue(innerType, &constType))
- return constType;
- BP_ALLOC_T(DbgType);
- constType = mAlloc.Alloc<DbgType>();
- constType->mCompileUnit = innerType->mCompileUnit;
- constType->mLanguage = innerType->mLanguage;
- constType->mTypeCode = DbgType_Const;
- constType->mTypeParam = innerType;
- constType->mSize = sizeof(addr_target);
- constType->mTypeIdx = (int32)linkedModule->mTypes.size();
- linkedModule->mTypes.push_back(constType);
- linkedModule->mConstTypes[innerType] = constType;
- return constType;
- }
- DbgType* DbgModule::GetPrimaryType(DbgType* dbgType)
- {
- if (dbgType->mPriority <= DbgTypePriority_Normal)
- {
- if ((dbgType->mLanguage == DbgLanguage_Beef) && (dbgType->mName != NULL))
- {
- auto newTypeEntry = FindType(dbgType->mName, dbgType->mLanguage);
- if (newTypeEntry != NULL)
- {
- DbgType* newType = newTypeEntry->mValue;
- if ((newType->mTypeCode == DbgType_Ptr) && (newType->IsBfObjectPtr()))
- newType = newType->mTypeParam;
- newType->mPriority = DbgTypePriority_Primary_Implicit;
- return newType;
- }
- }
- else if (dbgType->mName != NULL)
- {
- auto newTypeEntry = FindType(dbgType->mName, dbgType->mLanguage);
- if (newTypeEntry != NULL)
- {
- DbgType* newType = newTypeEntry->mValue;
- newType = newType->RemoveModifiers();
- if (newType != dbgType)
- newType = GetPrimaryType(newType);
- newType->mPriority = DbgTypePriority_Primary_Implicit;
- return newType;
- }
- }
- }
- return dbgType;
- }
- DbgType* DbgModule::GetInnerTypeOrVoid(DbgType* dbgType)
- {
- if (dbgType->mTypeParam != NULL)
- return dbgType->mTypeParam;
- return GetPrimitiveType(DbgType_Void, dbgType->mLanguage);
- }
- DbgType* DbgModule::FindTypeHelper(const String& typeName, DbgType* checkType)
- {
- for (auto subType : checkType->mSubTypeList)
- {
- if (strcmp(subType->mTypeName, typeName.c_str()) == 0)
- return subType;
- }
- for (auto baseType : checkType->mBaseTypes)
- {
- auto retType = FindTypeHelper(typeName, baseType->mBaseType);
- if (retType != NULL)
- return retType;
- }
- return NULL;
- }
- DbgType* DbgModule::FindType(const String& typeName, DbgType* contextType, DbgLanguage language, bool bfObjectPtr)
- {
- if ((language == DbgLanguage_Unknown) && (contextType != NULL))
- language = contextType->mLanguage;
- if (typeName.length() > 0)
- {
- if (typeName[typeName.length() - 1] == '*')
- {
- DbgType* dbgType = FindType(typeName.Substring(0, typeName.length() - 1), contextType, language, bfObjectPtr);
- if (dbgType == NULL)
- return NULL;
- return GetPointerType(dbgType);
- }
- }
- auto entry = GetLinkedModule()->mTypeMap.Find(typeName.c_str(), language);
- if (entry != NULL)
- {
- if ((bfObjectPtr) && (entry->mValue->IsBfObject()))
- return GetPointerType(entry->mValue);
- return entry->mValue;
- }
- if (contextType != NULL)
- {
- DbgType* checkType = contextType;
- if (checkType->IsPointer())
- checkType = checkType->mTypeParam;
- return FindTypeHelper(typeName, checkType);
- }
- return NULL;
- }
- DbgTypeMap::Entry* DbgModule::FindType(const char* typeName, DbgLanguage language)
- {
- return GetLinkedModule()->mTypeMap.Find(typeName, language);
- /*auto& typeMap = GetLinkedModule()->mTypeMap;
- auto dbgTypeEntry = typeMap.Find(typeName);
- if (dbgTypeEntry == NULL)
- return NULL;
- if (dbgTypeEntry->mValue->mLanguage == language)
- return dbgTypeEntry;
- while (dbgTypeEntry != NULL)
- {
- DbgType* dbgType = dbgTypeEntry->mValue;
- if ((dbgType->GetLanguage() == language) && (typeMap.StrEqual(dbgType->mName, typeName)))
- return dbgTypeEntry;
- dbgTypeEntry = dbgTypeEntry->mNext;
- }*/
- //return NULL;
- }
- DbgType* DbgModule::GetPrimitiveType(DbgTypeCode typeCode, DbgLanguage language)
- {
- if (language == DbgLanguage_Beef)
- return mBfPrimitiveTypes[(int)typeCode];
- else
- return mCPrimitiveTypes[(int)typeCode];
- }
- DbgType* DbgModule::GetPrimitiveStructType(DbgTypeCode typeCode)
- {
- const char* name = mPrimitiveStructNames[typeCode];
- if (name == NULL)
- return NULL;
- return FindType(name, NULL, DbgLanguage_Beef);
- }
- DbgType* DbgModule::GetSizedArrayType(DbgType * elementType, int count)
- {
- auto linkedModule = GetLinkedModule();
- if ((linkedModule != NULL) && (linkedModule != this))
- {
- return linkedModule->GetSizedArrayType(elementType, count);
- }
- DbgType** sizedArrayTypePtr;
- DbgSizedArrayEntry entry;
- entry.mElementType = elementType;
- entry.mCount = count;
- if (mSizedArrayTypes.TryAdd(entry, NULL, &sizedArrayTypePtr))
- {
- BP_ALLOC_T(DbgType);
- auto sizedArrayType = mAlloc.Alloc<DbgType>();
- sizedArrayType->mCompileUnit = elementType->mCompileUnit;
- sizedArrayType->mLanguage = elementType->mLanguage;
- sizedArrayType->mTypeCode = DbgType_SizedArray;
- sizedArrayType->mTypeParam = elementType;
- sizedArrayType->mSize = count * elementType->GetStride();
- sizedArrayType->mAlign = elementType->GetAlign();
- sizedArrayType->mSizeCalculated = true;
- sizedArrayType->mTypeIdx = (int32)mTypes.size();
- linkedModule->mTypes.push_back(sizedArrayType);
- *sizedArrayTypePtr = sizedArrayType;
- }
- return *sizedArrayTypePtr;
- }
|