lldb_wasm.patch 217 KB

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