objc-runtime-new.mm 218 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020
  1. /*
  2. * Copyright (c) 2005-2009 Apple Inc. All Rights Reserved.
  3. *
  4. * @APPLE_LICENSE_HEADER_START@
  5. *
  6. * This file contains Original Code and/or Modifications of Original Code
  7. * as defined in and that are subject to the Apple Public Source License
  8. * Version 2.0 (the 'License'). You may not use this file except in
  9. * compliance with the License. Please obtain a copy of the License at
  10. * http://www.opensource.apple.com/apsl/ and read it before using this
  11. * file.
  12. *
  13. * The Original Code and all software distributed under the License are
  14. * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  15. * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  16. * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  18. * Please see the License for the specific language governing rights and
  19. * limitations under the License.
  20. *
  21. * @APPLE_LICENSE_HEADER_END@
  22. */
  23. /***********************************************************************
  24. * objc-runtime-new.m
  25. * Support for new-ABI classes and images.
  26. **********************************************************************/
  27. #if __OBJC2__
  28. #include "objc-private.h"
  29. #include "objc-runtime-new.h"
  30. #include "objc-file.h"
  31. #include "objc-cache.h"
  32. #include <Block.h>
  33. #include <objc/message.h>
  34. #include <mach/shared_region.h>
  35. #define newprotocol(p) ((protocol_t *)p)
  36. static void disableTaggedPointers();
  37. static void detach_class(Class cls, bool isMeta);
  38. static void free_class(Class cls);
  39. static Class setSuperclass(Class cls, Class newSuper);
  40. static Class realizeClass(Class cls);
  41. static method_t *getMethodNoSuper_nolock(Class cls, SEL sel);
  42. static method_t *getMethod_nolock(Class cls, SEL sel);
  43. static IMP addMethod(Class cls, SEL name, IMP imp, const char *types, bool replace);
  44. static bool isRRSelector(SEL sel);
  45. static bool isAWZSelector(SEL sel);
  46. static bool methodListImplementsRR(const method_list_t *mlist);
  47. static bool methodListImplementsAWZ(const method_list_t *mlist);
  48. static void updateCustomRR_AWZ(Class cls, method_t *meth);
  49. static method_t *search_method_list(const method_list_t *mlist, SEL sel);
  50. static void flushCaches(Class cls);
  51. static void initializeTaggedPointerObfuscator(void);
  52. #if SUPPORT_FIXUP
  53. static void fixupMessageRef(message_ref_t *msg);
  54. #endif
  55. static bool MetaclassNSObjectAWZSwizzled;
  56. static bool ClassNSObjectRRSwizzled;
  57. /***********************************************************************
  58. * Lock management
  59. **********************************************************************/
  60. mutex_t runtimeLock;
  61. mutex_t selLock;
  62. mutex_t cacheUpdateLock;
  63. recursive_mutex_t loadMethodLock;
  64. void lock_init(void)
  65. {
  66. }
  67. /***********************************************************************
  68. * Class structure decoding
  69. **********************************************************************/
  70. const uintptr_t objc_debug_class_rw_data_mask = FAST_DATA_MASK;
  71. /***********************************************************************
  72. * Non-pointer isa decoding
  73. **********************************************************************/
  74. #if SUPPORT_INDEXED_ISA
  75. // Indexed non-pointer isa.
  76. // These are used to mask the ISA and see if its got an index or not.
  77. const uintptr_t objc_debug_indexed_isa_magic_mask = ISA_INDEX_MAGIC_MASK;
  78. const uintptr_t objc_debug_indexed_isa_magic_value = ISA_INDEX_MAGIC_VALUE;
  79. // die if masks overlap
  80. STATIC_ASSERT((ISA_INDEX_MASK & ISA_INDEX_MAGIC_MASK) == 0);
  81. // die if magic is wrong
  82. STATIC_ASSERT((~ISA_INDEX_MAGIC_MASK & ISA_INDEX_MAGIC_VALUE) == 0);
  83. // Then these are used to extract the index from the ISA.
  84. const uintptr_t objc_debug_indexed_isa_index_mask = ISA_INDEX_MASK;
  85. const uintptr_t objc_debug_indexed_isa_index_shift = ISA_INDEX_SHIFT;
  86. asm("\n .globl _objc_absolute_indexed_isa_magic_mask" \
  87. "\n _objc_absolute_indexed_isa_magic_mask = " STRINGIFY2(ISA_INDEX_MAGIC_MASK));
  88. asm("\n .globl _objc_absolute_indexed_isa_magic_value" \
  89. "\n _objc_absolute_indexed_isa_magic_value = " STRINGIFY2(ISA_INDEX_MAGIC_VALUE));
  90. asm("\n .globl _objc_absolute_indexed_isa_index_mask" \
  91. "\n _objc_absolute_indexed_isa_index_mask = " STRINGIFY2(ISA_INDEX_MASK));
  92. asm("\n .globl _objc_absolute_indexed_isa_index_shift" \
  93. "\n _objc_absolute_indexed_isa_index_shift = " STRINGIFY2(ISA_INDEX_SHIFT));
  94. // And then we can use that index to get the class from this array. Note
  95. // the size is provided so that clients can ensure the index they get is in
  96. // bounds and not read off the end of the array.
  97. // Defined in the objc-msg-*.s files
  98. // const Class objc_indexed_classes[]
  99. // When we don't have enough bits to store a class*, we can instead store an
  100. // index in to this array. Classes are added here when they are realized.
  101. // Note, an index of 0 is illegal.
  102. uintptr_t objc_indexed_classes_count = 0;
  103. // SUPPORT_INDEXED_ISA
  104. #else
  105. // not SUPPORT_INDEXED_ISA
  106. // These variables exist but are all set to 0 so that they are ignored.
  107. const uintptr_t objc_debug_indexed_isa_magic_mask = 0;
  108. const uintptr_t objc_debug_indexed_isa_magic_value = 0;
  109. const uintptr_t objc_debug_indexed_isa_index_mask = 0;
  110. const uintptr_t objc_debug_indexed_isa_index_shift = 0;
  111. Class objc_indexed_classes[1] = { nil };
  112. uintptr_t objc_indexed_classes_count = 0;
  113. // not SUPPORT_INDEXED_ISA
  114. #endif
  115. #if SUPPORT_PACKED_ISA
  116. // Packed non-pointer isa.
  117. asm("\n .globl _objc_absolute_packed_isa_class_mask" \
  118. "\n _objc_absolute_packed_isa_class_mask = " STRINGIFY2(ISA_MASK));
  119. const uintptr_t objc_debug_isa_class_mask = ISA_MASK;
  120. const uintptr_t objc_debug_isa_magic_mask = ISA_MAGIC_MASK;
  121. const uintptr_t objc_debug_isa_magic_value = ISA_MAGIC_VALUE;
  122. // die if masks overlap
  123. STATIC_ASSERT((ISA_MASK & ISA_MAGIC_MASK) == 0);
  124. // die if magic is wrong
  125. STATIC_ASSERT((~ISA_MAGIC_MASK & ISA_MAGIC_VALUE) == 0);
  126. // die if virtual address space bound goes up
  127. STATIC_ASSERT((~ISA_MASK & MACH_VM_MAX_ADDRESS) == 0 ||
  128. ISA_MASK + sizeof(void*) == MACH_VM_MAX_ADDRESS);
  129. // SUPPORT_PACKED_ISA
  130. #else
  131. // not SUPPORT_PACKED_ISA
  132. // These variables exist but enforce pointer alignment only.
  133. const uintptr_t objc_debug_isa_class_mask = (~WORD_MASK);
  134. const uintptr_t objc_debug_isa_magic_mask = WORD_MASK;
  135. const uintptr_t objc_debug_isa_magic_value = 0;
  136. // not SUPPORT_PACKED_ISA
  137. #endif
  138. /***********************************************************************
  139. * allocatedClasses
  140. * A table of all classes (and metaclasses) which have been allocated
  141. * with objc_allocateClassPair.
  142. **********************************************************************/
  143. static NXHashTable *allocatedClasses = nil;
  144. typedef locstamped_category_list_t category_list;
  145. /*
  146. Low two bits of mlist->entsize is used as the fixed-up marker.
  147. PREOPTIMIZED VERSION:
  148. Method lists from shared cache are 1 (uniqued) or 3 (uniqued and sorted).
  149. (Protocol method lists are not sorted because of their extra parallel data)
  150. Runtime fixed-up method lists get 3.
  151. UN-PREOPTIMIZED VERSION:
  152. Method lists from shared cache are 1 (uniqued) or 3 (uniqued and sorted)
  153. Shared cache's sorting and uniquing are not trusted, but do affect the
  154. location of the selector name string.
  155. Runtime fixed-up method lists get 2.
  156. High two bits of protocol->flags is used as the fixed-up marker.
  157. PREOPTIMIZED VERSION:
  158. Protocols from shared cache are 1<<30.
  159. Runtime fixed-up protocols get 1<<30.
  160. UN-PREOPTIMIZED VERSION:
  161. Protocols from shared cache are 1<<30.
  162. Shared cache's fixups are not trusted.
  163. Runtime fixed-up protocols get 3<<30.
  164. */
  165. static uint32_t fixed_up_method_list = 3;
  166. static uint32_t fixed_up_protocol = PROTOCOL_FIXED_UP_1;
  167. void
  168. disableSharedCacheOptimizations(void)
  169. {
  170. fixed_up_method_list = 2;
  171. fixed_up_protocol = PROTOCOL_FIXED_UP_1 | PROTOCOL_FIXED_UP_2;
  172. }
  173. bool method_list_t::isFixedUp() const {
  174. return flags() == fixed_up_method_list;
  175. }
  176. void method_list_t::setFixedUp() {
  177. runtimeLock.assertLocked();
  178. assert(!isFixedUp());
  179. entsizeAndFlags = entsize() | fixed_up_method_list;
  180. }
  181. bool protocol_t::isFixedUp() const {
  182. return (flags & PROTOCOL_FIXED_UP_MASK) == fixed_up_protocol;
  183. }
  184. void protocol_t::setFixedUp() {
  185. runtimeLock.assertLocked();
  186. assert(!isFixedUp());
  187. flags = (flags & ~PROTOCOL_FIXED_UP_MASK) | fixed_up_protocol;
  188. }
  189. method_list_t **method_array_t::endCategoryMethodLists(Class cls)
  190. {
  191. method_list_t **mlists = beginLists();
  192. method_list_t **mlistsEnd = endLists();
  193. if (mlists == mlistsEnd || !cls->data()->ro->baseMethods())
  194. {
  195. // No methods, or no base methods.
  196. // Everything here is a category method.
  197. return mlistsEnd;
  198. }
  199. // Have base methods. Category methods are
  200. // everything except the last method list.
  201. return mlistsEnd - 1;
  202. }
  203. static const char *sel_cname(SEL sel)
  204. {
  205. return (const char *)(void *)sel;
  206. }
  207. static size_t protocol_list_size(const protocol_list_t *plist)
  208. {
  209. return sizeof(protocol_list_t) + plist->count * sizeof(protocol_t *);
  210. }
  211. static void try_free(const void *p)
  212. {
  213. if (p && malloc_size(p)) free((void *)p);
  214. }
  215. static void (*classCopyFixupHandler)(Class _Nonnull oldClass,
  216. Class _Nonnull newClass);
  217. void _objc_setClassCopyFixupHandler(void (* _Nonnull newFixupHandler)
  218. (Class _Nonnull oldClass, Class _Nonnull newClass)) {
  219. classCopyFixupHandler = newFixupHandler;
  220. }
  221. static Class
  222. alloc_class_for_subclass(Class supercls, size_t extraBytes)
  223. {
  224. if (!supercls || !supercls->isAnySwift()) {
  225. return _calloc_class(sizeof(objc_class) + extraBytes);
  226. }
  227. // Superclass is a Swift class. New subclass must duplicate its extra bits.
  228. // Allocate the new class, with space for super's prefix and suffix
  229. // and self's extraBytes.
  230. swift_class_t *swiftSupercls = (swift_class_t *)supercls;
  231. size_t superSize = swiftSupercls->classSize;
  232. void *superBits = swiftSupercls->baseAddress();
  233. void *bits = malloc(superSize + extraBytes);
  234. // Copy all of the superclass's data to the new class.
  235. memcpy(bits, superBits, superSize);
  236. // Erase the objc data and the Swift description in the new class.
  237. swift_class_t *swcls = (swift_class_t *)
  238. ((uint8_t *)bits + swiftSupercls->classAddressOffset);
  239. bzero(swcls, sizeof(objc_class));
  240. swcls->description = nil;
  241. if (classCopyFixupHandler) {
  242. classCopyFixupHandler(supercls, (Class)swcls);
  243. }
  244. // Mark this class as Swift-enhanced.
  245. if (supercls->isSwiftStable()) {
  246. swcls->bits.setIsSwiftStable();
  247. }
  248. if (supercls->isSwiftLegacy()) {
  249. swcls->bits.setIsSwiftLegacy();
  250. }
  251. return (Class)swcls;
  252. }
  253. /***********************************************************************
  254. * object_getIndexedIvars.
  255. **********************************************************************/
  256. void *object_getIndexedIvars(id obj)
  257. {
  258. uint8_t *base = (uint8_t *)obj;
  259. if (!obj) return nil;
  260. if (obj->isTaggedPointer()) return nil;
  261. if (!obj->isClass()) return base + obj->ISA()->alignedInstanceSize();
  262. Class cls = (Class)obj;
  263. if (!cls->isAnySwift()) return base + sizeof(objc_class);
  264. swift_class_t *swcls = (swift_class_t *)cls;
  265. return base - swcls->classAddressOffset + word_align(swcls->classSize);
  266. }
  267. /***********************************************************************
  268. * make_ro_writeable
  269. * Reallocates rw->ro if necessary to make it writeable.
  270. * Locking: runtimeLock must be held by the caller.
  271. **********************************************************************/
  272. static class_ro_t *make_ro_writeable(class_rw_t *rw)
  273. {
  274. runtimeLock.assertLocked();
  275. if (rw->flags & RW_COPIED_RO) {
  276. // already writeable, do nothing
  277. } else {
  278. class_ro_t *ro = (class_ro_t *)
  279. memdup(rw->ro, sizeof(*rw->ro));
  280. rw->ro = ro;
  281. rw->flags |= RW_COPIED_RO;
  282. }
  283. return (class_ro_t *)rw->ro;
  284. }
  285. /***********************************************************************
  286. * unattachedCategories
  287. * Returns the class => categories map of unattached categories.
  288. * Locking: runtimeLock must be held by the caller.
  289. **********************************************************************/
  290. static NXMapTable *unattachedCategories(void)
  291. {
  292. runtimeLock.assertLocked();
  293. static NXMapTable *category_map = nil;
  294. if (category_map) return category_map;
  295. // fixme initial map size
  296. category_map = NXCreateMapTable(NXPtrValueMapPrototype, 16);
  297. return category_map;
  298. }
  299. /***********************************************************************
  300. * dataSegmentsContain
  301. * Returns true if the given address lies within a data segment in any
  302. * loaded image.
  303. *
  304. * This is optimized for use where the return value is expected to be
  305. * true. A call where the return value is false always results in a
  306. * slow linear search of all loaded images. A call where the return
  307. * value is fast will often be fast due to caching.
  308. **********************************************************************/
  309. static bool dataSegmentsContain(const void *ptr) {
  310. struct Range {
  311. uintptr_t start, end;
  312. bool contains(uintptr_t ptr) {
  313. return start <= ptr && ptr <= end;
  314. }
  315. };
  316. // This is a really simple linear searched cache. On a cache hit,
  317. // the hit entry is moved to the front of the array. On a cache
  318. // miss where a range is successfully found on the slow path, the
  319. // found range is inserted at the beginning of the cache. This gives
  320. // us fast access to the most recently used elements, and LRU
  321. // eviction.
  322. enum { cacheCount = 16 };
  323. static Range cache[cacheCount];
  324. uintptr_t addr = (uintptr_t)ptr;
  325. // Special case a hit on the first entry of the cache. No
  326. // bookkeeping is required at all in this case.
  327. if (cache[0].contains(addr)) {
  328. return true;
  329. }
  330. // Search the rest of the cache.
  331. for (unsigned i = 1; i < cacheCount; i++) {
  332. if (cache[i].contains(addr)) {
  333. // Cache hit. Move all preceding entries down one element,
  334. // then place this entry at the front.
  335. Range r = cache[i];
  336. memmove(&cache[1], &cache[0], i * sizeof(cache[0]));
  337. cache[0] = r;
  338. return true;
  339. }
  340. }
  341. // Cache miss. Find the image header containing the given address.
  342. // If there isn't one, then we're definitely not in any image,
  343. // so return false.
  344. Range found = { 0, 0 };
  345. auto *h = (headerType *)dyld_image_header_containing_address(ptr);
  346. if (h == nullptr)
  347. return false;
  348. // Iterate over the data segments in the found image. If the address
  349. // lies within one, note the data segment range in `found`.
  350. // TODO: this is more work than we'd like to do. All we really need
  351. // is the full range of the image. Addresses within the TEXT segment
  352. // would also be acceptable for our use case. If possible, we should
  353. // change this to work with the full address range of the found
  354. // image header. Another possibility would be to use the range
  355. // from `h` to the end of the page containing `addr`.
  356. foreach_data_segment(h, [&](const segmentType *seg, intptr_t slide) {
  357. Range r;
  358. r.start = seg->vmaddr + slide;
  359. r.end = r.start + seg->vmsize;
  360. if (r.contains(addr))
  361. found = r;
  362. });
  363. if (found.start != 0) {
  364. memmove(&cache[1], &cache[0], (cacheCount - 1) * sizeof(cache[0]));
  365. cache[0] = found;
  366. return true;
  367. }
  368. return false;
  369. }
  370. /***********************************************************************
  371. * isKnownClass
  372. * Return true if the class is known to the runtime (located within the
  373. * shared cache, within the data segment of a loaded image, or has been
  374. * allocated with obj_allocateClassPair).
  375. **********************************************************************/
  376. static bool isKnownClass(Class cls) {
  377. // The order of conditionals here is important for speed. We want to
  378. // put the most common cases first, but also the fastest cases
  379. // first. Checking the shared region is both fast and common.
  380. // Checking allocatedClasses is fast, but may not be common,
  381. // depending on what the program is doing. Checking if data segments
  382. // contain the address is slow, so do it last.
  383. return (sharedRegionContains(cls) ||
  384. NXHashMember(allocatedClasses, cls) ||
  385. dataSegmentsContain(cls));
  386. }
  387. /***********************************************************************
  388. * addClassTableEntry
  389. * Add a class to the table of all classes. If addMeta is true,
  390. * automatically adds the metaclass of the class as well.
  391. * Locking: runtimeLock must be held by the caller.
  392. **********************************************************************/
  393. static void addClassTableEntry(Class cls, bool addMeta = true) {
  394. runtimeLock.assertLocked();
  395. // This class is allowed to be a known class via the shared cache or via
  396. // data segments, but it is not allowed to be in the dynamic table already.
  397. assert(!NXHashMember(allocatedClasses, cls));
  398. if (!isKnownClass(cls))
  399. NXHashInsert(allocatedClasses, cls);
  400. if (addMeta)
  401. addClassTableEntry(cls->ISA(), false);
  402. }
  403. /***********************************************************************
  404. * checkIsKnownClass
  405. * Checks the given class against the list of all known classes. Dies
  406. * with a fatal error if the class is not known.
  407. * Locking: runtimeLock must be held by the caller.
  408. **********************************************************************/
  409. static void checkIsKnownClass(Class cls)
  410. {
  411. if (!isKnownClass(cls))
  412. _objc_fatal("Attempt to use unknown class %p.", cls);
  413. }
  414. /***********************************************************************
  415. * addUnattachedCategoryForClass
  416. * Records an unattached category.
  417. * Locking: runtimeLock must be held by the caller.
  418. **********************************************************************/
  419. static void addUnattachedCategoryForClass(category_t *cat, Class cls,
  420. header_info *catHeader)
  421. {
  422. runtimeLock.assertLocked();
  423. // DO NOT use cat->cls! cls may be cat->cls->isa instead
  424. NXMapTable *cats = unattachedCategories();
  425. category_list *list;
  426. list = (category_list *)NXMapGet(cats, cls);
  427. if (!list) {
  428. list = (category_list *)
  429. calloc(sizeof(*list) + sizeof(list->list[0]), 1);
  430. } else {
  431. list = (category_list *)
  432. realloc(list, sizeof(*list) + sizeof(list->list[0]) * (list->count + 1));
  433. }
  434. list->list[list->count++] = (locstamped_category_t){cat, catHeader};
  435. NXMapInsert(cats, cls, list);
  436. }
  437. /***********************************************************************
  438. * removeUnattachedCategoryForClass
  439. * Removes an unattached category.
  440. * Locking: runtimeLock must be held by the caller.
  441. **********************************************************************/
  442. static void removeUnattachedCategoryForClass(category_t *cat, Class cls)
  443. {
  444. runtimeLock.assertLocked();
  445. // DO NOT use cat->cls! cls may be cat->cls->isa instead
  446. NXMapTable *cats = unattachedCategories();
  447. category_list *list;
  448. list = (category_list *)NXMapGet(cats, cls);
  449. if (!list) return;
  450. uint32_t i;
  451. for (i = 0; i < list->count; i++) {
  452. if (list->list[i].cat == cat) {
  453. // shift entries to preserve list order
  454. memmove(&list->list[i], &list->list[i+1],
  455. (list->count-i-1) * sizeof(list->list[i]));
  456. list->count--;
  457. return;
  458. }
  459. }
  460. }
  461. /***********************************************************************
  462. * unattachedCategoriesForClass
  463. * Returns the list of unattached categories for a class, and
  464. * deletes them from the list.
  465. * The result must be freed by the caller.
  466. * Locking: runtimeLock must be held by the caller.
  467. **********************************************************************/
  468. static category_list *
  469. unattachedCategoriesForClass(Class cls, bool realizing)
  470. {
  471. runtimeLock.assertLocked();
  472. return (category_list *)NXMapRemove(unattachedCategories(), cls);
  473. }
  474. /***********************************************************************
  475. * removeAllUnattachedCategoriesForClass
  476. * Deletes all unattached categories (loaded or not) for a class.
  477. * Locking: runtimeLock must be held by the caller.
  478. **********************************************************************/
  479. static void removeAllUnattachedCategoriesForClass(Class cls)
  480. {
  481. runtimeLock.assertLocked();
  482. void *list = NXMapRemove(unattachedCategories(), cls);
  483. if (list) free(list);
  484. }
  485. /***********************************************************************
  486. * classNSObject
  487. * Returns class NSObject.
  488. * Locking: none
  489. **********************************************************************/
  490. static Class classNSObject(void)
  491. {
  492. extern objc_class OBJC_CLASS_$_NSObject;
  493. return (Class)&OBJC_CLASS_$_NSObject;
  494. }
  495. /***********************************************************************
  496. * printReplacements
  497. * Implementation of PrintReplacedMethods / OBJC_PRINT_REPLACED_METHODS.
  498. * Warn about methods from cats that override other methods in cats or cls.
  499. * Assumes no methods from cats have been added to cls yet.
  500. **********************************************************************/
  501. static void printReplacements(Class cls, category_list *cats)
  502. {
  503. uint32_t c;
  504. bool isMeta = cls->isMetaClass();
  505. if (!cats) return;
  506. // Newest categories are LAST in cats
  507. // Later categories override earlier ones.
  508. for (c = 0; c < cats->count; c++) {
  509. category_t *cat = cats->list[c].cat;
  510. method_list_t *mlist = cat->methodsForMeta(isMeta);
  511. if (!mlist) continue;
  512. for (const auto& meth : *mlist) {
  513. SEL s = sel_registerName(sel_cname(meth.name));
  514. // Search for replaced methods in method lookup order.
  515. // Complain about the first duplicate only.
  516. // Look for method in earlier categories
  517. for (uint32_t c2 = 0; c2 < c; c2++) {
  518. category_t *cat2 = cats->list[c2].cat;
  519. const method_list_t *mlist2 = cat2->methodsForMeta(isMeta);
  520. if (!mlist2) continue;
  521. for (const auto& meth2 : *mlist2) {
  522. SEL s2 = sel_registerName(sel_cname(meth2.name));
  523. if (s == s2) {
  524. logReplacedMethod(cls->nameForLogging(), s,
  525. cls->isMetaClass(), cat->name,
  526. meth2.imp, meth.imp);
  527. goto complained;
  528. }
  529. }
  530. }
  531. // Look for method in cls
  532. for (const auto& meth2 : cls->data()->methods) {
  533. SEL s2 = sel_registerName(sel_cname(meth2.name));
  534. if (s == s2) {
  535. logReplacedMethod(cls->nameForLogging(), s,
  536. cls->isMetaClass(), cat->name,
  537. meth2.imp, meth.imp);
  538. goto complained;
  539. }
  540. }
  541. complained:
  542. ;
  543. }
  544. }
  545. }
  546. static bool isBundleClass(Class cls)
  547. {
  548. return cls->data()->ro->flags & RO_FROM_BUNDLE;
  549. }
  550. static void
  551. fixupMethodList(method_list_t *mlist, bool bundleCopy, bool sort)
  552. {
  553. runtimeLock.assertLocked();
  554. assert(!mlist->isFixedUp());
  555. // fixme lock less in attachMethodLists ?
  556. {
  557. mutex_locker_t lock(selLock);
  558. // Unique selectors in list.
  559. for (auto& meth : *mlist) {
  560. const char *name = sel_cname(meth.name);
  561. meth.name = sel_registerNameNoLock(name, bundleCopy);
  562. }
  563. }
  564. // Sort by selector address.
  565. if (sort) {
  566. method_t::SortBySELAddress sorter;
  567. std::stable_sort(mlist->begin(), mlist->end(), sorter);
  568. }
  569. // Mark method list as uniqued and sorted
  570. mlist->setFixedUp();
  571. }
  572. static void
  573. prepareMethodLists(Class cls, method_list_t **addedLists, int addedCount,
  574. bool baseMethods, bool methodsFromBundle)
  575. {
  576. runtimeLock.assertLocked();
  577. if (addedCount == 0) return;
  578. // Don't scan redundantly
  579. bool scanForCustomRR = !cls->hasCustomRR();
  580. bool scanForCustomAWZ = !cls->hasCustomAWZ();
  581. // There exist RR/AWZ special cases for some class's base methods.
  582. // But this code should never need to scan base methods for RR/AWZ:
  583. // default RR/AWZ cannot be set before setInitialized().
  584. // Therefore we need not handle any special cases here.
  585. if (baseMethods) {
  586. assert(!scanForCustomRR && !scanForCustomAWZ);
  587. }
  588. // Add method lists to array.
  589. // Reallocate un-fixed method lists.
  590. // The new methods are PREPENDED to the method list array.
  591. for (int i = 0; i < addedCount; i++) {
  592. method_list_t *mlist = addedLists[i];
  593. assert(mlist);
  594. // Fixup selectors if necessary
  595. if (!mlist->isFixedUp()) {
  596. fixupMethodList(mlist, methodsFromBundle, true/*sort*/);
  597. }
  598. // Scan for method implementations tracked by the class's flags
  599. if (scanForCustomRR && methodListImplementsRR(mlist)) {
  600. cls->setHasCustomRR();
  601. scanForCustomRR = false;
  602. }
  603. if (scanForCustomAWZ && methodListImplementsAWZ(mlist)) {
  604. cls->setHasCustomAWZ();
  605. scanForCustomAWZ = false;
  606. }
  607. }
  608. }
  609. // Attach method lists and properties and protocols from categories to a class.
  610. // Assumes the categories in cats are all loaded and sorted by load order,
  611. // oldest categories first.
  612. static void
  613. attachCategories(Class cls, category_list *cats, bool flush_caches)
  614. {
  615. if (!cats) return;
  616. if (PrintReplacedMethods) printReplacements(cls, cats);
  617. bool isMeta = cls->isMetaClass();
  618. // fixme rearrange to remove these intermediate allocations
  619. method_list_t **mlists = (method_list_t **)
  620. malloc(cats->count * sizeof(*mlists));
  621. property_list_t **proplists = (property_list_t **)
  622. malloc(cats->count * sizeof(*proplists));
  623. protocol_list_t **protolists = (protocol_list_t **)
  624. malloc(cats->count * sizeof(*protolists));
  625. // Count backwards through cats to get newest categories first
  626. int mcount = 0;
  627. int propcount = 0;
  628. int protocount = 0;
  629. int i = cats->count;
  630. bool fromBundle = NO;
  631. while (i--) {
  632. auto& entry = cats->list[i];
  633. method_list_t *mlist = entry.cat->methodsForMeta(isMeta);
  634. if (mlist) {
  635. mlists[mcount++] = mlist;
  636. fromBundle |= entry.hi->isBundle();
  637. }
  638. property_list_t *proplist =
  639. entry.cat->propertiesForMeta(isMeta, entry.hi);
  640. if (proplist) {
  641. proplists[propcount++] = proplist;
  642. }
  643. protocol_list_t *protolist = entry.cat->protocols;
  644. if (protolist) {
  645. protolists[protocount++] = protolist;
  646. }
  647. }
  648. auto rw = cls->data();
  649. prepareMethodLists(cls, mlists, mcount, NO, fromBundle);
  650. rw->methods.attachLists(mlists, mcount);
  651. free(mlists);
  652. if (flush_caches && mcount > 0) flushCaches(cls);
  653. rw->properties.attachLists(proplists, propcount);
  654. free(proplists);
  655. rw->protocols.attachLists(protolists, protocount);
  656. free(protolists);
  657. }
  658. /***********************************************************************
  659. * methodizeClass
  660. * Fixes up cls's method list, protocol list, and property list.
  661. * Attaches any outstanding categories.
  662. * Locking: runtimeLock must be held by the caller
  663. **********************************************************************/
  664. static void methodizeClass(Class cls)
  665. {
  666. runtimeLock.assertLocked();
  667. bool isMeta = cls->isMetaClass();
  668. auto rw = cls->data();
  669. auto ro = rw->ro;
  670. // Methodizing for the first time
  671. if (PrintConnecting) {
  672. _objc_inform("CLASS: methodizing class '%s' %s",
  673. cls->nameForLogging(), isMeta ? "(meta)" : "");
  674. }
  675. // Install methods and properties that the class implements itself.
  676. method_list_t *list = ro->baseMethods();
  677. if (list) {
  678. prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls));
  679. rw->methods.attachLists(&list, 1);
  680. }
  681. property_list_t *proplist = ro->baseProperties;
  682. if (proplist) {
  683. rw->properties.attachLists(&proplist, 1);
  684. }
  685. protocol_list_t *protolist = ro->baseProtocols;
  686. if (protolist) {
  687. rw->protocols.attachLists(&protolist, 1);
  688. }
  689. // Root classes get bonus method implementations if they don't have
  690. // them already. These apply before category replacements.
  691. if (cls->isRootMetaclass()) {
  692. // root metaclass
  693. addMethod(cls, SEL_initialize, (IMP)&objc_noop_imp, "", NO);
  694. }
  695. // Attach categories.
  696. category_list *cats = unattachedCategoriesForClass(cls, true /*realizing*/);
  697. attachCategories(cls, cats, false /*don't flush caches*/);
  698. if (PrintConnecting) {
  699. if (cats) {
  700. for (uint32_t i = 0; i < cats->count; i++) {
  701. _objc_inform("CLASS: attached category %c%s(%s)",
  702. isMeta ? '+' : '-',
  703. cls->nameForLogging(), cats->list[i].cat->name);
  704. }
  705. }
  706. }
  707. if (cats) free(cats);
  708. #if DEBUG
  709. // Debug: sanity-check all SELs; log method list contents
  710. for (const auto& meth : rw->methods) {
  711. if (PrintConnecting) {
  712. _objc_inform("METHOD %c[%s %s]", isMeta ? '+' : '-',
  713. cls->nameForLogging(), sel_getName(meth.name));
  714. }
  715. assert(sel_registerName(sel_getName(meth.name)) == meth.name);
  716. }
  717. #endif
  718. }
  719. /***********************************************************************
  720. * remethodizeClass
  721. * Attach outstanding categories to an existing class.
  722. * Fixes up cls's method list, protocol list, and property list.
  723. * Updates method caches for cls and its subclasses.
  724. * Locking: runtimeLock must be held by the caller
  725. **********************************************************************/
  726. static void remethodizeClass(Class cls)
  727. {
  728. category_list *cats;
  729. bool isMeta;
  730. runtimeLock.assertLocked();
  731. isMeta = cls->isMetaClass();
  732. // Re-methodizing: check for more categories
  733. if ((cats = unattachedCategoriesForClass(cls, false/*not realizing*/))) {
  734. if (PrintConnecting) {
  735. _objc_inform("CLASS: attaching categories to class '%s' %s",
  736. cls->nameForLogging(), isMeta ? "(meta)" : "");
  737. }
  738. attachCategories(cls, cats, true /*flush caches*/);
  739. free(cats);
  740. }
  741. }
  742. /***********************************************************************
  743. * nonMetaClasses
  744. * Returns the secondary metaclass => class map
  745. * Used for some cases of +initialize and +resolveClassMethod:.
  746. * This map does not contain all class and metaclass pairs. It only
  747. * contains metaclasses whose classes would be in the runtime-allocated
  748. * named-class table, but are not because some other class with the same name
  749. * is in that table.
  750. * Classes with no duplicates are not included.
  751. * Classes in the preoptimized named-class table are not included.
  752. * Classes whose duplicates are in the preoptimized table are not included.
  753. * Most code should use getNonMetaClass() instead of reading this table.
  754. * Locking: runtimeLock must be read- or write-locked by the caller
  755. **********************************************************************/
  756. static NXMapTable *nonmeta_class_map = nil;
  757. static NXMapTable *nonMetaClasses(void)
  758. {
  759. runtimeLock.assertLocked();
  760. if (nonmeta_class_map) return nonmeta_class_map;
  761. // nonmeta_class_map is typically small
  762. INIT_ONCE_PTR(nonmeta_class_map,
  763. NXCreateMapTable(NXPtrValueMapPrototype, 32),
  764. NXFreeMapTable(v));
  765. return nonmeta_class_map;
  766. }
  767. /***********************************************************************
  768. * addNonMetaClass
  769. * Adds metacls => cls to the secondary metaclass map
  770. * Locking: runtimeLock must be held by the caller
  771. **********************************************************************/
  772. static void addNonMetaClass(Class cls)
  773. {
  774. runtimeLock.assertLocked();
  775. void *old;
  776. old = NXMapInsert(nonMetaClasses(), cls->ISA(), cls);
  777. assert(!cls->isMetaClass());
  778. assert(cls->ISA()->isMetaClass());
  779. assert(!old);
  780. }
  781. static void removeNonMetaClass(Class cls)
  782. {
  783. runtimeLock.assertLocked();
  784. NXMapRemove(nonMetaClasses(), cls->ISA());
  785. }
  786. static bool scanMangledField(const char *&string, const char *end,
  787. const char *&field, int& length)
  788. {
  789. // Leading zero not allowed.
  790. if (*string == '0') return false;
  791. length = 0;
  792. field = string;
  793. while (field < end) {
  794. char c = *field;
  795. if (!isdigit(c)) break;
  796. field++;
  797. if (__builtin_smul_overflow(length, 10, &length)) return false;
  798. if (__builtin_sadd_overflow(length, c - '0', &length)) return false;
  799. }
  800. string = field + length;
  801. return length > 0 && string <= end;
  802. }
  803. /***********************************************************************
  804. * copySwiftV1DemangledName
  805. * Returns the pretty form of the given Swift-v1-mangled class or protocol name.
  806. * Returns nil if the string doesn't look like a mangled Swift v1 name.
  807. * The result must be freed with free().
  808. **********************************************************************/
  809. static char *copySwiftV1DemangledName(const char *string, bool isProtocol = false)
  810. {
  811. if (!string) return nil;
  812. // Swift mangling prefix.
  813. if (strncmp(string, isProtocol ? "_TtP" : "_TtC", 4) != 0) return nil;
  814. string += 4;
  815. const char *end = string + strlen(string);
  816. // Module name.
  817. const char *prefix;
  818. int prefixLength;
  819. if (string[0] == 's') {
  820. // "s" is the Swift module.
  821. prefix = "Swift";
  822. prefixLength = 5;
  823. string += 1;
  824. } else {
  825. if (! scanMangledField(string, end, prefix, prefixLength)) return nil;
  826. }
  827. // Class or protocol name.
  828. const char *suffix;
  829. int suffixLength;
  830. if (! scanMangledField(string, end, suffix, suffixLength)) return nil;
  831. if (isProtocol) {
  832. // Remainder must be "_".
  833. if (strcmp(string, "_") != 0) return nil;
  834. } else {
  835. // Remainder must be empty.
  836. if (string != end) return nil;
  837. }
  838. char *result;
  839. asprintf(&result, "%.*s.%.*s", prefixLength,prefix, suffixLength,suffix);
  840. return result;
  841. }
  842. /***********************************************************************
  843. * copySwiftV1MangledName
  844. * Returns the Swift 1.0 mangled form of the given class or protocol name.
  845. * Returns nil if the string doesn't look like an unmangled Swift name.
  846. * The result must be freed with free().
  847. **********************************************************************/
  848. static char *copySwiftV1MangledName(const char *string, bool isProtocol = false)
  849. {
  850. if (!string) return nil;
  851. size_t dotCount = 0;
  852. size_t dotIndex;
  853. const char *s;
  854. for (s = string; *s; s++) {
  855. if (*s == '.') {
  856. dotCount++;
  857. dotIndex = s - string;
  858. }
  859. }
  860. size_t stringLength = s - string;
  861. if (dotCount != 1 || dotIndex == 0 || dotIndex >= stringLength-1) {
  862. return nil;
  863. }
  864. const char *prefix = string;
  865. size_t prefixLength = dotIndex;
  866. const char *suffix = string + dotIndex + 1;
  867. size_t suffixLength = stringLength - (dotIndex + 1);
  868. char *name;
  869. if (prefixLength == 5 && memcmp(prefix, "Swift", 5) == 0) {
  870. asprintf(&name, "_Tt%cs%zu%.*s%s",
  871. isProtocol ? 'P' : 'C',
  872. suffixLength, (int)suffixLength, suffix,
  873. isProtocol ? "_" : "");
  874. } else {
  875. asprintf(&name, "_Tt%c%zu%.*s%zu%.*s%s",
  876. isProtocol ? 'P' : 'C',
  877. prefixLength, (int)prefixLength, prefix,
  878. suffixLength, (int)suffixLength, suffix,
  879. isProtocol ? "_" : "");
  880. }
  881. return name;
  882. }
  883. /***********************************************************************
  884. * getClass
  885. * Looks up a class by name. The class MIGHT NOT be realized.
  886. * Demangled Swift names are recognized.
  887. * Locking: runtimeLock must be read- or write-locked by the caller.
  888. **********************************************************************/
  889. // This is a misnomer: gdb_objc_realized_classes is actually a list of
  890. // named classes not in the dyld shared cache, whether realized or not.
  891. NXMapTable *gdb_objc_realized_classes; // exported for debuggers in objc-gdb.h
  892. static Class getClass_impl(const char *name)
  893. {
  894. runtimeLock.assertLocked();
  895. // allocated in _read_images
  896. assert(gdb_objc_realized_classes);
  897. // Try runtime-allocated table
  898. Class result = (Class)NXMapGet(gdb_objc_realized_classes, name);
  899. if (result) return result;
  900. // Try table from dyld shared cache
  901. return getPreoptimizedClass(name);
  902. }
  903. static Class getClass(const char *name)
  904. {
  905. runtimeLock.assertLocked();
  906. // Try name as-is
  907. Class result = getClass_impl(name);
  908. if (result) return result;
  909. // Try Swift-mangled equivalent of the given name.
  910. if (char *swName = copySwiftV1MangledName(name)) {
  911. result = getClass_impl(swName);
  912. free(swName);
  913. return result;
  914. }
  915. return nil;
  916. }
  917. /***********************************************************************
  918. * addNamedClass
  919. * Adds name => cls to the named non-meta class map.
  920. * Warns about duplicate class names and keeps the old mapping.
  921. * Locking: runtimeLock must be held by the caller
  922. **********************************************************************/
  923. static void addNamedClass(Class cls, const char *name, Class replacing = nil)
  924. {
  925. runtimeLock.assertLocked();
  926. Class old;
  927. if ((old = getClass(name)) && old != replacing) {
  928. inform_duplicate(name, old, cls);
  929. // getNonMetaClass uses name lookups. Classes not found by name
  930. // lookup must be in the secondary meta->nonmeta table.
  931. addNonMetaClass(cls);
  932. } else {
  933. NXMapInsert(gdb_objc_realized_classes, name, cls);
  934. }
  935. assert(!(cls->data()->flags & RO_META));
  936. // wrong: constructed classes are already realized when they get here
  937. // assert(!cls->isRealized());
  938. }
  939. /***********************************************************************
  940. * removeNamedClass
  941. * Removes cls from the name => cls map.
  942. * Locking: runtimeLock must be held by the caller
  943. **********************************************************************/
  944. static void removeNamedClass(Class cls, const char *name)
  945. {
  946. runtimeLock.assertLocked();
  947. assert(!(cls->data()->flags & RO_META));
  948. if (cls == NXMapGet(gdb_objc_realized_classes, name)) {
  949. NXMapRemove(gdb_objc_realized_classes, name);
  950. } else {
  951. // cls has a name collision with another class - don't remove the other
  952. // but do remove cls from the secondary metaclass->class map.
  953. removeNonMetaClass(cls);
  954. }
  955. }
  956. /***********************************************************************
  957. * unreasonableClassCount
  958. * Provides an upper bound for any iteration of classes,
  959. * to prevent spins when runtime metadata is corrupted.
  960. **********************************************************************/
  961. unsigned unreasonableClassCount()
  962. {
  963. runtimeLock.assertLocked();
  964. int base = NXCountMapTable(gdb_objc_realized_classes) +
  965. getPreoptimizedClassUnreasonableCount();
  966. // Provide lots of slack here. Some iterations touch metaclasses too.
  967. // Some iterations backtrack (like realized class iteration).
  968. // We don't need an efficient bound, merely one that prevents spins.
  969. return (base + 1) * 16;
  970. }
  971. /***********************************************************************
  972. * futureNamedClasses
  973. * Returns the classname => future class map for unrealized future classes.
  974. * Locking: runtimeLock must be held by the caller
  975. **********************************************************************/
  976. static NXMapTable *future_named_class_map = nil;
  977. static NXMapTable *futureNamedClasses()
  978. {
  979. runtimeLock.assertLocked();
  980. if (future_named_class_map) return future_named_class_map;
  981. // future_named_class_map is big enough for CF's classes and a few others
  982. future_named_class_map =
  983. NXCreateMapTable(NXStrValueMapPrototype, 32);
  984. return future_named_class_map;
  985. }
  986. static bool haveFutureNamedClasses() {
  987. return future_named_class_map && NXCountMapTable(future_named_class_map);
  988. }
  989. /***********************************************************************
  990. * addFutureNamedClass
  991. * Installs cls as the class structure to use for the named class if it appears.
  992. * Locking: runtimeLock must be held by the caller
  993. **********************************************************************/
  994. static void addFutureNamedClass(const char *name, Class cls)
  995. {
  996. void *old;
  997. runtimeLock.assertLocked();
  998. if (PrintFuture) {
  999. _objc_inform("FUTURE: reserving %p for %s", (void*)cls, name);
  1000. }
  1001. class_rw_t *rw = (class_rw_t *)calloc(sizeof(class_rw_t), 1);
  1002. class_ro_t *ro = (class_ro_t *)calloc(sizeof(class_ro_t), 1);
  1003. ro->name = strdupIfMutable(name);
  1004. rw->ro = ro;
  1005. cls->setData(rw);
  1006. cls->data()->flags = RO_FUTURE;
  1007. old = NXMapKeyCopyingInsert(futureNamedClasses(), name, cls);
  1008. assert(!old);
  1009. }
  1010. /***********************************************************************
  1011. * popFutureNamedClass
  1012. * Removes the named class from the unrealized future class list,
  1013. * because it has been realized.
  1014. * Returns nil if the name is not used by a future class.
  1015. * Locking: runtimeLock must be held by the caller
  1016. **********************************************************************/
  1017. static Class popFutureNamedClass(const char *name)
  1018. {
  1019. runtimeLock.assertLocked();
  1020. Class cls = nil;
  1021. if (future_named_class_map) {
  1022. cls = (Class)NXMapKeyFreeingRemove(future_named_class_map, name);
  1023. if (cls && NXCountMapTable(future_named_class_map) == 0) {
  1024. NXFreeMapTable(future_named_class_map);
  1025. future_named_class_map = nil;
  1026. }
  1027. }
  1028. return cls;
  1029. }
  1030. /***********************************************************************
  1031. * remappedClasses
  1032. * Returns the oldClass => newClass map for realized future classes.
  1033. * Returns the oldClass => nil map for ignored weak-linked classes.
  1034. * Locking: runtimeLock must be read- or write-locked by the caller
  1035. **********************************************************************/
  1036. static NXMapTable *remappedClasses(bool create)
  1037. {
  1038. static NXMapTable *remapped_class_map = nil;
  1039. runtimeLock.assertLocked();
  1040. if (remapped_class_map) return remapped_class_map;
  1041. if (!create) return nil;
  1042. // remapped_class_map is big enough to hold CF's classes and a few others
  1043. INIT_ONCE_PTR(remapped_class_map,
  1044. NXCreateMapTable(NXPtrValueMapPrototype, 32),
  1045. NXFreeMapTable(v));
  1046. return remapped_class_map;
  1047. }
  1048. /***********************************************************************
  1049. * noClassesRemapped
  1050. * Returns YES if no classes have been remapped
  1051. * Locking: runtimeLock must be read- or write-locked by the caller
  1052. **********************************************************************/
  1053. static bool noClassesRemapped(void)
  1054. {
  1055. runtimeLock.assertLocked();
  1056. bool result = (remappedClasses(NO) == nil);
  1057. #if DEBUG
  1058. // Catch construction of an empty table, which defeats optimization.
  1059. NXMapTable *map = remappedClasses(NO);
  1060. if (map) assert(NXCountMapTable(map) > 0);
  1061. #endif
  1062. return result;
  1063. }
  1064. /***********************************************************************
  1065. * addRemappedClass
  1066. * newcls is a realized future class, replacing oldcls.
  1067. * OR newcls is nil, replacing ignored weak-linked class oldcls.
  1068. * Locking: runtimeLock must be write-locked by the caller
  1069. **********************************************************************/
  1070. static void addRemappedClass(Class oldcls, Class newcls)
  1071. {
  1072. runtimeLock.assertLocked();
  1073. if (PrintFuture) {
  1074. _objc_inform("FUTURE: using %p instead of %p for %s",
  1075. (void*)newcls, (void*)oldcls, oldcls->nameForLogging());
  1076. }
  1077. void *old;
  1078. old = NXMapInsert(remappedClasses(YES), oldcls, newcls);
  1079. assert(!old);
  1080. }
  1081. /***********************************************************************
  1082. * remapClass
  1083. * Returns the live class pointer for cls, which may be pointing to
  1084. * a class struct that has been reallocated.
  1085. * Returns nil if cls is ignored because of weak linking.
  1086. * Locking: runtimeLock must be read- or write-locked by the caller
  1087. **********************************************************************/
  1088. static Class remapClass(Class cls)
  1089. {
  1090. runtimeLock.assertLocked();
  1091. Class c2;
  1092. if (!cls) return nil;
  1093. NXMapTable *map = remappedClasses(NO);
  1094. if (!map || NXMapMember(map, cls, (void**)&c2) == NX_MAPNOTAKEY) {
  1095. return cls;
  1096. } else {
  1097. return c2;
  1098. }
  1099. }
  1100. static Class remapClass(classref_t cls)
  1101. {
  1102. return remapClass((Class)cls);
  1103. }
  1104. Class _class_remap(Class cls)
  1105. {
  1106. mutex_locker_t lock(runtimeLock);
  1107. return remapClass(cls);
  1108. }
  1109. /***********************************************************************
  1110. * remapClassRef
  1111. * Fix up a class ref, in case the class referenced has been reallocated
  1112. * or is an ignored weak-linked class.
  1113. * Locking: runtimeLock must be read- or write-locked by the caller
  1114. **********************************************************************/
  1115. static void remapClassRef(Class *clsref)
  1116. {
  1117. runtimeLock.assertLocked();
  1118. Class newcls = remapClass(*clsref);
  1119. if (*clsref != newcls) *clsref = newcls;
  1120. }
  1121. /***********************************************************************
  1122. * getNonMetaClass
  1123. * Return the ordinary class for this class or metaclass.
  1124. * `inst` is an instance of `cls` or a subclass thereof, or nil.
  1125. * Non-nil inst is faster.
  1126. * Used by +initialize.
  1127. * Locking: runtimeLock must be read- or write-locked by the caller
  1128. **********************************************************************/
  1129. static Class getNonMetaClass(Class metacls, id inst)
  1130. {
  1131. static int total, named, secondary, sharedcache;
  1132. runtimeLock.assertLocked();
  1133. realizeClass(metacls);
  1134. total++;
  1135. // return cls itself if it's already a non-meta class
  1136. if (!metacls->isMetaClass()) return metacls;
  1137. // metacls really is a metaclass
  1138. // special case for root metaclass
  1139. // where inst == inst->ISA() == metacls is possible
  1140. if (metacls->ISA() == metacls) {
  1141. Class cls = metacls->superclass;
  1142. assert(cls->isRealized());
  1143. assert(!cls->isMetaClass());
  1144. assert(cls->ISA() == metacls);
  1145. if (cls->ISA() == metacls) return cls;
  1146. }
  1147. // use inst if available
  1148. if (inst) {
  1149. Class cls = (Class)inst;
  1150. realizeClass(cls);
  1151. // cls may be a subclass - find the real class for metacls
  1152. while (cls && cls->ISA() != metacls) {
  1153. cls = cls->superclass;
  1154. realizeClass(cls);
  1155. }
  1156. if (cls) {
  1157. assert(!cls->isMetaClass());
  1158. assert(cls->ISA() == metacls);
  1159. return cls;
  1160. }
  1161. #if DEBUG
  1162. _objc_fatal("cls is not an instance of metacls");
  1163. #else
  1164. // release build: be forgiving and fall through to slow lookups
  1165. #endif
  1166. }
  1167. // try name lookup
  1168. {
  1169. Class cls = getClass(metacls->mangledName());
  1170. if (cls->ISA() == metacls) {
  1171. named++;
  1172. if (PrintInitializing) {
  1173. _objc_inform("INITIALIZE: %d/%d (%g%%) "
  1174. "successful by-name metaclass lookups",
  1175. named, total, named*100.0/total);
  1176. }
  1177. realizeClass(cls);
  1178. return cls;
  1179. }
  1180. }
  1181. // try secondary table
  1182. {
  1183. Class cls = (Class)NXMapGet(nonMetaClasses(), metacls);
  1184. if (cls) {
  1185. secondary++;
  1186. if (PrintInitializing) {
  1187. _objc_inform("INITIALIZE: %d/%d (%g%%) "
  1188. "successful secondary metaclass lookups",
  1189. secondary, total, secondary*100.0/total);
  1190. }
  1191. assert(cls->ISA() == metacls);
  1192. realizeClass(cls);
  1193. return cls;
  1194. }
  1195. }
  1196. // try any duplicates in the dyld shared cache
  1197. {
  1198. Class cls = nil;
  1199. int count;
  1200. Class *classes = copyPreoptimizedClasses(metacls->mangledName(),&count);
  1201. if (classes) {
  1202. for (int i = 0; i < count; i++) {
  1203. if (classes[i]->ISA() == metacls) {
  1204. cls = classes[i];
  1205. break;
  1206. }
  1207. }
  1208. free(classes);
  1209. }
  1210. if (cls) {
  1211. sharedcache++;
  1212. if (PrintInitializing) {
  1213. _objc_inform("INITIALIZE: %d/%d (%g%%) "
  1214. "successful shared cache metaclass lookups",
  1215. sharedcache, total, sharedcache*100.0/total);
  1216. }
  1217. realizeClass(cls);
  1218. return cls;
  1219. }
  1220. }
  1221. _objc_fatal("no class for metaclass %p", (void*)metacls);
  1222. }
  1223. /***********************************************************************
  1224. * _class_getNonMetaClass
  1225. * Return the ordinary class for this class or metaclass.
  1226. * Used by +initialize.
  1227. * Locking: acquires runtimeLock
  1228. **********************************************************************/
  1229. Class _class_getNonMetaClass(Class cls, id obj)
  1230. {
  1231. mutex_locker_t lock(runtimeLock);
  1232. cls = getNonMetaClass(cls, obj);
  1233. assert(cls->isRealized());
  1234. return cls;
  1235. }
  1236. /***********************************************************************
  1237. * addRootClass
  1238. * Adds cls as a new realized root class.
  1239. * Locking: runtimeLock must be held by the caller.
  1240. **********************************************************************/
  1241. static Class _firstRealizedClass = nil;
  1242. Class firstRealizedClass()
  1243. {
  1244. runtimeLock.assertLocked();
  1245. return _firstRealizedClass;
  1246. }
  1247. static void addRootClass(Class cls)
  1248. {
  1249. runtimeLock.assertLocked();
  1250. assert(cls->isRealized());
  1251. cls->data()->nextSiblingClass = _firstRealizedClass;
  1252. _firstRealizedClass = cls;
  1253. }
  1254. static void removeRootClass(Class cls)
  1255. {
  1256. runtimeLock.assertLocked();
  1257. Class *classp;
  1258. for (classp = &_firstRealizedClass;
  1259. *classp != cls;
  1260. classp = &(*classp)->data()->nextSiblingClass)
  1261. { }
  1262. *classp = (*classp)->data()->nextSiblingClass;
  1263. }
  1264. /***********************************************************************
  1265. * addSubclass
  1266. * Adds subcls as a subclass of supercls.
  1267. * Locking: runtimeLock must be held by the caller.
  1268. **********************************************************************/
  1269. static void addSubclass(Class supercls, Class subcls)
  1270. {
  1271. runtimeLock.assertLocked();
  1272. if (supercls && subcls) {
  1273. assert(supercls->isRealized());
  1274. assert(subcls->isRealized());
  1275. subcls->data()->nextSiblingClass = supercls->data()->firstSubclass;
  1276. supercls->data()->firstSubclass = subcls;
  1277. if (supercls->hasCxxCtor()) {
  1278. subcls->setHasCxxCtor();
  1279. }
  1280. if (supercls->hasCxxDtor()) {
  1281. subcls->setHasCxxDtor();
  1282. }
  1283. if (supercls->hasCustomRR()) {
  1284. subcls->setHasCustomRR(true);
  1285. }
  1286. if (supercls->hasCustomAWZ()) {
  1287. subcls->setHasCustomAWZ(true);
  1288. }
  1289. // Special case: instancesRequireRawIsa does not propagate
  1290. // from root class to root metaclass
  1291. if (supercls->instancesRequireRawIsa() && supercls->superclass) {
  1292. subcls->setInstancesRequireRawIsa(true);
  1293. }
  1294. }
  1295. }
  1296. /***********************************************************************
  1297. * removeSubclass
  1298. * Removes subcls as a subclass of supercls.
  1299. * Locking: runtimeLock must be held by the caller.
  1300. **********************************************************************/
  1301. static void removeSubclass(Class supercls, Class subcls)
  1302. {
  1303. runtimeLock.assertLocked();
  1304. assert(supercls->isRealized());
  1305. assert(subcls->isRealized());
  1306. assert(subcls->superclass == supercls);
  1307. Class *cp;
  1308. for (cp = &supercls->data()->firstSubclass;
  1309. *cp && *cp != subcls;
  1310. cp = &(*cp)->data()->nextSiblingClass)
  1311. ;
  1312. assert(*cp == subcls);
  1313. *cp = subcls->data()->nextSiblingClass;
  1314. }
  1315. /***********************************************************************
  1316. * protocols
  1317. * Returns the protocol name => protocol map for protocols.
  1318. * Locking: runtimeLock must read- or write-locked by the caller
  1319. **********************************************************************/
  1320. static NXMapTable *protocols(void)
  1321. {
  1322. static NXMapTable *protocol_map = nil;
  1323. runtimeLock.assertLocked();
  1324. INIT_ONCE_PTR(protocol_map,
  1325. NXCreateMapTable(NXStrValueMapPrototype, 16),
  1326. NXFreeMapTable(v) );
  1327. return protocol_map;
  1328. }
  1329. /***********************************************************************
  1330. * getProtocol
  1331. * Looks up a protocol by name. Demangled Swift names are recognized.
  1332. * Locking: runtimeLock must be read- or write-locked by the caller.
  1333. **********************************************************************/
  1334. static Protocol *getProtocol(const char *name)
  1335. {
  1336. runtimeLock.assertLocked();
  1337. // Try name as-is.
  1338. Protocol *result = (Protocol *)NXMapGet(protocols(), name);
  1339. if (result) return result;
  1340. // Try Swift-mangled equivalent of the given name.
  1341. if (char *swName = copySwiftV1MangledName(name, true/*isProtocol*/)) {
  1342. result = (Protocol *)NXMapGet(protocols(), swName);
  1343. free(swName);
  1344. return result;
  1345. }
  1346. return nil;
  1347. }
  1348. /***********************************************************************
  1349. * remapProtocol
  1350. * Returns the live protocol pointer for proto, which may be pointing to
  1351. * a protocol struct that has been reallocated.
  1352. * Locking: runtimeLock must be read- or write-locked by the caller
  1353. **********************************************************************/
  1354. static protocol_t *remapProtocol(protocol_ref_t proto)
  1355. {
  1356. runtimeLock.assertLocked();
  1357. protocol_t *newproto = (protocol_t *)
  1358. getProtocol(((protocol_t *)proto)->mangledName);
  1359. return newproto ? newproto : (protocol_t *)proto;
  1360. }
  1361. /***********************************************************************
  1362. * remapProtocolRef
  1363. * Fix up a protocol ref, in case the protocol referenced has been reallocated.
  1364. * Locking: runtimeLock must be read- or write-locked by the caller
  1365. **********************************************************************/
  1366. static size_t UnfixedProtocolReferences;
  1367. static void remapProtocolRef(protocol_t **protoref)
  1368. {
  1369. runtimeLock.assertLocked();
  1370. protocol_t *newproto = remapProtocol((protocol_ref_t)*protoref);
  1371. if (*protoref != newproto) {
  1372. *protoref = newproto;
  1373. UnfixedProtocolReferences++;
  1374. }
  1375. }
  1376. /***********************************************************************
  1377. * moveIvars
  1378. * Slides a class's ivars to accommodate the given superclass size.
  1379. * Ivars are NOT compacted to compensate for a superclass that shrunk.
  1380. * Locking: runtimeLock must be held by the caller.
  1381. **********************************************************************/
  1382. static void moveIvars(class_ro_t *ro, uint32_t superSize)
  1383. {
  1384. runtimeLock.assertLocked();
  1385. uint32_t diff;
  1386. assert(superSize > ro->instanceStart);
  1387. diff = superSize - ro->instanceStart;
  1388. if (ro->ivars) {
  1389. // Find maximum alignment in this class's ivars
  1390. uint32_t maxAlignment = 1;
  1391. for (const auto& ivar : *ro->ivars) {
  1392. if (!ivar.offset) continue; // anonymous bitfield
  1393. uint32_t alignment = ivar.alignment();
  1394. if (alignment > maxAlignment) maxAlignment = alignment;
  1395. }
  1396. // Compute a slide value that preserves that alignment
  1397. uint32_t alignMask = maxAlignment - 1;
  1398. diff = (diff + alignMask) & ~alignMask;
  1399. // Slide all of this class's ivars en masse
  1400. for (const auto& ivar : *ro->ivars) {
  1401. if (!ivar.offset) continue; // anonymous bitfield
  1402. uint32_t oldOffset = (uint32_t)*ivar.offset;
  1403. uint32_t newOffset = oldOffset + diff;
  1404. *ivar.offset = newOffset;
  1405. if (PrintIvars) {
  1406. _objc_inform("IVARS: offset %u -> %u for %s "
  1407. "(size %u, align %u)",
  1408. oldOffset, newOffset, ivar.name,
  1409. ivar.size, ivar.alignment());
  1410. }
  1411. }
  1412. }
  1413. *(uint32_t *)&ro->instanceStart += diff;
  1414. *(uint32_t *)&ro->instanceSize += diff;
  1415. }
  1416. static void reconcileInstanceVariables(Class cls, Class supercls, const class_ro_t*& ro)
  1417. {
  1418. class_rw_t *rw = cls->data();
  1419. assert(supercls);
  1420. assert(!cls->isMetaClass());
  1421. /* debug: print them all before sliding
  1422. if (ro->ivars) {
  1423. for (const auto& ivar : *ro->ivars) {
  1424. if (!ivar.offset) continue; // anonymous bitfield
  1425. _objc_inform("IVARS: %s.%s (offset %u, size %u, align %u)",
  1426. ro->name, ivar.name,
  1427. *ivar.offset, ivar.size, ivar.alignment());
  1428. }
  1429. }
  1430. */
  1431. // Non-fragile ivars - reconcile this class with its superclass
  1432. const class_ro_t *super_ro = supercls->data()->ro;
  1433. if (DebugNonFragileIvars) {
  1434. // Debugging: Force non-fragile ivars to slide.
  1435. // Intended to find compiler, runtime, and program bugs.
  1436. // If it fails with this and works without, you have a problem.
  1437. // Operation: Reset everything to 0 + misalignment.
  1438. // Then force the normal sliding logic to push everything back.
  1439. // Exceptions: root classes, metaclasses, *NSCF* classes,
  1440. // __CF* classes, NSConstantString, NSSimpleCString
  1441. // (already know it's not root because supercls != nil)
  1442. const char *clsname = cls->mangledName();
  1443. if (!strstr(clsname, "NSCF") &&
  1444. 0 != strncmp(clsname, "__CF", 4) &&
  1445. 0 != strcmp(clsname, "NSConstantString") &&
  1446. 0 != strcmp(clsname, "NSSimpleCString"))
  1447. {
  1448. uint32_t oldStart = ro->instanceStart;
  1449. class_ro_t *ro_w = make_ro_writeable(rw);
  1450. ro = rw->ro;
  1451. // Find max ivar alignment in class.
  1452. // default to word size to simplify ivar update
  1453. uint32_t alignment = 1<<WORD_SHIFT;
  1454. if (ro->ivars) {
  1455. for (const auto& ivar : *ro->ivars) {
  1456. if (ivar.alignment() > alignment) {
  1457. alignment = ivar.alignment();
  1458. }
  1459. }
  1460. }
  1461. uint32_t misalignment = ro->instanceStart % alignment;
  1462. uint32_t delta = ro->instanceStart - misalignment;
  1463. ro_w->instanceStart = misalignment;
  1464. ro_w->instanceSize -= delta;
  1465. if (PrintIvars) {
  1466. _objc_inform("IVARS: DEBUG: forcing ivars for class '%s' "
  1467. "to slide (instanceStart %zu -> %zu)",
  1468. cls->nameForLogging(), (size_t)oldStart,
  1469. (size_t)ro->instanceStart);
  1470. }
  1471. if (ro->ivars) {
  1472. for (const auto& ivar : *ro->ivars) {
  1473. if (!ivar.offset) continue; // anonymous bitfield
  1474. *ivar.offset -= delta;
  1475. }
  1476. }
  1477. }
  1478. }
  1479. if (ro->instanceStart >= super_ro->instanceSize) {
  1480. // Superclass has not overgrown its space. We're done here.
  1481. return;
  1482. }
  1483. // fixme can optimize for "class has no new ivars", etc
  1484. if (ro->instanceStart < super_ro->instanceSize) {
  1485. // Superclass has changed size. This class's ivars must move.
  1486. // Also slide layout bits in parallel.
  1487. // This code is incapable of compacting the subclass to
  1488. // compensate for a superclass that shrunk, so don't do that.
  1489. if (PrintIvars) {
  1490. _objc_inform("IVARS: sliding ivars for class %s "
  1491. "(superclass was %u bytes, now %u)",
  1492. cls->nameForLogging(), ro->instanceStart,
  1493. super_ro->instanceSize);
  1494. }
  1495. class_ro_t *ro_w = make_ro_writeable(rw);
  1496. ro = rw->ro;
  1497. moveIvars(ro_w, super_ro->instanceSize);
  1498. gdb_objc_class_changed(cls, OBJC_CLASS_IVARS_CHANGED, ro->name);
  1499. }
  1500. }
  1501. /***********************************************************************
  1502. * realizeClass
  1503. * Performs first-time initialization on class cls,
  1504. * including allocating its read-write data.
  1505. * Returns the real class structure for the class.
  1506. * Locking: runtimeLock must be write-locked by the caller
  1507. **********************************************************************/
  1508. static Class realizeClass(Class cls)
  1509. {
  1510. runtimeLock.assertLocked();
  1511. const class_ro_t *ro;
  1512. class_rw_t *rw;
  1513. Class supercls;
  1514. Class metacls;
  1515. bool isMeta;
  1516. if (!cls) return nil;
  1517. if (cls->isRealized()) return cls;
  1518. assert(cls == remapClass(cls));
  1519. // fixme verify class is not in an un-dlopened part of the shared cache?
  1520. ro = (const class_ro_t *)cls->data();
  1521. if (ro->flags & RO_FUTURE) {
  1522. // This was a future class. rw data is already allocated.
  1523. rw = cls->data();
  1524. ro = cls->data()->ro;
  1525. cls->changeInfo(RW_REALIZED|RW_REALIZING, RW_FUTURE);
  1526. } else {
  1527. // Normal class. Allocate writeable class data.
  1528. rw = (class_rw_t *)calloc(sizeof(class_rw_t), 1);
  1529. rw->ro = ro;
  1530. rw->flags = RW_REALIZED|RW_REALIZING;
  1531. cls->setData(rw);
  1532. }
  1533. isMeta = ro->flags & RO_META;
  1534. rw->version = isMeta ? 7 : 0; // old runtime went up to 6
  1535. // Choose an index for this class.
  1536. // Sets cls->instancesRequireRawIsa if indexes no more indexes are available
  1537. cls->chooseClassArrayIndex();
  1538. if (PrintConnecting) {
  1539. _objc_inform("CLASS: realizing class '%s'%s %p %p #%u",
  1540. cls->nameForLogging(), isMeta ? " (meta)" : "",
  1541. (void*)cls, ro, cls->classArrayIndex());
  1542. }
  1543. // Realize superclass and metaclass, if they aren't already.
  1544. // This needs to be done after RW_REALIZED is set above, for root classes.
  1545. // This needs to be done after class index is chosen, for root metaclasses.
  1546. supercls = realizeClass(remapClass(cls->superclass));
  1547. metacls = realizeClass(remapClass(cls->ISA()));
  1548. #if SUPPORT_NONPOINTER_ISA
  1549. // Disable non-pointer isa for some classes and/or platforms.
  1550. // Set instancesRequireRawIsa.
  1551. bool instancesRequireRawIsa = cls->instancesRequireRawIsa();
  1552. bool rawIsaIsInherited = false;
  1553. static bool hackedDispatch = false;
  1554. if (DisableNonpointerIsa) {
  1555. // Non-pointer isa disabled by environment or app SDK version
  1556. instancesRequireRawIsa = true;
  1557. }
  1558. else if (!hackedDispatch && !(ro->flags & RO_META) &&
  1559. 0 == strcmp(ro->name, "OS_object"))
  1560. {
  1561. // hack for libdispatch et al - isa also acts as vtable pointer
  1562. hackedDispatch = true;
  1563. instancesRequireRawIsa = true;
  1564. }
  1565. else if (supercls && supercls->superclass &&
  1566. supercls->instancesRequireRawIsa())
  1567. {
  1568. // This is also propagated by addSubclass()
  1569. // but nonpointer isa setup needs it earlier.
  1570. // Special case: instancesRequireRawIsa does not propagate
  1571. // from root class to root metaclass
  1572. instancesRequireRawIsa = true;
  1573. rawIsaIsInherited = true;
  1574. }
  1575. if (instancesRequireRawIsa) {
  1576. cls->setInstancesRequireRawIsa(rawIsaIsInherited);
  1577. }
  1578. // SUPPORT_NONPOINTER_ISA
  1579. #endif
  1580. // Update superclass and metaclass in case of remapping
  1581. cls->superclass = supercls;
  1582. cls->initClassIsa(metacls);
  1583. // Reconcile instance variable offsets / layout.
  1584. // This may reallocate class_ro_t, updating our ro variable.
  1585. if (supercls && !isMeta) reconcileInstanceVariables(cls, supercls, ro);
  1586. // Set fastInstanceSize if it wasn't set already.
  1587. cls->setInstanceSize(ro->instanceSize);
  1588. // Copy some flags from ro to rw
  1589. if (ro->flags & RO_HAS_CXX_STRUCTORS) {
  1590. cls->setHasCxxDtor();
  1591. if (! (ro->flags & RO_HAS_CXX_DTOR_ONLY)) {
  1592. cls->setHasCxxCtor();
  1593. }
  1594. }
  1595. // Connect this class to its superclass's subclass lists
  1596. if (supercls) {
  1597. addSubclass(supercls, cls);
  1598. } else {
  1599. addRootClass(cls);
  1600. }
  1601. // Attach categories
  1602. methodizeClass(cls);
  1603. return cls;
  1604. }
  1605. /***********************************************************************
  1606. * missingWeakSuperclass
  1607. * Return YES if some superclass of cls was weak-linked and is missing.
  1608. **********************************************************************/
  1609. static bool
  1610. missingWeakSuperclass(Class cls)
  1611. {
  1612. assert(!cls->isRealized());
  1613. if (!cls->superclass) {
  1614. // superclass nil. This is normal for root classes only.
  1615. return (!(cls->data()->flags & RO_ROOT));
  1616. } else {
  1617. // superclass not nil. Check if a higher superclass is missing.
  1618. Class supercls = remapClass(cls->superclass);
  1619. assert(cls != cls->superclass);
  1620. assert(cls != supercls);
  1621. if (!supercls) return YES;
  1622. if (supercls->isRealized()) return NO;
  1623. return missingWeakSuperclass(supercls);
  1624. }
  1625. }
  1626. /***********************************************************************
  1627. * realizeAllClassesInImage
  1628. * Non-lazily realizes all unrealized classes in the given image.
  1629. * Locking: runtimeLock must be held by the caller.
  1630. **********************************************************************/
  1631. static void realizeAllClassesInImage(header_info *hi)
  1632. {
  1633. runtimeLock.assertLocked();
  1634. size_t count, i;
  1635. classref_t *classlist;
  1636. if (hi->areAllClassesRealized()) return;
  1637. classlist = _getObjc2ClassList(hi, &count);
  1638. for (i = 0; i < count; i++) {
  1639. realizeClass(remapClass(classlist[i]));
  1640. }
  1641. hi->setAllClassesRealized(YES);
  1642. }
  1643. /***********************************************************************
  1644. * realizeAllClasses
  1645. * Non-lazily realizes all unrealized classes in all known images.
  1646. * Locking: runtimeLock must be held by the caller.
  1647. **********************************************************************/
  1648. static void realizeAllClasses(void)
  1649. {
  1650. runtimeLock.assertLocked();
  1651. header_info *hi;
  1652. for (hi = FirstHeader; hi; hi = hi->getNext()) {
  1653. realizeAllClassesInImage(hi);
  1654. }
  1655. }
  1656. /***********************************************************************
  1657. * _objc_allocateFutureClass
  1658. * Allocate an unresolved future class for the given class name.
  1659. * Returns any existing allocation if one was already made.
  1660. * Assumes the named class doesn't exist yet.
  1661. * Locking: acquires runtimeLock
  1662. **********************************************************************/
  1663. Class _objc_allocateFutureClass(const char *name)
  1664. {
  1665. mutex_locker_t lock(runtimeLock);
  1666. Class cls;
  1667. NXMapTable *map = futureNamedClasses();
  1668. if ((cls = (Class)NXMapGet(map, name))) {
  1669. // Already have a future class for this name.
  1670. return cls;
  1671. }
  1672. cls = _calloc_class(sizeof(objc_class));
  1673. addFutureNamedClass(name, cls);
  1674. return cls;
  1675. }
  1676. /***********************************************************************
  1677. * objc_getFutureClass. Return the id of the named class.
  1678. * If the class does not exist, return an uninitialized class
  1679. * structure that will be used for the class when and if it
  1680. * does get loaded.
  1681. * Not thread safe.
  1682. **********************************************************************/
  1683. Class objc_getFutureClass(const char *name)
  1684. {
  1685. Class cls;
  1686. // YES unconnected, NO class handler
  1687. // (unconnected is OK because it will someday be the real class)
  1688. cls = look_up_class(name, YES, NO);
  1689. if (cls) {
  1690. if (PrintFuture) {
  1691. _objc_inform("FUTURE: found %p already in use for %s",
  1692. (void*)cls, name);
  1693. }
  1694. return cls;
  1695. }
  1696. // No class or future class with that name yet. Make one.
  1697. // fixme not thread-safe with respect to
  1698. // simultaneous library load or getFutureClass.
  1699. return _objc_allocateFutureClass(name);
  1700. }
  1701. BOOL _class_isFutureClass(Class cls)
  1702. {
  1703. return cls && cls->isFuture();
  1704. }
  1705. /***********************************************************************
  1706. * _objc_flush_caches
  1707. * Flushes all caches.
  1708. * (Historical behavior: flush caches for cls, its metaclass,
  1709. * and subclasses thereof. Nil flushes all classes.)
  1710. * Locking: acquires runtimeLock
  1711. **********************************************************************/
  1712. static void flushCaches(Class cls)
  1713. {
  1714. runtimeLock.assertLocked();
  1715. mutex_locker_t lock(cacheUpdateLock);
  1716. if (cls) {
  1717. foreach_realized_class_and_subclass(cls, ^(Class c){
  1718. cache_erase_nolock(c);
  1719. });
  1720. }
  1721. else {
  1722. foreach_realized_class_and_metaclass(^(Class c){
  1723. cache_erase_nolock(c);
  1724. });
  1725. }
  1726. }
  1727. void _objc_flush_caches(Class cls)
  1728. {
  1729. {
  1730. mutex_locker_t lock(runtimeLock);
  1731. flushCaches(cls);
  1732. if (cls && cls->superclass && cls != cls->getIsa()) {
  1733. flushCaches(cls->getIsa());
  1734. } else {
  1735. // cls is a root class or root metaclass. Its metaclass is itself
  1736. // or a subclass so the metaclass caches were already flushed.
  1737. }
  1738. }
  1739. if (!cls) {
  1740. // collectALot if cls==nil
  1741. mutex_locker_t lock(cacheUpdateLock);
  1742. cache_collect(true);
  1743. }
  1744. }
  1745. /***********************************************************************
  1746. * map_images
  1747. * Process the given images which are being mapped in by dyld.
  1748. * Calls ABI-agnostic code after taking ABI-specific locks.
  1749. *
  1750. * Locking: write-locks runtimeLock
  1751. **********************************************************************/
  1752. void
  1753. map_images(unsigned count, const char * const paths[],
  1754. const struct mach_header * const mhdrs[])
  1755. {
  1756. mutex_locker_t lock(runtimeLock);
  1757. return map_images_nolock(count, paths, mhdrs);
  1758. }
  1759. /***********************************************************************
  1760. * load_images
  1761. * Process +load in the given images which are being mapped in by dyld.
  1762. *
  1763. * Locking: write-locks runtimeLock and loadMethodLock
  1764. **********************************************************************/
  1765. extern bool hasLoadMethods(const headerType *mhdr);
  1766. extern void prepare_load_methods(const headerType *mhdr);
  1767. void
  1768. load_images(const char *path __unused, const struct mach_header *mh)
  1769. {
  1770. // Return without taking locks if there are no +load methods here.
  1771. if (!hasLoadMethods((const headerType *)mh)) return;
  1772. recursive_mutex_locker_t lock(loadMethodLock);
  1773. // Discover load methods
  1774. {
  1775. mutex_locker_t lock2(runtimeLock);
  1776. prepare_load_methods((const headerType *)mh);
  1777. }
  1778. // Call +load methods (without runtimeLock - re-entrant)
  1779. call_load_methods();
  1780. }
  1781. /***********************************************************************
  1782. * unmap_image
  1783. * Process the given image which is about to be unmapped by dyld.
  1784. *
  1785. * Locking: write-locks runtimeLock and loadMethodLock
  1786. **********************************************************************/
  1787. void
  1788. unmap_image(const char *path __unused, const struct mach_header *mh)
  1789. {
  1790. recursive_mutex_locker_t lock(loadMethodLock);
  1791. mutex_locker_t lock2(runtimeLock);
  1792. unmap_image_nolock(mh);
  1793. }
  1794. /***********************************************************************
  1795. * mustReadClasses
  1796. * Preflight check in advance of readClass() from an image.
  1797. **********************************************************************/
  1798. bool mustReadClasses(header_info *hi)
  1799. {
  1800. const char *reason;
  1801. // If the image is not preoptimized then we must read classes.
  1802. if (!hi->isPreoptimized()) {
  1803. reason = nil; // Don't log this one because it is noisy.
  1804. goto readthem;
  1805. }
  1806. // If iOS simulator then we must read classes.
  1807. #if TARGET_OS_SIMULATOR
  1808. reason = "the image is for iOS simulator";
  1809. goto readthem;
  1810. #endif
  1811. assert(!hi->isBundle()); // no MH_BUNDLE in shared cache
  1812. // If the image may have missing weak superclasses then we must read classes
  1813. if (!noMissingWeakSuperclasses()) {
  1814. reason = "the image may contain classes with missing weak superclasses";
  1815. goto readthem;
  1816. }
  1817. // If there are unresolved future classes then we must read classes.
  1818. if (haveFutureNamedClasses()) {
  1819. reason = "there are unresolved future classes pending";
  1820. goto readthem;
  1821. }
  1822. // readClass() does not need to do anything.
  1823. return NO;
  1824. readthem:
  1825. if (PrintPreopt && reason) {
  1826. _objc_inform("PREOPTIMIZATION: reading classes manually from %s "
  1827. "because %s", hi->fname(), reason);
  1828. }
  1829. return YES;
  1830. }
  1831. /***********************************************************************
  1832. * readClass
  1833. * Read a class and metaclass as written by a compiler.
  1834. * Returns the new class pointer. This could be:
  1835. * - cls
  1836. * - nil (cls has a missing weak-linked superclass)
  1837. * - something else (space for this class was reserved by a future class)
  1838. *
  1839. * Note that all work performed by this function is preflighted by
  1840. * mustReadClasses(). Do not change this function without updating that one.
  1841. *
  1842. * Locking: runtimeLock acquired by map_images or objc_readClassPair
  1843. **********************************************************************/
  1844. Class readClass(Class cls, bool headerIsBundle, bool headerIsPreoptimized)
  1845. {
  1846. const char *mangledName = cls->mangledName();
  1847. if (missingWeakSuperclass(cls)) {
  1848. // No superclass (probably weak-linked).
  1849. // Disavow any knowledge of this subclass.
  1850. if (PrintConnecting) {
  1851. _objc_inform("CLASS: IGNORING class '%s' with "
  1852. "missing weak-linked superclass",
  1853. cls->nameForLogging());
  1854. }
  1855. addRemappedClass(cls, nil);
  1856. cls->superclass = nil;
  1857. return nil;
  1858. }
  1859. // Note: Class __ARCLite__'s hack does not go through here.
  1860. // Class structure fixups that apply to it also need to be
  1861. // performed in non-lazy realization below.
  1862. // These fields should be set to zero because of the
  1863. // binding of _objc_empty_vtable, but OS X 10.8's dyld
  1864. // does not bind shared cache absolute symbols as expected.
  1865. // This (and the __ARCLite__ hack below) can be removed
  1866. // once the simulator drops 10.8 support.
  1867. #if TARGET_OS_SIMULATOR
  1868. if (cls->cache._mask) cls->cache._mask = 0;
  1869. if (cls->cache._occupied) cls->cache._occupied = 0;
  1870. if (cls->ISA()->cache._mask) cls->ISA()->cache._mask = 0;
  1871. if (cls->ISA()->cache._occupied) cls->ISA()->cache._occupied = 0;
  1872. #endif
  1873. Class replacing = nil;
  1874. if (Class newCls = popFutureNamedClass(mangledName)) {
  1875. // This name was previously allocated as a future class.
  1876. // Copy objc_class to future class's struct.
  1877. // Preserve future's rw data block.
  1878. if (newCls->isAnySwift()) {
  1879. _objc_fatal("Can't complete future class request for '%s' "
  1880. "because the real class is too big.",
  1881. cls->nameForLogging());
  1882. }
  1883. class_rw_t *rw = newCls->data();
  1884. const class_ro_t *old_ro = rw->ro;
  1885. memcpy(newCls, cls, sizeof(objc_class));
  1886. rw->ro = (class_ro_t *)newCls->data();
  1887. newCls->setData(rw);
  1888. freeIfMutable((char *)old_ro->name);
  1889. free((void *)old_ro);
  1890. addRemappedClass(cls, newCls);
  1891. replacing = cls;
  1892. cls = newCls;
  1893. }
  1894. if (headerIsPreoptimized && !replacing) {
  1895. // class list built in shared cache
  1896. // fixme strict assert doesn't work because of duplicates
  1897. // assert(cls == getClass(name));
  1898. assert(getClass(mangledName));
  1899. } else {
  1900. addNamedClass(cls, mangledName, replacing);
  1901. addClassTableEntry(cls);
  1902. }
  1903. // for future reference: shared cache never contains MH_BUNDLEs
  1904. if (headerIsBundle) {
  1905. cls->data()->flags |= RO_FROM_BUNDLE;
  1906. cls->ISA()->data()->flags |= RO_FROM_BUNDLE;
  1907. }
  1908. return cls;
  1909. }
  1910. /***********************************************************************
  1911. * readProtocol
  1912. * Read a protocol as written by a compiler.
  1913. **********************************************************************/
  1914. static void
  1915. readProtocol(protocol_t *newproto, Class protocol_class,
  1916. NXMapTable *protocol_map,
  1917. bool headerIsPreoptimized, bool headerIsBundle)
  1918. {
  1919. // This is not enough to make protocols in unloaded bundles safe,
  1920. // but it does prevent crashes when looking up unrelated protocols.
  1921. auto insertFn = headerIsBundle ? NXMapKeyCopyingInsert : NXMapInsert;
  1922. protocol_t *oldproto = (protocol_t *)getProtocol(newproto->mangledName);
  1923. if (oldproto) {
  1924. // Some other definition already won.
  1925. if (PrintProtocols) {
  1926. _objc_inform("PROTOCOLS: protocol at %p is %s "
  1927. "(duplicate of %p)",
  1928. newproto, oldproto->nameForLogging(), oldproto);
  1929. }
  1930. }
  1931. else if (headerIsPreoptimized) {
  1932. // Shared cache initialized the protocol object itself,
  1933. // but in order to allow out-of-cache replacement we need
  1934. // to add it to the protocol table now.
  1935. protocol_t *cacheproto = (protocol_t *)
  1936. getPreoptimizedProtocol(newproto->mangledName);
  1937. protocol_t *installedproto;
  1938. if (cacheproto && cacheproto != newproto) {
  1939. // Another definition in the shared cache wins (because
  1940. // everything in the cache was fixed up to point to it).
  1941. installedproto = cacheproto;
  1942. }
  1943. else {
  1944. // This definition wins.
  1945. installedproto = newproto;
  1946. }
  1947. assert(installedproto->getIsa() == protocol_class);
  1948. assert(installedproto->size >= sizeof(protocol_t));
  1949. insertFn(protocol_map, installedproto->mangledName,
  1950. installedproto);
  1951. if (PrintProtocols) {
  1952. _objc_inform("PROTOCOLS: protocol at %p is %s",
  1953. installedproto, installedproto->nameForLogging());
  1954. if (newproto != installedproto) {
  1955. _objc_inform("PROTOCOLS: protocol at %p is %s "
  1956. "(duplicate of %p)",
  1957. newproto, installedproto->nameForLogging(),
  1958. installedproto);
  1959. }
  1960. }
  1961. }
  1962. else if (newproto->size >= sizeof(protocol_t)) {
  1963. // New protocol from an un-preoptimized image
  1964. // with sufficient storage. Fix it up in place.
  1965. // fixme duplicate protocols from unloadable bundle
  1966. newproto->initIsa(protocol_class); // fixme pinned
  1967. insertFn(protocol_map, newproto->mangledName, newproto);
  1968. if (PrintProtocols) {
  1969. _objc_inform("PROTOCOLS: protocol at %p is %s",
  1970. newproto, newproto->nameForLogging());
  1971. }
  1972. }
  1973. else {
  1974. // New protocol from an un-preoptimized image
  1975. // with insufficient storage. Reallocate it.
  1976. // fixme duplicate protocols from unloadable bundle
  1977. size_t size = max(sizeof(protocol_t), (size_t)newproto->size);
  1978. protocol_t *installedproto = (protocol_t *)calloc(size, 1);
  1979. memcpy(installedproto, newproto, newproto->size);
  1980. installedproto->size = (typeof(installedproto->size))size;
  1981. installedproto->initIsa(protocol_class); // fixme pinned
  1982. insertFn(protocol_map, installedproto->mangledName, installedproto);
  1983. if (PrintProtocols) {
  1984. _objc_inform("PROTOCOLS: protocol at %p is %s ",
  1985. installedproto, installedproto->nameForLogging());
  1986. _objc_inform("PROTOCOLS: protocol at %p is %s "
  1987. "(reallocated to %p)",
  1988. newproto, installedproto->nameForLogging(),
  1989. installedproto);
  1990. }
  1991. }
  1992. }
  1993. /***********************************************************************
  1994. * _read_images
  1995. * Perform initial processing of the headers in the linked
  1996. * list beginning with headerList.
  1997. *
  1998. * Called by: map_images_nolock
  1999. *
  2000. * Locking: runtimeLock acquired by map_images
  2001. **********************************************************************/
  2002. void _read_images(header_info **hList, uint32_t hCount, int totalClasses, int unoptimizedTotalClasses)
  2003. {
  2004. header_info *hi;
  2005. uint32_t hIndex;
  2006. size_t count;
  2007. size_t i;
  2008. Class *resolvedFutureClasses = nil;
  2009. size_t resolvedFutureClassCount = 0;
  2010. static bool doneOnce;
  2011. TimeLogger ts(PrintImageTimes);
  2012. runtimeLock.assertLocked();
  2013. #define EACH_HEADER \
  2014. hIndex = 0; \
  2015. hIndex < hCount && (hi = hList[hIndex]); \
  2016. hIndex++
  2017. if (!doneOnce) {
  2018. doneOnce = YES;
  2019. #if SUPPORT_NONPOINTER_ISA
  2020. // Disable non-pointer isa under some conditions.
  2021. # if SUPPORT_INDEXED_ISA
  2022. // Disable nonpointer isa if any image contains old Swift code
  2023. for (EACH_HEADER) {
  2024. if (hi->info()->containsSwift() &&
  2025. hi->info()->swiftVersion() < objc_image_info::SwiftVersion3)
  2026. {
  2027. DisableNonpointerIsa = true;
  2028. if (PrintRawIsa) {
  2029. _objc_inform("RAW ISA: disabling non-pointer isa because "
  2030. "the app or a framework contains Swift code "
  2031. "older than Swift 3.0");
  2032. }
  2033. break;
  2034. }
  2035. }
  2036. # endif
  2037. # if TARGET_OS_OSX
  2038. // Disable non-pointer isa if the app is too old
  2039. // (linked before OS X 10.11)
  2040. if (dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_11) {
  2041. DisableNonpointerIsa = true;
  2042. if (PrintRawIsa) {
  2043. _objc_inform("RAW ISA: disabling non-pointer isa because "
  2044. "the app is too old (SDK version " SDK_FORMAT ")",
  2045. FORMAT_SDK(dyld_get_program_sdk_version()));
  2046. }
  2047. }
  2048. // Disable non-pointer isa if the app has a __DATA,__objc_rawisa section
  2049. // New apps that load old extensions may need this.
  2050. for (EACH_HEADER) {
  2051. if (hi->mhdr()->filetype != MH_EXECUTE) continue;
  2052. unsigned long size;
  2053. if (getsectiondata(hi->mhdr(), "__DATA", "__objc_rawisa", &size)) {
  2054. DisableNonpointerIsa = true;
  2055. if (PrintRawIsa) {
  2056. _objc_inform("RAW ISA: disabling non-pointer isa because "
  2057. "the app has a __DATA,__objc_rawisa section");
  2058. }
  2059. }
  2060. break; // assume only one MH_EXECUTE image
  2061. }
  2062. # endif
  2063. #endif
  2064. if (DisableTaggedPointers) {
  2065. disableTaggedPointers();
  2066. }
  2067. initializeTaggedPointerObfuscator();
  2068. if (PrintConnecting) {
  2069. _objc_inform("CLASS: found %d classes during launch", totalClasses);
  2070. }
  2071. // namedClasses
  2072. // Preoptimized classes don't go in this table.
  2073. // 4/3 is NXMapTable's load factor
  2074. int namedClassesSize =
  2075. (isPreoptimized() ? unoptimizedTotalClasses : totalClasses) * 4 / 3;
  2076. gdb_objc_realized_classes =
  2077. NXCreateMapTable(NXStrValueMapPrototype, namedClassesSize);
  2078. allocatedClasses = NXCreateHashTable(NXPtrPrototype, 0, nil);
  2079. ts.log("IMAGE TIMES: first time tasks");
  2080. }
  2081. // Discover classes. Fix up unresolved future classes. Mark bundle classes.
  2082. for (EACH_HEADER) {
  2083. classref_t *classlist = _getObjc2ClassList(hi, &count);
  2084. if (! mustReadClasses(hi)) {
  2085. // Image is sufficiently optimized that we need not call readClass()
  2086. continue;
  2087. }
  2088. bool headerIsBundle = hi->isBundle();
  2089. bool headerIsPreoptimized = hi->isPreoptimized();
  2090. for (i = 0; i < count; i++) {
  2091. Class cls = (Class)classlist[i];
  2092. Class newCls = readClass(cls, headerIsBundle, headerIsPreoptimized);
  2093. if (newCls != cls && newCls) {
  2094. // Class was moved but not deleted. Currently this occurs
  2095. // only when the new class resolved a future class.
  2096. // Non-lazily realize the class below.
  2097. resolvedFutureClasses = (Class *)
  2098. realloc(resolvedFutureClasses,
  2099. (resolvedFutureClassCount+1) * sizeof(Class));
  2100. resolvedFutureClasses[resolvedFutureClassCount++] = newCls;
  2101. }
  2102. }
  2103. }
  2104. ts.log("IMAGE TIMES: discover classes");
  2105. // Fix up remapped classes
  2106. // Class list and nonlazy class list remain unremapped.
  2107. // Class refs and super refs are remapped for message dispatching.
  2108. if (!noClassesRemapped()) {
  2109. for (EACH_HEADER) {
  2110. Class *classrefs = _getObjc2ClassRefs(hi, &count);
  2111. for (i = 0; i < count; i++) {
  2112. remapClassRef(&classrefs[i]);
  2113. }
  2114. // fixme why doesn't test future1 catch the absence of this?
  2115. classrefs = _getObjc2SuperRefs(hi, &count);
  2116. for (i = 0; i < count; i++) {
  2117. remapClassRef(&classrefs[i]);
  2118. }
  2119. }
  2120. }
  2121. ts.log("IMAGE TIMES: remap classes");
  2122. // Fix up @selector references
  2123. static size_t UnfixedSelectors;
  2124. {
  2125. mutex_locker_t lock(selLock);
  2126. for (EACH_HEADER) {
  2127. if (hi->isPreoptimized()) continue;
  2128. bool isBundle = hi->isBundle();
  2129. SEL *sels = _getObjc2SelectorRefs(hi, &count);
  2130. UnfixedSelectors += count;
  2131. for (i = 0; i < count; i++) {
  2132. const char *name = sel_cname(sels[i]);
  2133. sels[i] = sel_registerNameNoLock(name, isBundle);
  2134. }
  2135. }
  2136. }
  2137. ts.log("IMAGE TIMES: fix up selector references");
  2138. #if SUPPORT_FIXUP
  2139. // Fix up old objc_msgSend_fixup call sites
  2140. for (EACH_HEADER) {
  2141. message_ref_t *refs = _getObjc2MessageRefs(hi, &count);
  2142. if (count == 0) continue;
  2143. if (PrintVtables) {
  2144. _objc_inform("VTABLES: repairing %zu unsupported vtable dispatch "
  2145. "call sites in %s", count, hi->fname());
  2146. }
  2147. for (i = 0; i < count; i++) {
  2148. fixupMessageRef(refs+i);
  2149. }
  2150. }
  2151. ts.log("IMAGE TIMES: fix up objc_msgSend_fixup");
  2152. #endif
  2153. // Discover protocols. Fix up protocol refs.
  2154. for (EACH_HEADER) {
  2155. extern objc_class OBJC_CLASS_$_Protocol;
  2156. Class cls = (Class)&OBJC_CLASS_$_Protocol;
  2157. assert(cls);
  2158. NXMapTable *protocol_map = protocols();
  2159. bool isPreoptimized = hi->isPreoptimized();
  2160. bool isBundle = hi->isBundle();
  2161. protocol_t **protolist = _getObjc2ProtocolList(hi, &count);
  2162. for (i = 0; i < count; i++) {
  2163. readProtocol(protolist[i], cls, protocol_map,
  2164. isPreoptimized, isBundle);
  2165. }
  2166. }
  2167. ts.log("IMAGE TIMES: discover protocols");
  2168. // Fix up @protocol references
  2169. // Preoptimized images may have the right
  2170. // answer already but we don't know for sure.
  2171. for (EACH_HEADER) {
  2172. protocol_t **protolist = _getObjc2ProtocolRefs(hi, &count);
  2173. for (i = 0; i < count; i++) {
  2174. remapProtocolRef(&protolist[i]);
  2175. }
  2176. }
  2177. ts.log("IMAGE TIMES: fix up @protocol references");
  2178. // Realize non-lazy classes (for +load methods and static instances)
  2179. for (EACH_HEADER) {
  2180. classref_t *classlist =
  2181. _getObjc2NonlazyClassList(hi, &count);
  2182. for (i = 0; i < count; i++) {
  2183. Class cls = remapClass(classlist[i]);
  2184. if (!cls) continue;
  2185. // hack for class __ARCLite__, which didn't get this above
  2186. #if TARGET_OS_SIMULATOR
  2187. if (cls->cache._buckets == (void*)&_objc_empty_cache &&
  2188. (cls->cache._mask || cls->cache._occupied))
  2189. {
  2190. cls->cache._mask = 0;
  2191. cls->cache._occupied = 0;
  2192. }
  2193. if (cls->ISA()->cache._buckets == (void*)&_objc_empty_cache &&
  2194. (cls->ISA()->cache._mask || cls->ISA()->cache._occupied))
  2195. {
  2196. cls->ISA()->cache._mask = 0;
  2197. cls->ISA()->cache._occupied = 0;
  2198. }
  2199. #endif
  2200. addClassTableEntry(cls);
  2201. realizeClass(cls);
  2202. }
  2203. }
  2204. ts.log("IMAGE TIMES: realize non-lazy classes");
  2205. // Realize newly-resolved future classes, in case CF manipulates them
  2206. if (resolvedFutureClasses) {
  2207. for (i = 0; i < resolvedFutureClassCount; i++) {
  2208. realizeClass(resolvedFutureClasses[i]);
  2209. resolvedFutureClasses[i]->setInstancesRequireRawIsa(false/*inherited*/);
  2210. }
  2211. free(resolvedFutureClasses);
  2212. }
  2213. ts.log("IMAGE TIMES: realize future classes");
  2214. // Discover categories.
  2215. for (EACH_HEADER) {
  2216. category_t **catlist =
  2217. _getObjc2CategoryList(hi, &count);
  2218. bool hasClassProperties = hi->info()->hasCategoryClassProperties();
  2219. for (i = 0; i < count; i++) {
  2220. category_t *cat = catlist[i];
  2221. Class cls = remapClass(cat->cls);
  2222. if (!cls) {
  2223. // Category's target class is missing (probably weak-linked).
  2224. // Disavow any knowledge of this category.
  2225. catlist[i] = nil;
  2226. if (PrintConnecting) {
  2227. _objc_inform("CLASS: IGNORING category \?\?\?(%s) %p with "
  2228. "missing weak-linked target class",
  2229. cat->name, cat);
  2230. }
  2231. continue;
  2232. }
  2233. // Process this category.
  2234. // First, register the category with its target class.
  2235. // Then, rebuild the class's method lists (etc) if
  2236. // the class is realized.
  2237. bool classExists = NO;
  2238. if (cat->instanceMethods || cat->protocols
  2239. || cat->instanceProperties)
  2240. {
  2241. addUnattachedCategoryForClass(cat, cls, hi);
  2242. if (cls->isRealized()) {
  2243. remethodizeClass(cls);
  2244. classExists = YES;
  2245. }
  2246. if (PrintConnecting) {
  2247. _objc_inform("CLASS: found category -%s(%s) %s",
  2248. cls->nameForLogging(), cat->name,
  2249. classExists ? "on existing class" : "");
  2250. }
  2251. }
  2252. if (cat->classMethods || cat->protocols
  2253. || (hasClassProperties && cat->_classProperties))
  2254. {
  2255. addUnattachedCategoryForClass(cat, cls->ISA(), hi);
  2256. if (cls->ISA()->isRealized()) {
  2257. remethodizeClass(cls->ISA());
  2258. }
  2259. if (PrintConnecting) {
  2260. _objc_inform("CLASS: found category +%s(%s)",
  2261. cls->nameForLogging(), cat->name);
  2262. }
  2263. }
  2264. }
  2265. }
  2266. ts.log("IMAGE TIMES: discover categories");
  2267. // Category discovery MUST BE LAST to avoid potential races
  2268. // when other threads call the new category code before
  2269. // this thread finishes its fixups.
  2270. // +load handled by prepare_load_methods()
  2271. if (DebugNonFragileIvars) {
  2272. realizeAllClasses();
  2273. }
  2274. // Print preoptimization statistics
  2275. if (PrintPreopt) {
  2276. static unsigned int PreoptTotalMethodLists;
  2277. static unsigned int PreoptOptimizedMethodLists;
  2278. static unsigned int PreoptTotalClasses;
  2279. static unsigned int PreoptOptimizedClasses;
  2280. for (EACH_HEADER) {
  2281. if (hi->isPreoptimized()) {
  2282. _objc_inform("PREOPTIMIZATION: honoring preoptimized selectors "
  2283. "in %s", hi->fname());
  2284. }
  2285. else if (hi->info()->optimizedByDyld()) {
  2286. _objc_inform("PREOPTIMIZATION: IGNORING preoptimized selectors "
  2287. "in %s", hi->fname());
  2288. }
  2289. classref_t *classlist = _getObjc2ClassList(hi, &count);
  2290. for (i = 0; i < count; i++) {
  2291. Class cls = remapClass(classlist[i]);
  2292. if (!cls) continue;
  2293. PreoptTotalClasses++;
  2294. if (hi->isPreoptimized()) {
  2295. PreoptOptimizedClasses++;
  2296. }
  2297. const method_list_t *mlist;
  2298. if ((mlist = ((class_ro_t *)cls->data())->baseMethods())) {
  2299. PreoptTotalMethodLists++;
  2300. if (mlist->isFixedUp()) {
  2301. PreoptOptimizedMethodLists++;
  2302. }
  2303. }
  2304. if ((mlist=((class_ro_t *)cls->ISA()->data())->baseMethods())) {
  2305. PreoptTotalMethodLists++;
  2306. if (mlist->isFixedUp()) {
  2307. PreoptOptimizedMethodLists++;
  2308. }
  2309. }
  2310. }
  2311. }
  2312. _objc_inform("PREOPTIMIZATION: %zu selector references not "
  2313. "pre-optimized", UnfixedSelectors);
  2314. _objc_inform("PREOPTIMIZATION: %u/%u (%.3g%%) method lists pre-sorted",
  2315. PreoptOptimizedMethodLists, PreoptTotalMethodLists,
  2316. PreoptTotalMethodLists
  2317. ? 100.0*PreoptOptimizedMethodLists/PreoptTotalMethodLists
  2318. : 0.0);
  2319. _objc_inform("PREOPTIMIZATION: %u/%u (%.3g%%) classes pre-registered",
  2320. PreoptOptimizedClasses, PreoptTotalClasses,
  2321. PreoptTotalClasses
  2322. ? 100.0*PreoptOptimizedClasses/PreoptTotalClasses
  2323. : 0.0);
  2324. _objc_inform("PREOPTIMIZATION: %zu protocol references not "
  2325. "pre-optimized", UnfixedProtocolReferences);
  2326. }
  2327. #undef EACH_HEADER
  2328. }
  2329. /***********************************************************************
  2330. * prepare_load_methods
  2331. * Schedule +load for classes in this image, any un-+load-ed
  2332. * superclasses in other images, and any categories in this image.
  2333. **********************************************************************/
  2334. // Recursively schedule +load for cls and any un-+load-ed superclasses.
  2335. // cls must already be connected.
  2336. static void schedule_class_load(Class cls)
  2337. {
  2338. if (!cls) return;
  2339. assert(cls->isRealized()); // _read_images should realize
  2340. if (cls->data()->flags & RW_LOADED) return;
  2341. // Ensure superclass-first ordering
  2342. schedule_class_load(cls->superclass);
  2343. add_class_to_loadable_list(cls);
  2344. cls->setInfo(RW_LOADED);
  2345. }
  2346. // Quick scan for +load methods that doesn't take a lock.
  2347. bool hasLoadMethods(const headerType *mhdr)
  2348. {
  2349. size_t count;
  2350. if (_getObjc2NonlazyClassList(mhdr, &count) && count > 0) return true;
  2351. if (_getObjc2NonlazyCategoryList(mhdr, &count) && count > 0) return true;
  2352. return false;
  2353. }
  2354. void prepare_load_methods(const headerType *mhdr)
  2355. {
  2356. size_t count, i;
  2357. runtimeLock.assertLocked();
  2358. classref_t *classlist =
  2359. _getObjc2NonlazyClassList(mhdr, &count);
  2360. for (i = 0; i < count; i++) {
  2361. schedule_class_load(remapClass(classlist[i]));
  2362. }
  2363. category_t **categorylist = _getObjc2NonlazyCategoryList(mhdr, &count);
  2364. for (i = 0; i < count; i++) {
  2365. category_t *cat = categorylist[i];
  2366. Class cls = remapClass(cat->cls);
  2367. if (!cls) continue; // category for ignored weak-linked class
  2368. realizeClass(cls);
  2369. assert(cls->ISA()->isRealized());
  2370. add_category_to_loadable_list(cat);
  2371. }
  2372. }
  2373. /***********************************************************************
  2374. * _unload_image
  2375. * Only handles MH_BUNDLE for now.
  2376. * Locking: write-lock and loadMethodLock acquired by unmap_image
  2377. **********************************************************************/
  2378. void _unload_image(header_info *hi)
  2379. {
  2380. size_t count, i;
  2381. loadMethodLock.assertLocked();
  2382. runtimeLock.assertLocked();
  2383. // Unload unattached categories and categories waiting for +load.
  2384. category_t **catlist = _getObjc2CategoryList(hi, &count);
  2385. for (i = 0; i < count; i++) {
  2386. category_t *cat = catlist[i];
  2387. if (!cat) continue; // category for ignored weak-linked class
  2388. Class cls = remapClass(cat->cls);
  2389. assert(cls); // shouldn't have live category for dead class
  2390. // fixme for MH_DYLIB cat's class may have been unloaded already
  2391. // unattached list
  2392. removeUnattachedCategoryForClass(cat, cls);
  2393. // +load queue
  2394. remove_category_from_loadable_list(cat);
  2395. }
  2396. // Unload classes.
  2397. // Gather classes from both __DATA,__objc_clslist
  2398. // and __DATA,__objc_nlclslist. arclite's hack puts a class in the latter
  2399. // only, and we need to unload that class if we unload an arclite image.
  2400. NXHashTable *classes = NXCreateHashTable(NXPtrPrototype, 0, nil);
  2401. classref_t *classlist;
  2402. classlist = _getObjc2ClassList(hi, &count);
  2403. for (i = 0; i < count; i++) {
  2404. Class cls = remapClass(classlist[i]);
  2405. if (cls) NXHashInsert(classes, cls);
  2406. }
  2407. classlist = _getObjc2NonlazyClassList(hi, &count);
  2408. for (i = 0; i < count; i++) {
  2409. Class cls = remapClass(classlist[i]);
  2410. if (cls) NXHashInsert(classes, cls);
  2411. }
  2412. // First detach classes from each other. Then free each class.
  2413. // This avoid bugs where this loop unloads a subclass before its superclass
  2414. NXHashState hs;
  2415. Class cls;
  2416. hs = NXInitHashState(classes);
  2417. while (NXNextHashState(classes, &hs, (void**)&cls)) {
  2418. remove_class_from_loadable_list(cls);
  2419. detach_class(cls->ISA(), YES);
  2420. detach_class(cls, NO);
  2421. }
  2422. hs = NXInitHashState(classes);
  2423. while (NXNextHashState(classes, &hs, (void**)&cls)) {
  2424. free_class(cls->ISA());
  2425. free_class(cls);
  2426. }
  2427. NXFreeHashTable(classes);
  2428. // XXX FIXME -- Clean up protocols:
  2429. // <rdar://problem/9033191> Support unloading protocols at dylib/image unload time
  2430. // fixme DebugUnload
  2431. }
  2432. /***********************************************************************
  2433. * method_getDescription
  2434. * Returns a pointer to this method's objc_method_description.
  2435. * Locking: none
  2436. **********************************************************************/
  2437. struct objc_method_description *
  2438. method_getDescription(Method m)
  2439. {
  2440. if (!m) return nil;
  2441. return (struct objc_method_description *)m;
  2442. }
  2443. IMP
  2444. method_getImplementation(Method m)
  2445. {
  2446. return m ? m->imp : nil;
  2447. }
  2448. /***********************************************************************
  2449. * method_getName
  2450. * Returns this method's selector.
  2451. * The method must not be nil.
  2452. * The method must already have been fixed-up.
  2453. * Locking: none
  2454. **********************************************************************/
  2455. SEL
  2456. method_getName(Method m)
  2457. {
  2458. if (!m) return nil;
  2459. assert(m->name == sel_registerName(sel_getName(m->name)));
  2460. return m->name;
  2461. }
  2462. /***********************************************************************
  2463. * method_getTypeEncoding
  2464. * Returns this method's old-style type encoding string.
  2465. * The method must not be nil.
  2466. * Locking: none
  2467. **********************************************************************/
  2468. const char *
  2469. method_getTypeEncoding(Method m)
  2470. {
  2471. if (!m) return nil;
  2472. return m->types;
  2473. }
  2474. /***********************************************************************
  2475. * method_setImplementation
  2476. * Sets this method's implementation to imp.
  2477. * The previous implementation is returned.
  2478. **********************************************************************/
  2479. static IMP
  2480. _method_setImplementation(Class cls, method_t *m, IMP imp)
  2481. {
  2482. runtimeLock.assertLocked();
  2483. if (!m) return nil;
  2484. if (!imp) return nil;
  2485. IMP old = m->imp;
  2486. m->imp = imp;
  2487. // Cache updates are slow if cls is nil (i.e. unknown)
  2488. // RR/AWZ updates are slow if cls is nil (i.e. unknown)
  2489. // fixme build list of classes whose Methods are known externally?
  2490. flushCaches(cls);
  2491. updateCustomRR_AWZ(cls, m);
  2492. return old;
  2493. }
  2494. IMP
  2495. method_setImplementation(Method m, IMP imp)
  2496. {
  2497. // Don't know the class - will be slow if RR/AWZ are affected
  2498. // fixme build list of classes whose Methods are known externally?
  2499. mutex_locker_t lock(runtimeLock);
  2500. return _method_setImplementation(Nil, m, imp);
  2501. }
  2502. void method_exchangeImplementations(Method m1, Method m2)
  2503. {
  2504. if (!m1 || !m2) return;
  2505. mutex_locker_t lock(runtimeLock);
  2506. IMP m1_imp = m1->imp;
  2507. m1->imp = m2->imp;
  2508. m2->imp = m1_imp;
  2509. // RR/AWZ updates are slow because class is unknown
  2510. // Cache updates are slow because class is unknown
  2511. // fixme build list of classes whose Methods are known externally?
  2512. flushCaches(nil);
  2513. updateCustomRR_AWZ(nil, m1);
  2514. updateCustomRR_AWZ(nil, m2);
  2515. }
  2516. /***********************************************************************
  2517. * ivar_getOffset
  2518. * fixme
  2519. * Locking: none
  2520. **********************************************************************/
  2521. ptrdiff_t
  2522. ivar_getOffset(Ivar ivar)
  2523. {
  2524. if (!ivar) return 0;
  2525. return *ivar->offset;
  2526. }
  2527. /***********************************************************************
  2528. * ivar_getName
  2529. * fixme
  2530. * Locking: none
  2531. **********************************************************************/
  2532. const char *
  2533. ivar_getName(Ivar ivar)
  2534. {
  2535. if (!ivar) return nil;
  2536. return ivar->name;
  2537. }
  2538. /***********************************************************************
  2539. * ivar_getTypeEncoding
  2540. * fixme
  2541. * Locking: none
  2542. **********************************************************************/
  2543. const char *
  2544. ivar_getTypeEncoding(Ivar ivar)
  2545. {
  2546. if (!ivar) return nil;
  2547. return ivar->type;
  2548. }
  2549. const char *property_getName(objc_property_t prop)
  2550. {
  2551. return prop->name;
  2552. }
  2553. const char *property_getAttributes(objc_property_t prop)
  2554. {
  2555. return prop->attributes;
  2556. }
  2557. objc_property_attribute_t *property_copyAttributeList(objc_property_t prop,
  2558. unsigned int *outCount)
  2559. {
  2560. if (!prop) {
  2561. if (outCount) *outCount = 0;
  2562. return nil;
  2563. }
  2564. mutex_locker_t lock(runtimeLock);
  2565. return copyPropertyAttributeList(prop->attributes,outCount);
  2566. }
  2567. char * property_copyAttributeValue(objc_property_t prop, const char *name)
  2568. {
  2569. if (!prop || !name || *name == '\0') return nil;
  2570. mutex_locker_t lock(runtimeLock);
  2571. return copyPropertyAttributeValue(prop->attributes, name);
  2572. }
  2573. /***********************************************************************
  2574. * getExtendedTypesIndexesForMethod
  2575. * Returns:
  2576. * a is the count of methods in all method lists before m's method list
  2577. * b is the index of m in m's method list
  2578. * a+b is the index of m's extended types in the extended types array
  2579. **********************************************************************/
  2580. static void getExtendedTypesIndexesForMethod(protocol_t *proto, const method_t *m, bool isRequiredMethod, bool isInstanceMethod, uint32_t& a, uint32_t &b)
  2581. {
  2582. a = 0;
  2583. if (proto->instanceMethods) {
  2584. if (isRequiredMethod && isInstanceMethod) {
  2585. b = proto->instanceMethods->indexOfMethod(m);
  2586. return;
  2587. }
  2588. a += proto->instanceMethods->count;
  2589. }
  2590. if (proto->classMethods) {
  2591. if (isRequiredMethod && !isInstanceMethod) {
  2592. b = proto->classMethods->indexOfMethod(m);
  2593. return;
  2594. }
  2595. a += proto->classMethods->count;
  2596. }
  2597. if (proto->optionalInstanceMethods) {
  2598. if (!isRequiredMethod && isInstanceMethod) {
  2599. b = proto->optionalInstanceMethods->indexOfMethod(m);
  2600. return;
  2601. }
  2602. a += proto->optionalInstanceMethods->count;
  2603. }
  2604. if (proto->optionalClassMethods) {
  2605. if (!isRequiredMethod && !isInstanceMethod) {
  2606. b = proto->optionalClassMethods->indexOfMethod(m);
  2607. return;
  2608. }
  2609. a += proto->optionalClassMethods->count;
  2610. }
  2611. }
  2612. /***********************************************************************
  2613. * getExtendedTypesIndexForMethod
  2614. * Returns the index of m's extended types in proto's extended types array.
  2615. **********************************************************************/
  2616. static uint32_t getExtendedTypesIndexForMethod(protocol_t *proto, const method_t *m, bool isRequiredMethod, bool isInstanceMethod)
  2617. {
  2618. uint32_t a;
  2619. uint32_t b;
  2620. getExtendedTypesIndexesForMethod(proto, m, isRequiredMethod,
  2621. isInstanceMethod, a, b);
  2622. return a + b;
  2623. }
  2624. /***********************************************************************
  2625. * fixupProtocolMethodList
  2626. * Fixes up a single method list in a protocol.
  2627. **********************************************************************/
  2628. static void
  2629. fixupProtocolMethodList(protocol_t *proto, method_list_t *mlist,
  2630. bool required, bool instance)
  2631. {
  2632. runtimeLock.assertLocked();
  2633. if (!mlist) return;
  2634. if (mlist->isFixedUp()) return;
  2635. const char **extTypes = proto->extendedMethodTypes();
  2636. fixupMethodList(mlist, true/*always copy for simplicity*/,
  2637. !extTypes/*sort if no extended method types*/);
  2638. if (extTypes) {
  2639. // Sort method list and extended method types together.
  2640. // fixupMethodList() can't do this.
  2641. // fixme COW stomp
  2642. uint32_t count = mlist->count;
  2643. uint32_t prefix;
  2644. uint32_t junk;
  2645. getExtendedTypesIndexesForMethod(proto, &mlist->get(0),
  2646. required, instance, prefix, junk);
  2647. for (uint32_t i = 0; i < count; i++) {
  2648. for (uint32_t j = i+1; j < count; j++) {
  2649. method_t& mi = mlist->get(i);
  2650. method_t& mj = mlist->get(j);
  2651. if (mi.name > mj.name) {
  2652. std::swap(mi, mj);
  2653. std::swap(extTypes[prefix+i], extTypes[prefix+j]);
  2654. }
  2655. }
  2656. }
  2657. }
  2658. }
  2659. /***********************************************************************
  2660. * fixupProtocol
  2661. * Fixes up all of a protocol's method lists.
  2662. **********************************************************************/
  2663. static void
  2664. fixupProtocol(protocol_t *proto)
  2665. {
  2666. runtimeLock.assertLocked();
  2667. if (proto->protocols) {
  2668. for (uintptr_t i = 0; i < proto->protocols->count; i++) {
  2669. protocol_t *sub = remapProtocol(proto->protocols->list[i]);
  2670. if (!sub->isFixedUp()) fixupProtocol(sub);
  2671. }
  2672. }
  2673. fixupProtocolMethodList(proto, proto->instanceMethods, YES, YES);
  2674. fixupProtocolMethodList(proto, proto->classMethods, YES, NO);
  2675. fixupProtocolMethodList(proto, proto->optionalInstanceMethods, NO, YES);
  2676. fixupProtocolMethodList(proto, proto->optionalClassMethods, NO, NO);
  2677. // fixme memory barrier so we can check this with no lock
  2678. proto->setFixedUp();
  2679. }
  2680. /***********************************************************************
  2681. * fixupProtocolIfNeeded
  2682. * Fixes up all of a protocol's method lists if they aren't fixed up already.
  2683. * Locking: write-locks runtimeLock.
  2684. **********************************************************************/
  2685. static void
  2686. fixupProtocolIfNeeded(protocol_t *proto)
  2687. {
  2688. runtimeLock.assertUnlocked();
  2689. assert(proto);
  2690. if (!proto->isFixedUp()) {
  2691. mutex_locker_t lock(runtimeLock);
  2692. fixupProtocol(proto);
  2693. }
  2694. }
  2695. static method_list_t *
  2696. getProtocolMethodList(protocol_t *proto, bool required, bool instance)
  2697. {
  2698. method_list_t **mlistp = nil;
  2699. if (required) {
  2700. if (instance) {
  2701. mlistp = &proto->instanceMethods;
  2702. } else {
  2703. mlistp = &proto->classMethods;
  2704. }
  2705. } else {
  2706. if (instance) {
  2707. mlistp = &proto->optionalInstanceMethods;
  2708. } else {
  2709. mlistp = &proto->optionalClassMethods;
  2710. }
  2711. }
  2712. return *mlistp;
  2713. }
  2714. /***********************************************************************
  2715. * protocol_getMethod_nolock
  2716. * Locking: runtimeLock must be held by the caller
  2717. **********************************************************************/
  2718. static method_t *
  2719. protocol_getMethod_nolock(protocol_t *proto, SEL sel,
  2720. bool isRequiredMethod, bool isInstanceMethod,
  2721. bool recursive)
  2722. {
  2723. runtimeLock.assertLocked();
  2724. if (!proto || !sel) return nil;
  2725. assert(proto->isFixedUp());
  2726. method_list_t *mlist =
  2727. getProtocolMethodList(proto, isRequiredMethod, isInstanceMethod);
  2728. if (mlist) {
  2729. method_t *m = search_method_list(mlist, sel);
  2730. if (m) return m;
  2731. }
  2732. if (recursive && proto->protocols) {
  2733. method_t *m;
  2734. for (uint32_t i = 0; i < proto->protocols->count; i++) {
  2735. protocol_t *realProto = remapProtocol(proto->protocols->list[i]);
  2736. m = protocol_getMethod_nolock(realProto, sel,
  2737. isRequiredMethod, isInstanceMethod,
  2738. true);
  2739. if (m) return m;
  2740. }
  2741. }
  2742. return nil;
  2743. }
  2744. /***********************************************************************
  2745. * protocol_getMethod
  2746. * fixme
  2747. * Locking: acquires runtimeLock
  2748. **********************************************************************/
  2749. Method
  2750. protocol_getMethod(protocol_t *proto, SEL sel, bool isRequiredMethod, bool isInstanceMethod, bool recursive)
  2751. {
  2752. if (!proto) return nil;
  2753. fixupProtocolIfNeeded(proto);
  2754. mutex_locker_t lock(runtimeLock);
  2755. return protocol_getMethod_nolock(proto, sel, isRequiredMethod,
  2756. isInstanceMethod, recursive);
  2757. }
  2758. /***********************************************************************
  2759. * protocol_getMethodTypeEncoding_nolock
  2760. * Return the @encode string for the requested protocol method.
  2761. * Returns nil if the compiler did not emit any extended @encode data.
  2762. * Locking: runtimeLock must be held by the caller
  2763. **********************************************************************/
  2764. const char *
  2765. protocol_getMethodTypeEncoding_nolock(protocol_t *proto, SEL sel,
  2766. bool isRequiredMethod,
  2767. bool isInstanceMethod)
  2768. {
  2769. runtimeLock.assertLocked();
  2770. if (!proto) return nil;
  2771. if (!proto->extendedMethodTypes()) return nil;
  2772. assert(proto->isFixedUp());
  2773. method_t *m =
  2774. protocol_getMethod_nolock(proto, sel,
  2775. isRequiredMethod, isInstanceMethod, false);
  2776. if (m) {
  2777. uint32_t i = getExtendedTypesIndexForMethod(proto, m,
  2778. isRequiredMethod,
  2779. isInstanceMethod);
  2780. return proto->extendedMethodTypes()[i];
  2781. }
  2782. // No method with that name. Search incorporated protocols.
  2783. if (proto->protocols) {
  2784. for (uintptr_t i = 0; i < proto->protocols->count; i++) {
  2785. const char *enc =
  2786. protocol_getMethodTypeEncoding_nolock(remapProtocol(proto->protocols->list[i]), sel, isRequiredMethod, isInstanceMethod);
  2787. if (enc) return enc;
  2788. }
  2789. }
  2790. return nil;
  2791. }
  2792. /***********************************************************************
  2793. * _protocol_getMethodTypeEncoding
  2794. * Return the @encode string for the requested protocol method.
  2795. * Returns nil if the compiler did not emit any extended @encode data.
  2796. * Locking: acquires runtimeLock
  2797. **********************************************************************/
  2798. const char *
  2799. _protocol_getMethodTypeEncoding(Protocol *proto_gen, SEL sel,
  2800. BOOL isRequiredMethod, BOOL isInstanceMethod)
  2801. {
  2802. protocol_t *proto = newprotocol(proto_gen);
  2803. if (!proto) return nil;
  2804. fixupProtocolIfNeeded(proto);
  2805. mutex_locker_t lock(runtimeLock);
  2806. return protocol_getMethodTypeEncoding_nolock(proto, sel,
  2807. isRequiredMethod,
  2808. isInstanceMethod);
  2809. }
  2810. /***********************************************************************
  2811. * protocol_t::demangledName
  2812. * Returns the (Swift-demangled) name of the given protocol.
  2813. * Locking: none
  2814. **********************************************************************/
  2815. const char *
  2816. protocol_t::demangledName()
  2817. {
  2818. assert(hasDemangledNameField());
  2819. if (! _demangledName) {
  2820. char *de = copySwiftV1DemangledName(mangledName, true/*isProtocol*/);
  2821. if (! OSAtomicCompareAndSwapPtrBarrier(nil, (void*)(de ?: mangledName),
  2822. (void**)&_demangledName))
  2823. {
  2824. if (de) free(de);
  2825. }
  2826. }
  2827. return _demangledName;
  2828. }
  2829. /***********************************************************************
  2830. * protocol_getName
  2831. * Returns the (Swift-demangled) name of the given protocol.
  2832. * Locking: runtimeLock must not be held by the caller
  2833. **********************************************************************/
  2834. const char *
  2835. protocol_getName(Protocol *proto)
  2836. {
  2837. if (!proto) return "nil";
  2838. else return newprotocol(proto)->demangledName();
  2839. }
  2840. /***********************************************************************
  2841. * protocol_getInstanceMethodDescription
  2842. * Returns the description of a named instance method.
  2843. * Locking: runtimeLock must not be held by the caller
  2844. **********************************************************************/
  2845. struct objc_method_description
  2846. protocol_getMethodDescription(Protocol *p, SEL aSel,
  2847. BOOL isRequiredMethod, BOOL isInstanceMethod)
  2848. {
  2849. Method m =
  2850. protocol_getMethod(newprotocol(p), aSel,
  2851. isRequiredMethod, isInstanceMethod, true);
  2852. if (m) return *method_getDescription(m);
  2853. else return (struct objc_method_description){nil, nil};
  2854. }
  2855. /***********************************************************************
  2856. * protocol_conformsToProtocol_nolock
  2857. * Returns YES if self conforms to other.
  2858. * Locking: runtimeLock must be held by the caller.
  2859. **********************************************************************/
  2860. static bool
  2861. protocol_conformsToProtocol_nolock(protocol_t *self, protocol_t *other)
  2862. {
  2863. runtimeLock.assertLocked();
  2864. if (!self || !other) {
  2865. return NO;
  2866. }
  2867. // protocols need not be fixed up
  2868. if (0 == strcmp(self->mangledName, other->mangledName)) {
  2869. return YES;
  2870. }
  2871. if (self->protocols) {
  2872. uintptr_t i;
  2873. for (i = 0; i < self->protocols->count; i++) {
  2874. protocol_t *proto = remapProtocol(self->protocols->list[i]);
  2875. if (0 == strcmp(other->mangledName, proto->mangledName)) {
  2876. return YES;
  2877. }
  2878. if (protocol_conformsToProtocol_nolock(proto, other)) {
  2879. return YES;
  2880. }
  2881. }
  2882. }
  2883. return NO;
  2884. }
  2885. /***********************************************************************
  2886. * protocol_conformsToProtocol
  2887. * Returns YES if self conforms to other.
  2888. * Locking: acquires runtimeLock
  2889. **********************************************************************/
  2890. BOOL protocol_conformsToProtocol(Protocol *self, Protocol *other)
  2891. {
  2892. mutex_locker_t lock(runtimeLock);
  2893. return protocol_conformsToProtocol_nolock(newprotocol(self),
  2894. newprotocol(other));
  2895. }
  2896. /***********************************************************************
  2897. * protocol_isEqual
  2898. * Return YES if two protocols are equal (i.e. conform to each other)
  2899. * Locking: acquires runtimeLock
  2900. **********************************************************************/
  2901. BOOL protocol_isEqual(Protocol *self, Protocol *other)
  2902. {
  2903. if (self == other) return YES;
  2904. if (!self || !other) return NO;
  2905. if (!protocol_conformsToProtocol(self, other)) return NO;
  2906. if (!protocol_conformsToProtocol(other, self)) return NO;
  2907. return YES;
  2908. }
  2909. /***********************************************************************
  2910. * protocol_copyMethodDescriptionList
  2911. * Returns descriptions of a protocol's methods.
  2912. * Locking: acquires runtimeLock
  2913. **********************************************************************/
  2914. struct objc_method_description *
  2915. protocol_copyMethodDescriptionList(Protocol *p,
  2916. BOOL isRequiredMethod,BOOL isInstanceMethod,
  2917. unsigned int *outCount)
  2918. {
  2919. protocol_t *proto = newprotocol(p);
  2920. struct objc_method_description *result = nil;
  2921. unsigned int count = 0;
  2922. if (!proto) {
  2923. if (outCount) *outCount = 0;
  2924. return nil;
  2925. }
  2926. fixupProtocolIfNeeded(proto);
  2927. mutex_locker_t lock(runtimeLock);
  2928. method_list_t *mlist =
  2929. getProtocolMethodList(proto, isRequiredMethod, isInstanceMethod);
  2930. if (mlist) {
  2931. result = (struct objc_method_description *)
  2932. calloc(mlist->count + 1, sizeof(struct objc_method_description));
  2933. for (const auto& meth : *mlist) {
  2934. result[count].name = meth.name;
  2935. result[count].types = (char *)meth.types;
  2936. count++;
  2937. }
  2938. }
  2939. if (outCount) *outCount = count;
  2940. return result;
  2941. }
  2942. /***********************************************************************
  2943. * protocol_getProperty
  2944. * fixme
  2945. * Locking: runtimeLock must be held by the caller
  2946. **********************************************************************/
  2947. static property_t *
  2948. protocol_getProperty_nolock(protocol_t *proto, const char *name,
  2949. bool isRequiredProperty, bool isInstanceProperty)
  2950. {
  2951. runtimeLock.assertLocked();
  2952. if (!isRequiredProperty) {
  2953. // Only required properties are currently supported.
  2954. return nil;
  2955. }
  2956. property_list_t *plist = isInstanceProperty ?
  2957. proto->instanceProperties : proto->classProperties();
  2958. if (plist) {
  2959. for (auto& prop : *plist) {
  2960. if (0 == strcmp(name, prop.name)) {
  2961. return &prop;
  2962. }
  2963. }
  2964. }
  2965. if (proto->protocols) {
  2966. uintptr_t i;
  2967. for (i = 0; i < proto->protocols->count; i++) {
  2968. protocol_t *p = remapProtocol(proto->protocols->list[i]);
  2969. property_t *prop =
  2970. protocol_getProperty_nolock(p, name,
  2971. isRequiredProperty,
  2972. isInstanceProperty);
  2973. if (prop) return prop;
  2974. }
  2975. }
  2976. return nil;
  2977. }
  2978. objc_property_t protocol_getProperty(Protocol *p, const char *name,
  2979. BOOL isRequiredProperty, BOOL isInstanceProperty)
  2980. {
  2981. if (!p || !name) return nil;
  2982. mutex_locker_t lock(runtimeLock);
  2983. return (objc_property_t)
  2984. protocol_getProperty_nolock(newprotocol(p), name,
  2985. isRequiredProperty, isInstanceProperty);
  2986. }
  2987. /***********************************************************************
  2988. * protocol_copyPropertyList
  2989. * protocol_copyPropertyList2
  2990. * fixme
  2991. * Locking: acquires runtimeLock
  2992. **********************************************************************/
  2993. static property_t **
  2994. copyPropertyList(property_list_t *plist, unsigned int *outCount)
  2995. {
  2996. property_t **result = nil;
  2997. unsigned int count = 0;
  2998. if (plist) {
  2999. count = plist->count;
  3000. }
  3001. if (count > 0) {
  3002. result = (property_t **)malloc((count+1) * sizeof(property_t *));
  3003. count = 0;
  3004. for (auto& prop : *plist) {
  3005. result[count++] = &prop;
  3006. }
  3007. result[count] = nil;
  3008. }
  3009. if (outCount) *outCount = count;
  3010. return result;
  3011. }
  3012. objc_property_t *
  3013. protocol_copyPropertyList2(Protocol *proto, unsigned int *outCount,
  3014. BOOL isRequiredProperty, BOOL isInstanceProperty)
  3015. {
  3016. if (!proto || !isRequiredProperty) {
  3017. // Optional properties are not currently supported.
  3018. if (outCount) *outCount = 0;
  3019. return nil;
  3020. }
  3021. mutex_locker_t lock(runtimeLock);
  3022. property_list_t *plist = isInstanceProperty
  3023. ? newprotocol(proto)->instanceProperties
  3024. : newprotocol(proto)->classProperties();
  3025. return (objc_property_t *)copyPropertyList(plist, outCount);
  3026. }
  3027. objc_property_t *
  3028. protocol_copyPropertyList(Protocol *proto, unsigned int *outCount)
  3029. {
  3030. return protocol_copyPropertyList2(proto, outCount,
  3031. YES/*required*/, YES/*instance*/);
  3032. }
  3033. /***********************************************************************
  3034. * protocol_copyProtocolList
  3035. * Copies this protocol's incorporated protocols.
  3036. * Does not copy those protocol's incorporated protocols in turn.
  3037. * Locking: acquires runtimeLock
  3038. **********************************************************************/
  3039. Protocol * __unsafe_unretained *
  3040. protocol_copyProtocolList(Protocol *p, unsigned int *outCount)
  3041. {
  3042. unsigned int count = 0;
  3043. Protocol **result = nil;
  3044. protocol_t *proto = newprotocol(p);
  3045. if (!proto) {
  3046. if (outCount) *outCount = 0;
  3047. return nil;
  3048. }
  3049. mutex_locker_t lock(runtimeLock);
  3050. if (proto->protocols) {
  3051. count = (unsigned int)proto->protocols->count;
  3052. }
  3053. if (count > 0) {
  3054. result = (Protocol **)malloc((count+1) * sizeof(Protocol *));
  3055. unsigned int i;
  3056. for (i = 0; i < count; i++) {
  3057. result[i] = (Protocol *)remapProtocol(proto->protocols->list[i]);
  3058. }
  3059. result[i] = nil;
  3060. }
  3061. if (outCount) *outCount = count;
  3062. return result;
  3063. }
  3064. /***********************************************************************
  3065. * objc_allocateProtocol
  3066. * Creates a new protocol. The protocol may not be used until
  3067. * objc_registerProtocol() is called.
  3068. * Returns nil if a protocol with the same name already exists.
  3069. * Locking: acquires runtimeLock
  3070. **********************************************************************/
  3071. Protocol *
  3072. objc_allocateProtocol(const char *name)
  3073. {
  3074. mutex_locker_t lock(runtimeLock);
  3075. if (getProtocol(name)) {
  3076. return nil;
  3077. }
  3078. protocol_t *result = (protocol_t *)calloc(sizeof(protocol_t), 1);
  3079. extern objc_class OBJC_CLASS_$___IncompleteProtocol;
  3080. Class cls = (Class)&OBJC_CLASS_$___IncompleteProtocol;
  3081. result->initProtocolIsa(cls);
  3082. result->size = sizeof(protocol_t);
  3083. // fixme mangle the name if it looks swift-y?
  3084. result->mangledName = strdupIfMutable(name);
  3085. // fixme reserve name without installing
  3086. return (Protocol *)result;
  3087. }
  3088. /***********************************************************************
  3089. * objc_registerProtocol
  3090. * Registers a newly-constructed protocol. The protocol is now
  3091. * ready for use and immutable.
  3092. * Locking: acquires runtimeLock
  3093. **********************************************************************/
  3094. void objc_registerProtocol(Protocol *proto_gen)
  3095. {
  3096. protocol_t *proto = newprotocol(proto_gen);
  3097. mutex_locker_t lock(runtimeLock);
  3098. extern objc_class OBJC_CLASS_$___IncompleteProtocol;
  3099. Class oldcls = (Class)&OBJC_CLASS_$___IncompleteProtocol;
  3100. extern objc_class OBJC_CLASS_$_Protocol;
  3101. Class cls = (Class)&OBJC_CLASS_$_Protocol;
  3102. if (proto->ISA() == cls) {
  3103. _objc_inform("objc_registerProtocol: protocol '%s' was already "
  3104. "registered!", proto->nameForLogging());
  3105. return;
  3106. }
  3107. if (proto->ISA() != oldcls) {
  3108. _objc_inform("objc_registerProtocol: protocol '%s' was not allocated "
  3109. "with objc_allocateProtocol!", proto->nameForLogging());
  3110. return;
  3111. }
  3112. // NOT initProtocolIsa(). The protocol object may already
  3113. // have been retained and we must preserve that count.
  3114. proto->changeIsa(cls);
  3115. NXMapKeyCopyingInsert(protocols(), proto->mangledName, proto);
  3116. }
  3117. /***********************************************************************
  3118. * protocol_addProtocol
  3119. * Adds an incorporated protocol to another protocol.
  3120. * No method enforcement is performed.
  3121. * `proto` must be under construction. `addition` must not.
  3122. * Locking: acquires runtimeLock
  3123. **********************************************************************/
  3124. void
  3125. protocol_addProtocol(Protocol *proto_gen, Protocol *addition_gen)
  3126. {
  3127. protocol_t *proto = newprotocol(proto_gen);
  3128. protocol_t *addition = newprotocol(addition_gen);
  3129. extern objc_class OBJC_CLASS_$___IncompleteProtocol;
  3130. Class cls = (Class)&OBJC_CLASS_$___IncompleteProtocol;
  3131. if (!proto_gen) return;
  3132. if (!addition_gen) return;
  3133. mutex_locker_t lock(runtimeLock);
  3134. if (proto->ISA() != cls) {
  3135. _objc_inform("protocol_addProtocol: modified protocol '%s' is not "
  3136. "under construction!", proto->nameForLogging());
  3137. return;
  3138. }
  3139. if (addition->ISA() == cls) {
  3140. _objc_inform("protocol_addProtocol: added protocol '%s' is still "
  3141. "under construction!", addition->nameForLogging());
  3142. return;
  3143. }
  3144. protocol_list_t *protolist = proto->protocols;
  3145. if (!protolist) {
  3146. protolist = (protocol_list_t *)
  3147. calloc(1, sizeof(protocol_list_t)
  3148. + sizeof(protolist->list[0]));
  3149. } else {
  3150. protolist = (protocol_list_t *)
  3151. realloc(protolist, protocol_list_size(protolist)
  3152. + sizeof(protolist->list[0]));
  3153. }
  3154. protolist->list[protolist->count++] = (protocol_ref_t)addition;
  3155. proto->protocols = protolist;
  3156. }
  3157. /***********************************************************************
  3158. * protocol_addMethodDescription
  3159. * Adds a method to a protocol. The protocol must be under construction.
  3160. * Locking: acquires runtimeLock
  3161. **********************************************************************/
  3162. static void
  3163. protocol_addMethod_nolock(method_list_t*& list, SEL name, const char *types)
  3164. {
  3165. if (!list) {
  3166. list = (method_list_t *)calloc(sizeof(method_list_t), 1);
  3167. list->entsizeAndFlags = sizeof(list->first);
  3168. list->setFixedUp();
  3169. } else {
  3170. size_t size = list->byteSize() + list->entsize();
  3171. list = (method_list_t *)realloc(list, size);
  3172. }
  3173. method_t& meth = list->get(list->count++);
  3174. meth.name = name;
  3175. meth.types = types ? strdupIfMutable(types) : "";
  3176. meth.imp = nil;
  3177. }
  3178. void
  3179. protocol_addMethodDescription(Protocol *proto_gen, SEL name, const char *types,
  3180. BOOL isRequiredMethod, BOOL isInstanceMethod)
  3181. {
  3182. protocol_t *proto = newprotocol(proto_gen);
  3183. extern objc_class OBJC_CLASS_$___IncompleteProtocol;
  3184. Class cls = (Class)&OBJC_CLASS_$___IncompleteProtocol;
  3185. if (!proto_gen) return;
  3186. mutex_locker_t lock(runtimeLock);
  3187. if (proto->ISA() != cls) {
  3188. _objc_inform("protocol_addMethodDescription: protocol '%s' is not "
  3189. "under construction!", proto->nameForLogging());
  3190. return;
  3191. }
  3192. if (isRequiredMethod && isInstanceMethod) {
  3193. protocol_addMethod_nolock(proto->instanceMethods, name, types);
  3194. } else if (isRequiredMethod && !isInstanceMethod) {
  3195. protocol_addMethod_nolock(proto->classMethods, name, types);
  3196. } else if (!isRequiredMethod && isInstanceMethod) {
  3197. protocol_addMethod_nolock(proto->optionalInstanceMethods, name,types);
  3198. } else /* !isRequiredMethod && !isInstanceMethod) */ {
  3199. protocol_addMethod_nolock(proto->optionalClassMethods, name, types);
  3200. }
  3201. }
  3202. /***********************************************************************
  3203. * protocol_addProperty
  3204. * Adds a property to a protocol. The protocol must be under construction.
  3205. * Locking: acquires runtimeLock
  3206. **********************************************************************/
  3207. static void
  3208. protocol_addProperty_nolock(property_list_t *&plist, const char *name,
  3209. const objc_property_attribute_t *attrs,
  3210. unsigned int count)
  3211. {
  3212. if (!plist) {
  3213. plist = (property_list_t *)calloc(sizeof(property_list_t), 1);
  3214. plist->entsizeAndFlags = sizeof(property_t);
  3215. } else {
  3216. plist = (property_list_t *)
  3217. realloc(plist, sizeof(property_list_t)
  3218. + plist->count * plist->entsize());
  3219. }
  3220. property_t& prop = plist->get(plist->count++);
  3221. prop.name = strdupIfMutable(name);
  3222. prop.attributes = copyPropertyAttributeString(attrs, count);
  3223. }
  3224. void
  3225. protocol_addProperty(Protocol *proto_gen, const char *name,
  3226. const objc_property_attribute_t *attrs,
  3227. unsigned int count,
  3228. BOOL isRequiredProperty, BOOL isInstanceProperty)
  3229. {
  3230. protocol_t *proto = newprotocol(proto_gen);
  3231. extern objc_class OBJC_CLASS_$___IncompleteProtocol;
  3232. Class cls = (Class)&OBJC_CLASS_$___IncompleteProtocol;
  3233. if (!proto) return;
  3234. if (!name) return;
  3235. mutex_locker_t lock(runtimeLock);
  3236. if (proto->ISA() != cls) {
  3237. _objc_inform("protocol_addProperty: protocol '%s' is not "
  3238. "under construction!", proto->nameForLogging());
  3239. return;
  3240. }
  3241. if (isRequiredProperty && isInstanceProperty) {
  3242. protocol_addProperty_nolock(proto->instanceProperties, name, attrs, count);
  3243. }
  3244. else if (isRequiredProperty && !isInstanceProperty) {
  3245. protocol_addProperty_nolock(proto->_classProperties, name, attrs, count);
  3246. }
  3247. //else if (!isRequiredProperty && isInstanceProperty) {
  3248. // protocol_addProperty_nolock(proto->optionalInstanceProperties, name, attrs, count);
  3249. //}
  3250. //else /* !isRequiredProperty && !isInstanceProperty) */ {
  3251. // protocol_addProperty_nolock(proto->optionalClassProperties, name, attrs, count);
  3252. //}
  3253. }
  3254. /***********************************************************************
  3255. * objc_getClassList
  3256. * Returns pointers to all classes.
  3257. * This requires all classes be realized, which is regretfully non-lazy.
  3258. * Locking: acquires runtimeLock
  3259. **********************************************************************/
  3260. int
  3261. objc_getClassList(Class *buffer, int bufferLen)
  3262. {
  3263. mutex_locker_t lock(runtimeLock);
  3264. realizeAllClasses();
  3265. __block int count = 0;
  3266. foreach_realized_class_and_metaclass(^(Class cls) {
  3267. if (!cls->isMetaClass()) count++;
  3268. });
  3269. if (buffer) {
  3270. __block int c = 0;
  3271. foreach_realized_class_and_metaclass(^(Class cls) {
  3272. if (c < bufferLen && !cls->isMetaClass()) {
  3273. buffer[c++] = cls;
  3274. }
  3275. });
  3276. }
  3277. return count;
  3278. }
  3279. /***********************************************************************
  3280. * objc_copyClassList
  3281. * Returns pointers to all classes.
  3282. * This requires all classes be realized, which is regretfully non-lazy.
  3283. *
  3284. * outCount may be nil. *outCount is the number of classes returned.
  3285. * If the returned array is not nil, it is nil-terminated and must be
  3286. * freed with free().
  3287. * Locking: write-locks runtimeLock
  3288. **********************************************************************/
  3289. Class *
  3290. objc_copyClassList(unsigned int *outCount)
  3291. {
  3292. mutex_locker_t lock(runtimeLock);
  3293. realizeAllClasses();
  3294. Class *result = nil;
  3295. __block unsigned int count = 0;
  3296. foreach_realized_class_and_metaclass(^(Class cls) {
  3297. if (!cls->isMetaClass()) count++;
  3298. });
  3299. if (count > 0) {
  3300. result = (Class *)malloc((1+count) * sizeof(Class));
  3301. __block unsigned int c = 0;
  3302. foreach_realized_class_and_metaclass(^(Class cls) {
  3303. if (!cls->isMetaClass()) {
  3304. result[c++] = cls;
  3305. }
  3306. });
  3307. result[c] = nil;
  3308. }
  3309. if (outCount) *outCount = count;
  3310. return result;
  3311. }
  3312. /***********************************************************************
  3313. * objc_copyProtocolList
  3314. * Returns pointers to all protocols.
  3315. * Locking: read-locks runtimeLock
  3316. **********************************************************************/
  3317. Protocol * __unsafe_unretained *
  3318. objc_copyProtocolList(unsigned int *outCount)
  3319. {
  3320. mutex_locker_t lock(runtimeLock);
  3321. NXMapTable *protocol_map = protocols();
  3322. unsigned int count = NXCountMapTable(protocol_map);
  3323. if (count == 0) {
  3324. if (outCount) *outCount = 0;
  3325. return nil;
  3326. }
  3327. Protocol **result = (Protocol **)malloc((count+1) * sizeof(Protocol*));
  3328. unsigned int i = 0;
  3329. Protocol *proto;
  3330. const char *name;
  3331. NXMapState state = NXInitMapState(protocol_map);
  3332. while (NXNextMapState(protocol_map, &state,
  3333. (const void **)&name, (const void **)&proto))
  3334. {
  3335. result[i++] = proto;
  3336. }
  3337. result[i++] = nil;
  3338. assert(i == count+1);
  3339. if (outCount) *outCount = count;
  3340. return result;
  3341. }
  3342. /***********************************************************************
  3343. * objc_getProtocol
  3344. * Get a protocol by name, or return nil
  3345. * Locking: read-locks runtimeLock
  3346. **********************************************************************/
  3347. Protocol *objc_getProtocol(const char *name)
  3348. {
  3349. mutex_locker_t lock(runtimeLock);
  3350. return getProtocol(name);
  3351. }
  3352. /***********************************************************************
  3353. * class_copyMethodList
  3354. * fixme
  3355. * Locking: read-locks runtimeLock
  3356. **********************************************************************/
  3357. Method *
  3358. class_copyMethodList(Class cls, unsigned int *outCount)
  3359. {
  3360. unsigned int count = 0;
  3361. Method *result = nil;
  3362. if (!cls) {
  3363. if (outCount) *outCount = 0;
  3364. return nil;
  3365. }
  3366. mutex_locker_t lock(runtimeLock);
  3367. assert(cls->isRealized());
  3368. count = cls->data()->methods.count();
  3369. if (count > 0) {
  3370. result = (Method *)malloc((count + 1) * sizeof(Method));
  3371. count = 0;
  3372. for (auto& meth : cls->data()->methods) {
  3373. result[count++] = &meth;
  3374. }
  3375. result[count] = nil;
  3376. }
  3377. if (outCount) *outCount = count;
  3378. return result;
  3379. }
  3380. /***********************************************************************
  3381. * class_copyIvarList
  3382. * fixme
  3383. * Locking: read-locks runtimeLock
  3384. **********************************************************************/
  3385. Ivar *
  3386. class_copyIvarList(Class cls, unsigned int *outCount)
  3387. {
  3388. const ivar_list_t *ivars;
  3389. Ivar *result = nil;
  3390. unsigned int count = 0;
  3391. if (!cls) {
  3392. if (outCount) *outCount = 0;
  3393. return nil;
  3394. }
  3395. mutex_locker_t lock(runtimeLock);
  3396. assert(cls->isRealized());
  3397. if ((ivars = cls->data()->ro->ivars) && ivars->count) {
  3398. result = (Ivar *)malloc((ivars->count+1) * sizeof(Ivar));
  3399. for (auto& ivar : *ivars) {
  3400. if (!ivar.offset) continue; // anonymous bitfield
  3401. result[count++] = &ivar;
  3402. }
  3403. result[count] = nil;
  3404. }
  3405. if (outCount) *outCount = count;
  3406. return result;
  3407. }
  3408. /***********************************************************************
  3409. * class_copyPropertyList. Returns a heap block containing the
  3410. * properties declared in the class, or nil if the class
  3411. * declares no properties. Caller must free the block.
  3412. * Does not copy any superclass's properties.
  3413. * Locking: read-locks runtimeLock
  3414. **********************************************************************/
  3415. objc_property_t *
  3416. class_copyPropertyList(Class cls, unsigned int *outCount)
  3417. {
  3418. if (!cls) {
  3419. if (outCount) *outCount = 0;
  3420. return nil;
  3421. }
  3422. mutex_locker_t lock(runtimeLock);
  3423. checkIsKnownClass(cls);
  3424. assert(cls->isRealized());
  3425. auto rw = cls->data();
  3426. property_t **result = nil;
  3427. unsigned int count = rw->properties.count();
  3428. if (count > 0) {
  3429. result = (property_t **)malloc((count + 1) * sizeof(property_t *));
  3430. count = 0;
  3431. for (auto& prop : rw->properties) {
  3432. result[count++] = &prop;
  3433. }
  3434. result[count] = nil;
  3435. }
  3436. if (outCount) *outCount = count;
  3437. return (objc_property_t *)result;
  3438. }
  3439. /***********************************************************************
  3440. * objc_class::getLoadMethod
  3441. * fixme
  3442. * Called only from add_class_to_loadable_list.
  3443. * Locking: runtimeLock must be read- or write-locked by the caller.
  3444. **********************************************************************/
  3445. IMP
  3446. objc_class::getLoadMethod()
  3447. {
  3448. runtimeLock.assertLocked();
  3449. const method_list_t *mlist;
  3450. assert(isRealized());
  3451. assert(ISA()->isRealized());
  3452. assert(!isMetaClass());
  3453. assert(ISA()->isMetaClass());
  3454. mlist = ISA()->data()->ro->baseMethods();
  3455. if (mlist) {
  3456. for (const auto& meth : *mlist) {
  3457. const char *name = sel_cname(meth.name);
  3458. if (0 == strcmp(name, "load")) {
  3459. return meth.imp;
  3460. }
  3461. }
  3462. }
  3463. return nil;
  3464. }
  3465. /***********************************************************************
  3466. * _category_getName
  3467. * Returns a category's name.
  3468. * Locking: none
  3469. **********************************************************************/
  3470. const char *
  3471. _category_getName(Category cat)
  3472. {
  3473. return cat->name;
  3474. }
  3475. /***********************************************************************
  3476. * _category_getClassName
  3477. * Returns a category's class's name
  3478. * Called only from add_category_to_loadable_list and
  3479. * remove_category_from_loadable_list for logging purposes.
  3480. * Locking: runtimeLock must be read- or write-locked by the caller
  3481. **********************************************************************/
  3482. const char *
  3483. _category_getClassName(Category cat)
  3484. {
  3485. runtimeLock.assertLocked();
  3486. return remapClass(cat->cls)->nameForLogging();
  3487. }
  3488. /***********************************************************************
  3489. * _category_getClass
  3490. * Returns a category's class
  3491. * Called only by call_category_loads.
  3492. * Locking: read-locks runtimeLock
  3493. **********************************************************************/
  3494. Class
  3495. _category_getClass(Category cat)
  3496. {
  3497. mutex_locker_t lock(runtimeLock);
  3498. Class result = remapClass(cat->cls);
  3499. assert(result->isRealized()); // ok for call_category_loads' usage
  3500. return result;
  3501. }
  3502. /***********************************************************************
  3503. * _category_getLoadMethod
  3504. * fixme
  3505. * Called only from add_category_to_loadable_list
  3506. * Locking: runtimeLock must be read- or write-locked by the caller
  3507. **********************************************************************/
  3508. IMP
  3509. _category_getLoadMethod(Category cat)
  3510. {
  3511. runtimeLock.assertLocked();
  3512. const method_list_t *mlist;
  3513. mlist = cat->classMethods;
  3514. if (mlist) {
  3515. for (const auto& meth : *mlist) {
  3516. const char *name = sel_cname(meth.name);
  3517. if (0 == strcmp(name, "load")) {
  3518. return meth.imp;
  3519. }
  3520. }
  3521. }
  3522. return nil;
  3523. }
  3524. /***********************************************************************
  3525. * category_t::propertiesForMeta
  3526. * Return a category's instance or class properties.
  3527. * hi is the image containing the category.
  3528. **********************************************************************/
  3529. property_list_t *
  3530. category_t::propertiesForMeta(bool isMeta, struct header_info *hi)
  3531. {
  3532. if (!isMeta) return instanceProperties;
  3533. else if (hi->info()->hasCategoryClassProperties()) return _classProperties;
  3534. else return nil;
  3535. }
  3536. /***********************************************************************
  3537. * class_copyProtocolList
  3538. * fixme
  3539. * Locking: read-locks runtimeLock
  3540. **********************************************************************/
  3541. Protocol * __unsafe_unretained *
  3542. class_copyProtocolList(Class cls, unsigned int *outCount)
  3543. {
  3544. unsigned int count = 0;
  3545. Protocol **result = nil;
  3546. if (!cls) {
  3547. if (outCount) *outCount = 0;
  3548. return nil;
  3549. }
  3550. mutex_locker_t lock(runtimeLock);
  3551. checkIsKnownClass(cls);
  3552. assert(cls->isRealized());
  3553. count = cls->data()->protocols.count();
  3554. if (count > 0) {
  3555. result = (Protocol **)malloc((count+1) * sizeof(Protocol *));
  3556. count = 0;
  3557. for (const auto& proto : cls->data()->protocols) {
  3558. result[count++] = (Protocol *)remapProtocol(proto);
  3559. }
  3560. result[count] = nil;
  3561. }
  3562. if (outCount) *outCount = count;
  3563. return result;
  3564. }
  3565. /***********************************************************************
  3566. * objc_copyImageNames
  3567. * Copies names of loaded images with ObjC contents.
  3568. *
  3569. * Locking: acquires runtimeLock
  3570. **********************************************************************/
  3571. const char **objc_copyImageNames(unsigned int *outCount)
  3572. {
  3573. mutex_locker_t lock(runtimeLock);
  3574. #if TARGET_OS_WIN32
  3575. const TCHAR **names = (const TCHAR **)
  3576. malloc((HeaderCount+1) * sizeof(TCHAR *));
  3577. #else
  3578. const char **names = (const char **)
  3579. malloc((HeaderCount+1) * sizeof(char *));
  3580. #endif
  3581. unsigned int count = 0;
  3582. for (header_info *hi = FirstHeader; hi != nil; hi = hi->getNext()) {
  3583. #if TARGET_OS_WIN32
  3584. if (hi->moduleName) {
  3585. names[count++] = hi->moduleName;
  3586. }
  3587. #else
  3588. const char *fname = hi->fname();
  3589. if (fname) {
  3590. names[count++] = fname;
  3591. }
  3592. #endif
  3593. }
  3594. names[count] = nil;
  3595. if (count == 0) {
  3596. // Return nil instead of empty list if there are no images
  3597. free((void *)names);
  3598. names = nil;
  3599. }
  3600. if (outCount) *outCount = count;
  3601. return names;
  3602. }
  3603. /***********************************************************************
  3604. * copyClassNamesForImage_nolock
  3605. * Copies class names from the given image.
  3606. * Missing weak-import classes are omitted.
  3607. * Swift class names are demangled.
  3608. *
  3609. * Locking: runtimeLock must be held by the caller
  3610. **********************************************************************/
  3611. const char **
  3612. copyClassNamesForImage_nolock(header_info *hi, unsigned int *outCount)
  3613. {
  3614. runtimeLock.assertLocked();
  3615. assert(hi);
  3616. size_t count;
  3617. classref_t *classlist = _getObjc2ClassList(hi, &count);
  3618. const char **names = (const char **)
  3619. malloc((count+1) * sizeof(const char *));
  3620. size_t shift = 0;
  3621. for (size_t i = 0; i < count; i++) {
  3622. Class cls = remapClass(classlist[i]);
  3623. if (cls) {
  3624. names[i-shift] = cls->demangledName(true/*realize*/);
  3625. } else {
  3626. shift++; // ignored weak-linked class
  3627. }
  3628. }
  3629. count -= shift;
  3630. names[count] = nil;
  3631. if (outCount) *outCount = (unsigned int)count;
  3632. return names;
  3633. }
  3634. /***********************************************************************
  3635. * objc_copyClassNamesForImage
  3636. * Copies class names from the named image.
  3637. * The image name must be identical to dladdr's dli_fname value.
  3638. * Missing weak-import classes are omitted.
  3639. * Swift class names are demangled.
  3640. *
  3641. * Locking: acquires runtimeLock
  3642. **********************************************************************/
  3643. const char **
  3644. objc_copyClassNamesForImage(const char *image, unsigned int *outCount)
  3645. {
  3646. if (!image) {
  3647. if (outCount) *outCount = 0;
  3648. return nil;
  3649. }
  3650. mutex_locker_t lock(runtimeLock);
  3651. // Find the image.
  3652. header_info *hi;
  3653. for (hi = FirstHeader; hi != nil; hi = hi->getNext()) {
  3654. #if TARGET_OS_WIN32
  3655. if (0 == wcscmp((TCHAR *)image, hi->moduleName)) break;
  3656. #else
  3657. if (0 == strcmp(image, hi->fname())) break;
  3658. #endif
  3659. }
  3660. if (!hi) {
  3661. if (outCount) *outCount = 0;
  3662. return nil;
  3663. }
  3664. return copyClassNamesForImage_nolock(hi, outCount);
  3665. }
  3666. /***********************************************************************
  3667. * objc_copyClassNamesForImageHeader
  3668. * Copies class names from the given image.
  3669. * Missing weak-import classes are omitted.
  3670. * Swift class names are demangled.
  3671. *
  3672. * Locking: acquires runtimeLock
  3673. **********************************************************************/
  3674. const char **
  3675. objc_copyClassNamesForImageHeader(const struct mach_header *mh, unsigned int *outCount)
  3676. {
  3677. if (!mh) {
  3678. if (outCount) *outCount = 0;
  3679. return nil;
  3680. }
  3681. mutex_locker_t lock(runtimeLock);
  3682. // Find the image.
  3683. header_info *hi;
  3684. for (hi = FirstHeader; hi != nil; hi = hi->getNext()) {
  3685. if (hi->mhdr() == (const headerType *)mh) break;
  3686. }
  3687. if (!hi) {
  3688. if (outCount) *outCount = 0;
  3689. return nil;
  3690. }
  3691. return copyClassNamesForImage_nolock(hi, outCount);
  3692. }
  3693. /***********************************************************************
  3694. * saveTemporaryString
  3695. * Save a string in a thread-local FIFO buffer.
  3696. * This is suitable for temporary strings generated for logging purposes.
  3697. **********************************************************************/
  3698. static void
  3699. saveTemporaryString(char *str)
  3700. {
  3701. // Fixed-size FIFO. We free the first string, shift
  3702. // the rest, and add the new string to the end.
  3703. _objc_pthread_data *data = _objc_fetch_pthread_data(true);
  3704. if (data->printableNames[0]) {
  3705. free(data->printableNames[0]);
  3706. }
  3707. int last = countof(data->printableNames) - 1;
  3708. for (int i = 0; i < last; i++) {
  3709. data->printableNames[i] = data->printableNames[i+1];
  3710. }
  3711. data->printableNames[last] = str;
  3712. }
  3713. /***********************************************************************
  3714. * objc_class::nameForLogging
  3715. * Returns the class's name, suitable for display.
  3716. * The returned memory is TEMPORARY. Print it or copy it immediately.
  3717. * Locking: none
  3718. **********************************************************************/
  3719. const char *
  3720. objc_class::nameForLogging()
  3721. {
  3722. // Handle the easy case directly.
  3723. if (isRealized() || isFuture()) {
  3724. if (data()->demangledName) return data()->demangledName;
  3725. }
  3726. char *result;
  3727. const char *name = mangledName();
  3728. char *de = copySwiftV1DemangledName(name);
  3729. if (de) result = de;
  3730. else result = strdup(name);
  3731. saveTemporaryString(result);
  3732. return result;
  3733. }
  3734. /***********************************************************************
  3735. * objc_class::demangledName
  3736. * If realize=false, the class must already be realized or future.
  3737. * Locking: If realize=true, runtimeLock must be held by the caller.
  3738. **********************************************************************/
  3739. mutex_t DemangleCacheLock;
  3740. static NXHashTable *DemangleCache;
  3741. const char *
  3742. objc_class::demangledName(bool realize)
  3743. {
  3744. // Return previously demangled name if available.
  3745. if (isRealized() || isFuture()) {
  3746. if (data()->demangledName) return data()->demangledName;
  3747. }
  3748. // Try demangling the mangled name.
  3749. const char *mangled = mangledName();
  3750. char *de = copySwiftV1DemangledName(mangled);
  3751. if (isRealized() || isFuture()) {
  3752. // Class is already realized or future.
  3753. // Save demangling result in rw data.
  3754. // We may not own runtimeLock so use an atomic operation instead.
  3755. if (! OSAtomicCompareAndSwapPtrBarrier(nil, (void*)(de ?: mangled),
  3756. (void**)&data()->demangledName))
  3757. {
  3758. if (de) free(de);
  3759. }
  3760. return data()->demangledName;
  3761. }
  3762. // Class is not yet realized.
  3763. if (!de) {
  3764. // Name is not mangled. Return it without caching.
  3765. return mangled;
  3766. }
  3767. // Class is not yet realized and name is mangled. Realize the class.
  3768. // Only objc_copyClassNamesForImage() should get here.
  3769. // fixme lldb's calls to class_getName() can also get here when
  3770. // interrogating the dyld shared cache. (rdar://27258517)
  3771. // fixme runtimeLock.assertLocked();
  3772. // fixme assert(realize);
  3773. if (realize) {
  3774. runtimeLock.assertLocked();
  3775. realizeClass((Class)this);
  3776. data()->demangledName = de;
  3777. return de;
  3778. }
  3779. else {
  3780. // Save the string to avoid leaks.
  3781. char *cached;
  3782. {
  3783. mutex_locker_t lock(DemangleCacheLock);
  3784. if (!DemangleCache) {
  3785. DemangleCache = NXCreateHashTable(NXStrPrototype, 0, nil);
  3786. }
  3787. cached = (char *)NXHashInsertIfAbsent(DemangleCache, de);
  3788. }
  3789. if (cached != de) free(de);
  3790. return cached;
  3791. }
  3792. }
  3793. /***********************************************************************
  3794. * class_getName
  3795. * fixme
  3796. * Locking: acquires runtimeLock
  3797. **********************************************************************/
  3798. const char *class_getName(Class cls)
  3799. {
  3800. if (!cls) return "nil";
  3801. // fixme lldb calls class_getName() on unrealized classes (rdar://27258517)
  3802. // assert(cls->isRealized() || cls->isFuture());
  3803. return cls->demangledName();
  3804. }
  3805. /***********************************************************************
  3806. * class_getVersion
  3807. * fixme
  3808. * Locking: none
  3809. **********************************************************************/
  3810. int
  3811. class_getVersion(Class cls)
  3812. {
  3813. if (!cls) return 0;
  3814. assert(cls->isRealized());
  3815. return cls->data()->version;
  3816. }
  3817. /***********************************************************************
  3818. * class_setVersion
  3819. * fixme
  3820. * Locking: none
  3821. **********************************************************************/
  3822. void
  3823. class_setVersion(Class cls, int version)
  3824. {
  3825. if (!cls) return;
  3826. assert(cls->isRealized());
  3827. cls->data()->version = version;
  3828. }
  3829. static method_t *findMethodInSortedMethodList(SEL key, const method_list_t *list)
  3830. {
  3831. assert(list);
  3832. const method_t * const first = &list->first;
  3833. const method_t *base = first;
  3834. const method_t *probe;
  3835. uintptr_t keyValue = (uintptr_t)key;
  3836. uint32_t count;
  3837. for (count = list->count; count != 0; count >>= 1) {
  3838. probe = base + (count >> 1);
  3839. uintptr_t probeValue = (uintptr_t)probe->name;
  3840. if (keyValue == probeValue) {
  3841. // `probe` is a match.
  3842. // Rewind looking for the *first* occurrence of this value.
  3843. // This is required for correct category overrides.
  3844. while (probe > first && keyValue == (uintptr_t)probe[-1].name) {
  3845. probe--;
  3846. }
  3847. return (method_t *)probe;
  3848. }
  3849. if (keyValue > probeValue) {
  3850. base = probe + 1;
  3851. count--;
  3852. }
  3853. }
  3854. return nil;
  3855. }
  3856. /***********************************************************************
  3857. * getMethodNoSuper_nolock
  3858. * fixme
  3859. * Locking: runtimeLock must be read- or write-locked by the caller
  3860. **********************************************************************/
  3861. static method_t *search_method_list(const method_list_t *mlist, SEL sel)
  3862. {
  3863. int methodListIsFixedUp = mlist->isFixedUp();
  3864. int methodListHasExpectedSize = mlist->entsize() == sizeof(method_t);
  3865. if (__builtin_expect(methodListIsFixedUp && methodListHasExpectedSize, 1)) {
  3866. return findMethodInSortedMethodList(sel, mlist);
  3867. } else {
  3868. // Linear search of unsorted method list
  3869. for (auto& meth : *mlist) {
  3870. if (meth.name == sel) return &meth;
  3871. }
  3872. }
  3873. #if DEBUG
  3874. // sanity-check negative results
  3875. if (mlist->isFixedUp()) {
  3876. for (auto& meth : *mlist) {
  3877. if (meth.name == sel) {
  3878. _objc_fatal("linear search worked when binary search did not");
  3879. }
  3880. }
  3881. }
  3882. #endif
  3883. return nil;
  3884. }
  3885. static method_t *
  3886. getMethodNoSuper_nolock(Class cls, SEL sel)
  3887. {
  3888. runtimeLock.assertLocked();
  3889. assert(cls->isRealized());
  3890. // fixme nil cls?
  3891. // fixme nil sel?
  3892. for (auto mlists = cls->data()->methods.beginLists(),
  3893. end = cls->data()->methods.endLists();
  3894. mlists != end;
  3895. ++mlists)
  3896. {
  3897. method_t *m = search_method_list(*mlists, sel);
  3898. if (m) return m;
  3899. }
  3900. return nil;
  3901. }
  3902. /***********************************************************************
  3903. * getMethod_nolock
  3904. * fixme
  3905. * Locking: runtimeLock must be read- or write-locked by the caller
  3906. **********************************************************************/
  3907. static method_t *
  3908. getMethod_nolock(Class cls, SEL sel)
  3909. {
  3910. method_t *m = nil;
  3911. runtimeLock.assertLocked();
  3912. // fixme nil cls?
  3913. // fixme nil sel?
  3914. assert(cls->isRealized());
  3915. while (cls && ((m = getMethodNoSuper_nolock(cls, sel))) == nil) {
  3916. cls = cls->superclass;
  3917. }
  3918. return m;
  3919. }
  3920. /***********************************************************************
  3921. * _class_getMethod
  3922. * fixme
  3923. * Locking: read-locks runtimeLock
  3924. **********************************************************************/
  3925. static Method _class_getMethod(Class cls, SEL sel)
  3926. {
  3927. mutex_locker_t lock(runtimeLock);
  3928. return getMethod_nolock(cls, sel);
  3929. }
  3930. /***********************************************************************
  3931. * class_getInstanceMethod. Return the instance method for the
  3932. * specified class and selector.
  3933. **********************************************************************/
  3934. Method class_getInstanceMethod(Class cls, SEL sel)
  3935. {
  3936. if (!cls || !sel) return nil;
  3937. // This deliberately avoids +initialize because it historically did so.
  3938. // This implementation is a bit weird because it's the only place that
  3939. // wants a Method instead of an IMP.
  3940. #warning fixme build and search caches
  3941. // Search method lists, try method resolver, etc.
  3942. lookUpImpOrNil(cls, sel, nil,
  3943. NO/*initialize*/, NO/*cache*/, YES/*resolver*/);
  3944. #warning fixme build and search caches
  3945. return _class_getMethod(cls, sel);
  3946. }
  3947. /***********************************************************************
  3948. * log_and_fill_cache
  3949. * Log this method call. If the logger permits it, fill the method cache.
  3950. * cls is the method whose cache should be filled.
  3951. * implementer is the class that owns the implementation in question.
  3952. **********************************************************************/
  3953. static void
  3954. log_and_fill_cache(Class cls, IMP imp, SEL sel, id receiver, Class implementer)
  3955. {
  3956. #if SUPPORT_MESSAGE_LOGGING
  3957. if (objcMsgLogEnabled) {
  3958. bool cacheIt = logMessageSend(implementer->isMetaClass(),
  3959. cls->nameForLogging(),
  3960. implementer->nameForLogging(),
  3961. sel);
  3962. if (!cacheIt) return;
  3963. }
  3964. #endif
  3965. cache_fill (cls, sel, imp, receiver);
  3966. }
  3967. /***********************************************************************
  3968. * _class_lookupMethodAndLoadCache.
  3969. * Method lookup for dispatchers ONLY. OTHER CODE SHOULD USE lookUpImp().
  3970. * This lookup avoids optimistic cache scan because the dispatcher
  3971. * already tried that.
  3972. **********************************************************************/
  3973. IMP _class_lookupMethodAndLoadCache3(id obj, SEL sel, Class cls)
  3974. {
  3975. return lookUpImpOrForward(cls, sel, obj,
  3976. YES/*initialize*/, NO/*cache*/, YES/*resolver*/);
  3977. }
  3978. /***********************************************************************
  3979. * lookUpImpOrForward.
  3980. * The standard IMP lookup.
  3981. * initialize==NO tries to avoid +initialize (but sometimes fails)
  3982. * cache==NO skips optimistic unlocked lookup (but uses cache elsewhere)
  3983. * Most callers should use initialize==YES and cache==YES.
  3984. * inst is an instance of cls or a subclass thereof, or nil if none is known.
  3985. * If cls is an un-initialized metaclass then a non-nil inst is faster.
  3986. * May return _objc_msgForward_impcache. IMPs destined for external use
  3987. * must be converted to _objc_msgForward or _objc_msgForward_stret.
  3988. * If you don't want forwarding at all, use lookUpImpOrNil() instead.
  3989. **********************************************************************/
  3990. IMP lookUpImpOrForward(Class cls, SEL sel, id inst,
  3991. bool initialize, bool cache, bool resolver)
  3992. {
  3993. IMP imp = nil;
  3994. bool triedResolver = NO;
  3995. runtimeLock.assertUnlocked();
  3996. // Optimistic cache lookup
  3997. if (cache) {
  3998. imp = cache_getImp(cls, sel);
  3999. if (imp) return imp;
  4000. }
  4001. // runtimeLock is held during isRealized and isInitialized checking
  4002. // to prevent races against concurrent realization.
  4003. // runtimeLock is held during method search to make
  4004. // method-lookup + cache-fill atomic with respect to method addition.
  4005. // Otherwise, a category could be added but ignored indefinitely because
  4006. // the cache was re-filled with the old value after the cache flush on
  4007. // behalf of the category.
  4008. runtimeLock.lock();
  4009. checkIsKnownClass(cls);
  4010. if (!cls->isRealized()) {
  4011. realizeClass(cls);
  4012. }
  4013. if (initialize && !cls->isInitialized()) {
  4014. runtimeLock.unlock();
  4015. _class_initialize (_class_getNonMetaClass(cls, inst));
  4016. runtimeLock.lock();
  4017. // If sel == initialize, _class_initialize will send +initialize and
  4018. // then the messenger will send +initialize again after this
  4019. // procedure finishes. Of course, if this is not being called
  4020. // from the messenger then it won't happen. 2778172
  4021. }
  4022. retry:
  4023. runtimeLock.assertLocked();
  4024. // Try this class's cache.
  4025. imp = cache_getImp(cls, sel);
  4026. if (imp) goto done;
  4027. // Try this class's method lists.
  4028. {
  4029. Method meth = getMethodNoSuper_nolock(cls, sel);
  4030. if (meth) {
  4031. log_and_fill_cache(cls, meth->imp, sel, inst, cls);
  4032. imp = meth->imp;
  4033. goto done;
  4034. }
  4035. }
  4036. // Try superclass caches and method lists.
  4037. {
  4038. unsigned attempts = unreasonableClassCount();
  4039. for (Class curClass = cls->superclass;
  4040. curClass != nil;
  4041. curClass = curClass->superclass)
  4042. {
  4043. // Halt if there is a cycle in the superclass chain.
  4044. if (--attempts == 0) {
  4045. _objc_fatal("Memory corruption in class list.");
  4046. }
  4047. // Superclass cache.
  4048. imp = cache_getImp(curClass, sel);
  4049. if (imp) {
  4050. if (imp != (IMP)_objc_msgForward_impcache) {
  4051. // Found the method in a superclass. Cache it in this class.
  4052. log_and_fill_cache(cls, imp, sel, inst, curClass);
  4053. goto done;
  4054. }
  4055. else {
  4056. // Found a forward:: entry in a superclass.
  4057. // Stop searching, but don't cache yet; call method
  4058. // resolver for this class first.
  4059. break;
  4060. }
  4061. }
  4062. // Superclass method list.
  4063. Method meth = getMethodNoSuper_nolock(curClass, sel);
  4064. if (meth) {
  4065. log_and_fill_cache(cls, meth->imp, sel, inst, curClass);
  4066. imp = meth->imp;
  4067. goto done;
  4068. }
  4069. }
  4070. }
  4071. // No implementation found. Try method resolver once.
  4072. if (resolver && !triedResolver) {
  4073. runtimeLock.unlock();
  4074. _class_resolveMethod(cls, sel, inst);
  4075. runtimeLock.lock();
  4076. // Don't cache the result; we don't hold the lock so it may have
  4077. // changed already. Re-do the search from scratch instead.
  4078. triedResolver = YES;
  4079. goto retry;
  4080. }
  4081. // No implementation found, and method resolver didn't help.
  4082. // Use forwarding.
  4083. imp = (IMP)_objc_msgForward_impcache;
  4084. cache_fill(cls, sel, imp, inst);
  4085. done:
  4086. runtimeLock.unlock();
  4087. return imp;
  4088. }
  4089. /***********************************************************************
  4090. * lookUpImpOrNil.
  4091. * Like lookUpImpOrForward, but returns nil instead of _objc_msgForward_impcache
  4092. **********************************************************************/
  4093. IMP lookUpImpOrNil(Class cls, SEL sel, id inst,
  4094. bool initialize, bool cache, bool resolver)
  4095. {
  4096. IMP imp = lookUpImpOrForward(cls, sel, inst, initialize, cache, resolver);
  4097. if (imp == _objc_msgForward_impcache) return nil;
  4098. else return imp;
  4099. }
  4100. /***********************************************************************
  4101. * lookupMethodInClassAndLoadCache.
  4102. * Like _class_lookupMethodAndLoadCache, but does not search superclasses.
  4103. * Caches and returns objc_msgForward if the method is not found in the class.
  4104. **********************************************************************/
  4105. IMP lookupMethodInClassAndLoadCache(Class cls, SEL sel)
  4106. {
  4107. Method meth;
  4108. IMP imp;
  4109. // fixme this is incomplete - no resolver, +initialize -
  4110. // but it's only used for .cxx_construct/destruct so we don't care
  4111. assert(sel == SEL_cxx_construct || sel == SEL_cxx_destruct);
  4112. // Search cache first.
  4113. imp = cache_getImp(cls, sel);
  4114. if (imp) return imp;
  4115. // Cache miss. Search method list.
  4116. mutex_locker_t lock(runtimeLock);
  4117. meth = getMethodNoSuper_nolock(cls, sel);
  4118. if (meth) {
  4119. // Hit in method list. Cache it.
  4120. cache_fill(cls, sel, meth->imp, nil);
  4121. return meth->imp;
  4122. } else {
  4123. // Miss in method list. Cache objc_msgForward.
  4124. cache_fill(cls, sel, _objc_msgForward_impcache, nil);
  4125. return _objc_msgForward_impcache;
  4126. }
  4127. }
  4128. /***********************************************************************
  4129. * class_getProperty
  4130. * fixme
  4131. * Locking: read-locks runtimeLock
  4132. **********************************************************************/
  4133. objc_property_t class_getProperty(Class cls, const char *name)
  4134. {
  4135. if (!cls || !name) return nil;
  4136. mutex_locker_t lock(runtimeLock);
  4137. checkIsKnownClass(cls);
  4138. assert(cls->isRealized());
  4139. for ( ; cls; cls = cls->superclass) {
  4140. for (auto& prop : cls->data()->properties) {
  4141. if (0 == strcmp(name, prop.name)) {
  4142. return (objc_property_t)&prop;
  4143. }
  4144. }
  4145. }
  4146. return nil;
  4147. }
  4148. /***********************************************************************
  4149. * Locking: fixme
  4150. **********************************************************************/
  4151. Class gdb_class_getClass(Class cls)
  4152. {
  4153. const char *className = cls->mangledName();
  4154. if(!className || !strlen(className)) return Nil;
  4155. Class rCls = look_up_class(className, NO, NO);
  4156. return rCls;
  4157. }
  4158. Class gdb_object_getClass(id obj)
  4159. {
  4160. if (!obj) return nil;
  4161. return gdb_class_getClass(obj->getIsa());
  4162. }
  4163. /***********************************************************************
  4164. * Locking: write-locks runtimeLock
  4165. **********************************************************************/
  4166. void
  4167. objc_class::setInitialized()
  4168. {
  4169. Class metacls;
  4170. Class cls;
  4171. assert(!isMetaClass());
  4172. cls = (Class)this;
  4173. metacls = cls->ISA();
  4174. mutex_locker_t lock(runtimeLock);
  4175. // Scan metaclass for custom AWZ.
  4176. // Scan metaclass for custom RR.
  4177. // Scan class for custom RR.
  4178. // Also print custom RR/AWZ because we probably haven't done it yet.
  4179. // Special cases:
  4180. // NSObject AWZ class methods are default.
  4181. // NSObject RR instance methods are default.
  4182. // updateCustomRR_AWZ() also knows these special cases.
  4183. // attachMethodLists() also knows these special cases.
  4184. bool inherited;
  4185. bool metaCustomAWZ = NO;
  4186. if (MetaclassNSObjectAWZSwizzled) {
  4187. // Somebody already swizzled NSObject's methods
  4188. metaCustomAWZ = YES;
  4189. inherited = NO;
  4190. }
  4191. else if (metacls == classNSObject()->ISA()) {
  4192. // NSObject's metaclass AWZ is default, but we still need to check cats
  4193. auto& methods = metacls->data()->methods;
  4194. for (auto mlists = methods.beginCategoryMethodLists(),
  4195. end = methods.endCategoryMethodLists(metacls);
  4196. mlists != end;
  4197. ++mlists)
  4198. {
  4199. if (methodListImplementsAWZ(*mlists)) {
  4200. metaCustomAWZ = YES;
  4201. inherited = NO;
  4202. break;
  4203. }
  4204. }
  4205. }
  4206. else if (metacls->superclass->hasCustomAWZ()) {
  4207. // Superclass is custom AWZ, therefore we are too.
  4208. metaCustomAWZ = YES;
  4209. inherited = YES;
  4210. }
  4211. else {
  4212. // Not metaclass NSObject.
  4213. auto& methods = metacls->data()->methods;
  4214. for (auto mlists = methods.beginLists(),
  4215. end = methods.endLists();
  4216. mlists != end;
  4217. ++mlists)
  4218. {
  4219. if (methodListImplementsAWZ(*mlists)) {
  4220. metaCustomAWZ = YES;
  4221. inherited = NO;
  4222. break;
  4223. }
  4224. }
  4225. }
  4226. if (!metaCustomAWZ) metacls->setHasDefaultAWZ();
  4227. if (PrintCustomAWZ && metaCustomAWZ) metacls->printCustomAWZ(inherited);
  4228. // metacls->printCustomRR();
  4229. bool clsCustomRR = NO;
  4230. if (ClassNSObjectRRSwizzled) {
  4231. // Somebody already swizzled NSObject's methods
  4232. clsCustomRR = YES;
  4233. inherited = NO;
  4234. }
  4235. if (cls == classNSObject()) {
  4236. // NSObject's RR is default, but we still need to check categories
  4237. auto& methods = cls->data()->methods;
  4238. for (auto mlists = methods.beginCategoryMethodLists(),
  4239. end = methods.endCategoryMethodLists(cls);
  4240. mlists != end;
  4241. ++mlists)
  4242. {
  4243. if (methodListImplementsRR(*mlists)) {
  4244. clsCustomRR = YES;
  4245. inherited = NO;
  4246. break;
  4247. }
  4248. }
  4249. }
  4250. else if (!cls->superclass) {
  4251. // Custom root class
  4252. clsCustomRR = YES;
  4253. inherited = NO;
  4254. }
  4255. else if (cls->superclass->hasCustomRR()) {
  4256. // Superclass is custom RR, therefore we are too.
  4257. clsCustomRR = YES;
  4258. inherited = YES;
  4259. }
  4260. else {
  4261. // Not class NSObject.
  4262. auto& methods = cls->data()->methods;
  4263. for (auto mlists = methods.beginLists(),
  4264. end = methods.endLists();
  4265. mlists != end;
  4266. ++mlists)
  4267. {
  4268. if (methodListImplementsRR(*mlists)) {
  4269. clsCustomRR = YES;
  4270. inherited = NO;
  4271. break;
  4272. }
  4273. }
  4274. }
  4275. if (!clsCustomRR) cls->setHasDefaultRR();
  4276. // cls->printCustomAWZ();
  4277. if (PrintCustomRR && clsCustomRR) cls->printCustomRR(inherited);
  4278. // Update the +initialize flags.
  4279. // Do this last.
  4280. metacls->changeInfo(RW_INITIALIZED, RW_INITIALIZING);
  4281. }
  4282. /***********************************************************************
  4283. * Return YES if sel is used by retain/release implementors
  4284. **********************************************************************/
  4285. static bool
  4286. isRRSelector(SEL sel)
  4287. {
  4288. return (sel == SEL_retain || sel == SEL_release ||
  4289. sel == SEL_autorelease || sel == SEL_retainCount ||
  4290. sel == SEL_tryRetain || sel == SEL_retainWeakReference ||
  4291. sel == SEL_isDeallocating || sel == SEL_allowsWeakReference);
  4292. }
  4293. /***********************************************************************
  4294. * Return YES if mlist implements one of the isRRSelector() methods
  4295. **********************************************************************/
  4296. static bool
  4297. methodListImplementsRR(const method_list_t *mlist)
  4298. {
  4299. return (search_method_list(mlist, SEL_retain) ||
  4300. search_method_list(mlist, SEL_release) ||
  4301. search_method_list(mlist, SEL_autorelease) ||
  4302. search_method_list(mlist, SEL_retainCount) ||
  4303. search_method_list(mlist, SEL_tryRetain) ||
  4304. search_method_list(mlist, SEL_isDeallocating) ||
  4305. search_method_list(mlist, SEL_retainWeakReference) ||
  4306. search_method_list(mlist, SEL_allowsWeakReference));
  4307. }
  4308. /***********************************************************************
  4309. * Return YES if sel is used by alloc or allocWithZone implementors
  4310. **********************************************************************/
  4311. static bool
  4312. isAWZSelector(SEL sel)
  4313. {
  4314. return (sel == SEL_allocWithZone || sel == SEL_alloc);
  4315. }
  4316. /***********************************************************************
  4317. * Return YES if mlist implements one of the isAWZSelector() methods
  4318. **********************************************************************/
  4319. static bool
  4320. methodListImplementsAWZ(const method_list_t *mlist)
  4321. {
  4322. return (search_method_list(mlist, SEL_allocWithZone) ||
  4323. search_method_list(mlist, SEL_alloc));
  4324. }
  4325. void
  4326. objc_class::printCustomRR(bool inherited)
  4327. {
  4328. assert(PrintCustomRR);
  4329. assert(hasCustomRR());
  4330. _objc_inform("CUSTOM RR: %s%s%s", nameForLogging(),
  4331. isMetaClass() ? " (meta)" : "",
  4332. inherited ? " (inherited)" : "");
  4333. }
  4334. void
  4335. objc_class::printCustomAWZ(bool inherited)
  4336. {
  4337. assert(PrintCustomAWZ);
  4338. assert(hasCustomAWZ());
  4339. _objc_inform("CUSTOM AWZ: %s%s%s", nameForLogging(),
  4340. isMetaClass() ? " (meta)" : "",
  4341. inherited ? " (inherited)" : "");
  4342. }
  4343. void
  4344. objc_class::printInstancesRequireRawIsa(bool inherited)
  4345. {
  4346. assert(PrintRawIsa);
  4347. assert(instancesRequireRawIsa());
  4348. _objc_inform("RAW ISA: %s%s%s", nameForLogging(),
  4349. isMetaClass() ? " (meta)" : "",
  4350. inherited ? " (inherited)" : "");
  4351. }
  4352. /***********************************************************************
  4353. * Mark this class and all of its subclasses as implementors or
  4354. * inheritors of custom RR (retain/release/autorelease/retainCount)
  4355. **********************************************************************/
  4356. void objc_class::setHasCustomRR(bool inherited)
  4357. {
  4358. Class cls = (Class)this;
  4359. runtimeLock.assertLocked();
  4360. if (hasCustomRR()) return;
  4361. foreach_realized_class_and_subclass(cls, ^(Class c){
  4362. if (c != cls && !c->isInitialized()) {
  4363. // Subclass not yet initialized. Wait for setInitialized() to do it
  4364. // fixme short circuit recursion?
  4365. return;
  4366. }
  4367. if (c->hasCustomRR()) {
  4368. // fixme short circuit recursion?
  4369. return;
  4370. }
  4371. c->bits.setHasCustomRR();
  4372. if (PrintCustomRR) c->printCustomRR(inherited || c != cls);
  4373. });
  4374. }
  4375. /***********************************************************************
  4376. * Mark this class and all of its subclasses as implementors or
  4377. * inheritors of custom alloc/allocWithZone:
  4378. **********************************************************************/
  4379. void objc_class::setHasCustomAWZ(bool inherited)
  4380. {
  4381. Class cls = (Class)this;
  4382. runtimeLock.assertLocked();
  4383. if (hasCustomAWZ()) return;
  4384. foreach_realized_class_and_subclass(cls, ^(Class c){
  4385. if (c != cls && !c->isInitialized()) {
  4386. // Subclass not yet initialized. Wait for setInitialized() to do it
  4387. // fixme short circuit recursion?
  4388. return;
  4389. }
  4390. if (c->hasCustomAWZ()) {
  4391. // fixme short circuit recursion?
  4392. return;
  4393. }
  4394. c->bits.setHasCustomAWZ();
  4395. if (PrintCustomAWZ) c->printCustomAWZ(inherited || c != cls);
  4396. });
  4397. }
  4398. /***********************************************************************
  4399. * Mark this class and all of its subclasses as requiring raw isa pointers
  4400. **********************************************************************/
  4401. void objc_class::setInstancesRequireRawIsa(bool inherited)
  4402. {
  4403. Class cls = (Class)this;
  4404. runtimeLock.assertLocked();
  4405. if (instancesRequireRawIsa()) return;
  4406. foreach_realized_class_and_subclass(cls, ^(Class c){
  4407. if (c->instancesRequireRawIsa()) {
  4408. // fixme short circuit recursion?
  4409. return;
  4410. }
  4411. c->bits.setInstancesRequireRawIsa();
  4412. if (PrintRawIsa) c->printInstancesRequireRawIsa(inherited || c != cls);
  4413. });
  4414. }
  4415. /***********************************************************************
  4416. * Choose a class index.
  4417. * Set instancesRequireRawIsa if no more class indexes are available.
  4418. **********************************************************************/
  4419. void objc_class::chooseClassArrayIndex()
  4420. {
  4421. #if SUPPORT_INDEXED_ISA
  4422. Class cls = (Class)this;
  4423. runtimeLock.assertLocked();
  4424. if (objc_indexed_classes_count >= ISA_INDEX_COUNT) {
  4425. // No more indexes available.
  4426. assert(cls->classArrayIndex() == 0);
  4427. cls->setInstancesRequireRawIsa(false/*not inherited*/);
  4428. return;
  4429. }
  4430. unsigned index = objc_indexed_classes_count++;
  4431. if (index == 0) index = objc_indexed_classes_count++; // index 0 is unused
  4432. classForIndex(index) = cls;
  4433. cls->setClassArrayIndex(index);
  4434. #endif
  4435. }
  4436. /***********************************************************************
  4437. * Update custom RR and AWZ when a method changes its IMP
  4438. **********************************************************************/
  4439. static void
  4440. updateCustomRR_AWZ(Class cls, method_t *meth)
  4441. {
  4442. // In almost all cases, IMP swizzling does not affect custom RR/AWZ bits.
  4443. // Custom RR/AWZ search will already find the method whether or not
  4444. // it is swizzled, so it does not transition from non-custom to custom.
  4445. //
  4446. // The only cases where IMP swizzling can affect the RR/AWZ bits is
  4447. // if the swizzled method is one of the methods that is assumed to be
  4448. // non-custom. These special cases are listed in setInitialized().
  4449. // We look for such cases here.
  4450. if (isRRSelector(meth->name)) {
  4451. if ((classNSObject()->isInitialized() &&
  4452. classNSObject()->hasCustomRR())
  4453. ||
  4454. ClassNSObjectRRSwizzled)
  4455. {
  4456. // already custom, nothing would change
  4457. return;
  4458. }
  4459. bool swizzlingNSObject = NO;
  4460. if (cls == classNSObject()) {
  4461. swizzlingNSObject = YES;
  4462. } else {
  4463. // Don't know the class.
  4464. // The only special case is class NSObject.
  4465. for (const auto& meth2 : classNSObject()->data()->methods) {
  4466. if (meth == &meth2) {
  4467. swizzlingNSObject = YES;
  4468. break;
  4469. }
  4470. }
  4471. }
  4472. if (swizzlingNSObject) {
  4473. if (classNSObject()->isInitialized()) {
  4474. classNSObject()->setHasCustomRR();
  4475. } else {
  4476. // NSObject not yet +initialized, so custom RR has not yet
  4477. // been checked, and setInitialized() will not notice the
  4478. // swizzle.
  4479. ClassNSObjectRRSwizzled = YES;
  4480. }
  4481. }
  4482. }
  4483. else if (isAWZSelector(meth->name)) {
  4484. Class metaclassNSObject = classNSObject()->ISA();
  4485. if ((metaclassNSObject->isInitialized() &&
  4486. metaclassNSObject->hasCustomAWZ())
  4487. ||
  4488. MetaclassNSObjectAWZSwizzled)
  4489. {
  4490. // already custom, nothing would change
  4491. return;
  4492. }
  4493. bool swizzlingNSObject = NO;
  4494. if (cls == metaclassNSObject) {
  4495. swizzlingNSObject = YES;
  4496. } else {
  4497. // Don't know the class.
  4498. // The only special case is metaclass NSObject.
  4499. for (const auto& meth2 : metaclassNSObject->data()->methods) {
  4500. if (meth == &meth2) {
  4501. swizzlingNSObject = YES;
  4502. break;
  4503. }
  4504. }
  4505. }
  4506. if (swizzlingNSObject) {
  4507. if (metaclassNSObject->isInitialized()) {
  4508. metaclassNSObject->setHasCustomAWZ();
  4509. } else {
  4510. // NSObject not yet +initialized, so custom RR has not yet
  4511. // been checked, and setInitialized() will not notice the
  4512. // swizzle.
  4513. MetaclassNSObjectAWZSwizzled = YES;
  4514. }
  4515. }
  4516. }
  4517. }
  4518. /***********************************************************************
  4519. * class_getIvarLayout
  4520. * Called by the garbage collector.
  4521. * The class must be nil or already realized.
  4522. * Locking: none
  4523. **********************************************************************/
  4524. const uint8_t *
  4525. class_getIvarLayout(Class cls)
  4526. {
  4527. if (cls) return cls->data()->ro->ivarLayout;
  4528. else return nil;
  4529. }
  4530. /***********************************************************************
  4531. * class_getWeakIvarLayout
  4532. * Called by the garbage collector.
  4533. * The class must be nil or already realized.
  4534. * Locking: none
  4535. **********************************************************************/
  4536. const uint8_t *
  4537. class_getWeakIvarLayout(Class cls)
  4538. {
  4539. if (cls) return cls->data()->ro->weakIvarLayout;
  4540. else return nil;
  4541. }
  4542. /***********************************************************************
  4543. * class_setIvarLayout
  4544. * Changes the class's ivar layout.
  4545. * nil layout means no unscanned ivars
  4546. * The class must be under construction.
  4547. * fixme: sanity-check layout vs instance size?
  4548. * fixme: sanity-check layout vs superclass?
  4549. * Locking: acquires runtimeLock
  4550. **********************************************************************/
  4551. void
  4552. class_setIvarLayout(Class cls, const uint8_t *layout)
  4553. {
  4554. if (!cls) return;
  4555. mutex_locker_t lock(runtimeLock);
  4556. checkIsKnownClass(cls);
  4557. // Can only change layout of in-construction classes.
  4558. // note: if modifications to post-construction classes were
  4559. // allowed, there would be a race below (us vs. concurrent object_setIvar)
  4560. if (!(cls->data()->flags & RW_CONSTRUCTING)) {
  4561. _objc_inform("*** Can't set ivar layout for already-registered "
  4562. "class '%s'", cls->nameForLogging());
  4563. return;
  4564. }
  4565. class_ro_t *ro_w = make_ro_writeable(cls->data());
  4566. try_free(ro_w->ivarLayout);
  4567. ro_w->ivarLayout = ustrdupMaybeNil(layout);
  4568. }
  4569. /***********************************************************************
  4570. * class_setWeakIvarLayout
  4571. * Changes the class's weak ivar layout.
  4572. * nil layout means no weak ivars
  4573. * The class must be under construction.
  4574. * fixme: sanity-check layout vs instance size?
  4575. * fixme: sanity-check layout vs superclass?
  4576. * Locking: acquires runtimeLock
  4577. **********************************************************************/
  4578. void
  4579. class_setWeakIvarLayout(Class cls, const uint8_t *layout)
  4580. {
  4581. if (!cls) return;
  4582. mutex_locker_t lock(runtimeLock);
  4583. checkIsKnownClass(cls);
  4584. // Can only change layout of in-construction classes.
  4585. // note: if modifications to post-construction classes were
  4586. // allowed, there would be a race below (us vs. concurrent object_setIvar)
  4587. if (!(cls->data()->flags & RW_CONSTRUCTING)) {
  4588. _objc_inform("*** Can't set weak ivar layout for already-registered "
  4589. "class '%s'", cls->nameForLogging());
  4590. return;
  4591. }
  4592. class_ro_t *ro_w = make_ro_writeable(cls->data());
  4593. try_free(ro_w->weakIvarLayout);
  4594. ro_w->weakIvarLayout = ustrdupMaybeNil(layout);
  4595. }
  4596. /***********************************************************************
  4597. * getIvar
  4598. * Look up an ivar by name.
  4599. * Locking: runtimeLock must be read- or write-locked by the caller.
  4600. **********************************************************************/
  4601. static ivar_t *getIvar(Class cls, const char *name)
  4602. {
  4603. runtimeLock.assertLocked();
  4604. const ivar_list_t *ivars;
  4605. assert(cls->isRealized());
  4606. if ((ivars = cls->data()->ro->ivars)) {
  4607. for (auto& ivar : *ivars) {
  4608. if (!ivar.offset) continue; // anonymous bitfield
  4609. // ivar.name may be nil for anonymous bitfields etc.
  4610. if (ivar.name && 0 == strcmp(name, ivar.name)) {
  4611. return &ivar;
  4612. }
  4613. }
  4614. }
  4615. return nil;
  4616. }
  4617. /***********************************************************************
  4618. * _class_getClassForIvar
  4619. * Given a class and an ivar that is in it or one of its superclasses,
  4620. * find the actual class that defined the ivar.
  4621. **********************************************************************/
  4622. Class _class_getClassForIvar(Class cls, Ivar ivar)
  4623. {
  4624. mutex_locker_t lock(runtimeLock);
  4625. for ( ; cls; cls = cls->superclass) {
  4626. if (auto ivars = cls->data()->ro->ivars) {
  4627. if (ivars->containsIvar(ivar)) {
  4628. return cls;
  4629. }
  4630. }
  4631. }
  4632. return nil;
  4633. }
  4634. /***********************************************************************
  4635. * _class_getVariable
  4636. * fixme
  4637. * Locking: read-locks runtimeLock
  4638. **********************************************************************/
  4639. Ivar
  4640. _class_getVariable(Class cls, const char *name)
  4641. {
  4642. mutex_locker_t lock(runtimeLock);
  4643. for ( ; cls; cls = cls->superclass) {
  4644. ivar_t *ivar = getIvar(cls, name);
  4645. if (ivar) {
  4646. return ivar;
  4647. }
  4648. }
  4649. return nil;
  4650. }
  4651. /***********************************************************************
  4652. * class_conformsToProtocol
  4653. * fixme
  4654. * Locking: read-locks runtimeLock
  4655. **********************************************************************/
  4656. BOOL class_conformsToProtocol(Class cls, Protocol *proto_gen)
  4657. {
  4658. protocol_t *proto = newprotocol(proto_gen);
  4659. if (!cls) return NO;
  4660. if (!proto_gen) return NO;
  4661. mutex_locker_t lock(runtimeLock);
  4662. checkIsKnownClass(cls);
  4663. assert(cls->isRealized());
  4664. for (const auto& proto_ref : cls->data()->protocols) {
  4665. protocol_t *p = remapProtocol(proto_ref);
  4666. if (p == proto || protocol_conformsToProtocol_nolock(p, proto)) {
  4667. return YES;
  4668. }
  4669. }
  4670. return NO;
  4671. }
  4672. /**********************************************************************
  4673. * addMethod
  4674. * fixme
  4675. * Locking: runtimeLock must be held by the caller
  4676. **********************************************************************/
  4677. static IMP
  4678. addMethod(Class cls, SEL name, IMP imp, const char *types, bool replace)
  4679. {
  4680. IMP result = nil;
  4681. runtimeLock.assertLocked();
  4682. checkIsKnownClass(cls);
  4683. assert(types);
  4684. assert(cls->isRealized());
  4685. method_t *m;
  4686. if ((m = getMethodNoSuper_nolock(cls, name))) {
  4687. // already exists
  4688. if (!replace) {
  4689. result = m->imp;
  4690. } else {
  4691. result = _method_setImplementation(cls, m, imp);
  4692. }
  4693. } else {
  4694. // fixme optimize
  4695. method_list_t *newlist;
  4696. newlist = (method_list_t *)calloc(sizeof(*newlist), 1);
  4697. newlist->entsizeAndFlags =
  4698. (uint32_t)sizeof(method_t) | fixed_up_method_list;
  4699. newlist->count = 1;
  4700. newlist->first.name = name;
  4701. newlist->first.types = strdupIfMutable(types);
  4702. newlist->first.imp = imp;
  4703. prepareMethodLists(cls, &newlist, 1, NO, NO);
  4704. cls->data()->methods.attachLists(&newlist, 1);
  4705. flushCaches(cls);
  4706. result = nil;
  4707. }
  4708. return result;
  4709. }
  4710. /**********************************************************************
  4711. * addMethods
  4712. * Add the given methods to a class in bulk.
  4713. * Returns the selectors which could not be added, when replace == NO and a
  4714. * method already exists. The returned selectors are NULL terminated and must be
  4715. * freed by the caller. They are NULL if no failures occurred.
  4716. * Locking: runtimeLock must be held by the caller
  4717. **********************************************************************/
  4718. static SEL *
  4719. addMethods(Class cls, const SEL *names, const IMP *imps, const char **types,
  4720. uint32_t count, bool replace, uint32_t *outFailedCount)
  4721. {
  4722. runtimeLock.assertLocked();
  4723. assert(names);
  4724. assert(imps);
  4725. assert(types);
  4726. assert(cls->isRealized());
  4727. method_list_t *newlist;
  4728. size_t newlistSize = method_list_t::byteSize(sizeof(method_t), count);
  4729. newlist = (method_list_t *)calloc(newlistSize, 1);
  4730. newlist->entsizeAndFlags =
  4731. (uint32_t)sizeof(method_t) | fixed_up_method_list;
  4732. newlist->count = 0;
  4733. method_t *newlistMethods = &newlist->first;
  4734. SEL *failedNames = nil;
  4735. uint32_t failedCount = 0;
  4736. for (uint32_t i = 0; i < count; i++) {
  4737. method_t *m;
  4738. if ((m = getMethodNoSuper_nolock(cls, names[i]))) {
  4739. // already exists
  4740. if (!replace) {
  4741. // report failure
  4742. if (failedNames == nil) {
  4743. // allocate an extra entry for a trailing NULL in case
  4744. // every method fails
  4745. failedNames = (SEL *)calloc(sizeof(*failedNames),
  4746. count + 1);
  4747. }
  4748. failedNames[failedCount] = m->name;
  4749. failedCount++;
  4750. } else {
  4751. _method_setImplementation(cls, m, imps[i]);
  4752. }
  4753. } else {
  4754. method_t *newmethod = &newlistMethods[newlist->count];
  4755. newmethod->name = names[i];
  4756. newmethod->types = strdupIfMutable(types[i]);
  4757. newmethod->imp = imps[i];
  4758. newlist->count++;
  4759. }
  4760. }
  4761. if (newlist->count > 0) {
  4762. // fixme resize newlist because it may have been over-allocated above.
  4763. // Note that realloc() alone doesn't work due to ptrauth.
  4764. method_t::SortBySELAddress sorter;
  4765. std::stable_sort(newlist->begin(), newlist->end(), sorter);
  4766. prepareMethodLists(cls, &newlist, 1, NO, NO);
  4767. cls->data()->methods.attachLists(&newlist, 1);
  4768. flushCaches(cls);
  4769. } else {
  4770. // Attaching the method list to the class consumes it. If we don't
  4771. // do that, we have to free the memory ourselves.
  4772. free(newlist);
  4773. }
  4774. if (outFailedCount) *outFailedCount = failedCount;
  4775. return failedNames;
  4776. }
  4777. BOOL
  4778. class_addMethod(Class cls, SEL name, IMP imp, const char *types)
  4779. {
  4780. if (!cls) return NO;
  4781. mutex_locker_t lock(runtimeLock);
  4782. return ! addMethod(cls, name, imp, types ?: "", NO);
  4783. }
  4784. IMP
  4785. class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
  4786. {
  4787. if (!cls) return nil;
  4788. mutex_locker_t lock(runtimeLock);
  4789. return addMethod(cls, name, imp, types ?: "", YES);
  4790. }
  4791. SEL *
  4792. class_addMethodsBulk(Class cls, const SEL *names, const IMP *imps,
  4793. const char **types, uint32_t count,
  4794. uint32_t *outFailedCount)
  4795. {
  4796. if (!cls) {
  4797. if (outFailedCount) *outFailedCount = count;
  4798. return (SEL *)memdup(names, count * sizeof(*names));
  4799. }
  4800. mutex_locker_t lock(runtimeLock);
  4801. return addMethods(cls, names, imps, types, count, NO, outFailedCount);
  4802. }
  4803. void
  4804. class_replaceMethodsBulk(Class cls, const SEL *names, const IMP *imps,
  4805. const char **types, uint32_t count)
  4806. {
  4807. if (!cls) return;
  4808. mutex_locker_t lock(runtimeLock);
  4809. addMethods(cls, names, imps, types, count, YES, nil);
  4810. }
  4811. /***********************************************************************
  4812. * class_addIvar
  4813. * Adds an ivar to a class.
  4814. * Locking: acquires runtimeLock
  4815. **********************************************************************/
  4816. BOOL
  4817. class_addIvar(Class cls, const char *name, size_t size,
  4818. uint8_t alignment, const char *type)
  4819. {
  4820. if (!cls) return NO;
  4821. if (!type) type = "";
  4822. if (name && 0 == strcmp(name, "")) name = nil;
  4823. mutex_locker_t lock(runtimeLock);
  4824. checkIsKnownClass(cls);
  4825. assert(cls->isRealized());
  4826. // No class variables
  4827. if (cls->isMetaClass()) {
  4828. return NO;
  4829. }
  4830. // Can only add ivars to in-construction classes.
  4831. if (!(cls->data()->flags & RW_CONSTRUCTING)) {
  4832. return NO;
  4833. }
  4834. // Check for existing ivar with this name, unless it's anonymous.
  4835. // Check for too-big ivar.
  4836. // fixme check for superclass ivar too?
  4837. if ((name && getIvar(cls, name)) || size > UINT32_MAX) {
  4838. return NO;
  4839. }
  4840. class_ro_t *ro_w = make_ro_writeable(cls->data());
  4841. // fixme allocate less memory here
  4842. ivar_list_t *oldlist, *newlist;
  4843. if ((oldlist = (ivar_list_t *)cls->data()->ro->ivars)) {
  4844. size_t oldsize = oldlist->byteSize();
  4845. newlist = (ivar_list_t *)calloc(oldsize + oldlist->entsize(), 1);
  4846. memcpy(newlist, oldlist, oldsize);
  4847. free(oldlist);
  4848. } else {
  4849. newlist = (ivar_list_t *)calloc(sizeof(ivar_list_t), 1);
  4850. newlist->entsizeAndFlags = (uint32_t)sizeof(ivar_t);
  4851. }
  4852. uint32_t offset = cls->unalignedInstanceSize();
  4853. uint32_t alignMask = (1<<alignment)-1;
  4854. offset = (offset + alignMask) & ~alignMask;
  4855. ivar_t& ivar = newlist->get(newlist->count++);
  4856. #if __x86_64__
  4857. // Deliberately over-allocate the ivar offset variable.
  4858. // Use calloc() to clear all 64 bits. See the note in struct ivar_t.
  4859. ivar.offset = (int32_t *)(int64_t *)calloc(sizeof(int64_t), 1);
  4860. #else
  4861. ivar.offset = (int32_t *)malloc(sizeof(int32_t));
  4862. #endif
  4863. *ivar.offset = offset;
  4864. ivar.name = name ? strdupIfMutable(name) : nil;
  4865. ivar.type = strdupIfMutable(type);
  4866. ivar.alignment_raw = alignment;
  4867. ivar.size = (uint32_t)size;
  4868. ro_w->ivars = newlist;
  4869. cls->setInstanceSize((uint32_t)(offset + size));
  4870. // Ivar layout updated in registerClass.
  4871. return YES;
  4872. }
  4873. /***********************************************************************
  4874. * class_addProtocol
  4875. * Adds a protocol to a class.
  4876. * Locking: acquires runtimeLock
  4877. **********************************************************************/
  4878. BOOL class_addProtocol(Class cls, Protocol *protocol_gen)
  4879. {
  4880. protocol_t *protocol = newprotocol(protocol_gen);
  4881. if (!cls) return NO;
  4882. if (class_conformsToProtocol(cls, protocol_gen)) return NO;
  4883. mutex_locker_t lock(runtimeLock);
  4884. assert(cls->isRealized());
  4885. // fixme optimize
  4886. protocol_list_t *protolist = (protocol_list_t *)
  4887. malloc(sizeof(protocol_list_t) + sizeof(protocol_t *));
  4888. protolist->count = 1;
  4889. protolist->list[0] = (protocol_ref_t)protocol;
  4890. cls->data()->protocols.attachLists(&protolist, 1);
  4891. // fixme metaclass?
  4892. return YES;
  4893. }
  4894. /***********************************************************************
  4895. * class_addProperty
  4896. * Adds a property to a class.
  4897. * Locking: acquires runtimeLock
  4898. **********************************************************************/
  4899. static bool
  4900. _class_addProperty(Class cls, const char *name,
  4901. const objc_property_attribute_t *attrs, unsigned int count,
  4902. bool replace)
  4903. {
  4904. if (!cls) return NO;
  4905. if (!name) return NO;
  4906. property_t *prop = class_getProperty(cls, name);
  4907. if (prop && !replace) {
  4908. // already exists, refuse to replace
  4909. return NO;
  4910. }
  4911. else if (prop) {
  4912. // replace existing
  4913. mutex_locker_t lock(runtimeLock);
  4914. try_free(prop->attributes);
  4915. prop->attributes = copyPropertyAttributeString(attrs, count);
  4916. return YES;
  4917. }
  4918. else {
  4919. mutex_locker_t lock(runtimeLock);
  4920. assert(cls->isRealized());
  4921. property_list_t *proplist = (property_list_t *)
  4922. malloc(sizeof(*proplist));
  4923. proplist->count = 1;
  4924. proplist->entsizeAndFlags = sizeof(proplist->first);
  4925. proplist->first.name = strdupIfMutable(name);
  4926. proplist->first.attributes = copyPropertyAttributeString(attrs, count);
  4927. cls->data()->properties.attachLists(&proplist, 1);
  4928. return YES;
  4929. }
  4930. }
  4931. BOOL
  4932. class_addProperty(Class cls, const char *name,
  4933. const objc_property_attribute_t *attrs, unsigned int n)
  4934. {
  4935. return _class_addProperty(cls, name, attrs, n, NO);
  4936. }
  4937. void
  4938. class_replaceProperty(Class cls, const char *name,
  4939. const objc_property_attribute_t *attrs, unsigned int n)
  4940. {
  4941. _class_addProperty(cls, name, attrs, n, YES);
  4942. }
  4943. /***********************************************************************
  4944. * look_up_class
  4945. * Look up a class by name, and realize it.
  4946. * Locking: acquires runtimeLock
  4947. **********************************************************************/
  4948. Class
  4949. look_up_class(const char *name,
  4950. bool includeUnconnected __attribute__((unused)),
  4951. bool includeClassHandler __attribute__((unused)))
  4952. {
  4953. if (!name) return nil;
  4954. Class result;
  4955. bool unrealized;
  4956. {
  4957. mutex_locker_t lock(runtimeLock);
  4958. result = getClass(name);
  4959. unrealized = result && !result->isRealized();
  4960. }
  4961. if (unrealized) {
  4962. mutex_locker_t lock(runtimeLock);
  4963. realizeClass(result);
  4964. }
  4965. return result;
  4966. }
  4967. /***********************************************************************
  4968. * objc_duplicateClass
  4969. * fixme
  4970. * Locking: acquires runtimeLock
  4971. **********************************************************************/
  4972. Class
  4973. objc_duplicateClass(Class original, const char *name,
  4974. size_t extraBytes)
  4975. {
  4976. Class duplicate;
  4977. mutex_locker_t lock(runtimeLock);
  4978. checkIsKnownClass(original);
  4979. assert(original->isRealized());
  4980. assert(!original->isMetaClass());
  4981. duplicate = alloc_class_for_subclass(original, extraBytes);
  4982. duplicate->initClassIsa(original->ISA());
  4983. duplicate->superclass = original->superclass;
  4984. duplicate->cache.initializeToEmpty();
  4985. class_rw_t *rw = (class_rw_t *)calloc(sizeof(*original->data()), 1);
  4986. rw->flags = (original->data()->flags | RW_COPIED_RO | RW_REALIZING);
  4987. rw->version = original->data()->version;
  4988. rw->firstSubclass = nil;
  4989. rw->nextSiblingClass = nil;
  4990. duplicate->bits = original->bits;
  4991. duplicate->setData(rw);
  4992. rw->ro = (class_ro_t *)
  4993. memdup(original->data()->ro, sizeof(*original->data()->ro));
  4994. *(char **)&rw->ro->name = strdupIfMutable(name);
  4995. rw->methods = original->data()->methods.duplicate();
  4996. // fixme dies when categories are added to the base
  4997. rw->properties = original->data()->properties;
  4998. rw->protocols = original->data()->protocols;
  4999. duplicate->chooseClassArrayIndex();
  5000. if (duplicate->superclass) {
  5001. addSubclass(duplicate->superclass, duplicate);
  5002. // duplicate->isa == original->isa so don't addSubclass() for it
  5003. } else {
  5004. addRootClass(duplicate);
  5005. }
  5006. // Don't methodize class - construction above is correct
  5007. addNamedClass(duplicate, duplicate->data()->ro->name);
  5008. addClassTableEntry(duplicate, /*addMeta=*/false);
  5009. if (PrintConnecting) {
  5010. _objc_inform("CLASS: realizing class '%s' (duplicate of %s) %p %p",
  5011. name, original->nameForLogging(),
  5012. (void*)duplicate, duplicate->data()->ro);
  5013. }
  5014. duplicate->clearInfo(RW_REALIZING);
  5015. return duplicate;
  5016. }
  5017. /***********************************************************************
  5018. * objc_initializeClassPair
  5019. * Locking: runtimeLock must be write-locked by the caller
  5020. **********************************************************************/
  5021. // &UnsetLayout is the default ivar layout during class construction
  5022. static const uint8_t UnsetLayout = 0;
  5023. static void objc_initializeClassPair_internal(Class superclass, const char *name, Class cls, Class meta)
  5024. {
  5025. runtimeLock.assertLocked();
  5026. class_ro_t *cls_ro_w, *meta_ro_w;
  5027. cls->setData((class_rw_t *)calloc(sizeof(class_rw_t), 1));
  5028. meta->setData((class_rw_t *)calloc(sizeof(class_rw_t), 1));
  5029. cls_ro_w = (class_ro_t *)calloc(sizeof(class_ro_t), 1);
  5030. meta_ro_w = (class_ro_t *)calloc(sizeof(class_ro_t), 1);
  5031. cls->data()->ro = cls_ro_w;
  5032. meta->data()->ro = meta_ro_w;
  5033. // Set basic info
  5034. cls->data()->flags = RW_CONSTRUCTING | RW_COPIED_RO | RW_REALIZED | RW_REALIZING;
  5035. meta->data()->flags = RW_CONSTRUCTING | RW_COPIED_RO | RW_REALIZED | RW_REALIZING;
  5036. cls->data()->version = 0;
  5037. meta->data()->version = 7;
  5038. cls_ro_w->flags = 0;
  5039. meta_ro_w->flags = RO_META;
  5040. if (!superclass) {
  5041. cls_ro_w->flags |= RO_ROOT;
  5042. meta_ro_w->flags |= RO_ROOT;
  5043. }
  5044. if (superclass) {
  5045. cls_ro_w->instanceStart = superclass->unalignedInstanceSize();
  5046. meta_ro_w->instanceStart = superclass->ISA()->unalignedInstanceSize();
  5047. cls->setInstanceSize(cls_ro_w->instanceStart);
  5048. meta->setInstanceSize(meta_ro_w->instanceStart);
  5049. } else {
  5050. cls_ro_w->instanceStart = 0;
  5051. meta_ro_w->instanceStart = (uint32_t)sizeof(objc_class);
  5052. cls->setInstanceSize((uint32_t)sizeof(id)); // just an isa
  5053. meta->setInstanceSize(meta_ro_w->instanceStart);
  5054. }
  5055. cls_ro_w->name = strdupIfMutable(name);
  5056. meta_ro_w->name = strdupIfMutable(name);
  5057. cls_ro_w->ivarLayout = &UnsetLayout;
  5058. cls_ro_w->weakIvarLayout = &UnsetLayout;
  5059. meta->chooseClassArrayIndex();
  5060. cls->chooseClassArrayIndex();
  5061. // Connect to superclasses and metaclasses
  5062. cls->initClassIsa(meta);
  5063. if (superclass) {
  5064. meta->initClassIsa(superclass->ISA()->ISA());
  5065. cls->superclass = superclass;
  5066. meta->superclass = superclass->ISA();
  5067. addSubclass(superclass, cls);
  5068. addSubclass(superclass->ISA(), meta);
  5069. } else {
  5070. meta->initClassIsa(meta);
  5071. cls->superclass = Nil;
  5072. meta->superclass = cls;
  5073. addRootClass(cls);
  5074. addSubclass(cls, meta);
  5075. }
  5076. cls->cache.initializeToEmpty();
  5077. meta->cache.initializeToEmpty();
  5078. addClassTableEntry(cls);
  5079. }
  5080. /***********************************************************************
  5081. * verifySuperclass
  5082. * Sanity-check the superclass provided to
  5083. * objc_allocateClassPair, objc_initializeClassPair, or objc_readClassPair.
  5084. **********************************************************************/
  5085. bool
  5086. verifySuperclass(Class superclass, bool rootOK)
  5087. {
  5088. if (!superclass) {
  5089. // Superclass does not exist.
  5090. // If subclass may be a root class, this is OK.
  5091. // If subclass must not be a root class, this is bad.
  5092. return rootOK;
  5093. }
  5094. // Superclass must be realized.
  5095. if (! superclass->isRealized()) return false;
  5096. // Superclass must not be under construction.
  5097. if (superclass->data()->flags & RW_CONSTRUCTING) return false;
  5098. return true;
  5099. }
  5100. /***********************************************************************
  5101. * objc_initializeClassPair
  5102. **********************************************************************/
  5103. Class objc_initializeClassPair(Class superclass, const char *name, Class cls, Class meta)
  5104. {
  5105. mutex_locker_t lock(runtimeLock);
  5106. // Fail if the class name is in use.
  5107. // Fail if the superclass isn't kosher.
  5108. if (getClass(name) || !verifySuperclass(superclass, true/*rootOK*/)) {
  5109. return nil;
  5110. }
  5111. objc_initializeClassPair_internal(superclass, name, cls, meta);
  5112. return cls;
  5113. }
  5114. /***********************************************************************
  5115. * objc_allocateClassPair
  5116. * fixme
  5117. * Locking: acquires runtimeLock
  5118. **********************************************************************/
  5119. Class objc_allocateClassPair(Class superclass, const char *name,
  5120. size_t extraBytes)
  5121. {
  5122. Class cls, meta;
  5123. mutex_locker_t lock(runtimeLock);
  5124. // Fail if the class name is in use.
  5125. // Fail if the superclass isn't kosher.
  5126. if (getClass(name) || !verifySuperclass(superclass, true/*rootOK*/)) {
  5127. return nil;
  5128. }
  5129. // Allocate new classes.
  5130. cls = alloc_class_for_subclass(superclass, extraBytes);
  5131. meta = alloc_class_for_subclass(superclass, extraBytes);
  5132. // fixme mangle the name if it looks swift-y?
  5133. objc_initializeClassPair_internal(superclass, name, cls, meta);
  5134. return cls;
  5135. }
  5136. /***********************************************************************
  5137. * objc_registerClassPair
  5138. * fixme
  5139. * Locking: acquires runtimeLock
  5140. **********************************************************************/
  5141. void objc_registerClassPair(Class cls)
  5142. {
  5143. mutex_locker_t lock(runtimeLock);
  5144. checkIsKnownClass(cls);
  5145. if ((cls->data()->flags & RW_CONSTRUCTED) ||
  5146. (cls->ISA()->data()->flags & RW_CONSTRUCTED))
  5147. {
  5148. _objc_inform("objc_registerClassPair: class '%s' was already "
  5149. "registered!", cls->data()->ro->name);
  5150. return;
  5151. }
  5152. if (!(cls->data()->flags & RW_CONSTRUCTING) ||
  5153. !(cls->ISA()->data()->flags & RW_CONSTRUCTING))
  5154. {
  5155. _objc_inform("objc_registerClassPair: class '%s' was not "
  5156. "allocated with objc_allocateClassPair!",
  5157. cls->data()->ro->name);
  5158. return;
  5159. }
  5160. // Clear "under construction" bit, set "done constructing" bit
  5161. cls->ISA()->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
  5162. cls->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
  5163. // Add to named class table.
  5164. addNamedClass(cls, cls->data()->ro->name);
  5165. }
  5166. /***********************************************************************
  5167. * objc_readClassPair()
  5168. * Read a class and metaclass as written by a compiler.
  5169. * Assumes the class and metaclass are not referenced by other things
  5170. * that might need to be fixed up (such as categories and subclasses).
  5171. * Does not call +load.
  5172. * Returns the class pointer, or nil.
  5173. *
  5174. * Locking: runtimeLock acquired by map_images
  5175. **********************************************************************/
  5176. Class objc_readClassPair(Class bits, const struct objc_image_info *info)
  5177. {
  5178. mutex_locker_t lock(runtimeLock);
  5179. // No info bits are significant yet.
  5180. (void)info;
  5181. // Fail if the superclass isn't kosher.
  5182. bool rootOK = bits->data()->flags & RO_ROOT;
  5183. if (!verifySuperclass(bits->superclass, rootOK)){
  5184. return nil;
  5185. }
  5186. // Duplicate classes are allowed, just like they are for image loading.
  5187. // readClass will complain about the duplicate.
  5188. Class cls = readClass(bits, false/*bundle*/, false/*shared cache*/);
  5189. if (cls != bits) {
  5190. // This function isn't allowed to remap anything.
  5191. _objc_fatal("objc_readClassPair for class %s changed %p to %p",
  5192. cls->nameForLogging(), bits, cls);
  5193. }
  5194. realizeClass(cls);
  5195. return cls;
  5196. }
  5197. /***********************************************************************
  5198. * detach_class
  5199. * Disconnect a class from other data structures.
  5200. * Exception: does not remove the class from the +load list
  5201. * Call this before free_class.
  5202. * Locking: runtimeLock must be held by the caller.
  5203. **********************************************************************/
  5204. static void detach_class(Class cls, bool isMeta)
  5205. {
  5206. runtimeLock.assertLocked();
  5207. // categories not yet attached to this class
  5208. removeAllUnattachedCategoriesForClass(cls);
  5209. // superclass's subclass list
  5210. if (cls->isRealized()) {
  5211. Class supercls = cls->superclass;
  5212. if (supercls) {
  5213. removeSubclass(supercls, cls);
  5214. } else {
  5215. removeRootClass(cls);
  5216. }
  5217. }
  5218. // class tables and +load queue
  5219. if (!isMeta) {
  5220. removeNamedClass(cls, cls->mangledName());
  5221. }
  5222. NXHashRemove(allocatedClasses, cls);
  5223. }
  5224. /***********************************************************************
  5225. * free_class
  5226. * Frees a class's data structures.
  5227. * Call this after detach_class.
  5228. * Locking: runtimeLock must be held by the caller
  5229. **********************************************************************/
  5230. static void free_class(Class cls)
  5231. {
  5232. runtimeLock.assertLocked();
  5233. if (! cls->isRealized()) return;
  5234. auto rw = cls->data();
  5235. auto ro = rw->ro;
  5236. cache_delete(cls);
  5237. for (auto& meth : rw->methods) {
  5238. try_free(meth.types);
  5239. }
  5240. rw->methods.tryFree();
  5241. const ivar_list_t *ivars = ro->ivars;
  5242. if (ivars) {
  5243. for (auto& ivar : *ivars) {
  5244. try_free(ivar.offset);
  5245. try_free(ivar.name);
  5246. try_free(ivar.type);
  5247. }
  5248. try_free(ivars);
  5249. }
  5250. for (auto& prop : rw->properties) {
  5251. try_free(prop.name);
  5252. try_free(prop.attributes);
  5253. }
  5254. rw->properties.tryFree();
  5255. rw->protocols.tryFree();
  5256. try_free(ro->ivarLayout);
  5257. try_free(ro->weakIvarLayout);
  5258. try_free(ro->name);
  5259. try_free(ro);
  5260. try_free(rw);
  5261. try_free(cls);
  5262. }
  5263. void objc_disposeClassPair(Class cls)
  5264. {
  5265. mutex_locker_t lock(runtimeLock);
  5266. checkIsKnownClass(cls);
  5267. if (!(cls->data()->flags & (RW_CONSTRUCTED|RW_CONSTRUCTING)) ||
  5268. !(cls->ISA()->data()->flags & (RW_CONSTRUCTED|RW_CONSTRUCTING)))
  5269. {
  5270. // class not allocated with objc_allocateClassPair
  5271. // disposing still-unregistered class is OK!
  5272. _objc_inform("objc_disposeClassPair: class '%s' was not "
  5273. "allocated with objc_allocateClassPair!",
  5274. cls->data()->ro->name);
  5275. return;
  5276. }
  5277. if (cls->isMetaClass()) {
  5278. _objc_inform("objc_disposeClassPair: class '%s' is a metaclass, "
  5279. "not a class!", cls->data()->ro->name);
  5280. return;
  5281. }
  5282. // Shouldn't have any live subclasses.
  5283. if (cls->data()->firstSubclass) {
  5284. _objc_inform("objc_disposeClassPair: class '%s' still has subclasses, "
  5285. "including '%s'!", cls->data()->ro->name,
  5286. cls->data()->firstSubclass->nameForLogging());
  5287. }
  5288. if (cls->ISA()->data()->firstSubclass) {
  5289. _objc_inform("objc_disposeClassPair: class '%s' still has subclasses, "
  5290. "including '%s'!", cls->data()->ro->name,
  5291. cls->ISA()->data()->firstSubclass->nameForLogging());
  5292. }
  5293. // don't remove_class_from_loadable_list()
  5294. // - it's not there and we don't have the lock
  5295. detach_class(cls->ISA(), YES);
  5296. detach_class(cls, NO);
  5297. free_class(cls->ISA());
  5298. free_class(cls);
  5299. }
  5300. /***********************************************************************
  5301. * objc_constructInstance
  5302. * Creates an instance of `cls` at the location pointed to by `bytes`.
  5303. * `bytes` must point to at least class_getInstanceSize(cls) bytes of
  5304. * well-aligned zero-filled memory.
  5305. * The new object's isa is set. Any C++ constructors are called.
  5306. * Returns `bytes` if successful. Returns nil if `cls` or `bytes` is
  5307. * nil, or if C++ constructors fail.
  5308. * Note: class_createInstance() and class_createInstances() preflight this.
  5309. **********************************************************************/
  5310. id
  5311. objc_constructInstance(Class cls, void *bytes)
  5312. {
  5313. if (!cls || !bytes) return nil;
  5314. id obj = (id)bytes;
  5315. // Read class's info bits all at once for performance
  5316. bool hasCxxCtor = cls->hasCxxCtor();
  5317. bool hasCxxDtor = cls->hasCxxDtor();
  5318. bool fast = cls->canAllocNonpointer();
  5319. if (fast) {
  5320. obj->initInstanceIsa(cls, hasCxxDtor);
  5321. } else {
  5322. obj->initIsa(cls);
  5323. }
  5324. if (hasCxxCtor) {
  5325. return object_cxxConstructFromClass(obj, cls);
  5326. } else {
  5327. return obj;
  5328. }
  5329. }
  5330. /***********************************************************************
  5331. * class_createInstance
  5332. * fixme
  5333. * Locking: none
  5334. **********************************************************************/
  5335. static __attribute__((always_inline))
  5336. id
  5337. _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,
  5338. bool cxxConstruct = true,
  5339. size_t *outAllocatedSize = nil)
  5340. {
  5341. if (!cls) return nil;
  5342. assert(cls->isRealized());
  5343. // Read class's info bits all at once for performance
  5344. bool hasCxxCtor = cls->hasCxxCtor();
  5345. bool hasCxxDtor = cls->hasCxxDtor();
  5346. bool fast = cls->canAllocNonpointer();
  5347. size_t size = cls->instanceSize(extraBytes);
  5348. if (outAllocatedSize) *outAllocatedSize = size;
  5349. id obj;
  5350. if (!zone && fast) {
  5351. obj = (id)calloc(1, size);
  5352. if (!obj) return nil;
  5353. obj->initInstanceIsa(cls, hasCxxDtor);
  5354. }
  5355. else {
  5356. if (zone) {
  5357. obj = (id)malloc_zone_calloc ((malloc_zone_t *)zone, 1, size);
  5358. } else {
  5359. obj = (id)calloc(1, size);
  5360. }
  5361. if (!obj) return nil;
  5362. // Use raw pointer isa on the assumption that they might be
  5363. // doing something weird with the zone or RR.
  5364. obj->initIsa(cls);
  5365. }
  5366. if (cxxConstruct && hasCxxCtor) {
  5367. obj = _objc_constructOrFree(obj, cls);
  5368. }
  5369. return obj;
  5370. }
  5371. id
  5372. class_createInstance(Class cls, size_t extraBytes)
  5373. {
  5374. return _class_createInstanceFromZone(cls, extraBytes, nil);
  5375. }
  5376. /***********************************************************************
  5377. * class_createInstances
  5378. * fixme
  5379. * Locking: none
  5380. **********************************************************************/
  5381. #if SUPPORT_NONPOINTER_ISA
  5382. #warning fixme optimize class_createInstances
  5383. #endif
  5384. unsigned
  5385. class_createInstances(Class cls, size_t extraBytes,
  5386. id *results, unsigned num_requested)
  5387. {
  5388. return _class_createInstancesFromZone(cls, extraBytes, nil,
  5389. results, num_requested);
  5390. }
  5391. /***********************************************************************
  5392. * object_copyFromZone
  5393. * fixme
  5394. * Locking: none
  5395. **********************************************************************/
  5396. static id
  5397. _object_copyFromZone(id oldObj, size_t extraBytes, void *zone)
  5398. {
  5399. if (!oldObj) return nil;
  5400. if (oldObj->isTaggedPointer()) return oldObj;
  5401. // fixme this doesn't handle C++ ivars correctly (#4619414)
  5402. Class cls = oldObj->ISA();
  5403. size_t size;
  5404. id obj = _class_createInstanceFromZone(cls, extraBytes, zone, false, &size);
  5405. if (!obj) return nil;
  5406. // Copy everything except the isa, which was already set above.
  5407. uint8_t *copyDst = (uint8_t *)obj + sizeof(Class);
  5408. uint8_t *copySrc = (uint8_t *)oldObj + sizeof(Class);
  5409. size_t copySize = size - sizeof(Class);
  5410. memmove(copyDst, copySrc, copySize);
  5411. fixupCopiedIvars(obj, oldObj);
  5412. return obj;
  5413. }
  5414. /***********************************************************************
  5415. * object_copy
  5416. * fixme
  5417. * Locking: none
  5418. **********************************************************************/
  5419. id
  5420. object_copy(id oldObj, size_t extraBytes)
  5421. {
  5422. return _object_copyFromZone(oldObj, extraBytes, malloc_default_zone());
  5423. }
  5424. #if SUPPORT_ZONES
  5425. /***********************************************************************
  5426. * class_createInstanceFromZone
  5427. * fixme
  5428. * Locking: none
  5429. **********************************************************************/
  5430. id
  5431. class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone)
  5432. {
  5433. return _class_createInstanceFromZone(cls, extraBytes, zone);
  5434. }
  5435. /***********************************************************************
  5436. * object_copyFromZone
  5437. * fixme
  5438. * Locking: none
  5439. **********************************************************************/
  5440. id
  5441. object_copyFromZone(id oldObj, size_t extraBytes, void *zone)
  5442. {
  5443. return _object_copyFromZone(oldObj, extraBytes, zone);
  5444. }
  5445. #endif
  5446. /***********************************************************************
  5447. * objc_destructInstance
  5448. * Destroys an instance without freeing memory.
  5449. * Calls C++ destructors.
  5450. * Calls ARC ivar cleanup.
  5451. * Removes associative references.
  5452. * Returns `obj`. Does nothing if `obj` is nil.
  5453. **********************************************************************/
  5454. void *objc_destructInstance(id obj)
  5455. {
  5456. if (obj) {
  5457. // Read all of the flags at once for performance.
  5458. bool cxx = obj->hasCxxDtor();
  5459. bool assoc = obj->hasAssociatedObjects();
  5460. // This order is important.
  5461. if (cxx) object_cxxDestruct(obj);
  5462. if (assoc) _object_remove_assocations(obj);
  5463. obj->clearDeallocating();
  5464. }
  5465. return obj;
  5466. }
  5467. /***********************************************************************
  5468. * object_dispose
  5469. * fixme
  5470. * Locking: none
  5471. **********************************************************************/
  5472. id
  5473. object_dispose(id obj)
  5474. {
  5475. if (!obj) return nil;
  5476. objc_destructInstance(obj);
  5477. free(obj);
  5478. return nil;
  5479. }
  5480. /***********************************************************************
  5481. * _objc_getFreedObjectClass
  5482. * fixme
  5483. * Locking: none
  5484. **********************************************************************/
  5485. Class _objc_getFreedObjectClass (void)
  5486. {
  5487. return nil;
  5488. }
  5489. /***********************************************************************
  5490. * Tagged pointer objects.
  5491. *
  5492. * Tagged pointer objects store the class and the object value in the
  5493. * object pointer; the "pointer" does not actually point to anything.
  5494. *
  5495. * Tagged pointer objects currently use this representation:
  5496. * (LSB)
  5497. * 1 bit set if tagged, clear if ordinary object pointer
  5498. * 3 bits tag index
  5499. * 60 bits payload
  5500. * (MSB)
  5501. * The tag index defines the object's class.
  5502. * The payload format is defined by the object's class.
  5503. *
  5504. * If the tag index is 0b111, the tagged pointer object uses an
  5505. * "extended" representation, allowing more classes but with smaller payloads:
  5506. * (LSB)
  5507. * 1 bit set if tagged, clear if ordinary object pointer
  5508. * 3 bits 0b111
  5509. * 8 bits extended tag index
  5510. * 52 bits payload
  5511. * (MSB)
  5512. *
  5513. * Some architectures reverse the MSB and LSB in these representations.
  5514. *
  5515. * This representation is subject to change. Representation-agnostic SPI is:
  5516. * objc-internal.h for class implementers.
  5517. * objc-gdb.h for debuggers.
  5518. **********************************************************************/
  5519. #if !SUPPORT_TAGGED_POINTERS
  5520. // These variables are always provided for debuggers.
  5521. uintptr_t objc_debug_taggedpointer_obfuscator = 0;
  5522. uintptr_t objc_debug_taggedpointer_mask = 0;
  5523. unsigned objc_debug_taggedpointer_slot_shift = 0;
  5524. uintptr_t objc_debug_taggedpointer_slot_mask = 0;
  5525. unsigned objc_debug_taggedpointer_payload_lshift = 0;
  5526. unsigned objc_debug_taggedpointer_payload_rshift = 0;
  5527. Class objc_debug_taggedpointer_classes[1] = { nil };
  5528. uintptr_t objc_debug_taggedpointer_ext_mask = 0;
  5529. unsigned objc_debug_taggedpointer_ext_slot_shift = 0;
  5530. uintptr_t objc_debug_taggedpointer_ext_slot_mask = 0;
  5531. unsigned objc_debug_taggedpointer_ext_payload_lshift = 0;
  5532. unsigned objc_debug_taggedpointer_ext_payload_rshift = 0;
  5533. Class objc_debug_taggedpointer_ext_classes[1] = { nil };
  5534. static void
  5535. disableTaggedPointers() { }
  5536. static void
  5537. initializeTaggedPointerObfuscator(void) { }
  5538. #else
  5539. // The "slot" used in the class table and given to the debugger
  5540. // includes the is-tagged bit. This makes objc_msgSend faster.
  5541. // The "ext" representation doesn't do that.
  5542. uintptr_t objc_debug_taggedpointer_obfuscator;
  5543. uintptr_t objc_debug_taggedpointer_mask = _OBJC_TAG_MASK;
  5544. unsigned objc_debug_taggedpointer_slot_shift = _OBJC_TAG_SLOT_SHIFT;
  5545. uintptr_t objc_debug_taggedpointer_slot_mask = _OBJC_TAG_SLOT_MASK;
  5546. unsigned objc_debug_taggedpointer_payload_lshift = _OBJC_TAG_PAYLOAD_LSHIFT;
  5547. unsigned objc_debug_taggedpointer_payload_rshift = _OBJC_TAG_PAYLOAD_RSHIFT;
  5548. // objc_debug_taggedpointer_classes is defined in objc-msg-*.s
  5549. uintptr_t objc_debug_taggedpointer_ext_mask = _OBJC_TAG_EXT_MASK;
  5550. unsigned objc_debug_taggedpointer_ext_slot_shift = _OBJC_TAG_EXT_SLOT_SHIFT;
  5551. uintptr_t objc_debug_taggedpointer_ext_slot_mask = _OBJC_TAG_EXT_SLOT_MASK;
  5552. unsigned objc_debug_taggedpointer_ext_payload_lshift = _OBJC_TAG_EXT_PAYLOAD_LSHIFT;
  5553. unsigned objc_debug_taggedpointer_ext_payload_rshift = _OBJC_TAG_EXT_PAYLOAD_RSHIFT;
  5554. // objc_debug_taggedpointer_ext_classes is defined in objc-msg-*.s
  5555. static void
  5556. disableTaggedPointers()
  5557. {
  5558. objc_debug_taggedpointer_mask = 0;
  5559. objc_debug_taggedpointer_slot_shift = 0;
  5560. objc_debug_taggedpointer_slot_mask = 0;
  5561. objc_debug_taggedpointer_payload_lshift = 0;
  5562. objc_debug_taggedpointer_payload_rshift = 0;
  5563. objc_debug_taggedpointer_ext_mask = 0;
  5564. objc_debug_taggedpointer_ext_slot_shift = 0;
  5565. objc_debug_taggedpointer_ext_slot_mask = 0;
  5566. objc_debug_taggedpointer_ext_payload_lshift = 0;
  5567. objc_debug_taggedpointer_ext_payload_rshift = 0;
  5568. }
  5569. // Returns a pointer to the class's storage in the tagged class arrays.
  5570. // Assumes the tag is a valid basic tag.
  5571. static Class *
  5572. classSlotForBasicTagIndex(objc_tag_index_t tag)
  5573. {
  5574. uintptr_t tagObfuscator = ((objc_debug_taggedpointer_obfuscator
  5575. >> _OBJC_TAG_INDEX_SHIFT)
  5576. & _OBJC_TAG_INDEX_MASK);
  5577. uintptr_t obfuscatedTag = tag ^ tagObfuscator;
  5578. // Array index in objc_tag_classes includes the tagged bit itself
  5579. #if SUPPORT_MSB_TAGGED_POINTERS
  5580. return &objc_tag_classes[0x8 | obfuscatedTag];
  5581. #else
  5582. return &objc_tag_classes[(obfuscatedTag << 1) | 1];
  5583. #endif
  5584. }
  5585. // Returns a pointer to the class's storage in the tagged class arrays,
  5586. // or nil if the tag is out of range.
  5587. static Class *
  5588. classSlotForTagIndex(objc_tag_index_t tag)
  5589. {
  5590. if (tag >= OBJC_TAG_First60BitPayload && tag <= OBJC_TAG_Last60BitPayload) {
  5591. return classSlotForBasicTagIndex(tag);
  5592. }
  5593. if (tag >= OBJC_TAG_First52BitPayload && tag <= OBJC_TAG_Last52BitPayload) {
  5594. int index = tag - OBJC_TAG_First52BitPayload;
  5595. uintptr_t tagObfuscator = ((objc_debug_taggedpointer_obfuscator
  5596. >> _OBJC_TAG_EXT_INDEX_SHIFT)
  5597. & _OBJC_TAG_EXT_INDEX_MASK);
  5598. return &objc_tag_ext_classes[index ^ tagObfuscator];
  5599. }
  5600. return nil;
  5601. }
  5602. /***********************************************************************
  5603. * initializeTaggedPointerObfuscator
  5604. * Initialize objc_debug_taggedpointer_obfuscator with randomness.
  5605. *
  5606. * The tagged pointer obfuscator is intended to make it more difficult
  5607. * for an attacker to construct a particular object as a tagged pointer,
  5608. * in the presence of a buffer overflow or other write control over some
  5609. * memory. The obfuscator is XORed with the tagged pointers when setting
  5610. * or retrieving payload values. They are filled with randomness on first
  5611. * use.
  5612. **********************************************************************/
  5613. static void
  5614. initializeTaggedPointerObfuscator(void)
  5615. {
  5616. if (sdkIsOlderThan(10_14, 12_0, 12_0, 5_0, 3_0) ||
  5617. // Set the obfuscator to zero for apps linked against older SDKs,
  5618. // in case they're relying on the tagged pointer representation.
  5619. DisableTaggedPointerObfuscation) {
  5620. objc_debug_taggedpointer_obfuscator = 0;
  5621. } else {
  5622. // Pull random data into the variable, then shift away all non-payload bits.
  5623. arc4random_buf(&objc_debug_taggedpointer_obfuscator,
  5624. sizeof(objc_debug_taggedpointer_obfuscator));
  5625. objc_debug_taggedpointer_obfuscator &= ~_OBJC_TAG_MASK;
  5626. }
  5627. }
  5628. /***********************************************************************
  5629. * _objc_registerTaggedPointerClass
  5630. * Set the class to use for the given tagged pointer index.
  5631. * Aborts if the tag is out of range, or if the tag is already
  5632. * used by some other class.
  5633. **********************************************************************/
  5634. void
  5635. _objc_registerTaggedPointerClass(objc_tag_index_t tag, Class cls)
  5636. {
  5637. if (objc_debug_taggedpointer_mask == 0) {
  5638. _objc_fatal("tagged pointers are disabled");
  5639. }
  5640. Class *slot = classSlotForTagIndex(tag);
  5641. if (!slot) {
  5642. _objc_fatal("tag index %u is invalid", (unsigned int)tag);
  5643. }
  5644. Class oldCls = *slot;
  5645. if (cls && oldCls && cls != oldCls) {
  5646. _objc_fatal("tag index %u used for two different classes "
  5647. "(was %p %s, now %p %s)", tag,
  5648. oldCls, oldCls->nameForLogging(),
  5649. cls, cls->nameForLogging());
  5650. }
  5651. *slot = cls;
  5652. // Store a placeholder class in the basic tag slot that is
  5653. // reserved for the extended tag space, if it isn't set already.
  5654. // Do this lazily when the first extended tag is registered so
  5655. // that old debuggers characterize bogus pointers correctly more often.
  5656. if (tag < OBJC_TAG_First60BitPayload || tag > OBJC_TAG_Last60BitPayload) {
  5657. Class *extSlot = classSlotForBasicTagIndex(OBJC_TAG_RESERVED_7);
  5658. if (*extSlot == nil) {
  5659. extern objc_class OBJC_CLASS_$___NSUnrecognizedTaggedPointer;
  5660. *extSlot = (Class)&OBJC_CLASS_$___NSUnrecognizedTaggedPointer;
  5661. }
  5662. }
  5663. }
  5664. /***********************************************************************
  5665. * _objc_getClassForTag
  5666. * Returns the class that is using the given tagged pointer tag.
  5667. * Returns nil if no class is using that tag or the tag is out of range.
  5668. **********************************************************************/
  5669. Class
  5670. _objc_getClassForTag(objc_tag_index_t tag)
  5671. {
  5672. Class *slot = classSlotForTagIndex(tag);
  5673. if (slot) return *slot;
  5674. else return nil;
  5675. }
  5676. #endif
  5677. #if SUPPORT_FIXUP
  5678. OBJC_EXTERN void objc_msgSend_fixup(void);
  5679. OBJC_EXTERN void objc_msgSendSuper2_fixup(void);
  5680. OBJC_EXTERN void objc_msgSend_stret_fixup(void);
  5681. OBJC_EXTERN void objc_msgSendSuper2_stret_fixup(void);
  5682. #if defined(__i386__) || defined(__x86_64__)
  5683. OBJC_EXTERN void objc_msgSend_fpret_fixup(void);
  5684. #endif
  5685. #if defined(__x86_64__)
  5686. OBJC_EXTERN void objc_msgSend_fp2ret_fixup(void);
  5687. #endif
  5688. OBJC_EXTERN void objc_msgSend_fixedup(void);
  5689. OBJC_EXTERN void objc_msgSendSuper2_fixedup(void);
  5690. OBJC_EXTERN void objc_msgSend_stret_fixedup(void);
  5691. OBJC_EXTERN void objc_msgSendSuper2_stret_fixedup(void);
  5692. #if defined(__i386__) || defined(__x86_64__)
  5693. OBJC_EXTERN void objc_msgSend_fpret_fixedup(void);
  5694. #endif
  5695. #if defined(__x86_64__)
  5696. OBJC_EXTERN void objc_msgSend_fp2ret_fixedup(void);
  5697. #endif
  5698. /***********************************************************************
  5699. * fixupMessageRef
  5700. * Repairs an old vtable dispatch call site.
  5701. * vtable dispatch itself is not supported.
  5702. **********************************************************************/
  5703. static void
  5704. fixupMessageRef(message_ref_t *msg)
  5705. {
  5706. msg->sel = sel_registerName((const char *)msg->sel);
  5707. if (msg->imp == &objc_msgSend_fixup) {
  5708. if (msg->sel == SEL_alloc) {
  5709. msg->imp = (IMP)&objc_alloc;
  5710. } else if (msg->sel == SEL_allocWithZone) {
  5711. msg->imp = (IMP)&objc_allocWithZone;
  5712. } else if (msg->sel == SEL_retain) {
  5713. msg->imp = (IMP)&objc_retain;
  5714. } else if (msg->sel == SEL_release) {
  5715. msg->imp = (IMP)&objc_release;
  5716. } else if (msg->sel == SEL_autorelease) {
  5717. msg->imp = (IMP)&objc_autorelease;
  5718. } else {
  5719. msg->imp = &objc_msgSend_fixedup;
  5720. }
  5721. }
  5722. else if (msg->imp == &objc_msgSendSuper2_fixup) {
  5723. msg->imp = &objc_msgSendSuper2_fixedup;
  5724. }
  5725. else if (msg->imp == &objc_msgSend_stret_fixup) {
  5726. msg->imp = &objc_msgSend_stret_fixedup;
  5727. }
  5728. else if (msg->imp == &objc_msgSendSuper2_stret_fixup) {
  5729. msg->imp = &objc_msgSendSuper2_stret_fixedup;
  5730. }
  5731. #if defined(__i386__) || defined(__x86_64__)
  5732. else if (msg->imp == &objc_msgSend_fpret_fixup) {
  5733. msg->imp = &objc_msgSend_fpret_fixedup;
  5734. }
  5735. #endif
  5736. #if defined(__x86_64__)
  5737. else if (msg->imp == &objc_msgSend_fp2ret_fixup) {
  5738. msg->imp = &objc_msgSend_fp2ret_fixedup;
  5739. }
  5740. #endif
  5741. }
  5742. // SUPPORT_FIXUP
  5743. #endif
  5744. // ProKit SPI
  5745. static Class setSuperclass(Class cls, Class newSuper)
  5746. {
  5747. Class oldSuper;
  5748. runtimeLock.assertLocked();
  5749. assert(cls->isRealized());
  5750. assert(newSuper->isRealized());
  5751. oldSuper = cls->superclass;
  5752. removeSubclass(oldSuper, cls);
  5753. removeSubclass(oldSuper->ISA(), cls->ISA());
  5754. cls->superclass = newSuper;
  5755. cls->ISA()->superclass = newSuper->ISA();
  5756. addSubclass(newSuper, cls);
  5757. addSubclass(newSuper->ISA(), cls->ISA());
  5758. // Flush subclass's method caches.
  5759. flushCaches(cls);
  5760. flushCaches(cls->ISA());
  5761. return oldSuper;
  5762. }
  5763. Class class_setSuperclass(Class cls, Class newSuper)
  5764. {
  5765. mutex_locker_t lock(runtimeLock);
  5766. return setSuperclass(cls, newSuper);
  5767. }
  5768. // __OBJC2__
  5769. #endif