123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891 |
- ====================CC-PDDC====================
- Doug Lea and released to the public domain, as explained at
- http://creativecommons.org/licenses/publicdomain. Send questions,
- ====================COPYRIGHT====================
- Copyright (C) 1998 Geoffrey Keating
- Copyright (C) 2001 John Hornkvist
- Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
- ====================COPYRIGHT====================
- Copyright (C) 2003-2004, 2006, 2009-2017 Free Software Foundation, Inc.
- ====================COPYRIGHT====================
- aix.S - Copyright (c) 2002, 2009 Free Software Foundation, Inc.
- based on darwin.S by John Hornkvist
- ====================COPYRIGHT====================
- aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.
- based on darwin_closure.S
- ====================COPYRIGHT====================
- asm.h - Copyright (c) 1998 Geoffrey Keating
- ====================COPYRIGHT====================
- closures.c - Copyright (c) 2019 Anthony Green
- Copyright (c) 2007, 2009, 2010 Red Hat, Inc.
- Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
- Copyright (c) 2011 Plausible Labs Cooperative, Inc.
- ====================COPYRIGHT====================
- darwin.S - Copyright (c) 2000 John Hornkvist
- Copyright (c) 2004, 2010 Free Software Foundation, Inc.
- ====================COPYRIGHT====================
- darwin_closure.S - Copyright (c) 2002, 2003, 2004, 2010,
- Free Software Foundation, Inc.
- based on ppc_closure.S
- ====================COPYRIGHT====================
- ffi.c - Copyright (C) 2013 IBM
- Copyright (C) 2011 Anthony Green
- Copyright (C) 2011 Kyle Moffett
- Copyright (C) 2008 Red Hat, Inc
- Copyright (C) 2007, 2008 Free Software Foundation, Inc
- Copyright (c) 1998 Geoffrey Keating
- ====================COPYRIGHT====================
- ffi.c - Copyright (c) 2011 Timothy Wall
- Copyright (c) 2011 Plausible Labs Cooperative, Inc.
- Copyright (c) 2011 Anthony Green
- Copyright (c) 2011 Free Software Foundation
- Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
- ====================COPYRIGHT====================
- ffi.c - Copyright (c) 2017 Anthony Green
- Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
- Copyright (c) 2002 Ranjit Mathew
- Copyright (c) 2002 Bo Thorsen
- Copyright (c) 2002 Roger Sayle
- Copyright (C) 2008, 2010 Free Software Foundation, Inc.
- ====================COPYRIGHT====================
- ffi64.c - Copyright (c) 2011, 2018 Anthony Green
- Copyright (c) 2013 The Written Word, Inc.
- Copyright (c) 2008, 2010 Red Hat, Inc.
- Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
- ====================COPYRIGHT====================
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
- Copyright (c) 1996-2003 Red Hat, Inc.
- ====================COPYRIGHT====================
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (c) 2010 CodeSourcery
- Copyright (c) 1996-2003 Red Hat, Inc.
- ====================COPYRIGHT====================
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- ====================COPYRIGHT====================
- ffiw64.c - Copyright (c) 2018 Anthony Green
- Copyright (c) 2014 Red Hat, Inc.
- ====================COPYRIGHT====================
- java_raw_api.c - Copyright (c) 1999, 2007, 2008 Red Hat, Inc.
- ====================COPYRIGHT====================
- libffi 3.3 - Copyright (c) 2011, 2014, 2019 Anthony Green
- - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
- ====================COPYRIGHT====================
- prep_cif.c - Copyright (c) 2011, 2012 Anthony Green
- Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
- ====================COPYRIGHT====================
- raw_api.c - Copyright (c) 1999, 2008 Red Hat, Inc.
- ====================COPYRIGHT====================
- sysv.S - Copyright (c) 1998 Geoffrey Keating
- Copyright (C) 2007 Free Software Foundation, Inc
- ====================COPYRIGHT====================
- sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
- Copyright (c) 2011 Plausible Labs Cooperative, Inc.
- Copyright (c) 2019 Microsoft Corporation.
- ====================COPYRIGHT====================
- sysv.S - Copyright (c) 2017 Anthony Green
- - Copyright (c) 2013 The Written Word, Inc.
- - Copyright (c) 1996,1998,2001-2003,2005,2008,2010 Red Hat, Inc.
- ====================COPYRIGHT====================
- sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
- Copyright (c) 2008 Red Hat, Inc.
- ====================COPYRIGHT====================
- types.c - Copyright (c) 1996, 1998 Red Hat, Inc.
- ====================COPYRIGHT====================
- unix64.S - Copyright (c) 2013 The Written Word, Inc.
- - Copyright (c) 2008 Red Hat, Inc
- - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
- ====================COPYRIGHT====================
- Copyright 1993 Bill Triggs <Bill.Triggs@inrialpes.fr>
- Copyright 1995-2017 Bruno Haible <bruno@clisp.org>
- ====================COPYRIGHT====================
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- ====================COPYRIGHT====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- ====================COPYRIGHT====================
- libffi - Copyright (c) 1996-2019 Anthony Green, Red Hat, Inc and others.
- See source files for details.
- ====================COPYRIGHT====================
- programs whose distribution conditions are different, write to the author
- to ask for permission. For software which is copyrighted by the Free
- Software Foundation, write to the Free Software Foundation; we sometimes
- make exceptions for this. Our decision will be guided by the two goals
- of preserving the free status of all derivatives of our free software and
- of promoting the sharing and reuse of software generally.
- ====================File: .yandex_meta/files/configs/aarch64-apple-iphoneos/include/ffitarget.h====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- #ifdef __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #elif defined(_M_ARM64)
- #define FFI_SIZEOF_ARG 8
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- typedef enum ffi_abi
- {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #define FFI_TRAMPOLINE_SIZE 24
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #ifdef _M_ARM64
- #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
- #endif
- /* ---- Internal ---- */
- #if defined (__APPLE__)
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
- #elif !defined(_M_ARM64)
- /* iOS and Windows reserve x18 for the system. Disable Go closures until
- a new static chain is chosen. */
- #define FFI_GO_CLOSURES 1
- #endif
- #ifndef _M_ARM64
- /* No complex type on Windows */
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/aarch64-apple-macos/include/ffitarget.h====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- #ifdef __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #elif defined(_M_ARM64)
- #define FFI_SIZEOF_ARG 8
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- typedef enum ffi_abi
- {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #define FFI_TRAMPOLINE_SIZE 24
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #ifdef _M_ARM64
- #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
- #endif
- /* ---- Internal ---- */
- #if defined (__APPLE__)
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
- #elif !defined(_M_ARM64)
- /* iOS and Windows reserve x18 for the system. Disable Go closures until
- a new static chain is chosen. */
- #define FFI_GO_CLOSURES 1
- #endif
- #ifndef _M_ARM64
- /* No complex type on Windows */
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/aarch64-unknown-linux-android21/include/ffitarget.h====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- #ifdef __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #elif defined(_M_ARM64)
- #define FFI_SIZEOF_ARG 8
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- typedef enum ffi_abi
- {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #define FFI_TRAMPOLINE_SIZE 24
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #ifdef _M_ARM64
- #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
- #endif
- /* ---- Internal ---- */
- #if defined (__APPLE__)
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
- #elif !defined(_M_ARM64)
- /* iOS and Windows reserve x18 for the system. Disable Go closures until
- a new static chain is chosen. */
- #define FFI_GO_CLOSURES 1
- #endif
- #ifndef _M_ARM64
- /* No complex type on Windows */
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/aarch64-unknown-linux-gnu/include/ffitarget.h====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- #ifdef __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #elif defined(_M_ARM64)
- #define FFI_SIZEOF_ARG 8
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- typedef enum ffi_abi
- {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #define FFI_TRAMPOLINE_SIZE 24
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #ifdef _M_ARM64
- #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
- #endif
- /* ---- Internal ---- */
- #if defined (__APPLE__)
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
- #elif !defined(_M_ARM64)
- /* iOS and Windows reserve x18 for the system. Disable Go closures until
- a new static chain is chosen. */
- #define FFI_GO_CLOSURES 1
- #endif
- #ifndef _M_ARM64
- /* No complex type on Windows */
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/armv7a-unknown-linux-androideabi16/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (c) 2010 CodeSourcery
- Copyright (c) 1996-2003 Red Hat, Inc.
- Target configuration macros for ARM.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_VFP,
- FFI_LAST_ABI,
- #if defined(__ARM_PCS_VFP) || defined(_M_ARM)
- FFI_DEFAULT_ABI = FFI_VFP,
- #else
- FFI_DEFAULT_ABI = FFI_SYSV,
- #endif
- } ffi_abi;
- #endif
- #define FFI_EXTRA_CIF_FIELDS \
- int vfp_used; \
- unsigned short vfp_reg_free, vfp_nargs; \
- signed char vfp_args[16] \
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #ifndef _M_ARM
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 12
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 8
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #ifdef _MSC_VER
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12
- #else
- #define FFI_TRAMPOLINE_SIZE 12
- #endif
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/armv7a-unknown-linux-gnueabihf/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (c) 2010 CodeSourcery
- Copyright (c) 1996-2003 Red Hat, Inc.
- Target configuration macros for ARM.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_VFP,
- FFI_LAST_ABI,
- #if defined(__ARM_PCS_VFP) || defined(_M_ARM)
- FFI_DEFAULT_ABI = FFI_VFP,
- #else
- FFI_DEFAULT_ABI = FFI_SYSV,
- #endif
- } ffi_abi;
- #endif
- #define FFI_EXTRA_CIF_FIELDS \
- int vfp_used; \
- unsigned short vfp_reg_free, vfp_nargs; \
- signed char vfp_args[16] \
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #ifndef _M_ARM
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 12
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 8
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #ifdef _MSC_VER
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12
- #else
- #define FFI_TRAMPOLINE_SIZE 12
- #endif
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/i386-microsoft-windows/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- /* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP
- + 8 bytes of pointer. */
- # define FFI_TRAMPOLINE_SIZE 32
- # define FFI_NATIVE_RAW_API 0
- #else
- /* 4 bytes of ENDBR32 + 5 bytes of MOV + 5 bytes of JMP + 2 unused
- bytes. */
- # define FFI_TRAMPOLINE_SIZE 16
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #if !defined(GENERATE_LIBFFI_MAP) && defined(__ASSEMBLER__) \
- && defined(__CET__)
- # include <cet.h>
- # define _CET_NOTRACK notrack
- #else
- # define _CET_ENDBR
- # define _CET_NOTRACK
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/i686-pc-linux-android16/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/powerpc64le-unknown-linux-gnu/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
- Copyright (c) 1996-2003 Red Hat, Inc.
- Target configuration macros for PowerPC.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- #if defined (POWERPC) && defined (__powerpc64__) /* linux64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #elif defined (POWERPC_DARWIN) && defined (__ppc64__) /* Darwin64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #ifndef POWERPC_DARWIN64
- #define POWERPC_DARWIN64
- #endif
- #elif defined (POWERPC_AIX) && defined (__64BIT__) /* AIX64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #endif
- #ifndef LIBFFI_ASM
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- #if defined (POWERPC_AIX)
- FFI_AIX,
- FFI_DARWIN,
- FFI_DEFAULT_ABI = FFI_AIX,
- FFI_LAST_ABI
- #elif defined (POWERPC_DARWIN)
- FFI_AIX,
- FFI_DARWIN,
- FFI_DEFAULT_ABI = FFI_DARWIN,
- FFI_LAST_ABI
- #else
- /* The FFI_COMPAT values are used by old code. Since libffi may be
- a shared library we have to support old values for backwards
- compatibility. */
- FFI_COMPAT_SYSV,
- FFI_COMPAT_GCC_SYSV,
- FFI_COMPAT_LINUX64,
- FFI_COMPAT_LINUX,
- FFI_COMPAT_LINUX_SOFT_FLOAT,
- # if defined (POWERPC64)
- /* This bit, always set in new code, must not be set in any of the
- old FFI_COMPAT values that might be used for 64-bit linux. We
- only need worry about FFI_COMPAT_LINUX64, but to be safe avoid
- all old values. */
- FFI_LINUX = 8,
- /* This and following bits can reuse FFI_COMPAT values. */
- FFI_LINUX_STRUCT_ALIGN = 1,
- FFI_LINUX_LONG_DOUBLE_128 = 2,
- FFI_LINUX_LONG_DOUBLE_IEEE128 = 4,
- FFI_DEFAULT_ABI = (FFI_LINUX
- # ifdef __STRUCT_PARM_ALIGN__
- | FFI_LINUX_STRUCT_ALIGN
- # endif
- # ifdef __LONG_DOUBLE_128__
- | FFI_LINUX_LONG_DOUBLE_128
- # ifdef __LONG_DOUBLE_IEEE128__
- | FFI_LINUX_LONG_DOUBLE_IEEE128
- # endif
- # endif
- ),
- FFI_LAST_ABI = 16
- # else
- /* This bit, always set in new code, must not be set in any of the
- old FFI_COMPAT values that might be used for 32-bit linux/sysv/bsd. */
- FFI_SYSV = 8,
- /* This and following bits can reuse FFI_COMPAT values. */
- FFI_SYSV_SOFT_FLOAT = 1,
- FFI_SYSV_STRUCT_RET = 2,
- FFI_SYSV_IBM_LONG_DOUBLE = 4,
- FFI_SYSV_LONG_DOUBLE_128 = 16,
- FFI_DEFAULT_ABI = (FFI_SYSV
- # ifdef __NO_FPRS__
- | FFI_SYSV_SOFT_FLOAT
- # endif
- # if (defined (__SVR4_STRUCT_RETURN) \
- || defined (POWERPC_FREEBSD) && !defined (__AIX_STRUCT_RETURN))
- | FFI_SYSV_STRUCT_RET
- # endif
- # if __LDBL_MANT_DIG__ == 106
- | FFI_SYSV_IBM_LONG_DOUBLE
- # endif
- # ifdef __LONG_DOUBLE_128__
- | FFI_SYSV_LONG_DOUBLE_128
- # endif
- ),
- FFI_LAST_ABI = 32
- # endif
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (POWERPC) || defined (POWERPC_FREEBSD)
- # define FFI_GO_CLOSURES 1
- # define FFI_TARGET_SPECIFIC_VARIADIC 1
- # define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
- #endif
- #if defined (POWERPC_AIX)
- # define FFI_GO_CLOSURES 1
- #endif
- /* ppc_closure.S and linux64_closure.S expect this. */
- #define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER
- /* We define additional types below. If generic types are added that
- must be supported by powerpc libffi then it is likely that
- FFI_PPC_TYPE_LAST needs increasing *and* the jump tables in
- ppc_closure.S and linux64_closure.S be extended. */
- #if !(FFI_TYPE_LAST == FFI_PPC_TYPE_LAST \
- || (FFI_TYPE_LAST == FFI_TYPE_COMPLEX \
- && !defined FFI_TARGET_HAS_COMPLEX_TYPE))
- # error "You likely have a broken powerpc libffi"
- #endif
- /* Needed for soft-float long-double-128 support. */
- #define FFI_TYPE_UINT128 (FFI_PPC_TYPE_LAST + 1)
- /* Needed for FFI_SYSV small structure returns. */
- #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 2)
- /* Used by ELFv2 for homogenous structure returns. */
- #define FFI_V2_TYPE_VECTOR (FFI_PPC_TYPE_LAST + 1)
- #define FFI_V2_TYPE_VECTOR_HOMOG (FFI_PPC_TYPE_LAST + 2)
- #define FFI_V2_TYPE_FLOAT_HOMOG (FFI_PPC_TYPE_LAST + 3)
- #define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_PPC_TYPE_LAST + 4)
- #define FFI_V2_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 5)
- #if _CALL_ELF == 2
- # define FFI_TRAMPOLINE_SIZE 32
- #else
- # if defined(POWERPC64) || defined(POWERPC_AIX)
- # if defined(POWERPC_DARWIN64)
- # define FFI_TRAMPOLINE_SIZE 48
- # else
- # define FFI_TRAMPOLINE_SIZE 24
- # endif
- # else /* POWERPC || POWERPC_AIX */
- # define FFI_TRAMPOLINE_SIZE 40
- # endif
- #endif
- #ifndef LIBFFI_ASM
- #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
- struct ffi_aix_trampoline_struct {
- void * code_pointer; /* Pointer to ffi_closure_ASM */
- void * toc; /* TOC */
- void * static_chain; /* Pointer to closure */
- };
- #endif
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/x86_64-apple-iphonesimulator/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/x86_64-apple-macosx/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/x86_64-microsoft-windows/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- /* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP
- + 8 bytes of pointer. */
- # define FFI_TRAMPOLINE_SIZE 32
- # define FFI_NATIVE_RAW_API 0
- #else
- /* 4 bytes of ENDBR32 + 5 bytes of MOV + 5 bytes of JMP + 2 unused
- bytes. */
- # define FFI_TRAMPOLINE_SIZE 16
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #if !defined(GENERATE_LIBFFI_MAP) && defined(__ASSEMBLER__) \
- && defined(__CET__)
- # include <cet.h>
- # define _CET_NOTRACK notrack
- #else
- # define _CET_ENDBR
- # define _CET_NOTRACK
- #endif
- #endif
- ====================File: .yandex_meta/files/configs/x86_64-pc-linux-android21/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: configs/aarch64-apple-iphoneos/include/ffitarget.h====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- #ifdef __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #elif defined(_M_ARM64)
- #define FFI_SIZEOF_ARG 8
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- typedef enum ffi_abi
- {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #define FFI_TRAMPOLINE_SIZE 24
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #ifdef _M_ARM64
- #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
- #endif
- /* ---- Internal ---- */
- #if defined (__APPLE__)
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
- #elif !defined(_M_ARM64)
- /* iOS and Windows reserve x18 for the system. Disable Go closures until
- a new static chain is chosen. */
- #define FFI_GO_CLOSURES 1
- #endif
- #ifndef _M_ARM64
- /* No complex type on Windows */
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- #endif
- ====================File: configs/aarch64-apple-macos/include/ffitarget.h====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- #ifdef __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #elif defined(_M_ARM64)
- #define FFI_SIZEOF_ARG 8
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- typedef enum ffi_abi
- {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #define FFI_TRAMPOLINE_SIZE 24
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #ifdef _M_ARM64
- #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
- #endif
- /* ---- Internal ---- */
- #if defined (__APPLE__)
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
- #elif !defined(_M_ARM64)
- /* iOS and Windows reserve x18 for the system. Disable Go closures until
- a new static chain is chosen. */
- #define FFI_GO_CLOSURES 1
- #endif
- #ifndef _M_ARM64
- /* No complex type on Windows */
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- #endif
- ====================File: configs/aarch64-unknown-linux-android21/include/ffitarget.h====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- #ifdef __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #elif defined(_M_ARM64)
- #define FFI_SIZEOF_ARG 8
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- typedef enum ffi_abi
- {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #define FFI_TRAMPOLINE_SIZE 24
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #ifdef _M_ARM64
- #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
- #endif
- /* ---- Internal ---- */
- #if defined (__APPLE__)
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
- #elif !defined(_M_ARM64)
- /* iOS and Windows reserve x18 for the system. Disable Go closures until
- a new static chain is chosen. */
- #define FFI_GO_CLOSURES 1
- #endif
- #ifndef _M_ARM64
- /* No complex type on Windows */
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- #endif
- ====================File: configs/aarch64-unknown-linux-gnu/include/ffitarget.h====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- #ifdef __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #elif defined(_M_ARM64)
- #define FFI_SIZEOF_ARG 8
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- typedef enum ffi_abi
- {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #define FFI_TRAMPOLINE_SIZE 24
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #ifdef _M_ARM64
- #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
- #endif
- /* ---- Internal ---- */
- #if defined (__APPLE__)
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
- #elif !defined(_M_ARM64)
- /* iOS and Windows reserve x18 for the system. Disable Go closures until
- a new static chain is chosen. */
- #define FFI_GO_CLOSURES 1
- #endif
- #ifndef _M_ARM64
- /* No complex type on Windows */
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- #endif
- ====================File: configs/armv7a-unknown-linux-androideabi16/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (c) 2010 CodeSourcery
- Copyright (c) 1996-2003 Red Hat, Inc.
- Target configuration macros for ARM.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_VFP,
- FFI_LAST_ABI,
- #if defined(__ARM_PCS_VFP) || defined(_M_ARM)
- FFI_DEFAULT_ABI = FFI_VFP,
- #else
- FFI_DEFAULT_ABI = FFI_SYSV,
- #endif
- } ffi_abi;
- #endif
- #define FFI_EXTRA_CIF_FIELDS \
- int vfp_used; \
- unsigned short vfp_reg_free, vfp_nargs; \
- signed char vfp_args[16] \
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #ifndef _M_ARM
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 12
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 8
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #ifdef _MSC_VER
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12
- #else
- #define FFI_TRAMPOLINE_SIZE 12
- #endif
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #endif
- ====================File: configs/armv7a-unknown-linux-gnueabihf/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (c) 2010 CodeSourcery
- Copyright (c) 1996-2003 Red Hat, Inc.
- Target configuration macros for ARM.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_VFP,
- FFI_LAST_ABI,
- #if defined(__ARM_PCS_VFP) || defined(_M_ARM)
- FFI_DEFAULT_ABI = FFI_VFP,
- #else
- FFI_DEFAULT_ABI = FFI_SYSV,
- #endif
- } ffi_abi;
- #endif
- #define FFI_EXTRA_CIF_FIELDS \
- int vfp_used; \
- unsigned short vfp_reg_free, vfp_nargs; \
- signed char vfp_args[16] \
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #ifndef _M_ARM
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 12
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 8
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #ifdef _MSC_VER
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12
- #else
- #define FFI_TRAMPOLINE_SIZE 12
- #endif
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #endif
- ====================File: configs/i386-microsoft-windows/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- /* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP
- + 8 bytes of pointer. */
- # define FFI_TRAMPOLINE_SIZE 32
- # define FFI_NATIVE_RAW_API 0
- #else
- /* 4 bytes of ENDBR32 + 5 bytes of MOV + 5 bytes of JMP + 2 unused
- bytes. */
- # define FFI_TRAMPOLINE_SIZE 16
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #if !defined(GENERATE_LIBFFI_MAP) && defined(__ASSEMBLER__) \
- && defined(__CET__)
- # include <cet.h>
- # define _CET_NOTRACK notrack
- #else
- # define _CET_ENDBR
- # define _CET_NOTRACK
- #endif
- #endif
- ====================File: configs/i686-pc-linux-android16/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: configs/powerpc64le-unknown-linux-gnu/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
- Copyright (c) 1996-2003 Red Hat, Inc.
- Target configuration macros for PowerPC.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- #if defined (POWERPC) && defined (__powerpc64__) /* linux64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #elif defined (POWERPC_DARWIN) && defined (__ppc64__) /* Darwin64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #ifndef POWERPC_DARWIN64
- #define POWERPC_DARWIN64
- #endif
- #elif defined (POWERPC_AIX) && defined (__64BIT__) /* AIX64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #endif
- #ifndef LIBFFI_ASM
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- #if defined (POWERPC_AIX)
- FFI_AIX,
- FFI_DARWIN,
- FFI_DEFAULT_ABI = FFI_AIX,
- FFI_LAST_ABI
- #elif defined (POWERPC_DARWIN)
- FFI_AIX,
- FFI_DARWIN,
- FFI_DEFAULT_ABI = FFI_DARWIN,
- FFI_LAST_ABI
- #else
- /* The FFI_COMPAT values are used by old code. Since libffi may be
- a shared library we have to support old values for backwards
- compatibility. */
- FFI_COMPAT_SYSV,
- FFI_COMPAT_GCC_SYSV,
- FFI_COMPAT_LINUX64,
- FFI_COMPAT_LINUX,
- FFI_COMPAT_LINUX_SOFT_FLOAT,
- # if defined (POWERPC64)
- /* This bit, always set in new code, must not be set in any of the
- old FFI_COMPAT values that might be used for 64-bit linux. We
- only need worry about FFI_COMPAT_LINUX64, but to be safe avoid
- all old values. */
- FFI_LINUX = 8,
- /* This and following bits can reuse FFI_COMPAT values. */
- FFI_LINUX_STRUCT_ALIGN = 1,
- FFI_LINUX_LONG_DOUBLE_128 = 2,
- FFI_LINUX_LONG_DOUBLE_IEEE128 = 4,
- FFI_DEFAULT_ABI = (FFI_LINUX
- # ifdef __STRUCT_PARM_ALIGN__
- | FFI_LINUX_STRUCT_ALIGN
- # endif
- # ifdef __LONG_DOUBLE_128__
- | FFI_LINUX_LONG_DOUBLE_128
- # ifdef __LONG_DOUBLE_IEEE128__
- | FFI_LINUX_LONG_DOUBLE_IEEE128
- # endif
- # endif
- ),
- FFI_LAST_ABI = 16
- # else
- /* This bit, always set in new code, must not be set in any of the
- old FFI_COMPAT values that might be used for 32-bit linux/sysv/bsd. */
- FFI_SYSV = 8,
- /* This and following bits can reuse FFI_COMPAT values. */
- FFI_SYSV_SOFT_FLOAT = 1,
- FFI_SYSV_STRUCT_RET = 2,
- FFI_SYSV_IBM_LONG_DOUBLE = 4,
- FFI_SYSV_LONG_DOUBLE_128 = 16,
- FFI_DEFAULT_ABI = (FFI_SYSV
- # ifdef __NO_FPRS__
- | FFI_SYSV_SOFT_FLOAT
- # endif
- # if (defined (__SVR4_STRUCT_RETURN) \
- || defined (POWERPC_FREEBSD) && !defined (__AIX_STRUCT_RETURN))
- | FFI_SYSV_STRUCT_RET
- # endif
- # if __LDBL_MANT_DIG__ == 106
- | FFI_SYSV_IBM_LONG_DOUBLE
- # endif
- # ifdef __LONG_DOUBLE_128__
- | FFI_SYSV_LONG_DOUBLE_128
- # endif
- ),
- FFI_LAST_ABI = 32
- # endif
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (POWERPC) || defined (POWERPC_FREEBSD)
- # define FFI_GO_CLOSURES 1
- # define FFI_TARGET_SPECIFIC_VARIADIC 1
- # define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
- #endif
- #if defined (POWERPC_AIX)
- # define FFI_GO_CLOSURES 1
- #endif
- /* ppc_closure.S and linux64_closure.S expect this. */
- #define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER
- /* We define additional types below. If generic types are added that
- must be supported by powerpc libffi then it is likely that
- FFI_PPC_TYPE_LAST needs increasing *and* the jump tables in
- ppc_closure.S and linux64_closure.S be extended. */
- #if !(FFI_TYPE_LAST == FFI_PPC_TYPE_LAST \
- || (FFI_TYPE_LAST == FFI_TYPE_COMPLEX \
- && !defined FFI_TARGET_HAS_COMPLEX_TYPE))
- # error "You likely have a broken powerpc libffi"
- #endif
- /* Needed for soft-float long-double-128 support. */
- #define FFI_TYPE_UINT128 (FFI_PPC_TYPE_LAST + 1)
- /* Needed for FFI_SYSV small structure returns. */
- #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 2)
- /* Used by ELFv2 for homogenous structure returns. */
- #define FFI_V2_TYPE_VECTOR (FFI_PPC_TYPE_LAST + 1)
- #define FFI_V2_TYPE_VECTOR_HOMOG (FFI_PPC_TYPE_LAST + 2)
- #define FFI_V2_TYPE_FLOAT_HOMOG (FFI_PPC_TYPE_LAST + 3)
- #define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_PPC_TYPE_LAST + 4)
- #define FFI_V2_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 5)
- #if _CALL_ELF == 2
- # define FFI_TRAMPOLINE_SIZE 32
- #else
- # if defined(POWERPC64) || defined(POWERPC_AIX)
- # if defined(POWERPC_DARWIN64)
- # define FFI_TRAMPOLINE_SIZE 48
- # else
- # define FFI_TRAMPOLINE_SIZE 24
- # endif
- # else /* POWERPC || POWERPC_AIX */
- # define FFI_TRAMPOLINE_SIZE 40
- # endif
- #endif
- #ifndef LIBFFI_ASM
- #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
- struct ffi_aix_trampoline_struct {
- void * code_pointer; /* Pointer to ffi_closure_ASM */
- void * toc; /* TOC */
- void * static_chain; /* Pointer to closure */
- };
- #endif
- #endif
- #endif
- ====================File: configs/x86_64-apple-iphonesimulator/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: configs/x86_64-apple-macosx/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: configs/x86_64-microsoft-windows/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- /* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP
- + 8 bytes of pointer. */
- # define FFI_TRAMPOLINE_SIZE 32
- # define FFI_NATIVE_RAW_API 0
- #else
- /* 4 bytes of ENDBR32 + 5 bytes of MOV + 5 bytes of JMP + 2 unused
- bytes. */
- # define FFI_TRAMPOLINE_SIZE 16
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #if !defined(GENERATE_LIBFFI_MAP) && defined(__ASSEMBLER__) \
- && defined(__CET__)
- # include <cet.h>
- # define _CET_NOTRACK notrack
- #else
- # define _CET_ENDBR
- # define _CET_NOTRACK
- #endif
- #endif
- ====================File: configs/x86_64-pc-linux-android21/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: configs/x86_64-pc-linux-gnu/include/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: src/aarch64/ffi.c====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #if defined(__aarch64__) || defined(__arm64__)|| defined (_M_ARM64)
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <fficonfig.h>
- #include <ffi.h>
- #include <ffi_common.h>
- #include "internal.h"
- #ifdef _M_ARM64
- #include <windows.h> /* FlushInstructionCache */
- #endif
- /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
- all further uses in this file will refer to the 128-bit type. */
- #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
- # if FFI_TYPE_LONGDOUBLE != 4
- # error FFI_TYPE_LONGDOUBLE out of date
- # endif
- #else
- # undef FFI_TYPE_LONGDOUBLE
- # define FFI_TYPE_LONGDOUBLE 4
- #endif
- union _d
- {
- UINT64 d;
- UINT32 s[2];
- };
- struct _v
- {
- union _d d[2] __attribute__((aligned(16)));
- };
- struct call_context
- {
- struct _v v[N_V_ARG_REG];
- UINT64 x[N_X_ARG_REG];
- };
- #if FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #include <mach/vm_param.h>
- #endif
- #else
- #if defined (__clang__) && defined (__APPLE__)
- extern void sys_icache_invalidate (void *start, size_t len);
- #endif
- static inline void
- ffi_clear_cache (void *start, void *end)
- {
- #if defined (__clang__) && defined (__APPLE__)
- sys_icache_invalidate (start, (char *)end - (char *)start);
- #elif defined (__GNUC__)
- __builtin___clear_cache (start, end);
- #elif defined (_M_ARM64)
- FlushInstructionCache(GetCurrentProcess(), start, (char*)end - (char*)start);
- #else
- #error "Missing builtin to flush instruction cache"
- #endif
- }
- #endif
- /* A subroutine of is_vfp_type. Given a structure type, return the type code
- of the first non-structure element. Recurse for structure elements.
- Return -1 if the structure is in fact empty, i.e. no nested elements. */
- static int
- is_hfa0 (const ffi_type *ty)
- {
- ffi_type **elements = ty->elements;
- int i, ret = -1;
- if (elements != NULL)
- for (i = 0; elements[i]; ++i)
- {
- ret = elements[i]->type;
- if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)
- {
- ret = is_hfa0 (elements[i]);
- if (ret < 0)
- continue;
- }
- break;
- }
- return ret;
- }
- /* A subroutine of is_vfp_type. Given a structure type, return true if all
- of the non-structure elements are the same as CANDIDATE. */
- static int
- is_hfa1 (const ffi_type *ty, int candidate)
- {
- ffi_type **elements = ty->elements;
- int i;
- if (elements != NULL)
- for (i = 0; elements[i]; ++i)
- {
- int t = elements[i]->type;
- if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
- {
- if (!is_hfa1 (elements[i], candidate))
- return 0;
- }
- else if (t != candidate)
- return 0;
- }
- return 1;
- }
- /* Determine if TY may be allocated to the FP registers. This is both an
- fp scalar type as well as an homogenous floating point aggregate (HFA).
- That is, a structure consisting of 1 to 4 members of all the same type,
- where that type is an fp scalar.
- Returns non-zero iff TY is an HFA. The result is the AARCH64_RET_*
- constant for the type. */
- static int
- is_vfp_type (const ffi_type *ty)
- {
- ffi_type **elements;
- int candidate, i;
- size_t size, ele_count;
- /* Quickest tests first. */
- candidate = ty->type;
- switch (candidate)
- {
- default:
- return 0;
- case FFI_TYPE_FLOAT:
- case FFI_TYPE_DOUBLE:
- case FFI_TYPE_LONGDOUBLE:
- ele_count = 1;
- goto done;
- case FFI_TYPE_COMPLEX:
- candidate = ty->elements[0]->type;
- switch (candidate)
- {
- case FFI_TYPE_FLOAT:
- case FFI_TYPE_DOUBLE:
- case FFI_TYPE_LONGDOUBLE:
- ele_count = 2;
- goto done;
- }
- return 0;
- case FFI_TYPE_STRUCT:
- break;
- }
- /* No HFA types are smaller than 4 bytes, or larger than 64 bytes. */
- size = ty->size;
- if (size < 4 || size > 64)
- return 0;
- /* Find the type of the first non-structure member. */
- elements = ty->elements;
- candidate = elements[0]->type;
- if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX)
- {
- for (i = 0; ; ++i)
- {
- candidate = is_hfa0 (elements[i]);
- if (candidate >= 0)
- break;
- }
- }
- /* If the first member is not a floating point type, it's not an HFA.
- Also quickly re-check the size of the structure. */
- switch (candidate)
- {
- case FFI_TYPE_FLOAT:
- ele_count = size / sizeof(float);
- if (size != ele_count * sizeof(float))
- return 0;
- break;
- case FFI_TYPE_DOUBLE:
- ele_count = size / sizeof(double);
- if (size != ele_count * sizeof(double))
- return 0;
- break;
- case FFI_TYPE_LONGDOUBLE:
- ele_count = size / sizeof(long double);
- if (size != ele_count * sizeof(long double))
- return 0;
- break;
- default:
- return 0;
- }
- if (ele_count > 4)
- return 0;
- /* Finally, make sure that all scalar elements are the same type. */
- for (i = 0; elements[i]; ++i)
- {
- int t = elements[i]->type;
- if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
- {
- if (!is_hfa1 (elements[i], candidate))
- return 0;
- }
- else if (t != candidate)
- return 0;
- }
- /* All tests succeeded. Encode the result. */
- done:
- return candidate * 4 + (4 - (int)ele_count);
- }
- /* Representation of the procedure call argument marshalling
- state.
- The terse state variable names match the names used in the AARCH64
- PCS. */
- struct arg_state
- {
- unsigned ngrn; /* Next general-purpose register number. */
- unsigned nsrn; /* Next vector register number. */
- size_t nsaa; /* Next stack offset. */
- #if defined (__APPLE__)
- unsigned allocating_variadic;
- #endif
- };
- /* Initialize a procedure call argument marshalling state. */
- static void
- arg_init (struct arg_state *state)
- {
- state->ngrn = 0;
- state->nsrn = 0;
- state->nsaa = 0;
- #if defined (__APPLE__)
- state->allocating_variadic = 0;
- #endif
- }
- /* Allocate an aligned slot on the stack and return a pointer to it. */
- static void *
- allocate_to_stack (struct arg_state *state, void *stack,
- size_t alignment, size_t size)
- {
- size_t nsaa = state->nsaa;
- /* Round up the NSAA to the larger of 8 or the natural
- alignment of the argument's type. */
- #if defined (__APPLE__)
- if (state->allocating_variadic && alignment < 8)
- alignment = 8;
- #else
- if (alignment < 8)
- alignment = 8;
- #endif
-
- nsaa = FFI_ALIGN (nsaa, alignment);
- state->nsaa = nsaa + size;
- return (char *)stack + nsaa;
- }
- static ffi_arg
- extend_integer_type (void *source, int type)
- {
- switch (type)
- {
- case FFI_TYPE_UINT8:
- return *(UINT8 *) source;
- case FFI_TYPE_SINT8:
- return *(SINT8 *) source;
- case FFI_TYPE_UINT16:
- return *(UINT16 *) source;
- case FFI_TYPE_SINT16:
- return *(SINT16 *) source;
- case FFI_TYPE_UINT32:
- return *(UINT32 *) source;
- case FFI_TYPE_INT:
- case FFI_TYPE_SINT32:
- return *(SINT32 *) source;
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- return *(UINT64 *) source;
- break;
- case FFI_TYPE_POINTER:
- return *(uintptr_t *) source;
- default:
- abort();
- }
- }
- #if defined(_MSC_VER)
- void extend_hfa_type (void *dest, void *src, int h);
- #else
- static void
- extend_hfa_type (void *dest, void *src, int h)
- {
- ssize_t f = h - AARCH64_RET_S4;
- void *x0;
- asm volatile (
- "adr %0, 0f\n"
- " add %0, %0, %1\n"
- " br %0\n"
- "0: ldp s16, s17, [%3]\n" /* S4 */
- " ldp s18, s19, [%3, #8]\n"
- " b 4f\n"
- " ldp s16, s17, [%3]\n" /* S3 */
- " ldr s18, [%3, #8]\n"
- " b 3f\n"
- " ldp s16, s17, [%3]\n" /* S2 */
- " b 2f\n"
- " nop\n"
- " ldr s16, [%3]\n" /* S1 */
- " b 1f\n"
- " nop\n"
- " ldp d16, d17, [%3]\n" /* D4 */
- " ldp d18, d19, [%3, #16]\n"
- " b 4f\n"
- " ldp d16, d17, [%3]\n" /* D3 */
- " ldr d18, [%3, #16]\n"
- " b 3f\n"
- " ldp d16, d17, [%3]\n" /* D2 */
- " b 2f\n"
- " nop\n"
- " ldr d16, [%3]\n" /* D1 */
- " b 1f\n"
- " nop\n"
- " ldp q16, q17, [%3]\n" /* Q4 */
- " ldp q18, q19, [%3, #32]\n"
- " b 4f\n"
- " ldp q16, q17, [%3]\n" /* Q3 */
- " ldr q18, [%3, #32]\n"
- " b 3f\n"
- " ldp q16, q17, [%3]\n" /* Q2 */
- " b 2f\n"
- " nop\n"
- " ldr q16, [%3]\n" /* Q1 */
- " b 1f\n"
- "4: str q19, [%2, #48]\n"
- "3: str q18, [%2, #32]\n"
- "2: str q17, [%2, #16]\n"
- "1: str q16, [%2]"
- : "=&r"(x0)
- : "r"(f * 12), "r"(dest), "r"(src)
- : "memory", "v16", "v17", "v18", "v19");
- }
- #endif
- #if defined(_MSC_VER)
- void* compress_hfa_type (void *dest, void *src, int h);
- #else
- static void *
- compress_hfa_type (void *dest, void *reg, int h)
- {
- switch (h)
- {
- case AARCH64_RET_S1:
- if (dest == reg)
- {
- #ifdef __AARCH64EB__
- dest += 12;
- #endif
- }
- else
- *(float *)dest = *(float *)reg;
- break;
- case AARCH64_RET_S2:
- asm ("ldp q16, q17, [%1]\n\t"
- "st2 { v16.s, v17.s }[0], [%0]"
- : : "r"(dest), "r"(reg) : "memory", "v16", "v17");
- break;
- case AARCH64_RET_S3:
- asm ("ldp q16, q17, [%1]\n\t"
- "ldr q18, [%1, #32]\n\t"
- "st3 { v16.s, v17.s, v18.s }[0], [%0]"
- : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18");
- break;
- case AARCH64_RET_S4:
- asm ("ldp q16, q17, [%1]\n\t"
- "ldp q18, q19, [%1, #32]\n\t"
- "st4 { v16.s, v17.s, v18.s, v19.s }[0], [%0]"
- : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19");
- break;
- case AARCH64_RET_D1:
- if (dest == reg)
- {
- #ifdef __AARCH64EB__
- dest += 8;
- #endif
- }
- else
- *(double *)dest = *(double *)reg;
- break;
- case AARCH64_RET_D2:
- asm ("ldp q16, q17, [%1]\n\t"
- "st2 { v16.d, v17.d }[0], [%0]"
- : : "r"(dest), "r"(reg) : "memory", "v16", "v17");
- break;
- case AARCH64_RET_D3:
- asm ("ldp q16, q17, [%1]\n\t"
- "ldr q18, [%1, #32]\n\t"
- "st3 { v16.d, v17.d, v18.d }[0], [%0]"
- : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18");
- break;
- case AARCH64_RET_D4:
- asm ("ldp q16, q17, [%1]\n\t"
- "ldp q18, q19, [%1, #32]\n\t"
- "st4 { v16.d, v17.d, v18.d, v19.d }[0], [%0]"
- : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19");
- break;
- default:
- if (dest != reg)
- return memcpy (dest, reg, 16 * (4 - (h & 3)));
- break;
- }
- return dest;
- }
- #endif
- /* Either allocate an appropriate register for the argument type, or if
- none are available, allocate a stack slot and return a pointer
- to the allocated space. */
- static void *
- allocate_int_to_reg_or_stack (struct call_context *context,
- struct arg_state *state,
- void *stack, size_t size)
- {
- if (state->ngrn < N_X_ARG_REG)
- return &context->x[state->ngrn++];
- state->ngrn = N_X_ARG_REG;
- return allocate_to_stack (state, stack, size, size);
- }
- ffi_status FFI_HIDDEN
- ffi_prep_cif_machdep (ffi_cif *cif)
- {
- ffi_type *rtype = cif->rtype;
- size_t bytes = cif->bytes;
- int flags, i, n;
- switch (rtype->type)
- {
- case FFI_TYPE_VOID:
- flags = AARCH64_RET_VOID;
- break;
- case FFI_TYPE_UINT8:
- flags = AARCH64_RET_UINT8;
- break;
- case FFI_TYPE_UINT16:
- flags = AARCH64_RET_UINT16;
- break;
- case FFI_TYPE_UINT32:
- flags = AARCH64_RET_UINT32;
- break;
- case FFI_TYPE_SINT8:
- flags = AARCH64_RET_SINT8;
- break;
- case FFI_TYPE_SINT16:
- flags = AARCH64_RET_SINT16;
- break;
- case FFI_TYPE_INT:
- case FFI_TYPE_SINT32:
- flags = AARCH64_RET_SINT32;
- break;
- case FFI_TYPE_SINT64:
- case FFI_TYPE_UINT64:
- flags = AARCH64_RET_INT64;
- break;
- case FFI_TYPE_POINTER:
- flags = (sizeof(void *) == 4 ? AARCH64_RET_UINT32 : AARCH64_RET_INT64);
- break;
- case FFI_TYPE_FLOAT:
- case FFI_TYPE_DOUBLE:
- case FFI_TYPE_LONGDOUBLE:
- case FFI_TYPE_STRUCT:
- case FFI_TYPE_COMPLEX:
- flags = is_vfp_type (rtype);
- if (flags == 0)
- {
- size_t s = rtype->size;
- if (s > 16)
- {
- flags = AARCH64_RET_VOID | AARCH64_RET_IN_MEM;
- bytes += 8;
- }
- else if (s == 16)
- flags = AARCH64_RET_INT128;
- else if (s == 8)
- flags = AARCH64_RET_INT64;
- else
- flags = AARCH64_RET_INT128 | AARCH64_RET_NEED_COPY;
- }
- break;
- default:
- abort();
- }
- for (i = 0, n = cif->nargs; i < n; i++)
- if (is_vfp_type (cif->arg_types[i]))
- {
- flags |= AARCH64_FLAG_ARG_V;
- break;
- }
- /* Round the stack up to a multiple of the stack alignment requirement. */
- cif->bytes = (unsigned) FFI_ALIGN(bytes, 16);
- cif->flags = flags;
- #if defined (__APPLE__)
- cif->aarch64_nfixedargs = 0;
- #endif
- return FFI_OK;
- }
- #if defined (__APPLE__)
- /* Perform Apple-specific cif processing for variadic calls */
- ffi_status FFI_HIDDEN
- ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
- unsigned int ntotalargs)
- {
- ffi_status status = ffi_prep_cif_machdep (cif);
- cif->aarch64_nfixedargs = nfixedargs;
- return status;
- }
- #endif /* __APPLE__ */
- extern void ffi_call_SYSV (struct call_context *context, void *frame,
- void (*fn)(void), void *rvalue, int flags,
- void *closure) FFI_HIDDEN;
- /* Call a function with the provided arguments and capture the return
- value. */
- static void
- ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
- void **avalue, void *closure)
- {
- struct call_context *context;
- void *stack, *frame, *rvalue;
- struct arg_state state;
- size_t stack_bytes, rtype_size, rsize;
- int i, nargs, flags;
- ffi_type *rtype;
- flags = cif->flags;
- rtype = cif->rtype;
- rtype_size = rtype->size;
- stack_bytes = cif->bytes;
- /* If the target function returns a structure via hidden pointer,
- then we cannot allow a null rvalue. Otherwise, mash a null
- rvalue to void return type. */
- rsize = 0;
- if (flags & AARCH64_RET_IN_MEM)
- {
- if (orig_rvalue == NULL)
- rsize = rtype_size;
- }
- else if (orig_rvalue == NULL)
- flags &= AARCH64_FLAG_ARG_V;
- else if (flags & AARCH64_RET_NEED_COPY)
- rsize = 16;
- /* Allocate consectutive stack for everything we'll need. */
- context = alloca (sizeof(struct call_context) + stack_bytes + 32 + rsize);
- stack = context + 1;
- frame = (void*)((uintptr_t)stack + (uintptr_t)stack_bytes);
- rvalue = (rsize ? (void*)((uintptr_t)frame + 32) : orig_rvalue);
- arg_init (&state);
- for (i = 0, nargs = cif->nargs; i < nargs; i++)
- {
- ffi_type *ty = cif->arg_types[i];
- size_t s = ty->size;
- void *a = avalue[i];
- int h, t;
- t = ty->type;
- switch (t)
- {
- case FFI_TYPE_VOID:
- FFI_ASSERT (0);
- break;
- /* If the argument is a basic type the argument is allocated to an
- appropriate register, or if none are available, to the stack. */
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_POINTER:
- do_pointer:
- {
- ffi_arg ext = extend_integer_type (a, t);
- if (state.ngrn < N_X_ARG_REG)
- context->x[state.ngrn++] = ext;
- else
- {
- void *d = allocate_to_stack (&state, stack, ty->alignment, s);
- state.ngrn = N_X_ARG_REG;
- /* Note that the default abi extends each argument
- to a full 64-bit slot, while the iOS abi allocates
- only enough space. */
- #ifdef __APPLE__
- memcpy(d, a, s);
- #else
- *(ffi_arg *)d = ext;
- #endif
- }
- }
- break;
- case FFI_TYPE_FLOAT:
- case FFI_TYPE_DOUBLE:
- case FFI_TYPE_LONGDOUBLE:
- case FFI_TYPE_STRUCT:
- case FFI_TYPE_COMPLEX:
- {
- void *dest;
- h = is_vfp_type (ty);
- if (h)
- {
- int elems = 4 - (h & 3);
- #ifdef _M_ARM64 /* for handling armasm calling convention */
- if (cif->is_variadic)
- {
- if (state.ngrn + elems <= N_X_ARG_REG)
- {
- dest = &context->x[state.ngrn];
- state.ngrn += elems;
- extend_hfa_type(dest, a, h);
- break;
- }
- state.nsrn = N_X_ARG_REG;
- dest = allocate_to_stack(&state, stack, ty->alignment, s);
- }
- else
- {
- #endif /* for handling armasm calling convention */
- if (state.nsrn + elems <= N_V_ARG_REG)
- {
- dest = &context->v[state.nsrn];
- state.nsrn += elems;
- extend_hfa_type (dest, a, h);
- break;
- }
- state.nsrn = N_V_ARG_REG;
- dest = allocate_to_stack (&state, stack, ty->alignment, s);
- #ifdef _M_ARM64 /* for handling armasm calling convention */
- }
- #endif /* for handling armasm calling convention */
- }
- else if (s > 16)
- {
- /* If the argument is a composite type that is larger than 16
- bytes, then the argument has been copied to memory, and
- the argument is replaced by a pointer to the copy. */
- a = &avalue[i];
- t = FFI_TYPE_POINTER;
- s = sizeof (void *);
- goto do_pointer;
- }
- else
- {
- size_t n = (s + 7) / 8;
- if (state.ngrn + n <= N_X_ARG_REG)
- {
- /* If the argument is a composite type and the size in
- double-words is not more than the number of available
- X registers, then the argument is copied into
- consecutive X registers. */
- dest = &context->x[state.ngrn];
- state.ngrn += (unsigned int)n;
- }
- else
- {
- /* Otherwise, there are insufficient X registers. Further
- X register allocations are prevented, the NSAA is
- adjusted and the argument is copied to memory at the
- adjusted NSAA. */
- state.ngrn = N_X_ARG_REG;
- dest = allocate_to_stack (&state, stack, ty->alignment, s);
- }
- }
- memcpy (dest, a, s);
- }
- break;
- default:
- abort();
- }
- #if defined (__APPLE__)
- if (i + 1 == cif->aarch64_nfixedargs)
- {
- state.ngrn = N_X_ARG_REG;
- state.nsrn = N_V_ARG_REG;
- state.allocating_variadic = 1;
- }
- #endif
- }
- ffi_call_SYSV (context, frame, fn, rvalue, flags, closure);
- if (flags & AARCH64_RET_NEED_COPY)
- memcpy (orig_rvalue, rvalue, rtype_size);
- }
- void
- ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
- {
- ffi_call_int (cif, fn, rvalue, avalue, NULL);
- }
- #ifdef FFI_GO_CLOSURES
- void
- ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,
- void **avalue, void *closure)
- {
- ffi_call_int (cif, fn, rvalue, avalue, closure);
- }
- #endif /* FFI_GO_CLOSURES */
- /* Build a trampoline. */
- extern void ffi_closure_SYSV (void) FFI_HIDDEN;
- extern void ffi_closure_SYSV_V (void) FFI_HIDDEN;
- ffi_status
- ffi_prep_closure_loc (ffi_closure *closure,
- ffi_cif* cif,
- void (*fun)(ffi_cif*,void*,void**,void*),
- void *user_data,
- void *codeloc)
- {
- if (cif->abi != FFI_SYSV)
- return FFI_BAD_ABI;
- void (*start)(void);
-
- if (cif->flags & AARCH64_FLAG_ARG_V)
- start = ffi_closure_SYSV_V;
- else
- start = ffi_closure_SYSV;
- #if FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);
- config[0] = closure;
- config[1] = start;
- #endif
- #else
- static const unsigned char trampoline[16] = {
- 0x90, 0x00, 0x00, 0x58, /* ldr x16, tramp+16 */
- 0xf1, 0xff, 0xff, 0x10, /* adr x17, tramp+0 */
- 0x00, 0x02, 0x1f, 0xd6 /* br x16 */
- };
- char *tramp = closure->tramp;
-
- memcpy (tramp, trampoline, sizeof(trampoline));
-
- *(UINT64 *)(tramp + 16) = (uintptr_t)start;
- ffi_clear_cache(tramp, tramp + FFI_TRAMPOLINE_SIZE);
- /* Also flush the cache for code mapping. */
- #ifdef _M_ARM64
- // Not using dlmalloc.c for Windows ARM64 builds
- // so calling ffi_data_to_code_pointer() isn't necessary
- unsigned char *tramp_code = tramp;
- #else
- unsigned char *tramp_code = ffi_data_to_code_pointer (tramp);
- #endif
- ffi_clear_cache (tramp_code, tramp_code + FFI_TRAMPOLINE_SIZE);
- #endif
- closure->cif = cif;
- closure->fun = fun;
- closure->user_data = user_data;
- return FFI_OK;
- }
- #ifdef FFI_GO_CLOSURES
- extern void ffi_go_closure_SYSV (void) FFI_HIDDEN;
- extern void ffi_go_closure_SYSV_V (void) FFI_HIDDEN;
- ffi_status
- ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif* cif,
- void (*fun)(ffi_cif*,void*,void**,void*))
- {
- void (*start)(void);
- if (cif->abi != FFI_SYSV)
- return FFI_BAD_ABI;
- if (cif->flags & AARCH64_FLAG_ARG_V)
- start = ffi_go_closure_SYSV_V;
- else
- start = ffi_go_closure_SYSV;
- closure->tramp = start;
- closure->cif = cif;
- closure->fun = fun;
- return FFI_OK;
- }
- #endif /* FFI_GO_CLOSURES */
- /* Primary handler to setup and invoke a function within a closure.
- A closure when invoked enters via the assembler wrapper
- ffi_closure_SYSV(). The wrapper allocates a call context on the
- stack, saves the interesting registers (from the perspective of
- the calling convention) into the context then passes control to
- ffi_closure_SYSV_inner() passing the saved context and a pointer to
- the stack at the point ffi_closure_SYSV() was invoked.
- On the return path the assembler wrapper will reload call context
- registers.
- ffi_closure_SYSV_inner() marshalls the call context into ffi value
- descriptors, invokes the wrapped function, then marshalls the return
- value back into the call context. */
- int FFI_HIDDEN
- ffi_closure_SYSV_inner (ffi_cif *cif,
- void (*fun)(ffi_cif*,void*,void**,void*),
- void *user_data,
- struct call_context *context,
- void *stack, void *rvalue, void *struct_rvalue)
- {
- void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
- int i, h, nargs, flags;
- struct arg_state state;
- arg_init (&state);
- for (i = 0, nargs = cif->nargs; i < nargs; i++)
- {
- ffi_type *ty = cif->arg_types[i];
- int t = ty->type;
- size_t n, s = ty->size;
- switch (t)
- {
- case FFI_TYPE_VOID:
- FFI_ASSERT (0);
- break;
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_POINTER:
- avalue[i] = allocate_int_to_reg_or_stack (context, &state, stack, s);
- break;
- case FFI_TYPE_FLOAT:
- case FFI_TYPE_DOUBLE:
- case FFI_TYPE_LONGDOUBLE:
- case FFI_TYPE_STRUCT:
- case FFI_TYPE_COMPLEX:
- h = is_vfp_type (ty);
- if (h)
- {
- n = 4 - (h & 3);
- #ifdef _M_ARM64 /* for handling armasm calling convention */
- if (cif->is_variadic)
- {
- if (state.ngrn + n <= N_X_ARG_REG)
- {
- void *reg = &context->x[state.ngrn];
- state.ngrn += (unsigned int)n;
-
- /* Eeek! We need a pointer to the structure, however the
- homogeneous float elements are being passed in individual
- registers, therefore for float and double the structure
- is not represented as a contiguous sequence of bytes in
- our saved register context. We don't need the original
- contents of the register storage, so we reformat the
- structure into the same memory. */
- avalue[i] = compress_hfa_type(reg, reg, h);
- }
- else
- {
- state.ngrn = N_X_ARG_REG;
- state.nsrn = N_V_ARG_REG;
- avalue[i] = allocate_to_stack(&state, stack,
- ty->alignment, s);
- }
- }
- else
- {
- #endif /* for handling armasm calling convention */
- if (state.nsrn + n <= N_V_ARG_REG)
- {
- void *reg = &context->v[state.nsrn];
- state.nsrn += (unsigned int)n;
- avalue[i] = compress_hfa_type(reg, reg, h);
- }
- else
- {
- state.nsrn = N_V_ARG_REG;
- avalue[i] = allocate_to_stack(&state, stack,
- ty->alignment, s);
- }
- #ifdef _M_ARM64 /* for handling armasm calling convention */
- }
- #endif /* for handling armasm calling convention */
- }
- else if (s > 16)
- {
- /* Replace Composite type of size greater than 16 with a
- pointer. */
- avalue[i] = *(void **)
- allocate_int_to_reg_or_stack (context, &state, stack,
- sizeof (void *));
- }
- else
- {
- n = (s + 7) / 8;
- if (state.ngrn + n <= N_X_ARG_REG)
- {
- avalue[i] = &context->x[state.ngrn];
- state.ngrn += (unsigned int)n;
- }
- else
- {
- state.ngrn = N_X_ARG_REG;
- avalue[i] = allocate_to_stack(&state, stack,
- ty->alignment, s);
- }
- }
- break;
- default:
- abort();
- }
- #if defined (__APPLE__)
- if (i + 1 == cif->aarch64_nfixedargs)
- {
- state.ngrn = N_X_ARG_REG;
- state.nsrn = N_V_ARG_REG;
- state.allocating_variadic = 1;
- }
- #endif
- }
- flags = cif->flags;
- if (flags & AARCH64_RET_IN_MEM)
- rvalue = struct_rvalue;
- fun (cif, rvalue, avalue, user_data);
- return flags;
- }
- #endif /* (__aarch64__) || defined(__arm64__)|| defined (_M_ARM64)*/
- ====================File: src/aarch64/ffitarget.h====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- #ifdef __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #elif defined(_M_ARM64)
- #define FFI_SIZEOF_ARG 8
- typedef unsigned long long ffi_arg;
- typedef signed long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- typedef enum ffi_abi
- {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #define FFI_TRAMPOLINE_SIZE 24
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #ifdef _M_ARM64
- #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
- #endif
- /* ---- Internal ---- */
- #if defined (__APPLE__)
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
- #elif !defined(_M_ARM64)
- /* iOS and Windows reserve x18 for the system. Disable Go closures until
- a new static chain is chosen. */
- #define FFI_GO_CLOSURES 1
- #endif
- #ifndef _M_ARM64
- /* No complex type on Windows */
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- #endif
- ====================File: src/aarch64/sysv.S====================
- /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- #if defined(__aarch64__) || defined(__arm64__)
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #include <ffi_cfi.h>
- #include "internal.h"
- #ifdef HAVE_MACHINE_ASM_H
- #include <machine/asm.h>
- #else
- #ifdef __USER_LABEL_PREFIX__
- #define CONCAT1(a, b) CONCAT2(a, b)
- #define CONCAT2(a, b) a ## b
- /* Use the right prefix for global labels. */
- #define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
- #else
- #define CNAME(x) x
- #endif
- #endif
- #ifdef __AARCH64EB__
- # define BE(X) X
- #else
- # define BE(X) 0
- #endif
- #ifdef __ILP32__
- #define PTR_REG(n) w##n
- #else
- #define PTR_REG(n) x##n
- #endif
- #ifdef __ILP32__
- #define PTR_SIZE 4
- #else
- #define PTR_SIZE 8
- #endif
- .text
- .align 4
- /* ffi_call_SYSV
- extern void ffi_call_SYSV (void *stack, void *frame,
- void (*fn)(void), void *rvalue,
- int flags, void *closure);
- Therefore on entry we have:
- x0 stack
- x1 frame
- x2 fn
- x3 rvalue
- x4 flags
- x5 closure
- */
- cfi_startproc
- CNAME(ffi_call_SYSV):
- /* Use a stack frame allocated by our caller. */
- cfi_def_cfa(x1, 32);
- stp x29, x30, [x1]
- mov x29, x1
- mov sp, x0
- cfi_def_cfa_register(x29)
- cfi_rel_offset (x29, 0)
- cfi_rel_offset (x30, 8)
- mov x9, x2 /* save fn */
- mov x8, x3 /* install structure return */
- #ifdef FFI_GO_CLOSURES
- mov x18, x5 /* install static chain */
- #endif
- stp x3, x4, [x29, #16] /* save rvalue and flags */
- /* Load the vector argument passing registers, if necessary. */
- tbz w4, #AARCH64_FLAG_ARG_V_BIT, 1f
- ldp q0, q1, [sp, #0]
- ldp q2, q3, [sp, #32]
- ldp q4, q5, [sp, #64]
- ldp q6, q7, [sp, #96]
- 1:
- /* Load the core argument passing registers, including
- the structure return pointer. */
- ldp x0, x1, [sp, #16*N_V_ARG_REG + 0]
- ldp x2, x3, [sp, #16*N_V_ARG_REG + 16]
- ldp x4, x5, [sp, #16*N_V_ARG_REG + 32]
- ldp x6, x7, [sp, #16*N_V_ARG_REG + 48]
- /* Deallocate the context, leaving the stacked arguments. */
- add sp, sp, #CALL_CONTEXT_SIZE
- blr x9 /* call fn */
- ldp x3, x4, [x29, #16] /* reload rvalue and flags */
- /* Partially deconstruct the stack frame. */
- mov sp, x29
- cfi_def_cfa_register (sp)
- ldp x29, x30, [x29]
- /* Save the return value as directed. */
- adr x5, 0f
- and w4, w4, #AARCH64_RET_MASK
- add x5, x5, x4, lsl #3
- br x5
- /* Note that each table entry is 2 insns, and thus 8 bytes.
- For integer data, note that we're storing into ffi_arg
- and therefore we want to extend to 64 bits; these types
- have two consecutive entries allocated for them. */
- .align 4
- 0: ret /* VOID */
- nop
- 1: str x0, [x3] /* INT64 */
- ret
- 2: stp x0, x1, [x3] /* INT128 */
- ret
- 3: brk #1000 /* UNUSED */
- ret
- 4: brk #1000 /* UNUSED */
- ret
- 5: brk #1000 /* UNUSED */
- ret
- 6: brk #1000 /* UNUSED */
- ret
- 7: brk #1000 /* UNUSED */
- ret
- 8: st4 { v0.s, v1.s, v2.s, v3.s }[0], [x3] /* S4 */
- ret
- 9: st3 { v0.s, v1.s, v2.s }[0], [x3] /* S3 */
- ret
- 10: stp s0, s1, [x3] /* S2 */
- ret
- 11: str s0, [x3] /* S1 */
- ret
- 12: st4 { v0.d, v1.d, v2.d, v3.d }[0], [x3] /* D4 */
- ret
- 13: st3 { v0.d, v1.d, v2.d }[0], [x3] /* D3 */
- ret
- 14: stp d0, d1, [x3] /* D2 */
- ret
- 15: str d0, [x3] /* D1 */
- ret
- 16: str q3, [x3, #48] /* Q4 */
- nop
- 17: str q2, [x3, #32] /* Q3 */
- nop
- 18: stp q0, q1, [x3] /* Q2 */
- ret
- 19: str q0, [x3] /* Q1 */
- ret
- 20: uxtb w0, w0 /* UINT8 */
- str x0, [x3]
- 21: ret /* reserved */
- nop
- 22: uxth w0, w0 /* UINT16 */
- str x0, [x3]
- 23: ret /* reserved */
- nop
- 24: mov w0, w0 /* UINT32 */
- str x0, [x3]
- 25: ret /* reserved */
- nop
- 26: sxtb x0, w0 /* SINT8 */
- str x0, [x3]
- 27: ret /* reserved */
- nop
- 28: sxth x0, w0 /* SINT16 */
- str x0, [x3]
- 29: ret /* reserved */
- nop
- 30: sxtw x0, w0 /* SINT32 */
- str x0, [x3]
- 31: ret /* reserved */
- nop
- cfi_endproc
- .globl CNAME(ffi_call_SYSV)
- FFI_HIDDEN(CNAME(ffi_call_SYSV))
- #ifdef __ELF__
- .type CNAME(ffi_call_SYSV), #function
- .size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV)
- #endif
- /* ffi_closure_SYSV
- Closure invocation glue. This is the low level code invoked directly by
- the closure trampoline to setup and call a closure.
- On entry x17 points to a struct ffi_closure, x16 has been clobbered
- all other registers are preserved.
- We allocate a call context and save the argument passing registers,
- then invoked the generic C ffi_closure_SYSV_inner() function to do all
- the real work, on return we load the result passing registers back from
- the call context.
- */
- #define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)
- .align 4
- CNAME(ffi_closure_SYSV_V):
- cfi_startproc
- stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
- cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
- cfi_rel_offset (x29, 0)
- cfi_rel_offset (x30, 8)
- /* Save the argument passing vector registers. */
- stp q0, q1, [sp, #16 + 0]
- stp q2, q3, [sp, #16 + 32]
- stp q4, q5, [sp, #16 + 64]
- stp q6, q7, [sp, #16 + 96]
- b 0f
- cfi_endproc
- .globl CNAME(ffi_closure_SYSV_V)
- FFI_HIDDEN(CNAME(ffi_closure_SYSV_V))
- #ifdef __ELF__
- .type CNAME(ffi_closure_SYSV_V), #function
- .size CNAME(ffi_closure_SYSV_V), . - CNAME(ffi_closure_SYSV_V)
- #endif
- .align 4
- cfi_startproc
- CNAME(ffi_closure_SYSV):
- stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
- cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
- cfi_rel_offset (x29, 0)
- cfi_rel_offset (x30, 8)
- 0:
- mov x29, sp
- /* Save the argument passing core registers. */
- stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
- stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
- stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
- stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
- /* Load ffi_closure_inner arguments. */
- ldp PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET] /* load cif, fn */
- ldr PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2] /* load user_data */
- .Ldo_closure:
- add x3, sp, #16 /* load context */
- add x4, sp, #ffi_closure_SYSV_FS /* load stack */
- add x5, sp, #16+CALL_CONTEXT_SIZE /* load rvalue */
- mov x6, x8 /* load struct_rval */
- bl CNAME(ffi_closure_SYSV_inner)
- /* Load the return value as directed. */
- adr x1, 0f
- and w0, w0, #AARCH64_RET_MASK
- add x1, x1, x0, lsl #3
- add x3, sp, #16+CALL_CONTEXT_SIZE
- br x1
- /* Note that each table entry is 2 insns, and thus 8 bytes. */
- .align 4
- 0: b 99f /* VOID */
- nop
- 1: ldr x0, [x3] /* INT64 */
- b 99f
- 2: ldp x0, x1, [x3] /* INT128 */
- b 99f
- 3: brk #1000 /* UNUSED */
- nop
- 4: brk #1000 /* UNUSED */
- nop
- 5: brk #1000 /* UNUSED */
- nop
- 6: brk #1000 /* UNUSED */
- nop
- 7: brk #1000 /* UNUSED */
- nop
- 8: ldr s3, [x3, #12] /* S4 */
- nop
- 9: ldr s2, [x3, #8] /* S3 */
- nop
- 10: ldp s0, s1, [x3] /* S2 */
- b 99f
- 11: ldr s0, [x3] /* S1 */
- b 99f
- 12: ldr d3, [x3, #24] /* D4 */
- nop
- 13: ldr d2, [x3, #16] /* D3 */
- nop
- 14: ldp d0, d1, [x3] /* D2 */
- b 99f
- 15: ldr d0, [x3] /* D1 */
- b 99f
- 16: ldr q3, [x3, #48] /* Q4 */
- nop
- 17: ldr q2, [x3, #32] /* Q3 */
- nop
- 18: ldp q0, q1, [x3] /* Q2 */
- b 99f
- 19: ldr q0, [x3] /* Q1 */
- b 99f
- 20: ldrb w0, [x3, #BE(7)] /* UINT8 */
- b 99f
- 21: brk #1000 /* reserved */
- nop
- 22: ldrh w0, [x3, #BE(6)] /* UINT16 */
- b 99f
- 23: brk #1000 /* reserved */
- nop
- 24: ldr w0, [x3, #BE(4)] /* UINT32 */
- b 99f
- 25: brk #1000 /* reserved */
- nop
- 26: ldrsb x0, [x3, #BE(7)] /* SINT8 */
- b 99f
- 27: brk #1000 /* reserved */
- nop
- 28: ldrsh x0, [x3, #BE(6)] /* SINT16 */
- b 99f
- 29: brk #1000 /* reserved */
- nop
- 30: ldrsw x0, [x3, #BE(4)] /* SINT32 */
- nop
- 31: /* reserved */
- 99: ldp x29, x30, [sp], #ffi_closure_SYSV_FS
- cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS)
- cfi_restore (x29)
- cfi_restore (x30)
- ret
- cfi_endproc
- .globl CNAME(ffi_closure_SYSV)
- FFI_HIDDEN(CNAME(ffi_closure_SYSV))
- #ifdef __ELF__
- .type CNAME(ffi_closure_SYSV), #function
- .size CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV)
- #endif
- #if FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #include <mach/machine/vm_param.h>
- .align PAGE_MAX_SHIFT
- CNAME(ffi_closure_trampoline_table_page):
- .rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
- adr x16, -PAGE_MAX_SIZE
- ldp x17, x16, [x16]
- br x16
- nop /* each entry in the trampoline config page is 2*sizeof(void*) so the trampoline itself cannot be smaller that 16 bytes */
- .endr
- .globl CNAME(ffi_closure_trampoline_table_page)
- FFI_HIDDEN(CNAME(ffi_closure_trampoline_table_page))
- #ifdef __ELF__
- .type CNAME(ffi_closure_trampoline_table_page), #function
- .size CNAME(ffi_closure_trampoline_table_page), . - CNAME(ffi_closure_trampoline_table_page)
- #endif
- #endif
- #endif /* FFI_EXEC_TRAMPOLINE_TABLE */
- #ifdef FFI_GO_CLOSURES
- .align 4
- CNAME(ffi_go_closure_SYSV_V):
- cfi_startproc
- stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
- cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
- cfi_rel_offset (x29, 0)
- cfi_rel_offset (x30, 8)
- /* Save the argument passing vector registers. */
- stp q0, q1, [sp, #16 + 0]
- stp q2, q3, [sp, #16 + 32]
- stp q4, q5, [sp, #16 + 64]
- stp q6, q7, [sp, #16 + 96]
- b 0f
- cfi_endproc
- .globl CNAME(ffi_go_closure_SYSV_V)
- FFI_HIDDEN(CNAME(ffi_go_closure_SYSV_V))
- #ifdef __ELF__
- .type CNAME(ffi_go_closure_SYSV_V), #function
- .size CNAME(ffi_go_closure_SYSV_V), . - CNAME(ffi_go_closure_SYSV_V)
- #endif
- .align 4
- cfi_startproc
- CNAME(ffi_go_closure_SYSV):
- stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
- cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
- cfi_rel_offset (x29, 0)
- cfi_rel_offset (x30, 8)
- 0:
- mov x29, sp
- /* Save the argument passing core registers. */
- stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
- stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
- stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
- stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
- /* Load ffi_closure_inner arguments. */
- ldp PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */
- mov x2, x18 /* load user_data */
- b .Ldo_closure
- cfi_endproc
- .globl CNAME(ffi_go_closure_SYSV)
- FFI_HIDDEN(CNAME(ffi_go_closure_SYSV))
- #ifdef __ELF__
- .type CNAME(ffi_go_closure_SYSV), #function
- .size CNAME(ffi_go_closure_SYSV), . - CNAME(ffi_go_closure_SYSV)
- #endif
- #endif /* FFI_GO_CLOSURES */
- #endif /* __arm64__ */
- #if defined __ELF__ && defined __linux__
- .section .note.GNU-stack,"",%progbits
- #endif
- ====================File: src/arm/ffi.c====================
- /* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2011 Timothy Wall
- Copyright (c) 2011 Plausible Labs Cooperative, Inc.
- Copyright (c) 2011 Anthony Green
- Copyright (c) 2011 Free Software Foundation
- Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
- ARM Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #if defined(__arm__) || defined(_M_ARM)
- #include <fficonfig.h>
- #include <ffi.h>
- #include <ffi_common.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include "internal.h"
- #if defined(_MSC_VER) && defined(_M_ARM)
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #endif
- #if FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #include <mach/machine/vm_param.h>
- #endif
- #else
- #ifndef _M_ARM
- extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN;
- #else
- extern unsigned int ffi_arm_trampoline[3] FFI_HIDDEN;
- #endif
- #endif
- /* Forward declares. */
- static int vfp_type_p (const ffi_type *);
- static void layout_vfp_args (ffi_cif *);
- static void *
- ffi_align (ffi_type *ty, void *p)
- {
- /* Align if necessary */
- size_t alignment;
- #ifdef _WIN32_WCE
- alignment = 4;
- #else
- alignment = ty->alignment;
- if (alignment < 4)
- alignment = 4;
- #endif
- return (void *) FFI_ALIGN (p, alignment);
- }
- static size_t
- ffi_put_arg (ffi_type *ty, void *src, void *dst)
- {
- size_t z = ty->size;
- switch (ty->type)
- {
- case FFI_TYPE_SINT8:
- *(UINT32 *)dst = *(SINT8 *)src;
- break;
- case FFI_TYPE_UINT8:
- *(UINT32 *)dst = *(UINT8 *)src;
- break;
- case FFI_TYPE_SINT16:
- *(UINT32 *)dst = *(SINT16 *)src;
- break;
- case FFI_TYPE_UINT16:
- *(UINT32 *)dst = *(UINT16 *)src;
- break;
- case FFI_TYPE_INT:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_POINTER:
- #ifndef _MSC_VER
- case FFI_TYPE_FLOAT:
- #endif
- *(UINT32 *)dst = *(UINT32 *)src;
- break;
- #ifdef _MSC_VER
- // casting a float* to a UINT32* doesn't work on Windows
- case FFI_TYPE_FLOAT:
- *(uintptr_t *)dst = 0;
- *(float *)dst = *(float *)src;
- break;
- #endif
- case FFI_TYPE_SINT64:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_DOUBLE:
- *(UINT64 *)dst = *(UINT64 *)src;
- break;
- case FFI_TYPE_STRUCT:
- case FFI_TYPE_COMPLEX:
- memcpy (dst, src, z);
- break;
- default:
- abort();
- }
- return FFI_ALIGN (z, 4);
- }
- /* ffi_prep_args is called once stack space has been allocated
- for the function's arguments.
- The vfp_space parameter is the load area for VFP regs, the return
- value is cif->vfp_used (word bitset of VFP regs used for passing
- arguments). These are only used for the VFP hard-float ABI.
- */
- static void
- ffi_prep_args_SYSV (ffi_cif *cif, int flags, void *rvalue,
- void **avalue, char *argp)
- {
- ffi_type **arg_types = cif->arg_types;
- int i, n;
- if (flags == ARM_TYPE_STRUCT)
- {
- *(void **) argp = rvalue;
- argp += 4;
- }
- for (i = 0, n = cif->nargs; i < n; i++)
- {
- ffi_type *ty = arg_types[i];
- argp = ffi_align (ty, argp);
- argp += ffi_put_arg (ty, avalue[i], argp);
- }
- }
- static void
- ffi_prep_args_VFP (ffi_cif *cif, int flags, void *rvalue,
- void **avalue, char *stack, char *vfp_space)
- {
- ffi_type **arg_types = cif->arg_types;
- int i, n, vi = 0;
- char *argp, *regp, *eo_regp;
- char stack_used = 0;
- char done_with_regs = 0;
- /* The first 4 words on the stack are used for values
- passed in core registers. */
- regp = stack;
- eo_regp = argp = regp + 16;
- /* If the function returns an FFI_TYPE_STRUCT in memory,
- that address is passed in r0 to the function. */
- if (flags == ARM_TYPE_STRUCT)
- {
- *(void **) regp = rvalue;
- regp += 4;
- }
- for (i = 0, n = cif->nargs; i < n; i++)
- {
- ffi_type *ty = arg_types[i];
- void *a = avalue[i];
- int is_vfp_type = vfp_type_p (ty);
- /* Allocated in VFP registers. */
- if (vi < cif->vfp_nargs && is_vfp_type)
- {
- char *vfp_slot = vfp_space + cif->vfp_args[vi++] * 4;
- ffi_put_arg (ty, a, vfp_slot);
- continue;
- }
- /* Try allocating in core registers. */
- else if (!done_with_regs && !is_vfp_type)
- {
- char *tregp = ffi_align (ty, regp);
- size_t size = ty->size;
- size = (size < 4) ? 4 : size; // pad
- /* Check if there is space left in the aligned register
- area to place the argument. */
- if (tregp + size <= eo_regp)
- {
- regp = tregp + ffi_put_arg (ty, a, tregp);
- done_with_regs = (regp == argp);
- // ensure we did not write into the stack area
- FFI_ASSERT (regp <= argp);
- continue;
- }
- /* In case there are no arguments in the stack area yet,
- the argument is passed in the remaining core registers
- and on the stack. */
- else if (!stack_used)
- {
- stack_used = 1;
- done_with_regs = 1;
- argp = tregp + ffi_put_arg (ty, a, tregp);
- FFI_ASSERT (eo_regp < argp);
- continue;
- }
- }
- /* Base case, arguments are passed on the stack */
- stack_used = 1;
- argp = ffi_align (ty, argp);
- argp += ffi_put_arg (ty, a, argp);
- }
- }
- /* Perform machine dependent cif processing */
- ffi_status FFI_HIDDEN
- ffi_prep_cif_machdep (ffi_cif *cif)
- {
- int flags = 0, cabi = cif->abi;
- size_t bytes = cif->bytes;
- /* Map out the register placements of VFP register args. The VFP
- hard-float calling conventions are slightly more sophisticated
- than the base calling conventions, so we do it here instead of
- in ffi_prep_args(). */
- if (cabi == FFI_VFP)
- layout_vfp_args (cif);
- /* Set the return type flag */
- switch (cif->rtype->type)
- {
- case FFI_TYPE_VOID:
- flags = ARM_TYPE_VOID;
- break;
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_POINTER:
- flags = ARM_TYPE_INT;
- break;
- case FFI_TYPE_SINT64:
- case FFI_TYPE_UINT64:
- flags = ARM_TYPE_INT64;
- break;
- case FFI_TYPE_FLOAT:
- flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_S : ARM_TYPE_INT);
- break;
- case FFI_TYPE_DOUBLE:
- flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_D : ARM_TYPE_INT64);
- break;
- case FFI_TYPE_STRUCT:
- case FFI_TYPE_COMPLEX:
- if (cabi == FFI_VFP)
- {
- int h = vfp_type_p (cif->rtype);
- flags = ARM_TYPE_VFP_N;
- if (h == 0x100 + FFI_TYPE_FLOAT)
- flags = ARM_TYPE_VFP_S;
- if (h == 0x100 + FFI_TYPE_DOUBLE)
- flags = ARM_TYPE_VFP_D;
- if (h != 0)
- break;
- }
- /* A Composite Type not larger than 4 bytes is returned in r0.
- A Composite Type larger than 4 bytes, or whose size cannot
- be determined statically ... is stored in memory at an
- address passed [in r0]. */
- if (cif->rtype->size <= 4)
- flags = ARM_TYPE_INT;
- else
- {
- flags = ARM_TYPE_STRUCT;
- bytes += 4;
- }
- break;
- default:
- abort();
- }
- /* Round the stack up to a multiple of 8 bytes. This isn't needed
- everywhere, but it is on some platforms, and it doesn't harm anything
- when it isn't needed. */
- bytes = FFI_ALIGN (bytes, 8);
- /* Minimum stack space is the 4 register arguments that we pop. */
- if (bytes < 4*4)
- bytes = 4*4;
- cif->bytes = bytes;
- cif->flags = flags;
- return FFI_OK;
- }
- /* Perform machine dependent cif processing for variadic calls */
- ffi_status FFI_HIDDEN
- ffi_prep_cif_machdep_var (ffi_cif * cif,
- unsigned int nfixedargs, unsigned int ntotalargs)
- {
- /* VFP variadic calls actually use the SYSV ABI */
- if (cif->abi == FFI_VFP)
- cif->abi = FFI_SYSV;
- return ffi_prep_cif_machdep (cif);
- }
- /* Prototypes for assembly functions, in sysv.S. */
- struct call_frame
- {
- void *fp;
- void *lr;
- void *rvalue;
- int flags;
- void *closure;
- };
- extern void ffi_call_SYSV (void *stack, struct call_frame *,
- void (*fn) (void)) FFI_HIDDEN;
- extern void ffi_call_VFP (void *vfp_space, struct call_frame *,
- void (*fn) (void), unsigned vfp_used) FFI_HIDDEN;
- static void
- ffi_call_int (ffi_cif * cif, void (*fn) (void), void *rvalue,
- void **avalue, void *closure)
- {
- int flags = cif->flags;
- ffi_type *rtype = cif->rtype;
- size_t bytes, rsize, vfp_size;
- char *stack, *vfp_space, *new_rvalue;
- struct call_frame *frame;
- rsize = 0;
- if (rvalue == NULL)
- {
- /* If the return value is a struct and we don't have a return
- value address then we need to make one. Otherwise the return
- value is in registers and we can ignore them. */
- if (flags == ARM_TYPE_STRUCT)
- rsize = rtype->size;
- else
- flags = ARM_TYPE_VOID;
- }
- else if (flags == ARM_TYPE_VFP_N)
- {
- /* Largest case is double x 4. */
- rsize = 32;
- }
- else if (flags == ARM_TYPE_INT && rtype->type == FFI_TYPE_STRUCT)
- rsize = 4;
- /* Largest case. */
- vfp_size = (cif->abi == FFI_VFP && cif->vfp_used ? 8*8: 0);
- bytes = cif->bytes;
- stack = alloca (vfp_size + bytes + sizeof(struct call_frame) + rsize);
- vfp_space = NULL;
- if (vfp_size)
- {
- vfp_space = stack;
- stack += vfp_size;
- }
- frame = (struct call_frame *)(stack + bytes);
- new_rvalue = rvalue;
- if (rsize)
- new_rvalue = (void *)(frame + 1);
- frame->rvalue = new_rvalue;
- frame->flags = flags;
- frame->closure = closure;
- if (vfp_space)
- {
- ffi_prep_args_VFP (cif, flags, new_rvalue, avalue, stack, vfp_space);
- ffi_call_VFP (vfp_space, frame, fn, cif->vfp_used);
- }
- else
- {
- ffi_prep_args_SYSV (cif, flags, new_rvalue, avalue, stack);
- ffi_call_SYSV (stack, frame, fn);
- }
- if (rvalue && rvalue != new_rvalue)
- memcpy (rvalue, new_rvalue, rtype->size);
- }
- void
- ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
- {
- ffi_call_int (cif, fn, rvalue, avalue, NULL);
- }
- void
- ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,
- void **avalue, void *closure)
- {
- ffi_call_int (cif, fn, rvalue, avalue, closure);
- }
- static void *
- ffi_prep_incoming_args_SYSV (ffi_cif *cif, void *rvalue,
- char *argp, void **avalue)
- {
- ffi_type **arg_types = cif->arg_types;
- int i, n;
- if (cif->flags == ARM_TYPE_STRUCT)
- {
- rvalue = *(void **) argp;
- argp += 4;
- }
- else
- {
- if (cif->rtype->size && cif->rtype->size < 4)
- *(uint32_t *) rvalue = 0;
- }
- for (i = 0, n = cif->nargs; i < n; i++)
- {
- ffi_type *ty = arg_types[i];
- size_t z = ty->size;
- argp = ffi_align (ty, argp);
- avalue[i] = (void *) argp;
- argp += z;
- }
- return rvalue;
- }
- static void *
- ffi_prep_incoming_args_VFP (ffi_cif *cif, void *rvalue, char *stack,
- char *vfp_space, void **avalue)
- {
- ffi_type **arg_types = cif->arg_types;
- int i, n, vi = 0;
- char *argp, *regp, *eo_regp;
- char done_with_regs = 0;
- char stack_used = 0;
- regp = stack;
- eo_regp = argp = regp + 16;
- if (cif->flags == ARM_TYPE_STRUCT)
- {
- rvalue = *(void **) regp;
- regp += 4;
- }
- for (i = 0, n = cif->nargs; i < n; i++)
- {
- ffi_type *ty = arg_types[i];
- int is_vfp_type = vfp_type_p (ty);
- size_t z = ty->size;
- if (vi < cif->vfp_nargs && is_vfp_type)
- {
- avalue[i] = vfp_space + cif->vfp_args[vi++] * 4;
- continue;
- }
- else if (!done_with_regs && !is_vfp_type)
- {
- char *tregp = ffi_align (ty, regp);
- z = (z < 4) ? 4 : z; // pad
- /* If the arguments either fits into the registers or uses registers
- and stack, while we haven't read other things from the stack */
- if (tregp + z <= eo_regp || !stack_used)
- {
- /* Because we're little endian, this is what it turns into. */
- avalue[i] = (void *) tregp;
- regp = tregp + z;
- /* If we read past the last core register, make sure we
- have not read from the stack before and continue
- reading after regp. */
- if (regp > eo_regp)
- {
- FFI_ASSERT (!stack_used);
- argp = regp;
- }
- if (regp >= eo_regp)
- {
- done_with_regs = 1;
- stack_used = 1;
- }
- continue;
- }
- }
- stack_used = 1;
- argp = ffi_align (ty, argp);
- avalue[i] = (void *) argp;
- argp += z;
- }
- return rvalue;
- }
- struct closure_frame
- {
- char vfp_space[8*8] __attribute__((aligned(8)));
- char result[8*4];
- char argp[];
- };
- int FFI_HIDDEN
- ffi_closure_inner_SYSV (ffi_cif *cif,
- void (*fun) (ffi_cif *, void *, void **, void *),
- void *user_data,
- struct closure_frame *frame)
- {
- void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
- void *rvalue = ffi_prep_incoming_args_SYSV (cif, frame->result,
- frame->argp, avalue);
- fun (cif, rvalue, avalue, user_data);
- return cif->flags;
- }
- int FFI_HIDDEN
- ffi_closure_inner_VFP (ffi_cif *cif,
- void (*fun) (ffi_cif *, void *, void **, void *),
- void *user_data,
- struct closure_frame *frame)
- {
- void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
- void *rvalue = ffi_prep_incoming_args_VFP (cif, frame->result, frame->argp,
- frame->vfp_space, avalue);
- fun (cif, rvalue, avalue, user_data);
- return cif->flags;
- }
- void ffi_closure_SYSV (void) FFI_HIDDEN;
- void ffi_closure_VFP (void) FFI_HIDDEN;
- void ffi_go_closure_SYSV (void) FFI_HIDDEN;
- void ffi_go_closure_VFP (void) FFI_HIDDEN;
- /* the cif must already be prep'ed */
- ffi_status
- ffi_prep_closure_loc (ffi_closure * closure,
- ffi_cif * cif,
- void (*fun) (ffi_cif *, void *, void **, void *),
- void *user_data, void *codeloc)
- {
- void (*closure_func) (void) = ffi_closure_SYSV;
- if (cif->abi == FFI_VFP)
- {
- /* We only need take the vfp path if there are vfp arguments. */
- if (cif->vfp_used)
- closure_func = ffi_closure_VFP;
- }
- else if (cif->abi != FFI_SYSV)
- return FFI_BAD_ABI;
- #if FFI_EXEC_TRAMPOLINE_TABLE
- void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);
- config[0] = closure;
- config[1] = closure_func;
- #else
- #ifndef _M_ARM
- memcpy(closure->tramp, ffi_arm_trampoline, 8);
- #else
- // cast away function type so MSVC doesn't set the lower bit of the function pointer
- memcpy(closure->tramp, (void*)((uintptr_t)ffi_arm_trampoline & 0xFFFFFFFE), FFI_TRAMPOLINE_CLOSURE_OFFSET);
- #endif
- #if defined (__QNX__)
- msync(closure->tramp, 8, 0x1000000); /* clear data map */
- msync(codeloc, 8, 0x1000000); /* clear insn map */
- #elif defined(_MSC_VER)
- FlushInstructionCache(GetCurrentProcess(), closure->tramp, FFI_TRAMPOLINE_SIZE);
- #else
- __clear_cache(closure->tramp, closure->tramp + 8); /* clear data map */
- __clear_cache(codeloc, codeloc + 8); /* clear insn map */
- #endif
- #ifdef _M_ARM
- *(void(**)(void))(closure->tramp + FFI_TRAMPOLINE_CLOSURE_FUNCTION) = closure_func;
- #else
- *(void (**)(void))(closure->tramp + 8) = closure_func;
- #endif
- #endif
- closure->cif = cif;
- closure->fun = fun;
- closure->user_data = user_data;
- return FFI_OK;
- }
- ffi_status
- ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
- void (*fun) (ffi_cif *, void *, void **, void *))
- {
- void (*closure_func) (void) = ffi_go_closure_SYSV;
- if (cif->abi == FFI_VFP)
- {
- /* We only need take the vfp path if there are vfp arguments. */
- if (cif->vfp_used)
- closure_func = ffi_go_closure_VFP;
- }
- else if (cif->abi != FFI_SYSV)
- return FFI_BAD_ABI;
- closure->tramp = closure_func;
- closure->cif = cif;
- closure->fun = fun;
- return FFI_OK;
- }
- /* Below are routines for VFP hard-float support. */
- /* A subroutine of vfp_type_p. Given a structure type, return the type code
- of the first non-structure element. Recurse for structure elements.
- Return -1 if the structure is in fact empty, i.e. no nested elements. */
- static int
- is_hfa0 (const ffi_type *ty)
- {
- ffi_type **elements = ty->elements;
- int i, ret = -1;
- if (elements != NULL)
- for (i = 0; elements[i]; ++i)
- {
- ret = elements[i]->type;
- if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)
- {
- ret = is_hfa0 (elements[i]);
- if (ret < 0)
- continue;
- }
- break;
- }
- return ret;
- }
- /* A subroutine of vfp_type_p. Given a structure type, return true if all
- of the non-structure elements are the same as CANDIDATE. */
- static int
- is_hfa1 (const ffi_type *ty, int candidate)
- {
- ffi_type **elements = ty->elements;
- int i;
- if (elements != NULL)
- for (i = 0; elements[i]; ++i)
- {
- int t = elements[i]->type;
- if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
- {
- if (!is_hfa1 (elements[i], candidate))
- return 0;
- }
- else if (t != candidate)
- return 0;
- }
- return 1;
- }
- /* Determine if TY is an homogenous floating point aggregate (HFA).
- That is, a structure consisting of 1 to 4 members of all the same type,
- where that type is a floating point scalar.
- Returns non-zero iff TY is an HFA. The result is an encoded value where
- bits 0-7 contain the type code, and bits 8-10 contain the element count. */
- static int
- vfp_type_p (const ffi_type *ty)
- {
- ffi_type **elements;
- int candidate, i;
- size_t size, ele_count;
- /* Quickest tests first. */
- candidate = ty->type;
- switch (ty->type)
- {
- default:
- return 0;
- case FFI_TYPE_FLOAT:
- case FFI_TYPE_DOUBLE:
- ele_count = 1;
- goto done;
- case FFI_TYPE_COMPLEX:
- candidate = ty->elements[0]->type;
- if (candidate != FFI_TYPE_FLOAT && candidate != FFI_TYPE_DOUBLE)
- return 0;
- ele_count = 2;
- goto done;
- case FFI_TYPE_STRUCT:
- break;
- }
- /* No HFA types are smaller than 4 bytes, or larger than 32 bytes. */
- size = ty->size;
- if (size < 4 || size > 32)
- return 0;
- /* Find the type of the first non-structure member. */
- elements = ty->elements;
- candidate = elements[0]->type;
- if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX)
- {
- for (i = 0; ; ++i)
- {
- candidate = is_hfa0 (elements[i]);
- if (candidate >= 0)
- break;
- }
- }
- /* If the first member is not a floating point type, it's not an HFA.
- Also quickly re-check the size of the structure. */
- switch (candidate)
- {
- case FFI_TYPE_FLOAT:
- ele_count = size / sizeof(float);
- if (size != ele_count * sizeof(float))
- return 0;
- break;
- case FFI_TYPE_DOUBLE:
- ele_count = size / sizeof(double);
- if (size != ele_count * sizeof(double))
- return 0;
- break;
- default:
- return 0;
- }
- if (ele_count > 4)
- return 0;
- /* Finally, make sure that all scalar elements are the same type. */
- for (i = 0; elements[i]; ++i)
- {
- int t = elements[i]->type;
- if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
- {
- if (!is_hfa1 (elements[i], candidate))
- return 0;
- }
- else if (t != candidate)
- return 0;
- }
- /* All tests succeeded. Encode the result. */
- done:
- return (ele_count << 8) | candidate;
- }
- static int
- place_vfp_arg (ffi_cif *cif, int h)
- {
- unsigned short reg = cif->vfp_reg_free;
- int align = 1, nregs = h >> 8;
- if ((h & 0xff) == FFI_TYPE_DOUBLE)
- align = 2, nregs *= 2;
- /* Align register number. */
- if ((reg & 1) && align == 2)
- reg++;
- while (reg + nregs <= 16)
- {
- int s, new_used = 0;
- for (s = reg; s < reg + nregs; s++)
- {
- new_used |= (1 << s);
- if (cif->vfp_used & (1 << s))
- {
- reg += align;
- goto next_reg;
- }
- }
- /* Found regs to allocate. */
- cif->vfp_used |= new_used;
- cif->vfp_args[cif->vfp_nargs++] = (signed char)reg;
- /* Update vfp_reg_free. */
- if (cif->vfp_used & (1 << cif->vfp_reg_free))
- {
- reg += nregs;
- while (cif->vfp_used & (1 << reg))
- reg += 1;
- cif->vfp_reg_free = reg;
- }
- return 0;
- next_reg:;
- }
- // done, mark all regs as used
- cif->vfp_reg_free = 16;
- cif->vfp_used = 0xFFFF;
- return 1;
- }
- static void
- layout_vfp_args (ffi_cif * cif)
- {
- unsigned int i;
- /* Init VFP fields */
- cif->vfp_used = 0;
- cif->vfp_nargs = 0;
- cif->vfp_reg_free = 0;
- memset (cif->vfp_args, -1, 16); /* Init to -1. */
- for (i = 0; i < cif->nargs; i++)
- {
- int h = vfp_type_p (cif->arg_types[i]);
- if (h && place_vfp_arg (cif, h) == 1)
- break;
- }
- }
- #endif /* __arm__ or _M_ARM */
- ====================File: src/arm/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (c) 2010 CodeSourcery
- Copyright (c) 1996-2003 Red Hat, Inc.
- Target configuration macros for ARM.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- #ifndef LIBFFI_ASM
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- FFI_SYSV,
- FFI_VFP,
- FFI_LAST_ABI,
- #if defined(__ARM_PCS_VFP) || defined(_M_ARM)
- FFI_DEFAULT_ABI = FFI_VFP,
- #else
- FFI_DEFAULT_ABI = FFI_SYSV,
- #endif
- } ffi_abi;
- #endif
- #define FFI_EXTRA_CIF_FIELDS \
- int vfp_used; \
- unsigned short vfp_reg_free, vfp_nargs; \
- signed char vfp_args[16] \
- #define FFI_TARGET_SPECIFIC_VARIADIC
- #ifndef _M_ARM
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #define FFI_TRAMPOLINE_SIZE 12
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET 8
- #else
- #error "No trampoline table implementation"
- #endif
- #else
- #ifdef _MSC_VER
- #define FFI_TRAMPOLINE_SIZE 16
- #define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12
- #else
- #define FFI_TRAMPOLINE_SIZE 12
- #endif
- #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
- #endif
- #endif
- ====================File: src/arm/sysv.S====================
- /* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
- Copyright (c) 2011 Plausible Labs Cooperative, Inc.
- ARM Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifdef __arm__
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #include <ffi_cfi.h>
- #include "internal.h"
- /* GCC 4.8 provides __ARM_ARCH; construct it otherwise. */
- #ifndef __ARM_ARCH
- # if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
- || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
- || defined(__ARM_ARCH_7EM__)
- # define __ARM_ARCH 7
- # elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
- || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
- || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
- || defined(__ARM_ARCH_6M__)
- # define __ARM_ARCH 6
- # elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
- || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
- || defined(__ARM_ARCH_5TEJ__)
- # define __ARM_ARCH 5
- # else
- # define __ARM_ARCH 4
- # endif
- #endif
- /* Conditionally compile unwinder directives. */
- #ifdef __ARM_EABI__
- # define UNWIND(...) __VA_ARGS__
- #else
- # define UNWIND(...)
- #endif
- #if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__ARM_EABI__)
- .cfi_sections .debug_frame
- #endif
- #define CONCAT(a, b) CONCAT2(a, b)
- #define CONCAT2(a, b) a ## b
- #ifdef __USER_LABEL_PREFIX__
- # define CNAME(X) CONCAT (__USER_LABEL_PREFIX__, X)
- #else
- # define CNAME(X) X
- #endif
- #ifdef __ELF__
- # define SIZE(X) .size CNAME(X), . - CNAME(X)
- # define TYPE(X, Y) .type CNAME(X), Y
- #else
- # define SIZE(X)
- # define TYPE(X, Y)
- #endif
- #define ARM_FUNC_START_LOCAL(name) \
- .align 3; \
- TYPE(CNAME(name), %function); \
- CNAME(name):
- #define ARM_FUNC_START(name) \
- .globl CNAME(name); \
- FFI_HIDDEN(CNAME(name)); \
- ARM_FUNC_START_LOCAL(name)
- #define ARM_FUNC_END(name) \
- SIZE(name)
- /* Aid in defining a jump table with 8 bytes between entries. */
- /* ??? The clang assembler doesn't handle .if with symbolic expressions. */
- #ifdef __clang__
- # define E(index)
- #else
- # define E(index) \
- .if . - 0b - 8*index; \
- .error "type table out of sync"; \
- .endif
- #endif
- .text
- .syntax unified
- .arm
- #ifndef __clang__
- /* We require interworking on LDM, which implies ARMv5T,
- which implies the existance of BLX. */
- .arch armv5t
- #endif
- /* Note that we use STC and LDC to encode VFP instructions,
- so that we do not need ".fpu vfp", nor get that added to
- the object file attributes. These will not be executed
- unless the FFI_VFP abi is used. */
- @ r0: stack
- @ r1: frame
- @ r2: fn
- @ r3: vfp_used
- ARM_FUNC_START(ffi_call_VFP)
- UNWIND(.fnstart)
- cfi_startproc
- cmp r3, #3 @ load only d0 if possible
- #ifdef __clang__
- vldrle d0, [sp]
- vldmgt sp, {d0-d7}
- #else
- ldcle p11, cr0, [r0] @ vldrle d0, [sp]
- ldcgt p11, cr0, [r0], {16} @ vldmgt sp, {d0-d7}
- #endif
- add r0, r0, #64 @ discard the vfp register args
- /* FALLTHRU */
- ARM_FUNC_END(ffi_call_VFP)
- ARM_FUNC_START(ffi_call_SYSV)
- stm r1, {fp, lr}
- mov fp, r1
- @ This is a bit of a lie wrt the origin of the unwind info, but
- @ now we've got the usual frame pointer and two saved registers.
- UNWIND(.save {fp,lr})
- UNWIND(.setfp fp, sp)
- cfi_def_cfa(fp, 8)
- cfi_rel_offset(fp, 0)
- cfi_rel_offset(lr, 4)
- mov sp, r0 @ install the stack pointer
- mov lr, r2 @ move the fn pointer out of the way
- ldr ip, [fp, #16] @ install the static chain
- ldmia sp!, {r0-r3} @ move first 4 parameters in registers.
- blx lr @ call fn
- @ Load r2 with the pointer to storage for the return value
- @ Load r3 with the return type code
- ldr r2, [fp, #8]
- ldr r3, [fp, #12]
- @ Deallocate the stack with the arguments.
- mov sp, fp
- cfi_def_cfa_register(sp)
- @ Store values stored in registers.
- .align 3
- add pc, pc, r3, lsl #3
- nop
- 0:
- E(ARM_TYPE_VFP_S)
- #ifdef __clang__
- vstr s0, [r2]
- #else
- stc p10, cr0, [r2] @ vstr s0, [r2]
- #endif
- pop {fp,pc}
- E(ARM_TYPE_VFP_D)
- #ifdef __clang__
- vstr d0, [r2]
- #else
- stc p11, cr0, [r2] @ vstr d0, [r2]
- #endif
- pop {fp,pc}
- E(ARM_TYPE_VFP_N)
- #ifdef __clang__
- vstm r2, {d0-d3}
- #else
- stc p11, cr0, [r2], {8} @ vstm r2, {d0-d3}
- #endif
- pop {fp,pc}
- E(ARM_TYPE_INT64)
- str r1, [r2, #4]
- nop
- E(ARM_TYPE_INT)
- str r0, [r2]
- pop {fp,pc}
- E(ARM_TYPE_VOID)
- pop {fp,pc}
- nop
- E(ARM_TYPE_STRUCT)
- pop {fp,pc}
- cfi_endproc
- UNWIND(.fnend)
- ARM_FUNC_END(ffi_call_SYSV)
- /*
- int ffi_closure_inner_* (cif, fun, user_data, frame)
- */
- ARM_FUNC_START(ffi_go_closure_SYSV)
- cfi_startproc
- stmdb sp!, {r0-r3} @ save argument regs
- cfi_adjust_cfa_offset(16)
- ldr r0, [ip, #4] @ load cif
- ldr r1, [ip, #8] @ load fun
- mov r2, ip @ load user_data
- b 0f
- cfi_endproc
- ARM_FUNC_END(ffi_go_closure_SYSV)
- ARM_FUNC_START(ffi_closure_SYSV)
- UNWIND(.fnstart)
- cfi_startproc
- stmdb sp!, {r0-r3} @ save argument regs
- cfi_adjust_cfa_offset(16)
- #if FFI_EXEC_TRAMPOLINE_TABLE
- ldr ip, [ip] @ ip points to the config page, dereference to get the ffi_closure*
- #endif
- ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] @ load cif
- ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] @ load fun
- ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] @ load user_data
- 0:
- add ip, sp, #16 @ compute entry sp
- sub sp, sp, #64+32 @ allocate frame
- cfi_adjust_cfa_offset(64+32)
- stmdb sp!, {ip,lr}
- /* Remember that EABI unwind info only applies at call sites.
- We need do nothing except note the save of the stack pointer
- and the link registers. */
- UNWIND(.save {sp,lr})
- cfi_adjust_cfa_offset(8)
- cfi_rel_offset(lr, 4)
- add r3, sp, #8 @ load frame
- bl CNAME(ffi_closure_inner_SYSV)
- @ Load values returned in registers.
- add r2, sp, #8+64 @ load result
- adr r3, CNAME(ffi_closure_ret)
- add pc, r3, r0, lsl #3
- cfi_endproc
- UNWIND(.fnend)
- ARM_FUNC_END(ffi_closure_SYSV)
- ARM_FUNC_START(ffi_go_closure_VFP)
- cfi_startproc
- stmdb sp!, {r0-r3} @ save argument regs
- cfi_adjust_cfa_offset(16)
- ldr r0, [ip, #4] @ load cif
- ldr r1, [ip, #8] @ load fun
- mov r2, ip @ load user_data
- b 0f
- cfi_endproc
- ARM_FUNC_END(ffi_go_closure_VFP)
- ARM_FUNC_START(ffi_closure_VFP)
- UNWIND(.fnstart)
- cfi_startproc
- stmdb sp!, {r0-r3} @ save argument regs
- cfi_adjust_cfa_offset(16)
- #if FFI_EXEC_TRAMPOLINE_TABLE
- ldr ip, [ip] @ ip points to the config page, dereference to get the ffi_closure*
- #endif
- ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] @ load cif
- ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] @ load fun
- ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] @ load user_data
- 0:
- add ip, sp, #16
- sub sp, sp, #64+32 @ allocate frame
- cfi_adjust_cfa_offset(64+32)
- #ifdef __clang__
- vstm sp, {d0-d7}
- #else
- stc p11, cr0, [sp], {16} @ vstm sp, {d0-d7}
- #endif
- stmdb sp!, {ip,lr}
- /* See above. */
- UNWIND(.save {sp,lr})
- cfi_adjust_cfa_offset(8)
- cfi_rel_offset(lr, 4)
- add r3, sp, #8 @ load frame
- bl CNAME(ffi_closure_inner_VFP)
- @ Load values returned in registers.
- add r2, sp, #8+64 @ load result
- adr r3, CNAME(ffi_closure_ret)
- add pc, r3, r0, lsl #3
- cfi_endproc
- UNWIND(.fnend)
- ARM_FUNC_END(ffi_closure_VFP)
- /* Load values returned in registers for both closure entry points.
- Note that we use LDM with SP in the register set. This is deprecated
- by ARM, but not yet unpredictable. */
- ARM_FUNC_START_LOCAL(ffi_closure_ret)
- cfi_startproc
- cfi_rel_offset(sp, 0)
- cfi_rel_offset(lr, 4)
- 0:
- E(ARM_TYPE_VFP_S)
- #ifdef __clang__
- vldr s0, [r2]
- #else
- ldc p10, cr0, [r2] @ vldr s0, [r2]
- #endif
- ldm sp, {sp,pc}
- E(ARM_TYPE_VFP_D)
- #ifdef __clang__
- vldr d0, [r2]
- #else
- ldc p11, cr0, [r2] @ vldr d0, [r2]
- #endif
- ldm sp, {sp,pc}
- E(ARM_TYPE_VFP_N)
- #ifdef __clang__
- vldm r2, {d0-d3}
- #else
- ldc p11, cr0, [r2], {8} @ vldm r2, {d0-d3}
- #endif
- ldm sp, {sp,pc}
- E(ARM_TYPE_INT64)
- ldr r1, [r2, #4]
- nop
- E(ARM_TYPE_INT)
- ldr r0, [r2]
- ldm sp, {sp,pc}
- E(ARM_TYPE_VOID)
- ldm sp, {sp,pc}
- nop
- E(ARM_TYPE_STRUCT)
- ldm sp, {sp,pc}
- cfi_endproc
- ARM_FUNC_END(ffi_closure_ret)
- #if FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #include <mach/machine/vm_param.h>
- .align PAGE_MAX_SHIFT
- ARM_FUNC_START(ffi_closure_trampoline_table_page)
- .rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
- adr ip, #-PAGE_MAX_SIZE @ the config page is PAGE_MAX_SIZE behind the trampoline page
- sub ip, #8 @ account for pc bias
- ldr pc, [ip, #4] @ jump to ffi_closure_SYSV or ffi_closure_VFP
- .endr
- ARM_FUNC_END(ffi_closure_trampoline_table_page)
- #endif
- #else
- ARM_FUNC_START(ffi_arm_trampoline)
- 0: adr ip, 0b
- ldr pc, 1f
- 1: .long 0
- ARM_FUNC_END(ffi_arm_trampoline)
- #endif /* FFI_EXEC_TRAMPOLINE_TABLE */
- #endif /* __arm__ */
- #if defined __ELF__ && defined __linux__
- .section .note.GNU-stack,"",%progbits
- #endif
- ====================File: src/closures.c====================
- /* -----------------------------------------------------------------------
- closures.c - Copyright (c) 2019 Anthony Green
- Copyright (c) 2007, 2009, 2010 Red Hat, Inc.
- Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
- Copyright (c) 2011 Plausible Labs Cooperative, Inc.
- Code to allocate and deallocate memory for closures.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #if defined __linux__ && !defined _GNU_SOURCE
- #define _GNU_SOURCE 1
- #endif
- #include <fficonfig.h>
- #include <ffi.h>
- #include <ffi_common.h>
- #ifdef __NetBSD__
- #include <sys/param.h>
- #endif
- #if __NetBSD_Version__ - 0 >= 799007200
- /* NetBSD with PROT_MPROTECT */
- #include <sys/mman.h>
- #include <stddef.h>
- #include <unistd.h>
- static const size_t overhead =
- (sizeof(max_align_t) > sizeof(void *) + sizeof(size_t)) ?
- sizeof(max_align_t)
- : sizeof(void *) + sizeof(size_t);
- #define ADD_TO_POINTER(p, d) ((void *)((uintptr_t)(p) + (d)))
- void *
- ffi_closure_alloc (size_t size, void **code)
- {
- static size_t page_size;
- size_t rounded_size;
- void *codeseg, *dataseg;
- int prot;
- /* Expect that PAX mprotect is active and a separate code mapping is necessary. */
- if (!code)
- return NULL;
- /* Obtain system page size. */
- if (!page_size)
- page_size = sysconf(_SC_PAGESIZE);
- /* Round allocation size up to the next page, keeping in mind the size field and pointer to code map. */
- rounded_size = (size + overhead + page_size - 1) & ~(page_size - 1);
- /* Primary mapping is RW, but request permission to switch to PROT_EXEC later. */
- prot = PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC);
- dataseg = mmap(NULL, rounded_size, prot, MAP_ANON | MAP_PRIVATE, -1, 0);
- if (dataseg == MAP_FAILED)
- return NULL;
- /* Create secondary mapping and switch it to RX. */
- codeseg = mremap(dataseg, rounded_size, NULL, rounded_size, MAP_REMAPDUP);
- if (codeseg == MAP_FAILED) {
- munmap(dataseg, rounded_size);
- return NULL;
- }
- if (mprotect(codeseg, rounded_size, PROT_READ | PROT_EXEC) == -1) {
- munmap(codeseg, rounded_size);
- munmap(dataseg, rounded_size);
- return NULL;
- }
- /* Remember allocation size and location of the secondary mapping for ffi_closure_free. */
- memcpy(dataseg, &rounded_size, sizeof(rounded_size));
- memcpy(ADD_TO_POINTER(dataseg, sizeof(size_t)), &codeseg, sizeof(void *));
- *code = ADD_TO_POINTER(codeseg, overhead);
- return ADD_TO_POINTER(dataseg, overhead);
- }
- void
- ffi_closure_free (void *ptr)
- {
- void *codeseg, *dataseg;
- size_t rounded_size;
- dataseg = ADD_TO_POINTER(ptr, -overhead);
- memcpy(&rounded_size, dataseg, sizeof(rounded_size));
- memcpy(&codeseg, ADD_TO_POINTER(dataseg, sizeof(size_t)), sizeof(void *));
- munmap(dataseg, rounded_size);
- munmap(codeseg, rounded_size);
- }
- #else /* !NetBSD with PROT_MPROTECT */
- #if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
- # if __linux__ && !defined(__ANDROID__)
- /* This macro indicates it may be forbidden to map anonymous memory
- with both write and execute permission. Code compiled when this
- option is defined will attempt to map such pages once, but if it
- fails, it falls back to creating a temporary file in a writable and
- executable filesystem and mapping pages from it into separate
- locations in the virtual memory space, one location writable and
- another executable. */
- # define FFI_MMAP_EXEC_WRIT 1
- # define HAVE_MNTENT 1
- # endif
- # if defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)
- /* Windows systems may have Data Execution Protection (DEP) enabled,
- which requires the use of VirtualMalloc/VirtualFree to alloc/free
- executable memory. */
- # define FFI_MMAP_EXEC_WRIT 1
- # endif
- #endif
- #if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
- # if defined(__linux__) && !defined(__ANDROID__)
- /* When defined to 1 check for SELinux and if SELinux is active,
- don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
- might cause audit messages. */
- # define FFI_MMAP_EXEC_SELINUX 1
- # endif
- #endif
- #if FFI_CLOSURES
- #if FFI_EXEC_TRAMPOLINE_TABLE
- #ifdef __MACH__
- #include <mach/mach.h>
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- extern void *ffi_closure_trampoline_table_page;
- typedef struct ffi_trampoline_table ffi_trampoline_table;
- typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;
- struct ffi_trampoline_table
- {
- /* contiguous writable and executable pages */
- vm_address_t config_page;
- vm_address_t trampoline_page;
- /* free list tracking */
- uint16_t free_count;
- ffi_trampoline_table_entry *free_list;
- ffi_trampoline_table_entry *free_list_pool;
- ffi_trampoline_table *prev;
- ffi_trampoline_table *next;
- };
- struct ffi_trampoline_table_entry
- {
- void *(*trampoline) (void);
- ffi_trampoline_table_entry *next;
- };
- /* Total number of trampolines that fit in one trampoline table */
- #define FFI_TRAMPOLINE_COUNT (PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE)
- static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;
- static ffi_trampoline_table *ffi_trampoline_tables = NULL;
- static ffi_trampoline_table *
- ffi_trampoline_table_alloc (void)
- {
- ffi_trampoline_table *table;
- vm_address_t config_page;
- vm_address_t trampoline_page;
- vm_address_t trampoline_page_template;
- vm_prot_t cur_prot;
- vm_prot_t max_prot;
- kern_return_t kt;
- uint16_t i;
- /* Allocate two pages -- a config page and a placeholder page */
- config_page = 0x0;
- kt = vm_allocate (mach_task_self (), &config_page, PAGE_MAX_SIZE * 2,
- VM_FLAGS_ANYWHERE);
- if (kt != KERN_SUCCESS)
- return NULL;
- /* Remap the trampoline table on top of the placeholder page */
- trampoline_page = config_page + PAGE_MAX_SIZE;
- trampoline_page_template = (vm_address_t)&ffi_closure_trampoline_table_page;
- #ifdef __arm__
- /* ffi_closure_trampoline_table_page can be thumb-biased on some ARM archs */
- trampoline_page_template &= ~1UL;
- #endif
- kt = vm_remap (mach_task_self (), &trampoline_page, PAGE_MAX_SIZE, 0x0,
- VM_FLAGS_OVERWRITE, mach_task_self (), trampoline_page_template,
- FALSE, &cur_prot, &max_prot, VM_INHERIT_SHARE);
- if (kt != KERN_SUCCESS)
- {
- vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2);
- return NULL;
- }
- /* We have valid trampoline and config pages */
- table = calloc (1, sizeof (ffi_trampoline_table));
- table->free_count = FFI_TRAMPOLINE_COUNT;
- table->config_page = config_page;
- table->trampoline_page = trampoline_page;
- /* Create and initialize the free list */
- table->free_list_pool =
- calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry));
- for (i = 0; i < table->free_count; i++)
- {
- ffi_trampoline_table_entry *entry = &table->free_list_pool[i];
- entry->trampoline =
- (void *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
- if (i < table->free_count - 1)
- entry->next = &table->free_list_pool[i + 1];
- }
- table->free_list = table->free_list_pool;
- return table;
- }
- static void
- ffi_trampoline_table_free (ffi_trampoline_table *table)
- {
- /* Remove from the list */
- if (table->prev != NULL)
- table->prev->next = table->next;
- if (table->next != NULL)
- table->next->prev = table->prev;
- /* Deallocate pages */
- vm_deallocate (mach_task_self (), table->config_page, PAGE_MAX_SIZE * 2);
- /* Deallocate free list */
- free (table->free_list_pool);
- free (table);
- }
- void *
- ffi_closure_alloc (size_t size, void **code)
- {
- /* Create the closure */
- ffi_closure *closure = malloc (size);
- if (closure == NULL)
- return NULL;
- pthread_mutex_lock (&ffi_trampoline_lock);
- /* Check for an active trampoline table with available entries. */
- ffi_trampoline_table *table = ffi_trampoline_tables;
- if (table == NULL || table->free_list == NULL)
- {
- table = ffi_trampoline_table_alloc ();
- if (table == NULL)
- {
- pthread_mutex_unlock (&ffi_trampoline_lock);
- free (closure);
- return NULL;
- }
- /* Insert the new table at the top of the list */
- table->next = ffi_trampoline_tables;
- if (table->next != NULL)
- table->next->prev = table;
- ffi_trampoline_tables = table;
- }
- /* Claim the free entry */
- ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list;
- ffi_trampoline_tables->free_list = entry->next;
- ffi_trampoline_tables->free_count--;
- entry->next = NULL;
- pthread_mutex_unlock (&ffi_trampoline_lock);
- /* Initialize the return values */
- *code = entry->trampoline;
- closure->trampoline_table = table;
- closure->trampoline_table_entry = entry;
- return closure;
- }
- void
- ffi_closure_free (void *ptr)
- {
- ffi_closure *closure = ptr;
- pthread_mutex_lock (&ffi_trampoline_lock);
- /* Fetch the table and entry references */
- ffi_trampoline_table *table = closure->trampoline_table;
- ffi_trampoline_table_entry *entry = closure->trampoline_table_entry;
- /* Return the entry to the free list */
- entry->next = table->free_list;
- table->free_list = entry;
- table->free_count++;
- /* If all trampolines within this table are free, and at least one other table exists, deallocate
- * the table */
- if (table->free_count == FFI_TRAMPOLINE_COUNT
- && ffi_trampoline_tables != table)
- {
- ffi_trampoline_table_free (table);
- }
- else if (ffi_trampoline_tables != table)
- {
- /* Otherwise, bump this table to the top of the list */
- table->prev = NULL;
- table->next = ffi_trampoline_tables;
- if (ffi_trampoline_tables != NULL)
- ffi_trampoline_tables->prev = table;
- ffi_trampoline_tables = table;
- }
- pthread_mutex_unlock (&ffi_trampoline_lock);
- /* Free the closure */
- free (closure);
- }
- #endif
- // Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations.
- #elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */
- #define USE_LOCKS 1
- #define USE_DL_PREFIX 1
- #ifdef __GNUC__
- #ifndef USE_BUILTIN_FFS
- #define USE_BUILTIN_FFS 1
- #endif
- #endif
- /* We need to use mmap, not sbrk. */
- #define HAVE_MORECORE 0
- /* We could, in theory, support mremap, but it wouldn't buy us anything. */
- #define HAVE_MREMAP 0
- /* We have no use for this, so save some code and data. */
- #define NO_MALLINFO 1
- /* We need all allocations to be in regular segments, otherwise we
- lose track of the corresponding code address. */
- #define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
- /* Don't allocate more than a page unless needed. */
- #define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- #ifndef _MSC_VER
- #include <unistd.h>
- #endif
- #include <string.h>
- #include <stdio.h>
- #if !defined(X86_WIN32) && !defined(X86_WIN64) && !defined(_M_ARM64)
- #ifdef HAVE_MNTENT
- #include <mntent.h>
- #endif /* HAVE_MNTENT */
- #include <sys/param.h>
- #include <pthread.h>
- /* We don't want sys/mman.h to be included after we redefine mmap and
- dlmunmap. */
- #include <sys/mman.h>
- #define LACKS_SYS_MMAN_H 1
- #if FFI_MMAP_EXEC_SELINUX
- #include <sys/statfs.h>
- #include <stdlib.h>
- static int selinux_enabled = -1;
- static int
- selinux_enabled_check (void)
- {
- struct statfs sfs;
- FILE *f;
- char *buf = NULL;
- size_t len = 0;
- if (statfs ("/selinux", &sfs) >= 0
- && (unsigned int) sfs.f_type == 0xf97cff8cU)
- return 1;
- f = fopen ("/proc/mounts", "r");
- if (f == NULL)
- return 0;
- while (getline (&buf, &len, f) >= 0)
- {
- char *p = strchr (buf, ' ');
- if (p == NULL)
- break;
- p = strchr (p + 1, ' ');
- if (p == NULL)
- break;
- if (strncmp (p + 1, "selinuxfs ", 10) == 0)
- {
- free (buf);
- fclose (f);
- return 1;
- }
- }
- free (buf);
- fclose (f);
- return 0;
- }
- #define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \
- : (selinux_enabled = selinux_enabled_check ()))
- #else
- #define is_selinux_enabled() 0
- #endif /* !FFI_MMAP_EXEC_SELINUX */
- /* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */
- #ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX
- #include <stdlib.h>
- static int emutramp_enabled = -1;
- static int
- emutramp_enabled_check (void)
- {
- char *buf = NULL;
- size_t len = 0;
- FILE *f;
- int ret;
- f = fopen ("/proc/self/status", "r");
- if (f == NULL)
- return 0;
- ret = 0;
- while (getline (&buf, &len, f) != -1)
- if (!strncmp (buf, "PaX:", 4))
- {
- char emutramp;
- if (sscanf (buf, "%*s %*c%c", &emutramp) == 1)
- ret = (emutramp == 'E');
- break;
- }
- free (buf);
- fclose (f);
- return ret;
- }
- #define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \
- : (emutramp_enabled = emutramp_enabled_check ()))
- #endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */
- #elif defined (__CYGWIN__) || defined(__INTERIX)
- #include <sys/mman.h>
- /* Cygwin is Linux-like, but not quite that Linux-like. */
- #define is_selinux_enabled() 0
- #endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
- #ifndef FFI_MMAP_EXEC_EMUTRAMP_PAX
- #define is_emutramp_enabled() 0
- #endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */
- /* Declare all functions defined in dlmalloc.c as static. */
- static void *dlmalloc(size_t);
- static void dlfree(void*);
- static void *dlcalloc(size_t, size_t) MAYBE_UNUSED;
- static void *dlrealloc(void *, size_t) MAYBE_UNUSED;
- static void *dlmemalign(size_t, size_t) MAYBE_UNUSED;
- static void *dlvalloc(size_t) MAYBE_UNUSED;
- static int dlmallopt(int, int) MAYBE_UNUSED;
- static size_t dlmalloc_footprint(void) MAYBE_UNUSED;
- static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED;
- static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED;
- static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED;
- static void *dlpvalloc(size_t) MAYBE_UNUSED;
- static int dlmalloc_trim(size_t) MAYBE_UNUSED;
- static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
- static void dlmalloc_stats(void) MAYBE_UNUSED;
- #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
- /* Use these for mmap and munmap within dlmalloc.c. */
- static void *dlmmap(void *, size_t, int, int, int, off_t);
- static int dlmunmap(void *, size_t);
- #endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
- #define mmap dlmmap
- #define munmap dlmunmap
- #include "dlmalloc.c"
- #undef mmap
- #undef munmap
- #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
- /* A mutex used to synchronize access to *exec* variables in this file. */
- static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
- /* A file descriptor of a temporary file from which we'll map
- executable pages. */
- static int execfd = -1;
- /* The amount of space already allocated from the temporary file. */
- static size_t execsize = 0;
- /* Open a temporary file name, and immediately unlink it. */
- static int
- open_temp_exec_file_name (char *name, int flags)
- {
- int fd;
- #ifdef HAVE_MKOSTEMP
- fd = mkostemp (name, flags);
- #else
- fd = mkstemp (name);
- #endif
- if (fd != -1)
- unlink (name);
- return fd;
- }
- /* Open a temporary file in the named directory. */
- static int
- open_temp_exec_file_dir (const char *dir)
- {
- static const char suffix[] = "/ffiXXXXXX";
- int lendir, flags;
- char *tempname;
- #ifdef O_TMPFILE
- int fd;
- #endif
- #ifdef O_CLOEXEC
- flags = O_CLOEXEC;
- #else
- flags = 0;
- #endif
- #ifdef O_TMPFILE
- fd = open (dir, flags | O_RDWR | O_EXCL | O_TMPFILE, 0700);
- /* If the running system does not support the O_TMPFILE flag then retry without it. */
- if (fd != -1 || (errno != EINVAL && errno != EISDIR && errno != EOPNOTSUPP)) {
- return fd;
- } else {
- errno = 0;
- }
- #endif
- lendir = (int) strlen (dir);
- tempname = __builtin_alloca (lendir + sizeof (suffix));
- if (!tempname)
- return -1;
- memcpy (tempname, dir, lendir);
- memcpy (tempname + lendir, suffix, sizeof (suffix));
- return open_temp_exec_file_name (tempname, flags);
- }
- /* Open a temporary file in the directory in the named environment
- variable. */
- static int
- open_temp_exec_file_env (const char *envvar)
- {
- const char *value = getenv (envvar);
- if (!value)
- return -1;
- return open_temp_exec_file_dir (value);
- }
- #ifdef HAVE_MNTENT
- /* Open a temporary file in an executable and writable mount point
- listed in the mounts file. Subsequent calls with the same mounts
- keep searching for mount points in the same file. Providing NULL
- as the mounts file closes the file. */
- static int
- open_temp_exec_file_mnt (const char *mounts)
- {
- static const char *last_mounts;
- static FILE *last_mntent;
- if (mounts != last_mounts)
- {
- if (last_mntent)
- endmntent (last_mntent);
- last_mounts = mounts;
- if (mounts)
- last_mntent = setmntent (mounts, "r");
- else
- last_mntent = NULL;
- }
- if (!last_mntent)
- return -1;
- for (;;)
- {
- int fd;
- struct mntent mnt;
- char buf[MAXPATHLEN * 3];
- if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL)
- return -1;
- if (hasmntopt (&mnt, "ro")
- || hasmntopt (&mnt, "noexec")
- || access (mnt.mnt_dir, W_OK))
- continue;
- fd = open_temp_exec_file_dir (mnt.mnt_dir);
- if (fd != -1)
- return fd;
- }
- }
- #endif /* HAVE_MNTENT */
- /* Instructions to look for a location to hold a temporary file that
- can be mapped in for execution. */
- static struct
- {
- int (*func)(const char *);
- const char *arg;
- int repeat;
- } open_temp_exec_file_opts[] = {
- { open_temp_exec_file_env, "TMPDIR", 0 },
- { open_temp_exec_file_dir, "/tmp", 0 },
- { open_temp_exec_file_dir, "/var/tmp", 0 },
- { open_temp_exec_file_dir, "/dev/shm", 0 },
- { open_temp_exec_file_env, "HOME", 0 },
- #ifdef HAVE_MNTENT
- { open_temp_exec_file_mnt, "/etc/mtab", 1 },
- { open_temp_exec_file_mnt, "/proc/mounts", 1 },
- #endif /* HAVE_MNTENT */
- };
- /* Current index into open_temp_exec_file_opts. */
- static int open_temp_exec_file_opts_idx = 0;
- /* Reset a current multi-call func, then advances to the next entry.
- If we're at the last, go back to the first and return nonzero,
- otherwise return zero. */
- static int
- open_temp_exec_file_opts_next (void)
- {
- if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
- open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL);
- open_temp_exec_file_opts_idx++;
- if (open_temp_exec_file_opts_idx
- == (sizeof (open_temp_exec_file_opts)
- / sizeof (*open_temp_exec_file_opts)))
- {
- open_temp_exec_file_opts_idx = 0;
- return 1;
- }
- return 0;
- }
- /* Return a file descriptor of a temporary zero-sized file in a
- writable and executable filesystem. */
- static int
- open_temp_exec_file (void)
- {
- int fd;
- do
- {
- fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func
- (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg);
- if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat
- || fd == -1)
- {
- if (open_temp_exec_file_opts_next ())
- break;
- }
- }
- while (fd == -1);
- return fd;
- }
- /* We need to allocate space in a file that will be backing a writable
- mapping. Several problems exist with the usual approaches:
- - fallocate() is Linux-only
- - posix_fallocate() is not available on all platforms
- - ftruncate() does not allocate space on filesystems with sparse files
- Failure to allocate the space will cause SIGBUS to be thrown when
- the mapping is subsequently written to. */
- static int
- allocate_space (int fd, off_t offset, off_t len)
- {
- static size_t page_size;
- /* Obtain system page size. */
- if (!page_size)
- page_size = sysconf(_SC_PAGESIZE);
- unsigned char buf[page_size];
- memset (buf, 0, page_size);
- while (len > 0)
- {
- off_t to_write = (len < page_size) ? len : page_size;
- if (write (fd, buf, to_write) < to_write)
- return -1;
- len -= to_write;
- }
- return 0;
- }
- /* Map in a chunk of memory from the temporary exec file into separate
- locations in the virtual memory address space, one writable and one
- executable. Returns the address of the writable portion, after
- storing an offset to the corresponding executable portion at the
- last word of the requested chunk. */
- static void *
- dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
- {
- void *ptr;
- if (execfd == -1)
- {
- open_temp_exec_file_opts_idx = 0;
- retry_open:
- execfd = open_temp_exec_file ();
- if (execfd == -1)
- return MFAIL;
- }
- offset = execsize;
- if (allocate_space (execfd, offset, length))
- return MFAIL;
- flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
- flags |= MAP_SHARED;
- ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC,
- flags, execfd, offset);
- if (ptr == MFAIL)
- {
- if (!offset)
- {
- close (execfd);
- goto retry_open;
- }
- if (ftruncate (execfd, offset) != 0)
- {
- /* Fixme : Error logs can be added here. Returning an error for
- * ftruncte() will not add any advantage as it is being
- * validating in the error case. */
- }
- return MFAIL;
- }
- else if (!offset
- && open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
- open_temp_exec_file_opts_next ();
- start = mmap (start, length, prot, flags, execfd, offset);
- if (start == MFAIL)
- {
- munmap (ptr, length);
- if (ftruncate (execfd, offset) != 0)
- {
- /* Fixme : Error logs can be added here. Returning an error for
- * ftruncte() will not add any advantage as it is being
- * validating in the error case. */
- }
- return start;
- }
- mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start;
- execsize += length;
- return start;
- }
- /* Map in a writable and executable chunk of memory if possible.
- Failing that, fall back to dlmmap_locked. */
- static void *
- dlmmap (void *start, size_t length, int prot,
- int flags, int fd, off_t offset)
- {
- void *ptr;
- assert (start == NULL && length % malloc_getpagesize == 0
- && prot == (PROT_READ | PROT_WRITE)
- && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
- && fd == -1 && offset == 0);
- if (execfd == -1 && is_emutramp_enabled ())
- {
- ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);
- return ptr;
- }
- if (execfd == -1 && !is_selinux_enabled ())
- {
- ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
- if (ptr != MFAIL || (errno != EPERM && errno != EACCES))
- /* Cool, no need to mess with separate segments. */
- return ptr;
- /* If MREMAP_DUP is ever introduced and implemented, try mmap
- with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with
- MREMAP_DUP and prot at this point. */
- }
- if (execsize == 0 || execfd == -1)
- {
- pthread_mutex_lock (&open_temp_exec_file_mutex);
- ptr = dlmmap_locked (start, length, prot, flags, offset);
- pthread_mutex_unlock (&open_temp_exec_file_mutex);
- return ptr;
- }
- return dlmmap_locked (start, length, prot, flags, offset);
- }
- /* Release memory at the given address, as well as the corresponding
- executable page if it's separate. */
- static int
- dlmunmap (void *start, size_t length)
- {
- /* We don't bother decreasing execsize or truncating the file, since
- we can't quite tell whether we're unmapping the end of the file.
- We don't expect frequent deallocation anyway. If we did, we
- could locate pages in the file by writing to the pages being
- deallocated and checking that the file contents change.
- Yuck. */
- msegmentptr seg = segment_holding (gm, start);
- void *code;
- if (seg && (code = add_segment_exec_offset (start, seg)) != start)
- {
- int ret = munmap (code, length);
- if (ret)
- return ret;
- }
- return munmap (start, length);
- }
- #if FFI_CLOSURE_FREE_CODE
- /* Return segment holding given code address. */
- static msegmentptr
- segment_holding_code (mstate m, char* addr)
- {
- msegmentptr sp = &m->seg;
- for (;;) {
- if (addr >= add_segment_exec_offset (sp->base, sp)
- && addr < add_segment_exec_offset (sp->base, sp) + sp->size)
- return sp;
- if ((sp = sp->next) == 0)
- return 0;
- }
- }
- #endif
- #endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
- /* Allocate a chunk of memory with the given size. Returns a pointer
- to the writable address, and sets *CODE to the executable
- corresponding virtual address. */
- void *
- ffi_closure_alloc (size_t size, void **code)
- {
- void *ptr;
- if (!code)
- return NULL;
- ptr = dlmalloc (size);
- if (ptr)
- {
- msegmentptr seg = segment_holding (gm, ptr);
- *code = add_segment_exec_offset (ptr, seg);
- }
- return ptr;
- }
- void *
- ffi_data_to_code_pointer (void *data)
- {
- msegmentptr seg = segment_holding (gm, data);
- /* We expect closures to be allocated with ffi_closure_alloc(), in
- which case seg will be non-NULL. However, some users take on the
- burden of managing this memory themselves, in which case this
- we'll just return data. */
- if (seg)
- return add_segment_exec_offset (data, seg);
- else
- return data;
- }
- /* Release a chunk of memory allocated with ffi_closure_alloc. If
- FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
- writable or the executable address given. Otherwise, only the
- writable address can be provided here. */
- void
- ffi_closure_free (void *ptr)
- {
- #if FFI_CLOSURE_FREE_CODE
- msegmentptr seg = segment_holding_code (gm, ptr);
- if (seg)
- ptr = sub_segment_exec_offset (ptr, seg);
- #endif
- dlfree (ptr);
- }
- # else /* ! FFI_MMAP_EXEC_WRIT */
- /* On many systems, memory returned by malloc is writable and
- executable, so just use it. */
- #include <stdlib.h>
- void *
- ffi_closure_alloc (size_t size, void **code)
- {
- if (!code)
- return NULL;
- return *code = malloc (size);
- }
- void
- ffi_closure_free (void *ptr)
- {
- free (ptr);
- }
- void *
- ffi_data_to_code_pointer (void *data)
- {
- return data;
- }
- # endif /* ! FFI_MMAP_EXEC_WRIT */
- #endif /* FFI_CLOSURES */
- #endif /* NetBSD with PROT_MPROTECT */
- ====================File: src/java_raw_api.c====================
- /* -----------------------------------------------------------------------
- java_raw_api.c - Copyright (c) 1999, 2007, 2008 Red Hat, Inc.
- Cloned from raw_api.c
- Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>
- Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com>
- $Id $
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- /* This defines a Java- and 64-bit specific variant of the raw API. */
- /* It assumes that "raw" argument blocks look like Java stacks on a */
- /* 64-bit machine. Arguments that can be stored in a single stack */
- /* stack slots (longs, doubles) occupy 128 bits, but only the first */
- /* 64 bits are actually used. */
- #include <ffi.h>
- #include <ffi_common.h>
- #include <stdlib.h>
- #if !defined(NO_JAVA_RAW_API)
- size_t
- ffi_java_raw_size (ffi_cif *cif)
- {
- size_t result = 0;
- int i;
- ffi_type **at = cif->arg_types;
- for (i = cif->nargs-1; i >= 0; i--, at++)
- {
- switch((*at) -> type) {
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_DOUBLE:
- result += 2 * FFI_SIZEOF_JAVA_RAW;
- break;
- case FFI_TYPE_STRUCT:
- /* No structure parameters in Java. */
- abort();
- case FFI_TYPE_COMPLEX:
- /* Not supported yet. */
- abort();
- default:
- result += FFI_SIZEOF_JAVA_RAW;
- }
- }
- return result;
- }
- void
- ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)
- {
- unsigned i;
- ffi_type **tp = cif->arg_types;
- #if WORDS_BIGENDIAN
- for (i = 0; i < cif->nargs; i++, tp++, args++)
- {
- switch ((*tp)->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- *args = (void*) ((char*)(raw++) + 3);
- break;
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- *args = (void*) ((char*)(raw++) + 2);
- break;
- #if FFI_SIZEOF_JAVA_RAW == 8
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_DOUBLE:
- *args = (void *)raw;
- raw += 2;
- break;
- #endif
- case FFI_TYPE_POINTER:
- *args = (void*) &(raw++)->ptr;
- break;
- case FFI_TYPE_COMPLEX:
- /* Not supported yet. */
- abort();
- default:
- *args = raw;
- raw +=
- FFI_ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
- }
- }
- #else /* WORDS_BIGENDIAN */
- #if !PDP
- /* then assume little endian */
- for (i = 0; i < cif->nargs; i++, tp++, args++)
- {
- #if FFI_SIZEOF_JAVA_RAW == 8
- switch((*tp)->type) {
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_DOUBLE:
- *args = (void*) raw;
- raw += 2;
- break;
- case FFI_TYPE_COMPLEX:
- /* Not supported yet. */
- abort();
- default:
- *args = (void*) raw++;
- }
- #else /* FFI_SIZEOF_JAVA_RAW != 8 */
- *args = (void*) raw;
- raw +=
- FFI_ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
- #endif /* FFI_SIZEOF_JAVA_RAW == 8 */
- }
- #else
- #error "pdp endian not supported"
- #endif /* ! PDP */
- #endif /* WORDS_BIGENDIAN */
- }
- void
- ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw)
- {
- unsigned i;
- ffi_type **tp = cif->arg_types;
- for (i = 0; i < cif->nargs; i++, tp++, args++)
- {
- switch ((*tp)->type)
- {
- case FFI_TYPE_UINT8:
- #if WORDS_BIGENDIAN
- *(UINT32*)(raw++) = *(UINT8*) (*args);
- #else
- (raw++)->uint = *(UINT8*) (*args);
- #endif
- break;
- case FFI_TYPE_SINT8:
- #if WORDS_BIGENDIAN
- *(SINT32*)(raw++) = *(SINT8*) (*args);
- #else
- (raw++)->sint = *(SINT8*) (*args);
- #endif
- break;
- case FFI_TYPE_UINT16:
- #if WORDS_BIGENDIAN
- *(UINT32*)(raw++) = *(UINT16*) (*args);
- #else
- (raw++)->uint = *(UINT16*) (*args);
- #endif
- break;
- case FFI_TYPE_SINT16:
- #if WORDS_BIGENDIAN
- *(SINT32*)(raw++) = *(SINT16*) (*args);
- #else
- (raw++)->sint = *(SINT16*) (*args);
- #endif
- break;
- case FFI_TYPE_UINT32:
- #if WORDS_BIGENDIAN
- *(UINT32*)(raw++) = *(UINT32*) (*args);
- #else
- (raw++)->uint = *(UINT32*) (*args);
- #endif
- break;
- case FFI_TYPE_SINT32:
- #if WORDS_BIGENDIAN
- *(SINT32*)(raw++) = *(SINT32*) (*args);
- #else
- (raw++)->sint = *(SINT32*) (*args);
- #endif
- break;
- case FFI_TYPE_FLOAT:
- (raw++)->flt = *(FLOAT32*) (*args);
- break;
- #if FFI_SIZEOF_JAVA_RAW == 8
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_DOUBLE:
- raw->uint = *(UINT64*) (*args);
- raw += 2;
- break;
- #endif
- case FFI_TYPE_POINTER:
- (raw++)->ptr = **(void***) args;
- break;
- default:
- #if FFI_SIZEOF_JAVA_RAW == 8
- FFI_ASSERT(0); /* Should have covered all cases */
- #else
- memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
- raw +=
- FFI_ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
- #endif
- }
- }
- }
- #if !FFI_NATIVE_RAW_API
- static void
- ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
- {
- #if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
- switch (cif->rtype->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_UINT32:
- *(UINT64 *)rvalue <<= 32;
- break;
- case FFI_TYPE_SINT8:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_INT:
- #if FFI_SIZEOF_JAVA_RAW == 4
- case FFI_TYPE_POINTER:
- #endif
- *(SINT64 *)rvalue <<= 32;
- break;
- case FFI_TYPE_COMPLEX:
- /* Not supported yet. */
- abort();
- default:
- break;
- }
- #endif
- }
- static void
- ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
- {
- #if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
- switch (cif->rtype->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_UINT32:
- *(UINT64 *)rvalue >>= 32;
- break;
- case FFI_TYPE_SINT8:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_INT:
- *(SINT64 *)rvalue >>= 32;
- break;
- case FFI_TYPE_COMPLEX:
- /* Not supported yet. */
- abort();
- default:
- break;
- }
- #endif
- }
- /* This is a generic definition of ffi_raw_call, to be used if the
- * native system does not provide a machine-specific implementation.
- * Having this, allows code to be written for the raw API, without
- * the need for system-specific code to handle input in that format;
- * these following couple of functions will handle the translation forth
- * and back automatically. */
- void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue,
- ffi_java_raw *raw)
- {
- void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
- ffi_java_raw_to_ptrarray (cif, raw, avalue);
- ffi_call (cif, fn, rvalue, avalue);
- ffi_java_rvalue_to_raw (cif, rvalue);
- }
- #if FFI_CLOSURES /* base system provides closures */
- static void
- ffi_java_translate_args (ffi_cif *cif, void *rvalue,
- void **avalue, void *user_data)
- {
- ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif));
- ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
- ffi_java_ptrarray_to_raw (cif, avalue, raw);
- (*cl->fun) (cif, rvalue, (ffi_raw*)raw, cl->user_data);
- ffi_java_raw_to_rvalue (cif, rvalue);
- }
- ffi_status
- ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl,
- ffi_cif *cif,
- void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
- void *user_data,
- void *codeloc)
- {
- ffi_status status;
- status = ffi_prep_closure_loc ((ffi_closure*) cl,
- cif,
- &ffi_java_translate_args,
- codeloc,
- codeloc);
- if (status == FFI_OK)
- {
- cl->fun = fun;
- cl->user_data = user_data;
- }
- return status;
- }
- /* Again, here is the generic version of ffi_prep_raw_closure, which
- * will install an intermediate "hub" for translation of arguments from
- * the pointer-array format, to the raw format */
- ffi_status
- ffi_prep_java_raw_closure (ffi_java_raw_closure* cl,
- ffi_cif *cif,
- void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
- void *user_data)
- {
- return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl);
- }
- #endif /* FFI_CLOSURES */
- #endif /* !FFI_NATIVE_RAW_API */
- #endif /* !NO_JAVA_RAW_API */
- ====================File: src/powerpc/aix.S====================
- /* -----------------------------------------------------------------------
- aix.S - Copyright (c) 2002, 2009 Free Software Foundation, Inc.
- based on darwin.S by John Hornkvist
- PowerPC Assembly glue.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- .set r0,0
- .set r1,1
- .set r2,2
- .set r3,3
- .set r4,4
- .set r5,5
- .set r6,6
- .set r7,7
- .set r8,8
- .set r9,9
- .set r10,10
- .set r11,11
- .set r12,12
- .set r13,13
- .set r14,14
- .set r15,15
- .set r16,16
- .set r17,17
- .set r18,18
- .set r19,19
- .set r20,20
- .set r21,21
- .set r22,22
- .set r23,23
- .set r24,24
- .set r25,25
- .set r26,26
- .set r27,27
- .set r28,28
- .set r29,29
- .set r30,30
- .set r31,31
- .set f0,0
- .set f1,1
- .set f2,2
- .set f3,3
- .set f4,4
- .set f5,5
- .set f6,6
- .set f7,7
- .set f8,8
- .set f9,9
- .set f10,10
- .set f11,11
- .set f12,12
- .set f13,13
- .set f14,14
- .set f15,15
- .set f16,16
- .set f17,17
- .set f18,18
- .set f19,19
- .set f20,20
- .set f21,21
- .extern .ffi_prep_args
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #define JUMPTARGET(name) name
- #define L(x) x
- .file "aix.S"
- .toc
- /* void ffi_call_AIX(extended_cif *ecif, unsigned long bytes,
- * unsigned int flags, unsigned int *rvalue,
- * void (*fn)(),
- * void (*prep_args)(extended_cif*, unsigned *const));
- * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args
- */
- .csect .text[PR]
- .align 2
- .globl ffi_call_AIX
- .globl .ffi_call_AIX
- .csect ffi_call_AIX[DS]
- ffi_call_AIX:
- #ifdef __64BIT__
- .llong .ffi_call_AIX, TOC[tc0], 0
- .csect .text[PR]
- .ffi_call_AIX:
- .function .ffi_call_AIX,.ffi_call_AIX,16,044,LFE..0-LFB..0
- .bf __LINE__
- .line 1
- LFB..0:
- /* Save registers we use. */
- mflr r0
- std r28,-32(r1)
- std r29,-24(r1)
- std r30,-16(r1)
- std r31, -8(r1)
- std r0, 16(r1)
- LCFI..0:
- mr r28, r1 /* our AP. */
- stdux r1, r1, r4
- LCFI..1:
- /* Save arguments over call... */
- mr r31, r5 /* flags, */
- mr r30, r6 /* rvalue, */
- mr r29, r7 /* function address. */
- std r2, 40(r1)
- /* Call ffi_prep_args. */
- mr r4, r1
- bl .ffi_prep_args
- nop
- /* Now do the call. */
- ld r0, 0(r29)
- ld r2, 8(r29)
- ld r11, 16(r29)
- /* Set up cr1 with bits 4-7 of the flags. */
- mtcrf 0x40, r31
- mtctr r0
- /* Load all those argument registers. */
- /* We have set up a nice stack frame, just load it into registers. */
- ld r3, 40+(1*8)(r1)
- ld r4, 40+(2*8)(r1)
- ld r5, 40+(3*8)(r1)
- ld r6, 40+(4*8)(r1)
- nop
- ld r7, 40+(5*8)(r1)
- ld r8, 40+(6*8)(r1)
- ld r9, 40+(7*8)(r1)
- ld r10,40+(8*8)(r1)
- L1:
- /* Load all the FP registers. */
- bf 6,L2 /* 2f + 0x18 */
- lfd f1,-32-(13*8)(r28)
- lfd f2,-32-(12*8)(r28)
- lfd f3,-32-(11*8)(r28)
- lfd f4,-32-(10*8)(r28)
- nop
- lfd f5,-32-(9*8)(r28)
- lfd f6,-32-(8*8)(r28)
- lfd f7,-32-(7*8)(r28)
- lfd f8,-32-(6*8)(r28)
- nop
- lfd f9,-32-(5*8)(r28)
- lfd f10,-32-(4*8)(r28)
- lfd f11,-32-(3*8)(r28)
- lfd f12,-32-(2*8)(r28)
- nop
- lfd f13,-32-(1*8)(r28)
- L2:
- /* Make the call. */
- bctrl
- ld r2, 40(r1)
- /* Now, deal with the return value. */
- mtcrf 0x01, r31
- bt 30, L(done_return_value)
- bt 29, L(fp_return_value)
- std r3, 0(r30)
- /* Fall through... */
- L(done_return_value):
- /* Restore the registers we used and return. */
- mr r1, r28
- ld r0, 16(r28)
- ld r28, -32(r1)
- mtlr r0
- ld r29, -24(r1)
- ld r30, -16(r1)
- ld r31, -8(r1)
- blr
- L(fp_return_value):
- bf 28, L(float_return_value)
- stfd f1, 0(r30)
- bf 31, L(done_return_value)
- stfd f2, 8(r30)
- b L(done_return_value)
- L(float_return_value):
- stfs f1, 0(r30)
- b L(done_return_value)
- LFE..0:
- #else /* ! __64BIT__ */
-
- .long .ffi_call_AIX, TOC[tc0], 0
- .csect .text[PR]
- .ffi_call_AIX:
- .function .ffi_call_AIX,.ffi_call_AIX,16,044,LFE..0-LFB..0
- .bf __LINE__
- .line 1
- LFB..0:
- /* Save registers we use. */
- mflr r0
- stw r28,-16(r1)
- stw r29,-12(r1)
- stw r30, -8(r1)
- stw r31, -4(r1)
- stw r0, 8(r1)
- LCFI..0:
- mr r28, r1 /* out AP. */
- stwux r1, r1, r4
- LCFI..1:
- /* Save arguments over call... */
- mr r31, r5 /* flags, */
- mr r30, r6 /* rvalue, */
- mr r29, r7 /* function address, */
- stw r2, 20(r1)
- /* Call ffi_prep_args. */
- mr r4, r1
- bl .ffi_prep_args
- nop
- /* Now do the call. */
- lwz r0, 0(r29)
- lwz r2, 4(r29)
- lwz r11, 8(r29)
- /* Set up cr1 with bits 4-7 of the flags. */
- mtcrf 0x40, r31
- mtctr r0
- /* Load all those argument registers. */
- /* We have set up a nice stack frame, just load it into registers. */
- lwz r3, 20+(1*4)(r1)
- lwz r4, 20+(2*4)(r1)
- lwz r5, 20+(3*4)(r1)
- lwz r6, 20+(4*4)(r1)
- nop
- lwz r7, 20+(5*4)(r1)
- lwz r8, 20+(6*4)(r1)
- lwz r9, 20+(7*4)(r1)
- lwz r10,20+(8*4)(r1)
- L1:
- /* Load all the FP registers. */
- bf 6,L2 /* 2f + 0x18 */
- lfd f1,-16-(13*8)(r28)
- lfd f2,-16-(12*8)(r28)
- lfd f3,-16-(11*8)(r28)
- lfd f4,-16-(10*8)(r28)
- nop
- lfd f5,-16-(9*8)(r28)
- lfd f6,-16-(8*8)(r28)
- lfd f7,-16-(7*8)(r28)
- lfd f8,-16-(6*8)(r28)
- nop
- lfd f9,-16-(5*8)(r28)
- lfd f10,-16-(4*8)(r28)
- lfd f11,-16-(3*8)(r28)
- lfd f12,-16-(2*8)(r28)
- nop
- lfd f13,-16-(1*8)(r28)
- L2:
- /* Make the call. */
- bctrl
- lwz r2, 20(r1)
- /* Now, deal with the return value. */
- mtcrf 0x01, r31
- bt 30, L(done_return_value)
- bt 29, L(fp_return_value)
- stw r3, 0(r30)
- bf 28, L(done_return_value)
- stw r4, 4(r30)
- /* Fall through... */
- L(done_return_value):
- /* Restore the registers we used and return. */
- mr r1, r28
- lwz r0, 8(r28)
- lwz r28,-16(r1)
- mtlr r0
- lwz r29,-12(r1)
- lwz r30, -8(r1)
- lwz r31, -4(r1)
- blr
- L(fp_return_value):
- bf 28, L(float_return_value)
- stfd f1, 0(r30)
- b L(done_return_value)
- L(float_return_value):
- stfs f1, 0(r30)
- b L(done_return_value)
- LFE..0:
- #endif
- .ef __LINE__
- .long 0
- .byte 0,0,0,1,128,4,0,0
- /* END(ffi_call_AIX) */
- /* void ffi_call_go_AIX(extended_cif *ecif, unsigned long bytes,
- * unsigned int flags, unsigned int *rvalue,
- * void (*fn)(),
- * void (*prep_args)(extended_cif*, unsigned *const),
- * void *closure);
- * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args, r9=closure
- */
- .csect .text[PR]
- .align 2
- .globl ffi_call_go_AIX
- .globl .ffi_call_go_AIX
- .csect ffi_call_go_AIX[DS]
- ffi_call_go_AIX:
- #ifdef __64BIT__
- .llong .ffi_call_go_AIX, TOC[tc0], 0
- .csect .text[PR]
- .ffi_call_go_AIX:
- .function .ffi_call_go_AIX,.ffi_call_go_AIX,16,044,LFE..1-LFB..1
- .bf __LINE__
- .line 1
- LFB..1:
- /* Save registers we use. */
- mflr r0
- std r28,-32(r1)
- std r29,-24(r1)
- std r30,-16(r1)
- std r31, -8(r1)
- std r9, 8(r1) /* closure, saved in cr field. */
- std r0, 16(r1)
- LCFI..2:
- mr r28, r1 /* our AP. */
- stdux r1, r1, r4
- LCFI..3:
- /* Save arguments over call... */
- mr r31, r5 /* flags, */
- mr r30, r6 /* rvalue, */
- mr r29, r7 /* function address, */
- std r2, 40(r1)
- /* Call ffi_prep_args. */
- mr r4, r1
- bl .ffi_prep_args
- nop
- /* Now do the call. */
- ld r0, 0(r29)
- ld r2, 8(r29)
- ld r11, 8(r28) /* closure */
- /* Set up cr1 with bits 4-7 of the flags. */
- mtcrf 0x40, r31
- mtctr r0
- /* Load all those argument registers. */
- /* We have set up a nice stack frame, just load it into registers. */
- ld r3, 40+(1*8)(r1)
- ld r4, 40+(2*8)(r1)
- ld r5, 40+(3*8)(r1)
- ld r6, 40+(4*8)(r1)
- nop
- ld r7, 40+(5*8)(r1)
- ld r8, 40+(6*8)(r1)
- ld r9, 40+(7*8)(r1)
- ld r10,40+(8*8)(r1)
- b L1
- LFE..1:
- #else /* ! __64BIT__ */
-
- .long .ffi_call_go_AIX, TOC[tc0], 0
- .csect .text[PR]
- .ffi_call_go_AIX:
- .function .ffi_call_go_AIX,.ffi_call_go_AIX,16,044,LFE..1-LFB..1
- .bf __LINE__
- .line 1
- /* Save registers we use. */
- LFB..1:
- mflr r0
- stw r28,-16(r1)
- stw r29,-12(r1)
- stw r30, -8(r1)
- stw r31, -4(r1)
- stw r9, 4(r1) /* closure, saved in cr field. */
- stw r0, 8(r1)
- LCFI..2:
- mr r28, r1 /* out AP. */
- stwux r1, r1, r4
- LCFI..3:
- /* Save arguments over call... */
- mr r31, r5 /* flags, */
- mr r30, r6 /* rvalue, */
- mr r29, r7 /* function address, */
- stw r2, 20(r1)
- /* Call ffi_prep_args. */
- mr r4, r1
- bl .ffi_prep_args
- nop
- /* Now do the call. */
- lwz r0, 0(r29)
- lwz r2, 4(r29)
- lwz r11, 4(r28) /* closure */
- /* Set up cr1 with bits 4-7 of the flags. */
- mtcrf 0x40, r31
- mtctr r0
- /* Load all those argument registers. */
- /* We have set up a nice stack frame, just load it into registers. */
- lwz r3, 20+(1*4)(r1)
- lwz r4, 20+(2*4)(r1)
- lwz r5, 20+(3*4)(r1)
- lwz r6, 20+(4*4)(r1)
- nop
- lwz r7, 20+(5*4)(r1)
- lwz r8, 20+(6*4)(r1)
- lwz r9, 20+(7*4)(r1)
- lwz r10,20+(8*4)(r1)
- b L1
- LFE..1:
- #endif
- .ef __LINE__
- .long 0
- .byte 0,0,0,1,128,4,0,0
- /* END(ffi_call_go_AIX) */
- .csect .text[PR]
- .align 2
- .globl ffi_call_DARWIN
- .globl .ffi_call_DARWIN
- .csect ffi_call_DARWIN[DS]
- ffi_call_DARWIN:
- #ifdef __64BIT__
- .llong .ffi_call_DARWIN, TOC[tc0], 0
- #else
- .long .ffi_call_DARWIN, TOC[tc0], 0
- #endif
- .csect .text[PR]
- .ffi_call_DARWIN:
- blr
- .long 0
- .byte 0,0,0,0,0,0,0,0
- /* END(ffi_call_DARWIN) */
- /* EH frame stuff. */
- #define LR_REGNO 0x41 /* Link Register (65), see rs6000.md */
- #ifdef __64BIT__
- #define PTRSIZE 8
- #define LOG2_PTRSIZE 3
- #define FDE_ENCODING 0x1c /* DW_EH_PE_pcrel|DW_EH_PE_sdata8 */
- #define EH_DATA_ALIGN_FACT 0x78 /* LEB128 -8 */
- #else
- #define PTRSIZE 4
- #define LOG2_PTRSIZE 2
- #define FDE_ENCODING 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4 */
- #define EH_DATA_ALIGN_FACT 0x7c /* LEB128 -4 */
- #endif
- .csect _unwind.ro_[RO],4
- .align LOG2_PTRSIZE
- .globl _GLOBAL__F_libffi_src_powerpc_aix
- _GLOBAL__F_libffi_src_powerpc_aix:
- Lframe..1:
- .vbyte 4,LECIE..1-LSCIE..1 /* CIE Length */
- LSCIE..1:
- .vbyte 4,0 /* CIE Identifier Tag */
- .byte 0x3 /* CIE Version */
- .byte "zR" /* CIE Augmentation */
- .byte 0
- .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */
- .byte EH_DATA_ALIGN_FACT /* leb128 -4/-8; CIE Data Alignment Factor */
- .byte 0x41 /* CIE RA Column */
- .byte 0x1 /* uleb128 0x1; Augmentation size */
- .byte FDE_ENCODING /* FDE Encoding (pcrel|sdata4/8) */
- .byte 0xc /* DW_CFA_def_cfa */
- .byte 0x1 /* uleb128 0x1; Register r1 */
- .byte 0 /* uleb128 0x0; Offset 0 */
- .align LOG2_PTRSIZE
- LECIE..1:
- LSFDE..1:
- .vbyte 4,LEFDE..1-LASFDE..1 /* FDE Length */
- LASFDE..1:
- .vbyte 4,LASFDE..1-Lframe..1 /* FDE CIE offset */
- .vbyte PTRSIZE,LFB..0-$ /* FDE initial location */
- .vbyte PTRSIZE,LFE..0-LFB..0 /* FDE address range */
- .byte 0 /* uleb128 0x0; Augmentation size */
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .vbyte 4,LCFI..0-LFB..0
- .byte 0x11 /* DW_CFA_def_offset_extended_sf */
- .byte LR_REGNO /* uleb128 LR_REGNO; Register LR */
- .byte 0x7e /* leb128 -2; Offset -2 (8/16) */
- .byte 0x9f /* DW_CFA_offset Register r31 */
- .byte 0x1 /* uleb128 0x1; Offset 1 (-4/-8) */
- .byte 0x9e /* DW_CFA_offset Register r30 */
- .byte 0x2 /* uleb128 0x2; Offset 2 (-8/-16) */
- .byte 0x9d /* DW_CFA_offset Register r29 */
- .byte 0x3 /* uleb128 0x3; Offset 3 (-12/-24) */
- .byte 0x9c /* DW_CFA_offset Register r28 */
- .byte 0x4 /* uleb128 0x4; Offset 4 (-16/-32) */
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .vbyte 4,LCFI..1-LCFI..0
- .byte 0xd /* DW_CFA_def_cfa_register */
- .byte 0x1c /* uleb128 28; Register r28 */
- .align LOG2_PTRSIZE
- LEFDE..1:
- LSFDE..2:
- .vbyte 4,LEFDE..2-LASFDE..2 /* FDE Length */
- LASFDE..2:
- .vbyte 4,LASFDE..2-Lframe..1 /* FDE CIE offset */
- .vbyte PTRSIZE,LFB..1-$ /* FDE initial location */
- .vbyte PTRSIZE,LFE..1-LFB..1 /* FDE address range */
- .byte 0 /* uleb128 0x0; Augmentation size */
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .vbyte 4,LCFI..2-LFB..1
- .byte 0x11 /* DW_CFA_def_offset_extended_sf */
- .byte LR_REGNO /* uleb128 LR_REGNO; Register LR */
- .byte 0x7e /* leb128 -2; Offset -2 (8/16) */
- .byte 0x9f /* DW_CFA_offset Register r31 */
- .byte 0x1 /* uleb128 0x1; Offset 1 (-4/-8) */
- .byte 0x9e /* DW_CFA_offset Register r30 */
- .byte 0x2 /* uleb128 0x2; Offset 2 (-8/-16) */
- .byte 0x9d /* DW_CFA_offset Register r29 */
- .byte 0x3 /* uleb128 0x3; Offset 3 (-12/-24) */
- .byte 0x9c /* DW_CFA_offset Register r28 */
- .byte 0x4 /* uleb128 0x4; Offset 4 (-16/-32) */
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .vbyte 4,LCFI..3-LCFI..2
- .byte 0xd /* DW_CFA_def_cfa_register */
- .byte 0x1c /* uleb128 28; Register r28 */
- .align LOG2_PTRSIZE
- LEFDE..2:
- .vbyte 4,0 /* End of FDEs */
- .csect .text[PR]
- .ref _GLOBAL__F_libffi_src_powerpc_aix /* Prevents garbage collection by AIX linker */
- ====================File: src/powerpc/aix_closure.S====================
- /* -----------------------------------------------------------------------
- aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.
- based on darwin_closure.S
- PowerPC Assembly glue.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- .set r0,0
- .set r1,1
- .set r2,2
- .set r3,3
- .set r4,4
- .set r5,5
- .set r6,6
- .set r7,7
- .set r8,8
- .set r9,9
- .set r10,10
- .set r11,11
- .set r12,12
- .set r13,13
- .set r14,14
- .set r15,15
- .set r16,16
- .set r17,17
- .set r18,18
- .set r19,19
- .set r20,20
- .set r21,21
- .set r22,22
- .set r23,23
- .set r24,24
- .set r25,25
- .set r26,26
- .set r27,27
- .set r28,28
- .set r29,29
- .set r30,30
- .set r31,31
- .set f0,0
- .set f1,1
- .set f2,2
- .set f3,3
- .set f4,4
- .set f5,5
- .set f6,6
- .set f7,7
- .set f8,8
- .set f9,9
- .set f10,10
- .set f11,11
- .set f12,12
- .set f13,13
- .set f14,14
- .set f15,15
- .set f16,16
- .set f17,17
- .set f18,18
- .set f19,19
- .set f20,20
- .set f21,21
- .extern .ffi_closure_helper_DARWIN
- .extern .ffi_go_closure_helper_DARWIN
- #define LIBFFI_ASM
- #define JUMPTARGET(name) name
- #define L(x) x
- .file "aix_closure.S"
- .toc
- LC..60:
- .tc L..60[TC],L..60
- .csect .text[PR]
- .align 2
- .csect .text[PR]
- .align 2
- .globl ffi_closure_ASM
- .globl .ffi_closure_ASM
- .csect ffi_closure_ASM[DS]
- ffi_closure_ASM:
- #ifdef __64BIT__
- .llong .ffi_closure_ASM, TOC[tc0], 0
- .csect .text[PR]
- .ffi_closure_ASM:
- .function .ffi_closure_ASM,.ffi_closure_ASM,16,044,LFE..0-LFB..0
- .bf __LINE__
- .line 1
- LFB..0:
- /* we want to build up an area for the parameters passed */
- /* in registers (both floating point and integer) */
- /* we store gpr 3 to gpr 10 (aligned to 4)
- in the parents outgoing area */
- std r3, 48+(0*8)(r1)
- std r4, 48+(1*8)(r1)
- std r5, 48+(2*8)(r1)
- std r6, 48+(3*8)(r1)
- mflr r0
- std r7, 48+(4*8)(r1)
- std r8, 48+(5*8)(r1)
- std r9, 48+(6*8)(r1)
- std r10, 48+(7*8)(r1)
- std r0, 16(r1) /* save the return address */
- LCFI..0:
- /* 48 Bytes (Linkage Area) */
- /* 64 Bytes (params) */
- /* 16 Bytes (result) */
- /* 104 Bytes (13*8 from FPR) */
- /* 8 Bytes (alignment) */
- /* 240 Bytes */
- stdu r1, -240(r1) /* skip over caller save area
- keep stack aligned to 16 */
- LCFI..1:
- /* next save fpr 1 to fpr 13 (aligned to 8) */
- stfd f1, 128+(0*8)(r1)
- stfd f2, 128+(1*8)(r1)
- stfd f3, 128+(2*8)(r1)
- stfd f4, 128+(3*8)(r1)
- stfd f5, 128+(4*8)(r1)
- stfd f6, 128+(5*8)(r1)
- stfd f7, 128+(6*8)(r1)
- stfd f8, 128+(7*8)(r1)
- stfd f9, 128+(8*8)(r1)
- stfd f10, 128+(9*8)(r1)
- stfd f11, 128+(10*8)(r1)
- stfd f12, 128+(11*8)(r1)
- stfd f13, 128+(12*8)(r1)
- /* set up registers for the routine that actually does the work */
- /* get the context pointer from the trampoline */
- mr r3, r11
- /* now load up the pointer to the result storage */
- addi r4, r1, 112
- /* now load up the pointer to the saved gpr registers */
- addi r5, r1, 288
- /* now load up the pointer to the saved fpr registers */
- addi r6, r1, 128
- /* make the call */
- bl .ffi_closure_helper_DARWIN
- nop
- .Ldoneclosure:
- /* now r3 contains the return type */
- /* so use it to look up in a table */
- /* so we know how to deal with each type */
- /* look up the proper starting point in table */
- /* by using return type as offset */
- lhz r3, 10(r3) /* load type from return type */
- ld r4, LC..60(2) /* get address of jump table */
- sldi r3, r3, 4 /* now multiply return type by 16 */
- ld r0, 240+16(r1) /* load return address */
- add r3, r3, r4 /* add contents of table to table address */
- mtctr r3
- bctr /* jump to it */
- /* Each fragment must be exactly 16 bytes long (4 instructions).
- Align to 16 byte boundary for cache and dispatch efficiency. */
- .align 4
- L..60:
- /* case FFI_TYPE_VOID */
- mtlr r0
- addi r1, r1, 240
- blr
- nop
- /* case FFI_TYPE_INT */
- lwa r3, 112+4(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_FLOAT */
- lfs f1, 112+0(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_DOUBLE */
- lfd f1, 112+0(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_LONGDOUBLE */
- lfd f1, 112+0(r1)
- mtlr r0
- lfd f2, 112+8(r1)
- b L..finish
- /* case FFI_TYPE_UINT8 */
- lbz r3, 112+7(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_SINT8 */
- lbz r3, 112+7(r1)
- mtlr r0
- extsb r3, r3
- b L..finish
- /* case FFI_TYPE_UINT16 */
- lhz r3, 112+6(r1)
- mtlr r0
- L..finish:
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_SINT16 */
- lha r3, 112+6(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_UINT32 */
- lwz r3, 112+4(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_SINT32 */
- lwa r3, 112+4(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_UINT64 */
- ld r3, 112+0(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_SINT64 */
- ld r3, 112+0(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- /* case FFI_TYPE_STRUCT */
- mtlr r0
- addi r1, r1, 240
- blr
- nop
- /* case FFI_TYPE_POINTER */
- ld r3, 112+0(r1)
- mtlr r0
- addi r1, r1, 240
- blr
- LFE..0:
- #else /* ! __64BIT__ */
-
- .long .ffi_closure_ASM, TOC[tc0], 0
- .csect .text[PR]
- .ffi_closure_ASM:
- .function .ffi_closure_ASM,.ffi_closure_ASM,16,044,LFE..0-LFB..0
- .bf __LINE__
- .line 1
- LFB..0:
- /* we want to build up an area for the parameters passed */
- /* in registers (both floating point and integer) */
- /* we store gpr 3 to gpr 10 (aligned to 4)
- in the parents outgoing area */
- stw r3, 24+(0*4)(r1)
- stw r4, 24+(1*4)(r1)
- stw r5, 24+(2*4)(r1)
- stw r6, 24+(3*4)(r1)
- mflr r0
- stw r7, 24+(4*4)(r1)
- stw r8, 24+(5*4)(r1)
- stw r9, 24+(6*4)(r1)
- stw r10, 24+(7*4)(r1)
- stw r0, 8(r1)
- LCFI..0:
- /* 24 Bytes (Linkage Area) */
- /* 32 Bytes (params) */
- /* 16 Bytes (result) */
- /* 104 Bytes (13*8 from FPR) */
- /* 176 Bytes */
- stwu r1, -176(r1) /* skip over caller save area
- keep stack aligned to 16 */
- LCFI..1:
- /* next save fpr 1 to fpr 13 (aligned to 8) */
- stfd f1, 72+(0*8)(r1)
- stfd f2, 72+(1*8)(r1)
- stfd f3, 72+(2*8)(r1)
- stfd f4, 72+(3*8)(r1)
- stfd f5, 72+(4*8)(r1)
- stfd f6, 72+(5*8)(r1)
- stfd f7, 72+(6*8)(r1)
- stfd f8, 72+(7*8)(r1)
- stfd f9, 72+(8*8)(r1)
- stfd f10, 72+(9*8)(r1)
- stfd f11, 72+(10*8)(r1)
- stfd f12, 72+(11*8)(r1)
- stfd f13, 72+(12*8)(r1)
- /* set up registers for the routine that actually does the work */
- /* get the context pointer from the trampoline */
- mr r3, r11
- /* now load up the pointer to the result storage */
- addi r4, r1, 56
- /* now load up the pointer to the saved gpr registers */
- addi r5, r1, 200
- /* now load up the pointer to the saved fpr registers */
- addi r6, r1, 72
- /* make the call */
- bl .ffi_closure_helper_DARWIN
- nop
- .Ldoneclosure:
- /* now r3 contains the return type */
- /* so use it to look up in a table */
- /* so we know how to deal with each type */
- /* look up the proper starting point in table */
- /* by using return type as offset */
- lhz r3, 6(r3) /* load type from return type */
- lwz r4, LC..60(2) /* get address of jump table */
- slwi r3, r3, 4 /* now multiply return type by 16 */
- lwz r0, 176+8(r1) /* load return address */
- add r3, r3, r4 /* add contents of table to table address */
- mtctr r3
- bctr /* jump to it */
- /* Each fragment must be exactly 16 bytes long (4 instructions).
- Align to 16 byte boundary for cache and dispatch efficiency. */
- .align 4
- L..60:
- /* case FFI_TYPE_VOID */
- mtlr r0
- addi r1, r1, 176
- blr
- nop
- /* case FFI_TYPE_INT */
- lwz r3, 56+0(r1)
- mtlr r0
- addi r1, r1, 176
- blr
- /* case FFI_TYPE_FLOAT */
- lfs f1, 56+0(r1)
- mtlr r0
- addi r1, r1, 176
- blr
- /* case FFI_TYPE_DOUBLE */
- lfd f1, 56+0(r1)
- mtlr r0
- addi r1, r1, 176
- blr
- /* case FFI_TYPE_LONGDOUBLE */
- lfd f1, 56+0(r1)
- mtlr r0
- lfd f2, 56+8(r1)
- b L..finish
- /* case FFI_TYPE_UINT8 */
- lbz r3, 56+3(r1)
- mtlr r0
- addi r1, r1, 176
- blr
- /* case FFI_TYPE_SINT8 */
- lbz r3, 56+3(r1)
- mtlr r0
- extsb r3, r3
- b L..finish
- /* case FFI_TYPE_UINT16 */
- lhz r3, 56+2(r1)
- mtlr r0
- addi r1, r1, 176
- blr
- /* case FFI_TYPE_SINT16 */
- lha r3, 56+2(r1)
- mtlr r0
- addi r1, r1, 176
- blr
- /* case FFI_TYPE_UINT32 */
- lwz r3, 56+0(r1)
- mtlr r0
- addi r1, r1, 176
- blr
- /* case FFI_TYPE_SINT32 */
- lwz r3, 56+0(r1)
- mtlr r0
- addi r1, r1, 176
- blr
- /* case FFI_TYPE_UINT64 */
- lwz r3, 56+0(r1)
- mtlr r0
- lwz r4, 56+4(r1)
- b L..finish
- /* case FFI_TYPE_SINT64 */
- lwz r3, 56+0(r1)
- mtlr r0
- lwz r4, 56+4(r1)
- b L..finish
- /* case FFI_TYPE_STRUCT */
- mtlr r0
- addi r1, r1, 176
- blr
- nop
- /* case FFI_TYPE_POINTER */
- lwz r3, 56+0(r1)
- mtlr r0
- L..finish:
- addi r1, r1, 176
- blr
- LFE..0:
- #endif
- .ef __LINE__
- /* END(ffi_closure_ASM) */
- .csect .text[PR]
- .align 2
- .globl ffi_go_closure_ASM
- .globl .ffi_go_closure_ASM
- .csect ffi_go_closure_ASM[DS]
- ffi_go_closure_ASM:
- #ifdef __64BIT__
- .llong .ffi_go_closure_ASM, TOC[tc0], 0
- .csect .text[PR]
- .ffi_go_closure_ASM:
- .function .ffi_go_closure_ASM,.ffi_go_closure_ASM,16,044,LFE..1-LFB..1
- .bf __LINE__
- .line 1
- LFB..1:
- /* we want to build up an area for the parameters passed */
- /* in registers (both floating point and integer) */
- /* we store gpr 3 to gpr 10 (aligned to 4)
- in the parents outgoing area */
- std r3, 48+(0*8)(r1)
- std r4, 48+(1*8)(r1)
- std r5, 48+(2*8)(r1)
- std r6, 48+(3*8)(r1)
- mflr r0
- std r7, 48+(4*8)(r1)
- std r8, 48+(5*8)(r1)
- std r9, 48+(6*8)(r1)
- std r10, 48+(7*8)(r1)
- std r0, 16(r1) /* save the return address */
- LCFI..2:
- /* 48 Bytes (Linkage Area) */
- /* 64 Bytes (params) */
- /* 16 Bytes (result) */
- /* 104 Bytes (13*8 from FPR) */
- /* 8 Bytes (alignment) */
- /* 240 Bytes */
- stdu r1, -240(r1) /* skip over caller save area
- keep stack aligned to 16 */
- LCFI..3:
- /* next save fpr 1 to fpr 13 (aligned to 8) */
- stfd f1, 128+(0*8)(r1)
- stfd f2, 128+(1*8)(r1)
- stfd f3, 128+(2*8)(r1)
- stfd f4, 128+(3*8)(r1)
- stfd f5, 128+(4*8)(r1)
- stfd f6, 128+(5*8)(r1)
- stfd f7, 128+(6*8)(r1)
- stfd f8, 128+(7*8)(r1)
- stfd f9, 128+(8*8)(r1)
- stfd f10, 128+(9*8)(r1)
- stfd f11, 128+(10*8)(r1)
- stfd f12, 128+(11*8)(r1)
- stfd f13, 128+(12*8)(r1)
- /* set up registers for the routine that actually does the work */
- mr r3, r11 /* go closure */
- /* now load up the pointer to the result storage */
- addi r4, r1, 112
- /* now load up the pointer to the saved gpr registers */
- addi r5, r1, 288
- /* now load up the pointer to the saved fpr registers */
- addi r6, r1, 128
- /* make the call */
- bl .ffi_go_closure_helper_DARWIN
- nop
- b .Ldoneclosure
- LFE..1:
- #else /* ! __64BIT__ */
-
- .long .ffi_go_closure_ASM, TOC[tc0], 0
- .csect .text[PR]
- .ffi_go_closure_ASM:
- .function .ffi_go_closure_ASM,.ffi_go_closure_ASM,16,044,LFE..1-LFB..1
- .bf __LINE__
- .line 1
- LFB..1:
- /* we want to build up an area for the parameters passed */
- /* in registers (both floating point and integer) */
- /* we store gpr 3 to gpr 10 (aligned to 4)
- in the parents outgoing area */
- stw r3, 24+(0*4)(r1)
- stw r4, 24+(1*4)(r1)
- stw r5, 24+(2*4)(r1)
- stw r6, 24+(3*4)(r1)
- mflr r0
- stw r7, 24+(4*4)(r1)
- stw r8, 24+(5*4)(r1)
- stw r9, 24+(6*4)(r1)
- stw r10, 24+(7*4)(r1)
- stw r0, 8(r1)
- LCFI..2:
- /* 24 Bytes (Linkage Area) */
- /* 32 Bytes (params) */
- /* 16 Bytes (result) */
- /* 104 Bytes (13*8 from FPR) */
- /* 176 Bytes */
- stwu r1, -176(r1) /* skip over caller save area
- keep stack aligned to 16 */
- LCFI..3:
- /* next save fpr 1 to fpr 13 (aligned to 8) */
- stfd f1, 72+(0*8)(r1)
- stfd f2, 72+(1*8)(r1)
- stfd f3, 72+(2*8)(r1)
- stfd f4, 72+(3*8)(r1)
- stfd f5, 72+(4*8)(r1)
- stfd f6, 72+(5*8)(r1)
- stfd f7, 72+(6*8)(r1)
- stfd f8, 72+(7*8)(r1)
- stfd f9, 72+(8*8)(r1)
- stfd f10, 72+(9*8)(r1)
- stfd f11, 72+(10*8)(r1)
- stfd f12, 72+(11*8)(r1)
- stfd f13, 72+(12*8)(r1)
- /* set up registers for the routine that actually does the work */
- mr r3, 11 /* go closure */
- /* now load up the pointer to the result storage */
- addi r4, r1, 56
- /* now load up the pointer to the saved gpr registers */
- addi r5, r1, 200
- /* now load up the pointer to the saved fpr registers */
- addi r6, r1, 72
- /* make the call */
- bl .ffi_go_closure_helper_DARWIN
- nop
- b .Ldoneclosure
- LFE..1:
- #endif
- .ef __LINE__
- /* END(ffi_go_closure_ASM) */
- /* EH frame stuff. */
- #define LR_REGNO 0x41 /* Link Register (65), see rs6000.md */
- #ifdef __64BIT__
- #define PTRSIZE 8
- #define LOG2_PTRSIZE 3
- #define CFA_OFFSET 0xf0,0x01 /* LEB128 240 */
- #define FDE_ENCODING 0x1c /* DW_EH_PE_pcrel|DW_EH_PE_sdata8 */
- #define EH_DATA_ALIGN_FACT 0x78 /* LEB128 -8 */
- #else
- #define PTRSIZE 4
- #define LOG2_PTRSIZE 2
- #define CFA_OFFSET 0xb0,0x01 /* LEB128 176 */
- #define FDE_ENCODING 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4 */
- #define EH_DATA_ALIGN_FACT 0x7c /* LEB128 -4 */
- #endif
- .csect _unwind.ro_[RO],4
- .align LOG2_PTRSIZE
- .globl _GLOBAL__F_libffi_src_powerpc_aix_closure
- _GLOBAL__F_libffi_src_powerpc_aix_closure:
- Lframe..1:
- .vbyte 4,LECIE..1-LSCIE..1 /* CIE Length */
- LSCIE..1:
- .vbyte 4,0 /* CIE Identifier Tag */
- .byte 0x3 /* CIE Version */
- .byte "zR" /* CIE Augmentation */
- .byte 0
- .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */
- .byte EH_DATA_ALIGN_FACT /* leb128 -4/-8; CIE Data Alignment Factor */
- .byte LR_REGNO /* CIE RA Column */
- .byte 0x1 /* uleb128 0x1; Augmentation size */
- .byte FDE_ENCODING /* FDE Encoding (pcrel|sdata4/8) */
- .byte 0xc /* DW_CFA_def_cfa */
- .byte 0x1 /* uleb128 0x1; Register r1 */
- .byte 0 /* uleb128 0x0; Offset 0 */
- .align LOG2_PTRSIZE
- LECIE..1:
- LSFDE..1:
- .vbyte 4,LEFDE..1-LASFDE..1 /* FDE Length */
- LASFDE..1:
- .vbyte 4,LASFDE..1-Lframe..1 /* FDE CIE offset */
- .vbyte PTRSIZE,LFB..0-$ /* FDE initial location */
- .vbyte PTRSIZE,LFE..0-LFB..0 /* FDE address range */
- .byte 0 /* uleb128 0x0; Augmentation size */
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .vbyte 4,LCFI..1-LCFI..0
- .byte 0xe /* DW_CFA_def_cfa_offset */
- .byte CFA_OFFSET /* uleb128 176/240 */
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .vbyte 4,LCFI..0-LFB..0
- .byte 0x11 /* DW_CFA_offset_extended_sf */
- .byte LR_REGNO /* uleb128 LR_REGNO; Register LR */
- .byte 0x7e /* leb128 -2; Offset -2 (8/16) */
- .align LOG2_PTRSIZE
- LEFDE..1:
- LSFDE..2:
- .vbyte 4,LEFDE..2-LASFDE..2 /* FDE Length */
- LASFDE..2:
- .vbyte 4,LASFDE..2-Lframe..1 /* FDE CIE offset */
- .vbyte PTRSIZE,LFB..1-$ /* FDE initial location */
- .vbyte PTRSIZE,LFE..1-LFB..1 /* FDE address range */
- .byte 0 /* uleb128 0x0; Augmentation size */
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .vbyte 4,LCFI..3-LCFI..2
- .byte 0xe /* DW_CFA_def_cfa_offset */
- .byte CFA_OFFSET /* uleb128 176/240 */
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .vbyte 4,LCFI..2-LFB..1
- .byte 0x11 /* DW_CFA_offset_extended_sf */
- .byte LR_REGNO /* uleb128 LR_REGNO; Register LR */
- .byte 0x7e /* leb128 -2; Offset -2 (8/16) */
- .align LOG2_PTRSIZE
- LEFDE..2:
- .vbyte 4,0 /* End of FDEs */
- .csect .text[PR]
- .ref _GLOBAL__F_libffi_src_powerpc_aix_closure /* Prevents garbage collection by AIX linker */
- ====================File: src/powerpc/asm.h====================
- /* -----------------------------------------------------------------------
- asm.h - Copyright (c) 1998 Geoffrey Keating
- PowerPC Assembly glue.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #define ASM_GLOBAL_DIRECTIVE .globl
- #define C_SYMBOL_NAME(name) name
- /* Macro for a label. */
- #ifdef __STDC__
- #define C_LABEL(name) name##:
- #else
- #define C_LABEL(name) name/**/:
- #endif
- /* This seems to always be the case on PPC. */
- #define ALIGNARG(log2) log2
- /* For ELF we need the `.type' directive to make shared libs work right. */
- #define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
- #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
- /* If compiled for profiling, call `_mcount' at the start of each function. */
- #ifdef PROF
- /* The mcount code relies on the return address being on the stack
- to locate our caller and so it can restore it; so store one just
- for its benefit. */
- #ifdef PIC
- #define CALL_MCOUNT \
- .pushsection; \
- .section ".data"; \
- .align ALIGNARG(2); \
- 0:.long 0; \
- .previous; \
- mflr %r0; \
- stw %r0,4(%r1); \
- bl _GLOBAL_OFFSET_TABLE_@local-4; \
- mflr %r11; \
- lwz %r0,0b@got(%r11); \
- bl JUMPTARGET(_mcount);
- #else /* PIC */
- #define CALL_MCOUNT \
- .section ".data"; \
- .align ALIGNARG(2); \
- 0:.long 0; \
- .previous; \
- mflr %r0; \
- lis %r11,0b@ha; \
- stw %r0,4(%r1); \
- addi %r0,%r11,0b@l; \
- bl JUMPTARGET(_mcount);
- #endif /* PIC */
- #else /* PROF */
- #define CALL_MCOUNT /* Do nothing. */
- #endif /* PROF */
- #define ENTRY(name) \
- ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
- ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
- .align ALIGNARG(2); \
- C_LABEL(name) \
- CALL_MCOUNT
- #define EALIGN_W_0 /* No words to insert. */
- #define EALIGN_W_1 nop
- #define EALIGN_W_2 nop;nop
- #define EALIGN_W_3 nop;nop;nop
- #define EALIGN_W_4 EALIGN_W_3;nop
- #define EALIGN_W_5 EALIGN_W_4;nop
- #define EALIGN_W_6 EALIGN_W_5;nop
- #define EALIGN_W_7 EALIGN_W_6;nop
- /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
- past a 2^align boundary. */
- #ifdef PROF
- #define EFFI_ALIGN(name, alignt, words) \
- ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
- ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
- .align ALIGNARG(2); \
- C_LABEL(name) \
- CALL_MCOUNT \
- b 0f; \
- .align ALIGNARG(alignt); \
- EALIGN_W_##words; \
- 0:
- #else /* PROF */
- #define EFFI_ALIGN(name, alignt, words) \
- ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
- ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
- .align ALIGNARG(alignt); \
- EALIGN_W_##words; \
- C_LABEL(name)
- #endif
- #define END(name) \
- ASM_SIZE_DIRECTIVE(name)
- #ifdef PIC
- #define JUMPTARGET(name) name##@plt
- #else
- #define JUMPTARGET(name) name
- #endif
- /* Local labels stripped out by the linker. */
- #define L(x) .L##x
- ====================File: src/powerpc/darwin.S====================
- /* -----------------------------------------------------------------------
- darwin.S - Copyright (c) 2000 John Hornkvist
- Copyright (c) 2004, 2010 Free Software Foundation, Inc.
- PowerPC Assembly glue.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #define LIBFFI_ASM
- #if defined(__ppc64__)
- #define MODE_CHOICE(x, y) y
- #else
- #define MODE_CHOICE(x, y) x
- #endif
- #define machine_choice MODE_CHOICE(ppc7400,ppc64)
- ; Define some pseudo-opcodes for size-independent load & store of GPRs ...
- #define lgu MODE_CHOICE(lwzu, ldu)
- #define lg MODE_CHOICE(lwz,ld)
- #define sg MODE_CHOICE(stw,std)
- #define sgu MODE_CHOICE(stwu,stdu)
- #define sgux MODE_CHOICE(stwux,stdux)
- ; ... and the size of GPRs and their storage indicator.
- #define GPR_BYTES MODE_CHOICE(4,8)
- #define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */
- #define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */
- ; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.
- #define LINKAGE_SIZE MODE_CHOICE(24,48)
- #define PARAM_AREA MODE_CHOICE(32,64)
- #define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* save position for lr */
- /* If there is any FP stuff we make space for all of the regs. */
- #define SAVED_FPR_COUNT 13
- #define FPR_SIZE 8
- #define RESULT_BYTES 16
- /* This should be kept in step with the same value in ffi_darwin.c. */
- #define ASM_NEEDS_REGISTERS 4
- #define SAVE_REGS_SIZE (ASM_NEEDS_REGISTERS * GPR_BYTES)
- #include <fficonfig.h>
- #include <ffi.h>
- #define JUMPTARGET(name) name
- #define L(x) x
- .text
- .align 2
- .globl _ffi_prep_args
- .align 2
- .globl _ffi_call_DARWIN
- /* We arrive here with:
- r3 = ptr to extended cif.
- r4 = -bytes.
- r5 = cif flags.
- r6 = ptr to return value.
- r7 = fn pointer (user func).
- r8 = fn pointer (ffi_prep_args).
- r9 = ffi_type* for the ret val. */
- _ffi_call_DARWIN:
- Lstartcode:
- mr r12,r8 /* We only need r12 until the call,
- so it does not have to be saved. */
- LFB1:
- /* Save the old stack pointer as AP. */
- mr r8,r1
- LCFI0:
-
- /* Save the retval type in parents frame. */
- sg r9,(LINKAGE_SIZE+6*GPR_BYTES)(r8)
- /* Allocate the stack space we need. */
- sgux r1,r1,r4
- /* Save registers we use. */
- mflr r9
- sg r9,SAVED_LR_OFFSET(r8)
- sg r28,-(4 * GPR_BYTES)(r8)
- sg r29,-(3 * GPR_BYTES)(r8)
- sg r30,-(2 * GPR_BYTES)(r8)
- sg r31,-( GPR_BYTES)(r8)
- #if !defined(POWERPC_DARWIN)
- /* The TOC slot is reserved in the Darwin ABI and r2 is volatile. */
- sg r2,(5 * GPR_BYTES)(r1)
- #endif
- LCFI1:
- /* Save arguments over call. */
- mr r31,r5 /* flags, */
- mr r30,r6 /* rvalue, */
- mr r29,r7 /* function address, */
- mr r28,r8 /* our AP. */
- LCFI2:
- /* Call ffi_prep_args. r3 = extended cif, r4 = stack ptr copy. */
- mr r4,r1
- li r9,0
- mtctr r12 /* r12 holds address of _ffi_prep_args. */
- bctrl
- #if !defined(POWERPC_DARWIN)
- /* The TOC slot is reserved in the Darwin ABI and r2 is volatile. */
- lg r2,(5 * GPR_BYTES)(r1)
- #endif
- /* Now do the call.
- Set up cr1 with bits 4-7 of the flags. */
- mtcrf 0x40,r31
- /* Get the address to call into CTR. */
- mtctr r29
- /* Load all those argument registers.
- We have set up a nice stack frame, just load it into registers. */
- lg r3, (LINKAGE_SIZE )(r1)
- lg r4, (LINKAGE_SIZE + GPR_BYTES)(r1)
- lg r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r1)
- lg r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r1)
- nop
- lg r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r1)
- lg r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r1)
- lg r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r1)
- lg r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r1)
- L1:
- /* ... Load all the FP registers. */
- bf 6,L2 /* No floats to load. */
- lfd f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28)
- lfd f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28)
- lfd f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28)
- lfd f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28)
- nop
- lfd f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28)
- lfd f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28)
- lfd f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28)
- lfd f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28)
- nop
- lfd f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28)
- lfd f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28)
- lfd f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28)
- lfd f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28)
- nop
- lfd f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28)
- L2:
- mr r12,r29 /* Put the target address in r12 as specified. */
- mtctr r12
- nop
- nop
- /* Make the call. */
- bctrl
- /* Now, deal with the return value. */
- /* m64 structure returns can occupy the same set of registers as
- would be used to pass such a structure as arg0 - so take care
- not to step on any possibly hot regs. */
- /* Get the flags.. */
- mtcrf 0x03,r31 ; we need c6 & cr7 now.
- ; FLAG_RETURNS_NOTHING also covers struct ret-by-ref.
- bt 30,L(done_return_value) ; FLAG_RETURNS_NOTHING
- bf 27,L(scalar_return_value) ; not FLAG_RETURNS_STRUCT
-
- /* OK, so we have a struct. */
- #if defined(__ppc64__)
- bt 31,L(maybe_return_128) ; FLAG_RETURNS_128BITS, special case
- /* OK, we have to map the return back to a mem struct.
- We are about to trample the parents param area, so recover the
- return type. r29 is free, since the call is done. */
- lg r29,(LINKAGE_SIZE + 6 * GPR_BYTES)(r28)
- sg r3, (LINKAGE_SIZE )(r28)
- sg r4, (LINKAGE_SIZE + GPR_BYTES)(r28)
- sg r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r28)
- sg r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r28)
- nop
- sg r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r28)
- sg r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r28)
- sg r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r28)
- sg r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28)
- /* OK, so do the block move - we trust that memcpy will not trample
- the fprs... */
- mr r3,r30 ; dest
- addi r4,r28,LINKAGE_SIZE ; source
- /* The size is a size_t, should be long. */
- lg r5,0(r29)
- /* Figure out small structs */
- cmpi 0,r5,4
- bgt L3 ; 1, 2 and 4 bytes have special rules.
- cmpi 0,r5,3
- beq L3 ; not 3
- addi r4,r4,8
- subf r4,r5,r4
- L3:
- bl _memcpy
-
- /* ... do we need the FP registers? - recover the flags.. */
- mtcrf 0x03,r31 ; we need c6 & cr7 now.
- bf 29,L(done_return_value) /* No floats in the struct. */
- stfd f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28)
- stfd f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28)
- stfd f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28)
- stfd f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28)
- nop
- stfd f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28)
- stfd f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28)
- stfd f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28)
- stfd f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28)
- nop
- stfd f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28)
- stfd f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28)
- stfd f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28)
- stfd f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28)
- nop
- stfd f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28)
- mr r3,r29 ; ffi_type *
- mr r4,r30 ; dest
- addi r5,r28,-SAVE_REGS_SIZE-(13*FPR_SIZE) ; fprs
- xor r6,r6,r6
- sg r6,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28)
- addi r6,r28,(LINKAGE_SIZE + 7 * GPR_BYTES) ; point to a zeroed counter.
- bl _darwin64_struct_floats_to_mem
- b L(done_return_value)
- #else
- stw r3,0(r30) ; m32 the only struct return in reg is 4 bytes.
- #endif
- b L(done_return_value)
- L(fp_return_value):
- /* Do we have long double to store? */
- bf 31,L(fd_return_value) ; FLAG_RETURNS_128BITS
- stfd f1,0(r30)
- stfd f2,FPR_SIZE(r30)
- b L(done_return_value)
- L(fd_return_value):
- /* Do we have double to store? */
- bf 28,L(float_return_value)
- stfd f1,0(r30)
- b L(done_return_value)
- L(float_return_value):
- /* We only have a float to store. */
- stfs f1,0(r30)
- b L(done_return_value)
- L(scalar_return_value):
- bt 29,L(fp_return_value) ; FLAG_RETURNS_FP
- ; ffi_arg is defined as unsigned long.
- sg r3,0(r30) ; Save the reg.
- bf 28,L(done_return_value) ; not FLAG_RETURNS_64BITS
- #if defined(__ppc64__)
- L(maybe_return_128):
- std r3,0(r30)
- bf 31,L(done_return_value) ; not FLAG_RETURNS_128BITS
- std r4,8(r30)
- #else
- stw r4,4(r30)
- #endif
- /* Fall through. */
- /* We want this at the end to simplify eh epilog computation. */
- L(done_return_value):
- /* Restore the registers we used and return. */
- lg r29,SAVED_LR_OFFSET(r28)
- ; epilog
- lg r31,-(1 * GPR_BYTES)(r28)
- mtlr r29
- lg r30,-(2 * GPR_BYTES)(r28)
- lg r29,-(3 * GPR_BYTES)(r28)
- lg r28,-(4 * GPR_BYTES)(r28)
- lg r1,0(r1)
- blr
- LFE1:
- .align 1
- /* END(_ffi_call_DARWIN) */
- /* Provide a null definition of _ffi_call_AIX. */
- .text
- .globl _ffi_call_AIX
- .align 2
- _ffi_call_AIX:
- blr
- /* END(_ffi_call_AIX) */
- /* EH stuff. */
- #define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)
- .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
- EH_frame1:
- .set L$set$0,LECIE1-LSCIE1
- .long L$set$0 ; Length of Common Information Entry
- LSCIE1:
- .long 0x0 ; CIE Identifier Tag
- .byte 0x1 ; CIE Version
- .ascii "zR\0" ; CIE Augmentation
- .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
- .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor
- .byte 0x41 ; CIE RA Column
- .byte 0x1 ; uleb128 0x1; Augmentation size
- .byte 0x10 ; FDE Encoding (pcrel)
- .byte 0xc ; DW_CFA_def_cfa
- .byte 0x1 ; uleb128 0x1
- .byte 0x0 ; uleb128 0x0
- .align LOG2_GPR_BYTES
- LECIE1:
- .globl _ffi_call_DARWIN.eh
- _ffi_call_DARWIN.eh:
- LSFDE1:
- .set L$set$1,LEFDE1-LASFDE1
- .long L$set$1 ; FDE Length
- LASFDE1:
- .long LASFDE1-EH_frame1 ; FDE CIE offset
- .g_long Lstartcode-. ; FDE initial location
- .set L$set$3,LFE1-Lstartcode
- .g_long L$set$3 ; FDE address range
- .byte 0x0 ; uleb128 0x0; Augmentation size
- .byte 0x4 ; DW_CFA_advance_loc4
- .set L$set$4,LCFI0-Lstartcode
- .long L$set$4
- .byte 0xd ; DW_CFA_def_cfa_register
- .byte 0x08 ; uleb128 0x08
- .byte 0x4 ; DW_CFA_advance_loc4
- .set L$set$5,LCFI1-LCFI0
- .long L$set$5
- .byte 0x11 ; DW_CFA_offset_extended_sf
- .byte 0x41 ; uleb128 0x41
- .byte 0x7e ; sleb128 -2
- .byte 0x9f ; DW_CFA_offset, column 0x1f
- .byte 0x1 ; uleb128 0x1
- .byte 0x9e ; DW_CFA_offset, column 0x1e
- .byte 0x2 ; uleb128 0x2
- .byte 0x9d ; DW_CFA_offset, column 0x1d
- .byte 0x3 ; uleb128 0x3
- .byte 0x9c ; DW_CFA_offset, column 0x1c
- .byte 0x4 ; uleb128 0x4
- .byte 0x4 ; DW_CFA_advance_loc4
- .set L$set$6,LCFI2-LCFI1
- .long L$set$6
- .byte 0xd ; DW_CFA_def_cfa_register
- .byte 0x1c ; uleb128 0x1c
- .align LOG2_GPR_BYTES
- LEFDE1:
- .align 1
- ====================File: src/powerpc/darwin_closure.S====================
- /* -----------------------------------------------------------------------
- darwin_closure.S - Copyright (c) 2002, 2003, 2004, 2010,
- Free Software Foundation, Inc.
- based on ppc_closure.S
- PowerPC Assembly glue.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #define LIBFFI_ASM
- #define L(x) x
- #if defined(__ppc64__)
- #define MODE_CHOICE(x, y) y
- #else
- #define MODE_CHOICE(x, y) x
- #endif
- #define machine_choice MODE_CHOICE(ppc7400,ppc64)
- ; Define some pseudo-opcodes for size-independent load & store of GPRs ...
- #define lgu MODE_CHOICE(lwzu, ldu)
- #define lg MODE_CHOICE(lwz,ld)
- #define sg MODE_CHOICE(stw,std)
- #define sgu MODE_CHOICE(stwu,stdu)
- ; ... and the size of GPRs and their storage indicator.
- #define GPR_BYTES MODE_CHOICE(4,8)
- #define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */
- #define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */
- ; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.
- #define LINKAGE_SIZE MODE_CHOICE(24,48)
- #define PARAM_AREA MODE_CHOICE(32,64)
- #define SAVED_CR_OFFSET MODE_CHOICE(4,8) /* save position for CR */
- #define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* save position for lr */
- /* WARNING: if ffi_type is changed... here be monsters.
- Offsets of items within the result type. */
- #define FFI_TYPE_TYPE MODE_CHOICE(6,10)
- #define FFI_TYPE_ELEM MODE_CHOICE(8,16)
- #define SAVED_FPR_COUNT 13
- #define FPR_SIZE 8
- /* biggest m64 struct ret is 8GPRS + 13FPRS = 168 bytes - rounded to 16bytes = 176. */
- #define RESULT_BYTES MODE_CHOICE(16,176)
- ; The whole stack frame **MUST** be 16byte-aligned.
- #define SAVE_SIZE (((LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES)+15) & -16LL)
- #define PAD_SIZE (SAVE_SIZE-(LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES))
- #define PARENT_PARM_BASE (SAVE_SIZE+LINKAGE_SIZE)
- #define FP_SAVE_BASE (LINKAGE_SIZE+PARAM_AREA)
- #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
- ; We no longer need the pic symbol stub for Darwin >= 9.
- #define BLCLS_HELP _ffi_closure_helper_DARWIN
- #define STRUCT_RETVALUE_P _darwin64_struct_ret_by_value_p
- #define PASS_STR_FLOATS _darwin64_pass_struct_floats
- #undef WANT_STUB
- #else
- #define BLCLS_HELP L_ffi_closure_helper_DARWIN$stub
- #define STRUCT_RETVALUE_P L_darwin64_struct_ret_by_value_p$stub
- #define PASS_STR_FLOATS L_darwin64_pass_struct_floats$stub
- #define WANT_STUB
- #endif
- /* m32/m64
- The stack layout looks like this:
- | Additional params... | | Higher address
- ~ ~ ~
- | Parameters (at least 8*4/8=32/64) | | NUM_GPR_ARG_REGISTERS
- |--------------------------------------------| |
- | TOC=R2 (AIX) Reserved (Darwin) 4/8 | |
- |--------------------------------------------| |
- | Reserved 2*4/8 | |
- |--------------------------------------------| |
- | Space for callee`s LR 4/8 | |
- |--------------------------------------------| |
- | Saved CR [low word for m64] 4/8 | |
- |--------------------------------------------| |
- | Current backchain pointer 4/8 |-/ Parent`s frame.
- |--------------------------------------------| <+ <<< on entry to
- | Result Bytes 16/176 | |
- |--------------------------------------------| |
- ~ padding to 16-byte alignment ~ ~
- |--------------------------------------------| |
- | NUM_FPR_ARG_REGISTERS slots | |
- | here fp13 .. fp1 13*8 | |
- |--------------------------------------------| |
- | R3..R10 8*4/8=32/64 | | NUM_GPR_ARG_REGISTERS
- |--------------------------------------------| |
- | TOC=R2 (AIX) Reserved (Darwin) 4/8 | |
- |--------------------------------------------| | stack |
- | Reserved [compiler,binder] 2*4/8 | | grows |
- |--------------------------------------------| | down V
- | Space for callees LR 4/8 | |
- |--------------------------------------------| | lower addresses
- | Saved CR [low word for m64] 4/8 | |
- |--------------------------------------------| | stack pointer here
- | Current backchain pointer 4/8 |-/ during
- |--------------------------------------------| <<< call.
- */
- .file "darwin_closure.S"
- .machine machine_choice
- .text
- .globl _ffi_closure_ASM
- .align LOG2_GPR_BYTES
- _ffi_closure_ASM:
- LFB1:
- Lstartcode:
- mflr r0 /* extract return address */
- sg r0,SAVED_LR_OFFSET(r1) /* save the return address */
- LCFI0:
- sgu r1,-SAVE_SIZE(r1) /* skip over caller save area
- keep stack aligned to 16. */
- LCFI1:
- /* We want to build up an area for the parameters passed
- in registers. (both floating point and integer) */
- /* Put gpr 3 to gpr 10 in the parents outgoing area...
- ... the remainder of any params that overflowed the regs will
- follow here. */
- sg r3, (PARENT_PARM_BASE )(r1)
- sg r4, (PARENT_PARM_BASE + GPR_BYTES )(r1)
- sg r5, (PARENT_PARM_BASE + GPR_BYTES * 2)(r1)
- sg r6, (PARENT_PARM_BASE + GPR_BYTES * 3)(r1)
- sg r7, (PARENT_PARM_BASE + GPR_BYTES * 4)(r1)
- sg r8, (PARENT_PARM_BASE + GPR_BYTES * 5)(r1)
- sg r9, (PARENT_PARM_BASE + GPR_BYTES * 6)(r1)
- sg r10,(PARENT_PARM_BASE + GPR_BYTES * 7)(r1)
- /* We save fpr 1 to fpr 14 in our own save frame. */
- stfd f1, (FP_SAVE_BASE )(r1)
- stfd f2, (FP_SAVE_BASE + FPR_SIZE )(r1)
- stfd f3, (FP_SAVE_BASE + FPR_SIZE * 2 )(r1)
- stfd f4, (FP_SAVE_BASE + FPR_SIZE * 3 )(r1)
- stfd f5, (FP_SAVE_BASE + FPR_SIZE * 4 )(r1)
- stfd f6, (FP_SAVE_BASE + FPR_SIZE * 5 )(r1)
- stfd f7, (FP_SAVE_BASE + FPR_SIZE * 6 )(r1)
- stfd f8, (FP_SAVE_BASE + FPR_SIZE * 7 )(r1)
- stfd f9, (FP_SAVE_BASE + FPR_SIZE * 8 )(r1)
- stfd f10,(FP_SAVE_BASE + FPR_SIZE * 9 )(r1)
- stfd f11,(FP_SAVE_BASE + FPR_SIZE * 10)(r1)
- stfd f12,(FP_SAVE_BASE + FPR_SIZE * 11)(r1)
- stfd f13,(FP_SAVE_BASE + FPR_SIZE * 12)(r1)
- /* Set up registers for the routine that actually does the work
- get the context pointer from the trampoline. */
- mr r3,r11
- /* Now load up the pointer to the result storage. */
- addi r4,r1,(SAVE_SIZE-RESULT_BYTES)
- /* Now load up the pointer to the saved gpr registers. */
- addi r5,r1,PARENT_PARM_BASE
- /* Now load up the pointer to the saved fpr registers. */
- addi r6,r1,FP_SAVE_BASE
- /* Make the call. */
- bl BLCLS_HELP
- /* r3 contains the rtype pointer... save it since we will need
- it later. */
- sg r3,LINKAGE_SIZE(r1) ; ffi_type * result_type
- lg r0,0(r3) ; size => r0
- lhz r3,FFI_TYPE_TYPE(r3) ; type => r3
- /* The helper will have intercepted structure returns and inserted
- the caller`s destination address for structs returned by ref. */
- /* r3 contains the return type so use it to look up in a table
- so we know how to deal with each type. */
- addi r5,r1,(SAVE_SIZE-RESULT_BYTES) /* Otherwise, our return is here. */
- bl Lget_ret_type0_addr /* Get pointer to Lret_type0 into LR. */
- mflr r4 /* Move to r4. */
- slwi r3,r3,4 /* Now multiply return type by 16. */
- add r3,r3,r4 /* Add contents of table to table address. */
- mtctr r3
- bctr /* Jump to it. */
- LFE1:
- /* Each of the ret_typeX code fragments has to be exactly 16 bytes long
- (4 instructions). For cache effectiveness we align to a 16 byte boundary
- first. */
- .align 4
- nop
- nop
- nop
- Lget_ret_type0_addr:
- blrl
- /* case FFI_TYPE_VOID */
- Lret_type0:
- b Lfinish
- nop
- nop
- nop
- /* case FFI_TYPE_INT */
- Lret_type1:
- lg r3,0(r5)
- b Lfinish
- nop
- nop
- /* case FFI_TYPE_FLOAT */
- Lret_type2:
- lfs f1,0(r5)
- b Lfinish
- nop
- nop
- /* case FFI_TYPE_DOUBLE */
- Lret_type3:
- lfd f1,0(r5)
- b Lfinish
- nop
- nop
- /* case FFI_TYPE_LONGDOUBLE */
- Lret_type4:
- lfd f1,0(r5)
- lfd f2,8(r5)
- b Lfinish
- nop
- /* case FFI_TYPE_UINT8 */
- Lret_type5:
- #if defined(__ppc64__)
- lbz r3,7(r5)
- #else
- lbz r3,3(r5)
- #endif
- b Lfinish
- nop
- nop
- /* case FFI_TYPE_SINT8 */
- Lret_type6:
- #if defined(__ppc64__)
- lbz r3,7(r5)
- #else
- lbz r3,3(r5)
- #endif
- extsb r3,r3
- b Lfinish
- nop
- /* case FFI_TYPE_UINT16 */
- Lret_type7:
- #if defined(__ppc64__)
- lhz r3,6(r5)
- #else
- lhz r3,2(r5)
- #endif
- b Lfinish
- nop
- nop
- /* case FFI_TYPE_SINT16 */
- Lret_type8:
- #if defined(__ppc64__)
- lha r3,6(r5)
- #else
- lha r3,2(r5)
- #endif
- b Lfinish
- nop
- nop
- /* case FFI_TYPE_UINT32 */
- Lret_type9:
- #if defined(__ppc64__)
- lwz r3,4(r5)
- #else
- lwz r3,0(r5)
- #endif
- b Lfinish
- nop
- nop
- /* case FFI_TYPE_SINT32 */
- Lret_type10:
- #if defined(__ppc64__)
- lwz r3,4(r5)
- #else
- lwz r3,0(r5)
- #endif
- b Lfinish
- nop
- nop
- /* case FFI_TYPE_UINT64 */
- Lret_type11:
- #if defined(__ppc64__)
- lg r3,0(r5)
- b Lfinish
- nop
- #else
- lwz r3,0(r5)
- lwz r4,4(r5)
- b Lfinish
- #endif
- nop
- /* case FFI_TYPE_SINT64 */
- Lret_type12:
- #if defined(__ppc64__)
- lg r3,0(r5)
- b Lfinish
- nop
- #else
- lwz r3,0(r5)
- lwz r4,4(r5)
- b Lfinish
- #endif
- nop
- /* case FFI_TYPE_STRUCT */
- Lret_type13:
- #if defined(__ppc64__)
- lg r3,0(r5) ; we need at least this...
- cmpi 0,r0,4
- bgt Lstructend ; not a special small case
- b Lsmallstruct ; see if we need more.
- #else
- cmpwi 0,r0,4
- bgt Lfinish ; not by value
- lg r3,0(r5)
- b Lfinish
- #endif
- /* case FFI_TYPE_POINTER */
- Lret_type14:
- lg r3,0(r5)
- b Lfinish
- nop
- nop
- #if defined(__ppc64__)
- Lsmallstruct:
- beq Lfour ; continuation of Lret13.
- cmpi 0,r0,3
- beq Lfinish ; don`t adjust this - can`t be any floats here...
- srdi r3,r3,48
- cmpi 0,r0,2
- beq Lfinish ; .. or here ..
- srdi r3,r3,8
- b Lfinish ; .. or here.
- Lfour:
- lg r6,LINKAGE_SIZE(r1) ; get the result type
- lg r6,FFI_TYPE_ELEM(r6) ; elements array pointer
- lg r6,0(r6) ; first element
- lhz r0,FFI_TYPE_TYPE(r6) ; OK go the type
- cmpi 0,r0,2 ; FFI_TYPE_FLOAT
- bne Lfourint
- lfs f1,0(r5) ; just one float in the struct.
- b Lfinish
- Lfourint:
- srdi r3,r3,32 ; four bytes.
- b Lfinish
- Lstructend:
- lg r3,LINKAGE_SIZE(r1) ; get the result type
- bl STRUCT_RETVALUE_P
- cmpi 0,r3,0
- beq Lfinish ; nope.
- /* Recover a pointer to the results. */
- addi r11,r1,(SAVE_SIZE-RESULT_BYTES)
- lg r3,0(r11) ; we need at least this...
- lg r4,8(r11)
- cmpi 0,r0,16
- beq Lfinish ; special case 16 bytes we don't consider floats.
- /* OK, frustratingly, the process of saving the struct to mem might have
- messed with the FPRs, so we have to re-load them :(.
- We`ll use our FPRs space again - calling:
- void darwin64_pass_struct_floats (ffi_type *s, char *src,
- unsigned *nfpr, double **fprs)
- We`ll temporarily pinch the first two slots of the param area for local
- vars used by the routine. */
- xor r6,r6,r6
- addi r5,r1,PARENT_PARM_BASE ; some space
- sg r6,0(r5) ; *nfpr zeroed.
- addi r6,r5,8 ; **fprs
- addi r3,r1,FP_SAVE_BASE ; pointer to FPRs space
- sg r3,0(r6)
- mr r4,r11 ; the struct is here...
- lg r3,LINKAGE_SIZE(r1) ; ffi_type * result_type.
- bl PASS_STR_FLOATS ; get struct floats into FPR save space.
- /* See if we used any floats */
- lwz r0,(SAVE_SIZE-RESULT_BYTES)(r1)
- cmpi 0,r0,0
- beq Lstructints ; nope.
- /* OK load `em up... */
- lfd f1, (FP_SAVE_BASE )(r1)
- lfd f2, (FP_SAVE_BASE + FPR_SIZE )(r1)
- lfd f3, (FP_SAVE_BASE + FPR_SIZE * 2 )(r1)
- lfd f4, (FP_SAVE_BASE + FPR_SIZE * 3 )(r1)
- lfd f5, (FP_SAVE_BASE + FPR_SIZE * 4 )(r1)
- lfd f6, (FP_SAVE_BASE + FPR_SIZE * 5 )(r1)
- lfd f7, (FP_SAVE_BASE + FPR_SIZE * 6 )(r1)
- lfd f8, (FP_SAVE_BASE + FPR_SIZE * 7 )(r1)
- lfd f9, (FP_SAVE_BASE + FPR_SIZE * 8 )(r1)
- lfd f10,(FP_SAVE_BASE + FPR_SIZE * 9 )(r1)
- lfd f11,(FP_SAVE_BASE + FPR_SIZE * 10)(r1)
- lfd f12,(FP_SAVE_BASE + FPR_SIZE * 11)(r1)
- lfd f13,(FP_SAVE_BASE + FPR_SIZE * 12)(r1)
- /* point back at our saved struct. */
- Lstructints:
- addi r11,r1,(SAVE_SIZE-RESULT_BYTES)
- lg r3,0(r11) ; we end up picking the
- lg r4,8(r11) ; first two again.
- lg r5,16(r11)
- lg r6,24(r11)
- lg r7,32(r11)
- lg r8,40(r11)
- lg r9,48(r11)
- lg r10,56(r11)
- #endif
- /* case done */
- Lfinish:
- addi r1,r1,SAVE_SIZE /* Restore stack pointer. */
- lg r0,SAVED_LR_OFFSET(r1) /* Get return address. */
- mtlr r0 /* Reset link register. */
- blr
- Lendcode:
- .align 1
-
- /* END(ffi_closure_ASM) */
- /* EH frame stuff. */
- #define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)
- /* 176, 400 */
- #define EH_FRAME_OFFSETA MODE_CHOICE(176,0x90)
- #define EH_FRAME_OFFSETB MODE_CHOICE(1,3)
- .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
- EH_frame1:
- .set L$set$0,LECIE1-LSCIE1
- .long L$set$0 ; Length of Common Information Entry
- LSCIE1:
- .long 0x0 ; CIE Identifier Tag
- .byte 0x1 ; CIE Version
- .ascii "zR\0" ; CIE Augmentation
- .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
- .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor
- .byte 0x41 ; CIE RA Column
- .byte 0x1 ; uleb128 0x1; Augmentation size
- .byte 0x10 ; FDE Encoding (pcrel)
- .byte 0xc ; DW_CFA_def_cfa
- .byte 0x1 ; uleb128 0x1
- .byte 0x0 ; uleb128 0x0
- .align LOG2_GPR_BYTES
- LECIE1:
- .globl _ffi_closure_ASM.eh
- _ffi_closure_ASM.eh:
- LSFDE1:
- .set L$set$1,LEFDE1-LASFDE1
- .long L$set$1 ; FDE Length
- LASFDE1:
- .long LASFDE1-EH_frame1 ; FDE CIE offset
- .g_long Lstartcode-. ; FDE initial location
- .set L$set$2,LFE1-Lstartcode
- .g_long L$set$2 ; FDE address range
- .byte 0x0 ; uleb128 0x0; Augmentation size
- .byte 0x4 ; DW_CFA_advance_loc4
- .set L$set$3,LCFI1-LCFI0
- .long L$set$3
- .byte 0xe ; DW_CFA_def_cfa_offset
- .byte EH_FRAME_OFFSETA,EH_FRAME_OFFSETB ; uleb128 176,1/190,3
- .byte 0x4 ; DW_CFA_advance_loc4
- .set L$set$4,LCFI0-Lstartcode
- .long L$set$4
- .byte 0x11 ; DW_CFA_offset_extended_sf
- .byte 0x41 ; uleb128 0x41
- .byte 0x7e ; sleb128 -2
- .align LOG2_GPR_BYTES
- LEFDE1:
- .align 1
- #ifdef WANT_STUB
- .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
- .align 5
- L_ffi_closure_helper_DARWIN$stub:
- .indirect_symbol _ffi_closure_helper_DARWIN
- mflr r0
- bcl 20,31,"L1$spb"
- "L1$spb":
- mflr r11
- addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")
- mtlr r0
- lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")(r11)
- mtctr r12
- bctr
- .lazy_symbol_pointer
- L_ffi_closure_helper_DARWIN$lazy_ptr:
- .indirect_symbol _ffi_closure_helper_DARWIN
- .g_long dyld_stub_binding_helper
- #if defined(__ppc64__)
- .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
- .align 5
- L_darwin64_struct_ret_by_value_p$stub:
- .indirect_symbol _darwin64_struct_ret_by_value_p
- mflr r0
- bcl 20,31,"L2$spb"
- "L2$spb":
- mflr r11
- addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")
- mtlr r0
- lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")(r11)
- mtctr r12
- bctr
- .lazy_symbol_pointer
- L_darwin64_struct_ret_by_value_p$lazy_ptr:
- .indirect_symbol _darwin64_struct_ret_by_value_p
- .g_long dyld_stub_binding_helper
- .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
- .align 5
- L_darwin64_pass_struct_floats$stub:
- .indirect_symbol _darwin64_pass_struct_floats
- mflr r0
- bcl 20,31,"L3$spb"
- "L3$spb":
- mflr r11
- addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")
- mtlr r0
- lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")(r11)
- mtctr r12
- bctr
- .lazy_symbol_pointer
- L_darwin64_pass_struct_floats$lazy_ptr:
- .indirect_symbol _darwin64_pass_struct_floats
- .g_long dyld_stub_binding_helper
- # endif
- #endif
- ====================File: src/powerpc/ffi.c====================
- /* -----------------------------------------------------------------------
- ffi.c - Copyright (C) 2013 IBM
- Copyright (C) 2011 Anthony Green
- Copyright (C) 2011 Kyle Moffett
- Copyright (C) 2008 Red Hat, Inc
- Copyright (C) 2007, 2008 Free Software Foundation, Inc
- Copyright (c) 1998 Geoffrey Keating
- PowerPC Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #include "ffi.h"
- #include "ffi_common.h"
- #include "ffi_powerpc.h"
- #if HAVE_LONG_DOUBLE_VARIANT
- /* Adjust ffi_type_longdouble. */
- void FFI_HIDDEN
- ffi_prep_types (ffi_abi abi)
- {
- # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- # ifdef POWERPC64
- ffi_prep_types_linux64 (abi);
- # else
- ffi_prep_types_sysv (abi);
- # endif
- # endif
- }
- #endif
- /* Perform machine dependent cif processing */
- ffi_status FFI_HIDDEN
- ffi_prep_cif_machdep (ffi_cif *cif)
- {
- #ifdef POWERPC64
- return ffi_prep_cif_linux64 (cif);
- #else
- return ffi_prep_cif_sysv (cif);
- #endif
- }
- ffi_status FFI_HIDDEN
- ffi_prep_cif_machdep_var (ffi_cif *cif,
- unsigned int nfixedargs MAYBE_UNUSED,
- unsigned int ntotalargs MAYBE_UNUSED)
- {
- #ifdef POWERPC64
- return ffi_prep_cif_linux64_var (cif, nfixedargs, ntotalargs);
- #else
- return ffi_prep_cif_sysv (cif);
- #endif
- }
- static void
- ffi_call_int (ffi_cif *cif,
- void (*fn) (void),
- void *rvalue,
- void **avalue,
- void *closure)
- {
- /* The final SYSV ABI says that structures smaller or equal 8 bytes
- are returned in r3/r4. A draft ABI used by linux instead returns
- them in memory.
- We bounce-buffer SYSV small struct return values so that sysv.S
- can write r3 and r4 to memory without worrying about struct size.
-
- For ELFv2 ABI, use a bounce buffer for homogeneous structs too,
- for similar reasons. This bounce buffer must be aligned to 16
- bytes for use with homogeneous structs of vectors (float128). */
- float128 smst_buffer[8];
- extended_cif ecif;
- ecif.cif = cif;
- ecif.avalue = avalue;
- ecif.rvalue = rvalue;
- if ((cif->flags & FLAG_RETURNS_SMST) != 0)
- ecif.rvalue = smst_buffer;
- /* Ensure that we have a valid struct return value.
- FIXME: Isn't this just papering over a user problem? */
- else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT)
- ecif.rvalue = alloca (cif->rtype->size);
- #ifdef POWERPC64
- ffi_call_LINUX64 (&ecif, fn, ecif.rvalue, cif->flags, closure,
- -(long) cif->bytes);
- #else
- ffi_call_SYSV (&ecif, fn, ecif.rvalue, cif->flags, closure, -cif->bytes);
- #endif
- /* Check for a bounce-buffered return value */
- if (rvalue && ecif.rvalue == smst_buffer)
- {
- unsigned int rsize = cif->rtype->size;
- #ifndef __LITTLE_ENDIAN__
- /* The SYSV ABI returns a structure of up to 4 bytes in size
- left-padded in r3. */
- # ifndef POWERPC64
- if (rsize <= 4)
- memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize);
- else
- # endif
- /* The SYSV ABI returns a structure of up to 8 bytes in size
- left-padded in r3/r4, and the ELFv2 ABI similarly returns a
- structure of up to 8 bytes in size left-padded in r3. But
- note that a structure of a single float is not paddded. */
- if (rsize <= 8 && (cif->flags & FLAG_RETURNS_FP) == 0)
- memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);
- else
- #endif
- memcpy (rvalue, smst_buffer, rsize);
- }
- }
- void
- ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
- {
- ffi_call_int (cif, fn, rvalue, avalue, NULL);
- }
- void
- ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
- void *closure)
- {
- ffi_call_int (cif, fn, rvalue, avalue, closure);
- }
- ffi_status
- ffi_prep_closure_loc (ffi_closure *closure,
- ffi_cif *cif,
- void (*fun) (ffi_cif *, void *, void **, void *),
- void *user_data,
- void *codeloc)
- {
- #ifdef POWERPC64
- return ffi_prep_closure_loc_linux64 (closure, cif, fun, user_data, codeloc);
- #else
- return ffi_prep_closure_loc_sysv (closure, cif, fun, user_data, codeloc);
- #endif
- }
- ffi_status
- ffi_prep_go_closure (ffi_go_closure *closure,
- ffi_cif *cif,
- void (*fun) (ffi_cif *, void *, void **, void *))
- {
- #ifdef POWERPC64
- closure->tramp = ffi_go_closure_linux64;
- #else
- closure->tramp = ffi_go_closure_sysv;
- #endif
- closure->cif = cif;
- closure->fun = fun;
- return FFI_OK;
- }
- ====================File: src/powerpc/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012 Anthony Green
- Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
- Copyright (c) 1996-2003 Red Hat, Inc.
- Target configuration macros for PowerPC.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- #if defined (POWERPC) && defined (__powerpc64__) /* linux64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #elif defined (POWERPC_DARWIN) && defined (__ppc64__) /* Darwin64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #ifndef POWERPC_DARWIN64
- #define POWERPC_DARWIN64
- #endif
- #elif defined (POWERPC_AIX) && defined (__64BIT__) /* AIX64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #endif
- #ifndef LIBFFI_ASM
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- typedef enum ffi_abi {
- FFI_FIRST_ABI = 0,
- #if defined (POWERPC_AIX)
- FFI_AIX,
- FFI_DARWIN,
- FFI_DEFAULT_ABI = FFI_AIX,
- FFI_LAST_ABI
- #elif defined (POWERPC_DARWIN)
- FFI_AIX,
- FFI_DARWIN,
- FFI_DEFAULT_ABI = FFI_DARWIN,
- FFI_LAST_ABI
- #else
- /* The FFI_COMPAT values are used by old code. Since libffi may be
- a shared library we have to support old values for backwards
- compatibility. */
- FFI_COMPAT_SYSV,
- FFI_COMPAT_GCC_SYSV,
- FFI_COMPAT_LINUX64,
- FFI_COMPAT_LINUX,
- FFI_COMPAT_LINUX_SOFT_FLOAT,
- # if defined (POWERPC64)
- /* This bit, always set in new code, must not be set in any of the
- old FFI_COMPAT values that might be used for 64-bit linux. We
- only need worry about FFI_COMPAT_LINUX64, but to be safe avoid
- all old values. */
- FFI_LINUX = 8,
- /* This and following bits can reuse FFI_COMPAT values. */
- FFI_LINUX_STRUCT_ALIGN = 1,
- FFI_LINUX_LONG_DOUBLE_128 = 2,
- FFI_LINUX_LONG_DOUBLE_IEEE128 = 4,
- FFI_DEFAULT_ABI = (FFI_LINUX
- # ifdef __STRUCT_PARM_ALIGN__
- | FFI_LINUX_STRUCT_ALIGN
- # endif
- # ifdef __LONG_DOUBLE_128__
- | FFI_LINUX_LONG_DOUBLE_128
- # ifdef __LONG_DOUBLE_IEEE128__
- | FFI_LINUX_LONG_DOUBLE_IEEE128
- # endif
- # endif
- ),
- FFI_LAST_ABI = 16
- # else
- /* This bit, always set in new code, must not be set in any of the
- old FFI_COMPAT values that might be used for 32-bit linux/sysv/bsd. */
- FFI_SYSV = 8,
- /* This and following bits can reuse FFI_COMPAT values. */
- FFI_SYSV_SOFT_FLOAT = 1,
- FFI_SYSV_STRUCT_RET = 2,
- FFI_SYSV_IBM_LONG_DOUBLE = 4,
- FFI_SYSV_LONG_DOUBLE_128 = 16,
- FFI_DEFAULT_ABI = (FFI_SYSV
- # ifdef __NO_FPRS__
- | FFI_SYSV_SOFT_FLOAT
- # endif
- # if (defined (__SVR4_STRUCT_RETURN) \
- || defined (POWERPC_FREEBSD) && !defined (__AIX_STRUCT_RETURN))
- | FFI_SYSV_STRUCT_RET
- # endif
- # if __LDBL_MANT_DIG__ == 106
- | FFI_SYSV_IBM_LONG_DOUBLE
- # endif
- # ifdef __LONG_DOUBLE_128__
- | FFI_SYSV_LONG_DOUBLE_128
- # endif
- ),
- FFI_LAST_ABI = 32
- # endif
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
- #if defined (POWERPC) || defined (POWERPC_FREEBSD)
- # define FFI_GO_CLOSURES 1
- # define FFI_TARGET_SPECIFIC_VARIADIC 1
- # define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
- #endif
- #if defined (POWERPC_AIX)
- # define FFI_GO_CLOSURES 1
- #endif
- /* ppc_closure.S and linux64_closure.S expect this. */
- #define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER
- /* We define additional types below. If generic types are added that
- must be supported by powerpc libffi then it is likely that
- FFI_PPC_TYPE_LAST needs increasing *and* the jump tables in
- ppc_closure.S and linux64_closure.S be extended. */
- #if !(FFI_TYPE_LAST == FFI_PPC_TYPE_LAST \
- || (FFI_TYPE_LAST == FFI_TYPE_COMPLEX \
- && !defined FFI_TARGET_HAS_COMPLEX_TYPE))
- # error "You likely have a broken powerpc libffi"
- #endif
- /* Needed for soft-float long-double-128 support. */
- #define FFI_TYPE_UINT128 (FFI_PPC_TYPE_LAST + 1)
- /* Needed for FFI_SYSV small structure returns. */
- #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 2)
- /* Used by ELFv2 for homogenous structure returns. */
- #define FFI_V2_TYPE_VECTOR (FFI_PPC_TYPE_LAST + 1)
- #define FFI_V2_TYPE_VECTOR_HOMOG (FFI_PPC_TYPE_LAST + 2)
- #define FFI_V2_TYPE_FLOAT_HOMOG (FFI_PPC_TYPE_LAST + 3)
- #define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_PPC_TYPE_LAST + 4)
- #define FFI_V2_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 5)
- #if _CALL_ELF == 2
- # define FFI_TRAMPOLINE_SIZE 32
- #else
- # if defined(POWERPC64) || defined(POWERPC_AIX)
- # if defined(POWERPC_DARWIN64)
- # define FFI_TRAMPOLINE_SIZE 48
- # else
- # define FFI_TRAMPOLINE_SIZE 24
- # endif
- # else /* POWERPC || POWERPC_AIX */
- # define FFI_TRAMPOLINE_SIZE 40
- # endif
- #endif
- #ifndef LIBFFI_ASM
- #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
- struct ffi_aix_trampoline_struct {
- void * code_pointer; /* Pointer to ffi_closure_ASM */
- void * toc; /* TOC */
- void * static_chain; /* Pointer to closure */
- };
- #endif
- #endif
- #endif
- ====================File: src/powerpc/ppc_closure.S====================
- /* -----------------------------------------------------------------------
- sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
- Copyright (c) 2008 Red Hat, Inc.
- PowerPC Assembly glue.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #include <powerpc/asm.h>
- .file "ppc_closure.S"
- #ifndef POWERPC64
- FFI_HIDDEN(ffi_closure_SYSV)
- ENTRY(ffi_closure_SYSV)
- .cfi_startproc
- stwu %r1,-144(%r1)
- .cfi_def_cfa_offset 144
- mflr %r0
- stw %r0,148(%r1)
- .cfi_offset 65, 4
- # we want to build up an areas for the parameters passed
- # in registers (both floating point and integer)
- # so first save gpr 3 to gpr 10 (aligned to 4)
- stw %r3, 16(%r1)
- stw %r4, 20(%r1)
- stw %r5, 24(%r1)
- # set up registers for the routine that does the work
- # closure->cif
- lwz %r3,FFI_TRAMPOLINE_SIZE(%r11)
- # closure->fun
- lwz %r4,FFI_TRAMPOLINE_SIZE+4(%r11)
- # closure->user_data
- lwz %r5,FFI_TRAMPOLINE_SIZE+8(%r11)
- .Ldoclosure:
- stw %r6, 28(%r1)
- stw %r7, 32(%r1)
- stw %r8, 36(%r1)
- stw %r9, 40(%r1)
- stw %r10,44(%r1)
- #ifndef __NO_FPRS__
- # next save fpr 1 to fpr 8 (aligned to 8)
- stfd %f1, 48(%r1)
- stfd %f2, 56(%r1)
- stfd %f3, 64(%r1)
- stfd %f4, 72(%r1)
- stfd %f5, 80(%r1)
- stfd %f6, 88(%r1)
- stfd %f7, 96(%r1)
- stfd %f8, 104(%r1)
- #endif
- # pointer to the result storage
- addi %r6,%r1,112
- # pointer to the saved gpr registers
- addi %r7,%r1,16
- # pointer to the saved fpr registers
- addi %r8,%r1,48
- # pointer to the outgoing parameter save area in the previous frame
- # i.e. the previous frame pointer + 8
- addi %r9,%r1,152
- # make the call
- bl ffi_closure_helper_SYSV@local
- .Lret:
- # now r3 contains the return type
- # so use it to look up in a table
- # so we know how to deal with each type
- # look up the proper starting point in table
- # by using return type as offset
- mflr %r4 # move address of .Lret to r4
- slwi %r3,%r3,4 # now multiply return type by 16
- addi %r4, %r4, .Lret_type0 - .Lret
- lwz %r0,148(%r1)
- add %r3,%r3,%r4 # add contents of table to table address
- mtctr %r3
- bctr # jump to it
- # Each of the ret_typeX code fragments has to be exactly 16 bytes long
- # (4 instructions). For cache effectiveness we align to a 16 byte boundary
- # first.
- .align 4
- # case FFI_TYPE_VOID
- .Lret_type0:
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- nop
- # case FFI_TYPE_INT
- lwz %r3,112+0(%r1)
- mtlr %r0
- .Lfinish:
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_TYPE_FLOAT
- #ifndef __NO_FPRS__
- lfs %f1,112+0(%r1)
- #else
- nop
- #endif
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_TYPE_DOUBLE
- #ifndef __NO_FPRS__
- lfd %f1,112+0(%r1)
- #else
- nop
- #endif
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_TYPE_LONGDOUBLE
- #ifndef __NO_FPRS__
- lfd %f1,112+0(%r1)
- lfd %f2,112+8(%r1)
- mtlr %r0
- b .Lfinish
- #else
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- nop
- #endif
- # case FFI_TYPE_UINT8
- #ifdef __LITTLE_ENDIAN__
- lbz %r3,112+0(%r1)
- #else
- lbz %r3,112+3(%r1)
- #endif
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_TYPE_SINT8
- #ifdef __LITTLE_ENDIAN__
- lbz %r3,112+0(%r1)
- #else
- lbz %r3,112+3(%r1)
- #endif
- extsb %r3,%r3
- mtlr %r0
- b .Lfinish
- # case FFI_TYPE_UINT16
- #ifdef __LITTLE_ENDIAN__
- lhz %r3,112+0(%r1)
- #else
- lhz %r3,112+2(%r1)
- #endif
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_TYPE_SINT16
- #ifdef __LITTLE_ENDIAN__
- lha %r3,112+0(%r1)
- #else
- lha %r3,112+2(%r1)
- #endif
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_TYPE_UINT32
- lwz %r3,112+0(%r1)
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_TYPE_SINT32
- lwz %r3,112+0(%r1)
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_TYPE_UINT64
- lwz %r3,112+0(%r1)
- lwz %r4,112+4(%r1)
- mtlr %r0
- b .Lfinish
- # case FFI_TYPE_SINT64
- lwz %r3,112+0(%r1)
- lwz %r4,112+4(%r1)
- mtlr %r0
- b .Lfinish
- # case FFI_TYPE_STRUCT
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- nop
- # case FFI_TYPE_POINTER
- lwz %r3,112+0(%r1)
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_TYPE_UINT128
- lwz %r3,112+0(%r1)
- lwz %r4,112+4(%r1)
- lwz %r5,112+8(%r1)
- b .Luint128
- # The return types below are only used when the ABI type is FFI_SYSV.
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
- lbz %r3,112+0(%r1)
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
- lhz %r3,112+0(%r1)
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
- lwz %r3,112+0(%r1)
- #ifdef __LITTLE_ENDIAN__
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- #else
- srwi %r3,%r3,8
- mtlr %r0
- b .Lfinish
- #endif
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
- lwz %r3,112+0(%r1)
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
- lwz %r3,112+0(%r1)
- lwz %r4,112+4(%r1)
- #ifdef __LITTLE_ENDIAN__
- mtlr %r0
- b .Lfinish
- #else
- li %r5,24
- b .Lstruct567
- #endif
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
- lwz %r3,112+0(%r1)
- lwz %r4,112+4(%r1)
- #ifdef __LITTLE_ENDIAN__
- mtlr %r0
- b .Lfinish
- #else
- li %r5,16
- b .Lstruct567
- #endif
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
- lwz %r3,112+0(%r1)
- lwz %r4,112+4(%r1)
- #ifdef __LITTLE_ENDIAN__
- mtlr %r0
- b .Lfinish
- #else
- li %r5,8
- b .Lstruct567
- #endif
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
- lwz %r3,112+0(%r1)
- lwz %r4,112+4(%r1)
- mtlr %r0
- b .Lfinish
- #ifndef __LITTLE_ENDIAN__
- .Lstruct567:
- subfic %r6,%r5,32
- srw %r4,%r4,%r5
- slw %r6,%r3,%r6
- srw %r3,%r3,%r5
- or %r4,%r6,%r4
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_def_cfa_offset 144
- #endif
- .Luint128:
- lwz %r6,112+12(%r1)
- mtlr %r0
- addi %r1,%r1,144
- .cfi_def_cfa_offset 0
- blr
- .cfi_endproc
- END(ffi_closure_SYSV)
- FFI_HIDDEN(ffi_go_closure_sysv)
- ENTRY(ffi_go_closure_sysv)
- .cfi_startproc
- stwu %r1,-144(%r1)
- .cfi_def_cfa_offset 144
- mflr %r0
- stw %r0,148(%r1)
- .cfi_offset 65, 4
- stw %r3, 16(%r1)
- stw %r4, 20(%r1)
- stw %r5, 24(%r1)
- # closure->cif
- lwz %r3,4(%r11)
- # closure->fun
- lwz %r4,8(%r11)
- # user_data
- mr %r5,%r11
- b .Ldoclosure
- .cfi_endproc
- END(ffi_go_closure_sysv)
- #if defined __ELF__ && defined __linux__
- .section .note.GNU-stack,"",@progbits
- #endif
- #endif
- ====================File: src/powerpc/sysv.S====================
- /* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 1998 Geoffrey Keating
- Copyright (C) 2007 Free Software Foundation, Inc
- PowerPC Assembly glue.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #include <powerpc/asm.h>
- #ifndef POWERPC64
- FFI_HIDDEN(ffi_call_SYSV)
- ENTRY(ffi_call_SYSV)
- .cfi_startproc
- /* Save the old stack pointer as AP. */
- mr %r10,%r1
- .cfi_def_cfa_register 10
- /* Allocate the stack space we need. */
- stwux %r1,%r1,%r8
- /* Save registers we use. */
- mflr %r9
- stw %r28,-16(%r10)
- stw %r29,-12(%r10)
- stw %r30, -8(%r10)
- stw %r31, -4(%r10)
- stw %r9, 4(%r10)
- .cfi_offset 65, 4
- .cfi_offset 31, -4
- .cfi_offset 30, -8
- .cfi_offset 29, -12
- .cfi_offset 28, -16
- /* Save arguments over call... */
- stw %r7, -20(%r10) /* closure, */
- mr %r31,%r6 /* flags, */
- mr %r30,%r5 /* rvalue, */
- mr %r29,%r4 /* function address, */
- mr %r28,%r10 /* our AP. */
- .cfi_def_cfa_register 28
- /* Call ffi_prep_args_SYSV. */
- mr %r4,%r1
- bl ffi_prep_args_SYSV@local
- /* Now do the call. */
- /* Set up cr1 with bits 4-7 of the flags. */
- mtcrf 0x40,%r31
- /* Get the address to call into CTR. */
- mtctr %r29
- /* Load all those argument registers. */
- lwz %r3,-24-(8*4)(%r28)
- lwz %r4,-24-(7*4)(%r28)
- lwz %r5,-24-(6*4)(%r28)
- lwz %r6,-24-(5*4)(%r28)
- bf- 5,1f
- nop
- lwz %r7,-24-(4*4)(%r28)
- lwz %r8,-24-(3*4)(%r28)
- lwz %r9,-24-(2*4)(%r28)
- lwz %r10,-24-(1*4)(%r28)
- nop
- 1:
- #ifndef __NO_FPRS__
- /* Load all the FP registers. */
- bf- 6,2f
- lfd %f1,-24-(8*4)-(8*8)(%r28)
- lfd %f2,-24-(8*4)-(7*8)(%r28)
- lfd %f3,-24-(8*4)-(6*8)(%r28)
- lfd %f4,-24-(8*4)-(5*8)(%r28)
- nop
- lfd %f5,-24-(8*4)-(4*8)(%r28)
- lfd %f6,-24-(8*4)-(3*8)(%r28)
- lfd %f7,-24-(8*4)-(2*8)(%r28)
- lfd %f8,-24-(8*4)-(1*8)(%r28)
- #endif
- 2:
- /* Make the call. */
- lwz %r11, -20(%r28)
- bctrl
- /* Now, deal with the return value. */
- mtcrf 0x01,%r31 /* cr7 */
- bt- 31,L(small_struct_return_value)
- bt- 30,L(done_return_value)
- #ifndef __NO_FPRS__
- bt- 29,L(fp_return_value)
- #endif
- stw %r3,0(%r30)
- bf+ 28,L(done_return_value)
- stw %r4,4(%r30)
- mtcrf 0x02,%r31 /* cr6 */
- bf 27,L(done_return_value)
- stw %r5,8(%r30)
- stw %r6,12(%r30)
- /* Fall through... */
- L(done_return_value):
- /* Restore the registers we used and return. */
- lwz %r9, 4(%r28)
- lwz %r31, -4(%r28)
- mtlr %r9
- lwz %r30, -8(%r28)
- lwz %r29,-12(%r28)
- lwz %r28,-16(%r28)
- .cfi_remember_state
- /* At this point we don't have a cfa register. Say all our
- saved regs have been restored. */
- .cfi_same_value 65
- .cfi_same_value 31
- .cfi_same_value 30
- .cfi_same_value 29
- .cfi_same_value 28
- /* Hopefully this works.. */
- .cfi_def_cfa_register 1
- .cfi_offset 1, 0
- lwz %r1,0(%r1)
- .cfi_same_value 1
- blr
- #ifndef __NO_FPRS__
- L(fp_return_value):
- .cfi_restore_state
- bf 28,L(float_return_value)
- stfd %f1,0(%r30)
- mtcrf 0x02,%r31 /* cr6 */
- bf 27,L(done_return_value)
- stfd %f2,8(%r30)
- b L(done_return_value)
- L(float_return_value):
- stfs %f1,0(%r30)
- b L(done_return_value)
- #endif
- L(small_struct_return_value):
- /*
- * The C code always allocates a properly-aligned 8-byte bounce
- * buffer to make this assembly code very simple. Just write out
- * r3 and r4 to the buffer to allow the C code to handle the rest.
- */
- stw %r3, 0(%r30)
- stw %r4, 4(%r30)
- b L(done_return_value)
- .cfi_endproc
- END(ffi_call_SYSV)
- #if defined __ELF__ && defined __linux__
- .section .note.GNU-stack,"",@progbits
- #endif
- #endif
- ====================File: src/prep_cif.c====================
- /* -----------------------------------------------------------------------
- prep_cif.c - Copyright (c) 2011, 2012 Anthony Green
- Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #include <ffi.h>
- #include <ffi_common.h>
- #include <stdlib.h>
- /* Round up to FFI_SIZEOF_ARG. */
- #define STACK_ARG_SIZE(x) FFI_ALIGN(x, FFI_SIZEOF_ARG)
- /* Perform machine independent initialization of aggregate type
- specifications. */
- static ffi_status initialize_aggregate(ffi_type *arg, size_t *offsets)
- {
- ffi_type **ptr;
- if (UNLIKELY(arg == NULL || arg->elements == NULL))
- return FFI_BAD_TYPEDEF;
- arg->size = 0;
- arg->alignment = 0;
- ptr = &(arg->elements[0]);
- if (UNLIKELY(ptr == 0))
- return FFI_BAD_TYPEDEF;
- while ((*ptr) != NULL)
- {
- if (UNLIKELY(((*ptr)->size == 0)
- && (initialize_aggregate((*ptr), NULL) != FFI_OK)))
- return FFI_BAD_TYPEDEF;
- /* Perform a sanity check on the argument type */
- FFI_ASSERT_VALID_TYPE(*ptr);
- arg->size = FFI_ALIGN(arg->size, (*ptr)->alignment);
- if (offsets)
- *offsets++ = arg->size;
- arg->size += (*ptr)->size;
- arg->alignment = (arg->alignment > (*ptr)->alignment) ?
- arg->alignment : (*ptr)->alignment;
- ptr++;
- }
- /* Structure size includes tail padding. This is important for
- structures that fit in one register on ABIs like the PowerPC64
- Linux ABI that right justify small structs in a register.
- It's also needed for nested structure layout, for example
- struct A { long a; char b; }; struct B { struct A x; char y; };
- should find y at an offset of 2*sizeof(long) and result in a
- total size of 3*sizeof(long). */
- arg->size = FFI_ALIGN (arg->size, arg->alignment);
- /* On some targets, the ABI defines that structures have an additional
- alignment beyond the "natural" one based on their elements. */
- #ifdef FFI_AGGREGATE_ALIGNMENT
- if (FFI_AGGREGATE_ALIGNMENT > arg->alignment)
- arg->alignment = FFI_AGGREGATE_ALIGNMENT;
- #endif
- if (arg->size == 0)
- return FFI_BAD_TYPEDEF;
- else
- return FFI_OK;
- }
- #ifndef __CRIS__
- /* The CRIS ABI specifies structure elements to have byte
- alignment only, so it completely overrides this functions,
- which assumes "natural" alignment and padding. */
- /* Perform machine independent ffi_cif preparation, then call
- machine dependent routine. */
- /* For non variadic functions isvariadic should be 0 and
- nfixedargs==ntotalargs.
- For variadic calls, isvariadic should be 1 and nfixedargs
- and ntotalargs set as appropriate. nfixedargs must always be >=1 */
- ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
- unsigned int isvariadic,
- unsigned int nfixedargs,
- unsigned int ntotalargs,
- ffi_type *rtype, ffi_type **atypes)
- {
- unsigned bytes = 0;
- unsigned int i;
- ffi_type **ptr;
- FFI_ASSERT(cif != NULL);
- FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
- FFI_ASSERT(nfixedargs <= ntotalargs);
- if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
- return FFI_BAD_ABI;
- cif->abi = abi;
- cif->arg_types = atypes;
- cif->nargs = ntotalargs;
- cif->rtype = rtype;
- cif->flags = 0;
- #ifdef _M_ARM64
- cif->is_variadic = isvariadic;
- #endif
- #if HAVE_LONG_DOUBLE_VARIANT
- ffi_prep_types (abi);
- #endif
- /* Initialize the return type if necessary */
- if ((cif->rtype->size == 0)
- && (initialize_aggregate(cif->rtype, NULL) != FFI_OK))
- return FFI_BAD_TYPEDEF;
- #ifndef FFI_TARGET_HAS_COMPLEX_TYPE
- if (rtype->type == FFI_TYPE_COMPLEX)
- abort();
- #endif
- /* Perform a sanity check on the return type */
- FFI_ASSERT_VALID_TYPE(cif->rtype);
- /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
- #if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- /* Make space for the return structure pointer */
- if (cif->rtype->type == FFI_TYPE_STRUCT
- #ifdef TILE
- && (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
- #endif
- #ifdef XTENSA
- && (cif->rtype->size > 16)
- #endif
- #ifdef NIOS2
- && (cif->rtype->size > 8)
- #endif
- )
- bytes = STACK_ARG_SIZE(sizeof(void*));
- #endif
- for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
- {
- /* Initialize any uninitialized aggregate type definitions */
- if (((*ptr)->size == 0)
- && (initialize_aggregate((*ptr), NULL) != FFI_OK))
- return FFI_BAD_TYPEDEF;
- #ifndef FFI_TARGET_HAS_COMPLEX_TYPE
- if ((*ptr)->type == FFI_TYPE_COMPLEX)
- abort();
- #endif
- /* Perform a sanity check on the argument type, do this
- check after the initialization. */
- FFI_ASSERT_VALID_TYPE(*ptr);
- #if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- {
- /* Add any padding if necessary */
- if (((*ptr)->alignment - 1) & bytes)
- bytes = (unsigned)FFI_ALIGN(bytes, (*ptr)->alignment);
- #ifdef TILE
- if (bytes < 10 * FFI_SIZEOF_ARG &&
- bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG)
- {
- /* An argument is never split between the 10 parameter
- registers and the stack. */
- bytes = 10 * FFI_SIZEOF_ARG;
- }
- #endif
- #ifdef XTENSA
- if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4)
- bytes = 6*4;
- #endif
- bytes += (unsigned int)STACK_ARG_SIZE((*ptr)->size);
- }
- #endif
- }
- cif->bytes = bytes;
- /* Perform machine dependent cif processing */
- #ifdef FFI_TARGET_SPECIFIC_VARIADIC
- if (isvariadic)
- return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs);
- #endif
- return ffi_prep_cif_machdep(cif);
- }
- #endif /* not __CRIS__ */
- ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
- ffi_type *rtype, ffi_type **atypes)
- {
- return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes);
- }
- ffi_status ffi_prep_cif_var(ffi_cif *cif,
- ffi_abi abi,
- unsigned int nfixedargs,
- unsigned int ntotalargs,
- ffi_type *rtype,
- ffi_type **atypes)
- {
- return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes);
- }
- #if FFI_CLOSURES
- ffi_status
- ffi_prep_closure (ffi_closure* closure,
- ffi_cif* cif,
- void (*fun)(ffi_cif*,void*,void**,void*),
- void *user_data)
- {
- return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
- }
- #endif
- ffi_status
- ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets)
- {
- if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
- return FFI_BAD_ABI;
- if (struct_type->type != FFI_TYPE_STRUCT)
- return FFI_BAD_TYPEDEF;
- #if HAVE_LONG_DOUBLE_VARIANT
- ffi_prep_types (abi);
- #endif
- return initialize_aggregate(struct_type, offsets);
- }
- ====================File: src/raw_api.c====================
- /* -----------------------------------------------------------------------
- raw_api.c - Copyright (c) 1999, 2008 Red Hat, Inc.
- Author: Kresten Krab Thorup <krab@gnu.org>
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- /* This file defines generic functions for use with the raw api. */
- #include <ffi.h>
- #include <ffi_common.h>
- #if !FFI_NO_RAW_API
- size_t
- ffi_raw_size (ffi_cif *cif)
- {
- size_t result = 0;
- int i;
- ffi_type **at = cif->arg_types;
- for (i = cif->nargs-1; i >= 0; i--, at++)
- {
- #if !FFI_NO_STRUCTS
- if ((*at)->type == FFI_TYPE_STRUCT)
- result += FFI_ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
- else
- #endif
- result += FFI_ALIGN ((*at)->size, FFI_SIZEOF_ARG);
- }
- return result;
- }
- void
- ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
- {
- unsigned i;
- ffi_type **tp = cif->arg_types;
- #if WORDS_BIGENDIAN
- for (i = 0; i < cif->nargs; i++, tp++, args++)
- {
- switch ((*tp)->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1);
- break;
-
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2);
- break;
- #if FFI_SIZEOF_ARG >= 4
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4);
- break;
- #endif
-
- #if !FFI_NO_STRUCTS
- case FFI_TYPE_STRUCT:
- *args = (raw++)->ptr;
- break;
- #endif
- case FFI_TYPE_COMPLEX:
- *args = (raw++)->ptr;
- break;
- case FFI_TYPE_POINTER:
- *args = (void*) &(raw++)->ptr;
- break;
-
- default:
- *args = raw;
- raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
- }
- }
- #else /* WORDS_BIGENDIAN */
- #if !PDP
- /* then assume little endian */
- for (i = 0; i < cif->nargs; i++, tp++, args++)
- {
- #if !FFI_NO_STRUCTS
- if ((*tp)->type == FFI_TYPE_STRUCT)
- {
- *args = (raw++)->ptr;
- }
- else
- #endif
- if ((*tp)->type == FFI_TYPE_COMPLEX)
- {
- *args = (raw++)->ptr;
- }
- else
- {
- *args = (void*) raw;
- raw += FFI_ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
- }
- }
- #else
- #error "pdp endian not supported"
- #endif /* ! PDP */
- #endif /* WORDS_BIGENDIAN */
- }
- void
- ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
- {
- unsigned i;
- ffi_type **tp = cif->arg_types;
- for (i = 0; i < cif->nargs; i++, tp++, args++)
- {
- switch ((*tp)->type)
- {
- case FFI_TYPE_UINT8:
- (raw++)->uint = *(UINT8*) (*args);
- break;
- case FFI_TYPE_SINT8:
- (raw++)->sint = *(SINT8*) (*args);
- break;
- case FFI_TYPE_UINT16:
- (raw++)->uint = *(UINT16*) (*args);
- break;
- case FFI_TYPE_SINT16:
- (raw++)->sint = *(SINT16*) (*args);
- break;
- #if FFI_SIZEOF_ARG >= 4
- case FFI_TYPE_UINT32:
- (raw++)->uint = *(UINT32*) (*args);
- break;
- case FFI_TYPE_SINT32:
- (raw++)->sint = *(SINT32*) (*args);
- break;
- #endif
- #if !FFI_NO_STRUCTS
- case FFI_TYPE_STRUCT:
- (raw++)->ptr = *args;
- break;
- #endif
- case FFI_TYPE_COMPLEX:
- (raw++)->ptr = *args;
- break;
- case FFI_TYPE_POINTER:
- (raw++)->ptr = **(void***) args;
- break;
- default:
- memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
- raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
- }
- }
- }
- #if !FFI_NATIVE_RAW_API
- /* This is a generic definition of ffi_raw_call, to be used if the
- * native system does not provide a machine-specific implementation.
- * Having this, allows code to be written for the raw API, without
- * the need for system-specific code to handle input in that format;
- * these following couple of functions will handle the translation forth
- * and back automatically. */
- void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw)
- {
- void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
- ffi_raw_to_ptrarray (cif, raw, avalue);
- ffi_call (cif, fn, rvalue, avalue);
- }
- #if FFI_CLOSURES /* base system provides closures */
- static void
- ffi_translate_args (ffi_cif *cif, void *rvalue,
- void **avalue, void *user_data)
- {
- ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif));
- ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
- ffi_ptrarray_to_raw (cif, avalue, raw);
- (*cl->fun) (cif, rvalue, raw, cl->user_data);
- }
- ffi_status
- ffi_prep_raw_closure_loc (ffi_raw_closure* cl,
- ffi_cif *cif,
- void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
- void *user_data,
- void *codeloc)
- {
- ffi_status status;
- status = ffi_prep_closure_loc ((ffi_closure*) cl,
- cif,
- &ffi_translate_args,
- codeloc,
- codeloc);
- if (status == FFI_OK)
- {
- cl->fun = fun;
- cl->user_data = user_data;
- }
- return status;
- }
- #endif /* FFI_CLOSURES */
- #endif /* !FFI_NATIVE_RAW_API */
- #if FFI_CLOSURES
- /* Again, here is the generic version of ffi_prep_raw_closure, which
- * will install an intermediate "hub" for translation of arguments from
- * the pointer-array format, to the raw format */
- ffi_status
- ffi_prep_raw_closure (ffi_raw_closure* cl,
- ffi_cif *cif,
- void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
- void *user_data)
- {
- return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl);
- }
- #endif /* FFI_CLOSURES */
- #endif /* !FFI_NO_RAW_API */
- ====================File: src/types.c====================
- /* -----------------------------------------------------------------------
- types.c - Copyright (c) 1996, 1998 Red Hat, Inc.
-
- Predefined ffi_types needed by libffi.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- /* Hide the basic type definitions from the header file, so that we
- can redefine them here as "const". */
- #define LIBFFI_HIDE_BASIC_TYPES
- #include <ffi.h>
- #include <ffi_common.h>
- /* Type definitions */
- #define FFI_TYPEDEF(name, type, id, maybe_const)\
- struct struct_align_##name { \
- char c; \
- type x; \
- }; \
- FFI_EXTERN \
- maybe_const ffi_type ffi_type_##name = { \
- sizeof(type), \
- offsetof(struct struct_align_##name, x), \
- id, NULL \
- }
- #define FFI_COMPLEX_TYPEDEF(name, type, maybe_const) \
- static ffi_type *ffi_elements_complex_##name [2] = { \
- (ffi_type *)(&ffi_type_##name), NULL \
- }; \
- struct struct_align_complex_##name { \
- char c; \
- _Complex type x; \
- }; \
- FFI_EXTERN \
- maybe_const ffi_type ffi_type_complex_##name = { \
- sizeof(_Complex type), \
- offsetof(struct struct_align_complex_##name, x), \
- FFI_TYPE_COMPLEX, \
- (ffi_type **)ffi_elements_complex_##name \
- }
- /* Size and alignment are fake here. They must not be 0. */
- FFI_EXTERN const ffi_type ffi_type_void = {
- 1, 1, FFI_TYPE_VOID, NULL
- };
- FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8, const);
- FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8, const);
- FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16, const);
- FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16, const);
- FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32, const);
- FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32, const);
- FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64, const);
- FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64, const);
- FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER, const);
- FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT, const);
- FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE, const);
- #if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__
- #define FFI_LDBL_CONST const
- #else
- #define FFI_LDBL_CONST
- #endif
- #ifdef __alpha__
- /* Even if we're not configured to default to 128-bit long double,
- maintain binary compatibility, as -mlong-double-128 can be used
- at any time. */
- /* Validate the hard-coded number below. */
- # if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4
- # error FFI_TYPE_LONGDOUBLE out of date
- # endif
- const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL };
- #elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE, FFI_LDBL_CONST);
- #endif
- #ifdef FFI_TARGET_HAS_COMPLEX_TYPE
- FFI_COMPLEX_TYPEDEF(float, float, const);
- FFI_COMPLEX_TYPEDEF(double, double, const);
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- FFI_COMPLEX_TYPEDEF(longdouble, long double, FFI_LDBL_CONST);
- #endif
- #endif
- ====================File: src/x86/ffi.c====================
- /* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2017 Anthony Green
- Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
- Copyright (c) 2002 Ranjit Mathew
- Copyright (c) 2002 Bo Thorsen
- Copyright (c) 2002 Roger Sayle
- Copyright (C) 2008, 2010 Free Software Foundation, Inc.
- x86 Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #if defined(__i386__) || defined(_M_IX86)
- #include <ffi.h>
- #include <ffi_common.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include "internal.h"
- /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
- all further uses in this file will refer to the 80-bit type. */
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- # if FFI_TYPE_LONGDOUBLE != 4
- # error FFI_TYPE_LONGDOUBLE out of date
- # endif
- #else
- # undef FFI_TYPE_LONGDOUBLE
- # define FFI_TYPE_LONGDOUBLE 4
- #endif
- #if defined(__GNUC__) && !defined(__declspec)
- # define __declspec(x) __attribute__((x))
- #endif
- #if defined(_MSC_VER) && defined(_M_IX86)
- /* Stack is not 16-byte aligned on Windows. */
- #define STACK_ALIGN(bytes) (bytes)
- #else
- #define STACK_ALIGN(bytes) FFI_ALIGN (bytes, 16)
- #endif
- /* Perform machine dependent cif processing. */
- ffi_status FFI_HIDDEN
- ffi_prep_cif_machdep(ffi_cif *cif)
- {
- size_t bytes = 0;
- int i, n, flags, cabi = cif->abi;
- switch (cabi)
- {
- case FFI_SYSV:
- case FFI_STDCALL:
- case FFI_THISCALL:
- case FFI_FASTCALL:
- case FFI_MS_CDECL:
- case FFI_PASCAL:
- case FFI_REGISTER:
- break;
- default:
- return FFI_BAD_ABI;
- }
- switch (cif->rtype->type)
- {
- case FFI_TYPE_VOID:
- flags = X86_RET_VOID;
- break;
- case FFI_TYPE_FLOAT:
- flags = X86_RET_FLOAT;
- break;
- case FFI_TYPE_DOUBLE:
- flags = X86_RET_DOUBLE;
- break;
- case FFI_TYPE_LONGDOUBLE:
- flags = X86_RET_LDOUBLE;
- break;
- case FFI_TYPE_UINT8:
- flags = X86_RET_UINT8;
- break;
- case FFI_TYPE_UINT16:
- flags = X86_RET_UINT16;
- break;
- case FFI_TYPE_SINT8:
- flags = X86_RET_SINT8;
- break;
- case FFI_TYPE_SINT16:
- flags = X86_RET_SINT16;
- break;
- case FFI_TYPE_INT:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_POINTER:
- flags = X86_RET_INT32;
- break;
- case FFI_TYPE_SINT64:
- case FFI_TYPE_UINT64:
- flags = X86_RET_INT64;
- break;
- case FFI_TYPE_STRUCT:
- #ifndef X86
- /* ??? This should be a different ABI rather than an ifdef. */
- if (cif->rtype->size == 1)
- flags = X86_RET_STRUCT_1B;
- else if (cif->rtype->size == 2)
- flags = X86_RET_STRUCT_2B;
- else if (cif->rtype->size == 4)
- flags = X86_RET_INT32;
- else if (cif->rtype->size == 8)
- flags = X86_RET_INT64;
- else
- #endif
- {
- do_struct:
- switch (cabi)
- {
- case FFI_THISCALL:
- case FFI_FASTCALL:
- case FFI_STDCALL:
- case FFI_MS_CDECL:
- flags = X86_RET_STRUCTARG;
- break;
- default:
- flags = X86_RET_STRUCTPOP;
- break;
- }
- /* Allocate space for return value pointer. */
- bytes += FFI_ALIGN (sizeof(void*), FFI_SIZEOF_ARG);
- }
- break;
- case FFI_TYPE_COMPLEX:
- switch (cif->rtype->elements[0]->type)
- {
- case FFI_TYPE_DOUBLE:
- case FFI_TYPE_LONGDOUBLE:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_UINT64:
- goto do_struct;
- case FFI_TYPE_FLOAT:
- case FFI_TYPE_INT:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT32:
- flags = X86_RET_INT64;
- break;
- case FFI_TYPE_SINT16:
- case FFI_TYPE_UINT16:
- flags = X86_RET_INT32;
- break;
- case FFI_TYPE_SINT8:
- case FFI_TYPE_UINT8:
- flags = X86_RET_STRUCT_2B;
- break;
- default:
- return FFI_BAD_TYPEDEF;
- }
- break;
- default:
- return FFI_BAD_TYPEDEF;
- }
- cif->flags = flags;
- for (i = 0, n = cif->nargs; i < n; i++)
- {
- ffi_type *t = cif->arg_types[i];
- bytes = FFI_ALIGN (bytes, t->alignment);
- bytes += FFI_ALIGN (t->size, FFI_SIZEOF_ARG);
- }
- cif->bytes = bytes;
- return FFI_OK;
- }
- static ffi_arg
- extend_basic_type(void *arg, int type)
- {
- switch (type)
- {
- case FFI_TYPE_SINT8:
- return *(SINT8 *)arg;
- case FFI_TYPE_UINT8:
- return *(UINT8 *)arg;
- case FFI_TYPE_SINT16:
- return *(SINT16 *)arg;
- case FFI_TYPE_UINT16:
- return *(UINT16 *)arg;
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_POINTER:
- case FFI_TYPE_FLOAT:
- return *(UINT32 *)arg;
- default:
- abort();
- }
- }
- struct call_frame
- {
- void *ebp; /* 0 */
- void *retaddr; /* 4 */
- void (*fn)(void); /* 8 */
- int flags; /* 12 */
- void *rvalue; /* 16 */
- unsigned regs[3]; /* 20-28 */
- };
- struct abi_params
- {
- int dir; /* parameter growth direction */
- int static_chain; /* the static chain register used by gcc */
- int nregs; /* number of register parameters */
- int regs[3];
- };
- static const struct abi_params abi_params[FFI_LAST_ABI] = {
- [FFI_SYSV] = { 1, R_ECX, 0 },
- [FFI_THISCALL] = { 1, R_EAX, 1, { R_ECX } },
- [FFI_FASTCALL] = { 1, R_EAX, 2, { R_ECX, R_EDX } },
- [FFI_STDCALL] = { 1, R_ECX, 0 },
- [FFI_PASCAL] = { -1, R_ECX, 0 },
- /* ??? No defined static chain; gcc does not support REGISTER. */
- [FFI_REGISTER] = { -1, R_ECX, 3, { R_EAX, R_EDX, R_ECX } },
- [FFI_MS_CDECL] = { 1, R_ECX, 0 }
- };
- #ifdef HAVE_FASTCALL
- #ifdef _MSC_VER
- #define FFI_DECLARE_FASTCALL __fastcall
- #else
- #define FFI_DECLARE_FASTCALL __declspec(fastcall)
- #endif
- #else
- #define FFI_DECLARE_FASTCALL
- #endif
- extern void FFI_DECLARE_FASTCALL ffi_call_i386(struct call_frame *, char *) FFI_HIDDEN;
- static void
- ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
- void **avalue, void *closure)
- {
- size_t rsize, bytes;
- struct call_frame *frame;
- char *stack, *argp;
- ffi_type **arg_types;
- int flags, cabi, i, n, dir, narg_reg;
- const struct abi_params *pabi;
- flags = cif->flags;
- cabi = cif->abi;
- pabi = &abi_params[cabi];
- dir = pabi->dir;
- rsize = 0;
- if (rvalue == NULL)
- {
- switch (flags)
- {
- case X86_RET_FLOAT:
- case X86_RET_DOUBLE:
- case X86_RET_LDOUBLE:
- case X86_RET_STRUCTPOP:
- case X86_RET_STRUCTARG:
- /* The float cases need to pop the 387 stack.
- The struct cases need to pass a valid pointer to the callee. */
- rsize = cif->rtype->size;
- break;
- default:
- /* We can pretend that the callee returns nothing. */
- flags = X86_RET_VOID;
- break;
- }
- }
- bytes = STACK_ALIGN (cif->bytes);
- stack = alloca(bytes + sizeof(*frame) + rsize);
- argp = (dir < 0 ? stack + bytes : stack);
- frame = (struct call_frame *)(stack + bytes);
- if (rsize)
- rvalue = frame + 1;
- frame->fn = fn;
- frame->flags = flags;
- frame->rvalue = rvalue;
- frame->regs[pabi->static_chain] = (unsigned)closure;
- narg_reg = 0;
- switch (flags)
- {
- case X86_RET_STRUCTARG:
- /* The pointer is passed as the first argument. */
- if (pabi->nregs > 0)
- {
- frame->regs[pabi->regs[0]] = (unsigned)rvalue;
- narg_reg = 1;
- break;
- }
- /* fallthru */
- case X86_RET_STRUCTPOP:
- *(void **)argp = rvalue;
- argp += sizeof(void *);
- break;
- }
- arg_types = cif->arg_types;
- for (i = 0, n = cif->nargs; i < n; i++)
- {
- ffi_type *ty = arg_types[i];
- void *valp = avalue[i];
- size_t z = ty->size;
- int t = ty->type;
- if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
- {
- ffi_arg val = extend_basic_type (valp, t);
- if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
- frame->regs[pabi->regs[narg_reg++]] = val;
- else if (dir < 0)
- {
- argp -= 4;
- *(ffi_arg *)argp = val;
- }
- else
- {
- *(ffi_arg *)argp = val;
- argp += 4;
- }
- }
- else
- {
- size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
- size_t align = FFI_SIZEOF_ARG;
- /* Issue 434: For thiscall and fastcall, if the paramter passed
- as 64-bit integer or struct, all following integer paramters
- will be passed on stack. */
- if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
- && (t == FFI_TYPE_SINT64
- || t == FFI_TYPE_UINT64
- || t == FFI_TYPE_STRUCT))
- narg_reg = 2;
- /* Alignment rules for arguments are quite complex. Vectors and
- structures with 16 byte alignment get it. Note that long double
- on Darwin does have 16 byte alignment, and does not get this
- alignment if passed directly; a structure with a long double
- inside, however, would get 16 byte alignment. Since libffi does
- not support vectors, we need non concern ourselves with other
- cases. */
- if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
- align = 16;
-
- if (dir < 0)
- {
- /* ??? These reverse argument ABIs are probably too old
- to have cared about alignment. Someone should check. */
- argp -= za;
- memcpy (argp, valp, z);
- }
- else
- {
- argp = (char *)FFI_ALIGN (argp, align);
- memcpy (argp, valp, z);
- argp += za;
- }
- }
- }
- FFI_ASSERT (dir > 0 || argp == stack);
- ffi_call_i386 (frame, stack);
- }
- void
- ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
- {
- ffi_call_int (cif, fn, rvalue, avalue, NULL);
- }
- void
- ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
- void **avalue, void *closure)
- {
- ffi_call_int (cif, fn, rvalue, avalue, closure);
- }
- /** private members **/
- void FFI_HIDDEN ffi_closure_i386(void);
- void FFI_HIDDEN ffi_closure_STDCALL(void);
- void FFI_HIDDEN ffi_closure_REGISTER(void);
- struct closure_frame
- {
- unsigned rettemp[4]; /* 0 */
- unsigned regs[3]; /* 16-24 */
- ffi_cif *cif; /* 28 */
- void (*fun)(ffi_cif*,void*,void**,void*); /* 32 */
- void *user_data; /* 36 */
- };
- int FFI_HIDDEN FFI_DECLARE_FASTCALL
- ffi_closure_inner (struct closure_frame *frame, char *stack)
- {
- ffi_cif *cif = frame->cif;
- int cabi, i, n, flags, dir, narg_reg;
- const struct abi_params *pabi;
- ffi_type **arg_types;
- char *argp;
- void *rvalue;
- void **avalue;
- cabi = cif->abi;
- flags = cif->flags;
- narg_reg = 0;
- rvalue = frame->rettemp;
- pabi = &abi_params[cabi];
- dir = pabi->dir;
- argp = (dir < 0 ? stack + STACK_ALIGN (cif->bytes) : stack);
- switch (flags)
- {
- case X86_RET_STRUCTARG:
- if (pabi->nregs > 0)
- {
- rvalue = (void *)frame->regs[pabi->regs[0]];
- narg_reg = 1;
- frame->rettemp[0] = (unsigned)rvalue;
- break;
- }
- /* fallthru */
- case X86_RET_STRUCTPOP:
- rvalue = *(void **)argp;
- argp += sizeof(void *);
- frame->rettemp[0] = (unsigned)rvalue;
- break;
- }
- n = cif->nargs;
- avalue = alloca(sizeof(void *) * n);
- arg_types = cif->arg_types;
- for (i = 0; i < n; ++i)
- {
- ffi_type *ty = arg_types[i];
- size_t z = ty->size;
- int t = ty->type;
- void *valp;
- if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
- {
- if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
- valp = &frame->regs[pabi->regs[narg_reg++]];
- else if (dir < 0)
- {
- argp -= 4;
- valp = argp;
- }
- else
- {
- valp = argp;
- argp += 4;
- }
- }
- else
- {
- size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
- size_t align = FFI_SIZEOF_ARG;
- /* See the comment in ffi_call_int. */
- if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
- align = 16;
- /* Issue 434: For thiscall and fastcall, if the paramter passed
- as 64-bit integer or struct, all following integer paramters
- will be passed on stack. */
- if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
- && (t == FFI_TYPE_SINT64
- || t == FFI_TYPE_UINT64
- || t == FFI_TYPE_STRUCT))
- narg_reg = 2;
- if (dir < 0)
- {
- /* ??? These reverse argument ABIs are probably too old
- to have cared about alignment. Someone should check. */
- argp -= za;
- valp = argp;
- }
- else
- {
- argp = (char *)FFI_ALIGN (argp, align);
- valp = argp;
- argp += za;
- }
- }
- avalue[i] = valp;
- }
- frame->fun (cif, rvalue, avalue, frame->user_data);
- if (cabi == FFI_STDCALL)
- return flags + (cif->bytes << X86_RET_POP_SHIFT);
- else
- return flags;
- }
- ffi_status
- ffi_prep_closure_loc (ffi_closure* closure,
- ffi_cif* cif,
- void (*fun)(ffi_cif*,void*,void**,void*),
- void *user_data,
- void *codeloc)
- {
- char *tramp = closure->tramp;
- void (*dest)(void);
- int op = 0xb8; /* movl imm, %eax */
- switch (cif->abi)
- {
- case FFI_SYSV:
- case FFI_THISCALL:
- case FFI_FASTCALL:
- case FFI_MS_CDECL:
- dest = ffi_closure_i386;
- break;
- case FFI_STDCALL:
- case FFI_PASCAL:
- dest = ffi_closure_STDCALL;
- break;
- case FFI_REGISTER:
- dest = ffi_closure_REGISTER;
- op = 0x68; /* pushl imm */
- break;
- default:
- return FFI_BAD_ABI;
- }
- /* movl or pushl immediate. */
- tramp[0] = op;
- *(void **)(tramp + 1) = codeloc;
- /* jmp dest */
- tramp[5] = 0xe9;
- *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
- closure->cif = cif;
- closure->fun = fun;
- closure->user_data = user_data;
- return FFI_OK;
- }
- void FFI_HIDDEN ffi_go_closure_EAX(void);
- void FFI_HIDDEN ffi_go_closure_ECX(void);
- void FFI_HIDDEN ffi_go_closure_STDCALL(void);
- ffi_status
- ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
- void (*fun)(ffi_cif*,void*,void**,void*))
- {
- void (*dest)(void);
- switch (cif->abi)
- {
- case FFI_SYSV:
- case FFI_MS_CDECL:
- dest = ffi_go_closure_ECX;
- break;
- case FFI_THISCALL:
- case FFI_FASTCALL:
- dest = ffi_go_closure_EAX;
- break;
- case FFI_STDCALL:
- case FFI_PASCAL:
- dest = ffi_go_closure_STDCALL;
- break;
- case FFI_REGISTER:
- default:
- return FFI_BAD_ABI;
- }
- closure->tramp = dest;
- closure->cif = cif;
- closure->fun = fun;
- return FFI_OK;
- }
- /* ------- Native raw API support -------------------------------- */
- #if !FFI_NO_RAW_API
- void FFI_HIDDEN ffi_closure_raw_SYSV(void);
- void FFI_HIDDEN ffi_closure_raw_THISCALL(void);
- ffi_status
- ffi_prep_raw_closure_loc (ffi_raw_closure *closure,
- ffi_cif *cif,
- void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
- void *user_data,
- void *codeloc)
- {
- char *tramp = closure->tramp;
- void (*dest)(void);
- int i;
- /* We currently don't support certain kinds of arguments for raw
- closures. This should be implemented by a separate assembly
- language routine, since it would require argument processing,
- something we don't do now for performance. */
- for (i = cif->nargs-1; i >= 0; i--)
- switch (cif->arg_types[i]->type)
- {
- case FFI_TYPE_STRUCT:
- case FFI_TYPE_LONGDOUBLE:
- return FFI_BAD_TYPEDEF;
- }
- switch (cif->abi)
- {
- case FFI_THISCALL:
- dest = ffi_closure_raw_THISCALL;
- break;
- case FFI_SYSV:
- dest = ffi_closure_raw_SYSV;
- break;
- default:
- return FFI_BAD_ABI;
- }
- /* movl imm, %eax. */
- tramp[0] = 0xb8;
- *(void **)(tramp + 1) = codeloc;
- /* jmp dest */
- tramp[5] = 0xe9;
- *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
- closure->cif = cif;
- closure->fun = fun;
- closure->user_data = user_data;
- return FFI_OK;
- }
- void
- ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
- {
- size_t rsize, bytes;
- struct call_frame *frame;
- char *stack, *argp;
- ffi_type **arg_types;
- int flags, cabi, i, n, narg_reg;
- const struct abi_params *pabi;
- flags = cif->flags;
- cabi = cif->abi;
- pabi = &abi_params[cabi];
- rsize = 0;
- if (rvalue == NULL)
- {
- switch (flags)
- {
- case X86_RET_FLOAT:
- case X86_RET_DOUBLE:
- case X86_RET_LDOUBLE:
- case X86_RET_STRUCTPOP:
- case X86_RET_STRUCTARG:
- /* The float cases need to pop the 387 stack.
- The struct cases need to pass a valid pointer to the callee. */
- rsize = cif->rtype->size;
- break;
- default:
- /* We can pretend that the callee returns nothing. */
- flags = X86_RET_VOID;
- break;
- }
- }
- bytes = STACK_ALIGN (cif->bytes);
- argp = stack =
- (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
- frame = (struct call_frame *)(stack + bytes);
- if (rsize)
- rvalue = frame + 1;
- frame->fn = fn;
- frame->flags = flags;
- frame->rvalue = rvalue;
- narg_reg = 0;
- switch (flags)
- {
- case X86_RET_STRUCTARG:
- /* The pointer is passed as the first argument. */
- if (pabi->nregs > 0)
- {
- frame->regs[pabi->regs[0]] = (unsigned)rvalue;
- narg_reg = 1;
- break;
- }
- /* fallthru */
- case X86_RET_STRUCTPOP:
- *(void **)argp = rvalue;
- argp += sizeof(void *);
- bytes -= sizeof(void *);
- break;
- }
- arg_types = cif->arg_types;
- for (i = 0, n = cif->nargs; narg_reg < pabi->nregs && i < n; i++)
- {
- ffi_type *ty = arg_types[i];
- size_t z = ty->size;
- int t = ty->type;
- if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT && t != FFI_TYPE_FLOAT)
- {
- ffi_arg val = extend_basic_type (avalue, t);
- frame->regs[pabi->regs[narg_reg++]] = val;
- z = FFI_SIZEOF_ARG;
- }
- else
- {
- memcpy (argp, avalue, z);
- z = FFI_ALIGN (z, FFI_SIZEOF_ARG);
- argp += z;
- }
- avalue += z;
- bytes -= z;
- }
- if (i < n)
- memcpy (argp, avalue, bytes);
- ffi_call_i386 (frame, stack);
- }
- #endif /* !FFI_NO_RAW_API */
- #endif /* __i386__ */
- ====================File: src/x86/ffi64.c====================
- /* -----------------------------------------------------------------------
- ffi64.c - Copyright (c) 2011, 2018 Anthony Green
- Copyright (c) 2013 The Written Word, Inc.
- Copyright (c) 2008, 2010 Red Hat, Inc.
- Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
- x86-64 Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #include <ffi.h>
- #include <ffi_common.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <stdint.h>
- #include "internal64.h"
- #ifdef __x86_64__
- #define MAX_GPR_REGS 6
- #define MAX_SSE_REGS 8
- #if defined(__INTEL_COMPILER)
- #include "xmmintrin.h"
- #define UINT128 __m128
- #else
- #if defined(__SUNPRO_C)
- #error #include <sunmedia_types.h>
- #define UINT128 __m128i
- #else
- #define UINT128 __int128_t
- #endif
- #endif
- union big_int_union
- {
- UINT32 i32;
- UINT64 i64;
- UINT128 i128;
- };
- struct register_args
- {
- /* Registers for argument passing. */
- UINT64 gpr[MAX_GPR_REGS];
- union big_int_union sse[MAX_SSE_REGS];
- UINT64 rax; /* ssecount */
- UINT64 r10; /* static chain */
- };
- extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
- void *raddr, void (*fnaddr)(void)) FFI_HIDDEN;
- /* All reference to register classes here is identical to the code in
- gcc/config/i386/i386.c. Do *not* change one without the other. */
- /* Register class used for passing given 64bit part of the argument.
- These represent classes as documented by the PS ABI, with the
- exception of SSESF, SSEDF classes, that are basically SSE class,
- just gcc will use SF or DFmode move instead of DImode to avoid
- reformatting penalties.
- Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
- whenever possible (upper half does contain padding). */
- enum x86_64_reg_class
- {
- X86_64_NO_CLASS,
- X86_64_INTEGER_CLASS,
- X86_64_INTEGERSI_CLASS,
- X86_64_SSE_CLASS,
- X86_64_SSESF_CLASS,
- X86_64_SSEDF_CLASS,
- X86_64_SSEUP_CLASS,
- X86_64_X87_CLASS,
- X86_64_X87UP_CLASS,
- X86_64_COMPLEX_X87_CLASS,
- X86_64_MEMORY_CLASS
- };
- #define MAX_CLASSES 4
- #define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
- /* x86-64 register passing implementation. See x86-64 ABI for details. Goal
- of this code is to classify each 8bytes of incoming argument by the register
- class and assign registers accordingly. */
- /* Return the union class of CLASS1 and CLASS2.
- See the x86-64 PS ABI for details. */
- static enum x86_64_reg_class
- merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
- {
- /* Rule #1: If both classes are equal, this is the resulting class. */
- if (class1 == class2)
- return class1;
- /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
- the other class. */
- if (class1 == X86_64_NO_CLASS)
- return class2;
- if (class2 == X86_64_NO_CLASS)
- return class1;
- /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
- if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
- return X86_64_MEMORY_CLASS;
- /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
- if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
- || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
- return X86_64_INTEGERSI_CLASS;
- if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
- || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
- return X86_64_INTEGER_CLASS;
- /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
- MEMORY is used. */
- if (class1 == X86_64_X87_CLASS
- || class1 == X86_64_X87UP_CLASS
- || class1 == X86_64_COMPLEX_X87_CLASS
- || class2 == X86_64_X87_CLASS
- || class2 == X86_64_X87UP_CLASS
- || class2 == X86_64_COMPLEX_X87_CLASS)
- return X86_64_MEMORY_CLASS;
- /* Rule #6: Otherwise class SSE is used. */
- return X86_64_SSE_CLASS;
- }
- /* Classify the argument of type TYPE and mode MODE.
- CLASSES will be filled by the register class used to pass each word
- of the operand. The number of words is returned. In case the parameter
- should be passed in memory, 0 is returned. As a special case for zero
- sized containers, classes[0] will be NO_CLASS and 1 is returned.
- See the x86-64 PS ABI for details.
- */
- static size_t
- classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
- size_t byte_offset)
- {
- switch (type->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_POINTER:
- do_integer:
- {
- size_t size = byte_offset + type->size;
- if (size <= 4)
- {
- classes[0] = X86_64_INTEGERSI_CLASS;
- return 1;
- }
- else if (size <= 8)
- {
- classes[0] = X86_64_INTEGER_CLASS;
- return 1;
- }
- else if (size <= 12)
- {
- classes[0] = X86_64_INTEGER_CLASS;
- classes[1] = X86_64_INTEGERSI_CLASS;
- return 2;
- }
- else if (size <= 16)
- {
- classes[0] = classes[1] = X86_64_INTEGER_CLASS;
- return 2;
- }
- else
- FFI_ASSERT (0);
- }
- case FFI_TYPE_FLOAT:
- if (!(byte_offset % 8))
- classes[0] = X86_64_SSESF_CLASS;
- else
- classes[0] = X86_64_SSE_CLASS;
- return 1;
- case FFI_TYPE_DOUBLE:
- classes[0] = X86_64_SSEDF_CLASS;
- return 1;
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_LONGDOUBLE:
- classes[0] = X86_64_X87_CLASS;
- classes[1] = X86_64_X87UP_CLASS;
- return 2;
- #endif
- case FFI_TYPE_STRUCT:
- {
- const size_t UNITS_PER_WORD = 8;
- size_t words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
- ffi_type **ptr;
- unsigned int i;
- enum x86_64_reg_class subclasses[MAX_CLASSES];
- /* If the struct is larger than 32 bytes, pass it on the stack. */
- if (type->size > 32)
- return 0;
- for (i = 0; i < words; i++)
- classes[i] = X86_64_NO_CLASS;
- /* Zero sized arrays or structures are NO_CLASS. We return 0 to
- signalize memory class, so handle it as special case. */
- if (!words)
- {
- case FFI_TYPE_VOID:
- classes[0] = X86_64_NO_CLASS;
- return 1;
- }
- /* Merge the fields of structure. */
- for (ptr = type->elements; *ptr != NULL; ptr++)
- {
- size_t num;
- byte_offset = FFI_ALIGN (byte_offset, (*ptr)->alignment);
- num = classify_argument (*ptr, subclasses, byte_offset % 8);
- if (num == 0)
- return 0;
- for (i = 0; i < num; i++)
- {
- size_t pos = byte_offset / 8;
- classes[i + pos] =
- merge_classes (subclasses[i], classes[i + pos]);
- }
- byte_offset += (*ptr)->size;
- }
- if (words > 2)
- {
- /* When size > 16 bytes, if the first one isn't
- X86_64_SSE_CLASS or any other ones aren't
- X86_64_SSEUP_CLASS, everything should be passed in
- memory. */
- if (classes[0] != X86_64_SSE_CLASS)
- return 0;
- for (i = 1; i < words; i++)
- if (classes[i] != X86_64_SSEUP_CLASS)
- return 0;
- }
- /* Final merger cleanup. */
- for (i = 0; i < words; i++)
- {
- /* If one class is MEMORY, everything should be passed in
- memory. */
- if (classes[i] == X86_64_MEMORY_CLASS)
- return 0;
- /* The X86_64_SSEUP_CLASS should be always preceded by
- X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
- if (i > 1 && classes[i] == X86_64_SSEUP_CLASS
- && classes[i - 1] != X86_64_SSE_CLASS
- && classes[i - 1] != X86_64_SSEUP_CLASS)
- {
- /* The first one should never be X86_64_SSEUP_CLASS. */
- FFI_ASSERT (i != 0);
- classes[i] = X86_64_SSE_CLASS;
- }
- /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
- everything should be passed in memory. */
- if (i > 1 && classes[i] == X86_64_X87UP_CLASS
- && (classes[i - 1] != X86_64_X87_CLASS))
- {
- /* The first one should never be X86_64_X87UP_CLASS. */
- FFI_ASSERT (i != 0);
- return 0;
- }
- }
- return words;
- }
- case FFI_TYPE_COMPLEX:
- {
- ffi_type *inner = type->elements[0];
- switch (inner->type)
- {
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- goto do_integer;
- case FFI_TYPE_FLOAT:
- classes[0] = X86_64_SSE_CLASS;
- if (byte_offset % 8)
- {
- classes[1] = X86_64_SSESF_CLASS;
- return 2;
- }
- return 1;
- case FFI_TYPE_DOUBLE:
- classes[0] = classes[1] = X86_64_SSEDF_CLASS;
- return 2;
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_LONGDOUBLE:
- classes[0] = X86_64_COMPLEX_X87_CLASS;
- return 1;
- #endif
- }
- }
- }
- abort();
- }
- /* Examine the argument and return set number of register required in each
- class. Return zero iff parameter should be passed in memory, otherwise
- the number of registers. */
- static size_t
- examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
- _Bool in_return, int *pngpr, int *pnsse)
- {
- size_t n;
- unsigned int i;
- int ngpr, nsse;
- n = classify_argument (type, classes, 0);
- if (n == 0)
- return 0;
- ngpr = nsse = 0;
- for (i = 0; i < n; ++i)
- switch (classes[i])
- {
- case X86_64_INTEGER_CLASS:
- case X86_64_INTEGERSI_CLASS:
- ngpr++;
- break;
- case X86_64_SSE_CLASS:
- case X86_64_SSESF_CLASS:
- case X86_64_SSEDF_CLASS:
- nsse++;
- break;
- case X86_64_NO_CLASS:
- case X86_64_SSEUP_CLASS:
- break;
- case X86_64_X87_CLASS:
- case X86_64_X87UP_CLASS:
- case X86_64_COMPLEX_X87_CLASS:
- return in_return != 0;
- default:
- abort ();
- }
- *pngpr = ngpr;
- *pnsse = nsse;
- return n;
- }
- /* Perform machine dependent cif processing. */
- #ifndef __ILP32__
- extern ffi_status
- ffi_prep_cif_machdep_efi64(ffi_cif *cif);
- #endif
- ffi_status FFI_HIDDEN
- ffi_prep_cif_machdep (ffi_cif *cif)
- {
- int gprcount, ssecount, i, avn, ngpr, nsse;
- unsigned flags;
- enum x86_64_reg_class classes[MAX_CLASSES];
- size_t bytes, n, rtype_size;
- ffi_type *rtype;
- #ifndef __ILP32__
- if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
- return ffi_prep_cif_machdep_efi64(cif);
- #endif
- if (cif->abi != FFI_UNIX64)
- return FFI_BAD_ABI;
- gprcount = ssecount = 0;
- rtype = cif->rtype;
- rtype_size = rtype->size;
- switch (rtype->type)
- {
- case FFI_TYPE_VOID:
- flags = UNIX64_RET_VOID;
- break;
- case FFI_TYPE_UINT8:
- flags = UNIX64_RET_UINT8;
- break;
- case FFI_TYPE_SINT8:
- flags = UNIX64_RET_SINT8;
- break;
- case FFI_TYPE_UINT16:
- flags = UNIX64_RET_UINT16;
- break;
- case FFI_TYPE_SINT16:
- flags = UNIX64_RET_SINT16;
- break;
- case FFI_TYPE_UINT32:
- flags = UNIX64_RET_UINT32;
- break;
- case FFI_TYPE_INT:
- case FFI_TYPE_SINT32:
- flags = UNIX64_RET_SINT32;
- break;
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- flags = UNIX64_RET_INT64;
- break;
- case FFI_TYPE_POINTER:
- flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64);
- break;
- case FFI_TYPE_FLOAT:
- flags = UNIX64_RET_XMM32;
- break;
- case FFI_TYPE_DOUBLE:
- flags = UNIX64_RET_XMM64;
- break;
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_LONGDOUBLE:
- flags = UNIX64_RET_X87;
- break;
- #endif
- case FFI_TYPE_STRUCT:
- n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
- if (n == 0)
- {
- /* The return value is passed in memory. A pointer to that
- memory is the first argument. Allocate a register for it. */
- gprcount++;
- /* We don't have to do anything in asm for the return. */
- flags = UNIX64_RET_VOID | UNIX64_FLAG_RET_IN_MEM;
- }
- else
- {
- _Bool sse0 = SSE_CLASS_P (classes[0]);
- if (rtype_size == 4 && sse0)
- flags = UNIX64_RET_XMM32;
- else if (rtype_size == 8)
- flags = sse0 ? UNIX64_RET_XMM64 : UNIX64_RET_INT64;
- else
- {
- _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
- if (sse0 && sse1)
- flags = UNIX64_RET_ST_XMM0_XMM1;
- else if (sse0)
- flags = UNIX64_RET_ST_XMM0_RAX;
- else if (sse1)
- flags = UNIX64_RET_ST_RAX_XMM0;
- else
- flags = UNIX64_RET_ST_RAX_RDX;
- flags |= rtype_size << UNIX64_SIZE_SHIFT;
- }
- }
- break;
- case FFI_TYPE_COMPLEX:
- switch (rtype->elements[0]->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- flags = UNIX64_RET_ST_RAX_RDX | ((unsigned) rtype_size << UNIX64_SIZE_SHIFT);
- break;
- case FFI_TYPE_FLOAT:
- flags = UNIX64_RET_XMM64;
- break;
- case FFI_TYPE_DOUBLE:
- flags = UNIX64_RET_ST_XMM0_XMM1 | (16 << UNIX64_SIZE_SHIFT);
- break;
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_LONGDOUBLE:
- flags = UNIX64_RET_X87_2;
- break;
- #endif
- default:
- return FFI_BAD_TYPEDEF;
- }
- break;
- default:
- return FFI_BAD_TYPEDEF;
- }
- /* Go over all arguments and determine the way they should be passed.
- If it's in a register and there is space for it, let that be so. If
- not, add it's size to the stack byte count. */
- for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
- {
- if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
- || gprcount + ngpr > MAX_GPR_REGS
- || ssecount + nsse > MAX_SSE_REGS)
- {
- long align = cif->arg_types[i]->alignment;
- if (align < 8)
- align = 8;
- bytes = FFI_ALIGN (bytes, align);
- bytes += cif->arg_types[i]->size;
- }
- else
- {
- gprcount += ngpr;
- ssecount += nsse;
- }
- }
- if (ssecount)
- flags |= UNIX64_FLAG_XMM_ARGS;
- cif->flags = flags;
- cif->bytes = (unsigned) FFI_ALIGN (bytes, 8);
- return FFI_OK;
- }
- static void
- ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
- void **avalue, void *closure)
- {
- enum x86_64_reg_class classes[MAX_CLASSES];
- char *stack, *argp;
- ffi_type **arg_types;
- int gprcount, ssecount, ngpr, nsse, i, avn, flags;
- struct register_args *reg_args;
- /* Can't call 32-bit mode from 64-bit mode. */
- FFI_ASSERT (cif->abi == FFI_UNIX64);
- /* If the return value is a struct and we don't have a return value
- address then we need to make one. Otherwise we can ignore it. */
- flags = cif->flags;
- if (rvalue == NULL)
- {
- if (flags & UNIX64_FLAG_RET_IN_MEM)
- rvalue = alloca (cif->rtype->size);
- else
- flags = UNIX64_RET_VOID;
- }
- /* Allocate the space for the arguments, plus 4 words of temp space. */
- stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
- reg_args = (struct register_args *) stack;
- argp = stack + sizeof (struct register_args);
- reg_args->r10 = (uintptr_t) closure;
- gprcount = ssecount = 0;
- /* If the return value is passed in memory, add the pointer as the
- first integer argument. */
- if (flags & UNIX64_FLAG_RET_IN_MEM)
- reg_args->gpr[gprcount++] = (unsigned long) rvalue;
- avn = cif->nargs;
- arg_types = cif->arg_types;
- for (i = 0; i < avn; ++i)
- {
- size_t n, size = arg_types[i]->size;
- n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
- if (n == 0
- || gprcount + ngpr > MAX_GPR_REGS
- || ssecount + nsse > MAX_SSE_REGS)
- {
- long align = arg_types[i]->alignment;
- /* Stack arguments are *always* at least 8 byte aligned. */
- if (align < 8)
- align = 8;
- /* Pass this argument in memory. */
- argp = (void *) FFI_ALIGN (argp, align);
- memcpy (argp, avalue[i], size);
- argp += size;
- }
- else
- {
- /* The argument is passed entirely in registers. */
- char *a = (char *) avalue[i];
- unsigned int j;
- for (j = 0; j < n; j++, a += 8, size -= 8)
- {
- switch (classes[j])
- {
- case X86_64_NO_CLASS:
- case X86_64_SSEUP_CLASS:
- break;
- case X86_64_INTEGER_CLASS:
- case X86_64_INTEGERSI_CLASS:
- /* Sign-extend integer arguments passed in general
- purpose registers, to cope with the fact that
- LLVM incorrectly assumes that this will be done
- (the x86-64 PS ABI does not specify this). */
- switch (arg_types[i]->type)
- {
- case FFI_TYPE_SINT8:
- reg_args->gpr[gprcount] = (SINT64) *((SINT8 *) a);
- break;
- case FFI_TYPE_SINT16:
- reg_args->gpr[gprcount] = (SINT64) *((SINT16 *) a);
- break;
- case FFI_TYPE_SINT32:
- reg_args->gpr[gprcount] = (SINT64) *((SINT32 *) a);
- break;
- default:
- reg_args->gpr[gprcount] = 0;
- memcpy (®_args->gpr[gprcount], a, size);
- }
- gprcount++;
- break;
- case X86_64_SSE_CLASS:
- case X86_64_SSEDF_CLASS:
- memcpy (®_args->sse[ssecount++].i64, a, sizeof(UINT64));
- break;
- case X86_64_SSESF_CLASS:
- memcpy (®_args->sse[ssecount++].i32, a, sizeof(UINT32));
- break;
- default:
- abort();
- }
- }
- }
- }
- reg_args->rax = ssecount;
- ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
- flags, rvalue, fn);
- }
- #ifndef __ILP32__
- extern void
- ffi_call_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);
- #endif
- void
- ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
- {
- #ifndef __ILP32__
- if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
- {
- ffi_call_efi64(cif, fn, rvalue, avalue);
- return;
- }
- #endif
- ffi_call_int (cif, fn, rvalue, avalue, NULL);
- }
- #ifndef __ILP32__
- extern void
- ffi_call_go_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue,
- void **avalue, void *closure);
- #endif
- void
- ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
- void **avalue, void *closure)
- {
- #ifndef __ILP32__
- if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
- {
- ffi_call_go_efi64(cif, fn, rvalue, avalue, closure);
- return;
- }
- #endif
- ffi_call_int (cif, fn, rvalue, avalue, closure);
- }
- extern void ffi_closure_unix64(void) FFI_HIDDEN;
- extern void ffi_closure_unix64_sse(void) FFI_HIDDEN;
- #ifndef __ILP32__
- extern ffi_status
- ffi_prep_closure_loc_efi64(ffi_closure* closure,
- ffi_cif* cif,
- void (*fun)(ffi_cif*, void*, void**, void*),
- void *user_data,
- void *codeloc);
- #endif
- ffi_status
- ffi_prep_closure_loc (ffi_closure* closure,
- ffi_cif* cif,
- void (*fun)(ffi_cif*, void*, void**, void*),
- void *user_data,
- void *codeloc)
- {
- static const unsigned char trampoline[16] = {
- /* leaq -0x7(%rip),%r10 # 0x0 */
- 0x4c, 0x8d, 0x15, 0xf9, 0xff, 0xff, 0xff,
- /* jmpq *0x3(%rip) # 0x10 */
- 0xff, 0x25, 0x03, 0x00, 0x00, 0x00,
- /* nopl (%rax) */
- 0x0f, 0x1f, 0x00
- };
- void (*dest)(void);
- char *tramp = closure->tramp;
- #ifndef __ILP32__
- if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
- return ffi_prep_closure_loc_efi64(closure, cif, fun, user_data, codeloc);
- #endif
- if (cif->abi != FFI_UNIX64)
- return FFI_BAD_ABI;
- if (cif->flags & UNIX64_FLAG_XMM_ARGS)
- dest = ffi_closure_unix64_sse;
- else
- dest = ffi_closure_unix64;
- memcpy (tramp, trampoline, sizeof(trampoline));
- *(UINT64 *)(tramp + 16) = (uintptr_t)dest;
- closure->cif = cif;
- closure->fun = fun;
- closure->user_data = user_data;
- return FFI_OK;
- }
- int FFI_HIDDEN
- ffi_closure_unix64_inner(ffi_cif *cif,
- void (*fun)(ffi_cif*, void*, void**, void*),
- void *user_data,
- void *rvalue,
- struct register_args *reg_args,
- char *argp)
- {
- void **avalue;
- ffi_type **arg_types;
- long i, avn;
- int gprcount, ssecount, ngpr, nsse;
- int flags;
- avn = cif->nargs;
- flags = cif->flags;
- avalue = alloca(avn * sizeof(void *));
- gprcount = ssecount = 0;
- if (flags & UNIX64_FLAG_RET_IN_MEM)
- {
- /* On return, %rax will contain the address that was passed
- by the caller in %rdi. */
- void *r = (void *)(uintptr_t)reg_args->gpr[gprcount++];
- *(void **)rvalue = r;
- rvalue = r;
- flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64);
- }
- arg_types = cif->arg_types;
- for (i = 0; i < avn; ++i)
- {
- enum x86_64_reg_class classes[MAX_CLASSES];
- size_t n;
- n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
- if (n == 0
- || gprcount + ngpr > MAX_GPR_REGS
- || ssecount + nsse > MAX_SSE_REGS)
- {
- long align = arg_types[i]->alignment;
- /* Stack arguments are *always* at least 8 byte aligned. */
- if (align < 8)
- align = 8;
- /* Pass this argument in memory. */
- argp = (void *) FFI_ALIGN (argp, align);
- avalue[i] = argp;
- argp += arg_types[i]->size;
- }
- /* If the argument is in a single register, or two consecutive
- integer registers, then we can use that address directly. */
- else if (n == 1
- || (n == 2 && !(SSE_CLASS_P (classes[0])
- || SSE_CLASS_P (classes[1]))))
- {
- /* The argument is in a single register. */
- if (SSE_CLASS_P (classes[0]))
- {
- avalue[i] = ®_args->sse[ssecount];
- ssecount += n;
- }
- else
- {
- avalue[i] = ®_args->gpr[gprcount];
- gprcount += n;
- }
- }
- /* Otherwise, allocate space to make them consecutive. */
- else
- {
- char *a = alloca (16);
- unsigned int j;
- avalue[i] = a;
- for (j = 0; j < n; j++, a += 8)
- {
- if (SSE_CLASS_P (classes[j]))
- memcpy (a, ®_args->sse[ssecount++], 8);
- else
- memcpy (a, ®_args->gpr[gprcount++], 8);
- }
- }
- }
- /* Invoke the closure. */
- fun (cif, rvalue, avalue, user_data);
- /* Tell assembly how to perform return type promotions. */
- return flags;
- }
- extern void ffi_go_closure_unix64(void) FFI_HIDDEN;
- extern void ffi_go_closure_unix64_sse(void) FFI_HIDDEN;
- #ifndef __ILP32__
- extern ffi_status
- ffi_prep_go_closure_efi64(ffi_go_closure* closure, ffi_cif* cif,
- void (*fun)(ffi_cif*, void*, void**, void*));
- #endif
- ffi_status
- ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
- void (*fun)(ffi_cif*, void*, void**, void*))
- {
- #ifndef __ILP32__
- if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
- return ffi_prep_go_closure_efi64(closure, cif, fun);
- #endif
- if (cif->abi != FFI_UNIX64)
- return FFI_BAD_ABI;
- closure->tramp = (cif->flags & UNIX64_FLAG_XMM_ARGS
- ? ffi_go_closure_unix64_sse
- : ffi_go_closure_unix64);
- closure->cif = cif;
- closure->fun = fun;
- return FFI_OK;
- }
- #endif /* __x86_64__ */
- ====================File: src/x86/ffitarget.h====================
- /* -----------------------------------------------------------------*-C-*-
- ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
- Copyright (c) 1996-2003, 2010 Red Hat, Inc.
- Copyright (C) 2008 Free Software Foundation, Inc.
- Target configuration macros for x86 and x86-64.
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- #ifndef LIBFFI_H
- #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
- #endif
- /* ---- System specific configurations ----------------------------------- */
- /* For code common to all platforms on x86 and x86_64. */
- #define X86_ANY
- #if defined (X86_64) && defined (__i386__)
- #undef X86_64
- #define X86
- #endif
- #ifdef X86_WIN64
- #define FFI_SIZEOF_ARG 8
- #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
- #endif
- #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
- #ifndef _MSC_VER
- #define FFI_TARGET_HAS_COMPLEX_TYPE
- #endif
- /* ---- Generic type definitions ----------------------------------------- */
- #ifndef LIBFFI_ASM
- #ifdef X86_WIN64
- #ifdef _MSC_VER
- typedef unsigned __int64 ffi_arg;
- typedef __int64 ffi_sarg;
- #else
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #endif
- #else
- #if defined __x86_64__ && defined __ILP32__
- #define FFI_SIZEOF_ARG 8
- #define FFI_SIZEOF_JAVA_RAW 4
- typedef unsigned long long ffi_arg;
- typedef long long ffi_sarg;
- #else
- typedef unsigned long ffi_arg;
- typedef signed long ffi_sarg;
- #endif
- #endif
- typedef enum ffi_abi {
- #if defined(X86_WIN64)
- FFI_FIRST_ABI = 0,
- FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
- FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
- FFI_LAST_ABI,
- #ifdef __GNUC__
- FFI_DEFAULT_ABI = FFI_GNUW64
- #else
- FFI_DEFAULT_ABI = FFI_WIN64
- #endif
- #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
- FFI_FIRST_ABI = 1,
- FFI_UNIX64,
- FFI_WIN64,
- FFI_EFI64 = FFI_WIN64,
- FFI_GNUW64,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_UNIX64
- #elif defined(X86_WIN32)
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_STDCALL = 2,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_MS_CDECL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_MS_CDECL
- #else
- FFI_FIRST_ABI = 0,
- FFI_SYSV = 1,
- FFI_THISCALL = 3,
- FFI_FASTCALL = 4,
- FFI_STDCALL = 5,
- FFI_PASCAL = 6,
- FFI_REGISTER = 7,
- FFI_MS_CDECL = 8,
- FFI_LAST_ABI,
- FFI_DEFAULT_ABI = FFI_SYSV
- #endif
- } ffi_abi;
- #endif
- /* ---- Definitions for closures ----------------------------------------- */
- #define FFI_CLOSURES 1
- #define FFI_GO_CLOSURES 1
- #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
- #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
- #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
- #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
- #if defined (X86_64) || defined(X86_WIN64) \
- || (defined (__x86_64__) && defined (X86_DARWIN))
- # define FFI_TRAMPOLINE_SIZE 24
- # define FFI_NATIVE_RAW_API 0
- #else
- # define FFI_TRAMPOLINE_SIZE 12
- # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
- #endif
- #endif
- ====================File: src/x86/ffiw64.c====================
- /* -----------------------------------------------------------------------
- ffiw64.c - Copyright (c) 2018 Anthony Green
- Copyright (c) 2014 Red Hat, Inc.
- x86 win64 Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #if defined(__x86_64__) || defined(_M_AMD64)
- #include <ffi.h>
- #include <ffi_common.h>
- #include <stdlib.h>
- #include <stdint.h>
- #ifdef X86_WIN64
- #define EFI64(name) name
- #else
- #define EFI64(name) FFI_HIDDEN name##_efi64
- #endif
- struct win64_call_frame
- {
- UINT64 rbp; /* 0 */
- UINT64 retaddr; /* 8 */
- UINT64 fn; /* 16 */
- UINT64 flags; /* 24 */
- UINT64 rvalue; /* 32 */
- };
- extern void ffi_call_win64 (void *stack, struct win64_call_frame *,
- void *closure) FFI_HIDDEN;
- ffi_status FFI_HIDDEN
- EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)
- {
- int flags, n;
- switch (cif->abi)
- {
- case FFI_WIN64:
- case FFI_GNUW64:
- break;
- default:
- return FFI_BAD_ABI;
- }
- flags = cif->rtype->type;
- switch (flags)
- {
- default:
- break;
- case FFI_TYPE_LONGDOUBLE:
- /* GCC returns long double values by reference, like a struct */
- if (cif->abi == FFI_GNUW64)
- flags = FFI_TYPE_STRUCT;
- break;
- case FFI_TYPE_COMPLEX:
- flags = FFI_TYPE_STRUCT;
- /* FALLTHRU */
- case FFI_TYPE_STRUCT:
- switch (cif->rtype->size)
- {
- case 8:
- flags = FFI_TYPE_UINT64;
- break;
- case 4:
- flags = FFI_TYPE_SMALL_STRUCT_4B;
- break;
- case 2:
- flags = FFI_TYPE_SMALL_STRUCT_2B;
- break;
- case 1:
- flags = FFI_TYPE_SMALL_STRUCT_1B;
- break;
- }
- break;
- }
- cif->flags = flags;
- /* Each argument either fits in a register, an 8 byte slot, or is
- passed by reference with the pointer in the 8 byte slot. */
- n = cif->nargs;
- n += (flags == FFI_TYPE_STRUCT);
- if (n < 4)
- n = 4;
- cif->bytes = n * 8;
- return FFI_OK;
- }
- static void
- ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
- void **avalue, void *closure)
- {
- int i, j, n, flags;
- UINT64 *stack;
- size_t rsize;
- struct win64_call_frame *frame;
- FFI_ASSERT(cif->abi == FFI_GNUW64 || cif->abi == FFI_WIN64);
- flags = cif->flags;
- rsize = 0;
- /* If we have no return value for a structure, we need to create one.
- Otherwise we can ignore the return type entirely. */
- if (rvalue == NULL)
- {
- if (flags == FFI_TYPE_STRUCT)
- rsize = cif->rtype->size;
- else
- flags = FFI_TYPE_VOID;
- }
- stack = alloca(cif->bytes + sizeof(struct win64_call_frame) + rsize);
- frame = (struct win64_call_frame *)((char *)stack + cif->bytes);
- if (rsize)
- rvalue = frame + 1;
- frame->fn = (uintptr_t)fn;
- frame->flags = flags;
- frame->rvalue = (uintptr_t)rvalue;
- j = 0;
- if (flags == FFI_TYPE_STRUCT)
- {
- stack[0] = (uintptr_t)rvalue;
- j = 1;
- }
- for (i = 0, n = cif->nargs; i < n; ++i, ++j)
- {
- switch (cif->arg_types[i]->size)
- {
- case 8:
- stack[j] = *(UINT64 *)avalue[i];
- break;
- case 4:
- stack[j] = *(UINT32 *)avalue[i];
- break;
- case 2:
- stack[j] = *(UINT16 *)avalue[i];
- break;
- case 1:
- stack[j] = *(UINT8 *)avalue[i];
- break;
- default:
- stack[j] = (uintptr_t)avalue[i];
- break;
- }
- }
- ffi_call_win64 (stack, frame, closure);
- }
- void
- EFI64(ffi_call)(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
- {
- ffi_call_int (cif, fn, rvalue, avalue, NULL);
- }
- void
- EFI64(ffi_call_go)(ffi_cif *cif, void (*fn)(void), void *rvalue,
- void **avalue, void *closure)
- {
- ffi_call_int (cif, fn, rvalue, avalue, closure);
- }
- extern void ffi_closure_win64(void) FFI_HIDDEN;
- extern void ffi_go_closure_win64(void) FFI_HIDDEN;
- ffi_status
- EFI64(ffi_prep_closure_loc)(ffi_closure* closure,
- ffi_cif* cif,
- void (*fun)(ffi_cif*, void*, void**, void*),
- void *user_data,
- void *codeloc)
- {
- static const unsigned char trampoline[16] = {
- /* leaq -0x7(%rip),%r10 # 0x0 */
- 0x4c, 0x8d, 0x15, 0xf9, 0xff, 0xff, 0xff,
- /* jmpq *0x3(%rip) # 0x10 */
- 0xff, 0x25, 0x03, 0x00, 0x00, 0x00,
- /* nopl (%rax) */
- 0x0f, 0x1f, 0x00
- };
- char *tramp = closure->tramp;
- switch (cif->abi)
- {
- case FFI_WIN64:
- case FFI_GNUW64:
- break;
- default:
- return FFI_BAD_ABI;
- }
- memcpy (tramp, trampoline, sizeof(trampoline));
- *(UINT64 *)(tramp + 16) = (uintptr_t)ffi_closure_win64;
- closure->cif = cif;
- closure->fun = fun;
- closure->user_data = user_data;
- return FFI_OK;
- }
- ffi_status
- EFI64(ffi_prep_go_closure)(ffi_go_closure* closure, ffi_cif* cif,
- void (*fun)(ffi_cif*, void*, void**, void*))
- {
- switch (cif->abi)
- {
- case FFI_WIN64:
- case FFI_GNUW64:
- break;
- default:
- return FFI_BAD_ABI;
- }
- closure->tramp = ffi_go_closure_win64;
- closure->cif = cif;
- closure->fun = fun;
- return FFI_OK;
- }
- struct win64_closure_frame
- {
- UINT64 rvalue[2];
- UINT64 fargs[4];
- UINT64 retaddr;
- UINT64 args[];
- };
- /* Force the inner function to use the MS ABI. When compiling on win64
- this is a nop. When compiling on unix, this simplifies the assembly,
- and places the burden of saving the extra call-saved registers on
- the compiler. */
- int FFI_HIDDEN __attribute__((ms_abi))
- ffi_closure_win64_inner(ffi_cif *cif,
- void (*fun)(ffi_cif*, void*, void**, void*),
- void *user_data,
- struct win64_closure_frame *frame)
- {
- void **avalue;
- void *rvalue;
- int i, n, nreg, flags;
- avalue = alloca(cif->nargs * sizeof(void *));
- rvalue = frame->rvalue;
- nreg = 0;
- /* When returning a structure, the address is in the first argument.
- We must also be prepared to return the same address in eax, so
- install that address in the frame and pretend we return a pointer. */
- flags = cif->flags;
- if (flags == FFI_TYPE_STRUCT)
- {
- rvalue = (void *)(uintptr_t)frame->args[0];
- frame->rvalue[0] = frame->args[0];
- nreg = 1;
- }
- for (i = 0, n = cif->nargs; i < n; ++i, ++nreg)
- {
- size_t size = cif->arg_types[i]->size;
- size_t type = cif->arg_types[i]->type;
- void *a;
- if (type == FFI_TYPE_DOUBLE || type == FFI_TYPE_FLOAT)
- {
- if (nreg < 4)
- a = &frame->fargs[nreg];
- else
- a = &frame->args[nreg];
- }
- else if (size == 1 || size == 2 || size == 4 || size == 8)
- a = &frame->args[nreg];
- else
- a = (void *)(uintptr_t)frame->args[nreg];
- avalue[i] = a;
- }
- /* Invoke the closure. */
- fun (cif, rvalue, avalue, user_data);
- return flags;
- }
- #endif /* __x86_64__ */
- ====================File: src/x86/sysv.S====================
- /* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 2017 Anthony Green
- - Copyright (c) 2013 The Written Word, Inc.
- - Copyright (c) 1996,1998,2001-2003,2005,2008,2010 Red Hat, Inc.
-
- X86 Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifdef __i386__
- #ifndef _MSC_VER
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #include "internal.h"
- #define C2(X, Y) X ## Y
- #define C1(X, Y) C2(X, Y)
- #ifdef __USER_LABEL_PREFIX__
- # define C(X) C1(__USER_LABEL_PREFIX__, X)
- #else
- # define C(X) X
- #endif
- #ifdef X86_DARWIN
- # define L(X) C1(L, X)
- #else
- # define L(X) C1(.L, X)
- #endif
- #ifdef __ELF__
- # define ENDF(X) .type X,@function; .size X, . - X
- #else
- # define ENDF(X)
- #endif
- /* Handle win32 fastcall name mangling. */
- #ifdef X86_WIN32
- # define ffi_call_i386 @ffi_call_i386@8
- # define ffi_closure_inner @ffi_closure_inner@8
- #else
- # define ffi_call_i386 C(ffi_call_i386)
- # define ffi_closure_inner C(ffi_closure_inner)
- #endif
- /* This macro allows the safe creation of jump tables without an
- actual table. The entry points into the table are all 8 bytes.
- The use of ORG asserts that we're at the correct location. */
- /* ??? The clang assembler doesn't handle .org with symbolic expressions. */
- #if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
- # define E(BASE, X) .balign 8
- #else
- # define E(BASE, X) .balign 8; .org BASE + X * 8
- #endif
- .text
- .balign 16
- .globl ffi_call_i386
- FFI_HIDDEN(ffi_call_i386)
- /* This is declared as
- void ffi_call_i386(struct call_frame *frame, char *argp)
- __attribute__((fastcall));
- Thus the arguments are present in
- ecx: frame
- edx: argp
- */
- ffi_call_i386:
- L(UW0):
- # cfi_startproc
- #if !HAVE_FASTCALL
- movl 4(%esp), %ecx
- movl 8(%esp), %edx
- #endif
- movl (%esp), %eax /* move the return address */
- movl %ebp, (%ecx) /* store %ebp into local frame */
- movl %eax, 4(%ecx) /* store retaddr into local frame */
- /* New stack frame based off ebp. This is a itty bit of unwind
- trickery in that the CFA *has* changed. There is no easy way
- to describe it correctly on entry to the function. Fortunately,
- it doesn't matter too much since at all points we can correctly
- unwind back to ffi_call. Note that the location to which we
- moved the return address is (the new) CFA-4, so from the
- perspective of the unwind info, it hasn't moved. */
- movl %ecx, %ebp
- L(UW1):
- # cfi_def_cfa(%ebp, 8)
- # cfi_rel_offset(%ebp, 0)
- movl %edx, %esp /* set outgoing argument stack */
- movl 20+R_EAX*4(%ebp), %eax /* set register arguments */
- movl 20+R_EDX*4(%ebp), %edx
- movl 20+R_ECX*4(%ebp), %ecx
- call *8(%ebp)
- movl 12(%ebp), %ecx /* load return type code */
- movl %ebx, 8(%ebp) /* preserve %ebx */
- L(UW2):
- # cfi_rel_offset(%ebx, 8)
- andl $X86_RET_TYPE_MASK, %ecx
- #ifdef __PIC__
- call C(__x86.get_pc_thunk.bx)
- L(pc1):
- leal L(store_table)-L(pc1)(%ebx, %ecx, 8), %ebx
- #else
- leal L(store_table)(,%ecx, 8), %ebx
- #endif
- movl 16(%ebp), %ecx /* load result address */
- jmp *%ebx
- .balign 8
- L(store_table):
- E(L(store_table), X86_RET_FLOAT)
- fstps (%ecx)
- jmp L(e1)
- E(L(store_table), X86_RET_DOUBLE)
- fstpl (%ecx)
- jmp L(e1)
- E(L(store_table), X86_RET_LDOUBLE)
- fstpt (%ecx)
- jmp L(e1)
- E(L(store_table), X86_RET_SINT8)
- movsbl %al, %eax
- mov %eax, (%ecx)
- jmp L(e1)
- E(L(store_table), X86_RET_SINT16)
- movswl %ax, %eax
- mov %eax, (%ecx)
- jmp L(e1)
- E(L(store_table), X86_RET_UINT8)
- movzbl %al, %eax
- mov %eax, (%ecx)
- jmp L(e1)
- E(L(store_table), X86_RET_UINT16)
- movzwl %ax, %eax
- mov %eax, (%ecx)
- jmp L(e1)
- E(L(store_table), X86_RET_INT64)
- movl %edx, 4(%ecx)
- /* fallthru */
- E(L(store_table), X86_RET_INT32)
- movl %eax, (%ecx)
- /* fallthru */
- E(L(store_table), X86_RET_VOID)
- L(e1):
- movl 8(%ebp), %ebx
- movl %ebp, %esp
- popl %ebp
- L(UW3):
- # cfi_remember_state
- # cfi_def_cfa(%esp, 4)
- # cfi_restore(%ebx)
- # cfi_restore(%ebp)
- ret
- L(UW4):
- # cfi_restore_state
- E(L(store_table), X86_RET_STRUCTPOP)
- jmp L(e1)
- E(L(store_table), X86_RET_STRUCTARG)
- jmp L(e1)
- E(L(store_table), X86_RET_STRUCT_1B)
- movb %al, (%ecx)
- jmp L(e1)
- E(L(store_table), X86_RET_STRUCT_2B)
- movw %ax, (%ecx)
- jmp L(e1)
- /* Fill out the table so that bad values are predictable. */
- E(L(store_table), X86_RET_UNUSED14)
- ud2
- E(L(store_table), X86_RET_UNUSED15)
- ud2
- L(UW5):
- # cfi_endproc
- ENDF(ffi_call_i386)
- /* The inner helper is declared as
- void ffi_closure_inner(struct closure_frame *frame, char *argp)
- __attribute_((fastcall))
- Thus the arguments are placed in
- ecx: frame
- edx: argp
- */
- /* Macros to help setting up the closure_data structure. */
- #if HAVE_FASTCALL
- # define closure_FS (40 + 4)
- # define closure_CF 0
- #else
- # define closure_FS (8 + 40 + 12)
- # define closure_CF 8
- #endif
- #define FFI_CLOSURE_SAVE_REGS \
- movl %eax, closure_CF+16+R_EAX*4(%esp); \
- movl %edx, closure_CF+16+R_EDX*4(%esp); \
- movl %ecx, closure_CF+16+R_ECX*4(%esp)
- #define FFI_CLOSURE_COPY_TRAMP_DATA \
- movl FFI_TRAMPOLINE_SIZE(%eax), %edx; /* copy cif */ \
- movl FFI_TRAMPOLINE_SIZE+4(%eax), %ecx; /* copy fun */ \
- movl FFI_TRAMPOLINE_SIZE+8(%eax), %eax; /* copy user_data */ \
- movl %edx, closure_CF+28(%esp); \
- movl %ecx, closure_CF+32(%esp); \
- movl %eax, closure_CF+36(%esp)
- #if HAVE_FASTCALL
- # define FFI_CLOSURE_PREP_CALL \
- movl %esp, %ecx; /* load closure_data */ \
- leal closure_FS+4(%esp), %edx; /* load incoming stack */
- #else
- # define FFI_CLOSURE_PREP_CALL \
- leal closure_CF(%esp), %ecx; /* load closure_data */ \
- leal closure_FS+4(%esp), %edx; /* load incoming stack */ \
- movl %ecx, (%esp); \
- movl %edx, 4(%esp)
- #endif
- #define FFI_CLOSURE_CALL_INNER(UWN) \
- call ffi_closure_inner
- #define FFI_CLOSURE_MASK_AND_JUMP(N, UW) \
- andl $X86_RET_TYPE_MASK, %eax; \
- leal L(C1(load_table,N))(, %eax, 8), %edx; \
- movl closure_CF(%esp), %eax; /* optimiztic load */ \
- jmp *%edx
- #ifdef __PIC__
- # if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
- # undef FFI_CLOSURE_MASK_AND_JUMP
- # define FFI_CLOSURE_MASK_AND_JUMP(N, UW) \
- andl $X86_RET_TYPE_MASK, %eax; \
- call C(__x86.get_pc_thunk.dx); \
- L(C1(pc,N)): \
- leal L(C1(load_table,N))-L(C1(pc,N))(%edx, %eax, 8), %edx; \
- movl closure_CF(%esp), %eax; /* optimiztic load */ \
- jmp *%edx
- # else
- # define FFI_CLOSURE_CALL_INNER_SAVE_EBX
- # undef FFI_CLOSURE_CALL_INNER
- # define FFI_CLOSURE_CALL_INNER(UWN) \
- movl %ebx, 40(%esp); /* save ebx */ \
- L(C1(UW,UWN)): \
- /* cfi_rel_offset(%ebx, 40); */ \
- call C(__x86.get_pc_thunk.bx); /* load got register */ \
- addl $C(_GLOBAL_OFFSET_TABLE_), %ebx; \
- call ffi_closure_inner@PLT
- # undef FFI_CLOSURE_MASK_AND_JUMP
- # define FFI_CLOSURE_MASK_AND_JUMP(N, UWN) \
- andl $X86_RET_TYPE_MASK, %eax; \
- leal L(C1(load_table,N))@GOTOFF(%ebx, %eax, 8), %edx; \
- movl 40(%esp), %ebx; /* restore ebx */ \
- L(C1(UW,UWN)): \
- /* cfi_restore(%ebx); */ \
- movl closure_CF(%esp), %eax; /* optimiztic load */ \
- jmp *%edx
- # endif /* DARWIN || HIDDEN */
- #endif /* __PIC__ */
- .balign 16
- .globl C(ffi_go_closure_EAX)
- FFI_HIDDEN(C(ffi_go_closure_EAX))
- C(ffi_go_closure_EAX):
- L(UW6):
- # cfi_startproc
- subl $closure_FS, %esp
- L(UW7):
- # cfi_def_cfa_offset(closure_FS + 4)
- FFI_CLOSURE_SAVE_REGS
- movl 4(%eax), %edx /* copy cif */
- movl 8(%eax), %ecx /* copy fun */
- movl %edx, closure_CF+28(%esp)
- movl %ecx, closure_CF+32(%esp)
- movl %eax, closure_CF+36(%esp) /* closure is user_data */
- jmp L(do_closure_i386)
- L(UW8):
- # cfi_endproc
- ENDF(C(ffi_go_closure_EAX))
- .balign 16
- .globl C(ffi_go_closure_ECX)
- FFI_HIDDEN(C(ffi_go_closure_ECX))
- C(ffi_go_closure_ECX):
- L(UW9):
- # cfi_startproc
- subl $closure_FS, %esp
- L(UW10):
- # cfi_def_cfa_offset(closure_FS + 4)
- FFI_CLOSURE_SAVE_REGS
- movl 4(%ecx), %edx /* copy cif */
- movl 8(%ecx), %eax /* copy fun */
- movl %edx, closure_CF+28(%esp)
- movl %eax, closure_CF+32(%esp)
- movl %ecx, closure_CF+36(%esp) /* closure is user_data */
- jmp L(do_closure_i386)
- L(UW11):
- # cfi_endproc
- ENDF(C(ffi_go_closure_ECX))
- /* The closure entry points are reached from the ffi_closure trampoline.
- On entry, %eax contains the address of the ffi_closure. */
- .balign 16
- .globl C(ffi_closure_i386)
- FFI_HIDDEN(C(ffi_closure_i386))
- C(ffi_closure_i386):
- L(UW12):
- # cfi_startproc
- subl $closure_FS, %esp
- L(UW13):
- # cfi_def_cfa_offset(closure_FS + 4)
- FFI_CLOSURE_SAVE_REGS
- FFI_CLOSURE_COPY_TRAMP_DATA
- /* Entry point from preceeding Go closures. */
- L(do_closure_i386):
- FFI_CLOSURE_PREP_CALL
- FFI_CLOSURE_CALL_INNER(14)
- FFI_CLOSURE_MASK_AND_JUMP(2, 15)
- .balign 8
- L(load_table2):
- E(L(load_table2), X86_RET_FLOAT)
- flds closure_CF(%esp)
- jmp L(e2)
- E(L(load_table2), X86_RET_DOUBLE)
- fldl closure_CF(%esp)
- jmp L(e2)
- E(L(load_table2), X86_RET_LDOUBLE)
- fldt closure_CF(%esp)
- jmp L(e2)
- E(L(load_table2), X86_RET_SINT8)
- movsbl %al, %eax
- jmp L(e2)
- E(L(load_table2), X86_RET_SINT16)
- movswl %ax, %eax
- jmp L(e2)
- E(L(load_table2), X86_RET_UINT8)
- movzbl %al, %eax
- jmp L(e2)
- E(L(load_table2), X86_RET_UINT16)
- movzwl %ax, %eax
- jmp L(e2)
- E(L(load_table2), X86_RET_INT64)
- movl closure_CF+4(%esp), %edx
- jmp L(e2)
- E(L(load_table2), X86_RET_INT32)
- nop
- /* fallthru */
- E(L(load_table2), X86_RET_VOID)
- L(e2):
- addl $closure_FS, %esp
- L(UW16):
- # cfi_adjust_cfa_offset(-closure_FS)
- ret
- L(UW17):
- # cfi_adjust_cfa_offset(closure_FS)
- E(L(load_table2), X86_RET_STRUCTPOP)
- addl $closure_FS, %esp
- L(UW18):
- # cfi_adjust_cfa_offset(-closure_FS)
- ret $4
- L(UW19):
- # cfi_adjust_cfa_offset(closure_FS)
- E(L(load_table2), X86_RET_STRUCTARG)
- jmp L(e2)
- E(L(load_table2), X86_RET_STRUCT_1B)
- movzbl %al, %eax
- jmp L(e2)
- E(L(load_table2), X86_RET_STRUCT_2B)
- movzwl %ax, %eax
- jmp L(e2)
- /* Fill out the table so that bad values are predictable. */
- E(L(load_table2), X86_RET_UNUSED14)
- ud2
- E(L(load_table2), X86_RET_UNUSED15)
- ud2
- L(UW20):
- # cfi_endproc
- ENDF(C(ffi_closure_i386))
- .balign 16
- .globl C(ffi_go_closure_STDCALL)
- FFI_HIDDEN(C(ffi_go_closure_STDCALL))
- C(ffi_go_closure_STDCALL):
- L(UW21):
- # cfi_startproc
- subl $closure_FS, %esp
- L(UW22):
- # cfi_def_cfa_offset(closure_FS + 4)
- FFI_CLOSURE_SAVE_REGS
- movl 4(%ecx), %edx /* copy cif */
- movl 8(%ecx), %eax /* copy fun */
- movl %edx, closure_CF+28(%esp)
- movl %eax, closure_CF+32(%esp)
- movl %ecx, closure_CF+36(%esp) /* closure is user_data */
- jmp L(do_closure_STDCALL)
- L(UW23):
- # cfi_endproc
- ENDF(C(ffi_go_closure_STDCALL))
- /* For REGISTER, we have no available parameter registers, and so we
- enter here having pushed the closure onto the stack. */
- .balign 16
- .globl C(ffi_closure_REGISTER)
- FFI_HIDDEN(C(ffi_closure_REGISTER))
- C(ffi_closure_REGISTER):
- L(UW24):
- # cfi_startproc
- # cfi_def_cfa(%esp, 8)
- # cfi_offset(%eip, -8)
- subl $closure_FS-4, %esp
- L(UW25):
- # cfi_def_cfa_offset(closure_FS + 4)
- FFI_CLOSURE_SAVE_REGS
- movl closure_FS-4(%esp), %ecx /* load retaddr */
- movl closure_FS(%esp), %eax /* load closure */
- movl %ecx, closure_FS(%esp) /* move retaddr */
- jmp L(do_closure_REGISTER)
- L(UW26):
- # cfi_endproc
- ENDF(C(ffi_closure_REGISTER))
- /* For STDCALL (and others), we need to pop N bytes of arguments off
- the stack following the closure. The amount needing to be popped
- is returned to us from ffi_closure_inner. */
- .balign 16
- .globl C(ffi_closure_STDCALL)
- FFI_HIDDEN(C(ffi_closure_STDCALL))
- C(ffi_closure_STDCALL):
- L(UW27):
- # cfi_startproc
- subl $closure_FS, %esp
- L(UW28):
- # cfi_def_cfa_offset(closure_FS + 4)
- FFI_CLOSURE_SAVE_REGS
- /* Entry point from ffi_closure_REGISTER. */
- L(do_closure_REGISTER):
- FFI_CLOSURE_COPY_TRAMP_DATA
- /* Entry point from preceeding Go closure. */
- L(do_closure_STDCALL):
- FFI_CLOSURE_PREP_CALL
- FFI_CLOSURE_CALL_INNER(29)
- movl %eax, %ecx
- shrl $X86_RET_POP_SHIFT, %ecx /* isolate pop count */
- leal closure_FS(%esp, %ecx), %ecx /* compute popped esp */
- movl closure_FS(%esp), %edx /* move return address */
- movl %edx, (%ecx)
- /* From this point on, the value of %esp upon return is %ecx+4,
- and we've copied the return address to %ecx to make return easy.
- There's no point in representing this in the unwind info, as
- there is always a window between the mov and the ret which
- will be wrong from one point of view or another. */
- FFI_CLOSURE_MASK_AND_JUMP(3, 30)
- .balign 8
- L(load_table3):
- E(L(load_table3), X86_RET_FLOAT)
- flds closure_CF(%esp)
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_DOUBLE)
- fldl closure_CF(%esp)
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_LDOUBLE)
- fldt closure_CF(%esp)
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_SINT8)
- movsbl %al, %eax
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_SINT16)
- movswl %ax, %eax
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_UINT8)
- movzbl %al, %eax
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_UINT16)
- movzwl %ax, %eax
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_INT64)
- movl closure_CF+4(%esp), %edx
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_INT32)
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_VOID)
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_STRUCTPOP)
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_STRUCTARG)
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_STRUCT_1B)
- movzbl %al, %eax
- movl %ecx, %esp
- ret
- E(L(load_table3), X86_RET_STRUCT_2B)
- movzwl %ax, %eax
- movl %ecx, %esp
- ret
- /* Fill out the table so that bad values are predictable. */
- E(L(load_table3), X86_RET_UNUSED14)
- ud2
- E(L(load_table3), X86_RET_UNUSED15)
- ud2
- L(UW31):
- # cfi_endproc
- ENDF(C(ffi_closure_STDCALL))
- #if !FFI_NO_RAW_API
- #define raw_closure_S_FS (16+16+12)
- .balign 16
- .globl C(ffi_closure_raw_SYSV)
- FFI_HIDDEN(C(ffi_closure_raw_SYSV))
- C(ffi_closure_raw_SYSV):
- L(UW32):
- # cfi_startproc
- subl $raw_closure_S_FS, %esp
- L(UW33):
- # cfi_def_cfa_offset(raw_closure_S_FS + 4)
- movl %ebx, raw_closure_S_FS-4(%esp)
- L(UW34):
- # cfi_rel_offset(%ebx, raw_closure_S_FS-4)
- movl FFI_TRAMPOLINE_SIZE+8(%eax), %edx /* load cl->user_data */
- movl %edx, 12(%esp)
- leal raw_closure_S_FS+4(%esp), %edx /* load raw_args */
- movl %edx, 8(%esp)
- leal 16(%esp), %edx /* load &res */
- movl %edx, 4(%esp)
- movl FFI_TRAMPOLINE_SIZE(%eax), %ebx /* load cl->cif */
- movl %ebx, (%esp)
- call *FFI_TRAMPOLINE_SIZE+4(%eax) /* call cl->fun */
- movl 20(%ebx), %eax /* load cif->flags */
- andl $X86_RET_TYPE_MASK, %eax
- #ifdef __PIC__
- call C(__x86.get_pc_thunk.bx)
- L(pc4):
- leal L(load_table4)-L(pc4)(%ebx, %eax, 8), %ecx
- #else
- leal L(load_table4)(,%eax, 8), %ecx
- #endif
- movl raw_closure_S_FS-4(%esp), %ebx
- L(UW35):
- # cfi_restore(%ebx)
- movl 16(%esp), %eax /* Optimistic load */
- jmp *%ecx
- .balign 8
- L(load_table4):
- E(L(load_table4), X86_RET_FLOAT)
- flds 16(%esp)
- jmp L(e4)
- E(L(load_table4), X86_RET_DOUBLE)
- fldl 16(%esp)
- jmp L(e4)
- E(L(load_table4), X86_RET_LDOUBLE)
- fldt 16(%esp)
- jmp L(e4)
- E(L(load_table4), X86_RET_SINT8)
- movsbl %al, %eax
- jmp L(e4)
- E(L(load_table4), X86_RET_SINT16)
- movswl %ax, %eax
- jmp L(e4)
- E(L(load_table4), X86_RET_UINT8)
- movzbl %al, %eax
- jmp L(e4)
- E(L(load_table4), X86_RET_UINT16)
- movzwl %ax, %eax
- jmp L(e4)
- E(L(load_table4), X86_RET_INT64)
- movl 16+4(%esp), %edx
- jmp L(e4)
- E(L(load_table4), X86_RET_INT32)
- nop
- /* fallthru */
- E(L(load_table4), X86_RET_VOID)
- L(e4):
- addl $raw_closure_S_FS, %esp
- L(UW36):
- # cfi_adjust_cfa_offset(-raw_closure_S_FS)
- ret
- L(UW37):
- # cfi_adjust_cfa_offset(raw_closure_S_FS)
- E(L(load_table4), X86_RET_STRUCTPOP)
- addl $raw_closure_S_FS, %esp
- L(UW38):
- # cfi_adjust_cfa_offset(-raw_closure_S_FS)
- ret $4
- L(UW39):
- # cfi_adjust_cfa_offset(raw_closure_S_FS)
- E(L(load_table4), X86_RET_STRUCTARG)
- jmp L(e4)
- E(L(load_table4), X86_RET_STRUCT_1B)
- movzbl %al, %eax
- jmp L(e4)
- E(L(load_table4), X86_RET_STRUCT_2B)
- movzwl %ax, %eax
- jmp L(e4)
- /* Fill out the table so that bad values are predictable. */
- E(L(load_table4), X86_RET_UNUSED14)
- ud2
- E(L(load_table4), X86_RET_UNUSED15)
- ud2
- L(UW40):
- # cfi_endproc
- ENDF(C(ffi_closure_raw_SYSV))
- #define raw_closure_T_FS (16+16+8)
- .balign 16
- .globl C(ffi_closure_raw_THISCALL)
- FFI_HIDDEN(C(ffi_closure_raw_THISCALL))
- C(ffi_closure_raw_THISCALL):
- L(UW41):
- # cfi_startproc
- /* Rearrange the stack such that %ecx is the first argument.
- This means moving the return address. */
- popl %edx
- L(UW42):
- # cfi_def_cfa_offset(0)
- # cfi_register(%eip, %edx)
- pushl %ecx
- L(UW43):
- # cfi_adjust_cfa_offset(4)
- pushl %edx
- L(UW44):
- # cfi_adjust_cfa_offset(4)
- # cfi_rel_offset(%eip, 0)
- subl $raw_closure_T_FS, %esp
- L(UW45):
- # cfi_adjust_cfa_offset(raw_closure_T_FS)
- movl %ebx, raw_closure_T_FS-4(%esp)
- L(UW46):
- # cfi_rel_offset(%ebx, raw_closure_T_FS-4)
- movl FFI_TRAMPOLINE_SIZE+8(%eax), %edx /* load cl->user_data */
- movl %edx, 12(%esp)
- leal raw_closure_T_FS+4(%esp), %edx /* load raw_args */
- movl %edx, 8(%esp)
- leal 16(%esp), %edx /* load &res */
- movl %edx, 4(%esp)
- movl FFI_TRAMPOLINE_SIZE(%eax), %ebx /* load cl->cif */
- movl %ebx, (%esp)
- call *FFI_TRAMPOLINE_SIZE+4(%eax) /* call cl->fun */
- movl 20(%ebx), %eax /* load cif->flags */
- andl $X86_RET_TYPE_MASK, %eax
- #ifdef __PIC__
- call C(__x86.get_pc_thunk.bx)
- L(pc5):
- leal L(load_table5)-L(pc5)(%ebx, %eax, 8), %ecx
- #else
- leal L(load_table5)(,%eax, 8), %ecx
- #endif
- movl raw_closure_T_FS-4(%esp), %ebx
- L(UW47):
- # cfi_restore(%ebx)
- movl 16(%esp), %eax /* Optimistic load */
- jmp *%ecx
- .balign 8
- L(load_table5):
- E(L(load_table5), X86_RET_FLOAT)
- flds 16(%esp)
- jmp L(e5)
- E(L(load_table5), X86_RET_DOUBLE)
- fldl 16(%esp)
- jmp L(e5)
- E(L(load_table5), X86_RET_LDOUBLE)
- fldt 16(%esp)
- jmp L(e5)
- E(L(load_table5), X86_RET_SINT8)
- movsbl %al, %eax
- jmp L(e5)
- E(L(load_table5), X86_RET_SINT16)
- movswl %ax, %eax
- jmp L(e5)
- E(L(load_table5), X86_RET_UINT8)
- movzbl %al, %eax
- jmp L(e5)
- E(L(load_table5), X86_RET_UINT16)
- movzwl %ax, %eax
- jmp L(e5)
- E(L(load_table5), X86_RET_INT64)
- movl 16+4(%esp), %edx
- jmp L(e5)
- E(L(load_table5), X86_RET_INT32)
- nop
- /* fallthru */
- E(L(load_table5), X86_RET_VOID)
- L(e5):
- addl $raw_closure_T_FS, %esp
- L(UW48):
- # cfi_adjust_cfa_offset(-raw_closure_T_FS)
- /* Remove the extra %ecx argument we pushed. */
- ret $4
- L(UW49):
- # cfi_adjust_cfa_offset(raw_closure_T_FS)
- E(L(load_table5), X86_RET_STRUCTPOP)
- addl $raw_closure_T_FS, %esp
- L(UW50):
- # cfi_adjust_cfa_offset(-raw_closure_T_FS)
- ret $8
- L(UW51):
- # cfi_adjust_cfa_offset(raw_closure_T_FS)
- E(L(load_table5), X86_RET_STRUCTARG)
- jmp L(e5)
- E(L(load_table5), X86_RET_STRUCT_1B)
- movzbl %al, %eax
- jmp L(e5)
- E(L(load_table5), X86_RET_STRUCT_2B)
- movzwl %ax, %eax
- jmp L(e5)
- /* Fill out the table so that bad values are predictable. */
- E(L(load_table5), X86_RET_UNUSED14)
- ud2
- E(L(load_table5), X86_RET_UNUSED15)
- ud2
- L(UW52):
- # cfi_endproc
- ENDF(C(ffi_closure_raw_THISCALL))
- #endif /* !FFI_NO_RAW_API */
- #ifdef X86_DARWIN
- # define COMDAT(X) \
- .section __TEXT,__text,coalesced,pure_instructions; \
- .weak_definition X; \
- FFI_HIDDEN(X)
- #elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__))
- # define COMDAT(X) \
- .section .text.X,"axG",@progbits,X,comdat; \
- .globl X; \
- FFI_HIDDEN(X)
- #else
- # define COMDAT(X)
- #endif
- #if defined(__PIC__)
- COMDAT(C(__x86.get_pc_thunk.bx))
- C(__x86.get_pc_thunk.bx):
- movl (%esp), %ebx
- ret
- ENDF(C(__x86.get_pc_thunk.bx))
- # if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
- COMDAT(C(__x86.get_pc_thunk.dx))
- C(__x86.get_pc_thunk.dx):
- movl (%esp), %edx
- ret
- ENDF(C(__x86.get_pc_thunk.dx))
- #endif /* DARWIN || HIDDEN */
- #endif /* __PIC__ */
- /* Sadly, OSX cctools-as doesn't understand .cfi directives at all. */
- #ifdef __APPLE__
- .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
- EHFrame0:
- #elif defined(X86_WIN32)
- .section .eh_frame,"r"
- #elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)
- .section .eh_frame,EH_FRAME_FLAGS,@unwind
- #else
- .section .eh_frame,EH_FRAME_FLAGS,@progbits
- #endif
- #ifdef HAVE_AS_X86_PCREL
- # define PCREL(X) X - .
- #else
- # define PCREL(X) X@rel
- #endif
- /* Simplify advancing between labels. Assume DW_CFA_advance_loc1 fits. */
- #define ADV(N, P) .byte 2, L(N)-L(P)
- .balign 4
- L(CIE):
- .set L(set0),L(ECIE)-L(SCIE)
- .long L(set0) /* CIE Length */
- L(SCIE):
- .long 0 /* CIE Identifier Tag */
- .byte 1 /* CIE Version */
- .ascii "zR\0" /* CIE Augmentation */
- .byte 1 /* CIE Code Alignment Factor */
- .byte 0x7c /* CIE Data Alignment Factor */
- .byte 0x8 /* CIE RA Column */
- .byte 1 /* Augmentation size */
- .byte 0x1b /* FDE Encoding (pcrel sdata4) */
- .byte 0xc, 4, 4 /* DW_CFA_def_cfa, %esp offset 4 */
- .byte 0x80+8, 1 /* DW_CFA_offset, %eip offset 1*-4 */
- .balign 4
- L(ECIE):
- .set L(set1),L(EFDE1)-L(SFDE1)
- .long L(set1) /* FDE Length */
- L(SFDE1):
- .long L(SFDE1)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW0)) /* Initial location */
- .long L(UW5)-L(UW0) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW1, UW0)
- .byte 0xc, 5, 8 /* DW_CFA_def_cfa, %ebp 8 */
- .byte 0x80+5, 2 /* DW_CFA_offset, %ebp 2*-4 */
- ADV(UW2, UW1)
- .byte 0x80+3, 0 /* DW_CFA_offset, %ebx 0*-4 */
- ADV(UW3, UW2)
- .byte 0xa /* DW_CFA_remember_state */
- .byte 0xc, 4, 4 /* DW_CFA_def_cfa, %esp 4 */
- .byte 0xc0+3 /* DW_CFA_restore, %ebx */
- .byte 0xc0+5 /* DW_CFA_restore, %ebp */
- ADV(UW4, UW3)
- .byte 0xb /* DW_CFA_restore_state */
- .balign 4
- L(EFDE1):
- .set L(set2),L(EFDE2)-L(SFDE2)
- .long L(set2) /* FDE Length */
- L(SFDE2):
- .long L(SFDE2)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW6)) /* Initial location */
- .long L(UW8)-L(UW6) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW7, UW6)
- .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */
- .balign 4
- L(EFDE2):
- .set L(set3),L(EFDE3)-L(SFDE3)
- .long L(set3) /* FDE Length */
- L(SFDE3):
- .long L(SFDE3)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW9)) /* Initial location */
- .long L(UW11)-L(UW9) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW10, UW9)
- .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */
- .balign 4
- L(EFDE3):
- .set L(set4),L(EFDE4)-L(SFDE4)
- .long L(set4) /* FDE Length */
- L(SFDE4):
- .long L(SFDE4)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW12)) /* Initial location */
- .long L(UW20)-L(UW12) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW13, UW12)
- .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */
- #ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX
- ADV(UW14, UW13)
- .byte 0x80+3, (40-(closure_FS+4))/-4 /* DW_CFA_offset %ebx */
- ADV(UW15, UW14)
- .byte 0xc0+3 /* DW_CFA_restore %ebx */
- ADV(UW16, UW15)
- #else
- ADV(UW16, UW13)
- #endif
- .byte 0xe, 4 /* DW_CFA_def_cfa_offset */
- ADV(UW17, UW16)
- .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */
- ADV(UW18, UW17)
- .byte 0xe, 4 /* DW_CFA_def_cfa_offset */
- ADV(UW19, UW18)
- .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */
- .balign 4
- L(EFDE4):
- .set L(set5),L(EFDE5)-L(SFDE5)
- .long L(set5) /* FDE Length */
- L(SFDE5):
- .long L(SFDE5)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW21)) /* Initial location */
- .long L(UW23)-L(UW21) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW22, UW21)
- .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */
- .balign 4
- L(EFDE5):
- .set L(set6),L(EFDE6)-L(SFDE6)
- .long L(set6) /* FDE Length */
- L(SFDE6):
- .long L(SFDE6)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW24)) /* Initial location */
- .long L(UW26)-L(UW24) /* Address range */
- .byte 0 /* Augmentation size */
- .byte 0xe, 8 /* DW_CFA_def_cfa_offset */
- .byte 0x80+8, 2 /* DW_CFA_offset %eip, 2*-4 */
- ADV(UW25, UW24)
- .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */
- .balign 4
- L(EFDE6):
- .set L(set7),L(EFDE7)-L(SFDE7)
- .long L(set7) /* FDE Length */
- L(SFDE7):
- .long L(SFDE7)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW27)) /* Initial location */
- .long L(UW31)-L(UW27) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW28, UW27)
- .byte 0xe, closure_FS+4 /* DW_CFA_def_cfa_offset */
- #ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX
- ADV(UW29, UW28)
- .byte 0x80+3, (40-(closure_FS+4))/-4 /* DW_CFA_offset %ebx */
- ADV(UW30, UW29)
- .byte 0xc0+3 /* DW_CFA_restore %ebx */
- #endif
- .balign 4
- L(EFDE7):
- #if !FFI_NO_RAW_API
- .set L(set8),L(EFDE8)-L(SFDE8)
- .long L(set8) /* FDE Length */
- L(SFDE8):
- .long L(SFDE8)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW32)) /* Initial location */
- .long L(UW40)-L(UW32) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW33, UW32)
- .byte 0xe, raw_closure_S_FS+4 /* DW_CFA_def_cfa_offset */
- ADV(UW34, UW33)
- .byte 0x80+3, 2 /* DW_CFA_offset %ebx 2*-4 */
- ADV(UW35, UW34)
- .byte 0xc0+3 /* DW_CFA_restore %ebx */
- ADV(UW36, UW35)
- .byte 0xe, 4 /* DW_CFA_def_cfa_offset */
- ADV(UW37, UW36)
- .byte 0xe, raw_closure_S_FS+4 /* DW_CFA_def_cfa_offset */
- ADV(UW38, UW37)
- .byte 0xe, 4 /* DW_CFA_def_cfa_offset */
- ADV(UW39, UW38)
- .byte 0xe, raw_closure_S_FS+4 /* DW_CFA_def_cfa_offset */
- .balign 4
- L(EFDE8):
- .set L(set9),L(EFDE9)-L(SFDE9)
- .long L(set9) /* FDE Length */
- L(SFDE9):
- .long L(SFDE9)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW41)) /* Initial location */
- .long L(UW52)-L(UW41) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW42, UW41)
- .byte 0xe, 0 /* DW_CFA_def_cfa_offset */
- .byte 0x9, 8, 2 /* DW_CFA_register %eip, %edx */
- ADV(UW43, UW42)
- .byte 0xe, 4 /* DW_CFA_def_cfa_offset */
- ADV(UW44, UW43)
- .byte 0xe, 8 /* DW_CFA_def_cfa_offset */
- .byte 0x80+8, 2 /* DW_CFA_offset %eip 2*-4 */
- ADV(UW45, UW44)
- .byte 0xe, raw_closure_T_FS+8 /* DW_CFA_def_cfa_offset */
- ADV(UW46, UW45)
- .byte 0x80+3, 3 /* DW_CFA_offset %ebx 3*-4 */
- ADV(UW47, UW46)
- .byte 0xc0+3 /* DW_CFA_restore %ebx */
- ADV(UW48, UW47)
- .byte 0xe, 8 /* DW_CFA_def_cfa_offset */
- ADV(UW49, UW48)
- .byte 0xe, raw_closure_T_FS+8 /* DW_CFA_def_cfa_offset */
- ADV(UW50, UW49)
- .byte 0xe, 8 /* DW_CFA_def_cfa_offset */
- ADV(UW51, UW50)
- .byte 0xe, raw_closure_T_FS+8 /* DW_CFA_def_cfa_offset */
- .balign 4
- L(EFDE9):
- #endif /* !FFI_NO_RAW_API */
- #ifdef _WIN32
- .def @feat.00;
- .scl 3;
- .type 0;
- .endef
- .globl @feat.00
- @feat.00 = 1
- #endif
- #ifdef __APPLE__
- .subsections_via_symbols
- .section __LD,__compact_unwind,regular,debug
- /* compact unwind for ffi_call_i386 */
- .long C(ffi_call_i386)
- .set L1,L(UW5)-L(UW0)
- .long L1
- .long 0x04000000 /* use dwarf unwind info */
- .long 0
- .long 0
- /* compact unwind for ffi_go_closure_EAX */
- .long C(ffi_go_closure_EAX)
- .set L2,L(UW8)-L(UW6)
- .long L2
- .long 0x04000000 /* use dwarf unwind info */
- .long 0
- .long 0
- /* compact unwind for ffi_go_closure_ECX */
- .long C(ffi_go_closure_ECX)
- .set L3,L(UW11)-L(UW9)
- .long L3
- .long 0x04000000 /* use dwarf unwind info */
- .long 0
- .long 0
- /* compact unwind for ffi_closure_i386 */
- .long C(ffi_closure_i386)
- .set L4,L(UW20)-L(UW12)
- .long L4
- .long 0x04000000 /* use dwarf unwind info */
- .long 0
- .long 0
- /* compact unwind for ffi_go_closure_STDCALL */
- .long C(ffi_go_closure_STDCALL)
- .set L5,L(UW23)-L(UW21)
- .long L5
- .long 0x04000000 /* use dwarf unwind info */
- .long 0
- .long 0
- /* compact unwind for ffi_closure_REGISTER */
- .long C(ffi_closure_REGISTER)
- .set L6,L(UW26)-L(UW24)
- .long L6
- .long 0x04000000 /* use dwarf unwind info */
- .long 0
- .long 0
- /* compact unwind for ffi_closure_STDCALL */
- .long C(ffi_closure_STDCALL)
- .set L7,L(UW31)-L(UW27)
- .long L7
- .long 0x04000000 /* use dwarf unwind info */
- .long 0
- .long 0
- /* compact unwind for ffi_closure_raw_SYSV */
- .long C(ffi_closure_raw_SYSV)
- .set L8,L(UW40)-L(UW32)
- .long L8
- .long 0x04000000 /* use dwarf unwind info */
- .long 0
- .long 0
- /* compact unwind for ffi_closure_raw_THISCALL */
- .long C(ffi_closure_raw_THISCALL)
- .set L9,L(UW52)-L(UW41)
- .long L9
- .long 0x04000000 /* use dwarf unwind info */
- .long 0
- .long 0
- #endif /* __APPLE__ */
- #endif /* ifndef _MSC_VER */
- #endif /* ifdef __i386__ */
- #if defined __ELF__ && defined __linux__
- .section .note.GNU-stack,"",@progbits
- #endif
- ====================File: src/x86/unix64.S====================
- /* -----------------------------------------------------------------------
- unix64.S - Copyright (c) 2013 The Written Word, Inc.
- - Copyright (c) 2008 Red Hat, Inc
- - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
- x86-64 Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #ifdef __x86_64__
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #include "internal64.h"
- #include "asmnames.h"
- .text
- /* This macro allows the safe creation of jump tables without an
- actual table. The entry points into the table are all 8 bytes.
- The use of ORG asserts that we're at the correct location. */
- /* ??? The clang assembler doesn't handle .org with symbolic expressions. */
- #if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
- # define E(BASE, X) .balign 8
- #else
- # define E(BASE, X) .balign 8; .org BASE + X * 8
- #endif
- /* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
- void *raddr, void (*fnaddr)(void));
- Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
- for this function. This has been allocated by ffi_call. We also
- deallocate some of the stack that has been alloca'd. */
- .balign 8
- .globl C(ffi_call_unix64)
- FFI_HIDDEN(C(ffi_call_unix64))
- C(ffi_call_unix64):
- L(UW0):
- movq (%rsp), %r10 /* Load return address. */
- leaq (%rdi, %rsi), %rax /* Find local stack base. */
- movq %rdx, (%rax) /* Save flags. */
- movq %rcx, 8(%rax) /* Save raddr. */
- movq %rbp, 16(%rax) /* Save old frame pointer. */
- movq %r10, 24(%rax) /* Relocate return address. */
- movq %rax, %rbp /* Finalize local stack frame. */
- /* New stack frame based off rbp. This is a itty bit of unwind
- trickery in that the CFA *has* changed. There is no easy way
- to describe it correctly on entry to the function. Fortunately,
- it doesn't matter too much since at all points we can correctly
- unwind back to ffi_call. Note that the location to which we
- moved the return address is (the new) CFA-8, so from the
- perspective of the unwind info, it hasn't moved. */
- L(UW1):
- /* cfi_def_cfa(%rbp, 32) */
- /* cfi_rel_offset(%rbp, 16) */
- movq %rdi, %r10 /* Save a copy of the register area. */
- movq %r8, %r11 /* Save a copy of the target fn. */
- movl %r9d, %eax /* Set number of SSE registers. */
- /* Load up all argument registers. */
- movq (%r10), %rdi
- movq 0x08(%r10), %rsi
- movq 0x10(%r10), %rdx
- movq 0x18(%r10), %rcx
- movq 0x20(%r10), %r8
- movq 0x28(%r10), %r9
- movl 0xb0(%r10), %eax
- testl %eax, %eax
- jnz L(load_sse)
- L(ret_from_load_sse):
- /* Deallocate the reg arg area, except for r10, then load via pop. */
- leaq 0xb8(%r10), %rsp
- popq %r10
- /* Call the user function. */
- call *%r11
- /* Deallocate stack arg area; local stack frame in redzone. */
- leaq 24(%rbp), %rsp
- movq 0(%rbp), %rcx /* Reload flags. */
- movq 8(%rbp), %rdi /* Reload raddr. */
- movq 16(%rbp), %rbp /* Reload old frame pointer. */
- L(UW2):
- /* cfi_remember_state */
- /* cfi_def_cfa(%rsp, 8) */
- /* cfi_restore(%rbp) */
- /* The first byte of the flags contains the FFI_TYPE. */
- cmpb $UNIX64_RET_LAST, %cl
- movzbl %cl, %r10d
- leaq L(store_table)(%rip), %r11
- ja L(sa)
- leaq (%r11, %r10, 8), %r10
- /* Prep for the structure cases: scratch area in redzone. */
- leaq -20(%rsp), %rsi
- jmp *%r10
- .balign 8
- L(store_table):
- E(L(store_table), UNIX64_RET_VOID)
- ret
- E(L(store_table), UNIX64_RET_UINT8)
- movzbl %al, %eax
- movq %rax, (%rdi)
- ret
- E(L(store_table), UNIX64_RET_UINT16)
- movzwl %ax, %eax
- movq %rax, (%rdi)
- ret
- E(L(store_table), UNIX64_RET_UINT32)
- movl %eax, %eax
- movq %rax, (%rdi)
- ret
- E(L(store_table), UNIX64_RET_SINT8)
- movsbq %al, %rax
- movq %rax, (%rdi)
- ret
- E(L(store_table), UNIX64_RET_SINT16)
- movswq %ax, %rax
- movq %rax, (%rdi)
- ret
- E(L(store_table), UNIX64_RET_SINT32)
- cltq
- movq %rax, (%rdi)
- ret
- E(L(store_table), UNIX64_RET_INT64)
- movq %rax, (%rdi)
- ret
- E(L(store_table), UNIX64_RET_XMM32)
- movd %xmm0, (%rdi)
- ret
- E(L(store_table), UNIX64_RET_XMM64)
- movq %xmm0, (%rdi)
- ret
- E(L(store_table), UNIX64_RET_X87)
- fstpt (%rdi)
- ret
- E(L(store_table), UNIX64_RET_X87_2)
- fstpt (%rdi)
- fstpt 16(%rdi)
- ret
- E(L(store_table), UNIX64_RET_ST_XMM0_RAX)
- movq %rax, 8(%rsi)
- jmp L(s3)
- E(L(store_table), UNIX64_RET_ST_RAX_XMM0)
- movq %xmm0, 8(%rsi)
- jmp L(s2)
- E(L(store_table), UNIX64_RET_ST_XMM0_XMM1)
- movq %xmm1, 8(%rsi)
- jmp L(s3)
- E(L(store_table), UNIX64_RET_ST_RAX_RDX)
- movq %rdx, 8(%rsi)
- L(s2):
- movq %rax, (%rsi)
- shrl $UNIX64_SIZE_SHIFT, %ecx
- rep movsb
- ret
- .balign 8
- L(s3):
- movq %xmm0, (%rsi)
- shrl $UNIX64_SIZE_SHIFT, %ecx
- rep movsb
- ret
- L(sa): call PLT(C(abort))
- /* Many times we can avoid loading any SSE registers at all.
- It's not worth an indirect jump to load the exact set of
- SSE registers needed; zero or all is a good compromise. */
- .balign 2
- L(UW3):
- /* cfi_restore_state */
- L(load_sse):
- movdqa 0x30(%r10), %xmm0
- movdqa 0x40(%r10), %xmm1
- movdqa 0x50(%r10), %xmm2
- movdqa 0x60(%r10), %xmm3
- movdqa 0x70(%r10), %xmm4
- movdqa 0x80(%r10), %xmm5
- movdqa 0x90(%r10), %xmm6
- movdqa 0xa0(%r10), %xmm7
- jmp L(ret_from_load_sse)
- L(UW4):
- ENDF(C(ffi_call_unix64))
- /* 6 general registers, 8 vector registers,
- 32 bytes of rvalue, 8 bytes of alignment. */
- #define ffi_closure_OFS_G 0
- #define ffi_closure_OFS_V (6*8)
- #define ffi_closure_OFS_RVALUE (ffi_closure_OFS_V + 8*16)
- #define ffi_closure_FS (ffi_closure_OFS_RVALUE + 32 + 8)
- /* The location of rvalue within the red zone after deallocating the frame. */
- #define ffi_closure_RED_RVALUE (ffi_closure_OFS_RVALUE - ffi_closure_FS)
- .balign 2
- .globl C(ffi_closure_unix64_sse)
- FFI_HIDDEN(C(ffi_closure_unix64_sse))
- C(ffi_closure_unix64_sse):
- L(UW5):
- subq $ffi_closure_FS, %rsp
- L(UW6):
- /* cfi_adjust_cfa_offset(ffi_closure_FS) */
- movdqa %xmm0, ffi_closure_OFS_V+0x00(%rsp)
- movdqa %xmm1, ffi_closure_OFS_V+0x10(%rsp)
- movdqa %xmm2, ffi_closure_OFS_V+0x20(%rsp)
- movdqa %xmm3, ffi_closure_OFS_V+0x30(%rsp)
- movdqa %xmm4, ffi_closure_OFS_V+0x40(%rsp)
- movdqa %xmm5, ffi_closure_OFS_V+0x50(%rsp)
- movdqa %xmm6, ffi_closure_OFS_V+0x60(%rsp)
- movdqa %xmm7, ffi_closure_OFS_V+0x70(%rsp)
- jmp L(sse_entry1)
- L(UW7):
- ENDF(C(ffi_closure_unix64_sse))
- .balign 2
- .globl C(ffi_closure_unix64)
- FFI_HIDDEN(C(ffi_closure_unix64))
- C(ffi_closure_unix64):
- L(UW8):
- subq $ffi_closure_FS, %rsp
- L(UW9):
- /* cfi_adjust_cfa_offset(ffi_closure_FS) */
- L(sse_entry1):
- movq %rdi, ffi_closure_OFS_G+0x00(%rsp)
- movq %rsi, ffi_closure_OFS_G+0x08(%rsp)
- movq %rdx, ffi_closure_OFS_G+0x10(%rsp)
- movq %rcx, ffi_closure_OFS_G+0x18(%rsp)
- movq %r8, ffi_closure_OFS_G+0x20(%rsp)
- movq %r9, ffi_closure_OFS_G+0x28(%rsp)
- #ifdef __ILP32__
- movl FFI_TRAMPOLINE_SIZE(%r10), %edi /* Load cif */
- movl FFI_TRAMPOLINE_SIZE+4(%r10), %esi /* Load fun */
- movl FFI_TRAMPOLINE_SIZE+8(%r10), %edx /* Load user_data */
- #else
- movq FFI_TRAMPOLINE_SIZE(%r10), %rdi /* Load cif */
- movq FFI_TRAMPOLINE_SIZE+8(%r10), %rsi /* Load fun */
- movq FFI_TRAMPOLINE_SIZE+16(%r10), %rdx /* Load user_data */
- #endif
- L(do_closure):
- leaq ffi_closure_OFS_RVALUE(%rsp), %rcx /* Load rvalue */
- movq %rsp, %r8 /* Load reg_args */
- leaq ffi_closure_FS+8(%rsp), %r9 /* Load argp */
- call PLT(C(ffi_closure_unix64_inner))
- /* Deallocate stack frame early; return value is now in redzone. */
- addq $ffi_closure_FS, %rsp
- L(UW10):
- /* cfi_adjust_cfa_offset(-ffi_closure_FS) */
- /* The first byte of the return value contains the FFI_TYPE. */
- cmpb $UNIX64_RET_LAST, %al
- movzbl %al, %r10d
- leaq L(load_table)(%rip), %r11
- ja L(la)
- leaq (%r11, %r10, 8), %r10
- leaq ffi_closure_RED_RVALUE(%rsp), %rsi
- jmp *%r10
- .balign 8
- L(load_table):
- E(L(load_table), UNIX64_RET_VOID)
- ret
- E(L(load_table), UNIX64_RET_UINT8)
- movzbl (%rsi), %eax
- ret
- E(L(load_table), UNIX64_RET_UINT16)
- movzwl (%rsi), %eax
- ret
- E(L(load_table), UNIX64_RET_UINT32)
- movl (%rsi), %eax
- ret
- E(L(load_table), UNIX64_RET_SINT8)
- movsbl (%rsi), %eax
- ret
- E(L(load_table), UNIX64_RET_SINT16)
- movswl (%rsi), %eax
- ret
- E(L(load_table), UNIX64_RET_SINT32)
- movl (%rsi), %eax
- ret
- E(L(load_table), UNIX64_RET_INT64)
- movq (%rsi), %rax
- ret
- E(L(load_table), UNIX64_RET_XMM32)
- movd (%rsi), %xmm0
- ret
- E(L(load_table), UNIX64_RET_XMM64)
- movq (%rsi), %xmm0
- ret
- E(L(load_table), UNIX64_RET_X87)
- fldt (%rsi)
- ret
- E(L(load_table), UNIX64_RET_X87_2)
- fldt 16(%rsi)
- fldt (%rsi)
- ret
- E(L(load_table), UNIX64_RET_ST_XMM0_RAX)
- movq 8(%rsi), %rax
- jmp L(l3)
- E(L(load_table), UNIX64_RET_ST_RAX_XMM0)
- movq 8(%rsi), %xmm0
- jmp L(l2)
- E(L(load_table), UNIX64_RET_ST_XMM0_XMM1)
- movq 8(%rsi), %xmm1
- jmp L(l3)
- E(L(load_table), UNIX64_RET_ST_RAX_RDX)
- movq 8(%rsi), %rdx
- L(l2):
- movq (%rsi), %rax
- ret
- .balign 8
- L(l3):
- movq (%rsi), %xmm0
- ret
- L(la): call PLT(C(abort))
- L(UW11):
- ENDF(C(ffi_closure_unix64))
- .balign 2
- .globl C(ffi_go_closure_unix64_sse)
- FFI_HIDDEN(C(ffi_go_closure_unix64_sse))
- C(ffi_go_closure_unix64_sse):
- L(UW12):
- subq $ffi_closure_FS, %rsp
- L(UW13):
- /* cfi_adjust_cfa_offset(ffi_closure_FS) */
- movdqa %xmm0, ffi_closure_OFS_V+0x00(%rsp)
- movdqa %xmm1, ffi_closure_OFS_V+0x10(%rsp)
- movdqa %xmm2, ffi_closure_OFS_V+0x20(%rsp)
- movdqa %xmm3, ffi_closure_OFS_V+0x30(%rsp)
- movdqa %xmm4, ffi_closure_OFS_V+0x40(%rsp)
- movdqa %xmm5, ffi_closure_OFS_V+0x50(%rsp)
- movdqa %xmm6, ffi_closure_OFS_V+0x60(%rsp)
- movdqa %xmm7, ffi_closure_OFS_V+0x70(%rsp)
- jmp L(sse_entry2)
- L(UW14):
- ENDF(C(ffi_go_closure_unix64_sse))
- .balign 2
- .globl C(ffi_go_closure_unix64)
- FFI_HIDDEN(C(ffi_go_closure_unix64))
- C(ffi_go_closure_unix64):
- L(UW15):
- subq $ffi_closure_FS, %rsp
- L(UW16):
- /* cfi_adjust_cfa_offset(ffi_closure_FS) */
- L(sse_entry2):
- movq %rdi, ffi_closure_OFS_G+0x00(%rsp)
- movq %rsi, ffi_closure_OFS_G+0x08(%rsp)
- movq %rdx, ffi_closure_OFS_G+0x10(%rsp)
- movq %rcx, ffi_closure_OFS_G+0x18(%rsp)
- movq %r8, ffi_closure_OFS_G+0x20(%rsp)
- movq %r9, ffi_closure_OFS_G+0x28(%rsp)
- #ifdef __ILP32__
- movl 4(%r10), %edi /* Load cif */
- movl 8(%r10), %esi /* Load fun */
- movl %r10d, %edx /* Load closure (user_data) */
- #else
- movq 8(%r10), %rdi /* Load cif */
- movq 16(%r10), %rsi /* Load fun */
- movq %r10, %rdx /* Load closure (user_data) */
- #endif
- jmp L(do_closure)
- L(UW17):
- ENDF(C(ffi_go_closure_unix64))
- /* Sadly, OSX cctools-as doesn't understand .cfi directives at all. */
- #ifdef __APPLE__
- .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
- EHFrame0:
- #elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)
- .section .eh_frame,"a",@unwind
- #else
- .section .eh_frame,"a",@progbits
- #endif
- #ifdef HAVE_AS_X86_PCREL
- # define PCREL(X) X - .
- #else
- # define PCREL(X) X@rel
- #endif
- /* Simplify advancing between labels. Assume DW_CFA_advance_loc1 fits. */
- #define ADV(N, P) .byte 2, L(N)-L(P)
- .balign 8
- L(CIE):
- .set L(set0),L(ECIE)-L(SCIE)
- .long L(set0) /* CIE Length */
- L(SCIE):
- .long 0 /* CIE Identifier Tag */
- .byte 1 /* CIE Version */
- .ascii "zR\0" /* CIE Augmentation */
- .byte 1 /* CIE Code Alignment Factor */
- .byte 0x78 /* CIE Data Alignment Factor */
- .byte 0x10 /* CIE RA Column */
- .byte 1 /* Augmentation size */
- .byte 0x1b /* FDE Encoding (pcrel sdata4) */
- .byte 0xc, 7, 8 /* DW_CFA_def_cfa, %rsp offset 8 */
- .byte 0x80+16, 1 /* DW_CFA_offset, %rip offset 1*-8 */
- .balign 8
- L(ECIE):
- .set L(set1),L(EFDE1)-L(SFDE1)
- .long L(set1) /* FDE Length */
- L(SFDE1):
- .long L(SFDE1)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW0)) /* Initial location */
- .long L(UW4)-L(UW0) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW1, UW0)
- .byte 0xc, 6, 32 /* DW_CFA_def_cfa, %rbp 32 */
- .byte 0x80+6, 2 /* DW_CFA_offset, %rbp 2*-8 */
- ADV(UW2, UW1)
- .byte 0xa /* DW_CFA_remember_state */
- .byte 0xc, 7, 8 /* DW_CFA_def_cfa, %rsp 8 */
- .byte 0xc0+6 /* DW_CFA_restore, %rbp */
- ADV(UW3, UW2)
- .byte 0xb /* DW_CFA_restore_state */
- .balign 8
- L(EFDE1):
- .set L(set2),L(EFDE2)-L(SFDE2)
- .long L(set2) /* FDE Length */
- L(SFDE2):
- .long L(SFDE2)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW5)) /* Initial location */
- .long L(UW7)-L(UW5) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW6, UW5)
- .byte 0xe /* DW_CFA_def_cfa_offset */
- .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */
- .balign 8
- L(EFDE2):
- .set L(set3),L(EFDE3)-L(SFDE3)
- .long L(set3) /* FDE Length */
- L(SFDE3):
- .long L(SFDE3)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW8)) /* Initial location */
- .long L(UW11)-L(UW8) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW9, UW8)
- .byte 0xe /* DW_CFA_def_cfa_offset */
- .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */
- ADV(UW10, UW9)
- .byte 0xe, 8 /* DW_CFA_def_cfa_offset 8 */
- L(EFDE3):
- .set L(set4),L(EFDE4)-L(SFDE4)
- .long L(set4) /* FDE Length */
- L(SFDE4):
- .long L(SFDE4)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW12)) /* Initial location */
- .long L(UW14)-L(UW12) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW13, UW12)
- .byte 0xe /* DW_CFA_def_cfa_offset */
- .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */
- .balign 8
- L(EFDE4):
- .set L(set5),L(EFDE5)-L(SFDE5)
- .long L(set5) /* FDE Length */
- L(SFDE5):
- .long L(SFDE5)-L(CIE) /* FDE CIE offset */
- .long PCREL(L(UW15)) /* Initial location */
- .long L(UW17)-L(UW15) /* Address range */
- .byte 0 /* Augmentation size */
- ADV(UW16, UW15)
- .byte 0xe /* DW_CFA_def_cfa_offset */
- .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */
- .balign 8
- L(EFDE5):
- #ifdef __APPLE__
- .subsections_via_symbols
- .section __LD,__compact_unwind,regular,debug
- /* compact unwind for ffi_call_unix64 */
- .quad C(ffi_call_unix64)
- .set L1,L(UW4)-L(UW0)
- .long L1
- .long 0x04000000 /* use dwarf unwind info */
- .quad 0
- .quad 0
- /* compact unwind for ffi_closure_unix64_sse */
- .quad C(ffi_closure_unix64_sse)
- .set L2,L(UW7)-L(UW5)
- .long L2
- .long 0x04000000 /* use dwarf unwind info */
- .quad 0
- .quad 0
- /* compact unwind for ffi_closure_unix64 */
- .quad C(ffi_closure_unix64)
- .set L3,L(UW11)-L(UW8)
- .long L3
- .long 0x04000000 /* use dwarf unwind info */
- .quad 0
- .quad 0
- /* compact unwind for ffi_go_closure_unix64_sse */
- .quad C(ffi_go_closure_unix64_sse)
- .set L4,L(UW14)-L(UW12)
- .long L4
- .long 0x04000000 /* use dwarf unwind info */
- .quad 0
- .quad 0
- /* compact unwind for ffi_go_closure_unix64 */
- .quad C(ffi_go_closure_unix64)
- .set L5,L(UW17)-L(UW15)
- .long L5
- .long 0x04000000 /* use dwarf unwind info */
- .quad 0
- .quad 0
- #endif
- #endif /* __x86_64__ */
- #if defined __ELF__ && defined __linux__
- .section .note.GNU-stack,"",@progbits
- #endif
- ====================MIT====================
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the ``Software''), to deal in the Software without
- restriction, including without limitation the rights to use, copy,
- modify, merge, publish, distribute, sublicense, and/or sell copies
- of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ====================MIT====================
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ====================MIT====================
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ====================MIT====================
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- ====================MIT====================
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- ====================MIT====================
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|