lldb-wasm.patch 215 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867
  1. diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h
  2. index f2e2a0d22..426d1129b 100644
  3. --- a/lldb/include/lldb/Breakpoint/Breakpoint.h
  4. +++ b/lldb/include/lldb/Breakpoint/Breakpoint.h
  5. @@ -9,6 +9,7 @@
  6. #ifndef LLDB_BREAKPOINT_BREAKPOINT_H
  7. #define LLDB_BREAKPOINT_BREAKPOINT_H
  8. +#include <limits>
  9. #include <memory>
  10. #include <string>
  11. #include <unordered_set>
  12. diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
  13. index dd7100c46..97d70daad 100644
  14. --- a/lldb/include/lldb/Core/Module.h
  15. +++ b/lldb/include/lldb/Core/Module.h
  16. @@ -41,6 +41,7 @@
  17. namespace lldb_private {
  18. class CompilerDeclContext;
  19. +class DWARFEvaluatorFactory;
  20. class Function;
  21. class Log;
  22. class ObjectFile;
  23. @@ -859,6 +860,8 @@ public:
  24. /// Update the ArchSpec to a more specific variant.
  25. bool MergeArchitecture(const ArchSpec &arch_spec);
  26. + DWARFEvaluatorFactory *GetDWARFExpressionEvaluatorFactory();
  27. +
  28. /// \class LookupInfo Module.h "lldb/Core/Module.h"
  29. /// A class that encapsulates name lookup information.
  30. ///
  31. @@ -985,6 +988,8 @@ protected:
  32. m_first_file_changed_log : 1; /// See if the module was modified after it
  33. /// was initially opened.
  34. + std::unique_ptr<DWARFEvaluatorFactory> m_dwarf_evaluator_factory;
  35. +
  36. /// Resolve a file or load virtual address.
  37. ///
  38. /// Tries to resolve \a vm_addr as a file address (if \a
  39. diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h
  40. index be91929c6..8d876fc1f 100644
  41. --- a/lldb/include/lldb/Core/PluginManager.h
  42. +++ b/lldb/include/lldb/Core/PluginManager.h
  43. @@ -508,6 +508,17 @@ public:
  44. static bool CreateSettingForStructuredDataPlugin(
  45. Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
  46. ConstString description, bool is_global_property);
  47. +
  48. + // DWARFEvaluatorFactory
  49. + static bool
  50. + RegisterPlugin(ConstString name, const char *description,
  51. + DWARFEvaluatorFactoryCreateInstance create_callback);
  52. +
  53. + static bool
  54. + UnregisterPlugin(DWARFEvaluatorFactoryCreateInstance create_callback);
  55. +
  56. + static DWARFEvaluatorFactoryCreateInstance
  57. + GetDWARFEvaluatorFactoryCreateCallbackAtIndex(uint32_t idx);
  58. };
  59. } // namespace lldb_private
  60. diff --git a/lldb/include/lldb/Expression/DWARFEvaluator.h b/lldb/include/lldb/Expression/DWARFEvaluator.h
  61. new file mode 100644
  62. index 000000000..6811cbeae
  63. --- /dev/null
  64. +++ b/lldb/include/lldb/Expression/DWARFEvaluator.h
  65. @@ -0,0 +1,110 @@
  66. +//===-- DWARFEvaluator.h ----------------------------------------*- C++ -*-===//
  67. +//
  68. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  69. +// See https://llvm.org/LICENSE.txt for license information.
  70. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  71. +//
  72. +//===----------------------------------------------------------------------===//
  73. +
  74. +#ifndef LLDB_EXPRESSION_DWARFEVALUATOR_H
  75. +#define LLDB_EXPRESSION_DWARFEVALUATOR_H
  76. +
  77. +#include "lldb/lldb-private.h"
  78. +#include <vector>
  79. +
  80. +namespace lldb_private {
  81. +
  82. +class DWARFExpression;
  83. +
  84. +/// \class DWARFEvaluator DWARFEvaluator.h
  85. +/// "lldb/Expression/DWARFEvaluator.h" Evaluates DWARF opcodes.
  86. +///
  87. +class DWARFEvaluator {
  88. +public:
  89. + /// Crates a DWARF location expression evaluator
  90. + ///
  91. + /// \param[in] dwarf_expression
  92. + /// The DWARF expression to evaluate.
  93. + ///
  94. + /// \param[in] exe_ctx
  95. + /// The execution context in which to evaluate the location
  96. + /// expression. The location expression may access the target's
  97. + /// memory, especially if it comes from the expression parser.
  98. + ///
  99. + /// \param[in] reg_ctx
  100. + /// An optional parameter which provides a RegisterContext for use
  101. + /// when evaluating the expression (i.e. for fetching register values).
  102. + /// Normally this will come from the ExecutionContext's StackFrame but
  103. + /// in the case where an expression needs to be evaluated while building
  104. + /// the stack frame list, this short-cut is available.
  105. + ///
  106. + /// \param[in] initial_value_ptr
  107. + /// A value to put on top of the interpreter stack before evaluating
  108. + /// the expression, if the expression is parametrized. Can be NULL.
  109. + ///
  110. + /// \param[in] object_address_ptr
  111. + ///
  112. + DWARFEvaluator(const DWARFExpression &dwarf_expression,
  113. + ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
  114. + const Value *initial_value_ptr,
  115. + const Value *object_address_ptr);
  116. +
  117. + /// DWARFEvaluator protocol.
  118. + /// \{
  119. +
  120. + /// Evaluate the DWARF location expression
  121. + ///
  122. + /// \param[in] result
  123. + /// A value into which the result of evaluating the expression is
  124. + /// to be placed.
  125. + ///
  126. + /// \param[in] error_ptr
  127. + /// If non-NULL, used to report errors in expression evaluation.
  128. + ///
  129. + /// \return
  130. + /// True on success; false otherwise. If error_ptr is non-NULL,
  131. + /// details of the failure are provided through it.
  132. + virtual bool Evaluate(Value &result, Status *error_ptr);
  133. +
  134. + /// Evaluate the DWARF location expression with the opcodes specified.
  135. + ///
  136. + /// \param[in] opcodes
  137. + /// The DWARF opcodes to evaluate.
  138. + ///
  139. + /// \param[in] result
  140. + /// A value into which the result of evaluating the expression is
  141. + /// to be placed.
  142. + ///
  143. + /// \param[in] error_ptr
  144. + /// If non-NULL, used to report errors in expression evaluation.
  145. + ///
  146. + /// \return
  147. + /// True on success; false otherwise. If error_ptr is non-NULL,
  148. + /// details of the failure are provided through it.
  149. + virtual bool Evaluate(const DataExtractor &opcodes, Value &result,
  150. + Status *error_ptr);
  151. +
  152. + /// Evaluates a specific DWARF opcode in the context of a DWARF expression
  153. + virtual bool Evaluate(const uint8_t op, Process *process, StackFrame *frame,
  154. + std::vector<Value> &stack, const DataExtractor &opcodes,
  155. + lldb::offset_t &offset, Value &pieces,
  156. + uint64_t &op_piece_offset, Log *log, Status *error_ptr);
  157. +
  158. + /// \}
  159. +
  160. +protected:
  161. + const DWARFExpression &m_dwarf_expression;
  162. + ExecutionContext *m_exe_ctx;
  163. + RegisterContext *m_reg_ctx;
  164. + const Value *m_initial_value_ptr;
  165. + const Value *m_object_address_ptr;
  166. +
  167. +private:
  168. + DWARFEvaluator(const DWARFEvaluator &);
  169. + const DWARFEvaluator &operator=(const DWARFEvaluator &) = delete;
  170. +
  171. +};
  172. +
  173. +} // namespace lldb_private
  174. +
  175. +#endif // LLDB_EXPRESSION_DWARFEVALUATOR_H
  176. diff --git a/lldb/include/lldb/Expression/DWARFEvaluatorFactory.h b/lldb/include/lldb/Expression/DWARFEvaluatorFactory.h
  177. new file mode 100644
  178. index 000000000..f3b496c58
  179. --- /dev/null
  180. +++ b/lldb/include/lldb/Expression/DWARFEvaluatorFactory.h
  181. @@ -0,0 +1,56 @@
  182. +//===-- DWARFEvaluatorFactory.h ---------------------------------*- C++ -*-===//
  183. +//
  184. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  185. +// See https://llvm.org/LICENSE.txt for license information.
  186. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  187. +//
  188. +//===----------------------------------------------------------------------===//
  189. +
  190. +#ifndef LLDB_EXPRESSION_DWARFEVALUATORFACTORY_H
  191. +#define LLDB_EXPRESSION_DWARFEVALUATORFACTORY_H
  192. +
  193. +#include "lldb/Core/PluginInterface.h"
  194. +#include "lldb/Utility/ConstString.h"
  195. +#include "lldb/lldb-private.h"
  196. +
  197. +class DWARFUnit;
  198. +
  199. +namespace lldb_private {
  200. +
  201. +class DWARFEvaluator;
  202. +class DWARFExpression;
  203. +
  204. +/// \class DWARFEvaluatorFactory DWARFEvaluatorFactory.h
  205. +/// "lldb/Expression/DWARFEvaluatorFactory.h" Factory class that allows the
  206. +/// registration of platform-specific DWARF expression evaluators, used to
  207. +/// handle platform-specific DWARF opcodes.
  208. +class DWARFEvaluatorFactory : public PluginInterface {
  209. +public:
  210. + static std::unique_ptr<DWARFEvaluatorFactory> FindPlugin(Module *module);
  211. +
  212. + /// PluginInterface protocol.
  213. + /// \{
  214. + ConstString GetPluginName() override;
  215. +
  216. + uint32_t GetPluginVersion() override { return 1; }
  217. + /// \}
  218. +
  219. + DWARFEvaluatorFactory() {}
  220. +
  221. + /// DWARFEvaluatorFactory protocol.
  222. + /// \{
  223. + virtual std::unique_ptr<DWARFEvaluator>
  224. + CreateDWARFEvaluator(const DWARFExpression &dwarf_expression,
  225. + ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
  226. + const Value *initial_value_ptr,
  227. + const Value *object_address_ptr);
  228. + /// \}
  229. +
  230. +private:
  231. + DWARFEvaluatorFactory(const DWARFEvaluatorFactory &);
  232. + const DWARFEvaluatorFactory &operator=(const DWARFEvaluatorFactory &) = delete;
  233. +};
  234. +
  235. +} // namespace lldb_private
  236. +
  237. +#endif // LLDB_EXPRESSION_DWARFEVALUATORFACTORY_H
  238. diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
  239. index 1490ac2d6..35c741d4e 100644
  240. --- a/lldb/include/lldb/Expression/DWARFExpression.h
  241. +++ b/lldb/include/lldb/Expression/DWARFExpression.h
  242. @@ -120,6 +120,10 @@ public:
  243. void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }
  244. + lldb::ModuleSP GetModule() const { return m_module_wp.lock(); }
  245. +
  246. + const DWARFUnit *GetDWARFCompileUnit() const { return m_dwarf_cu; }
  247. +
  248. bool ContainsThreadLocalStorage() const;
  249. bool LinkThreadLocalStorage(
  250. @@ -140,7 +144,7 @@ public:
  251. lldb::addr_t func_file_addr);
  252. /// Return the call-frame-info style register kind
  253. - int GetRegisterKind();
  254. + lldb::RegisterKind GetRegisterKind() const;
  255. /// Set the call-frame-info style register kind
  256. ///
  257. @@ -219,6 +223,9 @@ public:
  258. bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
  259. + static lldb::addr_t ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu,
  260. + uint32_t index);
  261. +
  262. llvm::Optional<DataExtractor>
  263. GetLocationExpression(lldb::addr_t load_function_start,
  264. lldb::addr_t addr) const;
  265. diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
  266. index aaa2470d2..c15f2db52 100644
  267. --- a/lldb/include/lldb/Target/Process.h
  268. +++ b/lldb/include/lldb/Target/Process.h
  269. @@ -1434,7 +1434,7 @@ public:
  270. /// vm_addr, \a buf, and \a size updated appropriately. Zero is
  271. /// returned in the case of an error.
  272. virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
  273. - Status &error);
  274. + Status &error, ExecutionContext *exe_ctx = nullptr);
  275. /// Read of memory from a process.
  276. ///
  277. diff --git a/lldb/include/lldb/Target/ProcessTrace.h b/lldb/include/lldb/Target/ProcessTrace.h
  278. index 7b9d6b13d..9525fc975 100644
  279. --- a/lldb/include/lldb/Target/ProcessTrace.h
  280. +++ b/lldb/include/lldb/Target/ProcessTrace.h
  281. @@ -59,7 +59,7 @@ public:
  282. bool WarnBeforeDetach() const override { return false; }
  283. size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
  284. - Status &error) override;
  285. + Status &error, ExecutionContext *exe_ctx = nullptr) override;
  286. size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
  287. Status &error) override;
  288. diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
  289. index ad5298151..5a3c0b27a 100644
  290. --- a/lldb/include/lldb/lldb-forward.h
  291. +++ b/lldb/include/lldb/lldb-forward.h
  292. @@ -74,6 +74,7 @@ class Disassembler;
  293. class DumpValueObjectOptions;
  294. class DynamicCheckerFunctions;
  295. class DynamicLoader;
  296. +class DWARFEvaluatorFactory;
  297. class Editline;
  298. class EmulateInstruction;
  299. class Environment;
  300. diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h
  301. index 2ed083ec8..f4d500d19 100644
  302. --- a/lldb/include/lldb/lldb-private-interfaces.h
  303. +++ b/lldb/include/lldb/lldb-private-interfaces.h
  304. @@ -113,6 +113,8 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error,
  305. const char *repl_options);
  306. typedef int (*ComparisonFunction)(const void *, const void *);
  307. typedef void (*DebuggerInitializeCallback)(Debugger &debugger);
  308. +typedef DWARFEvaluatorFactory *(*DWARFEvaluatorFactoryCreateInstance)(
  309. + Module *module);
  310. /// Trace
  311. /// \{
  312. typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceForSessionFile)(
  313. diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
  314. index 19c97be15..1647f93ec 100644
  315. --- a/lldb/source/Core/Module.cpp
  316. +++ b/lldb/source/Core/Module.cpp
  317. @@ -16,6 +16,7 @@
  318. #include "lldb/Core/ModuleSpec.h"
  319. #include "lldb/Core/SearchFilter.h"
  320. #include "lldb/Core/Section.h"
  321. +#include "lldb/Expression/DWARFEvaluatorFactory.h"
  322. #include "lldb/Host/FileSystem.h"
  323. #include "lldb/Host/Host.h"
  324. #include "lldb/Host/HostInfo.h"
  325. @@ -1659,3 +1660,9 @@ bool Module::GetIsDynamicLinkEditor() {
  326. return false;
  327. }
  328. +
  329. +DWARFEvaluatorFactory *Module::GetDWARFExpressionEvaluatorFactory() {
  330. + if (!m_dwarf_evaluator_factory)
  331. + m_dwarf_evaluator_factory = DWARFEvaluatorFactory::FindPlugin(this);
  332. + return m_dwarf_evaluator_factory.get();
  333. +}
  334. diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
  335. index fcaa868b0..59a404d4a 100644
  336. --- a/lldb/source/Core/PluginManager.cpp
  337. +++ b/lldb/source/Core/PluginManager.cpp
  338. @@ -1597,3 +1597,32 @@ bool PluginManager::CreateSettingForStructuredDataPlugin(
  339. ConstString("Settings for structured data plug-ins"), properties_sp,
  340. description, is_global_property);
  341. }
  342. +
  343. +#pragma mark DWARFEvaluator
  344. +
  345. +typedef PluginInstance<DWARFEvaluatorFactoryCreateInstance>
  346. + DWARFEvaluatorFactoryInstance;
  347. +typedef PluginInstances<DWARFEvaluatorFactoryInstance>
  348. + DWARFEvaluatorFactoryInstances;
  349. +
  350. +static DWARFEvaluatorFactoryInstances &GetDWARFEvaluatorFactoryInstances() {
  351. + static DWARFEvaluatorFactoryInstances g_instances;
  352. + return g_instances;
  353. +}
  354. +
  355. +bool PluginManager::RegisterPlugin(
  356. + ConstString name, const char *description,
  357. + DWARFEvaluatorFactoryCreateInstance create_callback) {
  358. + return GetDWARFEvaluatorFactoryInstances().RegisterPlugin(name, description,
  359. + create_callback);
  360. +}
  361. +
  362. +bool PluginManager::UnregisterPlugin(
  363. + DWARFEvaluatorFactoryCreateInstance create_callback) {
  364. + return GetDWARFEvaluatorFactoryInstances().UnregisterPlugin(create_callback);
  365. +}
  366. +
  367. +DWARFEvaluatorFactoryCreateInstance
  368. +PluginManager::GetDWARFEvaluatorFactoryCreateCallbackAtIndex(uint32_t idx) {
  369. + return GetDWARFEvaluatorFactoryInstances().GetCallbackAtIndex(idx);
  370. +}
  371. diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp
  372. index fb57c0fed..f92d6a54d 100644
  373. --- a/lldb/source/Core/Value.cpp
  374. +++ b/lldb/source/Core/Value.cpp
  375. @@ -538,7 +538,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
  376. if (process) {
  377. const size_t bytes_read =
  378. - process->ReadMemory(address, dst, byte_size, error);
  379. + process->ReadMemory(address, dst, byte_size, error, exe_ctx);
  380. if (bytes_read != byte_size)
  381. error.SetErrorStringWithFormat(
  382. "read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
  383. diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
  384. index 9c1ba99da..b15b214b2 100644
  385. --- a/lldb/source/Core/ValueObject.cpp
  386. +++ b/lldb/source/Core/ValueObject.cpp
  387. @@ -735,7 +735,7 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
  388. if (process) {
  389. heap_buf_ptr->SetByteSize(bytes);
  390. size_t bytes_read = process->ReadMemory(
  391. - addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
  392. + addr + offset, heap_buf_ptr->GetBytes(), bytes, error, &exe_ctx);
  393. if (error.Success() || bytes_read > 0) {
  394. data.SetData(data_sp);
  395. return bytes_read;
  396. diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt
  397. index bf94361dd..4e76d547a 100644
  398. --- a/lldb/source/Expression/CMakeLists.txt
  399. +++ b/lldb/source/Expression/CMakeLists.txt
  400. @@ -1,5 +1,7 @@
  401. add_lldb_library(lldbExpression
  402. DiagnosticManager.cpp
  403. + DWARFEvaluator.cpp
  404. + DWARFEvaluatorFactory.cpp
  405. DWARFExpression.cpp
  406. Expression.cpp
  407. ExpressionVariable.cpp
  408. diff --git a/lldb/source/Expression/DWARFEvaluator.cpp b/lldb/source/Expression/DWARFEvaluator.cpp
  409. new file mode 100644
  410. index 000000000..06107e136
  411. --- /dev/null
  412. +++ b/lldb/source/Expression/DWARFEvaluator.cpp
  413. @@ -0,0 +1,1952 @@
  414. +//===-- DWARFEvaluator.cpp ------------ -----------------------------------===//
  415. +//
  416. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  417. +// See https://llvm.org/LICENSE.txt for license information.
  418. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  419. +//
  420. +//===----------------------------------------------------------------------===//
  421. +
  422. +#include "lldb/Expression/DWARFEvaluator.h"
  423. +#include "lldb/Expression/DWARFExpression.h"
  424. +
  425. +#include "lldb/Core/Module.h"
  426. +#include "lldb/Core/Value.h"
  427. +#include "lldb/Core/dwarf.h"
  428. +
  429. +#include "lldb/Utility/Log.h"
  430. +#include "lldb/Utility/RegisterValue.h"
  431. +
  432. +#include "lldb/Target/Process.h"
  433. +#include "lldb/Target/RegisterContext.h"
  434. +#include "lldb/Target/StackFrame.h"
  435. +
  436. +#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
  437. +
  438. +using namespace lldb;
  439. +using namespace lldb_private;
  440. +
  441. +DWARFEvaluator::DWARFEvaluator(const DWARFExpression &dwarf_expression,
  442. + ExecutionContext *exe_ctx,
  443. + RegisterContext *reg_ctx,
  444. + const Value *initial_value_ptr,
  445. + const Value *object_address_ptr)
  446. + : m_dwarf_expression(dwarf_expression), m_exe_ctx(exe_ctx),
  447. + m_reg_ctx(reg_ctx), m_initial_value_ptr(initial_value_ptr),
  448. + m_object_address_ptr(object_address_ptr) {}
  449. +
  450. +static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
  451. + lldb::RegisterKind reg_kind,
  452. + uint32_t reg_num, Status *error_ptr,
  453. + Value &value) {
  454. + if (reg_ctx == nullptr) {
  455. + if (error_ptr)
  456. + error_ptr->SetErrorStringWithFormat("No register context in frame.\n");
  457. + } else {
  458. + uint32_t native_reg =
  459. + reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
  460. + if (native_reg == LLDB_INVALID_REGNUM) {
  461. + if (error_ptr)
  462. + error_ptr->SetErrorStringWithFormat("Unable to convert register "
  463. + "kind=%u reg_num=%u to a native "
  464. + "register number.\n",
  465. + reg_kind, reg_num);
  466. + } else {
  467. + const RegisterInfo *reg_info =
  468. + reg_ctx->GetRegisterInfoAtIndex(native_reg);
  469. + RegisterValue reg_value;
  470. + if (reg_ctx->ReadRegister(reg_info, reg_value)) {
  471. + if (reg_value.GetScalarValue(value.GetScalar())) {
  472. + value.SetValueType(Value::ValueType::Scalar);
  473. + value.SetContext(Value::ContextType::RegisterInfo,
  474. + const_cast<RegisterInfo *>(reg_info));
  475. + if (error_ptr)
  476. + error_ptr->Clear();
  477. + return true;
  478. + } else {
  479. + // If we get this error, then we need to implement a value buffer in
  480. + // the dwarf expression evaluation function...
  481. + if (error_ptr)
  482. + error_ptr->SetErrorStringWithFormat(
  483. + "register %s can't be converted to a scalar value",
  484. + reg_info->name);
  485. + }
  486. + } else {
  487. + if (error_ptr)
  488. + error_ptr->SetErrorStringWithFormat("register %s is not available",
  489. + reg_info->name);
  490. + }
  491. + }
  492. + }
  493. + return false;
  494. +}
  495. +
  496. +static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
  497. + ExecutionContext *exe_ctx,
  498. + RegisterContext *reg_ctx,
  499. + const DataExtractor &opcodes,
  500. + lldb::offset_t &opcode_offset,
  501. + Status *error_ptr, Log *log) {
  502. + // DW_OP_entry_value(sub-expr) describes the location a variable had upon
  503. + // function entry: this variable location is presumed to be optimized out at
  504. + // the current PC value. The caller of the function may have call site
  505. + // information that describes an alternate location for the variable (e.g. a
  506. + // constant literal, or a spilled stack value) in the parent frame.
  507. + //
  508. + // Example (this is pseudo-code & pseudo-DWARF, but hopefully illustrative):
  509. + //
  510. + // void child(int &sink, int x) {
  511. + // ...
  512. + // /* "x" gets optimized out. */
  513. + //
  514. + // /* The location of "x" here is: DW_OP_entry_value($reg2). */
  515. + // ++sink;
  516. + // }
  517. + //
  518. + // void parent() {
  519. + // int sink;
  520. + //
  521. + // /*
  522. + // * The callsite information emitted here is:
  523. + // *
  524. + // * DW_TAG_call_site
  525. + // * DW_AT_return_pc ... (for "child(sink, 123);")
  526. + // * DW_TAG_call_site_parameter (for "sink")
  527. + // * DW_AT_location ($reg1)
  528. + // * DW_AT_call_value ($SP - 8)
  529. + // * DW_TAG_call_site_parameter (for "x")
  530. + // * DW_AT_location ($reg2)
  531. + // * DW_AT_call_value ($literal 123)
  532. + // *
  533. + // * DW_TAG_call_site
  534. + // * DW_AT_return_pc ... (for "child(sink, 456);")
  535. + // * ...
  536. + // */
  537. + // child(sink, 123);
  538. + // child(sink, 456);
  539. + // }
  540. + //
  541. + // When the program stops at "++sink" within `child`, the debugger determines
  542. + // the call site by analyzing the return address. Once the call site is found,
  543. + // the debugger determines which parameter is referenced by DW_OP_entry_value
  544. + // and evaluates the corresponding location for that parameter in `parent`.
  545. +
  546. + // 1. Find the function which pushed the current frame onto the stack.
  547. + if ((!exe_ctx || !exe_ctx->HasTargetScope()) || !reg_ctx) {
  548. + LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no exe/reg context");
  549. + return false;
  550. + }
  551. +
  552. + StackFrame *current_frame = exe_ctx->GetFramePtr();
  553. + Thread *thread = exe_ctx->GetThreadPtr();
  554. + if (!current_frame || !thread) {
  555. + LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no current frame/thread");
  556. + return false;
  557. + }
  558. +
  559. + Target &target = exe_ctx->GetTargetRef();
  560. + StackFrameSP parent_frame = nullptr;
  561. + addr_t return_pc = LLDB_INVALID_ADDRESS;
  562. + uint32_t current_frame_idx = current_frame->GetFrameIndex();
  563. + uint32_t num_frames = thread->GetStackFrameCount();
  564. + for (uint32_t parent_frame_idx = current_frame_idx + 1;
  565. + parent_frame_idx < num_frames; ++parent_frame_idx) {
  566. + parent_frame = thread->GetStackFrameAtIndex(parent_frame_idx);
  567. + // Require a valid sequence of frames.
  568. + if (!parent_frame)
  569. + break;
  570. +
  571. + // Record the first valid return address, even if this is an inlined frame,
  572. + // in order to look up the associated call edge in the first non-inlined
  573. + // parent frame.
  574. + if (return_pc == LLDB_INVALID_ADDRESS) {
  575. + return_pc = parent_frame->GetFrameCodeAddress().GetLoadAddress(&target);
  576. + LLDB_LOG(log,
  577. + "Evaluate_DW_OP_entry_value: immediate ancestor with pc = {0:x}",
  578. + return_pc);
  579. + }
  580. +
  581. + // If we've found an inlined frame, skip it (these have no call site
  582. + // parameters).
  583. + if (parent_frame->IsInlined())
  584. + continue;
  585. +
  586. + // We've found the first non-inlined parent frame.
  587. + break;
  588. + }
  589. + if (!parent_frame || !parent_frame->GetRegisterContext()) {
  590. + LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no parent frame with reg ctx");
  591. + return false;
  592. + }
  593. +
  594. + Function *parent_func =
  595. + parent_frame->GetSymbolContext(eSymbolContextFunction).function;
  596. + if (!parent_func) {
  597. + LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no parent function");
  598. + return false;
  599. + }
  600. +
  601. + // 2. Find the call edge in the parent function responsible for creating the
  602. + // current activation.
  603. + Function *current_func =
  604. + current_frame->GetSymbolContext(eSymbolContextFunction).function;
  605. + if (!current_func) {
  606. + LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no current function");
  607. + return false;
  608. + }
  609. +
  610. + CallEdge *call_edge = nullptr;
  611. + ModuleList &modlist = target.GetImages();
  612. + ExecutionContext parent_exe_ctx = *exe_ctx;
  613. + parent_exe_ctx.SetFrameSP(parent_frame);
  614. + if (!parent_frame->IsArtificial()) {
  615. + // If the parent frame is not artificial, the current activation may be
  616. + // produced by an ambiguous tail call. In this case, refuse to proceed.
  617. + call_edge = parent_func->GetCallEdgeForReturnAddress(return_pc, target);
  618. + if (!call_edge) {
  619. + LLDB_LOG(log,
  620. + "Evaluate_DW_OP_entry_value: no call edge for retn-pc = {0:x} "
  621. + "in parent frame {1}",
  622. + return_pc, parent_func->GetName());
  623. + return false;
  624. + }
  625. + Function *callee_func = call_edge->GetCallee(modlist, parent_exe_ctx);
  626. + if (callee_func != current_func) {
  627. + LLDB_LOG(log, "Evaluate_DW_OP_entry_value: ambiguous call sequence, "
  628. + "can't find real parent frame");
  629. + return false;
  630. + }
  631. + } else {
  632. + // The StackFrameList solver machinery has deduced that an unambiguous tail
  633. + // call sequence that produced the current activation. The first edge in
  634. + // the parent that points to the current function must be valid.
  635. + for (auto &edge : parent_func->GetTailCallingEdges()) {
  636. + if (edge->GetCallee(modlist, parent_exe_ctx) == current_func) {
  637. + call_edge = edge.get();
  638. + break;
  639. + }
  640. + }
  641. + }
  642. + if (!call_edge) {
  643. + LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no unambiguous edge from parent "
  644. + "to current function");
  645. + return false;
  646. + }
  647. +
  648. + // 3. Attempt to locate the DW_OP_entry_value expression in the set of
  649. + // available call site parameters. If found, evaluate the corresponding
  650. + // parameter in the context of the parent frame.
  651. + const uint32_t subexpr_len = opcodes.GetULEB128(&opcode_offset);
  652. + const void *subexpr_data = opcodes.GetData(&opcode_offset, subexpr_len);
  653. + if (!subexpr_data) {
  654. + LLDB_LOG(log, "Evaluate_DW_OP_entry_value: subexpr could not be read");
  655. + return false;
  656. + }
  657. +
  658. + const CallSiteParameter *matched_param = nullptr;
  659. + for (const CallSiteParameter &param : call_edge->GetCallSiteParameters()) {
  660. + DataExtractor param_subexpr_extractor;
  661. + if (!param.LocationInCallee.GetExpressionData(param_subexpr_extractor))
  662. + continue;
  663. + lldb::offset_t param_subexpr_offset = 0;
  664. + const void *param_subexpr_data =
  665. + param_subexpr_extractor.GetData(&param_subexpr_offset, subexpr_len);
  666. + if (!param_subexpr_data ||
  667. + param_subexpr_extractor.BytesLeft(param_subexpr_offset) != 0)
  668. + continue;
  669. +
  670. + // At this point, the DW_OP_entry_value sub-expression and the callee-side
  671. + // expression in the call site parameter are known to have the same length.
  672. + // Check whether they are equal.
  673. + //
  674. + // Note that an equality check is sufficient: the contents of the
  675. + // DW_OP_entry_value subexpression are only used to identify the right call
  676. + // site parameter in the parent, and do not require any special handling.
  677. + if (memcmp(subexpr_data, param_subexpr_data, subexpr_len) == 0) {
  678. + matched_param = &param;
  679. + break;
  680. + }
  681. + }
  682. + if (!matched_param) {
  683. + LLDB_LOG(log,
  684. + "Evaluate_DW_OP_entry_value: no matching call site param found");
  685. + return false;
  686. + }
  687. +
  688. + // TODO: Add support for DW_OP_push_object_address within a DW_OP_entry_value
  689. + // subexpresion whenever llvm does.
  690. + Value result;
  691. + const DWARFExpression &param_expr = matched_param->LocationInCaller;
  692. + if (!param_expr.Evaluate(&parent_exe_ctx,
  693. + parent_frame->GetRegisterContext().get(),
  694. + /*loclist_base_addr=*/LLDB_INVALID_ADDRESS,
  695. + /*initial_value_ptr=*/nullptr,
  696. + /*object_address_ptr=*/nullptr, result, error_ptr)) {
  697. + LLDB_LOG(log,
  698. + "Evaluate_DW_OP_entry_value: call site param evaluation failed");
  699. + return false;
  700. + }
  701. +
  702. + stack.push_back(result);
  703. + return true;
  704. +}
  705. +
  706. +bool DWARFEvaluator::Evaluate(Value &result, Status *error_ptr) {
  707. + DataExtractor opcodes;
  708. + if (!m_dwarf_expression.GetExpressionData(opcodes)) {
  709. + if (error_ptr)
  710. + error_ptr->SetErrorString(
  711. + "no location, value may have been optimized out");
  712. + return false;
  713. + }
  714. + return Evaluate(opcodes, result, error_ptr);
  715. +}
  716. +
  717. +bool DWARFEvaluator::Evaluate(const DataExtractor &opcodes, Value &result,
  718. + Status *error_ptr) {
  719. + if (opcodes.GetByteSize() == 0) {
  720. + if (error_ptr)
  721. + error_ptr->SetErrorString(
  722. + "no location, value may have been optimized out");
  723. + return false;
  724. + }
  725. + std::vector<Value> stack;
  726. +
  727. + Process *process = nullptr;
  728. + StackFrame *frame = nullptr;
  729. +
  730. + if (m_exe_ctx) {
  731. + process = m_exe_ctx->GetProcessPtr();
  732. + frame = m_exe_ctx->GetFramePtr();
  733. + }
  734. + if (m_reg_ctx == nullptr && frame)
  735. + m_reg_ctx = frame->GetRegisterContext().get();
  736. +
  737. + if (m_initial_value_ptr)
  738. + stack.push_back(*m_initial_value_ptr);
  739. +
  740. + lldb::offset_t offset = 0;
  741. +
  742. + /// Insertion point for evaluating multi-piece expression.
  743. + uint64_t op_piece_offset = 0;
  744. + Value pieces; // Used for DW_OP_piece
  745. +
  746. + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
  747. +
  748. + uint8_t _opcode = 0;
  749. +
  750. + while (opcodes.ValidOffset(offset)) {
  751. + const lldb::offset_t op_offset = offset;
  752. + const uint8_t op = opcodes.GetU8(&offset);
  753. + _opcode = op;
  754. +
  755. + if (log && log->GetVerbose()) {
  756. + size_t count = stack.size();
  757. + LLDB_LOGF(log, "Stack before operation has %" PRIu64 " values:",
  758. + (uint64_t)count);
  759. + for (size_t i = 0; i < count; ++i) {
  760. + StreamString new_value;
  761. + new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
  762. + stack[i].Dump(&new_value);
  763. + LLDB_LOGF(log, " %s", new_value.GetData());
  764. + }
  765. + LLDB_LOGF(log, "0x%8.8" PRIx64 ": %s", op_offset,
  766. + DW_OP_value_to_name(op));
  767. + }
  768. +
  769. + if (!Evaluate(op, process, frame, stack, opcodes, offset, pieces,
  770. + op_piece_offset, log, error_ptr))
  771. + return false;
  772. + }
  773. +
  774. + if (stack.empty()) {
  775. + // Nothing on the stack, check if we created a piece value from DW_OP_piece
  776. + // or DW_OP_bit_piece opcodes
  777. + if (pieces.GetBuffer().GetByteSize())
  778. + result = pieces;
  779. + else {
  780. + if (error_ptr)
  781. + error_ptr->SetErrorString("Stack empty after evaluation.");
  782. + return false;
  783. + }
  784. + } else {
  785. + if (log && log->GetVerbose()) {
  786. + size_t count = stack.size();
  787. + LLDB_LOGF(log, "Stack after operation has %" PRIu64 " values:",
  788. + (uint64_t)count);
  789. + for (size_t i = 0; i < count; ++i) {
  790. + StreamString new_value;
  791. + new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
  792. + stack[i].Dump(&new_value);
  793. + LLDB_LOGF(log, " %s", new_value.GetData());
  794. + }
  795. + }
  796. + result = stack.back();
  797. + }
  798. + return true; // Return true on success
  799. +}
  800. +
  801. +bool DWARFEvaluator::Evaluate(const uint8_t op, Process *process,
  802. + StackFrame *frame, std::vector<Value> &stack,
  803. + const DataExtractor &opcodes,
  804. + lldb::offset_t &offset, Value &pieces,
  805. + uint64_t &op_piece_offset, Log *log,
  806. + Status *error_ptr) {
  807. + Value tmp;
  808. + uint32_t reg_num;
  809. +
  810. + lldb::ModuleSP module_sp = m_dwarf_expression.GetModule();
  811. + const DWARFUnit *dwarf_cu = m_dwarf_expression.GetDWARFCompileUnit();
  812. + const lldb::RegisterKind reg_kind = m_dwarf_expression.GetRegisterKind();
  813. +
  814. + switch (op) {
  815. + // The DW_OP_addr operation has a single operand that encodes a machine
  816. + // address and whose size is the size of an address on the target machine.
  817. + case DW_OP_addr:
  818. + stack.push_back(Scalar(opcodes.GetAddress(&offset)));
  819. + stack.back().SetValueType(Value::ValueType::FileAddress);
  820. + // Convert the file address to a load address, so subsequent
  821. + // DWARF operators can operate on it.
  822. + if (frame)
  823. + stack.back().ConvertToLoadAddress(module_sp.get(),
  824. + frame->CalculateTarget().get());
  825. + break;
  826. +
  827. + // The DW_OP_addr_sect_offset4 is used for any location expressions in
  828. + // shared libraries that have a location like:
  829. + // DW_OP_addr(0x1000)
  830. + // If this address resides in a shared library, then this virtual address
  831. + // won't make sense when it is evaluated in the context of a running
  832. + // process where shared libraries have been slid. To account for this, this
  833. + // new address type where we can store the section pointer and a 4 byte
  834. + // offset.
  835. + // case DW_OP_addr_sect_offset4:
  836. + // {
  837. + // result_type = eResultTypeFileAddress;
  838. + // lldb::Section *sect = (lldb::Section
  839. + // *)opcodes.GetMaxU64(&offset, sizeof(void *));
  840. + // lldb::addr_t sect_offset = opcodes.GetU32(&offset);
  841. + //
  842. + // Address so_addr (sect, sect_offset);
  843. + // lldb::addr_t load_addr = so_addr.GetLoadAddress();
  844. + // if (load_addr != LLDB_INVALID_ADDRESS)
  845. + // {
  846. + // // We successfully resolve a file address to a load
  847. + // // address.
  848. + // stack.push_back(load_addr);
  849. + // break;
  850. + // }
  851. + // else
  852. + // {
  853. + // // We were able
  854. + // if (error_ptr)
  855. + // error_ptr->SetErrorStringWithFormat ("Section %s in
  856. + // %s is not currently loaded.\n",
  857. + // sect->GetName().AsCString(),
  858. + // sect->GetModule()->GetFileSpec().GetFilename().AsCString());
  859. + // return false;
  860. + // }
  861. + // }
  862. + // break;
  863. +
  864. + // OPCODE: DW_OP_deref
  865. + // OPERANDS: none
  866. + // DESCRIPTION: Pops the top stack entry and treats it as an address.
  867. + // The value retrieved from that address is pushed. The size of the data
  868. + // retrieved from the dereferenced address is the size of an address on the
  869. + // target machine.
  870. + case DW_OP_deref: {
  871. + if (stack.empty()) {
  872. + if (error_ptr)
  873. + error_ptr->SetErrorString("Expression stack empty for DW_OP_deref.");
  874. + return false;
  875. + }
  876. + Value::ValueType value_type = stack.back().GetValueType();
  877. + switch (value_type) {
  878. + case Value::ValueType::HostAddress: {
  879. + void *src = (void *)stack.back().GetScalar().ULongLong();
  880. + intptr_t ptr;
  881. + ::memcpy(&ptr, src, sizeof(void *));
  882. + stack.back().GetScalar() = ptr;
  883. + stack.back().ClearContext();
  884. + } break;
  885. + case Value::ValueType::FileAddress: {
  886. + auto file_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
  887. + if (!module_sp) {
  888. + if (error_ptr)
  889. + error_ptr->SetErrorStringWithFormat(
  890. + "need module to resolve file address for DW_OP_deref");
  891. + return false;
  892. + }
  893. + Address so_addr;
  894. + if (!module_sp->ResolveFileAddress(file_addr, so_addr)) {
  895. + if (error_ptr)
  896. + error_ptr->SetErrorStringWithFormat(
  897. + "failed to resolve file address in module");
  898. + return false;
  899. + }
  900. + addr_t load_Addr = so_addr.GetLoadAddress(m_exe_ctx->GetTargetPtr());
  901. + if (load_Addr == LLDB_INVALID_ADDRESS) {
  902. + if (error_ptr)
  903. + error_ptr->SetErrorStringWithFormat("failed to resolve load address");
  904. + return false;
  905. + }
  906. + stack.back().GetScalar() = load_Addr;
  907. + stack.back().SetValueType(Value::ValueType::LoadAddress);
  908. + // Fall through to load address code below...
  909. + }
  910. + LLVM_FALLTHROUGH;
  911. + case Value::ValueType::LoadAddress:
  912. + if (m_exe_ctx) {
  913. + if (process) {
  914. + lldb::addr_t pointer_addr =
  915. + stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
  916. + Status error;
  917. + lldb::addr_t pointer_value =
  918. + process->ReadPointerFromMemory(pointer_addr, error);
  919. + if (pointer_value != LLDB_INVALID_ADDRESS) {
  920. + stack.back().GetScalar() = pointer_value;
  921. + stack.back().ClearContext();
  922. + } else {
  923. + if (error_ptr)
  924. + error_ptr->SetErrorStringWithFormat(
  925. + "Failed to dereference pointer from 0x%" PRIx64
  926. + " for DW_OP_deref: %s\n",
  927. + pointer_addr, error.AsCString());
  928. + return false;
  929. + }
  930. + } else {
  931. + if (error_ptr)
  932. + error_ptr->SetErrorStringWithFormat(
  933. + "NULL process for DW_OP_deref.\n");
  934. + return false;
  935. + }
  936. + } else {
  937. + if (error_ptr)
  938. + error_ptr->SetErrorStringWithFormat(
  939. + "NULL execution context for DW_OP_deref.\n");
  940. + return false;
  941. + }
  942. + break;
  943. +
  944. + default:
  945. + break;
  946. + }
  947. +
  948. + } break;
  949. +
  950. + // OPCODE: DW_OP_deref_size
  951. + // OPERANDS: 1
  952. + // 1 - uint8_t that specifies the size of the data to dereference.
  953. + // DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top
  954. + // stack entry and treats it as an address. The value retrieved from that
  955. + // address is pushed. In the DW_OP_deref_size operation, however, the size
  956. + // in bytes of the data retrieved from the dereferenced address is
  957. + // specified by the single operand. This operand is a 1-byte unsigned
  958. + // integral constant whose value may not be larger than the size of an
  959. + // address on the target machine. The data retrieved is zero extended to
  960. + // the size of an address on the target machine before being pushed on the
  961. + // expression stack.
  962. + case DW_OP_deref_size: {
  963. + if (stack.empty()) {
  964. + if (error_ptr)
  965. + error_ptr->SetErrorString(
  966. + "Expression stack empty for DW_OP_deref_size.");
  967. + return false;
  968. + }
  969. + uint8_t size = opcodes.GetU8(&offset);
  970. + Value::ValueType value_type = stack.back().GetValueType();
  971. + switch (value_type) {
  972. + case Value::ValueType::HostAddress: {
  973. + void *src = (void *)stack.back().GetScalar().ULongLong();
  974. + intptr_t ptr;
  975. + ::memcpy(&ptr, src, sizeof(void *));
  976. + // I can't decide whether the size operand should apply to the bytes in
  977. + // their
  978. + // lldb-host endianness or the target endianness.. I doubt this'll ever
  979. + // come up but I'll opt for assuming big endian regardless.
  980. + switch (size) {
  981. + case 1:
  982. + ptr = ptr & 0xff;
  983. + break;
  984. + case 2:
  985. + ptr = ptr & 0xffff;
  986. + break;
  987. + case 3:
  988. + ptr = ptr & 0xffffff;
  989. + break;
  990. + case 4:
  991. + ptr = ptr & 0xffffffff;
  992. + break;
  993. + // the casts are added to work around the case where intptr_t is a 32
  994. + // bit quantity;
  995. + // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this
  996. + // program.
  997. + case 5:
  998. + ptr = (intptr_t)ptr & 0xffffffffffULL;
  999. + break;
  1000. + case 6:
  1001. + ptr = (intptr_t)ptr & 0xffffffffffffULL;
  1002. + break;
  1003. + case 7:
  1004. + ptr = (intptr_t)ptr & 0xffffffffffffffULL;
  1005. + break;
  1006. + default:
  1007. + break;
  1008. + }
  1009. + stack.back().GetScalar() = ptr;
  1010. + stack.back().ClearContext();
  1011. + } break;
  1012. + case Value::ValueType::LoadAddress:
  1013. + if (m_exe_ctx) {
  1014. + if (process) {
  1015. + lldb::addr_t pointer_addr =
  1016. + stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
  1017. + uint8_t addr_bytes[sizeof(lldb::addr_t)];
  1018. + Status error;
  1019. + if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) ==
  1020. + size) {
  1021. + DataExtractor addr_data(addr_bytes, sizeof(addr_bytes),
  1022. + process->GetByteOrder(), size);
  1023. + lldb::offset_t addr_data_offset = 0;
  1024. + switch (size) {
  1025. + case 1:
  1026. + stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset);
  1027. + break;
  1028. + case 2:
  1029. + stack.back().GetScalar() = addr_data.GetU16(&addr_data_offset);
  1030. + break;
  1031. + case 4:
  1032. + stack.back().GetScalar() = addr_data.GetU32(&addr_data_offset);
  1033. + break;
  1034. + case 8:
  1035. + stack.back().GetScalar() = addr_data.GetU64(&addr_data_offset);
  1036. + break;
  1037. + default:
  1038. + stack.back().GetScalar() =
  1039. + addr_data.GetAddress(&addr_data_offset);
  1040. + }
  1041. + stack.back().ClearContext();
  1042. + } else {
  1043. + if (error_ptr)
  1044. + error_ptr->SetErrorStringWithFormat(
  1045. + "Failed to dereference pointer from 0x%" PRIx64
  1046. + " for DW_OP_deref: %s\n",
  1047. + pointer_addr, error.AsCString());
  1048. + return false;
  1049. + }
  1050. + } else {
  1051. + if (error_ptr)
  1052. + error_ptr->SetErrorStringWithFormat(
  1053. + "NULL process for DW_OP_deref.\n");
  1054. + return false;
  1055. + }
  1056. + } else {
  1057. + if (error_ptr)
  1058. + error_ptr->SetErrorStringWithFormat(
  1059. + "NULL execution context for DW_OP_deref.\n");
  1060. + return false;
  1061. + }
  1062. + break;
  1063. +
  1064. + default:
  1065. + break;
  1066. + }
  1067. +
  1068. + } break;
  1069. +
  1070. + // OPCODE: DW_OP_xderef_size
  1071. + // OPERANDS: 1
  1072. + // 1 - uint8_t that specifies the size of the data to dereference.
  1073. + // DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at
  1074. + // the top of the stack is treated as an address. The second stack entry is
  1075. + // treated as an "address space identifier" for those architectures that
  1076. + // support multiple address spaces. The top two stack elements are popped,
  1077. + // a data item is retrieved through an implementation-defined address
  1078. + // calculation and pushed as the new stack top. In the DW_OP_xderef_size
  1079. + // operation, however, the size in bytes of the data retrieved from the
  1080. + // dereferenced address is specified by the single operand. This operand is
  1081. + // a 1-byte unsigned integral constant whose value may not be larger than
  1082. + // the size of an address on the target machine. The data retrieved is zero
  1083. + // extended to the size of an address on the target machine before being
  1084. + // pushed on the expression stack.
  1085. + case DW_OP_xderef_size:
  1086. + if (error_ptr)
  1087. + error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef_size.");
  1088. + return false;
  1089. + // OPCODE: DW_OP_xderef
  1090. + // OPERANDS: none
  1091. + // DESCRIPTION: Provides an extended dereference mechanism. The entry at
  1092. + // the top of the stack is treated as an address. The second stack entry is
  1093. + // treated as an "address space identifier" for those architectures that
  1094. + // support multiple address spaces. The top two stack elements are popped,
  1095. + // a data item is retrieved through an implementation-defined address
  1096. + // calculation and pushed as the new stack top. The size of the data
  1097. + // retrieved from the dereferenced address is the size of an address on the
  1098. + // target machine.
  1099. + case DW_OP_xderef:
  1100. + if (error_ptr)
  1101. + error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef.");
  1102. + return false;
  1103. +
  1104. + // All DW_OP_constXXX opcodes have a single operand as noted below:
  1105. + //
  1106. + // Opcode Operand 1
  1107. + // DW_OP_const1u 1-byte unsigned integer constant DW_OP_const1s
  1108. + // 1-byte signed integer constant DW_OP_const2u 2-byte unsigned integer
  1109. + // constant DW_OP_const2s 2-byte signed integer constant DW_OP_const4u
  1110. + // 4-byte unsigned integer constant DW_OP_const4s 4-byte signed integer
  1111. + // constant DW_OP_const8u 8-byte unsigned integer constant DW_OP_const8s
  1112. + // 8-byte signed integer constant DW_OP_constu unsigned LEB128 integer
  1113. + // constant DW_OP_consts signed LEB128 integer constant
  1114. + case DW_OP_const1u:
  1115. + stack.push_back(Scalar((uint8_t)opcodes.GetU8(&offset)));
  1116. + break;
  1117. + case DW_OP_const1s:
  1118. + stack.push_back(Scalar((int8_t)opcodes.GetU8(&offset)));
  1119. + break;
  1120. + case DW_OP_const2u:
  1121. + stack.push_back(Scalar((uint16_t)opcodes.GetU16(&offset)));
  1122. + break;
  1123. + case DW_OP_const2s:
  1124. + stack.push_back(Scalar((int16_t)opcodes.GetU16(&offset)));
  1125. + break;
  1126. + case DW_OP_const4u:
  1127. + stack.push_back(Scalar((uint32_t)opcodes.GetU32(&offset)));
  1128. + break;
  1129. + case DW_OP_const4s:
  1130. + stack.push_back(Scalar((int32_t)opcodes.GetU32(&offset)));
  1131. + break;
  1132. + case DW_OP_const8u:
  1133. + stack.push_back(Scalar((uint64_t)opcodes.GetU64(&offset)));
  1134. + break;
  1135. + case DW_OP_const8s:
  1136. + stack.push_back(Scalar((int64_t)opcodes.GetU64(&offset)));
  1137. + break;
  1138. + case DW_OP_constu:
  1139. + stack.push_back(Scalar(opcodes.GetULEB128(&offset)));
  1140. + break;
  1141. + case DW_OP_consts:
  1142. + stack.push_back(Scalar(opcodes.GetSLEB128(&offset)));
  1143. + break;
  1144. +
  1145. + // OPCODE: DW_OP_dup
  1146. + // OPERANDS: none
  1147. + // DESCRIPTION: duplicates the value at the top of the stack
  1148. + case DW_OP_dup:
  1149. + if (stack.empty()) {
  1150. + if (error_ptr)
  1151. + error_ptr->SetErrorString("Expression stack empty for DW_OP_dup.");
  1152. + return false;
  1153. + } else
  1154. + stack.push_back(stack.back());
  1155. + break;
  1156. +
  1157. + // OPCODE: DW_OP_drop
  1158. + // OPERANDS: none
  1159. + // DESCRIPTION: pops the value at the top of the stack
  1160. + case DW_OP_drop:
  1161. + if (stack.empty()) {
  1162. + if (error_ptr)
  1163. + error_ptr->SetErrorString("Expression stack empty for DW_OP_drop.");
  1164. + return false;
  1165. + } else
  1166. + stack.pop_back();
  1167. + break;
  1168. +
  1169. + // OPCODE: DW_OP_over
  1170. + // OPERANDS: none
  1171. + // DESCRIPTION: Duplicates the entry currently second in the stack at
  1172. + // the top of the stack.
  1173. + case DW_OP_over:
  1174. + if (stack.size() < 2) {
  1175. + if (error_ptr)
  1176. + error_ptr->SetErrorString(
  1177. + "Expression stack needs at least 2 items for DW_OP_over.");
  1178. + return false;
  1179. + } else
  1180. + stack.push_back(stack[stack.size() - 2]);
  1181. + break;
  1182. +
  1183. + // OPCODE: DW_OP_pick
  1184. + // OPERANDS: uint8_t index into the current stack
  1185. + // DESCRIPTION: The stack entry with the specified index (0 through 255,
  1186. + // inclusive) is pushed on the stack
  1187. + case DW_OP_pick: {
  1188. + uint8_t pick_idx = opcodes.GetU8(&offset);
  1189. + if (pick_idx < stack.size())
  1190. + stack.push_back(stack[stack.size() - 1 - pick_idx]);
  1191. + else {
  1192. + if (error_ptr)
  1193. + error_ptr->SetErrorStringWithFormat(
  1194. + "Index %u out of range for DW_OP_pick.\n", pick_idx);
  1195. + return false;
  1196. + }
  1197. + } break;
  1198. +
  1199. + // OPCODE: DW_OP_swap
  1200. + // OPERANDS: none
  1201. + // DESCRIPTION: swaps the top two stack entries. The entry at the top
  1202. + // of the stack becomes the second stack entry, and the second entry
  1203. + // becomes the top of the stack
  1204. + case DW_OP_swap:
  1205. + if (stack.size() < 2) {
  1206. + if (error_ptr)
  1207. + error_ptr->SetErrorString(
  1208. + "Expression stack needs at least 2 items for DW_OP_swap.");
  1209. + return false;
  1210. + } else {
  1211. + tmp = stack.back();
  1212. + stack.back() = stack[stack.size() - 2];
  1213. + stack[stack.size() - 2] = tmp;
  1214. + }
  1215. + break;
  1216. +
  1217. + // OPCODE: DW_OP_rot
  1218. + // OPERANDS: none
  1219. + // DESCRIPTION: Rotates the first three stack entries. The entry at
  1220. + // the top of the stack becomes the third stack entry, the second entry
  1221. + // becomes the top of the stack, and the third entry becomes the second
  1222. + // entry.
  1223. + case DW_OP_rot:
  1224. + if (stack.size() < 3) {
  1225. + if (error_ptr)
  1226. + error_ptr->SetErrorString(
  1227. + "Expression stack needs at least 3 items for DW_OP_rot.");
  1228. + return false;
  1229. + } else {
  1230. + size_t last_idx = stack.size() - 1;
  1231. + Value old_top = stack[last_idx];
  1232. + stack[last_idx] = stack[last_idx - 1];
  1233. + stack[last_idx - 1] = stack[last_idx - 2];
  1234. + stack[last_idx - 2] = old_top;
  1235. + }
  1236. + break;
  1237. +
  1238. + // OPCODE: DW_OP_abs
  1239. + // OPERANDS: none
  1240. + // DESCRIPTION: pops the top stack entry, interprets it as a signed
  1241. + // value and pushes its absolute value. If the absolute value can not be
  1242. + // represented, the result is undefined.
  1243. + case DW_OP_abs:
  1244. + if (stack.empty()) {
  1245. + if (error_ptr)
  1246. + error_ptr->SetErrorString(
  1247. + "Expression stack needs at least 1 item for DW_OP_abs.");
  1248. + return false;
  1249. + } else if (!stack.back().ResolveValue(m_exe_ctx).AbsoluteValue()) {
  1250. + if (error_ptr)
  1251. + error_ptr->SetErrorString(
  1252. + "Failed to take the absolute value of the first stack item.");
  1253. + return false;
  1254. + }
  1255. + break;
  1256. +
  1257. + // OPCODE: DW_OP_and
  1258. + // OPERANDS: none
  1259. + // DESCRIPTION: pops the top two stack values, performs a bitwise and
  1260. + // operation on the two, and pushes the result.
  1261. + case DW_OP_and:
  1262. + if (stack.size() < 2) {
  1263. + if (error_ptr)
  1264. + error_ptr->SetErrorString(
  1265. + "Expression stack needs at least 2 items for DW_OP_and.");
  1266. + return false;
  1267. + } else {
  1268. + tmp = stack.back();
  1269. + stack.pop_back();
  1270. + stack.back().ResolveValue(m_exe_ctx) =
  1271. + stack.back().ResolveValue(m_exe_ctx) & tmp.ResolveValue(m_exe_ctx);
  1272. + }
  1273. + break;
  1274. +
  1275. + // OPCODE: DW_OP_div
  1276. + // OPERANDS: none
  1277. + // DESCRIPTION: pops the top two stack values, divides the former second
  1278. + // entry by the former top of the stack using signed division, and pushes
  1279. + // the result.
  1280. + case DW_OP_div:
  1281. + if (stack.size() < 2) {
  1282. + if (error_ptr)
  1283. + error_ptr->SetErrorString(
  1284. + "Expression stack needs at least 2 items for DW_OP_div.");
  1285. + return false;
  1286. + } else {
  1287. + tmp = stack.back();
  1288. + if (tmp.ResolveValue(m_exe_ctx).IsZero()) {
  1289. + if (error_ptr)
  1290. + error_ptr->SetErrorString("Divide by zero.");
  1291. + return false;
  1292. + } else {
  1293. + stack.pop_back();
  1294. + stack.back() =
  1295. + stack.back().ResolveValue(m_exe_ctx) / tmp.ResolveValue(m_exe_ctx);
  1296. + if (!stack.back().ResolveValue(m_exe_ctx).IsValid()) {
  1297. + if (error_ptr)
  1298. + error_ptr->SetErrorString("Divide failed.");
  1299. + return false;
  1300. + }
  1301. + }
  1302. + }
  1303. + break;
  1304. +
  1305. + // OPCODE: DW_OP_minus
  1306. + // OPERANDS: none
  1307. + // DESCRIPTION: pops the top two stack values, subtracts the former top
  1308. + // of the stack from the former second entry, and pushes the result.
  1309. + case DW_OP_minus:
  1310. + if (stack.size() < 2) {
  1311. + if (error_ptr)
  1312. + error_ptr->SetErrorString(
  1313. + "Expression stack needs at least 2 items for DW_OP_minus.");
  1314. + return false;
  1315. + } else {
  1316. + tmp = stack.back();
  1317. + stack.pop_back();
  1318. + stack.back().ResolveValue(m_exe_ctx) =
  1319. + stack.back().ResolveValue(m_exe_ctx) - tmp.ResolveValue(m_exe_ctx);
  1320. + }
  1321. + break;
  1322. +
  1323. + // OPCODE: DW_OP_mod
  1324. + // OPERANDS: none
  1325. + // DESCRIPTION: pops the top two stack values and pushes the result of
  1326. + // the calculation: former second stack entry modulo the former top of the
  1327. + // stack.
  1328. + case DW_OP_mod:
  1329. + if (stack.size() < 2) {
  1330. + if (error_ptr)
  1331. + error_ptr->SetErrorString(
  1332. + "Expression stack needs at least 2 items for DW_OP_mod.");
  1333. + return false;
  1334. + } else {
  1335. + tmp = stack.back();
  1336. + stack.pop_back();
  1337. + stack.back().ResolveValue(m_exe_ctx) =
  1338. + stack.back().ResolveValue(m_exe_ctx) % tmp.ResolveValue(m_exe_ctx);
  1339. + }
  1340. + break;
  1341. +
  1342. + // OPCODE: DW_OP_mul
  1343. + // OPERANDS: none
  1344. + // DESCRIPTION: pops the top two stack entries, multiplies them
  1345. + // together, and pushes the result.
  1346. + case DW_OP_mul:
  1347. + if (stack.size() < 2) {
  1348. + if (error_ptr)
  1349. + error_ptr->SetErrorString(
  1350. + "Expression stack needs at least 2 items for DW_OP_mul.");
  1351. + return false;
  1352. + } else {
  1353. + tmp = stack.back();
  1354. + stack.pop_back();
  1355. + stack.back().ResolveValue(m_exe_ctx) =
  1356. + stack.back().ResolveValue(m_exe_ctx) * tmp.ResolveValue(m_exe_ctx);
  1357. + }
  1358. + break;
  1359. +
  1360. + // OPCODE: DW_OP_neg
  1361. + // OPERANDS: none
  1362. + // DESCRIPTION: pops the top stack entry, and pushes its negation.
  1363. + case DW_OP_neg:
  1364. + if (stack.empty()) {
  1365. + if (error_ptr)
  1366. + error_ptr->SetErrorString(
  1367. + "Expression stack needs at least 1 item for DW_OP_neg.");
  1368. + return false;
  1369. + } else {
  1370. + if (!stack.back().ResolveValue(m_exe_ctx).UnaryNegate()) {
  1371. + if (error_ptr)
  1372. + error_ptr->SetErrorString("Unary negate failed.");
  1373. + return false;
  1374. + }
  1375. + }
  1376. + break;
  1377. +
  1378. + // OPCODE: DW_OP_not
  1379. + // OPERANDS: none
  1380. + // DESCRIPTION: pops the top stack entry, and pushes its bitwise
  1381. + // complement
  1382. + case DW_OP_not:
  1383. + if (stack.empty()) {
  1384. + if (error_ptr)
  1385. + error_ptr->SetErrorString(
  1386. + "Expression stack needs at least 1 item for DW_OP_not.");
  1387. + return false;
  1388. + } else {
  1389. + if (!stack.back().ResolveValue(m_exe_ctx).OnesComplement()) {
  1390. + if (error_ptr)
  1391. + error_ptr->SetErrorString("Logical NOT failed.");
  1392. + return false;
  1393. + }
  1394. + }
  1395. + break;
  1396. +
  1397. + // OPCODE: DW_OP_or
  1398. + // OPERANDS: none
  1399. + // DESCRIPTION: pops the top two stack entries, performs a bitwise or
  1400. + // operation on the two, and pushes the result.
  1401. + case DW_OP_or:
  1402. + if (stack.size() < 2) {
  1403. + if (error_ptr)
  1404. + error_ptr->SetErrorString(
  1405. + "Expression stack needs at least 2 items for DW_OP_or.");
  1406. + return false;
  1407. + } else {
  1408. + tmp = stack.back();
  1409. + stack.pop_back();
  1410. + stack.back().ResolveValue(m_exe_ctx) =
  1411. + stack.back().ResolveValue(m_exe_ctx) | tmp.ResolveValue(m_exe_ctx);
  1412. + }
  1413. + break;
  1414. +
  1415. + // OPCODE: DW_OP_plus
  1416. + // OPERANDS: none
  1417. + // DESCRIPTION: pops the top two stack entries, adds them together, and
  1418. + // pushes the result.
  1419. + case DW_OP_plus:
  1420. + if (stack.size() < 2) {
  1421. + if (error_ptr)
  1422. + error_ptr->SetErrorString(
  1423. + "Expression stack needs at least 2 items for DW_OP_plus.");
  1424. + return false;
  1425. + } else {
  1426. + tmp = stack.back();
  1427. + stack.pop_back();
  1428. + stack.back().GetScalar() += tmp.GetScalar();
  1429. + }
  1430. + break;
  1431. +
  1432. + // OPCODE: DW_OP_plus_uconst
  1433. + // OPERANDS: none
  1434. + // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128
  1435. + // constant operand and pushes the result.
  1436. + case DW_OP_plus_uconst:
  1437. + if (stack.empty()) {
  1438. + if (error_ptr)
  1439. + error_ptr->SetErrorString(
  1440. + "Expression stack needs at least 1 item for DW_OP_plus_uconst.");
  1441. + return false;
  1442. + } else {
  1443. + const uint64_t uconst_value = opcodes.GetULEB128(&offset);
  1444. + // Implicit conversion from a UINT to a Scalar...
  1445. + stack.back().GetScalar() += uconst_value;
  1446. + if (!stack.back().GetScalar().IsValid()) {
  1447. + if (error_ptr)
  1448. + error_ptr->SetErrorString("DW_OP_plus_uconst failed.");
  1449. + return false;
  1450. + }
  1451. + }
  1452. + break;
  1453. +
  1454. + // OPCODE: DW_OP_shl
  1455. + // OPERANDS: none
  1456. + // DESCRIPTION: pops the top two stack entries, shifts the former
  1457. + // second entry left by the number of bits specified by the former top of
  1458. + // the stack, and pushes the result.
  1459. + case DW_OP_shl:
  1460. + if (stack.size() < 2) {
  1461. + if (error_ptr)
  1462. + error_ptr->SetErrorString(
  1463. + "Expression stack needs at least 2 items for DW_OP_shl.");
  1464. + return false;
  1465. + } else {
  1466. + tmp = stack.back();
  1467. + stack.pop_back();
  1468. + stack.back().ResolveValue(m_exe_ctx) <<= tmp.ResolveValue(m_exe_ctx);
  1469. + }
  1470. + break;
  1471. +
  1472. + // OPCODE: DW_OP_shr
  1473. + // OPERANDS: none
  1474. + // DESCRIPTION: pops the top two stack entries, shifts the former second
  1475. + // entry right logically (filling with zero bits) by the number of bits
  1476. + // specified by the former top of the stack, and pushes the result.
  1477. + case DW_OP_shr:
  1478. + if (stack.size() < 2) {
  1479. + if (error_ptr)
  1480. + error_ptr->SetErrorString(
  1481. + "Expression stack needs at least 2 items for DW_OP_shr.");
  1482. + return false;
  1483. + } else {
  1484. + tmp = stack.back();
  1485. + stack.pop_back();
  1486. + if (!stack.back().ResolveValue(m_exe_ctx).ShiftRightLogical(
  1487. + tmp.ResolveValue(m_exe_ctx))) {
  1488. + if (error_ptr)
  1489. + error_ptr->SetErrorString("DW_OP_shr failed.");
  1490. + return false;
  1491. + }
  1492. + }
  1493. + break;
  1494. +
  1495. + // OPCODE: DW_OP_shra
  1496. + // OPERANDS: none
  1497. + // DESCRIPTION: pops the top two stack entries, shifts the former second
  1498. + // entry right arithmetically (divide the magnitude by 2, keep the same
  1499. + // sign for the result) by the number of bits specified by the former top
  1500. + // of the stack, and pushes the result.
  1501. + case DW_OP_shra:
  1502. + if (stack.size() < 2) {
  1503. + if (error_ptr)
  1504. + error_ptr->SetErrorString(
  1505. + "Expression stack needs at least 2 items for DW_OP_shra.");
  1506. + return false;
  1507. + } else {
  1508. + tmp = stack.back();
  1509. + stack.pop_back();
  1510. + stack.back().ResolveValue(m_exe_ctx) >>= tmp.ResolveValue(m_exe_ctx);
  1511. + }
  1512. + break;
  1513. +
  1514. + // OPCODE: DW_OP_xor
  1515. + // OPERANDS: none
  1516. + // DESCRIPTION: pops the top two stack entries, performs the bitwise
  1517. + // exclusive-or operation on the two, and pushes the result.
  1518. + case DW_OP_xor:
  1519. + if (stack.size() < 2) {
  1520. + if (error_ptr)
  1521. + error_ptr->SetErrorString(
  1522. + "Expression stack needs at least 2 items for DW_OP_xor.");
  1523. + return false;
  1524. + } else {
  1525. + tmp = stack.back();
  1526. + stack.pop_back();
  1527. + stack.back().ResolveValue(m_exe_ctx) =
  1528. + stack.back().ResolveValue(m_exe_ctx) ^ tmp.ResolveValue(m_exe_ctx);
  1529. + }
  1530. + break;
  1531. +
  1532. + // OPCODE: DW_OP_skip
  1533. + // OPERANDS: int16_t
  1534. + // DESCRIPTION: An unconditional branch. Its single operand is a 2-byte
  1535. + // signed integer constant. The 2-byte constant is the number of bytes of
  1536. + // the DWARF expression to skip forward or backward from the current
  1537. + // operation, beginning after the 2-byte constant.
  1538. + case DW_OP_skip: {
  1539. + int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
  1540. + lldb::offset_t new_offset = offset + skip_offset;
  1541. + if (opcodes.ValidOffset(new_offset))
  1542. + offset = new_offset;
  1543. + else {
  1544. + if (error_ptr)
  1545. + error_ptr->SetErrorString("Invalid opcode offset in DW_OP_skip.");
  1546. + return false;
  1547. + }
  1548. + } break;
  1549. +
  1550. + // OPCODE: DW_OP_bra
  1551. + // OPERANDS: int16_t
  1552. + // DESCRIPTION: A conditional branch. Its single operand is a 2-byte
  1553. + // signed integer constant. This operation pops the top of stack. If the
  1554. + // value popped is not the constant 0, the 2-byte constant operand is the
  1555. + // number of bytes of the DWARF expression to skip forward or backward from
  1556. + // the current operation, beginning after the 2-byte constant.
  1557. + case DW_OP_bra:
  1558. + if (stack.empty()) {
  1559. + if (error_ptr)
  1560. + error_ptr->SetErrorString(
  1561. + "Expression stack needs at least 1 item for DW_OP_bra.");
  1562. + return false;
  1563. + } else {
  1564. + tmp = stack.back();
  1565. + stack.pop_back();
  1566. + int16_t bra_offset = (int16_t)opcodes.GetU16(&offset);
  1567. + Scalar zero(0);
  1568. + if (tmp.ResolveValue(m_exe_ctx) != zero) {
  1569. + lldb::offset_t new_offset = offset + bra_offset;
  1570. + if (opcodes.ValidOffset(new_offset))
  1571. + offset = new_offset;
  1572. + else {
  1573. + if (error_ptr)
  1574. + error_ptr->SetErrorString("Invalid opcode offset in DW_OP_bra.");
  1575. + return false;
  1576. + }
  1577. + }
  1578. + }
  1579. + break;
  1580. +
  1581. + // OPCODE: DW_OP_eq
  1582. + // OPERANDS: none
  1583. + // DESCRIPTION: pops the top two stack values, compares using the
  1584. + // equals (==) operator.
  1585. + // STACK RESULT: push the constant value 1 onto the stack if the result
  1586. + // of the operation is true or the constant value 0 if the result of the
  1587. + // operation is false.
  1588. + case DW_OP_eq:
  1589. + if (stack.size() < 2) {
  1590. + if (error_ptr)
  1591. + error_ptr->SetErrorString(
  1592. + "Expression stack needs at least 2 items for DW_OP_eq.");
  1593. + return false;
  1594. + } else {
  1595. + tmp = stack.back();
  1596. + stack.pop_back();
  1597. + stack.back().ResolveValue(m_exe_ctx) =
  1598. + stack.back().ResolveValue(m_exe_ctx) == tmp.ResolveValue(m_exe_ctx);
  1599. + }
  1600. + break;
  1601. +
  1602. + // OPCODE: DW_OP_ge
  1603. + // OPERANDS: none
  1604. + // DESCRIPTION: pops the top two stack values, compares using the
  1605. + // greater than or equal to (>=) operator.
  1606. + // STACK RESULT: push the constant value 1 onto the stack if the result
  1607. + // of the operation is true or the constant value 0 if the result of the
  1608. + // operation is false.
  1609. + case DW_OP_ge:
  1610. + if (stack.size() < 2) {
  1611. + if (error_ptr)
  1612. + error_ptr->SetErrorString(
  1613. + "Expression stack needs at least 2 items for DW_OP_ge.");
  1614. + return false;
  1615. + } else {
  1616. + tmp = stack.back();
  1617. + stack.pop_back();
  1618. + stack.back().ResolveValue(m_exe_ctx) =
  1619. + stack.back().ResolveValue(m_exe_ctx) >= tmp.ResolveValue(m_exe_ctx);
  1620. + }
  1621. + break;
  1622. +
  1623. + // OPCODE: DW_OP_gt
  1624. + // OPERANDS: none
  1625. + // DESCRIPTION: pops the top two stack values, compares using the
  1626. + // greater than (>) operator.
  1627. + // STACK RESULT: push the constant value 1 onto the stack if the result
  1628. + // of the operation is true or the constant value 0 if the result of the
  1629. + // operation is false.
  1630. + case DW_OP_gt:
  1631. + if (stack.size() < 2) {
  1632. + if (error_ptr)
  1633. + error_ptr->SetErrorString(
  1634. + "Expression stack needs at least 2 items for DW_OP_gt.");
  1635. + return false;
  1636. + } else {
  1637. + tmp = stack.back();
  1638. + stack.pop_back();
  1639. + stack.back().ResolveValue(m_exe_ctx) =
  1640. + stack.back().ResolveValue(m_exe_ctx) > tmp.ResolveValue(m_exe_ctx);
  1641. + }
  1642. + break;
  1643. +
  1644. + // OPCODE: DW_OP_le
  1645. + // OPERANDS: none
  1646. + // DESCRIPTION: pops the top two stack values, compares using the
  1647. + // less than or equal to (<=) operator.
  1648. + // STACK RESULT: push the constant value 1 onto the stack if the result
  1649. + // of the operation is true or the constant value 0 if the result of the
  1650. + // operation is false.
  1651. + case DW_OP_le:
  1652. + if (stack.size() < 2) {
  1653. + if (error_ptr)
  1654. + error_ptr->SetErrorString(
  1655. + "Expression stack needs at least 2 items for DW_OP_le.");
  1656. + return false;
  1657. + } else {
  1658. + tmp = stack.back();
  1659. + stack.pop_back();
  1660. + stack.back().ResolveValue(m_exe_ctx) =
  1661. + stack.back().ResolveValue(m_exe_ctx) <= tmp.ResolveValue(m_exe_ctx);
  1662. + }
  1663. + break;
  1664. +
  1665. + // OPCODE: DW_OP_lt
  1666. + // OPERANDS: none
  1667. + // DESCRIPTION: pops the top two stack values, compares using the
  1668. + // less than (<) operator.
  1669. + // STACK RESULT: push the constant value 1 onto the stack if the result
  1670. + // of the operation is true or the constant value 0 if the result of the
  1671. + // operation is false.
  1672. + case DW_OP_lt:
  1673. + if (stack.size() < 2) {
  1674. + if (error_ptr)
  1675. + error_ptr->SetErrorString(
  1676. + "Expression stack needs at least 2 items for DW_OP_lt.");
  1677. + return false;
  1678. + } else {
  1679. + tmp = stack.back();
  1680. + stack.pop_back();
  1681. + stack.back().ResolveValue(m_exe_ctx) =
  1682. + stack.back().ResolveValue(m_exe_ctx) < tmp.ResolveValue(m_exe_ctx);
  1683. + }
  1684. + break;
  1685. +
  1686. + // OPCODE: DW_OP_ne
  1687. + // OPERANDS: none
  1688. + // DESCRIPTION: pops the top two stack values, compares using the
  1689. + // not equal (!=) operator.
  1690. + // STACK RESULT: push the constant value 1 onto the stack if the result
  1691. + // of the operation is true or the constant value 0 if the result of the
  1692. + // operation is false.
  1693. + case DW_OP_ne:
  1694. + if (stack.size() < 2) {
  1695. + if (error_ptr)
  1696. + error_ptr->SetErrorString(
  1697. + "Expression stack needs at least 2 items for DW_OP_ne.");
  1698. + return false;
  1699. + } else {
  1700. + tmp = stack.back();
  1701. + stack.pop_back();
  1702. + stack.back().ResolveValue(m_exe_ctx) =
  1703. + stack.back().ResolveValue(m_exe_ctx) != tmp.ResolveValue(m_exe_ctx);
  1704. + }
  1705. + break;
  1706. +
  1707. + // OPCODE: DW_OP_litn
  1708. + // OPERANDS: none
  1709. + // DESCRIPTION: encode the unsigned literal values from 0 through 31.
  1710. + // STACK RESULT: push the unsigned literal constant value onto the top
  1711. + // of the stack.
  1712. + case DW_OP_lit0:
  1713. + case DW_OP_lit1:
  1714. + case DW_OP_lit2:
  1715. + case DW_OP_lit3:
  1716. + case DW_OP_lit4:
  1717. + case DW_OP_lit5:
  1718. + case DW_OP_lit6:
  1719. + case DW_OP_lit7:
  1720. + case DW_OP_lit8:
  1721. + case DW_OP_lit9:
  1722. + case DW_OP_lit10:
  1723. + case DW_OP_lit11:
  1724. + case DW_OP_lit12:
  1725. + case DW_OP_lit13:
  1726. + case DW_OP_lit14:
  1727. + case DW_OP_lit15:
  1728. + case DW_OP_lit16:
  1729. + case DW_OP_lit17:
  1730. + case DW_OP_lit18:
  1731. + case DW_OP_lit19:
  1732. + case DW_OP_lit20:
  1733. + case DW_OP_lit21:
  1734. + case DW_OP_lit22:
  1735. + case DW_OP_lit23:
  1736. + case DW_OP_lit24:
  1737. + case DW_OP_lit25:
  1738. + case DW_OP_lit26:
  1739. + case DW_OP_lit27:
  1740. + case DW_OP_lit28:
  1741. + case DW_OP_lit29:
  1742. + case DW_OP_lit30:
  1743. + case DW_OP_lit31:
  1744. + stack.push_back(Scalar((uint64_t)(op - DW_OP_lit0)));
  1745. + break;
  1746. +
  1747. + // OPCODE: DW_OP_regN
  1748. + // OPERANDS: none
  1749. + // DESCRIPTION: Push the value in register n on the top of the stack.
  1750. + case DW_OP_reg0:
  1751. + case DW_OP_reg1:
  1752. + case DW_OP_reg2:
  1753. + case DW_OP_reg3:
  1754. + case DW_OP_reg4:
  1755. + case DW_OP_reg5:
  1756. + case DW_OP_reg6:
  1757. + case DW_OP_reg7:
  1758. + case DW_OP_reg8:
  1759. + case DW_OP_reg9:
  1760. + case DW_OP_reg10:
  1761. + case DW_OP_reg11:
  1762. + case DW_OP_reg12:
  1763. + case DW_OP_reg13:
  1764. + case DW_OP_reg14:
  1765. + case DW_OP_reg15:
  1766. + case DW_OP_reg16:
  1767. + case DW_OP_reg17:
  1768. + case DW_OP_reg18:
  1769. + case DW_OP_reg19:
  1770. + case DW_OP_reg20:
  1771. + case DW_OP_reg21:
  1772. + case DW_OP_reg22:
  1773. + case DW_OP_reg23:
  1774. + case DW_OP_reg24:
  1775. + case DW_OP_reg25:
  1776. + case DW_OP_reg26:
  1777. + case DW_OP_reg27:
  1778. + case DW_OP_reg28:
  1779. + case DW_OP_reg29:
  1780. + case DW_OP_reg30:
  1781. + case DW_OP_reg31: {
  1782. + reg_num = op - DW_OP_reg0;
  1783. +
  1784. + if (ReadRegisterValueAsScalar(m_reg_ctx, reg_kind, reg_num, error_ptr, tmp))
  1785. + stack.push_back(tmp);
  1786. + else
  1787. + return false;
  1788. + } break;
  1789. + // OPCODE: DW_OP_regx
  1790. + // OPERANDS:
  1791. + // ULEB128 literal operand that encodes the register.
  1792. + // DESCRIPTION: Push the value in register on the top of the stack.
  1793. + case DW_OP_regx: {
  1794. + reg_num = opcodes.GetULEB128(&offset);
  1795. + if (ReadRegisterValueAsScalar(m_reg_ctx, reg_kind, reg_num, error_ptr, tmp))
  1796. + stack.push_back(tmp);
  1797. + else
  1798. + return false;
  1799. + } break;
  1800. +
  1801. + // OPCODE: DW_OP_bregN
  1802. + // OPERANDS:
  1803. + // SLEB128 offset from register N
  1804. + // DESCRIPTION: Value is in memory at the address specified by register
  1805. + // N plus an offset.
  1806. + case DW_OP_breg0:
  1807. + case DW_OP_breg1:
  1808. + case DW_OP_breg2:
  1809. + case DW_OP_breg3:
  1810. + case DW_OP_breg4:
  1811. + case DW_OP_breg5:
  1812. + case DW_OP_breg6:
  1813. + case DW_OP_breg7:
  1814. + case DW_OP_breg8:
  1815. + case DW_OP_breg9:
  1816. + case DW_OP_breg10:
  1817. + case DW_OP_breg11:
  1818. + case DW_OP_breg12:
  1819. + case DW_OP_breg13:
  1820. + case DW_OP_breg14:
  1821. + case DW_OP_breg15:
  1822. + case DW_OP_breg16:
  1823. + case DW_OP_breg17:
  1824. + case DW_OP_breg18:
  1825. + case DW_OP_breg19:
  1826. + case DW_OP_breg20:
  1827. + case DW_OP_breg21:
  1828. + case DW_OP_breg22:
  1829. + case DW_OP_breg23:
  1830. + case DW_OP_breg24:
  1831. + case DW_OP_breg25:
  1832. + case DW_OP_breg26:
  1833. + case DW_OP_breg27:
  1834. + case DW_OP_breg28:
  1835. + case DW_OP_breg29:
  1836. + case DW_OP_breg30:
  1837. + case DW_OP_breg31: {
  1838. + reg_num = op - DW_OP_breg0;
  1839. +
  1840. + if (ReadRegisterValueAsScalar(m_reg_ctx, reg_kind, reg_num, error_ptr,
  1841. + tmp)) {
  1842. + int64_t breg_offset = opcodes.GetSLEB128(&offset);
  1843. + tmp.ResolveValue(m_exe_ctx) += (uint64_t)breg_offset;
  1844. + tmp.ClearContext();
  1845. + stack.push_back(tmp);
  1846. + stack.back().SetValueType(Value::ValueType::LoadAddress);
  1847. + } else
  1848. + return false;
  1849. + } break;
  1850. + // OPCODE: DW_OP_bregx
  1851. + // OPERANDS: 2
  1852. + // ULEB128 literal operand that encodes the register.
  1853. + // SLEB128 offset from register N
  1854. + // DESCRIPTION: Value is in memory at the address specified by register
  1855. + // N plus an offset.
  1856. + case DW_OP_bregx: {
  1857. + reg_num = opcodes.GetULEB128(&offset);
  1858. +
  1859. + if (ReadRegisterValueAsScalar(m_reg_ctx, reg_kind, reg_num, error_ptr,
  1860. + tmp)) {
  1861. + int64_t breg_offset = opcodes.GetSLEB128(&offset);
  1862. + tmp.ResolveValue(m_exe_ctx) += (uint64_t)breg_offset;
  1863. + tmp.ClearContext();
  1864. + stack.push_back(tmp);
  1865. + stack.back().SetValueType(Value::ValueType::LoadAddress);
  1866. + } else
  1867. + return false;
  1868. + } break;
  1869. +
  1870. + case DW_OP_fbreg:
  1871. + if (m_exe_ctx) {
  1872. + if (frame) {
  1873. + Scalar value;
  1874. + if (frame->GetFrameBaseValue(value, error_ptr)) {
  1875. + int64_t fbreg_offset = opcodes.GetSLEB128(&offset);
  1876. + value += fbreg_offset;
  1877. + stack.push_back(value);
  1878. + stack.back().SetValueType(Value::ValueType::LoadAddress);
  1879. + } else
  1880. + return false;
  1881. + } else {
  1882. + if (error_ptr)
  1883. + error_ptr->SetErrorString(
  1884. + "Invalid stack frame in context for DW_OP_fbreg opcode.");
  1885. + return false;
  1886. + }
  1887. + } else {
  1888. + if (error_ptr)
  1889. + error_ptr->SetErrorStringWithFormat(
  1890. + "NULL execution context for DW_OP_fbreg.\n");
  1891. + return false;
  1892. + }
  1893. +
  1894. + break;
  1895. +
  1896. + // OPCODE: DW_OP_nop
  1897. + // OPERANDS: none
  1898. + // DESCRIPTION: A place holder. It has no effect on the location stack
  1899. + // or any of its values.
  1900. + case DW_OP_nop:
  1901. + break;
  1902. +
  1903. + // OPCODE: DW_OP_piece
  1904. + // OPERANDS: 1
  1905. + // ULEB128: byte size of the piece
  1906. + // DESCRIPTION: The operand describes the size in bytes of the piece of
  1907. + // the object referenced by the DWARF expression whose result is at the top
  1908. + // of the stack. If the piece is located in a register, but does not occupy
  1909. + // the entire register, the placement of the piece within that register is
  1910. + // defined by the ABI.
  1911. + //
  1912. + // Many compilers store a single variable in sets of registers, or store a
  1913. + // variable partially in memory and partially in registers. DW_OP_piece
  1914. + // provides a way of describing how large a part of a variable a particular
  1915. + // DWARF expression refers to.
  1916. + case DW_OP_piece: {
  1917. + const uint64_t piece_byte_size = opcodes.GetULEB128(&offset);
  1918. +
  1919. + if (piece_byte_size > 0) {
  1920. + Value curr_piece;
  1921. +
  1922. + if (stack.empty()) {
  1923. + // In a multi-piece expression, this means that the current piece is
  1924. + // not available. Fill with zeros for now by resizing the data and
  1925. + // appending it
  1926. + curr_piece.ResizeData(piece_byte_size);
  1927. + // Note that "0" is not a correct value for the unknown bits.
  1928. + // It would be better to also return a mask of valid bits together
  1929. + // with the expression result, so the debugger can print missing
  1930. + // members as "<optimized out>" or something.
  1931. + ::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
  1932. + pieces.AppendDataToHostBuffer(curr_piece);
  1933. + } else {
  1934. + Status error;
  1935. + // Extract the current piece into "curr_piece"
  1936. + Value curr_piece_source_value(stack.back());
  1937. + stack.pop_back();
  1938. +
  1939. + const Value::ValueType curr_piece_source_value_type =
  1940. + curr_piece_source_value.GetValueType();
  1941. + switch (curr_piece_source_value_type) {
  1942. + case Value::ValueType::LoadAddress:
  1943. + if (process) {
  1944. + if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) {
  1945. + lldb::addr_t load_addr =
  1946. + curr_piece_source_value.GetScalar().ULongLong(
  1947. + LLDB_INVALID_ADDRESS);
  1948. + if (process->ReadMemory(
  1949. + load_addr, curr_piece.GetBuffer().GetBytes(),
  1950. + piece_byte_size, error) != piece_byte_size) {
  1951. + if (error_ptr)
  1952. + error_ptr->SetErrorStringWithFormat(
  1953. + "failed to read memory DW_OP_piece(%" PRIu64
  1954. + ") from 0x%" PRIx64,
  1955. + piece_byte_size, load_addr);
  1956. + return false;
  1957. + }
  1958. + } else {
  1959. + if (error_ptr)
  1960. + error_ptr->SetErrorStringWithFormat(
  1961. + "failed to resize the piece memory buffer for "
  1962. + "DW_OP_piece(%" PRIu64 ")",
  1963. + piece_byte_size);
  1964. + return false;
  1965. + }
  1966. + }
  1967. + break;
  1968. +
  1969. + case Value::ValueType::FileAddress:
  1970. + case Value::ValueType::HostAddress:
  1971. + if (error_ptr) {
  1972. + lldb::addr_t addr = curr_piece_source_value.GetScalar().ULongLong(
  1973. + LLDB_INVALID_ADDRESS);
  1974. + error_ptr->SetErrorStringWithFormat(
  1975. + "failed to read memory DW_OP_piece(%" PRIu64
  1976. + ") from %s address 0x%" PRIx64,
  1977. + piece_byte_size,
  1978. + curr_piece_source_value.GetValueType() ==
  1979. + Value::ValueType::FileAddress
  1980. + ? "file"
  1981. + : "host",
  1982. + addr);
  1983. + }
  1984. + return false;
  1985. +
  1986. + case Value::ValueType::Scalar: {
  1987. + uint32_t bit_size = piece_byte_size * 8;
  1988. + uint32_t bit_offset = 0;
  1989. + Scalar &scalar = curr_piece_source_value.GetScalar();
  1990. + if (!scalar.ExtractBitfield(bit_size, bit_offset)) {
  1991. + if (error_ptr)
  1992. + error_ptr->SetErrorStringWithFormat(
  1993. + "unable to extract %" PRIu64 " bytes from a %" PRIu64
  1994. + " byte scalar value.",
  1995. + piece_byte_size,
  1996. + (uint64_t)curr_piece_source_value.GetScalar().GetByteSize());
  1997. + return false;
  1998. + }
  1999. + // Create curr_piece with bit_size. By default Scalar
  2000. + // grows to the nearest host integer type.
  2001. + llvm::APInt fail_value(1, 0, false);
  2002. + llvm::APInt ap_int = scalar.UInt128(fail_value);
  2003. + assert(ap_int.getBitWidth() >= bit_size);
  2004. + llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
  2005. + ap_int.getNumWords()};
  2006. + curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
  2007. + } break;
  2008. + }
  2009. +
  2010. + // Check if this is the first piece?
  2011. + if (op_piece_offset == 0) {
  2012. + // This is the first piece, we should push it back onto the stack
  2013. + // so subsequent pieces will be able to access this piece and add
  2014. + // to it.
  2015. + if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
  2016. + if (error_ptr)
  2017. + error_ptr->SetErrorString("failed to append piece data");
  2018. + return false;
  2019. + }
  2020. + } else {
  2021. + // If this is the second or later piece there should be a value on
  2022. + // the stack.
  2023. + if (pieces.GetBuffer().GetByteSize() != op_piece_offset) {
  2024. + if (error_ptr)
  2025. + error_ptr->SetErrorStringWithFormat(
  2026. + "DW_OP_piece for offset %" PRIu64
  2027. + " but top of stack is of size %" PRIu64,
  2028. + op_piece_offset, pieces.GetBuffer().GetByteSize());
  2029. + return false;
  2030. + }
  2031. +
  2032. + if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
  2033. + if (error_ptr)
  2034. + error_ptr->SetErrorString("failed to append piece data");
  2035. + return false;
  2036. + }
  2037. + }
  2038. + }
  2039. + op_piece_offset += piece_byte_size;
  2040. + }
  2041. + } break;
  2042. +
  2043. + case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
  2044. + if (stack.size() < 1) {
  2045. + if (error_ptr)
  2046. + error_ptr->SetErrorString(
  2047. + "Expression stack needs at least 1 item for DW_OP_bit_piece.");
  2048. + return false;
  2049. + } else {
  2050. + const uint64_t piece_bit_size = opcodes.GetULEB128(&offset);
  2051. + const uint64_t piece_bit_offset = opcodes.GetULEB128(&offset);
  2052. + switch (stack.back().GetValueType()) {
  2053. + case Value::ValueType::Scalar: {
  2054. + if (!stack.back().GetScalar().ExtractBitfield(piece_bit_size,
  2055. + piece_bit_offset)) {
  2056. + if (error_ptr)
  2057. + error_ptr->SetErrorStringWithFormat(
  2058. + "unable to extract %" PRIu64 " bit value with %" PRIu64
  2059. + " bit offset from a %" PRIu64 " bit scalar value.",
  2060. + piece_bit_size, piece_bit_offset,
  2061. + (uint64_t)(stack.back().GetScalar().GetByteSize() * 8));
  2062. + return false;
  2063. + }
  2064. + } break;
  2065. +
  2066. + case Value::ValueType::FileAddress:
  2067. + case Value::ValueType::LoadAddress:
  2068. + case Value::ValueType::HostAddress:
  2069. + if (error_ptr) {
  2070. + error_ptr->SetErrorStringWithFormat(
  2071. + "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
  2072. + ", bit_offset = %" PRIu64 ") from an address value.",
  2073. + piece_bit_size, piece_bit_offset);
  2074. + }
  2075. + return false;
  2076. + }
  2077. + }
  2078. + break;
  2079. +
  2080. + // OPCODE: DW_OP_push_object_address
  2081. + // OPERANDS: none
  2082. + // DESCRIPTION: Pushes the address of the object currently being
  2083. + // evaluated as part of evaluation of a user presented expression. This
  2084. + // object may correspond to an independent variable described by its own
  2085. + // DIE or it may be a component of an array, structure, or class whose
  2086. + // address has been dynamically determined by an earlier step during user
  2087. + // expression evaluation.
  2088. + case DW_OP_push_object_address:
  2089. + if (m_object_address_ptr)
  2090. + stack.push_back(*m_object_address_ptr);
  2091. + else {
  2092. + if (error_ptr)
  2093. + error_ptr->SetErrorString("DW_OP_push_object_address used without "
  2094. + "specifying an object address");
  2095. + return false;
  2096. + }
  2097. + break;
  2098. +
  2099. + // OPCODE: DW_OP_call2
  2100. + // OPERANDS:
  2101. + // uint16_t compile unit relative offset of a DIE
  2102. + // DESCRIPTION: Performs subroutine calls during evaluation
  2103. + // of a DWARF expression. The operand is the 2-byte unsigned offset of a
  2104. + // debugging information entry in the current compilation unit.
  2105. + //
  2106. + // Operand interpretation is exactly like that for DW_FORM_ref2.
  2107. + //
  2108. + // This operation transfers control of DWARF expression evaluation to the
  2109. + // DW_AT_location attribute of the referenced DIE. If there is no such
  2110. + // attribute, then there is no effect. Execution of the DWARF expression of
  2111. + // a DW_AT_location attribute may add to and/or remove from values on the
  2112. + // stack. Execution returns to the point following the call when the end of
  2113. + // the attribute is reached. Values on the stack at the time of the call
  2114. + // may be used as parameters by the called expression and values left on
  2115. + // the stack by the called expression may be used as return values by prior
  2116. + // agreement between the calling and called expressions.
  2117. + case DW_OP_call2:
  2118. + if (error_ptr)
  2119. + error_ptr->SetErrorString("Unimplemented opcode DW_OP_call2.");
  2120. + return false;
  2121. + // OPCODE: DW_OP_call4
  2122. + // OPERANDS: 1
  2123. + // uint32_t compile unit relative offset of a DIE
  2124. + // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF
  2125. + // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset of
  2126. + // a debugging information entry in the current compilation unit.
  2127. + //
  2128. + // Operand interpretation DW_OP_call4 is exactly like that for
  2129. + // DW_FORM_ref4.
  2130. + //
  2131. + // This operation transfers control of DWARF expression evaluation to the
  2132. + // DW_AT_location attribute of the referenced DIE. If there is no such
  2133. + // attribute, then there is no effect. Execution of the DWARF expression of
  2134. + // a DW_AT_location attribute may add to and/or remove from values on the
  2135. + // stack. Execution returns to the point following the call when the end of
  2136. + // the attribute is reached. Values on the stack at the time of the call
  2137. + // may be used as parameters by the called expression and values left on
  2138. + // the stack by the called expression may be used as return values by prior
  2139. + // agreement between the calling and called expressions.
  2140. + case DW_OP_call4:
  2141. + if (error_ptr)
  2142. + error_ptr->SetErrorString("Unimplemented opcode DW_OP_call4.");
  2143. + return false;
  2144. +
  2145. + // OPCODE: DW_OP_stack_value
  2146. + // OPERANDS: None
  2147. + // DESCRIPTION: Specifies that the object does not exist in memory but
  2148. + // rather is a constant value. The value from the top of the stack is the
  2149. + // value to be used. This is the actual object value and not the location.
  2150. + case DW_OP_stack_value:
  2151. + if (stack.empty()) {
  2152. + if (error_ptr)
  2153. + error_ptr->SetErrorString(
  2154. + "Expression stack needs at least 1 item for DW_OP_stack_value.");
  2155. + return false;
  2156. + }
  2157. + stack.back().SetValueType(Value::ValueType::Scalar);
  2158. + break;
  2159. +
  2160. + // OPCODE: DW_OP_convert
  2161. + // OPERANDS: 1
  2162. + // A ULEB128 that is either a DIE offset of a
  2163. + // DW_TAG_base_type or 0 for the generic (pointer-sized) type.
  2164. + //
  2165. + // DESCRIPTION: Pop the top stack element, convert it to a
  2166. + // different type, and push the result.
  2167. + case DW_OP_convert: {
  2168. + if (stack.size() < 1) {
  2169. + if (error_ptr)
  2170. + error_ptr->SetErrorString(
  2171. + "Expression stack needs at least 1 item for DW_OP_convert.");
  2172. + return false;
  2173. + }
  2174. + const uint64_t die_offset = opcodes.GetULEB128(&offset);
  2175. + uint64_t bit_size;
  2176. + bool sign;
  2177. + if (die_offset == 0) {
  2178. + // The generic type has the size of an address on the target
  2179. + // machine and an unspecified signedness. Scalar has no
  2180. + // "unspecified signedness", so we use unsigned types.
  2181. + if (!module_sp) {
  2182. + if (error_ptr)
  2183. + error_ptr->SetErrorString("No module");
  2184. + return false;
  2185. + }
  2186. + sign = false;
  2187. + bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
  2188. + if (!bit_size) {
  2189. + if (error_ptr)
  2190. + error_ptr->SetErrorString("unspecified architecture");
  2191. + return false;
  2192. + }
  2193. + } else {
  2194. + // Retrieve the type DIE that the value is being converted to.
  2195. + // FIXME: the constness has annoying ripple effects.
  2196. + DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(die_offset);
  2197. + if (!die) {
  2198. + if (error_ptr)
  2199. + error_ptr->SetErrorString("Cannot resolve DW_OP_convert type DIE");
  2200. + return false;
  2201. + }
  2202. + uint64_t encoding =
  2203. + die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
  2204. + bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
  2205. + if (!bit_size)
  2206. + bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
  2207. + if (!bit_size) {
  2208. + if (error_ptr)
  2209. + error_ptr->SetErrorString("Unsupported type size in DW_OP_convert");
  2210. + return false;
  2211. + }
  2212. + switch (encoding) {
  2213. + case DW_ATE_signed:
  2214. + case DW_ATE_signed_char:
  2215. + sign = true;
  2216. + break;
  2217. + case DW_ATE_unsigned:
  2218. + case DW_ATE_unsigned_char:
  2219. + sign = false;
  2220. + break;
  2221. + default:
  2222. + if (error_ptr)
  2223. + error_ptr->SetErrorString("Unsupported encoding in DW_OP_convert");
  2224. + return false;
  2225. + }
  2226. + }
  2227. + Scalar &top = stack.back().ResolveValue(m_exe_ctx);
  2228. + top.TruncOrExtendTo(bit_size, sign);
  2229. + break;
  2230. + }
  2231. +
  2232. + // OPCODE: DW_OP_call_frame_cfa
  2233. + // OPERANDS: None
  2234. + // DESCRIPTION: Specifies a DWARF expression that pushes the value of
  2235. + // the canonical frame address consistent with the call frame information
  2236. + // located in .debug_frame (or in the FDEs of the eh_frame section).
  2237. + case DW_OP_call_frame_cfa:
  2238. + if (frame) {
  2239. + // Note that we don't have to parse FDEs because this DWARF expression
  2240. + // is commonly evaluated with a valid stack frame.
  2241. + StackID id = frame->GetStackID();
  2242. + addr_t cfa = id.GetCallFrameAddress();
  2243. + if (cfa != LLDB_INVALID_ADDRESS) {
  2244. + stack.push_back(Scalar(cfa));
  2245. + stack.back().SetValueType(Value::ValueType::LoadAddress);
  2246. + } else if (error_ptr)
  2247. + error_ptr->SetErrorString("Stack frame does not include a canonical "
  2248. + "frame address for DW_OP_call_frame_cfa "
  2249. + "opcode.");
  2250. + } else {
  2251. + if (error_ptr)
  2252. + error_ptr->SetErrorString("Invalid stack frame in context for "
  2253. + "DW_OP_call_frame_cfa opcode.");
  2254. + return false;
  2255. + }
  2256. + break;
  2257. +
  2258. + // OPCODE: DW_OP_form_tls_address (or the old pre-DWARFv3 vendor extension
  2259. + // opcode, DW_OP_GNU_push_tls_address)
  2260. + // OPERANDS: none
  2261. + // DESCRIPTION: Pops a TLS offset from the stack, converts it to
  2262. + // an address in the current thread's thread-local storage block, and
  2263. + // pushes it on the stack.
  2264. + case DW_OP_form_tls_address:
  2265. + case DW_OP_GNU_push_tls_address: {
  2266. + if (stack.size() < 1) {
  2267. + if (error_ptr) {
  2268. + if (op == DW_OP_form_tls_address)
  2269. + error_ptr->SetErrorString(
  2270. + "DW_OP_form_tls_address needs an argument.");
  2271. + else
  2272. + error_ptr->SetErrorString(
  2273. + "DW_OP_GNU_push_tls_address needs an argument.");
  2274. + }
  2275. + return false;
  2276. + }
  2277. +
  2278. + if (!m_exe_ctx || !module_sp) {
  2279. + if (error_ptr)
  2280. + error_ptr->SetErrorString("No context to evaluate TLS within.");
  2281. + return false;
  2282. + }
  2283. +
  2284. + Thread *thread = m_exe_ctx->GetThreadPtr();
  2285. + if (!thread) {
  2286. + if (error_ptr)
  2287. + error_ptr->SetErrorString("No thread to evaluate TLS within.");
  2288. + return false;
  2289. + }
  2290. +
  2291. + // Lookup the TLS block address for this thread and module.
  2292. + const addr_t tls_file_addr =
  2293. + stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
  2294. + const addr_t tls_load_addr =
  2295. + thread->GetThreadLocalData(module_sp, tls_file_addr);
  2296. +
  2297. + if (tls_load_addr == LLDB_INVALID_ADDRESS) {
  2298. + if (error_ptr)
  2299. + error_ptr->SetErrorString(
  2300. + "No TLS data currently exists for this thread.");
  2301. + return false;
  2302. + }
  2303. +
  2304. + stack.back().GetScalar() = tls_load_addr;
  2305. + stack.back().SetValueType(Value::ValueType::LoadAddress);
  2306. + } break;
  2307. +
  2308. + // OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.)
  2309. + // OPERANDS: 1
  2310. + // ULEB128: index to the .debug_addr section
  2311. + // DESCRIPTION: Pushes an address to the stack from the .debug_addr
  2312. + // section with the base address specified by the DW_AT_addr_base attribute
  2313. + // and the 0 based index is the ULEB128 encoded index.
  2314. + case DW_OP_addrx:
  2315. + case DW_OP_GNU_addr_index: {
  2316. + if (!dwarf_cu) {
  2317. + if (error_ptr)
  2318. + error_ptr->SetErrorString("DW_OP_GNU_addr_index found without a "
  2319. + "compile unit being specified");
  2320. + return false;
  2321. + }
  2322. + uint64_t index = opcodes.GetULEB128(&offset);
  2323. + lldb::addr_t value =
  2324. + DWARFExpression::ReadAddressFromDebugAddrSection(dwarf_cu, index);
  2325. + stack.push_back(Scalar(value));
  2326. + stack.back().SetValueType(Value::ValueType::FileAddress);
  2327. + } break;
  2328. +
  2329. + // OPCODE: DW_OP_GNU_const_index
  2330. + // OPERANDS: 1
  2331. + // ULEB128: index to the .debug_addr section
  2332. + // DESCRIPTION: Pushes an constant with the size of a machine address to
  2333. + // the stack from the .debug_addr section with the base address specified
  2334. + // by the DW_AT_addr_base attribute and the 0 based index is the ULEB128
  2335. + // encoded index.
  2336. + case DW_OP_GNU_const_index: {
  2337. + if (!dwarf_cu) {
  2338. + if (error_ptr)
  2339. + error_ptr->SetErrorString("DW_OP_GNU_const_index found without a "
  2340. + "compile unit being specified");
  2341. + return false;
  2342. + }
  2343. + uint64_t index = opcodes.GetULEB128(&offset);
  2344. + lldb::addr_t value =
  2345. + DWARFExpression::ReadAddressFromDebugAddrSection(dwarf_cu, index);
  2346. + stack.push_back(Scalar(value));
  2347. + } break;
  2348. +
  2349. + case DW_OP_entry_value: {
  2350. + if (!Evaluate_DW_OP_entry_value(stack, m_exe_ctx, m_reg_ctx, opcodes,
  2351. + offset, error_ptr, log)) {
  2352. + LLDB_ERRORF(error_ptr, "Could not evaluate %s.", DW_OP_value_to_name(op));
  2353. + return false;
  2354. + }
  2355. + break;
  2356. + }
  2357. +
  2358. + default:
  2359. + LLDB_LOGF(log, "Unhandled opcode %s in DWARFExpression.",
  2360. + DW_OP_value_to_name(op));
  2361. + break;
  2362. + }
  2363. +
  2364. + return true;
  2365. +}
  2366. diff --git a/lldb/source/Expression/DWARFEvaluatorFactory.cpp b/lldb/source/Expression/DWARFEvaluatorFactory.cpp
  2367. new file mode 100644
  2368. index 000000000..c06126412
  2369. --- /dev/null
  2370. +++ b/lldb/source/Expression/DWARFEvaluatorFactory.cpp
  2371. @@ -0,0 +1,57 @@
  2372. +//===-- DWARFEvaluatorFactory.cpp -----------------------------------------===//
  2373. +//
  2374. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  2375. +// See https://llvm.org/LICENSE.txt for license information.
  2376. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  2377. +//
  2378. +//===----------------------------------------------------------------------===//
  2379. +
  2380. +#include "lldb/Expression/DWARFEvaluatorFactory.h"
  2381. +#include "lldb/Expression/DWARFEvaluator.h"
  2382. +
  2383. +#include "lldb/Core/PluginManager.h"
  2384. +#include "lldb/Core/Value.h"
  2385. +#include "lldb/Target/RegisterContext.h"
  2386. +
  2387. +using namespace lldb;
  2388. +using namespace lldb_private;
  2389. +
  2390. +// PluginInterface protocol
  2391. +lldb_private::ConstString DWARFEvaluatorFactory::GetPluginName() {
  2392. + static ConstString g_name("vendor-default");
  2393. + return g_name;
  2394. +}
  2395. +
  2396. +// FindPlugin
  2397. +//
  2398. +// Platforms can register a callback to use when creating DWARF expression
  2399. +// evaluators to allow handling platform-specific DWARF codes.
  2400. +std::unique_ptr<DWARFEvaluatorFactory>
  2401. +DWARFEvaluatorFactory::FindPlugin(Module *module) {
  2402. + std::unique_ptr<DWARFEvaluatorFactory> instance_up;
  2403. + DWARFEvaluatorFactoryCreateInstance create_callback;
  2404. +
  2405. + for (size_t idx = 0;
  2406. + (create_callback =
  2407. + PluginManager::GetDWARFEvaluatorFactoryCreateCallbackAtIndex(
  2408. + idx)) != nullptr;
  2409. + ++idx) {
  2410. + instance_up.reset(create_callback(module));
  2411. +
  2412. + if (instance_up) {
  2413. + return instance_up;
  2414. + }
  2415. + }
  2416. +
  2417. + instance_up.reset(new DWARFEvaluatorFactory());
  2418. + return instance_up;
  2419. +}
  2420. +
  2421. +std::unique_ptr<DWARFEvaluator> DWARFEvaluatorFactory::CreateDWARFEvaluator(
  2422. + const DWARFExpression &dwarf_expression, ExecutionContext *exe_ctx,
  2423. + RegisterContext *reg_ctx, const Value *initial_value_ptr,
  2424. + const Value *object_address_ptr) {
  2425. + return std::make_unique<DWARFEvaluator>(dwarf_expression, exe_ctx, reg_ctx,
  2426. + initial_value_ptr,
  2427. + object_address_ptr);
  2428. +}
  2429. diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
  2430. index a10546c1d..4d13e4642 100644
  2431. --- a/lldb/source/Expression/DWARFExpression.cpp
  2432. +++ b/lldb/source/Expression/DWARFExpression.cpp
  2433. @@ -15,6 +15,8 @@
  2434. #include "lldb/Core/Module.h"
  2435. #include "lldb/Core/Value.h"
  2436. #include "lldb/Core/dwarf.h"
  2437. +#include "lldb/Expression/DWARFEvaluator.h"
  2438. +#include "lldb/Expression/DWARFEvaluatorFactory.h"
  2439. #include "lldb/Utility/DataEncoder.h"
  2440. #include "lldb/Utility/Log.h"
  2441. #include "lldb/Utility/RegisterValue.h"
  2442. @@ -41,8 +43,8 @@
  2443. using namespace lldb;
  2444. using namespace lldb_private;
  2445. -static lldb::addr_t
  2446. -ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu,
  2447. +lldb::addr_t
  2448. +DWARFExpression::ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu,
  2449. uint32_t index) {
  2450. uint32_t index_size = dwarf_cu->GetAddressByteSize();
  2451. dw_offset_t addr_base = dwarf_cu->GetAddrBase();
  2452. @@ -96,7 +98,7 @@ void DWARFExpression::SetLocationListAddresses(addr_t cu_file_addr,
  2453. m_loclist_addresses = LoclistAddresses{cu_file_addr, func_file_addr};
  2454. }
  2455. -int DWARFExpression::GetRegisterKind() { return m_reg_kind; }
  2456. +RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
  2457. void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) {
  2458. m_reg_kind = reg_kind;
  2459. @@ -150,52 +152,6 @@ void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level,
  2460. }
  2461. }
  2462. -static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
  2463. - lldb::RegisterKind reg_kind,
  2464. - uint32_t reg_num, Status *error_ptr,
  2465. - Value &value) {
  2466. - if (reg_ctx == nullptr) {
  2467. - if (error_ptr)
  2468. - error_ptr->SetErrorString("No register context in frame.\n");
  2469. - } else {
  2470. - uint32_t native_reg =
  2471. - reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
  2472. - if (native_reg == LLDB_INVALID_REGNUM) {
  2473. - if (error_ptr)
  2474. - error_ptr->SetErrorStringWithFormat("Unable to convert register "
  2475. - "kind=%u reg_num=%u to a native "
  2476. - "register number.\n",
  2477. - reg_kind, reg_num);
  2478. - } else {
  2479. - const RegisterInfo *reg_info =
  2480. - reg_ctx->GetRegisterInfoAtIndex(native_reg);
  2481. - RegisterValue reg_value;
  2482. - if (reg_ctx->ReadRegister(reg_info, reg_value)) {
  2483. - if (reg_value.GetScalarValue(value.GetScalar())) {
  2484. - value.SetValueType(Value::ValueType::Scalar);
  2485. - value.SetContext(Value::ContextType::RegisterInfo,
  2486. - const_cast<RegisterInfo *>(reg_info));
  2487. - if (error_ptr)
  2488. - error_ptr->Clear();
  2489. - return true;
  2490. - } else {
  2491. - // If we get this error, then we need to implement a value buffer in
  2492. - // the dwarf expression evaluation function...
  2493. - if (error_ptr)
  2494. - error_ptr->SetErrorStringWithFormat(
  2495. - "register %s can't be converted to a scalar value",
  2496. - reg_info->name);
  2497. - }
  2498. - } else {
  2499. - if (error_ptr)
  2500. - error_ptr->SetErrorStringWithFormat("register %s is not available",
  2501. - reg_info->name);
  2502. - }
  2503. - }
  2504. - }
  2505. - return false;
  2506. -}
  2507. -
  2508. /// Return the length in bytes of the set of operands for \p op. No guarantees
  2509. /// are made on the state of \p data after this call.
  2510. static offset_t GetOpcodeDataSize(const DataExtractor &data,
  2511. @@ -955,1719 +911,17 @@ bool DWARFExpression::Evaluate(
  2512. const Value *initial_value_ptr, const Value *object_address_ptr,
  2513. Value &result, Status *error_ptr) {
  2514. - if (opcodes.GetByteSize() == 0) {
  2515. - if (error_ptr)
  2516. - error_ptr->SetErrorString(
  2517. - "no location, value may have been optimized out");
  2518. - return false;
  2519. - }
  2520. - std::vector<Value> stack;
  2521. -
  2522. - Process *process = nullptr;
  2523. - StackFrame *frame = nullptr;
  2524. -
  2525. - if (exe_ctx) {
  2526. - process = exe_ctx->GetProcessPtr();
  2527. - frame = exe_ctx->GetFramePtr();
  2528. - }
  2529. - if (reg_ctx == nullptr && frame)
  2530. - reg_ctx = frame->GetRegisterContext().get();
  2531. -
  2532. - if (initial_value_ptr)
  2533. - stack.push_back(*initial_value_ptr);
  2534. -
  2535. - lldb::offset_t offset = 0;
  2536. - Value tmp;
  2537. - uint32_t reg_num;
  2538. -
  2539. - /// Insertion point for evaluating multi-piece expression.
  2540. - uint64_t op_piece_offset = 0;
  2541. - Value pieces; // Used for DW_OP_piece
  2542. -
  2543. - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
  2544. - // A generic type is "an integral type that has the size of an address and an
  2545. - // unspecified signedness". For now, just use the signedness of the operand.
  2546. - // TODO: Implement a real typed stack, and store the genericness of the value
  2547. - // there.
  2548. - auto to_generic = [&](auto v) {
  2549. - bool is_signed = std::is_signed<decltype(v)>::value;
  2550. - return Scalar(llvm::APSInt(
  2551. - llvm::APInt(8 * opcodes.GetAddressByteSize(), v, is_signed),
  2552. - !is_signed));
  2553. - };
  2554. -
  2555. - // The default kind is a memory location. This is updated by any
  2556. - // operation that changes this, such as DW_OP_stack_value, and reset
  2557. - // by composition operations like DW_OP_piece.
  2558. - LocationDescriptionKind dwarf4_location_description_kind = Memory;
  2559. -
  2560. - while (opcodes.ValidOffset(offset)) {
  2561. - const lldb::offset_t op_offset = offset;
  2562. - const uint8_t op = opcodes.GetU8(&offset);
  2563. -
  2564. - if (log && log->GetVerbose()) {
  2565. - size_t count = stack.size();
  2566. - LLDB_LOGF(log, "Stack before operation has %" PRIu64 " values:",
  2567. - (uint64_t)count);
  2568. - for (size_t i = 0; i < count; ++i) {
  2569. - StreamString new_value;
  2570. - new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
  2571. - stack[i].Dump(&new_value);
  2572. - LLDB_LOGF(log, " %s", new_value.GetData());
  2573. - }
  2574. - LLDB_LOGF(log, "0x%8.8" PRIx64 ": %s", op_offset,
  2575. - DW_OP_value_to_name(op));
  2576. - }
  2577. -
  2578. - switch (op) {
  2579. - // The DW_OP_addr operation has a single operand that encodes a machine
  2580. - // address and whose size is the size of an address on the target machine.
  2581. - case DW_OP_addr:
  2582. - stack.push_back(Scalar(opcodes.GetAddress(&offset)));
  2583. - stack.back().SetValueType(Value::ValueType::FileAddress);
  2584. - // Convert the file address to a load address, so subsequent
  2585. - // DWARF operators can operate on it.
  2586. - if (frame)
  2587. - stack.back().ConvertToLoadAddress(module_sp.get(),
  2588. - frame->CalculateTarget().get());
  2589. - break;
  2590. -
  2591. - // The DW_OP_addr_sect_offset4 is used for any location expressions in
  2592. - // shared libraries that have a location like:
  2593. - // DW_OP_addr(0x1000)
  2594. - // If this address resides in a shared library, then this virtual address
  2595. - // won't make sense when it is evaluated in the context of a running
  2596. - // process where shared libraries have been slid. To account for this, this
  2597. - // new address type where we can store the section pointer and a 4 byte
  2598. - // offset.
  2599. - // case DW_OP_addr_sect_offset4:
  2600. - // {
  2601. - // result_type = eResultTypeFileAddress;
  2602. - // lldb::Section *sect = (lldb::Section
  2603. - // *)opcodes.GetMaxU64(&offset, sizeof(void *));
  2604. - // lldb::addr_t sect_offset = opcodes.GetU32(&offset);
  2605. - //
  2606. - // Address so_addr (sect, sect_offset);
  2607. - // lldb::addr_t load_addr = so_addr.GetLoadAddress();
  2608. - // if (load_addr != LLDB_INVALID_ADDRESS)
  2609. - // {
  2610. - // // We successfully resolve a file address to a load
  2611. - // // address.
  2612. - // stack.push_back(load_addr);
  2613. - // break;
  2614. - // }
  2615. - // else
  2616. - // {
  2617. - // // We were able
  2618. - // if (error_ptr)
  2619. - // error_ptr->SetErrorStringWithFormat ("Section %s in
  2620. - // %s is not currently loaded.\n",
  2621. - // sect->GetName().AsCString(),
  2622. - // sect->GetModule()->GetFileSpec().GetFilename().AsCString());
  2623. - // return false;
  2624. - // }
  2625. - // }
  2626. - // break;
  2627. -
  2628. - // OPCODE: DW_OP_deref
  2629. - // OPERANDS: none
  2630. - // DESCRIPTION: Pops the top stack entry and treats it as an address.
  2631. - // The value retrieved from that address is pushed. The size of the data
  2632. - // retrieved from the dereferenced address is the size of an address on the
  2633. - // target machine.
  2634. - case DW_OP_deref: {
  2635. - if (stack.empty()) {
  2636. - if (error_ptr)
  2637. - error_ptr->SetErrorString("Expression stack empty for DW_OP_deref.");
  2638. - return false;
  2639. - }
  2640. - Value::ValueType value_type = stack.back().GetValueType();
  2641. - switch (value_type) {
  2642. - case Value::ValueType::HostAddress: {
  2643. - void *src = (void *)stack.back().GetScalar().ULongLong();
  2644. - intptr_t ptr;
  2645. - ::memcpy(&ptr, src, sizeof(void *));
  2646. - stack.back().GetScalar() = ptr;
  2647. - stack.back().ClearContext();
  2648. - } break;
  2649. - case Value::ValueType::FileAddress: {
  2650. - auto file_addr = stack.back().GetScalar().ULongLong(
  2651. - LLDB_INVALID_ADDRESS);
  2652. - if (!module_sp) {
  2653. - if (error_ptr)
  2654. - error_ptr->SetErrorString(
  2655. - "need module to resolve file address for DW_OP_deref");
  2656. - return false;
  2657. - }
  2658. - Address so_addr;
  2659. - if (!module_sp->ResolveFileAddress(file_addr, so_addr)) {
  2660. - if (error_ptr)
  2661. - error_ptr->SetErrorString(
  2662. - "failed to resolve file address in module");
  2663. - return false;
  2664. - }
  2665. - addr_t load_Addr = so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());
  2666. - if (load_Addr == LLDB_INVALID_ADDRESS) {
  2667. - if (error_ptr)
  2668. - error_ptr->SetErrorString("failed to resolve load address");
  2669. - return false;
  2670. - }
  2671. - stack.back().GetScalar() = load_Addr;
  2672. - // Fall through to load address promotion code below.
  2673. - } LLVM_FALLTHROUGH;
  2674. - case Value::ValueType::Scalar:
  2675. - // Promote Scalar to LoadAddress and fall through.
  2676. - stack.back().SetValueType(Value::ValueType::LoadAddress);
  2677. - LLVM_FALLTHROUGH;
  2678. - case Value::ValueType::LoadAddress:
  2679. - if (exe_ctx) {
  2680. - if (process) {
  2681. - lldb::addr_t pointer_addr =
  2682. - stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
  2683. - Status error;
  2684. - lldb::addr_t pointer_value =
  2685. - process->ReadPointerFromMemory(pointer_addr, error);
  2686. - if (pointer_value != LLDB_INVALID_ADDRESS) {
  2687. - if (ABISP abi_sp = process->GetABI())
  2688. - pointer_value = abi_sp->FixCodeAddress(pointer_value);
  2689. - stack.back().GetScalar() = pointer_value;
  2690. - stack.back().ClearContext();
  2691. - } else {
  2692. - if (error_ptr)
  2693. - error_ptr->SetErrorStringWithFormat(
  2694. - "Failed to dereference pointer from 0x%" PRIx64
  2695. - " for DW_OP_deref: %s\n",
  2696. - pointer_addr, error.AsCString());
  2697. - return false;
  2698. - }
  2699. - } else {
  2700. - if (error_ptr)
  2701. - error_ptr->SetErrorString("NULL process for DW_OP_deref.\n");
  2702. - return false;
  2703. - }
  2704. - } else {
  2705. - if (error_ptr)
  2706. - error_ptr->SetErrorString(
  2707. - "NULL execution context for DW_OP_deref.\n");
  2708. - return false;
  2709. - }
  2710. - break;
  2711. -
  2712. - case Value::ValueType::Invalid:
  2713. - if (error_ptr)
  2714. - error_ptr->SetErrorString("Invalid value type for DW_OP_deref.\n");
  2715. - return false;
  2716. - }
  2717. -
  2718. - } break;
  2719. -
  2720. - // OPCODE: DW_OP_deref_size
  2721. - // OPERANDS: 1
  2722. - // 1 - uint8_t that specifies the size of the data to dereference.
  2723. - // DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top
  2724. - // stack entry and treats it as an address. The value retrieved from that
  2725. - // address is pushed. In the DW_OP_deref_size operation, however, the size
  2726. - // in bytes of the data retrieved from the dereferenced address is
  2727. - // specified by the single operand. This operand is a 1-byte unsigned
  2728. - // integral constant whose value may not be larger than the size of an
  2729. - // address on the target machine. The data retrieved is zero extended to
  2730. - // the size of an address on the target machine before being pushed on the
  2731. - // expression stack.
  2732. - case DW_OP_deref_size: {
  2733. - if (stack.empty()) {
  2734. - if (error_ptr)
  2735. - error_ptr->SetErrorString(
  2736. - "Expression stack empty for DW_OP_deref_size.");
  2737. - return false;
  2738. - }
  2739. - uint8_t size = opcodes.GetU8(&offset);
  2740. - Value::ValueType value_type = stack.back().GetValueType();
  2741. - switch (value_type) {
  2742. - case Value::ValueType::HostAddress: {
  2743. - void *src = (void *)stack.back().GetScalar().ULongLong();
  2744. - intptr_t ptr;
  2745. - ::memcpy(&ptr, src, sizeof(void *));
  2746. - // I can't decide whether the size operand should apply to the bytes in
  2747. - // their
  2748. - // lldb-host endianness or the target endianness.. I doubt this'll ever
  2749. - // come up but I'll opt for assuming big endian regardless.
  2750. - switch (size) {
  2751. - case 1:
  2752. - ptr = ptr & 0xff;
  2753. - break;
  2754. - case 2:
  2755. - ptr = ptr & 0xffff;
  2756. - break;
  2757. - case 3:
  2758. - ptr = ptr & 0xffffff;
  2759. - break;
  2760. - case 4:
  2761. - ptr = ptr & 0xffffffff;
  2762. - break;
  2763. - // the casts are added to work around the case where intptr_t is a 32
  2764. - // bit quantity;
  2765. - // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this
  2766. - // program.
  2767. - case 5:
  2768. - ptr = (intptr_t)ptr & 0xffffffffffULL;
  2769. - break;
  2770. - case 6:
  2771. - ptr = (intptr_t)ptr & 0xffffffffffffULL;
  2772. - break;
  2773. - case 7:
  2774. - ptr = (intptr_t)ptr & 0xffffffffffffffULL;
  2775. - break;
  2776. - default:
  2777. - break;
  2778. - }
  2779. - stack.back().GetScalar() = ptr;
  2780. - stack.back().ClearContext();
  2781. - } break;
  2782. - case Value::ValueType::Scalar:
  2783. - case Value::ValueType::LoadAddress:
  2784. - if (exe_ctx) {
  2785. - if (process) {
  2786. - lldb::addr_t pointer_addr =
  2787. - stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
  2788. - uint8_t addr_bytes[sizeof(lldb::addr_t)];
  2789. - Status error;
  2790. - if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) ==
  2791. - size) {
  2792. - DataExtractor addr_data(addr_bytes, sizeof(addr_bytes),
  2793. - process->GetByteOrder(), size);
  2794. - lldb::offset_t addr_data_offset = 0;
  2795. - switch (size) {
  2796. - case 1:
  2797. - stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset);
  2798. - break;
  2799. - case 2:
  2800. - stack.back().GetScalar() = addr_data.GetU16(&addr_data_offset);
  2801. - break;
  2802. - case 4:
  2803. - stack.back().GetScalar() = addr_data.GetU32(&addr_data_offset);
  2804. - break;
  2805. - case 8:
  2806. - stack.back().GetScalar() = addr_data.GetU64(&addr_data_offset);
  2807. - break;
  2808. - default:
  2809. - stack.back().GetScalar() =
  2810. - addr_data.GetAddress(&addr_data_offset);
  2811. - }
  2812. - stack.back().ClearContext();
  2813. - } else {
  2814. - if (error_ptr)
  2815. - error_ptr->SetErrorStringWithFormat(
  2816. - "Failed to dereference pointer from 0x%" PRIx64
  2817. - " for DW_OP_deref: %s\n",
  2818. - pointer_addr, error.AsCString());
  2819. - return false;
  2820. - }
  2821. - } else {
  2822. - if (error_ptr)
  2823. - error_ptr->SetErrorString("NULL process for DW_OP_deref_size.\n");
  2824. - return false;
  2825. - }
  2826. - } else {
  2827. - if (error_ptr)
  2828. - error_ptr->SetErrorString(
  2829. - "NULL execution context for DW_OP_deref_size.\n");
  2830. - return false;
  2831. - }
  2832. - break;
  2833. -
  2834. - case Value::ValueType::FileAddress:
  2835. - case Value::ValueType::Invalid:
  2836. - if (error_ptr)
  2837. - error_ptr->SetErrorString("Invalid value for DW_OP_deref_size.\n");
  2838. - return false;
  2839. - }
  2840. -
  2841. - } break;
  2842. -
  2843. - // OPCODE: DW_OP_xderef_size
  2844. - // OPERANDS: 1
  2845. - // 1 - uint8_t that specifies the size of the data to dereference.
  2846. - // DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at
  2847. - // the top of the stack is treated as an address. The second stack entry is
  2848. - // treated as an "address space identifier" for those architectures that
  2849. - // support multiple address spaces. The top two stack elements are popped,
  2850. - // a data item is retrieved through an implementation-defined address
  2851. - // calculation and pushed as the new stack top. In the DW_OP_xderef_size
  2852. - // operation, however, the size in bytes of the data retrieved from the
  2853. - // dereferenced address is specified by the single operand. This operand is
  2854. - // a 1-byte unsigned integral constant whose value may not be larger than
  2855. - // the size of an address on the target machine. The data retrieved is zero
  2856. - // extended to the size of an address on the target machine before being
  2857. - // pushed on the expression stack.
  2858. - case DW_OP_xderef_size:
  2859. - if (error_ptr)
  2860. - error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef_size.");
  2861. - return false;
  2862. - // OPCODE: DW_OP_xderef
  2863. - // OPERANDS: none
  2864. - // DESCRIPTION: Provides an extended dereference mechanism. The entry at
  2865. - // the top of the stack is treated as an address. The second stack entry is
  2866. - // treated as an "address space identifier" for those architectures that
  2867. - // support multiple address spaces. The top two stack elements are popped,
  2868. - // a data item is retrieved through an implementation-defined address
  2869. - // calculation and pushed as the new stack top. The size of the data
  2870. - // retrieved from the dereferenced address is the size of an address on the
  2871. - // target machine.
  2872. - case DW_OP_xderef:
  2873. - if (error_ptr)
  2874. - error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef.");
  2875. - return false;
  2876. -
  2877. - // All DW_OP_constXXX opcodes have a single operand as noted below:
  2878. - //
  2879. - // Opcode Operand 1
  2880. - // DW_OP_const1u 1-byte unsigned integer constant
  2881. - // DW_OP_const1s 1-byte signed integer constant
  2882. - // DW_OP_const2u 2-byte unsigned integer constant
  2883. - // DW_OP_const2s 2-byte signed integer constant
  2884. - // DW_OP_const4u 4-byte unsigned integer constant
  2885. - // DW_OP_const4s 4-byte signed integer constant
  2886. - // DW_OP_const8u 8-byte unsigned integer constant
  2887. - // DW_OP_const8s 8-byte signed integer constant
  2888. - // DW_OP_constu unsigned LEB128 integer constant
  2889. - // DW_OP_consts signed LEB128 integer constant
  2890. - case DW_OP_const1u:
  2891. - stack.push_back(to_generic(opcodes.GetU8(&offset)));
  2892. - break;
  2893. - case DW_OP_const1s:
  2894. - stack.push_back(to_generic((int8_t)opcodes.GetU8(&offset)));
  2895. - break;
  2896. - case DW_OP_const2u:
  2897. - stack.push_back(to_generic(opcodes.GetU16(&offset)));
  2898. - break;
  2899. - case DW_OP_const2s:
  2900. - stack.push_back(to_generic((int16_t)opcodes.GetU16(&offset)));
  2901. - break;
  2902. - case DW_OP_const4u:
  2903. - stack.push_back(to_generic(opcodes.GetU32(&offset)));
  2904. - break;
  2905. - case DW_OP_const4s:
  2906. - stack.push_back(to_generic((int32_t)opcodes.GetU32(&offset)));
  2907. - break;
  2908. - case DW_OP_const8u:
  2909. - stack.push_back(to_generic(opcodes.GetU64(&offset)));
  2910. - break;
  2911. - case DW_OP_const8s:
  2912. - stack.push_back(to_generic((int64_t)opcodes.GetU64(&offset)));
  2913. - break;
  2914. - // These should also use to_generic, but we can't do that due to a
  2915. - // producer-side bug in llvm. See llvm.org/pr48087.
  2916. - case DW_OP_constu:
  2917. - stack.push_back(Scalar(opcodes.GetULEB128(&offset)));
  2918. - break;
  2919. - case DW_OP_consts:
  2920. - stack.push_back(Scalar(opcodes.GetSLEB128(&offset)));
  2921. - break;
  2922. -
  2923. - // OPCODE: DW_OP_dup
  2924. - // OPERANDS: none
  2925. - // DESCRIPTION: duplicates the value at the top of the stack
  2926. - case DW_OP_dup:
  2927. - if (stack.empty()) {
  2928. - if (error_ptr)
  2929. - error_ptr->SetErrorString("Expression stack empty for DW_OP_dup.");
  2930. - return false;
  2931. - } else
  2932. - stack.push_back(stack.back());
  2933. - break;
  2934. -
  2935. - // OPCODE: DW_OP_drop
  2936. - // OPERANDS: none
  2937. - // DESCRIPTION: pops the value at the top of the stack
  2938. - case DW_OP_drop:
  2939. - if (stack.empty()) {
  2940. - if (error_ptr)
  2941. - error_ptr->SetErrorString("Expression stack empty for DW_OP_drop.");
  2942. - return false;
  2943. - } else
  2944. - stack.pop_back();
  2945. - break;
  2946. -
  2947. - // OPCODE: DW_OP_over
  2948. - // OPERANDS: none
  2949. - // DESCRIPTION: Duplicates the entry currently second in the stack at
  2950. - // the top of the stack.
  2951. - case DW_OP_over:
  2952. - if (stack.size() < 2) {
  2953. - if (error_ptr)
  2954. - error_ptr->SetErrorString(
  2955. - "Expression stack needs at least 2 items for DW_OP_over.");
  2956. - return false;
  2957. - } else
  2958. - stack.push_back(stack[stack.size() - 2]);
  2959. - break;
  2960. -
  2961. - // OPCODE: DW_OP_pick
  2962. - // OPERANDS: uint8_t index into the current stack
  2963. - // DESCRIPTION: The stack entry with the specified index (0 through 255,
  2964. - // inclusive) is pushed on the stack
  2965. - case DW_OP_pick: {
  2966. - uint8_t pick_idx = opcodes.GetU8(&offset);
  2967. - if (pick_idx < stack.size())
  2968. - stack.push_back(stack[stack.size() - 1 - pick_idx]);
  2969. - else {
  2970. - if (error_ptr)
  2971. - error_ptr->SetErrorStringWithFormat(
  2972. - "Index %u out of range for DW_OP_pick.\n", pick_idx);
  2973. - return false;
  2974. - }
  2975. - } break;
  2976. -
  2977. - // OPCODE: DW_OP_swap
  2978. - // OPERANDS: none
  2979. - // DESCRIPTION: swaps the top two stack entries. The entry at the top
  2980. - // of the stack becomes the second stack entry, and the second entry
  2981. - // becomes the top of the stack
  2982. - case DW_OP_swap:
  2983. - if (stack.size() < 2) {
  2984. - if (error_ptr)
  2985. - error_ptr->SetErrorString(
  2986. - "Expression stack needs at least 2 items for DW_OP_swap.");
  2987. - return false;
  2988. - } else {
  2989. - tmp = stack.back();
  2990. - stack.back() = stack[stack.size() - 2];
  2991. - stack[stack.size() - 2] = tmp;
  2992. - }
  2993. - break;
  2994. -
  2995. - // OPCODE: DW_OP_rot
  2996. - // OPERANDS: none
  2997. - // DESCRIPTION: Rotates the first three stack entries. The entry at
  2998. - // the top of the stack becomes the third stack entry, the second entry
  2999. - // becomes the top of the stack, and the third entry becomes the second
  3000. - // entry.
  3001. - case DW_OP_rot:
  3002. - if (stack.size() < 3) {
  3003. - if (error_ptr)
  3004. - error_ptr->SetErrorString(
  3005. - "Expression stack needs at least 3 items for DW_OP_rot.");
  3006. - return false;
  3007. - } else {
  3008. - size_t last_idx = stack.size() - 1;
  3009. - Value old_top = stack[last_idx];
  3010. - stack[last_idx] = stack[last_idx - 1];
  3011. - stack[last_idx - 1] = stack[last_idx - 2];
  3012. - stack[last_idx - 2] = old_top;
  3013. - }
  3014. - break;
  3015. -
  3016. - // OPCODE: DW_OP_abs
  3017. - // OPERANDS: none
  3018. - // DESCRIPTION: pops the top stack entry, interprets it as a signed
  3019. - // value and pushes its absolute value. If the absolute value can not be
  3020. - // represented, the result is undefined.
  3021. - case DW_OP_abs:
  3022. - if (stack.empty()) {
  3023. - if (error_ptr)
  3024. - error_ptr->SetErrorString(
  3025. - "Expression stack needs at least 1 item for DW_OP_abs.");
  3026. - return false;
  3027. - } else if (!stack.back().ResolveValue(exe_ctx).AbsoluteValue()) {
  3028. - if (error_ptr)
  3029. - error_ptr->SetErrorString(
  3030. - "Failed to take the absolute value of the first stack item.");
  3031. - return false;
  3032. - }
  3033. - break;
  3034. -
  3035. - // OPCODE: DW_OP_and
  3036. - // OPERANDS: none
  3037. - // DESCRIPTION: pops the top two stack values, performs a bitwise and
  3038. - // operation on the two, and pushes the result.
  3039. - case DW_OP_and:
  3040. - if (stack.size() < 2) {
  3041. - if (error_ptr)
  3042. - error_ptr->SetErrorString(
  3043. - "Expression stack needs at least 2 items for DW_OP_and.");
  3044. - return false;
  3045. - } else {
  3046. - tmp = stack.back();
  3047. - stack.pop_back();
  3048. - stack.back().ResolveValue(exe_ctx) =
  3049. - stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx);
  3050. - }
  3051. - break;
  3052. -
  3053. - // OPCODE: DW_OP_div
  3054. - // OPERANDS: none
  3055. - // DESCRIPTION: pops the top two stack values, divides the former second
  3056. - // entry by the former top of the stack using signed division, and pushes
  3057. - // the result.
  3058. - case DW_OP_div:
  3059. - if (stack.size() < 2) {
  3060. - if (error_ptr)
  3061. - error_ptr->SetErrorString(
  3062. - "Expression stack needs at least 2 items for DW_OP_div.");
  3063. - return false;
  3064. - } else {
  3065. - tmp = stack.back();
  3066. - if (tmp.ResolveValue(exe_ctx).IsZero()) {
  3067. - if (error_ptr)
  3068. - error_ptr->SetErrorString("Divide by zero.");
  3069. - return false;
  3070. - } else {
  3071. - stack.pop_back();
  3072. - stack.back() =
  3073. - stack.back().ResolveValue(exe_ctx) / tmp.ResolveValue(exe_ctx);
  3074. - if (!stack.back().ResolveValue(exe_ctx).IsValid()) {
  3075. - if (error_ptr)
  3076. - error_ptr->SetErrorString("Divide failed.");
  3077. - return false;
  3078. - }
  3079. - }
  3080. - }
  3081. - break;
  3082. -
  3083. - // OPCODE: DW_OP_minus
  3084. - // OPERANDS: none
  3085. - // DESCRIPTION: pops the top two stack values, subtracts the former top
  3086. - // of the stack from the former second entry, and pushes the result.
  3087. - case DW_OP_minus:
  3088. - if (stack.size() < 2) {
  3089. - if (error_ptr)
  3090. - error_ptr->SetErrorString(
  3091. - "Expression stack needs at least 2 items for DW_OP_minus.");
  3092. - return false;
  3093. - } else {
  3094. - tmp = stack.back();
  3095. - stack.pop_back();
  3096. - stack.back().ResolveValue(exe_ctx) =
  3097. - stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx);
  3098. - }
  3099. - break;
  3100. -
  3101. - // OPCODE: DW_OP_mod
  3102. - // OPERANDS: none
  3103. - // DESCRIPTION: pops the top two stack values and pushes the result of
  3104. - // the calculation: former second stack entry modulo the former top of the
  3105. - // stack.
  3106. - case DW_OP_mod:
  3107. - if (stack.size() < 2) {
  3108. - if (error_ptr)
  3109. - error_ptr->SetErrorString(
  3110. - "Expression stack needs at least 2 items for DW_OP_mod.");
  3111. - return false;
  3112. - } else {
  3113. - tmp = stack.back();
  3114. - stack.pop_back();
  3115. - stack.back().ResolveValue(exe_ctx) =
  3116. - stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx);
  3117. - }
  3118. - break;
  3119. -
  3120. - // OPCODE: DW_OP_mul
  3121. - // OPERANDS: none
  3122. - // DESCRIPTION: pops the top two stack entries, multiplies them
  3123. - // together, and pushes the result.
  3124. - case DW_OP_mul:
  3125. - if (stack.size() < 2) {
  3126. - if (error_ptr)
  3127. - error_ptr->SetErrorString(
  3128. - "Expression stack needs at least 2 items for DW_OP_mul.");
  3129. - return false;
  3130. - } else {
  3131. - tmp = stack.back();
  3132. - stack.pop_back();
  3133. - stack.back().ResolveValue(exe_ctx) =
  3134. - stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx);
  3135. - }
  3136. - break;
  3137. -
  3138. - // OPCODE: DW_OP_neg
  3139. - // OPERANDS: none
  3140. - // DESCRIPTION: pops the top stack entry, and pushes its negation.
  3141. - case DW_OP_neg:
  3142. - if (stack.empty()) {
  3143. - if (error_ptr)
  3144. - error_ptr->SetErrorString(
  3145. - "Expression stack needs at least 1 item for DW_OP_neg.");
  3146. - return false;
  3147. - } else {
  3148. - if (!stack.back().ResolveValue(exe_ctx).UnaryNegate()) {
  3149. - if (error_ptr)
  3150. - error_ptr->SetErrorString("Unary negate failed.");
  3151. - return false;
  3152. - }
  3153. - }
  3154. - break;
  3155. -
  3156. - // OPCODE: DW_OP_not
  3157. - // OPERANDS: none
  3158. - // DESCRIPTION: pops the top stack entry, and pushes its bitwise
  3159. - // complement
  3160. - case DW_OP_not:
  3161. - if (stack.empty()) {
  3162. - if (error_ptr)
  3163. - error_ptr->SetErrorString(
  3164. - "Expression stack needs at least 1 item for DW_OP_not.");
  3165. - return false;
  3166. - } else {
  3167. - if (!stack.back().ResolveValue(exe_ctx).OnesComplement()) {
  3168. - if (error_ptr)
  3169. - error_ptr->SetErrorString("Logical NOT failed.");
  3170. - return false;
  3171. - }
  3172. - }
  3173. - break;
  3174. -
  3175. - // OPCODE: DW_OP_or
  3176. - // OPERANDS: none
  3177. - // DESCRIPTION: pops the top two stack entries, performs a bitwise or
  3178. - // operation on the two, and pushes the result.
  3179. - case DW_OP_or:
  3180. - if (stack.size() < 2) {
  3181. - if (error_ptr)
  3182. - error_ptr->SetErrorString(
  3183. - "Expression stack needs at least 2 items for DW_OP_or.");
  3184. - return false;
  3185. - } else {
  3186. - tmp = stack.back();
  3187. - stack.pop_back();
  3188. - stack.back().ResolveValue(exe_ctx) =
  3189. - stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx);
  3190. - }
  3191. - break;
  3192. -
  3193. - // OPCODE: DW_OP_plus
  3194. - // OPERANDS: none
  3195. - // DESCRIPTION: pops the top two stack entries, adds them together, and
  3196. - // pushes the result.
  3197. - case DW_OP_plus:
  3198. - if (stack.size() < 2) {
  3199. - if (error_ptr)
  3200. - error_ptr->SetErrorString(
  3201. - "Expression stack needs at least 2 items for DW_OP_plus.");
  3202. - return false;
  3203. - } else {
  3204. - tmp = stack.back();
  3205. - stack.pop_back();
  3206. - stack.back().GetScalar() += tmp.GetScalar();
  3207. - }
  3208. - break;
  3209. -
  3210. - // OPCODE: DW_OP_plus_uconst
  3211. - // OPERANDS: none
  3212. - // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128
  3213. - // constant operand and pushes the result.
  3214. - case DW_OP_plus_uconst:
  3215. - if (stack.empty()) {
  3216. - if (error_ptr)
  3217. - error_ptr->SetErrorString(
  3218. - "Expression stack needs at least 1 item for DW_OP_plus_uconst.");
  3219. - return false;
  3220. - } else {
  3221. - const uint64_t uconst_value = opcodes.GetULEB128(&offset);
  3222. - // Implicit conversion from a UINT to a Scalar...
  3223. - stack.back().GetScalar() += uconst_value;
  3224. - if (!stack.back().GetScalar().IsValid()) {
  3225. - if (error_ptr)
  3226. - error_ptr->SetErrorString("DW_OP_plus_uconst failed.");
  3227. - return false;
  3228. - }
  3229. - }
  3230. - break;
  3231. -
  3232. - // OPCODE: DW_OP_shl
  3233. - // OPERANDS: none
  3234. - // DESCRIPTION: pops the top two stack entries, shifts the former
  3235. - // second entry left by the number of bits specified by the former top of
  3236. - // the stack, and pushes the result.
  3237. - case DW_OP_shl:
  3238. - if (stack.size() < 2) {
  3239. - if (error_ptr)
  3240. - error_ptr->SetErrorString(
  3241. - "Expression stack needs at least 2 items for DW_OP_shl.");
  3242. - return false;
  3243. - } else {
  3244. - tmp = stack.back();
  3245. - stack.pop_back();
  3246. - stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx);
  3247. - }
  3248. - break;
  3249. -
  3250. - // OPCODE: DW_OP_shr
  3251. - // OPERANDS: none
  3252. - // DESCRIPTION: pops the top two stack entries, shifts the former second
  3253. - // entry right logically (filling with zero bits) by the number of bits
  3254. - // specified by the former top of the stack, and pushes the result.
  3255. - case DW_OP_shr:
  3256. - if (stack.size() < 2) {
  3257. - if (error_ptr)
  3258. - error_ptr->SetErrorString(
  3259. - "Expression stack needs at least 2 items for DW_OP_shr.");
  3260. - return false;
  3261. - } else {
  3262. - tmp = stack.back();
  3263. - stack.pop_back();
  3264. - if (!stack.back().ResolveValue(exe_ctx).ShiftRightLogical(
  3265. - tmp.ResolveValue(exe_ctx))) {
  3266. - if (error_ptr)
  3267. - error_ptr->SetErrorString("DW_OP_shr failed.");
  3268. - return false;
  3269. - }
  3270. - }
  3271. - break;
  3272. -
  3273. - // OPCODE: DW_OP_shra
  3274. - // OPERANDS: none
  3275. - // DESCRIPTION: pops the top two stack entries, shifts the former second
  3276. - // entry right arithmetically (divide the magnitude by 2, keep the same
  3277. - // sign for the result) by the number of bits specified by the former top
  3278. - // of the stack, and pushes the result.
  3279. - case DW_OP_shra:
  3280. - if (stack.size() < 2) {
  3281. - if (error_ptr)
  3282. - error_ptr->SetErrorString(
  3283. - "Expression stack needs at least 2 items for DW_OP_shra.");
  3284. - return false;
  3285. - } else {
  3286. - tmp = stack.back();
  3287. - stack.pop_back();
  3288. - stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx);
  3289. - }
  3290. - break;
  3291. -
  3292. - // OPCODE: DW_OP_xor
  3293. - // OPERANDS: none
  3294. - // DESCRIPTION: pops the top two stack entries, performs the bitwise
  3295. - // exclusive-or operation on the two, and pushes the result.
  3296. - case DW_OP_xor:
  3297. - if (stack.size() < 2) {
  3298. - if (error_ptr)
  3299. - error_ptr->SetErrorString(
  3300. - "Expression stack needs at least 2 items for DW_OP_xor.");
  3301. - return false;
  3302. - } else {
  3303. - tmp = stack.back();
  3304. - stack.pop_back();
  3305. - stack.back().ResolveValue(exe_ctx) =
  3306. - stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx);
  3307. - }
  3308. - break;
  3309. -
  3310. - // OPCODE: DW_OP_skip
  3311. - // OPERANDS: int16_t
  3312. - // DESCRIPTION: An unconditional branch. Its single operand is a 2-byte
  3313. - // signed integer constant. The 2-byte constant is the number of bytes of
  3314. - // the DWARF expression to skip forward or backward from the current
  3315. - // operation, beginning after the 2-byte constant.
  3316. - case DW_OP_skip: {
  3317. - int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
  3318. - lldb::offset_t new_offset = offset + skip_offset;
  3319. - if (opcodes.ValidOffset(new_offset))
  3320. - offset = new_offset;
  3321. - else {
  3322. - if (error_ptr)
  3323. - error_ptr->SetErrorString("Invalid opcode offset in DW_OP_skip.");
  3324. - return false;
  3325. - }
  3326. - } break;
  3327. -
  3328. - // OPCODE: DW_OP_bra
  3329. - // OPERANDS: int16_t
  3330. - // DESCRIPTION: A conditional branch. Its single operand is a 2-byte
  3331. - // signed integer constant. This operation pops the top of stack. If the
  3332. - // value popped is not the constant 0, the 2-byte constant operand is the
  3333. - // number of bytes of the DWARF expression to skip forward or backward from
  3334. - // the current operation, beginning after the 2-byte constant.
  3335. - case DW_OP_bra:
  3336. - if (stack.empty()) {
  3337. - if (error_ptr)
  3338. - error_ptr->SetErrorString(
  3339. - "Expression stack needs at least 1 item for DW_OP_bra.");
  3340. - return false;
  3341. - } else {
  3342. - tmp = stack.back();
  3343. - stack.pop_back();
  3344. - int16_t bra_offset = (int16_t)opcodes.GetU16(&offset);
  3345. - Scalar zero(0);
  3346. - if (tmp.ResolveValue(exe_ctx) != zero) {
  3347. - lldb::offset_t new_offset = offset + bra_offset;
  3348. - if (opcodes.ValidOffset(new_offset))
  3349. - offset = new_offset;
  3350. - else {
  3351. - if (error_ptr)
  3352. - error_ptr->SetErrorString("Invalid opcode offset in DW_OP_bra.");
  3353. - return false;
  3354. - }
  3355. - }
  3356. - }
  3357. - break;
  3358. -
  3359. - // OPCODE: DW_OP_eq
  3360. - // OPERANDS: none
  3361. - // DESCRIPTION: pops the top two stack values, compares using the
  3362. - // equals (==) operator.
  3363. - // STACK RESULT: push the constant value 1 onto the stack if the result
  3364. - // of the operation is true or the constant value 0 if the result of the
  3365. - // operation is false.
  3366. - case DW_OP_eq:
  3367. - if (stack.size() < 2) {
  3368. - if (error_ptr)
  3369. - error_ptr->SetErrorString(
  3370. - "Expression stack needs at least 2 items for DW_OP_eq.");
  3371. - return false;
  3372. - } else {
  3373. - tmp = stack.back();
  3374. - stack.pop_back();
  3375. - stack.back().ResolveValue(exe_ctx) =
  3376. - stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx);
  3377. - }
  3378. - break;
  3379. -
  3380. - // OPCODE: DW_OP_ge
  3381. - // OPERANDS: none
  3382. - // DESCRIPTION: pops the top two stack values, compares using the
  3383. - // greater than or equal to (>=) operator.
  3384. - // STACK RESULT: push the constant value 1 onto the stack if the result
  3385. - // of the operation is true or the constant value 0 if the result of the
  3386. - // operation is false.
  3387. - case DW_OP_ge:
  3388. - if (stack.size() < 2) {
  3389. - if (error_ptr)
  3390. - error_ptr->SetErrorString(
  3391. - "Expression stack needs at least 2 items for DW_OP_ge.");
  3392. - return false;
  3393. - } else {
  3394. - tmp = stack.back();
  3395. - stack.pop_back();
  3396. - stack.back().ResolveValue(exe_ctx) =
  3397. - stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx);
  3398. - }
  3399. - break;
  3400. -
  3401. - // OPCODE: DW_OP_gt
  3402. - // OPERANDS: none
  3403. - // DESCRIPTION: pops the top two stack values, compares using the
  3404. - // greater than (>) operator.
  3405. - // STACK RESULT: push the constant value 1 onto the stack if the result
  3406. - // of the operation is true or the constant value 0 if the result of the
  3407. - // operation is false.
  3408. - case DW_OP_gt:
  3409. - if (stack.size() < 2) {
  3410. - if (error_ptr)
  3411. - error_ptr->SetErrorString(
  3412. - "Expression stack needs at least 2 items for DW_OP_gt.");
  3413. - return false;
  3414. - } else {
  3415. - tmp = stack.back();
  3416. - stack.pop_back();
  3417. - stack.back().ResolveValue(exe_ctx) =
  3418. - stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx);
  3419. - }
  3420. - break;
  3421. -
  3422. - // OPCODE: DW_OP_le
  3423. - // OPERANDS: none
  3424. - // DESCRIPTION: pops the top two stack values, compares using the
  3425. - // less than or equal to (<=) operator.
  3426. - // STACK RESULT: push the constant value 1 onto the stack if the result
  3427. - // of the operation is true or the constant value 0 if the result of the
  3428. - // operation is false.
  3429. - case DW_OP_le:
  3430. - if (stack.size() < 2) {
  3431. - if (error_ptr)
  3432. - error_ptr->SetErrorString(
  3433. - "Expression stack needs at least 2 items for DW_OP_le.");
  3434. - return false;
  3435. - } else {
  3436. - tmp = stack.back();
  3437. - stack.pop_back();
  3438. - stack.back().ResolveValue(exe_ctx) =
  3439. - stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx);
  3440. - }
  3441. - break;
  3442. -
  3443. - // OPCODE: DW_OP_lt
  3444. - // OPERANDS: none
  3445. - // DESCRIPTION: pops the top two stack values, compares using the
  3446. - // less than (<) operator.
  3447. - // STACK RESULT: push the constant value 1 onto the stack if the result
  3448. - // of the operation is true or the constant value 0 if the result of the
  3449. - // operation is false.
  3450. - case DW_OP_lt:
  3451. - if (stack.size() < 2) {
  3452. - if (error_ptr)
  3453. - error_ptr->SetErrorString(
  3454. - "Expression stack needs at least 2 items for DW_OP_lt.");
  3455. - return false;
  3456. - } else {
  3457. - tmp = stack.back();
  3458. - stack.pop_back();
  3459. - stack.back().ResolveValue(exe_ctx) =
  3460. - stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx);
  3461. - }
  3462. - break;
  3463. -
  3464. - // OPCODE: DW_OP_ne
  3465. - // OPERANDS: none
  3466. - // DESCRIPTION: pops the top two stack values, compares using the
  3467. - // not equal (!=) operator.
  3468. - // STACK RESULT: push the constant value 1 onto the stack if the result
  3469. - // of the operation is true or the constant value 0 if the result of the
  3470. - // operation is false.
  3471. - case DW_OP_ne:
  3472. - if (stack.size() < 2) {
  3473. - if (error_ptr)
  3474. - error_ptr->SetErrorString(
  3475. - "Expression stack needs at least 2 items for DW_OP_ne.");
  3476. - return false;
  3477. - } else {
  3478. - tmp = stack.back();
  3479. - stack.pop_back();
  3480. - stack.back().ResolveValue(exe_ctx) =
  3481. - stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx);
  3482. - }
  3483. - break;
  3484. -
  3485. - // OPCODE: DW_OP_litn
  3486. - // OPERANDS: none
  3487. - // DESCRIPTION: encode the unsigned literal values from 0 through 31.
  3488. - // STACK RESULT: push the unsigned literal constant value onto the top
  3489. - // of the stack.
  3490. - case DW_OP_lit0:
  3491. - case DW_OP_lit1:
  3492. - case DW_OP_lit2:
  3493. - case DW_OP_lit3:
  3494. - case DW_OP_lit4:
  3495. - case DW_OP_lit5:
  3496. - case DW_OP_lit6:
  3497. - case DW_OP_lit7:
  3498. - case DW_OP_lit8:
  3499. - case DW_OP_lit9:
  3500. - case DW_OP_lit10:
  3501. - case DW_OP_lit11:
  3502. - case DW_OP_lit12:
  3503. - case DW_OP_lit13:
  3504. - case DW_OP_lit14:
  3505. - case DW_OP_lit15:
  3506. - case DW_OP_lit16:
  3507. - case DW_OP_lit17:
  3508. - case DW_OP_lit18:
  3509. - case DW_OP_lit19:
  3510. - case DW_OP_lit20:
  3511. - case DW_OP_lit21:
  3512. - case DW_OP_lit22:
  3513. - case DW_OP_lit23:
  3514. - case DW_OP_lit24:
  3515. - case DW_OP_lit25:
  3516. - case DW_OP_lit26:
  3517. - case DW_OP_lit27:
  3518. - case DW_OP_lit28:
  3519. - case DW_OP_lit29:
  3520. - case DW_OP_lit30:
  3521. - case DW_OP_lit31:
  3522. - stack.push_back(to_generic(op - DW_OP_lit0));
  3523. - break;
  3524. -
  3525. - // OPCODE: DW_OP_regN
  3526. - // OPERANDS: none
  3527. - // DESCRIPTION: Push the value in register n on the top of the stack.
  3528. - case DW_OP_reg0:
  3529. - case DW_OP_reg1:
  3530. - case DW_OP_reg2:
  3531. - case DW_OP_reg3:
  3532. - case DW_OP_reg4:
  3533. - case DW_OP_reg5:
  3534. - case DW_OP_reg6:
  3535. - case DW_OP_reg7:
  3536. - case DW_OP_reg8:
  3537. - case DW_OP_reg9:
  3538. - case DW_OP_reg10:
  3539. - case DW_OP_reg11:
  3540. - case DW_OP_reg12:
  3541. - case DW_OP_reg13:
  3542. - case DW_OP_reg14:
  3543. - case DW_OP_reg15:
  3544. - case DW_OP_reg16:
  3545. - case DW_OP_reg17:
  3546. - case DW_OP_reg18:
  3547. - case DW_OP_reg19:
  3548. - case DW_OP_reg20:
  3549. - case DW_OP_reg21:
  3550. - case DW_OP_reg22:
  3551. - case DW_OP_reg23:
  3552. - case DW_OP_reg24:
  3553. - case DW_OP_reg25:
  3554. - case DW_OP_reg26:
  3555. - case DW_OP_reg27:
  3556. - case DW_OP_reg28:
  3557. - case DW_OP_reg29:
  3558. - case DW_OP_reg30:
  3559. - case DW_OP_reg31: {
  3560. - dwarf4_location_description_kind = Register;
  3561. - reg_num = op - DW_OP_reg0;
  3562. -
  3563. - if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, tmp))
  3564. - stack.push_back(tmp);
  3565. - else
  3566. - return false;
  3567. - } break;
  3568. - // OPCODE: DW_OP_regx
  3569. - // OPERANDS:
  3570. - // ULEB128 literal operand that encodes the register.
  3571. - // DESCRIPTION: Push the value in register on the top of the stack.
  3572. - case DW_OP_regx: {
  3573. - dwarf4_location_description_kind = Register;
  3574. - reg_num = opcodes.GetULEB128(&offset);
  3575. - if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, tmp))
  3576. - stack.push_back(tmp);
  3577. - else
  3578. - return false;
  3579. - } break;
  3580. -
  3581. - // OPCODE: DW_OP_bregN
  3582. - // OPERANDS:
  3583. - // SLEB128 offset from register N
  3584. - // DESCRIPTION: Value is in memory at the address specified by register
  3585. - // N plus an offset.
  3586. - case DW_OP_breg0:
  3587. - case DW_OP_breg1:
  3588. - case DW_OP_breg2:
  3589. - case DW_OP_breg3:
  3590. - case DW_OP_breg4:
  3591. - case DW_OP_breg5:
  3592. - case DW_OP_breg6:
  3593. - case DW_OP_breg7:
  3594. - case DW_OP_breg8:
  3595. - case DW_OP_breg9:
  3596. - case DW_OP_breg10:
  3597. - case DW_OP_breg11:
  3598. - case DW_OP_breg12:
  3599. - case DW_OP_breg13:
  3600. - case DW_OP_breg14:
  3601. - case DW_OP_breg15:
  3602. - case DW_OP_breg16:
  3603. - case DW_OP_breg17:
  3604. - case DW_OP_breg18:
  3605. - case DW_OP_breg19:
  3606. - case DW_OP_breg20:
  3607. - case DW_OP_breg21:
  3608. - case DW_OP_breg22:
  3609. - case DW_OP_breg23:
  3610. - case DW_OP_breg24:
  3611. - case DW_OP_breg25:
  3612. - case DW_OP_breg26:
  3613. - case DW_OP_breg27:
  3614. - case DW_OP_breg28:
  3615. - case DW_OP_breg29:
  3616. - case DW_OP_breg30:
  3617. - case DW_OP_breg31: {
  3618. - reg_num = op - DW_OP_breg0;
  3619. -
  3620. - if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr,
  3621. - tmp)) {
  3622. - int64_t breg_offset = opcodes.GetSLEB128(&offset);
  3623. - tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
  3624. - tmp.ClearContext();
  3625. - stack.push_back(tmp);
  3626. - stack.back().SetValueType(Value::ValueType::LoadAddress);
  3627. - } else
  3628. - return false;
  3629. - } break;
  3630. - // OPCODE: DW_OP_bregx
  3631. - // OPERANDS: 2
  3632. - // ULEB128 literal operand that encodes the register.
  3633. - // SLEB128 offset from register N
  3634. - // DESCRIPTION: Value is in memory at the address specified by register
  3635. - // N plus an offset.
  3636. - case DW_OP_bregx: {
  3637. - reg_num = opcodes.GetULEB128(&offset);
  3638. -
  3639. - if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr,
  3640. - tmp)) {
  3641. - int64_t breg_offset = opcodes.GetSLEB128(&offset);
  3642. - tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
  3643. - tmp.ClearContext();
  3644. - stack.push_back(tmp);
  3645. - stack.back().SetValueType(Value::ValueType::LoadAddress);
  3646. - } else
  3647. - return false;
  3648. - } break;
  3649. -
  3650. - case DW_OP_fbreg:
  3651. - if (exe_ctx) {
  3652. - if (frame) {
  3653. - Scalar value;
  3654. - if (frame->GetFrameBaseValue(value, error_ptr)) {
  3655. - int64_t fbreg_offset = opcodes.GetSLEB128(&offset);
  3656. - value += fbreg_offset;
  3657. - stack.push_back(value);
  3658. - stack.back().SetValueType(Value::ValueType::LoadAddress);
  3659. - } else
  3660. - return false;
  3661. - } else {
  3662. - if (error_ptr)
  3663. - error_ptr->SetErrorString(
  3664. - "Invalid stack frame in context for DW_OP_fbreg opcode.");
  3665. - return false;
  3666. - }
  3667. - } else {
  3668. - if (error_ptr)
  3669. - error_ptr->SetErrorString(
  3670. - "NULL execution context for DW_OP_fbreg.\n");
  3671. - return false;
  3672. - }
  3673. -
  3674. - break;
  3675. -
  3676. - // OPCODE: DW_OP_nop
  3677. - // OPERANDS: none
  3678. - // DESCRIPTION: A place holder. It has no effect on the location stack
  3679. - // or any of its values.
  3680. - case DW_OP_nop:
  3681. - break;
  3682. -
  3683. - // OPCODE: DW_OP_piece
  3684. - // OPERANDS: 1
  3685. - // ULEB128: byte size of the piece
  3686. - // DESCRIPTION: The operand describes the size in bytes of the piece of
  3687. - // the object referenced by the DWARF expression whose result is at the top
  3688. - // of the stack. If the piece is located in a register, but does not occupy
  3689. - // the entire register, the placement of the piece within that register is
  3690. - // defined by the ABI.
  3691. - //
  3692. - // Many compilers store a single variable in sets of registers, or store a
  3693. - // variable partially in memory and partially in registers. DW_OP_piece
  3694. - // provides a way of describing how large a part of a variable a particular
  3695. - // DWARF expression refers to.
  3696. - case DW_OP_piece: {
  3697. - LocationDescriptionKind piece_locdesc = dwarf4_location_description_kind;
  3698. - // Reset for the next piece.
  3699. - dwarf4_location_description_kind = Memory;
  3700. -
  3701. - const uint64_t piece_byte_size = opcodes.GetULEB128(&offset);
  3702. -
  3703. - if (piece_byte_size > 0) {
  3704. - Value curr_piece;
  3705. -
  3706. - if (stack.empty()) {
  3707. - UpdateValueTypeFromLocationDescription(
  3708. - log, dwarf_cu, LocationDescriptionKind::Empty);
  3709. - // In a multi-piece expression, this means that the current piece is
  3710. - // not available. Fill with zeros for now by resizing the data and
  3711. - // appending it
  3712. - curr_piece.ResizeData(piece_byte_size);
  3713. - // Note that "0" is not a correct value for the unknown bits.
  3714. - // It would be better to also return a mask of valid bits together
  3715. - // with the expression result, so the debugger can print missing
  3716. - // members as "<optimized out>" or something.
  3717. - ::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
  3718. - pieces.AppendDataToHostBuffer(curr_piece);
  3719. - } else {
  3720. - Status error;
  3721. - // Extract the current piece into "curr_piece"
  3722. - Value curr_piece_source_value(stack.back());
  3723. - stack.pop_back();
  3724. - UpdateValueTypeFromLocationDescription(log, dwarf_cu, piece_locdesc,
  3725. - &curr_piece_source_value);
  3726. -
  3727. - const Value::ValueType curr_piece_source_value_type =
  3728. - curr_piece_source_value.GetValueType();
  3729. - switch (curr_piece_source_value_type) {
  3730. - case Value::ValueType::Invalid:
  3731. - return false;
  3732. - case Value::ValueType::LoadAddress:
  3733. - if (process) {
  3734. - if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) {
  3735. - lldb::addr_t load_addr =
  3736. - curr_piece_source_value.GetScalar().ULongLong(
  3737. - LLDB_INVALID_ADDRESS);
  3738. - if (process->ReadMemory(
  3739. - load_addr, curr_piece.GetBuffer().GetBytes(),
  3740. - piece_byte_size, error) != piece_byte_size) {
  3741. - if (error_ptr)
  3742. - error_ptr->SetErrorStringWithFormat(
  3743. - "failed to read memory DW_OP_piece(%" PRIu64
  3744. - ") from 0x%" PRIx64,
  3745. - piece_byte_size, load_addr);
  3746. - return false;
  3747. - }
  3748. - } else {
  3749. - if (error_ptr)
  3750. - error_ptr->SetErrorStringWithFormat(
  3751. - "failed to resize the piece memory buffer for "
  3752. - "DW_OP_piece(%" PRIu64 ")",
  3753. - piece_byte_size);
  3754. - return false;
  3755. - }
  3756. - }
  3757. - break;
  3758. -
  3759. - case Value::ValueType::FileAddress:
  3760. - case Value::ValueType::HostAddress:
  3761. - if (error_ptr) {
  3762. - lldb::addr_t addr = curr_piece_source_value.GetScalar().ULongLong(
  3763. - LLDB_INVALID_ADDRESS);
  3764. - error_ptr->SetErrorStringWithFormat(
  3765. - "failed to read memory DW_OP_piece(%" PRIu64
  3766. - ") from %s address 0x%" PRIx64,
  3767. - piece_byte_size, curr_piece_source_value.GetValueType() ==
  3768. - Value::ValueType::FileAddress
  3769. - ? "file"
  3770. - : "host",
  3771. - addr);
  3772. - }
  3773. - return false;
  3774. -
  3775. - case Value::ValueType::Scalar: {
  3776. - uint32_t bit_size = piece_byte_size * 8;
  3777. - uint32_t bit_offset = 0;
  3778. - Scalar &scalar = curr_piece_source_value.GetScalar();
  3779. - if (!scalar.ExtractBitfield(
  3780. - bit_size, bit_offset)) {
  3781. - if (error_ptr)
  3782. - error_ptr->SetErrorStringWithFormat(
  3783. - "unable to extract %" PRIu64 " bytes from a %" PRIu64
  3784. - " byte scalar value.",
  3785. - piece_byte_size,
  3786. - (uint64_t)curr_piece_source_value.GetScalar()
  3787. - .GetByteSize());
  3788. - return false;
  3789. - }
  3790. - // Create curr_piece with bit_size. By default Scalar
  3791. - // grows to the nearest host integer type.
  3792. - llvm::APInt fail_value(1, 0, false);
  3793. - llvm::APInt ap_int = scalar.UInt128(fail_value);
  3794. - assert(ap_int.getBitWidth() >= bit_size);
  3795. - llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
  3796. - ap_int.getNumWords()};
  3797. - curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
  3798. - } break;
  3799. - }
  3800. -
  3801. - // Check if this is the first piece?
  3802. - if (op_piece_offset == 0) {
  3803. - // This is the first piece, we should push it back onto the stack
  3804. - // so subsequent pieces will be able to access this piece and add
  3805. - // to it.
  3806. - if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
  3807. - if (error_ptr)
  3808. - error_ptr->SetErrorString("failed to append piece data");
  3809. - return false;
  3810. - }
  3811. - } else {
  3812. - // If this is the second or later piece there should be a value on
  3813. - // the stack.
  3814. - if (pieces.GetBuffer().GetByteSize() != op_piece_offset) {
  3815. - if (error_ptr)
  3816. - error_ptr->SetErrorStringWithFormat(
  3817. - "DW_OP_piece for offset %" PRIu64
  3818. - " but top of stack is of size %" PRIu64,
  3819. - op_piece_offset, pieces.GetBuffer().GetByteSize());
  3820. - return false;
  3821. - }
  3822. -
  3823. - if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
  3824. - if (error_ptr)
  3825. - error_ptr->SetErrorString("failed to append piece data");
  3826. - return false;
  3827. - }
  3828. - }
  3829. - }
  3830. - op_piece_offset += piece_byte_size;
  3831. - }
  3832. - } break;
  3833. -
  3834. - case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
  3835. - if (stack.size() < 1) {
  3836. - UpdateValueTypeFromLocationDescription(log, dwarf_cu,
  3837. - LocationDescriptionKind::Empty);
  3838. - // Reset for the next piece.
  3839. - dwarf4_location_description_kind = Memory;
  3840. - if (error_ptr)
  3841. - error_ptr->SetErrorString(
  3842. - "Expression stack needs at least 1 item for DW_OP_bit_piece.");
  3843. - return false;
  3844. - } else {
  3845. - UpdateValueTypeFromLocationDescription(
  3846. - log, dwarf_cu, dwarf4_location_description_kind, &stack.back());
  3847. - // Reset for the next piece.
  3848. - dwarf4_location_description_kind = Memory;
  3849. - const uint64_t piece_bit_size = opcodes.GetULEB128(&offset);
  3850. - const uint64_t piece_bit_offset = opcodes.GetULEB128(&offset);
  3851. - switch (stack.back().GetValueType()) {
  3852. - case Value::ValueType::Invalid:
  3853. - return false;
  3854. - case Value::ValueType::Scalar: {
  3855. - if (!stack.back().GetScalar().ExtractBitfield(piece_bit_size,
  3856. - piece_bit_offset)) {
  3857. - if (error_ptr)
  3858. - error_ptr->SetErrorStringWithFormat(
  3859. - "unable to extract %" PRIu64 " bit value with %" PRIu64
  3860. - " bit offset from a %" PRIu64 " bit scalar value.",
  3861. - piece_bit_size, piece_bit_offset,
  3862. - (uint64_t)(stack.back().GetScalar().GetByteSize() * 8));
  3863. - return false;
  3864. - }
  3865. - } break;
  3866. -
  3867. - case Value::ValueType::FileAddress:
  3868. - case Value::ValueType::LoadAddress:
  3869. - case Value::ValueType::HostAddress:
  3870. - if (error_ptr) {
  3871. - error_ptr->SetErrorStringWithFormat(
  3872. - "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
  3873. - ", bit_offset = %" PRIu64 ") from an address value.",
  3874. - piece_bit_size, piece_bit_offset);
  3875. - }
  3876. - return false;
  3877. - }
  3878. - }
  3879. - break;
  3880. -
  3881. - // OPCODE: DW_OP_implicit_value
  3882. - // OPERANDS: 2
  3883. - // ULEB128 size of the value block in bytes
  3884. - // uint8_t* block bytes encoding value in target's memory
  3885. - // representation
  3886. - // DESCRIPTION: Value is immediately stored in block in the debug info with
  3887. - // the memory representation of the target.
  3888. - case DW_OP_implicit_value: {
  3889. - dwarf4_location_description_kind = Implicit;
  3890. -
  3891. - const uint32_t len = opcodes.GetULEB128(&offset);
  3892. - const void *data = opcodes.GetData(&offset, len);
  3893. -
  3894. - if (!data) {
  3895. - LLDB_LOG(log, "Evaluate_DW_OP_implicit_value: could not be read data");
  3896. - LLDB_ERRORF(error_ptr, "Could not evaluate %s.",
  3897. - DW_OP_value_to_name(op));
  3898. - return false;
  3899. - }
  3900. -
  3901. - Value result(data, len);
  3902. - stack.push_back(result);
  3903. - break;
  3904. - }
  3905. -
  3906. - case DW_OP_implicit_pointer: {
  3907. - dwarf4_location_description_kind = Implicit;
  3908. - LLDB_ERRORF(error_ptr, "Could not evaluate %s.", DW_OP_value_to_name(op));
  3909. - return false;
  3910. - }
  3911. -
  3912. - // OPCODE: DW_OP_push_object_address
  3913. - // OPERANDS: none
  3914. - // DESCRIPTION: Pushes the address of the object currently being
  3915. - // evaluated as part of evaluation of a user presented expression. This
  3916. - // object may correspond to an independent variable described by its own
  3917. - // DIE or it may be a component of an array, structure, or class whose
  3918. - // address has been dynamically determined by an earlier step during user
  3919. - // expression evaluation.
  3920. - case DW_OP_push_object_address:
  3921. - if (object_address_ptr)
  3922. - stack.push_back(*object_address_ptr);
  3923. - else {
  3924. - if (error_ptr)
  3925. - error_ptr->SetErrorString("DW_OP_push_object_address used without "
  3926. - "specifying an object address");
  3927. - return false;
  3928. - }
  3929. - break;
  3930. -
  3931. - // OPCODE: DW_OP_call2
  3932. - // OPERANDS:
  3933. - // uint16_t compile unit relative offset of a DIE
  3934. - // DESCRIPTION: Performs subroutine calls during evaluation
  3935. - // of a DWARF expression. The operand is the 2-byte unsigned offset of a
  3936. - // debugging information entry in the current compilation unit.
  3937. - //
  3938. - // Operand interpretation is exactly like that for DW_FORM_ref2.
  3939. - //
  3940. - // This operation transfers control of DWARF expression evaluation to the
  3941. - // DW_AT_location attribute of the referenced DIE. If there is no such
  3942. - // attribute, then there is no effect. Execution of the DWARF expression of
  3943. - // a DW_AT_location attribute may add to and/or remove from values on the
  3944. - // stack. Execution returns to the point following the call when the end of
  3945. - // the attribute is reached. Values on the stack at the time of the call
  3946. - // may be used as parameters by the called expression and values left on
  3947. - // the stack by the called expression may be used as return values by prior
  3948. - // agreement between the calling and called expressions.
  3949. - case DW_OP_call2:
  3950. - if (error_ptr)
  3951. - error_ptr->SetErrorString("Unimplemented opcode DW_OP_call2.");
  3952. - return false;
  3953. - // OPCODE: DW_OP_call4
  3954. - // OPERANDS: 1
  3955. - // uint32_t compile unit relative offset of a DIE
  3956. - // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF
  3957. - // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset of
  3958. - // a debugging information entry in the current compilation unit.
  3959. - //
  3960. - // Operand interpretation DW_OP_call4 is exactly like that for
  3961. - // DW_FORM_ref4.
  3962. - //
  3963. - // This operation transfers control of DWARF expression evaluation to the
  3964. - // DW_AT_location attribute of the referenced DIE. If there is no such
  3965. - // attribute, then there is no effect. Execution of the DWARF expression of
  3966. - // a DW_AT_location attribute may add to and/or remove from values on the
  3967. - // stack. Execution returns to the point following the call when the end of
  3968. - // the attribute is reached. Values on the stack at the time of the call
  3969. - // may be used as parameters by the called expression and values left on
  3970. - // the stack by the called expression may be used as return values by prior
  3971. - // agreement between the calling and called expressions.
  3972. - case DW_OP_call4:
  3973. - if (error_ptr)
  3974. - error_ptr->SetErrorString("Unimplemented opcode DW_OP_call4.");
  3975. - return false;
  3976. -
  3977. - // OPCODE: DW_OP_stack_value
  3978. - // OPERANDS: None
  3979. - // DESCRIPTION: Specifies that the object does not exist in memory but
  3980. - // rather is a constant value. The value from the top of the stack is the
  3981. - // value to be used. This is the actual object value and not the location.
  3982. - case DW_OP_stack_value:
  3983. - dwarf4_location_description_kind = Implicit;
  3984. - if (stack.empty()) {
  3985. - if (error_ptr)
  3986. - error_ptr->SetErrorString(
  3987. - "Expression stack needs at least 1 item for DW_OP_stack_value.");
  3988. - return false;
  3989. - }
  3990. - stack.back().SetValueType(Value::ValueType::Scalar);
  3991. - break;
  3992. -
  3993. - // OPCODE: DW_OP_convert
  3994. - // OPERANDS: 1
  3995. - // A ULEB128 that is either a DIE offset of a
  3996. - // DW_TAG_base_type or 0 for the generic (pointer-sized) type.
  3997. - //
  3998. - // DESCRIPTION: Pop the top stack element, convert it to a
  3999. - // different type, and push the result.
  4000. - case DW_OP_convert: {
  4001. - if (stack.size() < 1) {
  4002. - if (error_ptr)
  4003. - error_ptr->SetErrorString(
  4004. - "Expression stack needs at least 1 item for DW_OP_convert.");
  4005. - return false;
  4006. - }
  4007. - const uint64_t die_offset = opcodes.GetULEB128(&offset);
  4008. - uint64_t bit_size;
  4009. - bool sign;
  4010. - if (die_offset == 0) {
  4011. - // The generic type has the size of an address on the target
  4012. - // machine and an unspecified signedness. Scalar has no
  4013. - // "unspecified signedness", so we use unsigned types.
  4014. - if (!module_sp) {
  4015. - if (error_ptr)
  4016. - error_ptr->SetErrorString("No module");
  4017. - return false;
  4018. - }
  4019. - sign = false;
  4020. - bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
  4021. - if (!bit_size) {
  4022. - if (error_ptr)
  4023. - error_ptr->SetErrorString("unspecified architecture");
  4024. - return false;
  4025. - }
  4026. - } else {
  4027. - // Retrieve the type DIE that the value is being converted to.
  4028. - // FIXME: the constness has annoying ripple effects.
  4029. - DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(die_offset);
  4030. - if (!die) {
  4031. - if (error_ptr)
  4032. - error_ptr->SetErrorString("Cannot resolve DW_OP_convert type DIE");
  4033. - return false;
  4034. - }
  4035. - uint64_t encoding =
  4036. - die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
  4037. - bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
  4038. - if (!bit_size)
  4039. - bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
  4040. - if (!bit_size) {
  4041. - if (error_ptr)
  4042. - error_ptr->SetErrorString("Unsupported type size in DW_OP_convert");
  4043. - return false;
  4044. - }
  4045. - switch (encoding) {
  4046. - case DW_ATE_signed:
  4047. - case DW_ATE_signed_char:
  4048. - sign = true;
  4049. - break;
  4050. - case DW_ATE_unsigned:
  4051. - case DW_ATE_unsigned_char:
  4052. - sign = false;
  4053. - break;
  4054. - default:
  4055. - if (error_ptr)
  4056. - error_ptr->SetErrorString("Unsupported encoding in DW_OP_convert");
  4057. - return false;
  4058. - }
  4059. - }
  4060. - Scalar &top = stack.back().ResolveValue(exe_ctx);
  4061. - top.TruncOrExtendTo(bit_size, sign);
  4062. - break;
  4063. - }
  4064. -
  4065. - // OPCODE: DW_OP_call_frame_cfa
  4066. - // OPERANDS: None
  4067. - // DESCRIPTION: Specifies a DWARF expression that pushes the value of
  4068. - // the canonical frame address consistent with the call frame information
  4069. - // located in .debug_frame (or in the FDEs of the eh_frame section).
  4070. - case DW_OP_call_frame_cfa:
  4071. - if (frame) {
  4072. - // Note that we don't have to parse FDEs because this DWARF expression
  4073. - // is commonly evaluated with a valid stack frame.
  4074. - StackID id = frame->GetStackID();
  4075. - addr_t cfa = id.GetCallFrameAddress();
  4076. - if (cfa != LLDB_INVALID_ADDRESS) {
  4077. - stack.push_back(Scalar(cfa));
  4078. - stack.back().SetValueType(Value::ValueType::LoadAddress);
  4079. - } else if (error_ptr)
  4080. - error_ptr->SetErrorString("Stack frame does not include a canonical "
  4081. - "frame address for DW_OP_call_frame_cfa "
  4082. - "opcode.");
  4083. - } else {
  4084. - if (error_ptr)
  4085. - error_ptr->SetErrorString("Invalid stack frame in context for "
  4086. - "DW_OP_call_frame_cfa opcode.");
  4087. - return false;
  4088. - }
  4089. - break;
  4090. -
  4091. - // OPCODE: DW_OP_form_tls_address (or the old pre-DWARFv3 vendor extension
  4092. - // opcode, DW_OP_GNU_push_tls_address)
  4093. - // OPERANDS: none
  4094. - // DESCRIPTION: Pops a TLS offset from the stack, converts it to
  4095. - // an address in the current thread's thread-local storage block, and
  4096. - // pushes it on the stack.
  4097. - case DW_OP_form_tls_address:
  4098. - case DW_OP_GNU_push_tls_address: {
  4099. - if (stack.size() < 1) {
  4100. - if (error_ptr) {
  4101. - if (op == DW_OP_form_tls_address)
  4102. - error_ptr->SetErrorString(
  4103. - "DW_OP_form_tls_address needs an argument.");
  4104. - else
  4105. - error_ptr->SetErrorString(
  4106. - "DW_OP_GNU_push_tls_address needs an argument.");
  4107. - }
  4108. - return false;
  4109. - }
  4110. -
  4111. - if (!exe_ctx || !module_sp) {
  4112. - if (error_ptr)
  4113. - error_ptr->SetErrorString("No context to evaluate TLS within.");
  4114. - return false;
  4115. - }
  4116. -
  4117. - Thread *thread = exe_ctx->GetThreadPtr();
  4118. - if (!thread) {
  4119. - if (error_ptr)
  4120. - error_ptr->SetErrorString("No thread to evaluate TLS within.");
  4121. - return false;
  4122. - }
  4123. -
  4124. - // Lookup the TLS block address for this thread and module.
  4125. - const addr_t tls_file_addr =
  4126. - stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
  4127. - const addr_t tls_load_addr =
  4128. - thread->GetThreadLocalData(module_sp, tls_file_addr);
  4129. -
  4130. - if (tls_load_addr == LLDB_INVALID_ADDRESS) {
  4131. - if (error_ptr)
  4132. - error_ptr->SetErrorString(
  4133. - "No TLS data currently exists for this thread.");
  4134. - return false;
  4135. - }
  4136. -
  4137. - stack.back().GetScalar() = tls_load_addr;
  4138. - stack.back().SetValueType(Value::ValueType::LoadAddress);
  4139. - } break;
  4140. -
  4141. - // OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.)
  4142. - // OPERANDS: 1
  4143. - // ULEB128: index to the .debug_addr section
  4144. - // DESCRIPTION: Pushes an address to the stack from the .debug_addr
  4145. - // section with the base address specified by the DW_AT_addr_base attribute
  4146. - // and the 0 based index is the ULEB128 encoded index.
  4147. - case DW_OP_addrx:
  4148. - case DW_OP_GNU_addr_index: {
  4149. - if (!dwarf_cu) {
  4150. - if (error_ptr)
  4151. - error_ptr->SetErrorString("DW_OP_GNU_addr_index found without a "
  4152. - "compile unit being specified");
  4153. - return false;
  4154. - }
  4155. - uint64_t index = opcodes.GetULEB128(&offset);
  4156. - lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index);
  4157. - stack.push_back(Scalar(value));
  4158. - stack.back().SetValueType(Value::ValueType::FileAddress);
  4159. - } break;
  4160. -
  4161. - // OPCODE: DW_OP_GNU_const_index
  4162. - // OPERANDS: 1
  4163. - // ULEB128: index to the .debug_addr section
  4164. - // DESCRIPTION: Pushes an constant with the size of a machine address to
  4165. - // the stack from the .debug_addr section with the base address specified
  4166. - // by the DW_AT_addr_base attribute and the 0 based index is the ULEB128
  4167. - // encoded index.
  4168. - case DW_OP_GNU_const_index: {
  4169. - if (!dwarf_cu) {
  4170. - if (error_ptr)
  4171. - error_ptr->SetErrorString("DW_OP_GNU_const_index found without a "
  4172. - "compile unit being specified");
  4173. - return false;
  4174. - }
  4175. - uint64_t index = opcodes.GetULEB128(&offset);
  4176. - lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index);
  4177. - stack.push_back(Scalar(value));
  4178. - } break;
  4179. -
  4180. - case DW_OP_GNU_entry_value:
  4181. - case DW_OP_entry_value: {
  4182. - if (!Evaluate_DW_OP_entry_value(stack, exe_ctx, reg_ctx, opcodes, offset,
  4183. - error_ptr, log)) {
  4184. - LLDB_ERRORF(error_ptr, "Could not evaluate %s.",
  4185. - DW_OP_value_to_name(op));
  4186. - return false;
  4187. - }
  4188. - break;
  4189. - }
  4190. -
  4191. - default:
  4192. - if (error_ptr)
  4193. - error_ptr->SetErrorStringWithFormatv(
  4194. - "Unhandled opcode {0} in DWARFExpression", LocationAtom(op));
  4195. - return false;
  4196. - }
  4197. - }
  4198. -
  4199. - if (stack.empty()) {
  4200. - // Nothing on the stack, check if we created a piece value from DW_OP_piece
  4201. - // or DW_OP_bit_piece opcodes
  4202. - if (pieces.GetBuffer().GetByteSize()) {
  4203. - result = pieces;
  4204. - return true;
  4205. - }
  4206. - if (error_ptr)
  4207. - error_ptr->SetErrorString("Stack empty after evaluation.");
  4208. - return false;
  4209. - }
  4210. -
  4211. - UpdateValueTypeFromLocationDescription(
  4212. - log, dwarf_cu, dwarf4_location_description_kind, &stack.back());
  4213. -
  4214. - if (log && log->GetVerbose()) {
  4215. - size_t count = stack.size();
  4216. - LLDB_LOGF(log,
  4217. - "Stack after operation has %" PRIu64 " values:", (uint64_t)count);
  4218. - for (size_t i = 0; i < count; ++i) {
  4219. - StreamString new_value;
  4220. - new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
  4221. - stack[i].Dump(&new_value);
  4222. - LLDB_LOGF(log, " %s", new_value.GetData());
  4223. - }
  4224. - }
  4225. - result = stack.back();
  4226. - return true; // Return true on success
  4227. + DWARFExpression expr(module_sp, opcodes, dwarf_cu);
  4228. + expr.SetRegisterKind(reg_kind);
  4229. +
  4230. + // Use the DWARF expression evaluator registered for this module (or
  4231. + // DWARFEvaluator by default).
  4232. + DWARFEvaluatorFactory *evaluator_factory =
  4233. + module_sp->GetDWARFExpressionEvaluatorFactory();
  4234. + std::unique_ptr<DWARFEvaluator> evaluator =
  4235. + evaluator_factory->CreateDWARFEvaluator(
  4236. + expr, exe_ctx, reg_ctx, initial_value_ptr, object_address_ptr);
  4237. + return evaluator->Evaluate(result, error_ptr);
  4238. }
  4239. static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc,
  4240. diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
  4241. index 00e9ccb76..2137a1ac8 100644
  4242. --- a/lldb/source/Interpreter/CommandInterpreter.cpp
  4243. +++ b/lldb/source/Interpreter/CommandInterpreter.cpp
  4244. @@ -759,6 +759,24 @@ void CommandInterpreter::LoadCommandDictionary() {
  4245. }
  4246. }
  4247. + std::unique_ptr<CommandObjectRegexCommand> connect_wasm_cmd_up(
  4248. + new CommandObjectRegexCommand(
  4249. + *this, "wasm",
  4250. + "Connect to a WebAssembly process via remote GDB server. "
  4251. + "If no host is specifed, localhost is assumed.",
  4252. + "wasm [<hostname>:]<portnum>", 2, 0, false));
  4253. + if (connect_wasm_cmd_up) {
  4254. + if (connect_wasm_cmd_up->AddRegexCommand(
  4255. + "^([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)$",
  4256. + "process connect --plugin wasm connect://%1:%2") &&
  4257. + connect_wasm_cmd_up->AddRegexCommand(
  4258. + "^([[:digit:]]+)$",
  4259. + "process connect --plugin wasm connect://localhost:%1")) {
  4260. + CommandObjectSP command_sp(connect_wasm_cmd_up.release());
  4261. + m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
  4262. + }
  4263. + }
  4264. +
  4265. std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_up(
  4266. new CommandObjectRegexCommand(
  4267. *this, "kdp-remote",
  4268. diff --git a/lldb/source/Plugins/CMakeLists.txt b/lldb/source/Plugins/CMakeLists.txt
  4269. index 9181a4e47..2be6ec365 100644
  4270. --- a/lldb/source/Plugins/CMakeLists.txt
  4271. +++ b/lldb/source/Plugins/CMakeLists.txt
  4272. @@ -2,6 +2,7 @@ add_subdirectory(ABI)
  4273. add_subdirectory(Architecture)
  4274. add_subdirectory(Disassembler)
  4275. add_subdirectory(DynamicLoader)
  4276. +add_subdirectory(DWARFEvaluator)
  4277. add_subdirectory(ExpressionParser)
  4278. add_subdirectory(Instruction)
  4279. add_subdirectory(InstrumentationRuntime)
  4280. @@ -32,6 +33,7 @@ set(LLDB_ENUM_PLUGINS "")
  4281. # FIXME: ProcessWindowsCommon needs to be initialized after all other process
  4282. # plugins but before ProcessGDBRemote.
  4283. set(LLDB_PROCESS_WINDOWS_PLUGIN "")
  4284. +set(LLDB_PROCESS_WASM_PLUGIN "")
  4285. set(LLDB_PROCESS_GDB_PLUGIN "")
  4286. foreach(p ${LLDB_ALL_PLUGINS})
  4287. @@ -43,6 +45,8 @@ foreach(p ${LLDB_ALL_PLUGINS})
  4288. set(LLDB_PROCESS_WINDOWS_PLUGIN "LLDB_PLUGIN(${pStripped})\n")
  4289. elseif(${pStripped} STREQUAL "ProcessGDBRemote")
  4290. set(LLDB_PROCESS_GDB_PLUGIN "LLDB_PLUGIN(${pStripped})\n")
  4291. + elseif(${pStripped} STREQUAL "ProcessWasm")
  4292. + set(LLDB_PROCESS_WASM_PLUGIN "LLDB_PLUGIN(${pStripped})\n")
  4293. else()
  4294. set(LLDB_ENUM_PLUGINS "${LLDB_ENUM_PLUGINS}LLDB_PLUGIN(${pStripped})\n")
  4295. endif()
  4296. diff --git a/lldb/source/Plugins/DWARFEvaluator/CMakeLists.txt b/lldb/source/Plugins/DWARFEvaluator/CMakeLists.txt
  4297. new file mode 100644
  4298. index 000000000..73fad41e1
  4299. --- /dev/null
  4300. +++ b/lldb/source/Plugins/DWARFEvaluator/CMakeLists.txt
  4301. @@ -0,0 +1 @@
  4302. +add_subdirectory(wasm)
  4303. diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/CMakeLists.txt b/lldb/source/Plugins/DWARFEvaluator/wasm/CMakeLists.txt
  4304. new file mode 100644
  4305. index 000000000..e50b1bef7
  4306. --- /dev/null
  4307. +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/CMakeLists.txt
  4308. @@ -0,0 +1,10 @@
  4309. +add_lldb_library(lldbPluginWasmDWARFEvaluatorFactory PLUGIN
  4310. + WasmDWARFEvaluator.cpp
  4311. + WasmDWARFEvaluatorFactory.cpp
  4312. +
  4313. + LINK_LIBS
  4314. + lldbCore
  4315. + lldbHost
  4316. + lldbSymbol
  4317. + lldbPluginObjectFileWasm
  4318. + )
  4319. diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.cpp b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.cpp
  4320. new file mode 100644
  4321. index 000000000..fdda1991d
  4322. --- /dev/null
  4323. +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.cpp
  4324. @@ -0,0 +1,126 @@
  4325. +//===-- WasmDWARFEvaluator.cpp --------------------------------------------===//
  4326. +//
  4327. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4328. +// See https://llvm.org/LICENSE.txt for license information.
  4329. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4330. +//
  4331. +//===----------------------------------------------------------------------===//
  4332. +
  4333. +#include "WasmDWARFEvaluator.h"
  4334. +
  4335. +#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
  4336. +#include "Plugins/Process/wasm/ProcessWasm.h"
  4337. +#include "lldb/Core/Module.h"
  4338. +#include "lldb/Core/PluginManager.h"
  4339. +#include "lldb/Core/Value.h"
  4340. +#include "lldb/Core/dwarf.h"
  4341. +#include "lldb/Expression/DWARFExpression.h"
  4342. +
  4343. +using namespace lldb;
  4344. +using namespace lldb_private;
  4345. +using namespace lldb_private::wasm;
  4346. +
  4347. +bool WasmDWARFEvaluator::Evaluate(const uint8_t op, Process *process,
  4348. + StackFrame *frame, std::vector<Value> &stack,
  4349. + const DataExtractor &opcodes,
  4350. + lldb::offset_t &offset, Value &pieces,
  4351. + uint64_t &op_piece_offset, Log *log,
  4352. + Status *error_ptr) {
  4353. + lldb::ModuleSP module_sp = m_dwarf_expression.GetModule();
  4354. +
  4355. + switch (op) {
  4356. + case DW_OP_WASM_location: {
  4357. + if (frame) {
  4358. + const llvm::Triple::ArchType machine =
  4359. + frame->CalculateTarget()->GetArchitecture().GetMachine();
  4360. + if (machine != llvm::Triple::wasm32) {
  4361. + if (error_ptr)
  4362. + error_ptr->SetErrorString("Invalid target architecture for "
  4363. + "DW_OP_WASM_location opcode.");
  4364. + return false;
  4365. + }
  4366. +
  4367. + ProcessWasm *wasm_process =
  4368. + static_cast<wasm::ProcessWasm *>(frame->CalculateProcess().get());
  4369. + int frame_index = frame->GetConcreteFrameIndex();
  4370. + uint64_t wasm_op = opcodes.GetULEB128(&offset);
  4371. + uint64_t index = opcodes.GetULEB128(&offset);
  4372. + uint8_t buf[16];
  4373. + size_t size = 0;
  4374. + switch (wasm_op) {
  4375. + case 0: // Local
  4376. + if (!wasm_process->GetWasmLocal(frame_index, index, buf, 16, size)) {
  4377. + return false;
  4378. + }
  4379. + break;
  4380. + case 1: // Global
  4381. + if (!wasm_process->GetWasmGlobal(frame_index, index, buf, 16, size)) {
  4382. + return false;
  4383. + }
  4384. + break;
  4385. + case 2: // Operand Stack
  4386. + if (!wasm_process->GetWasmStackValue(frame_index, index, buf, 16,
  4387. + size)) {
  4388. + return false;
  4389. + }
  4390. + break;
  4391. + default:
  4392. + return false;
  4393. + }
  4394. +
  4395. + if (size == sizeof(uint32_t)) {
  4396. + uint32_t value;
  4397. + memcpy(&value, buf, size);
  4398. + stack.push_back(Scalar(value));
  4399. + } else if (size == sizeof(uint64_t)) {
  4400. + uint64_t value;
  4401. + memcpy(&value, buf, size);
  4402. + stack.push_back(Scalar(value));
  4403. + } else
  4404. + return false;
  4405. + } else {
  4406. + if (error_ptr)
  4407. + error_ptr->SetErrorString("Invalid stack frame in context for "
  4408. + "DW_OP_WASM_location opcode.");
  4409. + return false;
  4410. + }
  4411. + } break;
  4412. +
  4413. + case DW_OP_addr: {
  4414. + /// {addr} is an offset in the module Data section.
  4415. + lldb::addr_t addr = opcodes.GetAddress(&offset);
  4416. + stack.push_back(Scalar(addr));
  4417. + stack.back().SetValueType(Value::ValueType::LoadAddress);
  4418. + } break;
  4419. +
  4420. + case DW_OP_fbreg:
  4421. + if (m_exe_ctx) {
  4422. + if (frame) {
  4423. + Scalar value;
  4424. + if (frame->GetFrameBaseValue(value, error_ptr)) {
  4425. + // The value is an address in the Wasm Memory space.
  4426. + int64_t fbreg_offset = opcodes.GetSLEB128(&offset);
  4427. + stack.push_back(Scalar(value.ULong() + fbreg_offset));
  4428. + stack.back().SetValueType(Value::ValueType::LoadAddress);
  4429. + } else
  4430. + return false;
  4431. + } else {
  4432. + if (error_ptr)
  4433. + error_ptr->SetErrorString(
  4434. + "Invalid stack frame in context for DW_OP_fbreg opcode.");
  4435. + return false;
  4436. + }
  4437. + } else {
  4438. + if (error_ptr)
  4439. + error_ptr->SetErrorStringWithFormat(
  4440. + "NULL execution context for DW_OP_fbreg.\n");
  4441. + return false;
  4442. + }
  4443. + break;
  4444. +
  4445. + default:
  4446. + return DWARFEvaluator::Evaluate(op, process, frame, stack, opcodes, offset,
  4447. + pieces, op_piece_offset, log, error_ptr);
  4448. + }
  4449. + return true;
  4450. +}
  4451. diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.h b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.h
  4452. new file mode 100644
  4453. index 000000000..a01159064
  4454. --- /dev/null
  4455. +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluator.h
  4456. @@ -0,0 +1,47 @@
  4457. +//===-- WasmDWARFEvaluator.h ------------------------------------*- C++ -*-===//
  4458. +//
  4459. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4460. +// See https://llvm.org/LICENSE.txt for license information.
  4461. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4462. +//
  4463. +//===----------------------------------------------------------------------===//
  4464. +
  4465. +#ifndef LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATOR_H
  4466. +#define LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATOR_H
  4467. +
  4468. +#include "lldb/Expression/DWARFEvaluator.h"
  4469. +#include "lldb/lldb-private.h"
  4470. +
  4471. +namespace lldb_private {
  4472. +namespace wasm {
  4473. +
  4474. +/// \class WasmDWARFEvaluator evaluates DWARF expressions in the context of a
  4475. +/// WebAssembly process.
  4476. +///
  4477. +class WasmDWARFEvaluator : public DWARFEvaluator {
  4478. +public:
  4479. + WasmDWARFEvaluator(const DWARFExpression &dwarf_expression,
  4480. + ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
  4481. + const Value *initial_value_ptr,
  4482. + const Value *object_address_ptr)
  4483. + : DWARFEvaluator(dwarf_expression, exe_ctx, reg_ctx, initial_value_ptr,
  4484. + object_address_ptr) {}
  4485. +
  4486. + /// DWARFEvaluator protocol.
  4487. + /// \{
  4488. + bool Evaluate(const uint8_t op, Process *process, StackFrame *frame,
  4489. + std::vector<Value> &stack, const DataExtractor &opcodes,
  4490. + lldb::offset_t &offset, Value &pieces,
  4491. + uint64_t &op_piece_offset, Log *log,
  4492. + Status *error_ptr) override;
  4493. + /// \}
  4494. +
  4495. +private:
  4496. + WasmDWARFEvaluator(const WasmDWARFEvaluator &);
  4497. + const WasmDWARFEvaluator &operator=(const WasmDWARFEvaluator &) = delete;
  4498. +};
  4499. +
  4500. +} // namespace wasm
  4501. +} // namespace lldb_private
  4502. +
  4503. +#endif // LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATOR_H
  4504. diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.cpp b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.cpp
  4505. new file mode 100644
  4506. index 000000000..d43e96a34
  4507. --- /dev/null
  4508. +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.cpp
  4509. @@ -0,0 +1,64 @@
  4510. +//===-- WasmDWARFEvaluatorFactory.cpp -------------------------------------===//
  4511. +//
  4512. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4513. +// See https://llvm.org/LICENSE.txt for license information.
  4514. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4515. +//
  4516. +//===----------------------------------------------------------------------===//
  4517. +
  4518. +#include "WasmDWARFEvaluatorFactory.h"
  4519. +#include "WasmDWARFEvaluator.h"
  4520. +
  4521. +#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
  4522. +#include "lldb/Core/Module.h"
  4523. +#include "lldb/Core/PluginManager.h"
  4524. +
  4525. +using namespace lldb;
  4526. +using namespace lldb_private;
  4527. +using namespace lldb_private::wasm;
  4528. +
  4529. +LLDB_PLUGIN_DEFINE(WasmDWARFEvaluatorFactory)
  4530. +
  4531. +void WasmDWARFEvaluatorFactory::Initialize() {
  4532. + PluginManager::RegisterPlugin(GetPluginNameStatic(),
  4533. + GetPluginDescriptionStatic(), CreateInstance);
  4534. +}
  4535. +
  4536. +void WasmDWARFEvaluatorFactory::Terminate() {
  4537. + PluginManager::UnregisterPlugin(CreateInstance);
  4538. +}
  4539. +
  4540. +lldb_private::ConstString WasmDWARFEvaluatorFactory::GetPluginNameStatic() {
  4541. + static ConstString g_name("WASM");
  4542. + return g_name;
  4543. +}
  4544. +
  4545. +const char *WasmDWARFEvaluatorFactory::GetPluginDescriptionStatic() {
  4546. + return "DWARF expression evaluator factory for WASM.";
  4547. +}
  4548. +
  4549. +// CreateInstance
  4550. +//
  4551. +// Platforms can register a callback to use when creating DWARF expression
  4552. +// evaluators to allow handling platform-specific DWARF codes.
  4553. +DWARFEvaluatorFactory *
  4554. +WasmDWARFEvaluatorFactory::CreateInstance(Module *module) {
  4555. + if (!module)
  4556. + return nullptr;
  4557. +
  4558. + ObjectFileWasm *obj_file =
  4559. + llvm::dyn_cast_or_null<ObjectFileWasm>(module->GetObjectFile());
  4560. + if (!obj_file)
  4561. + return nullptr;
  4562. +
  4563. + return new WasmDWARFEvaluatorFactory();
  4564. +}
  4565. +
  4566. +std::unique_ptr<DWARFEvaluator> WasmDWARFEvaluatorFactory::CreateDWARFEvaluator(
  4567. + const DWARFExpression &dwarf_expression, ExecutionContext *exe_ctx,
  4568. + RegisterContext *reg_ctx, const Value *initial_value_ptr,
  4569. + const Value *object_address_ptr) {
  4570. + return std::make_unique<WasmDWARFEvaluator>(dwarf_expression, exe_ctx,
  4571. + reg_ctx, initial_value_ptr,
  4572. + object_address_ptr);
  4573. +}
  4574. diff --git a/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.h b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.h
  4575. new file mode 100644
  4576. index 000000000..8a946592a
  4577. --- /dev/null
  4578. +++ b/lldb/source/Plugins/DWARFEvaluator/wasm/WasmDWARFEvaluatorFactory.h
  4579. @@ -0,0 +1,55 @@
  4580. +//===-- WasmDWARFEvaluatorFactory.h -----------------------------*- C++ -*-===//
  4581. +//
  4582. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4583. +// See https://llvm.org/LICENSE.txt for license information.
  4584. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4585. +//
  4586. +//===----------------------------------------------------------------------===//
  4587. +
  4588. +#ifndef LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATORFACTORY_H
  4589. +#define LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATORFACTORY_H
  4590. +
  4591. +#include "lldb/Expression/DWARFEvaluatorFactory.h"
  4592. +
  4593. +namespace lldb_private {
  4594. +namespace wasm {
  4595. +
  4596. +/// \class WasmDWARFEvaluatorFactory creates DWARF evaluators specialized to
  4597. +/// manage DWARF-specific opcodes.
  4598. +class WasmDWARFEvaluatorFactory : public DWARFEvaluatorFactory {
  4599. +public:
  4600. + static void Initialize();
  4601. + static void Terminate();
  4602. + static lldb_private::ConstString GetPluginNameStatic();
  4603. + static const char *GetPluginDescriptionStatic();
  4604. +
  4605. + static lldb_private::DWARFEvaluatorFactory *CreateInstance(Module *module);
  4606. +
  4607. + /// PluginInterface protocol.
  4608. + /// \{
  4609. + lldb_private::ConstString GetPluginName() override {
  4610. + return GetPluginNameStatic();
  4611. + }
  4612. + uint32_t GetPluginVersion() override { return 1; }
  4613. + /// \}
  4614. +
  4615. + WasmDWARFEvaluatorFactory() {}
  4616. +
  4617. + /// DWARFEvaluatorFactory protocol.
  4618. + /// \{
  4619. + std::unique_ptr<DWARFEvaluator>
  4620. + CreateDWARFEvaluator(const DWARFExpression &dwarf_expression,
  4621. + ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
  4622. + const Value *initial_value_ptr,
  4623. + const Value *object_address_ptr) override;
  4624. + /// \}
  4625. +
  4626. +private:
  4627. + WasmDWARFEvaluatorFactory(const WasmDWARFEvaluatorFactory &);
  4628. + const WasmDWARFEvaluatorFactory &operator=(const WasmDWARFEvaluatorFactory &) = delete;
  4629. +};
  4630. +
  4631. +} // namespace wasm
  4632. +} // namespace lldb_private
  4633. +
  4634. +#endif // LLDB_SOURCE_PLUGINS_DWARFEVALUATOR_WASM_WASMDWARFEVALUATORFACTORY_H
  4635. diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
  4636. index ae7e011ea..24ea75d19 100644
  4637. --- a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
  4638. +++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
  4639. @@ -62,6 +62,15 @@ void DynamicLoaderWasmDYLD::DidAttach() {
  4640. // Ask the process for the list of loaded WebAssembly modules.
  4641. auto error = m_process->LoadModules();
  4642. LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}");
  4643. +
  4644. + // TODO: multi-modules support ?
  4645. + Target &target = m_process->GetTarget();
  4646. + const ModuleList &modules = target.GetImages();
  4647. + ModuleSP module_sp(modules.GetModuleAtIndex(0));
  4648. + // module_sp is nullptr if without libxml2
  4649. + if(module_sp) {
  4650. + module_sp->PreloadSymbols();
  4651. + }
  4652. }
  4653. ThreadPlanSP DynamicLoaderWasmDYLD::GetStepThroughTrampolinePlan(Thread &thread,
  4654. diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
  4655. index 5272da9ab..abc5523bf 100644
  4656. --- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
  4657. +++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
  4658. @@ -23,6 +23,7 @@
  4659. #include "llvm/BinaryFormat/Wasm.h"
  4660. #include "llvm/Support/Endian.h"
  4661. #include "llvm/Support/Format.h"
  4662. +#include "Plugins/Process/wasm/ProcessWasm.h"
  4663. using namespace lldb;
  4664. using namespace lldb_private;
  4665. @@ -341,6 +342,8 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
  4666. 0, // Alignment of the section
  4667. 0, // Flags for this section.
  4668. 1)); // Number of host bytes per target byte
  4669. + if (section_type == eSectionTypeCode)
  4670. + section_sp->SetPermissions(ePermissionsReadable|ePermissionsExecutable);
  4671. m_sections_up->AddSection(section_sp);
  4672. unified_section_list.AddSection(section_sp);
  4673. }
  4674. @@ -367,6 +370,7 @@ bool ObjectFileWasm::SetLoadAddress(Target &target, lldb::addr_t load_address,
  4675. assert(m_memory_addr == LLDB_INVALID_ADDRESS ||
  4676. m_memory_addr == load_address);
  4677. + lldb::addr_t adjust_addr;
  4678. ModuleSP module_sp = GetModule();
  4679. if (!module_sp)
  4680. return false;
  4681. @@ -381,8 +385,9 @@ bool ObjectFileWasm::SetLoadAddress(Target &target, lldb::addr_t load_address,
  4682. const size_t num_sections = section_list->GetSize();
  4683. for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
  4684. SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
  4685. + adjust_addr = load_address;
  4686. if (target.SetSectionLoadAddress(
  4687. - section_sp, load_address | section_sp->GetFileOffset())) {
  4688. + section_sp, adjust_addr | section_sp->GetFileOffset())) {
  4689. ++num_loaded_sections;
  4690. }
  4691. }
  4692. diff --git a/lldb/source/Plugins/Platform/CMakeLists.txt b/lldb/source/Plugins/Platform/CMakeLists.txt
  4693. index 5f284e517..6084cbc93 100644
  4694. --- a/lldb/source/Plugins/Platform/CMakeLists.txt
  4695. +++ b/lldb/source/Plugins/Platform/CMakeLists.txt
  4696. @@ -15,3 +15,4 @@
  4697. add_subdirectory(POSIX)
  4698. add_subdirectory(gdb-server)
  4699. add_subdirectory(Android)
  4700. +add_subdirectory(wasm-remote)
  4701. diff --git a/lldb/source/Plugins/Platform/wasm-remote/CMakeLists.txt b/lldb/source/Plugins/Platform/wasm-remote/CMakeLists.txt
  4702. new file mode 100644
  4703. index 000000000..4a65765a5
  4704. --- /dev/null
  4705. +++ b/lldb/source/Plugins/Platform/wasm-remote/CMakeLists.txt
  4706. @@ -0,0 +1,10 @@
  4707. +add_lldb_library(lldbPluginPlatformWasm PLUGIN
  4708. + PlatformRemoteWasmServer.cpp
  4709. +
  4710. + LINK_LIBS
  4711. + lldbBreakpoint
  4712. + lldbCore
  4713. + lldbHost
  4714. + lldbTarget
  4715. + lldbPluginProcessUtility
  4716. + )
  4717. diff --git a/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.cpp b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.cpp
  4718. new file mode 100644
  4719. index 000000000..f26d11f00
  4720. --- /dev/null
  4721. +++ b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.cpp
  4722. @@ -0,0 +1,139 @@
  4723. +#include "PlatformRemoteWasmServer.h"
  4724. +#include "lldb/Host/Config.h"
  4725. +
  4726. +#include "lldb/Breakpoint/BreakpointLocation.h"
  4727. +#include "lldb/Core/Debugger.h"
  4728. +#include "lldb/Core/Module.h"
  4729. +#include "lldb/Core/ModuleList.h"
  4730. +#include "lldb/Core/ModuleSpec.h"
  4731. +#include "lldb/Core/PluginManager.h"
  4732. +#include "lldb/Core/StreamFile.h"
  4733. +#include "lldb/Host/ConnectionFileDescriptor.h"
  4734. +#include "lldb/Host/Host.h"
  4735. +#include "lldb/Host/HostInfo.h"
  4736. +#include "lldb/Host/PosixApi.h"
  4737. +#include "lldb/Target/Process.h"
  4738. +#include "lldb/Target/Target.h"
  4739. +#include "lldb/Utility/FileSpec.h"
  4740. +#include "lldb/Utility/Log.h"
  4741. +#include "lldb/Utility/ProcessInfo.h"
  4742. +#include "lldb/Utility/Status.h"
  4743. +#include "lldb/Utility/StreamString.h"
  4744. +#include "lldb/Utility/UriParser.h"
  4745. +
  4746. +#include "Plugins/Process/Utility/GDBRemoteSignals.h"
  4747. +
  4748. +using namespace lldb;
  4749. +using namespace lldb_private;
  4750. +using namespace lldb_private::platform_wasm_server;
  4751. +
  4752. +LLDB_PLUGIN_DEFINE_ADV(PlatformRemoteWASMServer, PlatformWasm)
  4753. +
  4754. +static bool g_initialized = false;
  4755. +
  4756. +void PlatformRemoteWASMServer::Initialize() {
  4757. + Platform::Initialize();
  4758. +
  4759. + if (!g_initialized) {
  4760. + g_initialized = true;
  4761. + PluginManager::RegisterPlugin(
  4762. + PlatformRemoteWASMServer::GetPluginNameStatic(),
  4763. + PlatformRemoteWASMServer::GetDescriptionStatic(),
  4764. + PlatformRemoteWASMServer::CreateInstance);
  4765. + }
  4766. +}
  4767. +
  4768. +void PlatformRemoteWASMServer::Terminate() {
  4769. + if (g_initialized) {
  4770. + g_initialized = false;
  4771. + PluginManager::UnregisterPlugin(PlatformRemoteWASMServer::CreateInstance);
  4772. + }
  4773. +
  4774. + Platform::Terminate();
  4775. +}
  4776. +
  4777. +PlatformSP PlatformRemoteWASMServer::CreateInstance(bool force,
  4778. + const ArchSpec *arch) {
  4779. + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
  4780. + if (log) {
  4781. + const char *arch_name;
  4782. + if (arch && arch->GetArchitectureName())
  4783. + arch_name = arch->GetArchitectureName();
  4784. + else
  4785. + arch_name = "<null>";
  4786. +
  4787. + const char *triple_cstr =
  4788. + arch ? arch->GetTriple().getTriple().c_str() : "<null>";
  4789. +
  4790. + LLDB_LOGF(log, "PlatformRemoteWASMServer::%s(force=%s, arch={%s,%s})",
  4791. + __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
  4792. + }
  4793. +
  4794. + bool create = force;
  4795. + if (!create && arch && arch->IsValid()) {
  4796. + const llvm::Triple &triple = arch->GetTriple();
  4797. + if (arch->GetMachine() == llvm::Triple::wasm32 &&
  4798. + triple.getOS() == llvm::Triple::WASI) {
  4799. + create = true;
  4800. + }
  4801. + }
  4802. +
  4803. + if (create) {
  4804. + if (log)
  4805. + LLDB_LOGF(log, "PlatformRemoteWASMServer::%s() creating platform",
  4806. + __FUNCTION__);
  4807. + return PlatformSP(new PlatformRemoteWASMServer());
  4808. + }
  4809. +
  4810. + if (log)
  4811. + LLDB_LOGF(log,
  4812. + "PlatformRemoteWASMServer::%s() aborting creation of platform",
  4813. + __FUNCTION__);
  4814. + return PlatformSP();
  4815. +}
  4816. +
  4817. +ConstString PlatformRemoteWASMServer::GetPluginNameStatic() {
  4818. + static ConstString g_name("remote-wasm-server");
  4819. + return g_name;
  4820. +}
  4821. +
  4822. +ConstString PlatformRemoteWASMServer::GetPluginName() {
  4823. + return GetPluginNameStatic();
  4824. +}
  4825. +
  4826. +const char *PlatformRemoteWASMServer::GetDescriptionStatic() {
  4827. + return "A platform that uses the GDB remote protocol as the communication "
  4828. + "transport for Wasm Runtime";
  4829. +}
  4830. +
  4831. +size_t PlatformRemoteWASMServer::ConnectToWaitingProcesses(Debugger &debugger,
  4832. + Status &error) {
  4833. + std::vector<std::string> connection_urls;
  4834. + GetPendingGdbServerList(connection_urls);
  4835. +
  4836. + for (size_t i = 0; i < connection_urls.size(); ++i) {
  4837. + ConnectProcess(connection_urls[i].c_str(), "wasm", debugger, nullptr, error);
  4838. + if (error.Fail())
  4839. + return i; // We already connected to i process succsessfully
  4840. + }
  4841. + return connection_urls.size();
  4842. +}
  4843. +
  4844. +bool PlatformRemoteWASMServer::GetSupportedArchitectureAtIndex(uint32_t idx,
  4845. + ArchSpec &arch) {
  4846. + ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture();
  4847. + if (idx == 0) {
  4848. + arch = remote_arch;
  4849. + return arch.IsValid();
  4850. + } else if (idx == 1 && remote_arch.IsValid() &&
  4851. + remote_arch.GetTriple().getOS() == llvm::Triple::WASI) {
  4852. + return arch.IsValid();
  4853. + }
  4854. + return false;
  4855. +}
  4856. +
  4857. +/// Default Constructor
  4858. +PlatformRemoteWASMServer::PlatformRemoteWASMServer()
  4859. + : PlatformRemoteGDBServer()
  4860. + {
  4861. + }
  4862. \ No newline at end of file
  4863. diff --git a/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.h b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.h
  4864. new file mode 100644
  4865. index 000000000..f306a79d3
  4866. --- /dev/null
  4867. +++ b/lldb/source/Plugins/Platform/wasm-remote/PlatformRemoteWasmServer.h
  4868. @@ -0,0 +1,37 @@
  4869. +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEWASMSERVER_H
  4870. +#define LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEWASMSERVER_H
  4871. +
  4872. +#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
  4873. +#include "lldb/Target/Platform.h"
  4874. +
  4875. +namespace lldb_private {
  4876. +namespace platform_wasm_server {
  4877. +
  4878. +class PlatformRemoteWASMServer : public lldb_private::platform_gdb_server::PlatformRemoteGDBServer{
  4879. +
  4880. +public:
  4881. + static void Initialize();
  4882. +
  4883. + static void Terminate();
  4884. +
  4885. + static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
  4886. +
  4887. + static ConstString GetPluginNameStatic();
  4888. +
  4889. + static const char *GetDescriptionStatic();
  4890. +
  4891. + size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
  4892. + lldb_private::Status &error) override;
  4893. +
  4894. + bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
  4895. +
  4896. + ConstString GetPluginName() override;
  4897. +
  4898. + PlatformRemoteWASMServer();
  4899. +
  4900. +};
  4901. +
  4902. +} // namespace platform_wasm_server
  4903. +} // namespace lldb_private
  4904. +
  4905. +#endif
  4906. \ No newline at end of file
  4907. diff --git a/lldb/source/Plugins/Plugins.def.in b/lldb/source/Plugins/Plugins.def.in
  4908. index bf54598fb..b0bd7b996 100644
  4909. --- a/lldb/source/Plugins/Plugins.def.in
  4910. +++ b/lldb/source/Plugins/Plugins.def.in
  4911. @@ -31,6 +31,7 @@
  4912. @LLDB_ENUM_PLUGINS@
  4913. @LLDB_PROCESS_WINDOWS_PLUGIN@
  4914. +@LLDB_PROCESS_WASM_PLUGIN@
  4915. @LLDB_PROCESS_GDB_PLUGIN@
  4916. #undef LLDB_PLUGIN
  4917. diff --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt
  4918. index bea5bac9e..7a0855e02 100644
  4919. --- a/lldb/source/Plugins/Process/CMakeLists.txt
  4920. +++ b/lldb/source/Plugins/Process/CMakeLists.txt
  4921. @@ -18,3 +18,4 @@ add_subdirectory(Utility)
  4922. add_subdirectory(elf-core)
  4923. add_subdirectory(mach-core)
  4924. add_subdirectory(minidump)
  4925. +add_subdirectory(wasm)
  4926. diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
  4927. index 12bc7390c..707ab85e5 100644
  4928. --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
  4929. +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
  4930. @@ -285,7 +285,7 @@ bool ProcessElfCore::IsAlive() { return true; }
  4931. // Process Memory
  4932. size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
  4933. - Status &error) {
  4934. + Status &error, ExecutionContext *exe_ctx) {
  4935. // Don't allow the caching that lldb_private::Process::ReadMemory does since
  4936. // in core files we have it all cached our our core file anyway.
  4937. return DoReadMemory(addr, buf, size, error);
  4938. diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
  4939. index d8e3cc9ae..f0bf9c4d3 100644
  4940. --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
  4941. +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
  4942. @@ -84,7 +84,8 @@ public:
  4943. // Process Memory
  4944. size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
  4945. - lldb_private::Status &error) override;
  4946. + lldb_private::Status &error,
  4947. + lldb_private::ExecutionContext *exe_ctx = nullptr) override;
  4948. size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
  4949. lldb_private::Status &error) override;
  4950. diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  4951. index 6914b3734..bb8a05604 100644
  4952. --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  4953. +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  4954. @@ -334,6 +334,11 @@ ConstString ProcessGDBRemote::GetPluginName() { return GetPluginNameStatic(); }
  4955. uint32_t ProcessGDBRemote::GetPluginVersion() { return 1; }
  4956. +std::shared_ptr<ThreadGDBRemote>
  4957. +ProcessGDBRemote::CreateThread(lldb::tid_t tid) {
  4958. + return std::make_shared<ThreadGDBRemote>(*this, tid);
  4959. +}
  4960. +
  4961. bool ProcessGDBRemote::ParsePythonTargetDefinition(
  4962. const FileSpec &target_definition_fspec) {
  4963. ScriptInterpreter *interpreter =
  4964. @@ -1626,7 +1631,7 @@ bool ProcessGDBRemote::DoUpdateThreadList(ThreadList &old_thread_list,
  4965. ThreadSP thread_sp(
  4966. old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
  4967. if (!thread_sp) {
  4968. - thread_sp = std::make_shared<ThreadGDBRemote>(*this, tid);
  4969. + thread_sp = CreateThread(tid);
  4970. LLDB_LOGV(log, "Making new thread: {0} for thread ID: {1:x}.",
  4971. thread_sp.get(), thread_sp->GetID());
  4972. } else {
  4973. @@ -1742,7 +1747,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
  4974. if (!thread_sp) {
  4975. // Create the thread if we need to
  4976. - thread_sp = std::make_shared<ThreadGDBRemote>(*this, tid);
  4977. + thread_sp = CreateThread(tid);
  4978. m_thread_list_real.AddThread(thread_sp);
  4979. }
  4980. }
  4981. diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
  4982. index fe04cdddd..e4a14c645 100644
  4983. --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
  4984. +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
  4985. @@ -237,6 +237,8 @@ protected:
  4986. bool SupportsMemoryTagging() override;
  4987. + virtual std::shared_ptr<ThreadGDBRemote> CreateThread(lldb::tid_t tid);
  4988. +
  4989. /// Broadcaster event bits definitions.
  4990. enum {
  4991. eBroadcastBitAsyncContinue = (1 << 0),
  4992. diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
  4993. index 84548edb5..0ae6f7e4a 100644
  4994. --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
  4995. +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
  4996. @@ -596,7 +596,7 @@ bool ProcessMachCore::WarnBeforeDetach() const { return false; }
  4997. // Process Memory
  4998. size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size,
  4999. - Status &error) {
  5000. + Status &error, ExecutionContext *exe_ctx) {
  5001. // Don't allow the caching that lldb_private::Process::ReadMemory does since
  5002. // in core files we have it all cached our our core file anyway.
  5003. return DoReadMemory(addr, buf, size, error);
  5004. diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
  5005. index db77e96f1..1c930896c 100644
  5006. --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
  5007. +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
  5008. @@ -65,7 +65,8 @@ public:
  5009. // Process Memory
  5010. size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
  5011. - lldb_private::Status &error) override;
  5012. + lldb_private::Status &error,
  5013. + lldb_private::ExecutionContext *exe_ctx = nullptr) override;
  5014. size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
  5015. lldb_private::Status &error) override;
  5016. diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
  5017. index 385557422..d8bb21581 100644
  5018. --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
  5019. +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
  5020. @@ -374,7 +374,7 @@ bool ProcessMinidump::IsAlive() { return true; }
  5021. bool ProcessMinidump::WarnBeforeDetach() const { return false; }
  5022. size_t ProcessMinidump::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
  5023. - Status &error) {
  5024. + Status &error, ExecutionContext *exe_ctx) {
  5025. // Don't allow the caching that lldb_private::Process::ReadMemory does since
  5026. // we have it all cached in our dump file anyway.
  5027. return DoReadMemory(addr, buf, size, error);
  5028. diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
  5029. index 27b0da004..e94ecab43 100644
  5030. --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
  5031. +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
  5032. @@ -69,8 +69,8 @@ public:
  5033. bool WarnBeforeDetach() const override;
  5034. - size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
  5035. - Status &error) override;
  5036. + size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error,
  5037. + ExecutionContext *exe_ctx = nullptr) override;
  5038. size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
  5039. Status &error) override;
  5040. diff --git a/lldb/source/Plugins/Process/wasm/CMakeLists.txt b/lldb/source/Plugins/Process/wasm/CMakeLists.txt
  5041. new file mode 100644
  5042. index 000000000..61efb933f
  5043. --- /dev/null
  5044. +++ b/lldb/source/Plugins/Process/wasm/CMakeLists.txt
  5045. @@ -0,0 +1,12 @@
  5046. +
  5047. +add_lldb_library(lldbPluginProcessWasm PLUGIN
  5048. + ProcessWasm.cpp
  5049. + ThreadWasm.cpp
  5050. + UnwindWasm.cpp
  5051. +
  5052. + LINK_LIBS
  5053. + lldbCore
  5054. + ${LLDB_PLUGINS}
  5055. + LINK_COMPONENTS
  5056. + Support
  5057. + )
  5058. diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
  5059. new file mode 100644
  5060. index 000000000..9c0fc7b7f
  5061. --- /dev/null
  5062. +++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
  5063. @@ -0,0 +1,261 @@
  5064. +//===-- ProcessWasm.cpp ---------------------------------------------------===//
  5065. +//
  5066. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5067. +// See https://llvm.org/LICENSE.txt for license information.
  5068. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  5069. +//
  5070. +//===----------------------------------------------------------------------===//
  5071. +
  5072. +#include "ProcessWasm.h"
  5073. +#include "ThreadWasm.h"
  5074. +#include "lldb/Core/Module.h"
  5075. +#include "lldb/Core/PluginManager.h"
  5076. +#include "lldb/Utility/DataBufferHeap.h"
  5077. +
  5078. +#include "lldb/Target/UnixSignals.h"
  5079. +
  5080. +using namespace lldb;
  5081. +using namespace lldb_private;
  5082. +using namespace lldb_private::process_gdb_remote;
  5083. +using namespace lldb_private::wasm;
  5084. +
  5085. +LLDB_PLUGIN_DEFINE(ProcessWasm)
  5086. +
  5087. +// ProcessGDBRemote constructor
  5088. +ProcessWasm::ProcessWasm(lldb::TargetSP target_sp, ListenerSP listener_sp)
  5089. + : ProcessGDBRemote(target_sp, listener_sp) {
  5090. + /* always use linux signals for wasm process */
  5091. + m_unix_signals_sp = UnixSignals::Create(ArchSpec{"wasm32-Ant-wasi-wasm"});
  5092. +}
  5093. +
  5094. +void ProcessWasm::Initialize() {
  5095. + static llvm::once_flag g_once_flag;
  5096. +
  5097. + llvm::call_once(g_once_flag, []() {
  5098. + PluginManager::RegisterPlugin(GetPluginNameStatic(),
  5099. + GetPluginDescriptionStatic(), CreateInstance,
  5100. + DebuggerInitialize);
  5101. + });
  5102. +}
  5103. +
  5104. +void ProcessWasm::DebuggerInitialize(Debugger &debugger) {
  5105. + ProcessGDBRemote::DebuggerInitialize(debugger);
  5106. +}
  5107. +
  5108. +// PluginInterface
  5109. +ConstString ProcessWasm::GetPluginName() { return GetPluginNameStatic(); }
  5110. +
  5111. +uint32_t ProcessWasm::GetPluginVersion() { return 1; }
  5112. +
  5113. +ConstString ProcessWasm::GetPluginNameStatic() {
  5114. + static ConstString g_name("wasm");
  5115. + return g_name;
  5116. +}
  5117. +
  5118. +const char *ProcessWasm::GetPluginDescriptionStatic() {
  5119. + return "GDB Remote protocol based WebAssembly debugging plug-in.";
  5120. +}
  5121. +
  5122. +void ProcessWasm::Terminate() {
  5123. + PluginManager::UnregisterPlugin(ProcessWasm::CreateInstance);
  5124. +}
  5125. +
  5126. +lldb::ProcessSP ProcessWasm::CreateInstance(lldb::TargetSP target_sp,
  5127. + ListenerSP listener_sp,
  5128. + const FileSpec *crash_file_path,
  5129. + bool can_connect) {
  5130. + lldb::ProcessSP process_sp;
  5131. + if (crash_file_path == nullptr)
  5132. + process_sp = std::make_shared<ProcessWasm>(target_sp, listener_sp);
  5133. + return process_sp;
  5134. +}
  5135. +
  5136. +bool ProcessWasm::CanDebug(lldb::TargetSP target_sp,
  5137. + bool plugin_specified_by_name) {
  5138. + if (plugin_specified_by_name)
  5139. + return true;
  5140. +
  5141. + Module *exe_module = target_sp->GetExecutableModulePointer();
  5142. + if (exe_module) {
  5143. + ObjectFile *exe_objfile = exe_module->GetObjectFile();
  5144. + return exe_objfile->GetArchitecture().GetMachine() == llvm::Triple::wasm32;
  5145. + }
  5146. + // However, if there is no wasm module, we return false, otherwise,
  5147. + // we might use ProcessWasm to attach gdb remote.
  5148. + return false;
  5149. +}
  5150. +
  5151. +
  5152. +
  5153. +std::shared_ptr<ThreadGDBRemote> ProcessWasm::CreateThread(lldb::tid_t tid) {
  5154. + return std::make_shared<ThreadWasm>(*this, tid);
  5155. +}
  5156. +
  5157. +size_t ProcessWasm::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
  5158. + Status &error, ExecutionContext *exe_ctx) {
  5159. + wasm_addr_t wasm_addr(vm_addr);
  5160. + size_t nread = 0;
  5161. +
  5162. + switch (wasm_addr.GetType()) {
  5163. + case WasmAddressType::Memory:
  5164. + case WasmAddressType::Object:
  5165. + return ProcessGDBRemote::ReadMemory(vm_addr, buf, size, error);
  5166. + case WasmAddressType::Invalid:
  5167. + default:
  5168. + error.SetErrorStringWithFormat(
  5169. + "Wasm read failed for invalid address 0x%" PRIx64, vm_addr);
  5170. + return 0;
  5171. + }
  5172. +}
  5173. +
  5174. +size_t ProcessWasm::WasmReadMemory(uint32_t wasm_module_id, lldb::addr_t addr,
  5175. + void *buf, size_t buffer_size) {
  5176. + char packet[64];
  5177. + int packet_len =
  5178. + ::snprintf(packet, sizeof(packet), "qWasmMem:%d;%" PRIx64 ";%" PRIx64,
  5179. + wasm_module_id, static_cast<uint64_t>(addr),
  5180. + static_cast<uint64_t>(buffer_size));
  5181. + assert(packet_len + 1 < (int)sizeof(packet));
  5182. + UNUSED_IF_ASSERT_DISABLED(packet_len);
  5183. + StringExtractorGDBRemote response;
  5184. + if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, GetInterruptTimeout()) ==
  5185. + GDBRemoteCommunication::PacketResult::Success) {
  5186. + if (response.IsNormalResponse()) {
  5187. + return response.GetHexBytes(llvm::MutableArrayRef<uint8_t>(
  5188. + static_cast<uint8_t *>(buf), buffer_size),
  5189. + '\xdd');
  5190. + }
  5191. + }
  5192. + return 0;
  5193. +}
  5194. +
  5195. +size_t ProcessWasm::WasmReadData(uint32_t wasm_module_id, lldb::addr_t addr,
  5196. + void *buf, size_t buffer_size) {
  5197. + char packet[64];
  5198. + int packet_len =
  5199. + ::snprintf(packet, sizeof(packet), "qWasmData:%d;%" PRIx64 ";%" PRIx64,
  5200. + wasm_module_id, static_cast<uint64_t>(addr),
  5201. + static_cast<uint64_t>(buffer_size));
  5202. + assert(packet_len + 1 < (int)sizeof(packet));
  5203. + UNUSED_IF_ASSERT_DISABLED(packet_len);
  5204. + StringExtractorGDBRemote response;
  5205. + if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, GetInterruptTimeout()) ==
  5206. + GDBRemoteCommunication::PacketResult::Success) {
  5207. + if (response.IsNormalResponse()) {
  5208. + return response.GetHexBytes(llvm::MutableArrayRef<uint8_t>(
  5209. + static_cast<uint8_t *>(buf), buffer_size),
  5210. + '\xdd');
  5211. + }
  5212. + }
  5213. + return 0;
  5214. +}
  5215. +
  5216. +bool ProcessWasm::GetWasmLocal(int frame_index, int index, void *buf,
  5217. + size_t buffer_size, size_t &size) {
  5218. + StreamString packet;
  5219. + packet.Printf("qWasmLocal:");
  5220. + packet.Printf("%d;%d", frame_index, index);
  5221. + StringExtractorGDBRemote response;
  5222. + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
  5223. + GDBRemoteCommunication::PacketResult::Success) {
  5224. + return false;
  5225. + }
  5226. +
  5227. + if (!response.IsNormalResponse()) {
  5228. + return false;
  5229. + }
  5230. +
  5231. + DataBufferSP buffer_sp(
  5232. + new DataBufferHeap(response.GetStringRef().size() / 2, 0));
  5233. + response.GetHexBytes(buffer_sp->GetData(), '\xcc');
  5234. + size = buffer_sp->GetByteSize();
  5235. + if (size <= buffer_size) {
  5236. + memcpy(buf, buffer_sp->GetBytes(), size);
  5237. + return true;
  5238. + }
  5239. +
  5240. + return false;
  5241. +}
  5242. +
  5243. +bool ProcessWasm::GetWasmGlobal(int frame_index, int index, void *buf,
  5244. + size_t buffer_size, size_t &size) {
  5245. + StreamString packet;
  5246. + packet.PutCString("qWasmGlobal:");
  5247. + packet.Printf("%d;%d", frame_index, index);
  5248. + StringExtractorGDBRemote response;
  5249. + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
  5250. + GDBRemoteCommunication::PacketResult::Success) {
  5251. + return false;
  5252. + }
  5253. +
  5254. + if (!response.IsNormalResponse()) {
  5255. + return false;
  5256. + }
  5257. +
  5258. + DataBufferSP buffer_sp(
  5259. + new DataBufferHeap(response.GetStringRef().size() / 2, 0));
  5260. + response.GetHexBytes(buffer_sp->GetData(), '\xcc');
  5261. + size = buffer_sp->GetByteSize();
  5262. + if (size <= buffer_size) {
  5263. + memcpy(buf, buffer_sp->GetBytes(), size);
  5264. + return true;
  5265. + }
  5266. +
  5267. + return false;
  5268. +}
  5269. +
  5270. +bool ProcessWasm::GetWasmStackValue(int frame_index, int index, void *buf,
  5271. + size_t buffer_size, size_t &size) {
  5272. + StreamString packet;
  5273. + packet.PutCString("qWasmStackValue:");
  5274. + packet.Printf("%d;%d", frame_index, index);
  5275. + StringExtractorGDBRemote response;
  5276. + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
  5277. + GDBRemoteCommunication::PacketResult::Success) {
  5278. + return false;
  5279. + }
  5280. +
  5281. + if (!response.IsNormalResponse()) {
  5282. + return false;
  5283. + }
  5284. +
  5285. + DataBufferSP buffer_sp(
  5286. + new DataBufferHeap(response.GetStringRef().size() / 2, 0));
  5287. + response.GetHexBytes(buffer_sp->GetData(), '\xcc');
  5288. + size = buffer_sp->GetByteSize();
  5289. + if (size <= buffer_size) {
  5290. + memcpy(buf, buffer_sp->GetBytes(), size);
  5291. + return true;
  5292. + }
  5293. +
  5294. + return false;
  5295. +}
  5296. +
  5297. +bool ProcessWasm::GetWasmCallStack(lldb::tid_t tid,
  5298. + std::vector<lldb::addr_t> &call_stack_pcs) {
  5299. + call_stack_pcs.clear();
  5300. + StreamString packet;
  5301. + packet.Printf("qWasmCallStack:");
  5302. + packet.Printf("%llx", tid);
  5303. + StringExtractorGDBRemote response;
  5304. + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
  5305. + GDBRemoteCommunication::PacketResult::Success) {
  5306. + return false;
  5307. + }
  5308. +
  5309. + if (!response.IsNormalResponse()) {
  5310. + return false;
  5311. + }
  5312. +
  5313. + addr_t buf[1024 / sizeof(addr_t)];
  5314. + size_t bytes = response.GetHexBytes(
  5315. + llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, sizeof(buf)), '\xdd');
  5316. + if (bytes == 0) {
  5317. + return false;
  5318. + }
  5319. +
  5320. + for (size_t i = 0; i < bytes / sizeof(addr_t); i++) {
  5321. + call_stack_pcs.push_back(buf[i]);
  5322. + }
  5323. + return true;
  5324. +}
  5325. diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.h b/lldb/source/Plugins/Process/wasm/ProcessWasm.h
  5326. new file mode 100644
  5327. index 000000000..d3aece7a6
  5328. --- /dev/null
  5329. +++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.h
  5330. @@ -0,0 +1,128 @@
  5331. +//===-- ProcessWasm.h -------------------------------------------*- C++ -*-===//
  5332. +//
  5333. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5334. +// See https://llvm.org/LICENSE.txt for license information.
  5335. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  5336. +//
  5337. +//===----------------------------------------------------------------------===//
  5338. +
  5339. +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_WASM_PROCESSWASM_H
  5340. +#define LLDB_SOURCE_PLUGINS_PROCESS_WASM_PROCESSWASM_H
  5341. +
  5342. +#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
  5343. +#include "lldb/Target/RegisterContext.h"
  5344. +
  5345. +namespace lldb_private {
  5346. +namespace wasm {
  5347. +
  5348. +// Each WebAssembly module has separated address spaces for Code and Memory.
  5349. +// A WebAssembly module also has a Data section which, when the module is
  5350. +// loaded, gets mapped into a region in the module Memory.
  5351. +// For the purpose of debugging, we can represent all these separated 32-bit
  5352. +// address spaces with a single virtual 64-bit address space.
  5353. +//
  5354. +// Struct wasm_addr_t provides this encoding using bitfields
  5355. +//
  5356. +enum WasmAddressType {
  5357. + Memory = 0x00,
  5358. + Object = 0x01,
  5359. + Invalid = 0x03
  5360. +};
  5361. +struct wasm_addr_t {
  5362. + uint64_t offset : 32;
  5363. + uint64_t module_id : 30;
  5364. + uint64_t type : 2;
  5365. +
  5366. + wasm_addr_t(lldb::addr_t addr)
  5367. + : type(addr >> 62), module_id((addr & 0x00ffffff00000000) >> 32),
  5368. + offset(addr & 0x00000000ffffffff) {}
  5369. +
  5370. + wasm_addr_t(WasmAddressType type_, uint32_t module_id_, uint32_t offset_)
  5371. + : type(type_), module_id(module_id_), offset(offset_) {}
  5372. +
  5373. + WasmAddressType GetType() { return static_cast<WasmAddressType>(type); }
  5374. + operator lldb::addr_t() { return *(uint64_t *)this; }
  5375. +};
  5376. +
  5377. +/// ProcessWasm provides the access to the Wasm program state
  5378. +/// retrieved from the Wasm engine.
  5379. +class ProcessWasm : public process_gdb_remote::ProcessGDBRemote {
  5380. +public:
  5381. + ProcessWasm(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
  5382. + ~ProcessWasm() override = default;
  5383. +
  5384. + static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
  5385. + lldb::ListenerSP listener_sp,
  5386. + const FileSpec *crash_file_path,
  5387. + bool can_connect);
  5388. +
  5389. + static void Initialize();
  5390. + static void DebuggerInitialize(Debugger &debugger);
  5391. + static void Terminate();
  5392. + static ConstString GetPluginNameStatic();
  5393. + static const char *GetPluginDescriptionStatic();
  5394. +
  5395. + /// PluginInterface protocol.
  5396. + /// \{
  5397. + ConstString GetPluginName() override;
  5398. + uint32_t GetPluginVersion() override;
  5399. + /// \}
  5400. +
  5401. + /// Process protocol.
  5402. + /// \{
  5403. + size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error,
  5404. + ExecutionContext *exe_ctx = nullptr) override;
  5405. + /// \}
  5406. +
  5407. + /// Query the value of a WebAssembly local variable from the WebAssembly
  5408. + /// remote process.
  5409. + bool GetWasmLocal(int frame_index, int index, void *buf, size_t buffer_size,
  5410. + size_t &size);
  5411. +
  5412. + /// Query the value of a WebAssembly global variable from the WebAssembly
  5413. + /// remote process.
  5414. + bool GetWasmGlobal(int frame_index, int index, void *buf, size_t buffer_size,
  5415. + size_t &size);
  5416. +
  5417. + /// Query the value of an item in the WebAssembly operand stack from the
  5418. + /// WebAssembly remote process.
  5419. + bool GetWasmStackValue(int frame_index, int index, void *buf,
  5420. + size_t buffer_size, size_t &size);
  5421. +
  5422. + /// Read from the WebAssembly Memory space.
  5423. + size_t WasmReadMemory(uint32_t wasm_module_id, lldb::addr_t addr, void *buf,
  5424. + size_t buffer_size);
  5425. +
  5426. + /// Read from the WebAssembly Data space.
  5427. + size_t WasmReadData(uint32_t wasm_module_id, lldb::addr_t addr, void *buf,
  5428. + size_t buffer_size);
  5429. +
  5430. + /// Retrieve the current call stack from the WebAssembly remote process.
  5431. + bool GetWasmCallStack(lldb::tid_t tid,
  5432. + std::vector<lldb::addr_t> &call_stack_pcs);
  5433. +
  5434. + // Check if a given Process
  5435. + bool CanDebug(lldb::TargetSP target_sp,
  5436. + bool plugin_specified_by_name) override;
  5437. +
  5438. +protected:
  5439. + /// ProcessGDBRemote protocol.
  5440. + /// \{
  5441. + std::shared_ptr<process_gdb_remote::ThreadGDBRemote>
  5442. + CreateThread(lldb::tid_t tid) override;
  5443. + /// \}
  5444. +
  5445. +private:
  5446. + friend class UnwindWasm;
  5447. + process_gdb_remote::GDBRemoteDynamicRegisterInfoSP &GetRegisterInfo() {
  5448. + return m_register_info_sp;
  5449. + }
  5450. +
  5451. + ProcessWasm(const ProcessWasm &);
  5452. + const ProcessWasm &operator=(const ProcessWasm &) = delete;
  5453. +};
  5454. +
  5455. +} // namespace wasm
  5456. +} // namespace lldb_private
  5457. +
  5458. +#endif // LLDB_SOURCE_PLUGINS_PROCESS_WASM_PROCESSWASM_H
  5459. diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp
  5460. new file mode 100644
  5461. index 000000000..fa02073e7
  5462. --- /dev/null
  5463. +++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp
  5464. @@ -0,0 +1,35 @@
  5465. +//===-- ThreadWasm.cpp ----------------------------------------------------===//
  5466. +//
  5467. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5468. +// See https://llvm.org/LICENSE.txt for license information.
  5469. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  5470. +//
  5471. +//===----------------------------------------------------------------------===//
  5472. +
  5473. +#include "ThreadWasm.h"
  5474. +
  5475. +#include "ProcessWasm.h"
  5476. +#include "UnwindWasm.h"
  5477. +#include "lldb/Target/Target.h"
  5478. +
  5479. +using namespace lldb;
  5480. +using namespace lldb_private;
  5481. +using namespace lldb_private::wasm;
  5482. +
  5483. +Unwind &ThreadWasm::GetUnwinder() {
  5484. + if (!m_unwinder_up) {
  5485. + assert(CalculateTarget()->GetArchitecture().GetMachine() ==
  5486. + llvm::Triple::wasm32);
  5487. + m_unwinder_up.reset(new wasm::UnwindWasm(*this));
  5488. + }
  5489. + return *m_unwinder_up;
  5490. +}
  5491. +
  5492. +bool ThreadWasm::GetWasmCallStack(std::vector<lldb::addr_t> &call_stack_pcs) {
  5493. + ProcessSP process_sp(GetProcess());
  5494. + if (process_sp) {
  5495. + ProcessWasm *wasm_process = static_cast<ProcessWasm *>(process_sp.get());
  5496. + return wasm_process->GetWasmCallStack(GetID(), call_stack_pcs);
  5497. + }
  5498. + return false;
  5499. +}
  5500. diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.h b/lldb/source/Plugins/Process/wasm/ThreadWasm.h
  5501. new file mode 100644
  5502. index 000000000..0a33c07de
  5503. --- /dev/null
  5504. +++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.h
  5505. @@ -0,0 +1,41 @@
  5506. +//===-- ThreadWasm.h --------------------------------------------*- C++ -*-===//
  5507. +//
  5508. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5509. +// See https://llvm.org/LICENSE.txt for license information.
  5510. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  5511. +//
  5512. +//===----------------------------------------------------------------------===//
  5513. +
  5514. +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_WASM_THREADWASM_H
  5515. +#define LLDB_SOURCE_PLUGINS_PROCESS_WASM_THREADWASM_H
  5516. +
  5517. +#include "Plugins/Process/gdb-remote/ThreadGDBRemote.h"
  5518. +
  5519. +namespace lldb_private {
  5520. +namespace wasm {
  5521. +
  5522. +/// ProcessWasm provides the access to the Wasm program state
  5523. +/// retrieved from the Wasm engine.
  5524. +class ThreadWasm : public process_gdb_remote::ThreadGDBRemote {
  5525. +public:
  5526. + ThreadWasm(Process &process, lldb::tid_t tid)
  5527. + : process_gdb_remote::ThreadGDBRemote(process, tid) {}
  5528. + ~ThreadWasm() override = default;
  5529. +
  5530. + /// Retrieve the current call stack from the WebAssembly remote process.
  5531. + bool GetWasmCallStack(std::vector<lldb::addr_t> &call_stack_pcs);
  5532. +
  5533. +protected:
  5534. + /// Thread protocol.
  5535. + /// \{
  5536. + Unwind &GetUnwinder() override;
  5537. + /// \}
  5538. +
  5539. + ThreadWasm(const ThreadWasm &);
  5540. + const ThreadWasm &operator=(const ThreadWasm &) = delete;
  5541. +};
  5542. +
  5543. +} // namespace wasm
  5544. +} // namespace lldb_private
  5545. +
  5546. +#endif // LLDB_SOURCE_PLUGINS_PROCESS_WASM_THREADWASM_H
  5547. diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
  5548. new file mode 100644
  5549. index 000000000..1a195cb93
  5550. --- /dev/null
  5551. +++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
  5552. @@ -0,0 +1,74 @@
  5553. +//===-- UnwindWasm.cpp ----------------------------------------------------===//
  5554. +//
  5555. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5556. +// See https://llvm.org/LICENSE.txt for license information.
  5557. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  5558. +//
  5559. +//===----------------------------------------------------------------------===//
  5560. +
  5561. +#include "UnwindWasm.h"
  5562. +#include "Plugins/Process/gdb-remote/ThreadGDBRemote.h"
  5563. +#include "Plugins/Process/wasm/ProcessWasm.h"
  5564. +#include "Plugins/Process/wasm/ThreadWasm.h"
  5565. +
  5566. +using namespace lldb;
  5567. +using namespace lldb_private;
  5568. +using namespace process_gdb_remote;
  5569. +using namespace wasm;
  5570. +
  5571. +class WasmGDBRemoteRegisterContext : public GDBRemoteRegisterContext {
  5572. +public:
  5573. + WasmGDBRemoteRegisterContext(ThreadGDBRemote &thread,
  5574. + uint32_t concrete_frame_idx,
  5575. + GDBRemoteDynamicRegisterInfoSP &reg_info_sp,
  5576. + uint64_t pc)
  5577. + : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false,
  5578. + false) {
  5579. + PrivateSetRegisterValue(0, pc);
  5580. + }
  5581. +};
  5582. +
  5583. +lldb::RegisterContextSP
  5584. +UnwindWasm::DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
  5585. + if (m_frames.size() <= frame->GetFrameIndex()) {
  5586. + return lldb::RegisterContextSP();
  5587. + }
  5588. +
  5589. + ThreadSP thread = frame->GetThread();
  5590. + ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *>(thread.get());
  5591. + ProcessWasm *wasm_process =
  5592. + static_cast<ProcessWasm *>(thread->GetProcess().get());
  5593. + std::shared_ptr<GDBRemoteRegisterContext> reg_ctx_sp =
  5594. + std::make_shared<WasmGDBRemoteRegisterContext>(
  5595. + *gdb_thread, frame->GetConcreteFrameIndex(),
  5596. + wasm_process->GetRegisterInfo(), m_frames[frame->GetFrameIndex()]);
  5597. + return reg_ctx_sp;
  5598. +}
  5599. +
  5600. +uint32_t UnwindWasm::DoGetFrameCount() {
  5601. + if (!m_unwind_complete) {
  5602. + m_unwind_complete = true;
  5603. + m_frames.clear();
  5604. +
  5605. + ThreadWasm &wasm_thread = static_cast<ThreadWasm &>(GetThread());
  5606. + if (!wasm_thread.GetWasmCallStack(m_frames))
  5607. + m_frames.clear();
  5608. + }
  5609. + return m_frames.size();
  5610. +}
  5611. +
  5612. +bool UnwindWasm::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
  5613. + lldb::addr_t &pc,
  5614. + bool &behaves_like_zeroth_frame) {
  5615. + if (m_frames.size() == 0) {
  5616. + DoGetFrameCount();
  5617. + }
  5618. +
  5619. + if (frame_idx < m_frames.size()) {
  5620. + behaves_like_zeroth_frame = (frame_idx == 0);
  5621. + cfa = 0;
  5622. + pc = m_frames[frame_idx];
  5623. + return true;
  5624. + }
  5625. + return false;
  5626. +}
  5627. \ No newline at end of file
  5628. diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.h b/lldb/source/Plugins/Process/wasm/UnwindWasm.h
  5629. new file mode 100644
  5630. index 000000000..9bd1dac9a
  5631. --- /dev/null
  5632. +++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.h
  5633. @@ -0,0 +1,55 @@
  5634. +//===-- UnwindWasm.h --------------------------------------------*- C++ -*-===//
  5635. +//
  5636. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5637. +// See https://llvm.org/LICENSE.txt for license information.
  5638. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  5639. +//
  5640. +//===----------------------------------------------------------------------===//
  5641. +
  5642. +#ifndef lldb_UnwindWasm_h_
  5643. +#define lldb_UnwindWasm_h_
  5644. +
  5645. +#include "lldb/Target/RegisterContext.h"
  5646. +#include "lldb/Target/Unwind.h"
  5647. +#include <vector>
  5648. +
  5649. +namespace lldb_private {
  5650. +namespace wasm {
  5651. +
  5652. +/// UnwindWasm manages stack unwinding for a WebAssembly process.
  5653. +class UnwindWasm : public lldb_private::Unwind {
  5654. +public:
  5655. + UnwindWasm(lldb_private::Thread &thread)
  5656. + : Unwind(thread), m_frames(), m_unwind_complete(false) {}
  5657. + ~UnwindWasm() override = default;
  5658. +
  5659. +protected:
  5660. + /// Unwind protocol.
  5661. + /// \{
  5662. + void DoClear() override {
  5663. + m_frames.clear();
  5664. + m_unwind_complete = false;
  5665. + }
  5666. +
  5667. + uint32_t DoGetFrameCount() override;
  5668. +
  5669. + bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
  5670. + lldb::addr_t &pc,
  5671. + bool &behaves_like_zeroth_frame) override;
  5672. +
  5673. + lldb::RegisterContextSP
  5674. + DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
  5675. + /// \}
  5676. +
  5677. +private:
  5678. + std::vector<lldb::addr_t> m_frames;
  5679. + bool m_unwind_complete;
  5680. +
  5681. + UnwindWasm(const UnwindWasm &);
  5682. + const UnwindWasm &operator=(const UnwindWasm &) = delete;
  5683. +};
  5684. +
  5685. +} // namespace wasm
  5686. +} // namespace lldb_private
  5687. +
  5688. +#endif // lldb_UnwindWasm_h_
  5689. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  5690. index ccaf31317..c3ef5aebd 100644
  5691. --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  5692. +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  5693. @@ -3212,8 +3212,13 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
  5694. GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString();
  5695. }
  5696. - if (tag == DW_TAG_formal_parameter)
  5697. + if (tag == DW_TAG_formal_parameter) {
  5698. scope = eValueTypeVariableArgument;
  5699. + // For Wasm dwarft, pamameter may don't have location attr,
  5700. + // so set module here
  5701. + if (!location.GetModule())
  5702. + location.SetModule(module);
  5703. + }
  5704. else {
  5705. // DWARF doesn't specify if a DW_TAG_variable is a local, global
  5706. // or static variable, so we have to do a little digging:
  5707. diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp
  5708. index b660c310e..cd76421ce 100644
  5709. --- a/lldb/source/Target/PathMappingList.cpp
  5710. +++ b/lldb/source/Target/PathMappingList.cpp
  5711. @@ -218,7 +218,12 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co
  5712. }
  5713. llvm::Optional<FileSpec> PathMappingList::FindFile(const FileSpec &orig_spec) const {
  5714. - if (auto remapped = RemapPath(orig_spec.GetPath(), /*only_if_exists=*/true))
  5715. + // We must normalize the orig_spec again using the host's path style,
  5716. + // otherwise there will be mismatch between the host and remote platform
  5717. + // if they use different path styles.
  5718. + if (auto remapped = RemapPath(
  5719. + NormalizePath(ConstString(orig_spec.GetCString())).GetStringRef(),
  5720. + /*only_if_exists=*/true))
  5721. return remapped;
  5722. return {};
  5723. diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
  5724. index a77ecddfb..e257f9350 100644
  5725. --- a/lldb/source/Target/Platform.cpp
  5726. +++ b/lldb/source/Target/Platform.cpp
  5727. @@ -1970,6 +1970,12 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
  5728. trap_opcode_size = sizeof(g_i386_opcode);
  5729. } break;
  5730. + case llvm::Triple::wasm32: {
  5731. + static const uint8_t g_wasm_opcode[] = {0x00}; // unreachable
  5732. + trap_opcode = g_wasm_opcode;
  5733. + trap_opcode_size = sizeof(g_wasm_opcode);
  5734. + } break;
  5735. +
  5736. default:
  5737. return 0;
  5738. }
  5739. diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
  5740. index 8ecc66b59..f14898791 100644
  5741. --- a/lldb/source/Target/Process.cpp
  5742. +++ b/lldb/source/Target/Process.cpp
  5743. @@ -1892,7 +1892,8 @@ Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) {
  5744. // code
  5745. //#define VERIFY_MEMORY_READS
  5746. -size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) {
  5747. +size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error,
  5748. + ExecutionContext *exe_ctx) {
  5749. error.Clear();
  5750. if (!GetDisableMemoryCache()) {
  5751. #if defined(VERIFY_MEMORY_READS)
  5752. diff --git a/lldb/source/Target/ProcessTrace.cpp b/lldb/source/Target/ProcessTrace.cpp
  5753. index c878a2ac4..ad5945b0a 100644
  5754. --- a/lldb/source/Target/ProcessTrace.cpp
  5755. +++ b/lldb/source/Target/ProcessTrace.cpp
  5756. @@ -88,7 +88,7 @@ void ProcessTrace::RefreshStateAfterStop() {}
  5757. Status ProcessTrace::DoDestroy() { return Status(); }
  5758. size_t ProcessTrace::ReadMemory(addr_t addr, void *buf, size_t size,
  5759. - Status &error) {
  5760. + Status &error, ExecutionContext *exe_ctx) {
  5761. // Don't allow the caching that lldb_private::Process::ReadMemory does since
  5762. // we have it all cached in the trace files.
  5763. return DoReadMemory(addr, buf, size, error);
  5764. diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp
  5765. index 896e647bb..f76307016 100644
  5766. --- a/lldb/source/Target/ThreadPlanStepRange.cpp
  5767. +++ b/lldb/source/Target/ThreadPlanStepRange.cpp
  5768. @@ -334,7 +334,10 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
  5769. // If we didn't find a branch, run to the end of the range.
  5770. if (branch_index == UINT32_MAX) {
  5771. uint32_t last_index = instructions->GetSize() - 1;
  5772. - if (last_index - pc_index > 1) {
  5773. + /* This line causes the "step over was treated as step in" issue, we
  5774. + * modify it as a workaround */
  5775. + /* The origin line is: if (last_index - pc_index > 1) { */
  5776. + if (last_index - pc_index >= 1) {
  5777. InstructionSP last_inst =
  5778. instructions->GetInstructionAtIndex(last_index);
  5779. size_t last_inst_size = last_inst->GetOpcode().GetByteSize();
  5780. diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp
  5781. index 4ec2e25c7..24c88fe9a 100644
  5782. --- a/lldb/source/Target/UnixSignals.cpp
  5783. +++ b/lldb/source/Target/UnixSignals.cpp
  5784. @@ -46,6 +46,8 @@ lldb::UnixSignalsSP UnixSignals::Create(const ArchSpec &arch) {
  5785. return std::make_shared<FreeBSDSignals>();
  5786. case llvm::Triple::NetBSD:
  5787. return std::make_shared<NetBSDSignals>();
  5788. + case llvm::Triple::WASI:
  5789. + return std::make_shared<LinuxSignals>();
  5790. default:
  5791. return std::make_shared<UnixSignals>();
  5792. }
  5793. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h
  5794. index 4310ba9ce..297b33879 100644
  5795. --- a/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h
  5796. +++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h
  5797. @@ -13,6 +13,7 @@
  5798. #ifndef LLVM_EXECUTIONENGINE_ORC_ORCRPCEXECUTORPROCESSCONTROL_H
  5799. #define LLVM_EXECUTIONENGINE_ORC_ORCRPCEXECUTORPROCESSCONTROL_H
  5800. +#include "llvm/ExecutionEngine/Orc/Core.h"
  5801. #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
  5802. #include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
  5803. #include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
  5804. diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
  5805. index 753b1998c..27370c62d 100644
  5806. --- a/llvm/include/llvm/Support/MathExtras.h
  5807. +++ b/llvm/include/llvm/Support/MathExtras.h
  5808. @@ -16,6 +16,7 @@
  5809. #include "llvm/Support/Compiler.h"
  5810. #include <cassert>
  5811. #include <climits>
  5812. +#include <limits>
  5813. #include <cmath>
  5814. #include <cstdint>
  5815. #include <cstring>