symbols.c 341 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067
  1. /* symbols.c - core analysis suite
  2. *
  3. * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
  4. * Copyright (C) 2002-2014 David Anderson
  5. * Copyright (C) 2002-2014 Red Hat, Inc. All rights reserved.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. */
  17. #include "defs.h"
  18. #include <elf.h>
  19. #ifdef GDB_7_6
  20. #define __CONFIG_H__ 1
  21. #include "config.h"
  22. #endif
  23. #include "bfd.h"
  24. static void store_symbols(bfd *, int, void *, long, unsigned int);
  25. static void store_sysmap_symbols(void);
  26. static ulong relocate(ulong, char *, int);
  27. static int relocate_force(ulong, char *);
  28. static void kaslr_init(void);
  29. static ulong symbol_value_from_proc_kallsyms(char *);
  30. static void strip_module_symbol_end(char *s);
  31. static int compare_syms(const void *, const void *);
  32. static int compare_mods(const void *, const void *);
  33. static int compare_prios(const void *v1, const void *v2);
  34. static asection *get_kernel_section(char *);
  35. static char * get_section(ulong vaddr, char *buf);
  36. static void symbol_dump(ulong, char *);
  37. static void check_for_dups(struct load_module *);
  38. static int symbol_name_count(char *);
  39. static struct syment *kallsyms_module_symbol(struct load_module *, symbol_info *);
  40. static void store_load_module_symbols \
  41. (bfd *, int, void *, long, uint, ulong, char *);
  42. static int load_module_index(struct syment *);
  43. static void section_header_info(bfd *, asection *, void *);
  44. static void store_section_data(struct load_module *, bfd *, asection *);
  45. static void calculate_load_order_v1(struct load_module *, bfd *);
  46. static void calculate_load_order_v2(struct load_module *, bfd *, int,
  47. void *, long, unsigned int);
  48. static void check_insmod_builtin(struct load_module *, int, ulong *);
  49. static int is_insmod_builtin(struct load_module *, struct syment *);
  50. struct load_module;
  51. static int add_symbol_file(struct load_module *);
  52. static int add_symbol_file_kallsyms(struct load_module *, struct gnu_request *);
  53. static void find_mod_etext(struct load_module *);
  54. static long rodata_search(ulong *, ulong);
  55. static int ascii_long(ulong word);
  56. static int is_bfd_format(char *);
  57. static int is_binary_stripped(char *);
  58. static int namespace_ctl(int, struct symbol_namespace *, void *, void *);
  59. static void symval_hash_init(void);
  60. static struct syment *symval_hash_search(ulong);
  61. static void symname_hash_init(void);
  62. static void symname_hash_install(struct syment *);
  63. static struct syment *symname_hash_search(char *);
  64. static void gnu_qsort(bfd *, void *, long, unsigned int, asymbol *, asymbol *);
  65. static int check_gnu_debuglink(bfd *);
  66. static int separate_debug_file_exists(const char *, unsigned long, int *);
  67. static int store_module_kallsyms_v1(struct load_module *, int, int, char *);
  68. static int store_module_kallsyms_v2(struct load_module *, int, int, char *);
  69. static void datatype_error(void **, char *, char *, char *, int);
  70. static char *get_thisfile(void);
  71. struct elf_common;
  72. static void Elf32_Sym_to_common(Elf32_Sym *, struct elf_common *);
  73. static void Elf64_Sym_to_common(Elf64_Sym *, struct elf_common *);
  74. static void cmd_datatype_common(ulong);
  75. static void do_datatype_addr(struct datatype_member *, ulong, int,
  76. ulong, char **, int);
  77. static void process_gdb_output(char *, unsigned, const char *, int);
  78. static int display_per_cpu_info(struct syment *, int, char *);
  79. static struct load_module *get_module_percpu_sym_owner(struct syment *);
  80. static int is_percpu_symbol(struct syment *);
  81. static void dump_percpu_symbols(struct load_module *);
  82. static void print_struct_with_dereference(ulong, struct datatype_member *, ulong);
  83. static int dereference_pointer(ulong, struct datatype_member *, ulong);
  84. #define KERNEL_SECTIONS (void *)(1)
  85. #define MODULE_SECTIONS (void *)(2)
  86. #define VERIFY_SECTIONS (void *)(3)
  87. #define EV_DWARFEXTRACT 101010101
  88. #define PARSE_FOR_DATA (1)
  89. #define PARSE_FOR_DECLARATION (2)
  90. static void parse_for_member(struct datatype_member *, ulong);
  91. static int show_member_offset(FILE *, struct datatype_member *, char *);
  92. /*
  93. * structure/union printing stuff
  94. */
  95. #define UINT8 (0x1)
  96. #define INT8 (0x2)
  97. #define UINT16 (0x4)
  98. #define INT16 (0x8)
  99. #define UINT32 (0x10)
  100. #define INT32 (0x20)
  101. #define UINT64 (0x40)
  102. #define INT64 (0x80)
  103. #define POINTER (0x100)
  104. #define FUNCTION (0x200)
  105. #define UNION_REQUEST (0x400)
  106. #define STRUCT_REQUEST (0x800)
  107. #define ARRAY (0x1000)
  108. #define ENUM (0x2000)
  109. #define TYPEDEF (0x4000)
  110. #define STRUCT_VERBOSE (0x8000)
  111. #define SHOW_OFFSET (0x10000)
  112. #define IN_UNION (0x20000)
  113. #define IN_STRUCT (0x40000)
  114. #define DATATYPE_QUERY (0x80000)
  115. #define ANON_MEMBER_QUERY (0x100000)
  116. #define SHOW_RAW_DATA (0x200000)
  117. #define DEREF_POINTERS (0x400000)
  118. #define INTEGER_TYPE (UINT8|INT8|UINT16|INT16|UINT32|INT32|UINT64|INT64)
  119. #define INITIAL_INDENT (4)
  120. #define INDENT_INCR (2)
  121. static void whatis_datatype(char *, ulong, FILE *);
  122. static void whatis_variable(struct syment *);
  123. static void print_struct(char *, ulong);
  124. static void print_union(char *, ulong);
  125. static void dump_datatype_member(FILE *, struct datatype_member *);
  126. static void dump_datatype_flags(ulong, FILE *);
  127. static long anon_member_offset(char *, char *);
  128. static int gdb_whatis(char *);
  129. static void do_datatype_declaration(struct datatype_member *, ulong);
  130. static int member_to_datatype(char *, struct datatype_member *, ulong);
  131. #define DEBUGINFO_ERROR_MESSAGE1 \
  132. "the use of a System.map file requires that the accompanying namelist\nargument is a kernel file built with the -g CFLAG. The namelist argument\nsupplied in this case is a debuginfo file, which must be accompanied by the\nkernel file from which it was derived.\n"
  133. #define DEBUGINFO_ERROR_MESSAGE2 \
  134. "The namelist argument supplied in this case is a debuginfo file,\nwhich must be accompanied by the kernel file from which it was derived.\n"
  135. /*
  136. * This routine scours the namelist for kernel text and data symbols,
  137. * sorts, and stores, them in a static table for quick reference.
  138. */
  139. void
  140. symtab_init(void)
  141. {
  142. char **matching;
  143. long symcount;
  144. void *minisyms;
  145. unsigned int size;
  146. asymbol *sort_x;
  147. asymbol *sort_y;
  148. if ((st->bfd = bfd_openr(pc->namelist, NULL)) == NULL)
  149. error(FATAL, "cannot open object file: %s\n", pc->namelist);
  150. if (!bfd_check_format_matches(st->bfd, bfd_object, &matching))
  151. error(FATAL, "cannot determine object file format: %s\n",
  152. pc->namelist);
  153. /*
  154. * Check whether the namelist is a kerntypes file built by
  155. * dwarfextract, which places a magic number in e_version.
  156. */
  157. if (file_elf_version(pc->namelist) == EV_DWARFEXTRACT)
  158. pc->flags |= KERNTYPES;
  159. if (pc->flags & SYSMAP) {
  160. bfd_map_over_sections(st->bfd, section_header_info,
  161. VERIFY_SECTIONS);
  162. if ((st->flags & (NO_SEC_LOAD|NO_SEC_CONTENTS)) ==
  163. (NO_SEC_LOAD|NO_SEC_CONTENTS)) {
  164. error(INFO, "%s: no text and data contents\n",
  165. pc->namelist);
  166. error(FATAL, pc->flags & SYSMAP_ARG ?
  167. DEBUGINFO_ERROR_MESSAGE1 :
  168. DEBUGINFO_ERROR_MESSAGE2);
  169. }
  170. store_sysmap_symbols();
  171. return;
  172. } else if (LKCD_KERNTYPES())
  173. error(FATAL, "%s: use of kerntypes requires a system map\n",
  174. pc->namelist);
  175. /*
  176. * Pull a bait-and-switch on st->bfd if we've got a separate
  177. * .gnu_debuglink file that matches the CRC. Not done for kerntypes.
  178. */
  179. if (!(LKCD_KERNTYPES()) &&
  180. !(bfd_get_file_flags(st->bfd) & HAS_SYMS)) {
  181. if (!check_gnu_debuglink(st->bfd))
  182. no_debugging_data(FATAL);
  183. }
  184. /*
  185. * Gather references to the kernel sections.
  186. */
  187. if ((st->sections = (struct sec *)
  188. malloc(st->bfd->section_count * sizeof(struct sec *))) == NULL)
  189. error(FATAL, "symbol table section array malloc: %s\n",
  190. strerror(errno));
  191. BZERO(st->sections, st->bfd->section_count * sizeof(struct sec *));
  192. st->first_section_start = st->last_section_end = 0;
  193. bfd_map_over_sections(st->bfd, section_header_info, KERNEL_SECTIONS);
  194. if ((st->flags & (NO_SEC_LOAD|NO_SEC_CONTENTS)) ==
  195. (NO_SEC_LOAD|NO_SEC_CONTENTS)) {
  196. if (!pc->namelist_debug && !pc->debuginfo_file) {
  197. error(INFO, "%s: no text and data contents\n",
  198. pc->namelist);
  199. error(FATAL, DEBUGINFO_ERROR_MESSAGE2);
  200. }
  201. }
  202. symcount = bfd_read_minisymbols(st->bfd, FALSE, &minisyms, &size);
  203. if (symcount <= 0)
  204. no_debugging_data(FATAL);
  205. sort_x = bfd_make_empty_symbol(st->bfd);
  206. sort_y = bfd_make_empty_symbol(st->bfd);
  207. if (sort_x == NULL || sort_y == NULL)
  208. error(FATAL, "bfd_make_empty_symbol() failed\n");
  209. kaslr_init();
  210. gnu_qsort(st->bfd, minisyms, symcount, size, sort_x, sort_y);
  211. store_symbols(st->bfd, FALSE, minisyms, symcount, size);
  212. free(minisyms);
  213. symname_hash_init();
  214. symval_hash_init();
  215. }
  216. /*
  217. * Adapted from gdb's get_debug_link_info()
  218. *
  219. * Look in: current directory
  220. * basename-of-namelist/.debug directory
  221. * /usr/lib/debug/boot (since we know it's a Red Hat kernel)
  222. */
  223. static int
  224. check_gnu_debuglink(bfd *bfd)
  225. {
  226. int i, exists, found;
  227. asection *sect;
  228. bfd_size_type debuglink_size;
  229. char *contents;
  230. int crc_offset;
  231. unsigned long crc32;
  232. char *dirname;
  233. char *namelist_debug;
  234. char **matching;
  235. sect = bfd_get_section_by_name(bfd, ".gnu_debuglink");
  236. if (!sect) {
  237. error(INFO, "%s: no .gnu_debuglink section\n", pc->namelist);
  238. return FALSE;
  239. }
  240. debuglink_size = bfd_section_size(bfd, sect);
  241. contents = GETBUF(debuglink_size);
  242. bfd_get_section_contents(bfd, sect, contents,
  243. (file_ptr)0, (bfd_size_type)debuglink_size);
  244. crc_offset = strlen (contents) + 1;
  245. crc_offset = (crc_offset + 3) & ~3;
  246. crc32 = bfd_get_32(bfd, (bfd_byte *)(contents + crc_offset));
  247. if (CRASHDEBUG(1))
  248. error(NOTE, "gnu_debuglink file: %s\ncrc32: %lx\n",
  249. contents, crc32);
  250. if ((pc->debuginfo_file = (char *)
  251. malloc(((strlen(pc->namelist) + strlen("/.debug/") +
  252. + strlen(".debug") + strlen(" /usr/lib/debug/boot/ "))*10)
  253. + strlen(pc->namelist_debug ? pc->namelist_debug : " "))) == NULL)
  254. error(FATAL, "debuginfo file name malloc: %s\n",
  255. strerror(errno));
  256. dirname = GETBUF(strlen(pc->namelist)+1);
  257. strcpy(dirname, pc->namelist);
  258. for (i = strlen(dirname)-1; i >= 0; i--)
  259. {
  260. if (dirname[i] == '/')
  261. break;
  262. }
  263. dirname[i+1] = NULLCHAR;
  264. if (!strlen(dirname))
  265. sprintf(dirname, ".");
  266. namelist_debug = NULL;
  267. if (pc->namelist_debug) {
  268. sprintf(pc->debuginfo_file, "%s", pc->namelist_debug);
  269. if (separate_debug_file_exists(pc->debuginfo_file,
  270. crc32, &exists)) {
  271. if (CRASHDEBUG(1))
  272. fprintf(fp, "%s: CRC matches\n",
  273. pc->debuginfo_file);
  274. st->flags |= CRC_MATCHES;
  275. goto reset_bfd;
  276. } else {
  277. if ((st->flags & FORCE_DEBUGINFO) && exists) {
  278. error(WARNING,
  279. "%s:\n CRC value does not match\n\n",
  280. pc->debuginfo_file);
  281. goto reset_bfd;
  282. } else
  283. error(INFO, "%s:\n CRC value does not match\n\n",
  284. pc->debuginfo_file);
  285. namelist_debug = pc->namelist_debug;
  286. pc->namelist_debug = NULL;
  287. }
  288. }
  289. found = 0;
  290. sprintf(pc->debuginfo_file, "%s/%s", dirname, contents);
  291. if (separate_debug_file_exists(pc->debuginfo_file, crc32, &exists)) {
  292. if (CRASHDEBUG(1))
  293. fprintf(fp, "%s: CRC matches\n", pc->debuginfo_file);
  294. st->flags |= CRC_MATCHES;
  295. goto reset_bfd;
  296. } else {
  297. if (CRASHDEBUG(1))
  298. fprintf(fp, "%s: %s\n", pc->debuginfo_file, exists ?
  299. "CRC does not match" : "not readable/found");
  300. if (exists) {
  301. error(INFO, "%s: CRC does not match\n\n",
  302. pc->debuginfo_file);
  303. found++;
  304. }
  305. }
  306. sprintf(pc->debuginfo_file, "%s/.debug/%s", dirname, contents);
  307. if (separate_debug_file_exists(pc->debuginfo_file, crc32, &exists)) {
  308. if (CRASHDEBUG(1))
  309. fprintf(fp, "%s: CRC matches\n", pc->debuginfo_file);
  310. st->flags |= CRC_MATCHES;
  311. goto reset_bfd;
  312. } else {
  313. if (CRASHDEBUG(1))
  314. fprintf(fp, "%s: %s\n", pc->debuginfo_file, exists ?
  315. "CRC does not match" : "not readable/found");
  316. if (exists) {
  317. error(INFO, "%s: CRC does not match\n\n",
  318. pc->debuginfo_file);
  319. found++;
  320. }
  321. }
  322. sprintf(pc->debuginfo_file, "/usr/lib/debug/boot/%s", contents);
  323. if (separate_debug_file_exists(pc->debuginfo_file, crc32, &exists)) {
  324. if (CRASHDEBUG(1))
  325. fprintf(fp, "%s: CRC matches\n", pc->debuginfo_file);
  326. st->flags |= CRC_MATCHES;
  327. goto reset_bfd;
  328. } else {
  329. if (CRASHDEBUG(1))
  330. fprintf(fp, "%s: %s\n", pc->debuginfo_file, exists ?
  331. "CRC does not match" : "not readable/found");
  332. if (exists) {
  333. error(INFO, "%s: CRC does not match\n\n",
  334. pc->debuginfo_file);
  335. found++;
  336. }
  337. }
  338. if (!found && namelist_debug) {
  339. error(INFO,
  340. "%s:\n use of -f option may suffice, or may fail miserably\n",
  341. namelist_debug);
  342. }
  343. if (!found && !namelist_debug) {
  344. no_debugging_data(INFO);
  345. error(INFO, "%s: debuginfo file not found\n", contents);
  346. error(FATAL,
  347. "either install the appropriate kernel debuginfo package, or\n copy %s to this machine", contents);
  348. }
  349. return FALSE;
  350. reset_bfd:
  351. if ((st->bfd = bfd_openr(pc->debuginfo_file, NULL)) == NULL)
  352. error(FATAL, "cannot open object file: %s\n",
  353. pc->debuginfo_file);
  354. if (!bfd_check_format_matches(st->bfd, bfd_object, &matching))
  355. error(FATAL, "cannot determine object file format: %s\n",
  356. pc->debuginfo_file);
  357. FREEBUF(contents);
  358. FREEBUF(dirname);
  359. return TRUE;
  360. }
  361. /*
  362. * Based upon gdb's separate_debug_file_exists().
  363. */
  364. static int
  365. separate_debug_file_exists(const char *name, unsigned long crc, int *exists)
  366. {
  367. unsigned long file_crc = 0;
  368. int fd;
  369. char buffer[8*1024];
  370. size_t count;
  371. fd = open(name, O_RDONLY);
  372. if (fd < 0) {
  373. *exists = FALSE;
  374. return 0;
  375. }
  376. *exists = TRUE;
  377. while ((count = read(fd, buffer, sizeof(buffer))) > 0)
  378. #ifdef GDB_5_3
  379. file_crc = calc_crc32(file_crc, buffer, count);
  380. #else
  381. #ifdef GDB_7_6
  382. file_crc = bfd_calc_gnu_debuglink_crc32(file_crc,
  383. (unsigned char *)buffer, count);
  384. #else
  385. file_crc = gnu_debuglink_crc32(file_crc,
  386. (unsigned char *)buffer, count);
  387. #endif
  388. #endif
  389. close (fd);
  390. return crc == file_crc;
  391. }
  392. /*
  393. * Callback for gdb to use a specified vmlinux.debug file.
  394. */
  395. char *
  396. check_specified_kernel_debug_file()
  397. {
  398. if (pc->flags & GDB_INIT)
  399. return NULL;
  400. return (pc->namelist_debug ? pc->namelist_debug : NULL);
  401. }
  402. /*
  403. * Common bailout/warning routine when running against non-debug kernels.
  404. *
  405. * INFO: used when this routine should return.
  406. * FATAL: kills function if runtime, or kills program if during init.
  407. * WARNING: called by gdb_session_init() only, in an attempt to at least
  408. * get by with built-in debug data; if not possible the program
  409. * is killed.
  410. */
  411. void
  412. no_debugging_data(int error_type)
  413. {
  414. switch (error_type)
  415. {
  416. case INFO:
  417. error(INFO, "%s: no debugging data available\n", pc->namelist);
  418. break;
  419. case FATAL:
  420. error(FATAL, "%s%s: no debugging data available\n",
  421. pc->flags & RUNTIME ? "" : "\n", pc->namelist);
  422. clean_exit(1);
  423. case WARNING:
  424. error(FATAL, "\n%s: no debugging data available\n",
  425. pc->namelist);
  426. clean_exit(1);
  427. }
  428. }
  429. /*
  430. * Get the address space formerly used as init-time text. While there
  431. * get the boundaries of the kernel .rodata section so that it won't
  432. * be confused with text.
  433. *
  434. * This is done indirectly by the call-back to section_header_info().
  435. */
  436. void
  437. get_text_init_space(void)
  438. {
  439. asection *section = NULL;
  440. if (pc->flags & SYSMAP)
  441. return;
  442. if (machine_type("ARM"))
  443. section = get_kernel_section(".init");
  444. if (!section && !(section = get_kernel_section(".text.init")))
  445. section = get_kernel_section(".init.text");
  446. if (!section) {
  447. error(WARNING, "cannot determine text init space\n");
  448. return;
  449. }
  450. kt->stext_init = (ulong)bfd_get_section_vma(st->bfd, section);
  451. kt->etext_init = kt->stext_init +
  452. (ulong)bfd_section_size(st->bfd, section);
  453. if (kt->relocate) {
  454. kt->stext_init -= kt->relocate;
  455. kt->etext_init -= kt->relocate;
  456. }
  457. }
  458. /*
  459. * Strip gcc-generated cloned text symbol name endings.
  460. */
  461. static char *
  462. strip_symbol_end(const char *name, char *buf)
  463. {
  464. char *p;
  465. if (st->flags & NO_STRIP)
  466. return (char *)name;
  467. if ((p = strstr(name, ".isra."))) {
  468. if (buf) {
  469. strcpy(buf, name);
  470. buf[p-name] = NULLCHAR;
  471. return buf;
  472. } else {
  473. *p = NULLCHAR;
  474. return (char *)name;
  475. }
  476. }
  477. if ((p = strstr(name, ".part."))) {
  478. if (buf) {
  479. strcpy(buf, name);
  480. buf[p-name] = NULLCHAR;
  481. return buf;
  482. } else {
  483. *p = NULLCHAR;
  484. return (char *)name;
  485. }
  486. }
  487. return (char *)name;
  488. }
  489. /*
  490. * Gather the relevant information from the dumpfile or live system
  491. * and determine whether to derive the KASLR offset.
  492. *
  493. * Setting st->_stext_vmlinux to UNINITIALIZED will trigger the
  494. * search for "_stext" from the vmlinux file during the initial
  495. * symbol sort operation.
  496. *
  497. * Setting RELOC_AUTO will ensure that derive_kaslr_offset() is
  498. * called after the sorting operation has captured the vmlinux
  499. * file's "_stext" symbol value -- which it will compare to the
  500. * relocated "_stext" value found in either a dumpfile's vmcoreinfo
  501. * or in /proc/kallsyms on a live system.
  502. *
  503. * Setting KASLR_CHECK will trigger a search for "randomize_modules"
  504. * during the initial symbol sort operation, and if found, will
  505. * set (RELOC_AUTO|KASLR). On live systems, the search is done
  506. * here by checking /proc/kallsyms.
  507. */
  508. static void
  509. kaslr_init(void)
  510. {
  511. char *string;
  512. if (!machine_type("X86_64") || (kt->flags & RELOC_SET))
  513. return;
  514. /*
  515. * --kaslr=auto
  516. */
  517. if ((kt->flags2 & (RELOC_AUTO|KASLR)) == (RELOC_AUTO|KASLR))
  518. st->_stext_vmlinux = UNINITIALIZED;
  519. if (ACTIVE() && /* Linux 3.15 */
  520. (symbol_value_from_proc_kallsyms("randomize_modules") != BADVAL)) {
  521. kt->flags2 |= (RELOC_AUTO|KASLR);
  522. st->_stext_vmlinux = UNINITIALIZED;
  523. }
  524. if (KDUMP_DUMPFILE() || DISKDUMP_DUMPFILE()) {
  525. if ((string = pc->read_vmcoreinfo("SYMBOL(_stext)"))) {
  526. kt->vmcoreinfo._stext_SYMBOL =
  527. htol(string, RETURN_ON_ERROR, NULL);
  528. free(string);
  529. }
  530. /* Linux 3.14 */
  531. if ((string = pc->read_vmcoreinfo("KERNELOFFSET"))) {
  532. free(string);
  533. kt->flags2 |= KASLR_CHECK;
  534. st->_stext_vmlinux = UNINITIALIZED;
  535. }
  536. }
  537. }
  538. /*
  539. * Derives the kernel aslr offset by comparing the _stext symbol from the
  540. * the vmcoreinfo in the dump file to the _stext symbol in the vmlinux file.
  541. */
  542. static void
  543. derive_kaslr_offset(bfd *abfd, int dynamic, bfd_byte *start, bfd_byte *end,
  544. unsigned int size, asymbol *store)
  545. {
  546. unsigned long relocate;
  547. ulong _stext_relocated;
  548. if (ACTIVE()) {
  549. _stext_relocated = symbol_value_from_proc_kallsyms("_stext");
  550. if (_stext_relocated == BADVAL)
  551. return;
  552. } else {
  553. _stext_relocated = kt->vmcoreinfo._stext_SYMBOL;
  554. if (_stext_relocated == 0)
  555. return;
  556. }
  557. /*
  558. * To avoid mistaking an mismatched kernel version with
  559. * a kaslr offset, we make sure that the offset is
  560. * aligned by 0x1000, as it always will be for kaslr.
  561. */
  562. if (st->_stext_vmlinux && (st->_stext_vmlinux != UNINITIALIZED)) {
  563. relocate = st->_stext_vmlinux - _stext_relocated;
  564. if (relocate && !(relocate & 0xfff)) {
  565. kt->relocate = relocate;
  566. kt->flags |= RELOC_SET;
  567. }
  568. }
  569. if (CRASHDEBUG(1) && (kt->flags & RELOC_SET)) {
  570. fprintf(fp, "KASLR:\n");
  571. fprintf(fp, " _stext from %s: %lx\n",
  572. basename(pc->namelist), st->_stext_vmlinux);
  573. fprintf(fp, " _stext from %s: %lx\n",
  574. ACTIVE() ? "/proc/kallsyms" : "vmcoreinfo",
  575. _stext_relocated);
  576. fprintf(fp, " relocate: %lx (%ldMB)\n",
  577. kt->relocate * -1, (kt->relocate * -1) >> 20);
  578. }
  579. }
  580. /*
  581. * Store the symbols gathered by symtab_init(). The symbols are stored
  582. * in increasing numerical order.
  583. */
  584. static void
  585. store_symbols(bfd *abfd, int dynamic, void *minisyms, long symcount,
  586. unsigned int size)
  587. {
  588. asymbol *store;
  589. asymbol *sym;
  590. bfd_byte *from, *fromend;
  591. symbol_info syminfo;
  592. struct syment *sp;
  593. char buf[BUFSIZE];
  594. char *name;
  595. int first;
  596. if ((store = bfd_make_empty_symbol(abfd)) == NULL)
  597. error(FATAL, "bfd_make_empty_symbol() failed\n");
  598. if ((st->symtable = (struct syment *)
  599. calloc(symcount, sizeof(struct syment))) == NULL)
  600. error(FATAL, "symbol table syment space malloc: %s\n",
  601. strerror(errno));
  602. if (!namespace_ctl(NAMESPACE_INIT, &st->kernel_namespace,
  603. (void *)symcount, NULL))
  604. error(FATAL, "symbol table namespace malloc: %s\n",
  605. strerror(errno));
  606. st->syment_size = symcount * sizeof(struct syment);
  607. st->symcnt = 0;
  608. sp = st->symtable;
  609. first = 0;
  610. from = (bfd_byte *) minisyms;
  611. fromend = from + symcount * size;
  612. if (machine_type("X86")) {
  613. if (!(kt->flags & RELOC_SET))
  614. kt->flags |= RELOC_FORCE;
  615. } else if (machine_type("X86_64")) {
  616. if ((kt->flags2 & RELOC_AUTO) && !(kt->flags & RELOC_SET))
  617. derive_kaslr_offset(abfd, dynamic, from,
  618. fromend, size, store);
  619. } else
  620. kt->flags &= ~RELOC_SET;
  621. for (; from < fromend; from += size)
  622. {
  623. if ((sym = bfd_minisymbol_to_symbol(abfd, dynamic, from, store))
  624. == NULL)
  625. error(FATAL, "bfd_minisymbol_to_symbol() failed\n");
  626. bfd_get_symbol_info(abfd, sym, &syminfo);
  627. name = strip_symbol_end(syminfo.name, buf);
  628. if (machdep->verify_symbol(name, syminfo.value,
  629. syminfo.type)) {
  630. if (kt->flags & (RELOC_SET|RELOC_FORCE))
  631. sp->value = relocate(syminfo.value,
  632. (char *)syminfo.name, !(first++));
  633. else
  634. sp->value = syminfo.value;
  635. sp->type = syminfo.type;
  636. namespace_ctl(NAMESPACE_INSTALL, &st->kernel_namespace,
  637. sp, name);
  638. sp++;
  639. st->symcnt++;
  640. }
  641. }
  642. st->symend = &st->symtable[st->symcnt];
  643. st->flags |= KERNEL_SYMS;
  644. namespace_ctl(NAMESPACE_COMPLETE, &st->kernel_namespace,
  645. st->symtable, st->symend);
  646. }
  647. /*
  648. * Store the symbols from the designated System.map. The symbols are stored
  649. * in increasing numerical order.
  650. */
  651. static void
  652. store_sysmap_symbols(void)
  653. {
  654. int c, first;
  655. long symcount;
  656. char buf[BUFSIZE];
  657. char name[BUFSIZE];
  658. FILE *map;
  659. char *mapitems[MAXARGS];
  660. struct syment *sp, syment;
  661. if ((map = fopen(pc->system_map, "r")) == NULL)
  662. error(FATAL, "cannot open %s\n", pc->system_map);
  663. symcount = 0;
  664. while (fgets(buf, BUFSIZE, map))
  665. symcount++;
  666. if ((st->symtable = (struct syment *)
  667. calloc(symcount, sizeof(struct syment))) == NULL)
  668. error(FATAL, "symbol table syment space malloc: %s\n",
  669. strerror(errno));
  670. if (!namespace_ctl(NAMESPACE_INIT, &st->kernel_namespace,
  671. (void *)symcount, NULL))
  672. error(FATAL, "symbol table namespace malloc: %s\n",
  673. strerror(errno));
  674. if (!machine_type("X86") && !machine_type("X86_64"))
  675. kt->flags &= ~RELOC_SET;
  676. first = 0;
  677. st->syment_size = symcount * sizeof(struct syment);
  678. st->symcnt = 0;
  679. sp = st->symtable;
  680. rewind(map);
  681. while (fgets(buf, BUFSIZE, map)) {
  682. if ((c = parse_line(buf, mapitems)) != 3)
  683. continue;
  684. syment.value = htol(mapitems[0], FAULT_ON_ERROR, NULL);
  685. syment.type = mapitems[1][0];
  686. syment.name = mapitems[2];
  687. strcpy(name, syment.name);
  688. strip_symbol_end(name, NULL);
  689. if (machdep->verify_symbol(name, syment.value,
  690. syment.type)) {
  691. if (kt->flags & RELOC_SET)
  692. sp->value = relocate(syment.value,
  693. syment.name, !(first++));
  694. else
  695. sp->value = syment.value;
  696. sp->type = syment.type;
  697. namespace_ctl(NAMESPACE_INSTALL, &st->kernel_namespace,
  698. sp, name);
  699. sp++;
  700. st->symcnt++;
  701. }
  702. }
  703. fclose(map);
  704. st->symend = &st->symtable[st->symcnt];
  705. st->flags |= KERNEL_SYMS;
  706. namespace_ctl(NAMESPACE_COMPLETE, &st->kernel_namespace,
  707. st->symtable, st->symend);
  708. symname_hash_init();
  709. symval_hash_init();
  710. }
  711. /*
  712. * Handle x86 kernels configured such that the vmlinux symbols
  713. * are not as loaded into the kernel (not unity-mapped).
  714. */
  715. static ulong
  716. relocate(ulong symval, char *symname, int first_symbol)
  717. {
  718. if (XEN_HYPER_MODE()) {
  719. kt->flags &= ~(RELOC_SET|RELOC_FORCE);
  720. return symval;
  721. }
  722. switch (kt->flags & (RELOC_SET|RELOC_FORCE))
  723. {
  724. case RELOC_SET:
  725. break;
  726. case RELOC_FORCE:
  727. if (first_symbol && !relocate_force(symval, symname))
  728. kt->flags &= ~RELOC_FORCE;
  729. break;
  730. }
  731. if (machine_type("X86_64")) {
  732. /*
  733. * There are some symbols which are outside of any section
  734. * either because they are offsets or because they are absolute
  735. * addresses. These should not be relocated.
  736. */
  737. if (symval >= st->first_section_start &&
  738. symval <= st->last_section_end) {
  739. return symval - kt->relocate;
  740. } else {
  741. return symval;
  742. }
  743. } else
  744. return symval - kt->relocate;
  745. }
  746. /*
  747. * If no --reloc argument was passed, try to figure it out
  748. * by comparing the first vmlinux kernel symbol with the
  749. * first /proc/kallsyms symbol. (should be "_text")
  750. *
  751. * Live system only (at least for now).
  752. */
  753. static int
  754. relocate_force(ulong symval, char *symname)
  755. {
  756. int count, found;
  757. FILE *kp;
  758. char buf[BUFSIZE];
  759. char *kallsyms[MAXARGS];
  760. ulong kallsym;
  761. if (!ACTIVE() || !file_exists("/proc/kallsyms", NULL)) {
  762. if (CRASHDEBUG(1))
  763. fprintf(fp,
  764. "cannot determine relocation value: %s\n",
  765. !ACTIVE() ? "not a live system" :
  766. "/proc/kallsyms does not exist");
  767. return FALSE;
  768. }
  769. if ((kp = fopen("/proc/kallsyms", "r")) == NULL) {
  770. if (CRASHDEBUG(1))
  771. fprintf(fp,
  772. "cannot open /proc/kallsyms to determine relocation\n");
  773. return FALSE;
  774. }
  775. if (CRASHDEBUG(1))
  776. fprintf(fp,
  777. "relocate from: %s\n"
  778. " %s @ %lx\n"
  779. "relocate to: /proc/kallsyms\n",
  780. pc->namelist, symname, symval);
  781. found = FALSE;
  782. count = kallsym = 0;
  783. while (!found && fgets(buf, BUFSIZE, kp) &&
  784. (parse_line(buf, kallsyms) == 3) &&
  785. hexadecimal(kallsyms[0], 0)) {
  786. if (STREQ(kallsyms[2], symname)) {
  787. kallsym = htol(kallsyms[0], RETURN_ON_ERROR, NULL);
  788. found = TRUE;
  789. }
  790. count++;
  791. if (CRASHDEBUG(1))
  792. fprintf(fp,
  793. " %s @ %s %s\n",
  794. kallsyms[2], kallsyms[0],
  795. STREQ(kallsyms[2], symname) ?
  796. "(match!)" : "");
  797. }
  798. fclose(kp);
  799. /*
  800. * If the symbols match and have different values,
  801. * force the relocation.
  802. */
  803. if (found) {
  804. if (symval != kallsym) {
  805. kt->relocate = symval - kallsym;
  806. return TRUE;
  807. }
  808. }
  809. if (CRASHDEBUG(1))
  810. fprintf(fp,
  811. "cannot determine relocation value from"
  812. " %d symbols in /proc/kallsyms\n", count);
  813. return FALSE;
  814. }
  815. /*
  816. * Get a symbol value from /proc/kallsyms.
  817. */
  818. static ulong
  819. symbol_value_from_proc_kallsyms(char *symname)
  820. {
  821. FILE *kp;
  822. char buf[BUFSIZE];
  823. char *kallsyms[MAXARGS];
  824. ulong kallsym;
  825. int found;
  826. if (!file_exists("/proc/kallsyms", NULL)) {
  827. if (CRASHDEBUG(1))
  828. error(INFO, "cannot determine value of %s: "
  829. "/proc/kallsyms does not exist\n\n", symname);
  830. return BADVAL;
  831. }
  832. if ((kp = fopen("/proc/kallsyms", "r")) == NULL) {
  833. if (CRASHDEBUG(1))
  834. error(INFO, "cannot determine value of %s: "
  835. "cannot open /proc/kallsyms\n\n", symname);
  836. return BADVAL;
  837. }
  838. found = FALSE;
  839. while (!found && fgets(buf, BUFSIZE, kp) &&
  840. (parse_line(buf, kallsyms) == 3) &&
  841. hexadecimal(kallsyms[0], 0)) {
  842. if (STREQ(kallsyms[2], symname)) {
  843. kallsym = htol(kallsyms[0], RETURN_ON_ERROR, NULL);
  844. found = TRUE;
  845. break;
  846. }
  847. }
  848. fclose(kp);
  849. return(found ? kallsym : BADVAL);
  850. }
  851. /*
  852. * Install all static kernel symbol values into the symval_hash.
  853. */
  854. static void
  855. symval_hash_init(void)
  856. {
  857. int index;
  858. struct syment *sp, *sph;
  859. for (sp = st->symtable; sp < st->symend; sp++) {
  860. index = SYMVAL_HASH_INDEX(sp->value);
  861. if (st->symval_hash[index].val_hash_head == NULL) {
  862. st->symval_hash[index].val_hash_head = sp;
  863. st->symval_hash[index].val_hash_last = sp;
  864. continue;
  865. }
  866. sph = st->symval_hash[index].val_hash_head;
  867. while (sph->val_hash_next)
  868. sph = sph->val_hash_next;
  869. sph->val_hash_next = sp;
  870. }
  871. }
  872. /*
  873. * Static kernel symbol value search
  874. */
  875. static struct syment *
  876. symval_hash_search(ulong value)
  877. {
  878. int index;
  879. struct syment *sp, *splo;
  880. index = SYMVAL_HASH_INDEX(value);
  881. if (!st->symval_hash[index].val_hash_head)
  882. return NULL;
  883. st->val_hash_searches += 1;
  884. st->val_hash_iterations += 1;
  885. if (st->symval_hash[index].val_hash_last->value <= value)
  886. sp = st->symval_hash[index].val_hash_last;
  887. else
  888. sp = st->symval_hash[index].val_hash_head;
  889. for (splo = NULL; sp; sp = sp->val_hash_next) {
  890. if (sp->value == value) {
  891. st->symval_hash[index].val_hash_last = sp;
  892. return sp;
  893. }
  894. if (sp->value > value)
  895. break;
  896. st->val_hash_iterations += 1;
  897. splo = sp;
  898. }
  899. if (splo)
  900. st->symval_hash[index].val_hash_last = splo;
  901. return splo;
  902. }
  903. /*
  904. * Store all kernel static symbols into the symname_hash.
  905. */
  906. static void
  907. symname_hash_init(void)
  908. {
  909. struct syment *sp;
  910. for (sp = st->symtable; sp < st->symend; sp++)
  911. symname_hash_install(sp);
  912. if ((sp = symbol_search("__per_cpu_start")))
  913. st->__per_cpu_start = sp->value;
  914. if ((sp = symbol_search("__per_cpu_end")))
  915. st->__per_cpu_end = sp->value;
  916. }
  917. /*
  918. * Install a single static kernel symbol into the symname_hash.
  919. */
  920. static void
  921. symname_hash_install(struct syment *spn)
  922. {
  923. struct syment *sp;
  924. int index;
  925. index = SYMNAME_HASH_INDEX(spn->name);
  926. spn->cnt = 1;
  927. if ((sp = st->symname_hash[index]) == NULL)
  928. st->symname_hash[index] = spn;
  929. else {
  930. while (sp) {
  931. if (STREQ(sp->name, spn->name)) {
  932. sp->cnt++;
  933. spn->cnt++;
  934. }
  935. if (sp->name_hash_next)
  936. sp = sp->name_hash_next;
  937. else {
  938. sp->name_hash_next = spn;
  939. break;
  940. }
  941. }
  942. }
  943. }
  944. /*
  945. * Static kernel symbol value search
  946. */
  947. static struct syment *
  948. symname_hash_search(char *name)
  949. {
  950. struct syment *sp;
  951. sp = st->symname_hash[SYMNAME_HASH_INDEX(name)];
  952. while (sp) {
  953. if (STREQ(sp->name, name))
  954. return sp;
  955. sp = sp->name_hash_next;
  956. }
  957. return NULL;
  958. }
  959. /*
  960. * Output for sym -[lL] command.
  961. */
  962. #define MODULE_PSEUDO_SYMBOL(sp) \
  963. ((STRNEQ((sp)->name, "_MODULE_START_") || STRNEQ((sp)->name, "_MODULE_END_")) || \
  964. (STRNEQ((sp)->name, "_MODULE_INIT_START_") || STRNEQ((sp)->name, "_MODULE_INIT_END_")) || \
  965. (STRNEQ((sp)->name, "_MODULE_SECTION_")))
  966. #define MODULE_START(sp) (STRNEQ((sp)->name, "_MODULE_START_"))
  967. #define MODULE_END(sp) (STRNEQ((sp)->name, "_MODULE_END_"))
  968. #define MODULE_INIT_START(sp) (STRNEQ((sp)->name, "_MODULE_INIT_START_"))
  969. #define MODULE_INIT_END(sp) (STRNEQ((sp)->name, "_MODULE_INIT_END_"))
  970. #define MODULE_SECTION_START(sp) (STRNEQ((sp)->name, "_MODULE_SECTION_START"))
  971. #define MODULE_SECTION_END(sp) (STRNEQ((sp)->name, "_MODULE_SECTION_END"))
  972. static void
  973. symbol_dump(ulong flags, char *module)
  974. {
  975. int i, start, percpu_syms;
  976. struct syment *sp, *sp_end;
  977. struct load_module *lm;
  978. char *p1, *p2;;
  979. #define TBD 1
  980. #define DISPLAYED 2
  981. if (flags & KERNEL_SYMS) {
  982. for (sp = st->symtable; sp < st->symend; sp++) {
  983. show_symbol(sp, 0, SHOW_RADIX());
  984. if (received_SIGINT() || output_closed())
  985. return;
  986. }
  987. }
  988. if (!(flags & MODULE_SYMS))
  989. return;
  990. for (i = 0; i < st->mods_installed; i++) {
  991. lm = &st->load_modules[i];
  992. if (module && !STREQ(module, lm->mod_name))
  993. continue;
  994. if (received_SIGINT() || output_closed())
  995. return;
  996. sp = lm->mod_symtable;
  997. sp_end = lm->mod_symend;
  998. percpu_syms = 0;
  999. for (start = FALSE; sp <= sp_end; sp++) {
  1000. if (IN_MODULE_PERCPU(sp->value, lm)) {
  1001. if (percpu_syms == DISPLAYED)
  1002. continue;
  1003. if (!start) {
  1004. percpu_syms = TBD;
  1005. continue;
  1006. }
  1007. dump_percpu_symbols(lm);
  1008. percpu_syms = DISPLAYED;
  1009. }
  1010. if (MODULE_PSEUDO_SYMBOL(sp)) {
  1011. if (MODULE_SECTION_START(sp)) {
  1012. p1 = sp->name +
  1013. strlen("_MODULE_SECTION_START ");
  1014. p2 = "section start";
  1015. } else if (MODULE_SECTION_END(sp)) {
  1016. p1 = sp->name +
  1017. strlen("_MODULE_SECTION_END ");
  1018. p2 = "section end";
  1019. } else if (MODULE_START(sp)) {
  1020. p1 = "MODULE START";
  1021. p2 = sp->name+strlen("_MODULE_START_");
  1022. start = TRUE;
  1023. } else {
  1024. p1 = "MODULE END";
  1025. p2 = sp->name+strlen("_MODULE_END_");
  1026. if (MODULE_PERCPU_SYMS_LOADED(lm) &&
  1027. !percpu_syms) {
  1028. dump_percpu_symbols(lm);
  1029. percpu_syms = DISPLAYED;
  1030. }
  1031. }
  1032. fprintf(fp, "%lx %s: %s\n", sp->value, p1, p2);
  1033. if (percpu_syms == TBD) {
  1034. dump_percpu_symbols(lm);
  1035. percpu_syms = DISPLAYED;
  1036. }
  1037. } else
  1038. show_symbol(sp, 0, SHOW_RADIX());
  1039. }
  1040. if (lm->mod_init_symtable) {
  1041. sp = lm->mod_init_symtable;
  1042. sp_end = lm->mod_init_symend;
  1043. for ( ; sp <= sp_end; sp++) {
  1044. if (MODULE_PSEUDO_SYMBOL(sp)) {
  1045. if (MODULE_INIT_START(sp)) {
  1046. p1 = "MODULE INIT START";
  1047. p2 = sp->name+strlen("_MODULE_INIT_START_");
  1048. } else {
  1049. p1 = "MODULE INIT END";
  1050. p2 = sp->name+strlen("_MODULE_INIT_END_");
  1051. }
  1052. fprintf(fp, "%lx %s: %s\n", sp->value, p1, p2);
  1053. } else
  1054. show_symbol(sp, 0, SHOW_RADIX());
  1055. }
  1056. }
  1057. }
  1058. #undef TBD
  1059. #undef DISPLAYED
  1060. }
  1061. static void
  1062. dump_percpu_symbols(struct load_module *lm)
  1063. {
  1064. struct syment *sp, *sp_end;
  1065. if (MODULE_PERCPU_SYMS_LOADED(lm)) {
  1066. sp = lm->mod_symtable;
  1067. sp_end = lm->mod_symend;
  1068. for ( ; sp <= sp_end; sp++) {
  1069. if (IN_MODULE_PERCPU(sp->value, lm))
  1070. show_symbol(sp, 0, SHOW_RADIX());
  1071. }
  1072. }
  1073. }
  1074. /*
  1075. * Get a pointer to the desired asection.
  1076. */
  1077. static asection *
  1078. get_kernel_section(char *name)
  1079. {
  1080. int i;
  1081. asection **sec;
  1082. sec = (asection **)st->sections;
  1083. for (i = 0; i < st->bfd->section_count; i++, sec++) {
  1084. if (STREQ(name, (*sec)->name))
  1085. return(*sec);
  1086. }
  1087. return NULL;
  1088. }
  1089. /*
  1090. * Walk through the current set of symbols and check for duplicates.
  1091. */
  1092. static void
  1093. check_for_dups(struct load_module *lm)
  1094. {
  1095. struct syment *sp, *sp_end;
  1096. sp = lm->mod_symtable;
  1097. sp_end = lm->mod_symend;
  1098. for ( ; sp <= sp_end; sp++) {
  1099. if (symbol_name_count(sp->name) > 1)
  1100. error(NOTE, "%s: duplicate symbol name: %s\n",
  1101. lm->mod_name, sp->name);
  1102. }
  1103. }
  1104. /*
  1105. * Store the externally declared symbols for all modules in the system.
  1106. * allowing for dynamic loading of symbols from individual mod object files
  1107. * during runtime.
  1108. */
  1109. struct module_symbol {
  1110. unsigned long value;
  1111. const char *name;
  1112. };
  1113. void
  1114. store_module_symbols_v1(ulong total, int mods_installed)
  1115. {
  1116. int i, m;
  1117. ulong mod, mod_next, mod_name;
  1118. uint nsyms;
  1119. ulong syms, size_of_struct;
  1120. long strbuflen, size;
  1121. int mcnt, lm_mcnt;
  1122. struct module_symbol *modsym;
  1123. struct load_module *lm;
  1124. char buf1[BUFSIZE];
  1125. char buf2[BUFSIZE];
  1126. char name[BUFSIZE];
  1127. char rodata[BUFSIZE];
  1128. char *strbuf, *modbuf, *modsymbuf;
  1129. struct syment *sp;
  1130. ulong first, last;
  1131. st->mods_installed = mods_installed;
  1132. if (!st->mods_installed) {
  1133. st->flags &= ~MODULE_SYMS;
  1134. return;
  1135. }
  1136. /*
  1137. * If we've been here before, free up everything and start over.
  1138. */
  1139. if (st->flags & MODULE_SYMS) {
  1140. error(FATAL,
  1141. "re-initialization of module symbols not implemented yet!\n");
  1142. }
  1143. if ((st->ext_module_symtable = (struct syment *)
  1144. calloc(total, sizeof(struct syment))) == NULL)
  1145. error(FATAL, "module syment space malloc: %s\n",
  1146. strerror(errno));
  1147. if (!namespace_ctl(NAMESPACE_INIT, &st->ext_module_namespace,
  1148. (void *)total, NULL))
  1149. error(FATAL, "module namespace malloc: %s\n",
  1150. strerror(errno));
  1151. if ((st->load_modules = (struct load_module *)calloc
  1152. (st->mods_installed, sizeof(struct load_module))) == NULL)
  1153. error(FATAL, "load_module array malloc: %s\n", strerror(errno));
  1154. modbuf = GETBUF(SIZE(module));
  1155. modsymbuf = NULL;
  1156. m = mcnt = mod_next = 0;
  1157. for (mod = kt->module_list; mod != kt->kernel_module; mod = mod_next) {
  1158. readmem(mod, KVADDR, modbuf, SIZE(module),
  1159. "module buffer", FAULT_ON_ERROR);
  1160. nsyms = UINT(modbuf + OFFSET(module_nsyms));
  1161. syms = ULONG(modbuf + OFFSET(module_syms));
  1162. size = LONG(modbuf + OFFSET(module_size));
  1163. mod_name = ULONG(modbuf + OFFSET(module_name));
  1164. size_of_struct = ULONG(modbuf +
  1165. OFFSET(module_size_of_struct));
  1166. if (!read_string(mod_name, name, BUFSIZE-1))
  1167. sprintf(name, "(unknown module)");
  1168. sprintf(rodata, "__insmod_%s_S.rodata", name);
  1169. lm = &st->load_modules[m++];
  1170. BZERO(lm, sizeof(struct load_module));
  1171. lm->mod_base = lm->module_struct = mod;
  1172. lm->mod_size = size;
  1173. lm->mod_size_of_struct = size_of_struct;
  1174. if (strlen(name) < MAX_MOD_NAME)
  1175. strcpy(lm->mod_name, name);
  1176. else {
  1177. error(INFO,
  1178. "module name greater than MAX_MOD_NAME: %s\n",
  1179. name);
  1180. strncpy(lm->mod_name, name, MAX_MOD_NAME-1);
  1181. }
  1182. lm->mod_flags = MOD_EXT_SYMS;
  1183. lm->mod_ext_symcnt = mcnt;
  1184. lm->mod_etext_guess = 0;
  1185. st->ext_module_symtable[mcnt].value = mod;
  1186. st->ext_module_symtable[mcnt].type = 'm';
  1187. st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
  1188. sprintf(buf2, "%s%s", "_MODULE_START_", name);
  1189. namespace_ctl(NAMESPACE_INSTALL, &st->ext_module_namespace,
  1190. &st->ext_module_symtable[mcnt], buf2);
  1191. lm_mcnt = mcnt;
  1192. mcnt++;
  1193. if (nsyms) {
  1194. modsymbuf = GETBUF(sizeof(struct module_symbol)*nsyms);
  1195. readmem((ulong)syms, KVADDR, modsymbuf,
  1196. nsyms * sizeof(struct module_symbol),
  1197. "module symbols", FAULT_ON_ERROR);
  1198. }
  1199. for (i = first = last = 0; i < nsyms; i++) {
  1200. modsym = (struct module_symbol *)
  1201. (modsymbuf + (i * sizeof(struct module_symbol)));
  1202. if (!first)
  1203. first = (ulong)modsym->name;
  1204. last = (ulong)modsym->name;
  1205. }
  1206. if (last > first) {
  1207. strbuflen = (last-first) + BUFSIZE;
  1208. if ((first + strbuflen) >=
  1209. (lm->mod_base + lm->mod_size)) {
  1210. strbuflen = (lm->mod_base + lm->mod_size) -
  1211. first;
  1212. }
  1213. strbuf = GETBUF(strbuflen);
  1214. if (!readmem(first, KVADDR, strbuf, strbuflen,
  1215. "module symbol strings", RETURN_ON_ERROR)) {
  1216. FREEBUF(strbuf);
  1217. strbuf = NULL;
  1218. }
  1219. } else
  1220. strbuf = NULL;
  1221. for (i = first = last = 0; i < nsyms; i++) {
  1222. modsym = (struct module_symbol *)
  1223. (modsymbuf + (i * sizeof(struct module_symbol)));
  1224. if (!first)
  1225. first = (ulong)modsym->name;
  1226. last = (ulong)modsym->name;
  1227. BZERO(buf1, BUFSIZE);
  1228. if (strbuf)
  1229. strcpy(buf1,
  1230. &strbuf[(ulong)modsym->name - first]);
  1231. else
  1232. read_string((ulong)modsym->name, buf1,
  1233. BUFSIZE-1);
  1234. if (strlen(buf1)) {
  1235. st->ext_module_symtable[mcnt].value =
  1236. modsym->value;
  1237. st->ext_module_symtable[mcnt].type = '?';
  1238. st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
  1239. strip_module_symbol_end(buf1);
  1240. strip_symbol_end(buf1, NULL);
  1241. namespace_ctl(NAMESPACE_INSTALL,
  1242. &st->ext_module_namespace,
  1243. &st->ext_module_symtable[mcnt], buf1);
  1244. if (strstr(buf1, rodata))
  1245. lm->mod_etext_guess = modsym->value;
  1246. sprintf(buf2, "__insmod_%s_O/", lm->mod_name);
  1247. if (strstr(buf1, buf2) &&
  1248. !strstr(buf1, "modules"))
  1249. lm->mod_flags |= MOD_INITRD;
  1250. mcnt++;
  1251. }
  1252. }
  1253. if (modsymbuf) {
  1254. FREEBUF(modsymbuf);
  1255. modsymbuf = NULL;
  1256. }
  1257. if (strbuf)
  1258. FREEBUF(strbuf);
  1259. /*
  1260. * If the module was compiled with kallsyms, add them in.
  1261. */
  1262. switch (kt->flags & (KALLSYMS_V1|KALLSYMS_V2))
  1263. {
  1264. case KALLSYMS_V1:
  1265. mcnt += store_module_kallsyms_v1(lm, lm_mcnt,
  1266. mcnt, modbuf);
  1267. break;
  1268. case KALLSYMS_V2: /* impossible, I hope... */
  1269. mcnt += store_module_kallsyms_v2(lm, lm_mcnt,
  1270. mcnt, modbuf);
  1271. break;
  1272. }
  1273. st->ext_module_symtable[mcnt].value = mod + size;
  1274. st->ext_module_symtable[mcnt].type = 'm';
  1275. st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
  1276. sprintf(buf2, "%s%s", "_MODULE_END_", name);
  1277. namespace_ctl(NAMESPACE_INSTALL,
  1278. &st->ext_module_namespace,
  1279. &st->ext_module_symtable[mcnt], buf2);
  1280. mcnt++;
  1281. lm->mod_ext_symcnt = mcnt - lm->mod_ext_symcnt;
  1282. if (!lm->mod_etext_guess)
  1283. find_mod_etext(lm);
  1284. NEXT_MODULE(mod_next, modbuf);
  1285. }
  1286. FREEBUF(modbuf);
  1287. st->ext_module_symcnt = mcnt;
  1288. st->ext_module_symend = &st->ext_module_symtable[mcnt];
  1289. namespace_ctl(NAMESPACE_COMPLETE, &st->ext_module_namespace,
  1290. st->ext_module_symtable, st->ext_module_symend);
  1291. qsort(st->ext_module_symtable, mcnt, sizeof(struct syment),
  1292. compare_syms);
  1293. qsort(st->load_modules, m, sizeof(struct load_module), compare_mods);
  1294. for (m = 0; m < st->mods_installed; m++) {
  1295. lm = &st->load_modules[m];
  1296. sprintf(buf1, "_MODULE_START_%s", lm->mod_name);
  1297. sprintf(buf2, "_MODULE_END_%s", lm->mod_name);
  1298. for (sp = st->ext_module_symtable;
  1299. sp < st->ext_module_symend; sp++) {
  1300. if (STREQ(sp->name, buf1)) {
  1301. lm->mod_ext_symtable = sp;
  1302. lm->mod_symtable = sp;
  1303. }
  1304. if (STREQ(sp->name, buf2)) {
  1305. lm->mod_ext_symend = sp;
  1306. lm->mod_symend = sp;
  1307. }
  1308. }
  1309. }
  1310. st->flags |= MODULE_SYMS;
  1311. if (symbol_query("__insmod_", NULL, NULL))
  1312. st->flags |= INSMOD_BUILTIN;
  1313. }
  1314. struct kernel_symbol
  1315. {
  1316. unsigned long value;
  1317. const char *name;
  1318. };
  1319. void
  1320. store_module_symbols_v2(ulong total, int mods_installed)
  1321. {
  1322. int i, m;
  1323. ulong mod, mod_next;
  1324. char *mod_name;
  1325. uint nsyms, ngplsyms;
  1326. ulong syms, gpl_syms;
  1327. ulong nksyms;
  1328. long strbuflen;
  1329. ulong size;
  1330. int mcnt, lm_mcnt;
  1331. struct kernel_symbol *modsym;
  1332. struct load_module *lm;
  1333. char buf1[BUFSIZE];
  1334. char buf2[BUFSIZE];
  1335. char buf3[BUFSIZE];
  1336. char buf4[BUFSIZE];
  1337. char *strbuf, *modbuf, *modsymbuf;
  1338. struct syment *sp;
  1339. ulong first, last;
  1340. st->mods_installed = mods_installed;
  1341. if (!st->mods_installed) {
  1342. st->flags &= ~MODULE_SYMS;
  1343. return;
  1344. }
  1345. /*
  1346. * If we've been here before, free up everything and start over.
  1347. */
  1348. if (st->flags & MODULE_SYMS) {
  1349. error(FATAL,
  1350. "re-initialization of module symbols not implemented yet!\n");
  1351. }
  1352. if ((st->ext_module_symtable = (struct syment *)
  1353. calloc(total, sizeof(struct syment))) == NULL)
  1354. error(FATAL, "v2 module syment space malloc (%ld symbols): %s\n",
  1355. total, strerror(errno));
  1356. if (!namespace_ctl(NAMESPACE_INIT, &st->ext_module_namespace,
  1357. (void *)total, NULL))
  1358. error(FATAL, "module namespace malloc: %s\n",
  1359. strerror(errno));
  1360. if ((st->load_modules = (struct load_module *)calloc
  1361. (st->mods_installed, sizeof(struct load_module))) == NULL)
  1362. error(FATAL, "load_module array malloc: %s\n", strerror(errno));
  1363. modbuf = GETBUF(SIZE(module));
  1364. modsymbuf = NULL;
  1365. m = mcnt = mod_next = 0;
  1366. for (mod = kt->module_list; mod != kt->kernel_module; mod = mod_next) {
  1367. readmem(mod, KVADDR, modbuf, SIZE(module),
  1368. "module buffer", FAULT_ON_ERROR);
  1369. syms = ULONG(modbuf + OFFSET(module_syms));
  1370. gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
  1371. nsyms = UINT(modbuf + OFFSET(module_num_syms));
  1372. ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
  1373. if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) {
  1374. nksyms = UINT(modbuf + OFFSET(module_num_symtab));
  1375. size = UINT(modbuf + OFFSET(module_core_size));
  1376. } else {
  1377. nksyms = ULONG(modbuf + OFFSET(module_num_symtab));
  1378. size = ULONG(modbuf + OFFSET(module_core_size));
  1379. }
  1380. mod_name = modbuf + OFFSET(module_name);
  1381. lm = &st->load_modules[m++];
  1382. BZERO(lm, sizeof(struct load_module));
  1383. lm->mod_base = ULONG(modbuf + OFFSET(module_module_core));
  1384. lm->module_struct = mod;
  1385. lm->mod_size = size;
  1386. if (strlen(mod_name) < MAX_MOD_NAME)
  1387. strcpy(lm->mod_name, mod_name);
  1388. else {
  1389. error(INFO,
  1390. "module name greater than MAX_MOD_NAME: %s\n",
  1391. mod_name);
  1392. strncpy(lm->mod_name, mod_name, MAX_MOD_NAME-1);
  1393. }
  1394. if (CRASHDEBUG(3))
  1395. fprintf(fp,
  1396. "%lx (%lx): %s syms: %d gplsyms: %d ksyms: %ld\n",
  1397. mod, lm->mod_base, lm->mod_name, nsyms,
  1398. ngplsyms, nksyms);
  1399. lm->mod_flags = MOD_EXT_SYMS;
  1400. lm->mod_ext_symcnt = mcnt;
  1401. lm->mod_init_module_ptr = ULONG(modbuf +
  1402. OFFSET(module_module_init));
  1403. if (VALID_MEMBER(module_percpu))
  1404. lm->mod_percpu = ULONG(modbuf + OFFSET(module_percpu));
  1405. if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) {
  1406. lm->mod_etext_guess = lm->mod_base +
  1407. UINT(modbuf + OFFSET(module_core_text_size));
  1408. lm->mod_init_size =
  1409. UINT(modbuf + OFFSET(module_init_size));
  1410. lm->mod_init_text_size =
  1411. UINT(modbuf + OFFSET(module_init_text_size));
  1412. } else {
  1413. lm->mod_etext_guess = lm->mod_base +
  1414. ULONG(modbuf + OFFSET(module_core_text_size));
  1415. lm->mod_init_size =
  1416. ULONG(modbuf + OFFSET(module_init_size));
  1417. lm->mod_init_text_size =
  1418. ULONG(modbuf + OFFSET(module_init_text_size));
  1419. }
  1420. lm->mod_text_start = lm->mod_base;
  1421. st->ext_module_symtable[mcnt].value = lm->mod_base;
  1422. st->ext_module_symtable[mcnt].type = 'm';
  1423. st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
  1424. sprintf(buf2, "%s%s", "_MODULE_START_", mod_name);
  1425. namespace_ctl(NAMESPACE_INSTALL, &st->ext_module_namespace,
  1426. &st->ext_module_symtable[mcnt], buf2);
  1427. lm_mcnt = mcnt;
  1428. mcnt++;
  1429. if (lm->mod_init_size > 0) {
  1430. st->ext_module_symtable[mcnt].value = lm->mod_init_module_ptr;
  1431. st->ext_module_symtable[mcnt].type = 'm';
  1432. st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
  1433. sprintf(buf3, "%s%s", "_MODULE_INIT_START_", mod_name);
  1434. namespace_ctl(NAMESPACE_INSTALL,
  1435. &st->ext_module_namespace,
  1436. &st->ext_module_symtable[mcnt], buf3);
  1437. lm_mcnt = mcnt;
  1438. mcnt++;
  1439. lm->mod_flags |= MOD_INIT;
  1440. }
  1441. if (nsyms && !IN_MODULE(syms, lm)) {
  1442. error(WARNING,
  1443. "[%s] module.syms outside of module "
  1444. "address space (%lx)\n\n",
  1445. lm->mod_name, syms);
  1446. nsyms = 0;
  1447. }
  1448. if (nsyms) {
  1449. modsymbuf = GETBUF(sizeof(struct kernel_symbol)*nsyms);
  1450. readmem((ulong)syms, KVADDR, modsymbuf,
  1451. nsyms * sizeof(struct kernel_symbol),
  1452. "module symbols", FAULT_ON_ERROR);
  1453. }
  1454. for (i = first = last = 0; i < nsyms; i++) {
  1455. modsym = (struct kernel_symbol *)
  1456. (modsymbuf + (i * sizeof(struct kernel_symbol)));
  1457. if (!first)
  1458. first = (ulong)modsym->name;
  1459. last = (ulong)modsym->name;
  1460. }
  1461. if (last > first) {
  1462. strbuflen = (last-first) + BUFSIZE;
  1463. if ((first + strbuflen) >=
  1464. (lm->mod_base + lm->mod_size)) {
  1465. strbuflen = (lm->mod_base + lm->mod_size) -
  1466. first;
  1467. }
  1468. strbuf = GETBUF(strbuflen);
  1469. if (!readmem(first, KVADDR, strbuf, strbuflen,
  1470. "module symbol strings", RETURN_ON_ERROR)) {
  1471. FREEBUF(strbuf);
  1472. strbuf = NULL;
  1473. }
  1474. } else
  1475. strbuf = NULL;
  1476. for (i = first = last = 0; i < nsyms; i++) {
  1477. modsym = (struct kernel_symbol *)
  1478. (modsymbuf + (i * sizeof(struct kernel_symbol)));
  1479. if (!first)
  1480. first = (ulong)modsym->name;
  1481. last = (ulong)modsym->name;
  1482. BZERO(buf1, BUFSIZE);
  1483. if (strbuf)
  1484. strcpy(buf1,
  1485. &strbuf[(ulong)modsym->name - first]);
  1486. else
  1487. read_string((ulong)modsym->name, buf1,
  1488. BUFSIZE-1);
  1489. if (strlen(buf1)) {
  1490. st->ext_module_symtable[mcnt].value =
  1491. modsym->value;
  1492. st->ext_module_symtable[mcnt].type = '?';
  1493. st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
  1494. strip_module_symbol_end(buf1);
  1495. strip_symbol_end(buf1, NULL);
  1496. namespace_ctl(NAMESPACE_INSTALL,
  1497. &st->ext_module_namespace,
  1498. &st->ext_module_symtable[mcnt], buf1);
  1499. mcnt++;
  1500. }
  1501. }
  1502. if (modsymbuf) {
  1503. FREEBUF(modsymbuf);
  1504. modsymbuf = NULL;
  1505. }
  1506. if (strbuf)
  1507. FREEBUF(strbuf);
  1508. if (ngplsyms) {
  1509. modsymbuf = GETBUF(sizeof(struct kernel_symbol) *
  1510. ngplsyms);
  1511. readmem((ulong)gpl_syms, KVADDR, modsymbuf,
  1512. ngplsyms * sizeof(struct kernel_symbol),
  1513. "module gpl symbols", FAULT_ON_ERROR);
  1514. }
  1515. for (i = first = last = 0; i < ngplsyms; i++) {
  1516. modsym = (struct kernel_symbol *)
  1517. (modsymbuf + (i * sizeof(struct kernel_symbol)));
  1518. if (!first)
  1519. first = (ulong)modsym->name;
  1520. last = (ulong)modsym->name;
  1521. }
  1522. if (last > first) {
  1523. strbuflen = (last-first) + BUFSIZE;
  1524. if ((first + strbuflen) >=
  1525. (lm->mod_base + lm->mod_size)) {
  1526. strbuflen = (lm->mod_base + lm->mod_size) -
  1527. first;
  1528. }
  1529. strbuf = GETBUF(strbuflen);
  1530. if (!readmem(first, KVADDR, strbuf, strbuflen,
  1531. "module gpl symbol strings", RETURN_ON_ERROR)) {
  1532. FREEBUF(strbuf);
  1533. strbuf = NULL;
  1534. }
  1535. } else
  1536. strbuf = NULL;
  1537. for (i = first = last = 0; i < ngplsyms; i++) {
  1538. modsym = (struct kernel_symbol *)
  1539. (modsymbuf + (i * sizeof(struct kernel_symbol)));
  1540. if (!first)
  1541. first = (ulong)modsym->name;
  1542. last = (ulong)modsym->name;
  1543. BZERO(buf1, BUFSIZE);
  1544. if (strbuf)
  1545. strcpy(buf1,
  1546. &strbuf[(ulong)modsym->name - first]);
  1547. else
  1548. read_string((ulong)modsym->name, buf1,
  1549. BUFSIZE-1);
  1550. if (strlen(buf1)) {
  1551. st->ext_module_symtable[mcnt].value =
  1552. modsym->value;
  1553. st->ext_module_symtable[mcnt].type = '?';
  1554. st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
  1555. strip_module_symbol_end(buf1);
  1556. strip_symbol_end(buf1, NULL);
  1557. namespace_ctl(NAMESPACE_INSTALL,
  1558. &st->ext_module_namespace,
  1559. &st->ext_module_symtable[mcnt], buf1);
  1560. mcnt++;
  1561. }
  1562. }
  1563. if (modsymbuf) {
  1564. FREEBUF(modsymbuf);
  1565. modsymbuf = NULL;
  1566. }
  1567. if (strbuf)
  1568. FREEBUF(strbuf);
  1569. /*
  1570. * If the module was compiled with kallsyms, add them in.
  1571. */
  1572. switch (kt->flags & (KALLSYMS_V1|KALLSYMS_V2))
  1573. {
  1574. case KALLSYMS_V1: /* impossible, I hope... */
  1575. mcnt += store_module_kallsyms_v1(lm, lm_mcnt,
  1576. mcnt, modbuf);
  1577. break;
  1578. case KALLSYMS_V2:
  1579. mcnt += store_module_kallsyms_v2(lm, lm_mcnt,
  1580. mcnt, modbuf);
  1581. break;
  1582. }
  1583. st->ext_module_symtable[mcnt].value = lm->mod_base + size;
  1584. st->ext_module_symtable[mcnt].type = 'm';
  1585. st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
  1586. sprintf(buf2, "%s%s", "_MODULE_END_", mod_name);
  1587. namespace_ctl(NAMESPACE_INSTALL,
  1588. &st->ext_module_namespace,
  1589. &st->ext_module_symtable[mcnt], buf2);
  1590. mcnt++;
  1591. if (lm->mod_init_size > 0) {
  1592. st->ext_module_symtable[mcnt].value = lm->mod_init_module_ptr + lm->mod_init_size;
  1593. st->ext_module_symtable[mcnt].type = 'm';
  1594. st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
  1595. sprintf(buf4, "%s%s", "_MODULE_INIT_END_", mod_name);
  1596. namespace_ctl(NAMESPACE_INSTALL,
  1597. &st->ext_module_namespace,
  1598. &st->ext_module_symtable[mcnt], buf4);
  1599. mcnt++;
  1600. }
  1601. lm->mod_ext_symcnt = mcnt - lm->mod_ext_symcnt;
  1602. if (!lm->mod_etext_guess)
  1603. find_mod_etext(lm);
  1604. NEXT_MODULE(mod_next, modbuf);
  1605. }
  1606. FREEBUF(modbuf);
  1607. st->ext_module_symcnt = mcnt;
  1608. st->ext_module_symend = &st->ext_module_symtable[mcnt];
  1609. namespace_ctl(NAMESPACE_COMPLETE, &st->ext_module_namespace,
  1610. st->ext_module_symtable, st->ext_module_symend);
  1611. qsort(st->ext_module_symtable, mcnt, sizeof(struct syment),
  1612. compare_syms);
  1613. qsort(st->load_modules, m, sizeof(struct load_module), compare_mods);
  1614. for (m = 0; m < st->mods_installed; m++) {
  1615. lm = &st->load_modules[m];
  1616. sprintf(buf1, "_MODULE_START_%s", lm->mod_name);
  1617. sprintf(buf2, "_MODULE_END_%s", lm->mod_name);
  1618. sprintf(buf3, "_MODULE_INIT_START_%s", lm->mod_name);
  1619. sprintf(buf4, "_MODULE_INIT_END_%s", lm->mod_name);
  1620. for (sp = st->ext_module_symtable;
  1621. sp < st->ext_module_symend; sp++) {
  1622. if (STREQ(sp->name, buf1)) {
  1623. lm->mod_ext_symtable = sp;
  1624. lm->mod_symtable = sp;
  1625. }
  1626. if (STREQ(sp->name, buf2)) {
  1627. lm->mod_ext_symend = sp;
  1628. lm->mod_symend = sp;
  1629. }
  1630. if (STREQ(sp->name, buf3)) {
  1631. lm->mod_init_symtable = sp;
  1632. }
  1633. if (STREQ(sp->name, buf4)) {
  1634. lm->mod_init_symend = sp;
  1635. }
  1636. }
  1637. }
  1638. st->flags |= MODULE_SYMS;
  1639. if (symbol_query("__insmod_", NULL, NULL))
  1640. st->flags |= INSMOD_BUILTIN;
  1641. if (mcnt > total)
  1642. error(FATAL, "store_module_symbols_v2: total: %ld mcnt: %d\n",
  1643. total, mcnt);
  1644. }
  1645. /*
  1646. * Get the module's kallsyms list if it was compiled in.
  1647. */
  1648. static int
  1649. store_module_kallsyms_v1(struct load_module *lm, int start, int curr,
  1650. char *modbuf)
  1651. {
  1652. int i, j;
  1653. struct syment *sp;
  1654. ulong kallsyms_header;
  1655. char *module_buf;
  1656. char *header_buf;
  1657. uint symbols;
  1658. ulong name_off;
  1659. ulong sec_name_off;
  1660. ulong section_off;
  1661. ulong symptr;
  1662. ulong symbol_addr;
  1663. ulong stringptr;
  1664. ulong sectionptr;
  1665. char *nameptr;
  1666. char *secnameptr;
  1667. ulong secptr;
  1668. char type;
  1669. int mcnt;
  1670. int mcnt_idx;
  1671. int found;
  1672. struct symbol_namespace *ns;
  1673. if (!(kt->flags & KALLSYMS_V1))
  1674. return 0;
  1675. kallsyms_header = ULONG(modbuf + OFFSET(module_kallsyms_start));
  1676. if (!kallsyms_header)
  1677. return 0;
  1678. mcnt = 0;
  1679. mcnt_idx = curr;
  1680. module_buf = GETBUF(ULONG(modbuf + OFFSET(module_size)));
  1681. ns = &st->ext_module_namespace;
  1682. if (!readmem(lm->mod_base, KVADDR, module_buf, lm->mod_size,
  1683. "module (kallsyms)", RETURN_ON_ERROR|QUIET)) {
  1684. error(WARNING,"cannot access module kallsyms\n");
  1685. FREEBUF(module_buf);
  1686. return 0;
  1687. }
  1688. #define IN_MODULE_BUF_V1(x) \
  1689. (((x) >= module_buf) && ((x) < (module_buf + lm->mod_size)))
  1690. header_buf = module_buf + (kallsyms_header - lm->mod_base);
  1691. symbols = UINT(header_buf + OFFSET(kallsyms_header_symbols));
  1692. // sections = UINT(header_buf + OFFSET(kallsyms_header_sections));
  1693. if (CRASHDEBUG(7))
  1694. fprintf(fp, "kallsyms: module: %s\n", lm->mod_name);
  1695. symptr = (ulong)(header_buf +
  1696. ULONG(header_buf + OFFSET(kallsyms_header_symbol_off)));
  1697. stringptr = (ulong)(header_buf +
  1698. ULONG(header_buf + OFFSET(kallsyms_header_string_off)));
  1699. sectionptr = (ulong)(header_buf +
  1700. ULONG(header_buf + OFFSET(kallsyms_header_section_off)));
  1701. for (i = 0; i < symbols; i++, symptr += SIZE(kallsyms_symbol)) {
  1702. symbol_addr = ULONG(symptr+OFFSET(kallsyms_symbol_symbol_addr));
  1703. name_off = ULONG(symptr+OFFSET(kallsyms_symbol_name_off));
  1704. section_off = ULONG(symptr+OFFSET(kallsyms_symbol_section_off));
  1705. nameptr = (char *)(stringptr + name_off);
  1706. secptr = (ulong)(sectionptr + section_off);
  1707. sec_name_off = ULONG(secptr+OFFSET(kallsyms_section_name_off));
  1708. secnameptr = (char *)(stringptr + sec_name_off);
  1709. if (!IN_MODULE_BUF_V1(nameptr)) {
  1710. if (CRASHDEBUG(7))
  1711. error(INFO,
  1712. "%s: invalid nameptr: %lx (stringptr: %lx + name_off: %lx)\n",
  1713. lm->mod_name, nameptr,
  1714. stringptr, name_off);
  1715. continue;
  1716. }
  1717. if (!IN_MODULE_BUF_V1(secnameptr)) {
  1718. if (CRASHDEBUG(7))
  1719. error(INFO,
  1720. "%s: invalid secnameptr: %lx (stringptr: %lx + sec_name_off: %lx)\n",
  1721. lm->mod_name, secnameptr,
  1722. stringptr, sec_name_off);
  1723. continue;
  1724. }
  1725. if (!STREQ(nameptr, secnameptr)) {
  1726. if (STREQ(secnameptr, ".text"))
  1727. type = 't';
  1728. else if (STREQ(secnameptr, ".data"))
  1729. type = 'd';
  1730. else if (STREQ(secnameptr, ".bss"))
  1731. type = 'b';
  1732. else if (STREQ(secnameptr, ".rodata"))
  1733. type = 'd';
  1734. else
  1735. continue;
  1736. strip_module_symbol_end(nameptr);
  1737. strip_symbol_end(nameptr, NULL);
  1738. if (CRASHDEBUG(7))
  1739. fprintf(fp," symbol: %lx \"%s\" section: %s\n",
  1740. symbol_addr, nameptr, secnameptr);
  1741. for (found = 0, j = start; j < curr; j++) {
  1742. sp = &st->ext_module_symtable[j];
  1743. if ((sp->value == symbol_addr) &&
  1744. STREQ(nameptr,
  1745. &ns->address[(ulong)sp->name])) {
  1746. if (CRASHDEBUG(7))
  1747. fprintf(fp,
  1748. "current symbol \"%s\" at %lx of type (%c)\n",
  1749. &ns->address[(ulong)sp->name],
  1750. sp->value, sp->type);
  1751. if (sp->type == '?')
  1752. sp->type = type;
  1753. found++;
  1754. break;
  1755. }
  1756. }
  1757. if (found)
  1758. continue;
  1759. st->ext_module_symtable[mcnt_idx].value = symbol_addr;
  1760. st->ext_module_symtable[mcnt_idx].type = type;
  1761. st->ext_module_symtable[mcnt_idx].flags |= MODULE_SYMBOL;
  1762. namespace_ctl(NAMESPACE_INSTALL,
  1763. &st->ext_module_namespace,
  1764. &st->ext_module_symtable[mcnt_idx++], nameptr);
  1765. mcnt++;
  1766. }
  1767. }
  1768. lm->mod_flags |= MOD_KALLSYMS;
  1769. FREEBUF(module_buf);
  1770. return mcnt;
  1771. }
  1772. /*
  1773. * Translate either an Elf32_Sym or Elf64_Sym to an elf_common structure
  1774. * for more convenient use by store_module_kallsyms_v2().
  1775. */
  1776. struct elf_common {
  1777. ulong st_name;
  1778. ulong st_value;
  1779. ulong st_shndx;
  1780. unsigned char st_info;
  1781. };
  1782. static void Elf32_Sym_to_common(Elf32_Sym *e32, struct elf_common *ec)
  1783. {
  1784. ec->st_name = (ulong)e32->st_name;
  1785. ec->st_value = (ulong)e32->st_value;
  1786. ec->st_shndx = (ulong)e32->st_shndx;
  1787. ec->st_info = e32->st_info;
  1788. }
  1789. static void Elf64_Sym_to_common(Elf64_Sym *e64, struct elf_common *ec)
  1790. {
  1791. ec->st_name = (ulong)e64->st_name;
  1792. ec->st_value = (ulong)e64->st_value;
  1793. ec->st_shndx = (ulong)e64->st_shndx;
  1794. ec->st_info = e64->st_info;
  1795. }
  1796. static int
  1797. store_module_kallsyms_v2(struct load_module *lm, int start, int curr,
  1798. char *modbuf)
  1799. {
  1800. int i, j, found;
  1801. struct elf_common elf_common, *ec;
  1802. ulong nksyms, ksymtab, kstrtab;
  1803. char *module_buf, *ptr, *locsymtab, *locstrtab, *nameptr;
  1804. struct syment *sp;
  1805. struct symbol_namespace *ns;
  1806. int mcnt;
  1807. int mcnt_idx;
  1808. char *module_buf_init = NULL;
  1809. if (!(kt->flags & KALLSYMS_V2))
  1810. return 0;
  1811. mcnt = 0;
  1812. BZERO(&elf_common, sizeof(struct elf_common));
  1813. mcnt_idx = curr;
  1814. ns = &st->ext_module_namespace;
  1815. ec = &elf_common;
  1816. module_buf = GETBUF(lm->mod_size);
  1817. if (!readmem(lm->mod_base, KVADDR, module_buf, lm->mod_size,
  1818. "module (kallsyms)", RETURN_ON_ERROR|QUIET)) {
  1819. error(WARNING,"cannot access module kallsyms\n");
  1820. FREEBUF(module_buf);
  1821. return 0;
  1822. }
  1823. if (lm->mod_init_size > 0) {
  1824. module_buf_init = GETBUF(lm->mod_init_size);
  1825. if (!readmem(lm->mod_init_module_ptr, KVADDR, module_buf_init, lm->mod_init_size,
  1826. "module init (kallsyms)", RETURN_ON_ERROR|QUIET)) {
  1827. error(WARNING,"cannot access module init kallsyms\n");
  1828. FREEBUF(module_buf_init);
  1829. }
  1830. }
  1831. if (THIS_KERNEL_VERSION >= LINUX(2,6,27))
  1832. nksyms = UINT(modbuf + OFFSET(module_num_symtab));
  1833. else
  1834. nksyms = ULONG(modbuf + OFFSET(module_num_symtab));
  1835. ksymtab = ULONG(modbuf + OFFSET(module_symtab));
  1836. if (!IN_MODULE(ksymtab, lm) && !IN_MODULE_INIT(ksymtab, lm)) {
  1837. error(WARNING,
  1838. "%s: module.symtab outside of module address space\n",
  1839. lm->mod_name);
  1840. FREEBUF(module_buf);
  1841. if (module_buf_init)
  1842. FREEBUF(module_buf_init);
  1843. return 0;
  1844. }
  1845. if (IN_MODULE(ksymtab, lm))
  1846. locsymtab = module_buf + (ksymtab - lm->mod_base);
  1847. else
  1848. locsymtab = module_buf_init + (ksymtab - lm->mod_init_module_ptr);
  1849. kstrtab = ULONG(modbuf + OFFSET(module_strtab));
  1850. if (!IN_MODULE(kstrtab, lm) && !IN_MODULE_INIT(kstrtab, lm)) {
  1851. error(WARNING,
  1852. "%s: module.strtab outside of module address space\n",
  1853. lm->mod_name);
  1854. FREEBUF(module_buf);
  1855. if (module_buf_init)
  1856. FREEBUF(module_buf_init);
  1857. return 0;
  1858. }
  1859. if (IN_MODULE(kstrtab, lm))
  1860. locstrtab = module_buf + (kstrtab - lm->mod_base);
  1861. else
  1862. locstrtab = module_buf_init + (kstrtab - lm->mod_init_module_ptr);
  1863. for (i = 1; i < nksyms; i++) { /* ELF starts real symbols at 1 */
  1864. switch (BITS())
  1865. {
  1866. case 32:
  1867. ptr = locsymtab + (i * sizeof(Elf32_Sym));
  1868. Elf32_Sym_to_common((Elf32_Sym *)ptr, ec);
  1869. break;
  1870. case 64:
  1871. ptr = locsymtab + (i * sizeof(Elf64_Sym));
  1872. Elf64_Sym_to_common((Elf64_Sym *)ptr, ec);
  1873. break;
  1874. }
  1875. if (((ec->st_value < lm->mod_base) ||
  1876. (ec->st_value > (lm->mod_base + lm->mod_size))) &&
  1877. ((ec->st_value < lm->mod_init_module_ptr) ||
  1878. (ec->st_value > (lm->mod_init_module_ptr + lm->mod_init_size))))
  1879. continue;
  1880. if (ec->st_shndx == SHN_UNDEF)
  1881. continue;
  1882. if (!IN_MODULE(kstrtab + ec->st_name, lm) && !IN_MODULE_INIT(kstrtab + ec->st_name, lm)) {
  1883. if (CRASHDEBUG(3)) {
  1884. error(WARNING,
  1885. "%s: bad st_name index: %lx -> %lx\n "
  1886. " st_value: %lx st_shndx: %ld st_info: %c\n",
  1887. lm->mod_name,
  1888. ec->st_name, (kstrtab + ec->st_name),
  1889. ec->st_value, ec->st_shndx,
  1890. ec->st_info);
  1891. }
  1892. continue;
  1893. }
  1894. nameptr = locstrtab + ec->st_name;
  1895. if (*nameptr == '\0')
  1896. continue;
  1897. /*
  1898. * On ARM we have linker mapping symbols like '$a' and '$d'.
  1899. * Make sure that these don't end up into our symbol list.
  1900. */
  1901. if (machine_type("ARM") &&
  1902. !machdep->verify_symbol(nameptr, ec->st_value, ec->st_info))
  1903. continue;
  1904. if (CRASHDEBUG(7))
  1905. fprintf(fp,
  1906. "%s: st_name: %ld st_value: %lx st_shndx: %ld st_info: %c\n",
  1907. nameptr, ec->st_name, ec->st_value,
  1908. ec->st_shndx, ec->st_info);
  1909. strip_symbol_end(nameptr, NULL);
  1910. for (found = 0, j = start; j < curr; j++) {
  1911. sp = &st->ext_module_symtable[j];
  1912. if ((sp->value == ec->st_value) &&
  1913. STREQ(nameptr, &ns->address[(ulong)sp->name])) {
  1914. if (CRASHDEBUG(7))
  1915. fprintf(fp,
  1916. "current symbol \"%s\" at %lx of type (%c)\n",
  1917. &ns->address[(ulong)sp->name],
  1918. sp->value, sp->type);
  1919. if (sp->type == '?')
  1920. sp->type = ec->st_info;
  1921. found++;
  1922. break;
  1923. }
  1924. }
  1925. if (found)
  1926. continue;
  1927. st->ext_module_symtable[mcnt_idx].value = ec->st_value;
  1928. st->ext_module_symtable[mcnt_idx].type = ec->st_info;
  1929. st->ext_module_symtable[mcnt_idx].flags |= MODULE_SYMBOL;
  1930. namespace_ctl(NAMESPACE_INSTALL,
  1931. &st->ext_module_namespace,
  1932. &st->ext_module_symtable[mcnt_idx++], nameptr);
  1933. mcnt++;
  1934. }
  1935. lm->mod_flags |= MOD_KALLSYMS;
  1936. FREEBUF(module_buf);
  1937. if (module_buf_init)
  1938. FREEBUF(module_buf_init);
  1939. return mcnt;
  1940. }
  1941. /*
  1942. * Strip the kernel clutter tagged on the end of an exported module symbol.
  1943. */
  1944. static void
  1945. strip_module_symbol_end(char *buf)
  1946. {
  1947. char *p1, *lastR;
  1948. if (!(lastR = strrchr(buf, 'R')))
  1949. return;
  1950. if (((p1 = lastR-1) < buf) || (*p1 != '_'))
  1951. return;
  1952. if ((kt->flags & SMP) && STRNEQ(p1, "_Rsmp_")) {
  1953. *p1 = NULLCHAR;
  1954. return;
  1955. }
  1956. if (!hexadecimal(lastR+1, 0))
  1957. return;
  1958. *p1 = NULLCHAR;
  1959. }
  1960. /*
  1961. * Return the lowest or highest module virtual address.
  1962. */
  1963. ulong
  1964. lowest_module_address(void)
  1965. {
  1966. int i;
  1967. struct load_module *lm;
  1968. ulong low, lowest;
  1969. if (!st->mods_installed)
  1970. return 0;
  1971. lowest = (ulong)(-1);
  1972. for (i = 0; i < st->mods_installed; i++) {
  1973. lm = &st->load_modules[i];
  1974. low = lm->mod_base;
  1975. if (low < lowest)
  1976. lowest = low;
  1977. }
  1978. return lowest;
  1979. }
  1980. ulong
  1981. highest_module_address(void)
  1982. {
  1983. int i;
  1984. struct load_module *lm;
  1985. ulong high, highest;
  1986. highest = 0;
  1987. for (i = 0; i < st->mods_installed; i++) {
  1988. lm = &st->load_modules[i];
  1989. high = lm->mod_base + lm->mod_size;
  1990. if (high > highest)
  1991. highest = high;
  1992. }
  1993. return highest;
  1994. }
  1995. /*
  1996. * Look through a string for bogus kernel clutter of an exported
  1997. * module symbol. In the case of LM_P_FILTER, shift the string left
  1998. * as appropriate to get rid of the extra stuff. In the case of
  1999. * LM_DIS_FILTER, translation of the previous address is done first,
  2000. * and its results are stuffed into the string. In both cases,
  2001. * this routine is recursive to catch multiple instances.
  2002. */
  2003. #define SMP_CLUTTER (strlen("_Rsmp_"))
  2004. #define UP_CLUTTER (strlen("_R"))
  2005. #define CLUTTER_IDLEN (8)
  2006. char *
  2007. load_module_filter(char *s, int type)
  2008. {
  2009. char *arglist[MAXARGS];
  2010. char buf1[BUFSIZE];
  2011. char buf2[BUFSIZE];
  2012. int clen, last;
  2013. int prev;
  2014. char *pstart, *p1, *p2, *smp, *pend, *colon;
  2015. ulong vaddr;
  2016. ulong offset;
  2017. struct syment *sp;
  2018. int argc;
  2019. switch (type)
  2020. {
  2021. case LM_P_FILTER:
  2022. if (!(pstart = strstr(s, "_R")))
  2023. return s;
  2024. smp = strstr(s, "_Rsmp_");
  2025. pend = &s[strlen(s)];
  2026. p2 = pstart + (smp ? SMP_CLUTTER : UP_CLUTTER);
  2027. if ((p2 >= pend) || !hexadecimal(p2, CLUTTER_IDLEN))
  2028. return s;
  2029. clen = smp ?
  2030. SMP_CLUTTER+CLUTTER_IDLEN : UP_CLUTTER+CLUTTER_IDLEN;
  2031. if (bracketed(s, pstart, clen)) { /* hack it out for now */
  2032. pstart--;
  2033. shift_string_left(pstart, clen+2);
  2034. if (*pstart == ',')
  2035. shift_string_left(pstart-1, 1);
  2036. } else
  2037. shift_string_left(pstart, clen);
  2038. return (load_module_filter(s, type)); /* catch multiples */
  2039. case LM_DIS_FILTER:
  2040. strip_beginning_whitespace(s);
  2041. strcpy(buf1, s);
  2042. argc = parse_line(buf1, arglist);
  2043. if (argc < 2)
  2044. return s;
  2045. /*
  2046. * Fix up the first half of the disassembly expression,
  2047. * that is, the address and symbol to the left of the
  2048. * colon.
  2049. */
  2050. colon = NULL;
  2051. if (hexadecimal(arglist[0], VADDR_PRLEN+2) &&
  2052. bracketed(arglist[1], &arglist[1][1], 0) &&
  2053. (colon = strstr(s, ":"))) {
  2054. strcpy(buf2, colon+2);
  2055. vaddr = htol(arglist[0], FAULT_ON_ERROR, NULL);
  2056. if ((sp = value_search(vaddr, &offset))) {
  2057. if (offset)
  2058. sprintf(s, "%s <%s+%ld>:\t%s",
  2059. arglist[0], sp->name, offset, buf2);
  2060. else
  2061. sprintf(s, "%s <%s>:\t%s",
  2062. arglist[0], sp->name, buf2);
  2063. }
  2064. }
  2065. /*
  2066. * Now work on the second part -- if it exists.
  2067. * Find a virtual address followed by a bracked symbol
  2068. * at the end of the line.
  2069. */
  2070. if (colon) {
  2071. strcpy(buf1, s);
  2072. argc = parse_line(buf1, arglist);
  2073. colon = strstr(s, ":");
  2074. }
  2075. last = argc-1;
  2076. prev = argc-2;
  2077. if (bracketed(arglist[last], &arglist[last][1], 0) &&
  2078. hexadecimal(arglist[prev], VADDR_PRLEN+2)) {
  2079. vaddr = htol(arglist[prev], FAULT_ON_ERROR, NULL);
  2080. p1 = strstr(s, arglist[last]);
  2081. if ((sp = value_search(vaddr, &offset)) &&
  2082. !(colon && (p1 < colon))) {
  2083. if (offset)
  2084. sprintf(p1, "<%s+%ld>\n",
  2085. sp->name, offset);
  2086. else
  2087. sprintf(p1, "<%s>\n", sp->name);
  2088. }
  2089. }
  2090. pend = &s[strlen(s)-3];
  2091. if (STREQ(pend, ":\t\n"))
  2092. LASTCHAR(s) = NULLCHAR;
  2093. return s;
  2094. default:
  2095. return NULL; /* can't get here */
  2096. }
  2097. }
  2098. /*
  2099. * Handle the various commands for controlling symbol string space:
  2100. *
  2101. * NAMESPACE_INIT: Allocates an estimated size for the string space.
  2102. * NAMESPACE_REUSE: Resets appropriate fields to allow a previously
  2103. * allocated module string buffer to be reused.
  2104. * NAMESPACE_FREE: Frees (module) string space.
  2105. * NAMESPACE_INSTALL: Copies a symbol name string into the next available
  2106. * buffer space. If the string cannot be squeezed in,
  2107. * the whole string space is reallocated, which may
  2108. * change its starting address. For that reason, the
  2109. * buffer index is temporarily stored in the sp->name
  2110. * field, which NAMESPACE_COMPLETE later transforms into
  2111. * the proper address when the buffer is set.
  2112. * NAMESPACE_COMPLETE: Reallocs a completed string buffer to the exact
  2113. * size that is required, and then calculates and stores
  2114. * the proper addresses into the name fields of the
  2115. * passed-in syment array.
  2116. */
  2117. #define AVERAGE_SYMBOL_SIZE (16)
  2118. static int
  2119. namespace_ctl(int cmd, struct symbol_namespace *ns, void *nsarg1, void *nsarg2)
  2120. {
  2121. char *addr;
  2122. struct syment *sp, *sp_end;
  2123. char *name;
  2124. long cnt;
  2125. int len;
  2126. switch (cmd)
  2127. {
  2128. case NAMESPACE_INIT:
  2129. cnt = (long)nsarg1;
  2130. if ((addr = calloc(cnt, AVERAGE_SYMBOL_SIZE)) == NULL)
  2131. return FALSE;
  2132. ns->address = addr;
  2133. ns->index = 0;
  2134. ns->cnt = 0;
  2135. ns->size = cnt * AVERAGE_SYMBOL_SIZE;
  2136. return TRUE;
  2137. case NAMESPACE_REUSE:
  2138. ns->index = 0;
  2139. ns->cnt = 0;
  2140. return TRUE;
  2141. case NAMESPACE_FREE:
  2142. if (!ns->address)
  2143. error(FATAL,
  2144. "attempt to free unallocated module namespace\n");
  2145. free(ns->address);
  2146. ns->address = 0;
  2147. ns->index = 0;
  2148. ns->size = 0;
  2149. ns->cnt = 0;
  2150. return TRUE;
  2151. case NAMESPACE_INSTALL:
  2152. sp = (struct syment *)nsarg1;
  2153. name = (char *)nsarg2;
  2154. len = strlen(name)+1;
  2155. if ((ns->index + len) >= ns->size) {
  2156. if (!(addr = realloc(ns->address, ns->size*2)))
  2157. error(FATAL, "symbol name space malloc: %s\n",
  2158. strerror(errno));
  2159. ns->address = addr;
  2160. ns->size *= 2;
  2161. }
  2162. sp->name = (char *)ns->index;
  2163. BCOPY(name, &ns->address[ns->index], len);
  2164. ns->index += len;
  2165. ns->cnt++;
  2166. return TRUE;
  2167. case NAMESPACE_COMPLETE:
  2168. sp = (struct syment *)nsarg1;
  2169. sp_end = (struct syment *)nsarg2;
  2170. if (ns->index < (ns->size-1)) {
  2171. if ((addr = realloc(ns->address, ns->index+1))) {
  2172. ns->address = addr;
  2173. ns->size = ns->index+1;
  2174. }
  2175. }
  2176. for ( ; sp < sp_end; sp++)
  2177. sp->name = ns->address + (long)sp->name;
  2178. return TRUE;
  2179. default:
  2180. return FALSE; /* can't get here */
  2181. }
  2182. }
  2183. /*
  2184. * These comparison functions must return an integer less than,
  2185. * equal to, or greater than zero if the first argument is
  2186. * considered to be respectively less than, equal to, or
  2187. * greater than the second. If two members compare as equal,
  2188. * their order in the sorted array is undefined.
  2189. */
  2190. static int
  2191. compare_syms(const void *v1, const void *v2)
  2192. {
  2193. struct syment *s1, *s2;
  2194. char sn1[BUFSIZE], sn2[BUFSIZE];
  2195. s1 = (struct syment *)v1;
  2196. s2 = (struct syment *)v2;
  2197. if (s1->value == s2->value) {
  2198. if (STRNEQ(s1->name, "__insmod"))
  2199. return -1;
  2200. if (STRNEQ(s2->name, "__insmod"))
  2201. return 1;
  2202. if (STRNEQ(s2->name, "_MODULE_START_"))
  2203. return 1;
  2204. /* Get pseudo section name. */
  2205. if (MODULE_SECTION_START(s1))
  2206. sscanf(s1->name, "_MODULE_SECTION_START [%s]", sn1);
  2207. else if (MODULE_SECTION_END(s1))
  2208. sscanf(s1->name, "_MODULE_SECTION_END [%s]", sn1);
  2209. if (MODULE_SECTION_START(s2))
  2210. sscanf(s2->name, "_MODULE_SECTION_START [%s]", sn2);
  2211. else if (MODULE_SECTION_END(s2))
  2212. sscanf(s2->name, "_MODULE_SECTION_END [%s]", sn2);
  2213. /*
  2214. * Sort pseudo symbols in mind section.
  2215. * The same values must be sorted like examples.
  2216. * - exp1
  2217. * c9046000 MODULE START: sctp
  2218. * c9046000 [.data]: section start
  2219. * c9046000 (D) sctp_timer_events
  2220. *
  2221. * - exp2
  2222. * c9046c68 [.bss]: section end
  2223. * c9046c68 MODULE END: sctp
  2224. *
  2225. * - exp3
  2226. * c90e9b44 [.text]: section end
  2227. * c90e9b44 [.exit.text]: section start
  2228. * c90e9b44 (T) cleanup_module
  2229. * c90e9b44 (t) sctp_exit
  2230. * c90e9c81 [.exit.text]: section end
  2231. */
  2232. if (MODULE_SECTION_END(s1)) {
  2233. if (!MODULE_PSEUDO_SYMBOL(s2) || MODULE_END(s2))
  2234. return -1;
  2235. else if (MODULE_SECTION_START(s2) && !STREQ(sn1, sn2))
  2236. return -1;
  2237. return 1;
  2238. }
  2239. if (MODULE_SECTION_END(s2)) {
  2240. if (MODULE_END(s1) || !MODULE_PSEUDO_SYMBOL(s1))
  2241. return 1;
  2242. else if (MODULE_SECTION_START(s1) && STREQ(sn1, sn2))
  2243. return 1;
  2244. return -1;
  2245. }
  2246. if (MODULE_SECTION_START(s2)) {
  2247. if (MODULE_START(s1))
  2248. return -1;
  2249. return 1;
  2250. }
  2251. }
  2252. return (s1->value < s2->value ? -1 :
  2253. s1->value == s2->value ? 0 : 1);
  2254. }
  2255. static int
  2256. compare_mods(const void *v1, const void *v2)
  2257. {
  2258. struct load_module *lm1, *lm2;
  2259. lm1 = (struct load_module *)v1;
  2260. lm2 = (struct load_module *)v2;
  2261. return (lm1->mod_base < lm2->mod_base ? -1 :
  2262. lm1->mod_base == lm2->mod_base ? 0 : 1);
  2263. }
  2264. /*
  2265. * Check whether a value falls into a text-type (SEC_CODE) section.
  2266. * If it's a module address, and symbols are not loaded, we're forced
  2267. * to use our "mod_etext_guess" value.
  2268. */
  2269. int
  2270. is_kernel_text(ulong value)
  2271. {
  2272. int i, s;
  2273. asection **sec, *section;
  2274. struct load_module *lm;
  2275. ulong start, end;
  2276. struct syment *sp;
  2277. start = 0;
  2278. if (pc->flags & SYSMAP) {
  2279. if ((sp = value_search(value, NULL)) &&
  2280. ((sp->type == 'T') || (sp->type == 't')))
  2281. return TRUE;
  2282. for (sp = st->symtable; sp < st->symend; sp++) {
  2283. if (!((sp->type == 'T') || (sp->type == 't')))
  2284. continue;
  2285. if ((value >= sp->value) && (value < kt->etext))
  2286. return TRUE;
  2287. break;
  2288. }
  2289. } else {
  2290. sec = (asection **)st->sections;
  2291. for (i = 0; i < st->bfd->section_count; i++, sec++) {
  2292. section = *sec;
  2293. if (section->flags & SEC_CODE) {
  2294. start = (ulong)bfd_get_section_vma(st->bfd,
  2295. section);
  2296. end = start + (ulong)bfd_section_size(st->bfd,
  2297. section);
  2298. if ((value >= start) && (value < end))
  2299. return TRUE;
  2300. }
  2301. }
  2302. }
  2303. if ((sp = value_search(value, NULL)) &&
  2304. ((sp->type == 'T') || (sp->type == 't')))
  2305. return TRUE;
  2306. if (NO_MODULES())
  2307. return FALSE;
  2308. for (i = 0; i < st->mods_installed; i++) {
  2309. lm = &st->load_modules[i];
  2310. if (!IN_MODULE(value, lm) && !IN_MODULE_INIT(value, lm))
  2311. continue;
  2312. if (lm->mod_flags & MOD_LOAD_SYMS) {
  2313. for (s = (lm->mod_sections-1); s >= 0; s--) {
  2314. if (!(lm->mod_section_data[s].flags & SEC_CODE))
  2315. continue;
  2316. start = lm->mod_base +
  2317. lm->mod_section_data[s].offset;
  2318. end = start + lm->mod_section_data[s].size;
  2319. if ((value >= start) && (value < end))
  2320. return TRUE;
  2321. }
  2322. } else {
  2323. switch (kt->flags & (KMOD_V1|KMOD_V2))
  2324. {
  2325. case KMOD_V1:
  2326. start = lm->mod_base + lm->mod_size_of_struct;
  2327. break;
  2328. case KMOD_V2:
  2329. if (IN_MODULE(value, lm))
  2330. start = lm->mod_base;
  2331. else
  2332. start = lm->mod_init_module_ptr;
  2333. break;
  2334. }
  2335. end = lm->mod_etext_guess;
  2336. if (IN_MODULE_INIT(value, lm) && end < lm->mod_init_module_ptr + lm->mod_init_size)
  2337. end = lm->mod_init_module_ptr + lm->mod_init_size;
  2338. if ((value >= start) && (value < end))
  2339. return TRUE;
  2340. }
  2341. }
  2342. return FALSE;
  2343. }
  2344. /*
  2345. * Detemine whether an address is offset into a text function, i.e., not
  2346. * the starting address of the function.
  2347. */
  2348. int
  2349. is_kernel_text_offset(ulong value)
  2350. {
  2351. struct syment *sp;
  2352. ulong offset;
  2353. if (!is_kernel_text(value))
  2354. return FALSE;
  2355. if (!(sp = value_search(value, &offset)))
  2356. return FALSE;
  2357. return(offset ? TRUE : FALSE);
  2358. }
  2359. /*
  2360. * Check whether an address is most likely kernel data.
  2361. *
  2362. * TBD: This should be refined to recognize module text/data.
  2363. */
  2364. int
  2365. is_kernel_data(ulong value)
  2366. {
  2367. return(IS_KVADDR(value) &&
  2368. !is_kernel_text(value) && !IS_MODULE_VADDR(value));
  2369. }
  2370. /*
  2371. * Check whether the closest symbol to a value is rodata.
  2372. */
  2373. int
  2374. is_rodata(ulong value, struct syment **spp)
  2375. {
  2376. struct syment *sp;
  2377. if (!(sp = value_search(value, NULL)))
  2378. return FALSE;
  2379. if ((sp->type == 'r') || (sp->type == 'R')) {
  2380. if (spp)
  2381. *spp = sp;
  2382. return TRUE;
  2383. }
  2384. return FALSE;
  2385. }
  2386. /*
  2387. * "help -s" output
  2388. */
  2389. void
  2390. dump_symbol_table(void)
  2391. {
  2392. int i, s, cnt, tot;
  2393. struct load_module *lm;
  2394. struct syment *sp;
  2395. int others;
  2396. asection **sec;
  2397. fprintf(fp, " flags: %lx%s(", st->flags,
  2398. count_bits_long(st->flags) > 3 ? "\n " : " ");
  2399. others = 0;
  2400. if (st->flags & KERNEL_SYMS)
  2401. fprintf(fp, "%sKERNEL_SYMS", others++ ? "|" : "");
  2402. if (st->flags & MODULE_SYMS)
  2403. fprintf(fp, "%sMODULE_SYMS", others++ ? "|" : "");
  2404. if (st->flags & LOAD_MODULE_SYMS)
  2405. fprintf(fp, "%sLOAD_MODULE_SYMS",
  2406. others++ ? "|" : "");
  2407. if (st->flags & INSMOD_BUILTIN)
  2408. fprintf(fp, "%sINSMOD_BUILTIN", others++ ? "|" : "");
  2409. if (st->flags & GDB_SYMS_PATCHED)
  2410. fprintf(fp, "%sGDB_SYMS_PATCHED", others++ ? "|" : "");
  2411. if (st->flags & NO_SEC_LOAD)
  2412. fprintf(fp, "%sNO_SEC_LOAD", others++ ? "|" : "");
  2413. if (st->flags & NO_SEC_CONTENTS)
  2414. fprintf(fp, "%sNO_SEC_CONTENTS", others++ ? "|" : "");
  2415. if (st->flags & FORCE_DEBUGINFO)
  2416. fprintf(fp, "%sFORCE_DEBUGINFO", others++ ? "|" : "");
  2417. if (st->flags & CRC_MATCHES)
  2418. fprintf(fp, "%sCRC_MATCHES", others++ ? "|" : "");
  2419. if (st->flags & ADD_SYMBOL_FILE)
  2420. fprintf(fp, "%sADD_SYMBOL_FILE", others++ ? "|" : "");
  2421. if (st->flags & USE_OLD_ADD_SYM)
  2422. fprintf(fp, "%sUSE_OLD_ADD_SYM", others++ ? "|" : "");
  2423. if (st->flags & PERCPU_SYMS)
  2424. fprintf(fp, "%sPERCPU_SYMS", others++ ? "|" : "");
  2425. if (st->flags & MODSECT_V1)
  2426. fprintf(fp, "%sMODSECT_V1", others++ ? "|" : "");
  2427. if (st->flags & MODSECT_V2)
  2428. fprintf(fp, "%sMODSECT_V2", others++ ? "|" : "");
  2429. if (st->flags & MODSECT_V3)
  2430. fprintf(fp, "%sMODSECT_V3", others++ ? "|" : "");
  2431. if (st->flags & MODSECT_UNKNOWN)
  2432. fprintf(fp, "%sMODSECT_UNKNOWN", others++ ? "|" : "");
  2433. if (st->flags & NO_STRIP)
  2434. fprintf(fp, "%sNO_STRIP", others++ ? "|" : "");
  2435. fprintf(fp, ")\n");
  2436. fprintf(fp, " bfd: %lx\n", (ulong)st->bfd);
  2437. fprintf(fp, " symtable: %lx\n", (ulong)st->symtable);
  2438. fprintf(fp, " symend: %lx\n", (ulong)st->symend);
  2439. fprintf(fp, " symcnt: %ld\n", st->symcnt);
  2440. fprintf(fp, " syment_size: %ld\n", st->syment_size);
  2441. fprintf(fp, " first_ksymbol: ");
  2442. if (st->first_ksymbol) {
  2443. fprintf(fp, "%lx (%s)\n",
  2444. st->first_ksymbol,
  2445. st->flags & KERNEL_SYMS ?
  2446. value_symbol(st->first_ksymbol) : "");
  2447. } else
  2448. fprintf(fp, "(unused)\n");
  2449. if (st->__per_cpu_start || st->__per_cpu_end) {
  2450. fprintf(fp, " __per_cpu_start: %lx\n", st->__per_cpu_start);
  2451. fprintf(fp, " __per_cpu_end: %lx\n", st->__per_cpu_end);
  2452. } else {
  2453. fprintf(fp, " __per_cpu_start: (unused)\n");
  2454. fprintf(fp, " __per_cpu_end: (unused)\n");
  2455. }
  2456. fprintf(fp, " first_section_start: %lx\n", st->first_section_start);
  2457. fprintf(fp, " last_section_end: %lx\n", st->last_section_end);
  2458. fprintf(fp, " _stext_vmlinux: %lx ", st->_stext_vmlinux);
  2459. if (st->_stext_vmlinux == UNINITIALIZED)
  2460. fprintf(fp, "(UNINITIALIZED)\n");
  2461. else if (st->_stext_vmlinux == 0)
  2462. fprintf(fp, "(unused)\n");
  2463. else
  2464. fprintf(fp, "\n");
  2465. fprintf(fp, " symval_hash[%d]: %lx\n", SYMVAL_HASH,
  2466. (ulong)&st->symval_hash[0]);
  2467. if (CRASHDEBUG(1)) {
  2468. fprintf(fp, " ");
  2469. for (i = 0; i < SYMVAL_HASH; i++) {
  2470. fprintf(fp, " [%3d]: ", i);
  2471. sp = st->symval_hash[i].val_hash_head;
  2472. if (!sp) {
  2473. fprintf(fp, " 0 ");
  2474. } else {
  2475. cnt = 1;
  2476. while ((sp = sp->val_hash_next))
  2477. cnt++;
  2478. fprintf(fp, "%3d ", cnt);
  2479. }
  2480. if (i && (((i+1)%6)== 0))
  2481. fprintf(fp, "\n ");
  2482. }
  2483. }
  2484. fprintf(fp, "%s val_hash_searches: %.0f\n",
  2485. CRASHDEBUG(1) ? "\n" : "", st->val_hash_searches);
  2486. fprintf(fp, " val_hash_iterations: %.0f (avg: %.1f)\n",
  2487. st->val_hash_iterations,
  2488. st->val_hash_iterations/st->val_hash_searches);
  2489. fprintf(fp, " symname_hash[%d]: %lx\n", SYMNAME_HASH,
  2490. (ulong)&st->symname_hash[0]);
  2491. if (CRASHDEBUG(1)) {
  2492. fprintf(fp, " ");
  2493. for (i = tot = 0; i < SYMNAME_HASH; i++) {
  2494. fprintf(fp, "[%3d]: ", i);
  2495. if ((sp = st->symname_hash[i]) == NULL)
  2496. fprintf(fp, "%3d ", 0);
  2497. else {
  2498. cnt = 1;
  2499. while (sp->name_hash_next) {
  2500. cnt++;
  2501. sp = sp->name_hash_next;
  2502. }
  2503. fprintf(fp, "%3d ", cnt);
  2504. tot += cnt;
  2505. }
  2506. if (i && (((i+1) % 6) == 0))
  2507. fprintf(fp, "\n ");
  2508. }
  2509. if (SYMNAME_HASH % 6)
  2510. fprintf(fp, "\n");
  2511. }
  2512. fprintf(fp, " symbol_namespace: ");
  2513. fprintf(fp, "address: %lx ", (ulong)st->kernel_namespace.address);
  2514. fprintf(fp, "index: %ld ", st->kernel_namespace.index);
  2515. fprintf(fp, "size: %ld ", (ulong)st->kernel_namespace.size);
  2516. fprintf(fp, "cnt: %ld\n", st->kernel_namespace.cnt);
  2517. fprintf(fp, " ext_module_symtable: %lx\n",
  2518. (ulong)st->ext_module_symtable);
  2519. fprintf(fp, " ext_module_symend: %lx\n",
  2520. (ulong)st->ext_module_symend);
  2521. fprintf(fp, " ext_module_symcnt: %ld\n",
  2522. (ulong)st->ext_module_symcnt);
  2523. fprintf(fp, "ext_module_namespace: ");
  2524. fprintf(fp, "address: %lx ",
  2525. (ulong)st->ext_module_namespace.address);
  2526. fprintf(fp, "index: %ld ",
  2527. st->ext_module_namespace.index);
  2528. fprintf(fp, "size: %ld ",
  2529. (ulong)st->ext_module_namespace.size);
  2530. fprintf(fp, "cnt: %ld\n",
  2531. st->ext_module_namespace.cnt);
  2532. fprintf(fp, " mods_installed: %d\n", st->mods_installed);
  2533. fprintf(fp, " current: %lx\n", (ulong)st->current);
  2534. fprintf(fp, " load_modules: %lx\n", (ulong)st->load_modules);
  2535. for (i = 0; i < st->mods_installed; i++) {
  2536. lm = &st->load_modules[i];
  2537. others = 0;
  2538. fprintf(fp, "\n mod_base: %lx\n", lm->mod_base);
  2539. fprintf(fp, " module_struct: %lx\n", lm->module_struct);
  2540. fprintf(fp, " mod_name: %s\n", lm->mod_name);
  2541. fprintf(fp, " mod_size: %ld\n", lm->mod_size);
  2542. fprintf(fp, " mod_namelist: %s\n", lm->mod_namelist);
  2543. fprintf(fp, " mod_flags: %lx (", lm->mod_flags);
  2544. if (lm->mod_flags & MOD_EXT_SYMS)
  2545. fprintf(fp, "%sMOD_EXT_SYMS", others++ ? "|" : "");
  2546. if (lm->mod_flags & MOD_LOAD_SYMS)
  2547. fprintf(fp, "%sMOD_LOAD_SYMS", others++ ? "|" : "");
  2548. if (lm->mod_flags & MOD_REMOTE)
  2549. fprintf(fp, "%sMOD_REMOTE", others++ ? "|" : "");
  2550. if (lm->mod_flags & MOD_KALLSYMS)
  2551. fprintf(fp, "%sMOD_KALLSYMS", others++ ? "|" : "");
  2552. if (lm->mod_flags & MOD_INITRD)
  2553. fprintf(fp, "%sMOD_INITRD", others++ ? "|" : "");
  2554. if (lm->mod_flags & MOD_NOPATCH)
  2555. fprintf(fp, "%sMOD_NOPATCH", others++ ? "|" : "");
  2556. if (lm->mod_flags & MOD_INIT)
  2557. fprintf(fp, "%sMOD_INIT", others++ ? "|" : "");
  2558. if (lm->mod_flags & MOD_DO_READNOW)
  2559. fprintf(fp, "%sMOD_DO_READNOW", others++ ? "|" : "");
  2560. fprintf(fp, ")\n");
  2561. fprintf(fp, " mod_symtable: %lx\n",
  2562. (ulong)lm->mod_symtable);
  2563. fprintf(fp, " mod_symend: %lx\n",
  2564. (ulong)lm->mod_symend);
  2565. fprintf(fp, " mod_init_symtable: %lx\n",
  2566. (ulong)lm->mod_init_symtable);
  2567. fprintf(fp, " mod_init_symend: %lx\n",
  2568. (ulong)lm->mod_init_symend);
  2569. fprintf(fp, " mod_ext_symcnt: %ld\n",
  2570. lm->mod_ext_symcnt);
  2571. fprintf(fp, " mod_ext_symtable: %lx\n",
  2572. (ulong)lm->mod_ext_symtable);
  2573. fprintf(fp, " mod_ext_symend: %lx\n",
  2574. (ulong)lm->mod_ext_symend);
  2575. fprintf(fp, " mod_load_symcnt: %ld\n",
  2576. lm->mod_load_symcnt);
  2577. fprintf(fp, " mod_load_symtable: %lx\n",
  2578. (ulong)lm->mod_load_symtable);
  2579. fprintf(fp, " mod_load_symend: %lx\n",
  2580. (ulong)lm->mod_load_symend);
  2581. fprintf(fp, " mod_load_namespace: ");
  2582. fprintf(fp, "address: %lx ",
  2583. (ulong)lm->mod_load_namespace.address);
  2584. fprintf(fp, "index: %ld ",
  2585. lm->mod_load_namespace.index);
  2586. fprintf(fp, "size: %ld ",
  2587. (ulong)lm->mod_load_namespace.size);
  2588. fprintf(fp, "cnt: %ld\n",
  2589. lm->mod_load_namespace.cnt);
  2590. fprintf(fp, " mod_symalloc: %ld\n", lm->mod_symalloc);
  2591. fprintf(fp, " mod_size_of_struct: %ld (%lx)\n",
  2592. lm->mod_size_of_struct, lm->mod_size_of_struct);
  2593. fprintf(fp, " mod_text_start: %lx (%lx)\n",
  2594. lm->mod_text_start,
  2595. lm->mod_text_start ?
  2596. lm->mod_text_start - lm->mod_base : 0);
  2597. fprintf(fp, " mod_etext_guess: %lx (%lx)\n",
  2598. lm->mod_etext_guess,
  2599. lm->mod_etext_guess ?
  2600. lm->mod_etext_guess - lm->mod_base : 0);
  2601. fprintf(fp, " mod_rodata_start: %lx (%lx)\n",
  2602. lm->mod_rodata_start,
  2603. lm->mod_rodata_start ?
  2604. lm->mod_rodata_start - lm->mod_base : 0);
  2605. fprintf(fp, " mod_data_start: %lx (%lx)\n",
  2606. lm->mod_data_start,
  2607. lm->mod_data_start ?
  2608. lm->mod_data_start - lm->mod_base : 0);
  2609. fprintf(fp, " mod_bss_start: %lx (%lx)\n",
  2610. lm->mod_bss_start,
  2611. lm->mod_bss_start ?
  2612. lm->mod_bss_start - lm->mod_base : 0);
  2613. fprintf(fp, " mod_init_size: %ld\n",
  2614. lm->mod_init_size);
  2615. fprintf(fp, " mod_init_text_size: %ld\n",
  2616. lm->mod_init_text_size);
  2617. fprintf(fp, " mod_init_module_ptr: %lx\n",
  2618. lm->mod_init_module_ptr);
  2619. if (lm->mod_percpu_size) {
  2620. fprintf(fp, " mod_percpu_size: %lx\n",
  2621. lm->mod_percpu_size);
  2622. fprintf(fp, " mod_percpu: %lx - %lx\n",
  2623. lm->mod_percpu,
  2624. lm->mod_percpu + lm->mod_percpu_size);
  2625. } else {
  2626. if (lm->mod_percpu) {
  2627. fprintf(fp,
  2628. " mod_percpu_size: (not loaded)\n");
  2629. fprintf(fp,
  2630. " mod_percpu: %lx - (unknown)\n",
  2631. lm->mod_percpu);
  2632. } else {
  2633. fprintf(fp,
  2634. " mod_percpu_size: (not used)\n");
  2635. fprintf(fp,
  2636. " mod_percpu: (not used)\n");
  2637. }
  2638. }
  2639. fprintf(fp, " mod_sections: %d\n", lm->mod_sections);
  2640. fprintf(fp, " mod_section_data: %lx %s\n",
  2641. (ulong)lm->mod_section_data,
  2642. lm->mod_section_data ? "" : "(not allocated)");
  2643. for (s = 0; s < lm->mod_sections; s++) {
  2644. fprintf(fp,
  2645. " %12s prio: %x flags: %05x offset: %-8lx size: %lx\n",
  2646. lm->mod_section_data[s].name,
  2647. lm->mod_section_data[s].priority,
  2648. lm->mod_section_data[s].flags,
  2649. lm->mod_section_data[s].offset,
  2650. lm->mod_section_data[s].size);
  2651. }
  2652. if (CRASHDEBUG(1)) {
  2653. for (sp = lm->mod_load_symtable;
  2654. sp < lm->mod_load_symend; sp++) {
  2655. fprintf(fp, " %lx %s\n",
  2656. sp->value, sp->name);
  2657. }
  2658. }
  2659. }
  2660. fprintf(fp, "\n");
  2661. fprintf(fp, " dwarf_eh_frame_file_offset: %llx\n",
  2662. (unsigned long long)st->dwarf_eh_frame_file_offset);
  2663. fprintf(fp, " dwarf_eh_frame_size: %ld\n", st->dwarf_eh_frame_size);
  2664. fprintf(fp, "dwarf_debug_frame_file_offset: %llx\n",
  2665. (unsigned long long)st->dwarf_debug_frame_file_offset);
  2666. fprintf(fp, " dwarf_debug_frame_size: %ld\n", st->dwarf_debug_frame_size);
  2667. fprintf(fp, "\n");
  2668. sec = (asection **)st->sections;
  2669. fprintf(fp, " sections: %s\n", sec ? "" : "(not in use)");
  2670. for (i = 0; sec && (i < st->bfd->section_count); i++, sec++) {
  2671. asection *section;
  2672. section = *sec;
  2673. fprintf(fp, "%25s vma: %.*lx size: %ld\n",
  2674. section->name, VADDR_PRLEN,
  2675. (ulong)bfd_get_section_vma(st->bfd, section),
  2676. (ulong)bfd_section_size(st->bfd, section));
  2677. }
  2678. }
  2679. /*
  2680. * Determine whether a file is in ELF format by checking the magic number
  2681. * in the first EI_NIDENT characters of the file; if those match, check
  2682. * whether the file is a known BFD format.
  2683. */
  2684. int
  2685. is_elf_file(char *s)
  2686. {
  2687. int fd;
  2688. char magic[EI_NIDENT];
  2689. if ((fd = open(s, O_RDONLY)) < 0) {
  2690. error(INFO, "%s: %s\n", s, strerror(errno));
  2691. return FALSE;
  2692. }
  2693. if (read(fd, magic, EI_NIDENT) != EI_NIDENT) {
  2694. /* error(INFO, "%s: %s\n", s, strerror(errno)); */
  2695. close(fd);
  2696. return FALSE;
  2697. }
  2698. close(fd);
  2699. magic[EI_CLASS] = NULLCHAR;
  2700. if (!STREQ(magic, ELFMAG))
  2701. return FALSE;
  2702. return(is_bfd_format(s));
  2703. }
  2704. /*
  2705. * Verify a vmlinux file, issuing a warning for processor and endianness
  2706. * mismatches.
  2707. */
  2708. int
  2709. is_kernel(char *file)
  2710. {
  2711. int fd, swap;
  2712. char eheader[BUFSIZE];
  2713. Elf32_Ehdr *elf32;
  2714. Elf64_Ehdr *elf64;
  2715. if ((fd = open(file, O_RDONLY)) < 0) {
  2716. error(INFO, "%s: %s\n", file, strerror(errno));
  2717. return FALSE;
  2718. }
  2719. if (read(fd, eheader, BUFSIZE) != BUFSIZE) {
  2720. /* error(INFO, "%s: %s\n", file, strerror(errno)); */
  2721. close(fd);
  2722. return FALSE;
  2723. }
  2724. close(fd);
  2725. if (!STRNEQ(eheader, ELFMAG) || eheader[EI_VERSION] != EV_CURRENT)
  2726. return FALSE;
  2727. elf32 = (Elf32_Ehdr *)&eheader[0];
  2728. elf64 = (Elf64_Ehdr *)&eheader[0];
  2729. swap = (((eheader[EI_DATA] == ELFDATA2LSB) &&
  2730. (__BYTE_ORDER == __BIG_ENDIAN)) ||
  2731. ((eheader[EI_DATA] == ELFDATA2MSB) &&
  2732. (__BYTE_ORDER == __LITTLE_ENDIAN)));
  2733. if ((elf32->e_ident[EI_CLASS] == ELFCLASS32) &&
  2734. (swap16(elf32->e_type, swap) == ET_EXEC) &&
  2735. (swap32(elf32->e_version, swap) == EV_CURRENT)) {
  2736. switch (swap16(elf32->e_machine, swap))
  2737. {
  2738. case EM_386:
  2739. if (machine_type_mismatch(file, "X86", NULL, 0)) {
  2740. if (machine_type("X86_64")) {
  2741. /*
  2742. * Since is_bfd_format() returns TRUE
  2743. * in this case, just bail out here.
  2744. */
  2745. return FALSE;
  2746. }
  2747. goto bailout;
  2748. }
  2749. break;
  2750. case EM_S390:
  2751. if (machine_type_mismatch(file, "S390", NULL, 0))
  2752. goto bailout;
  2753. break;
  2754. case EM_ARM:
  2755. if (machine_type_mismatch(file, "ARM", NULL, 0))
  2756. goto bailout;
  2757. break;
  2758. case EM_PPC:
  2759. if (machine_type_mismatch(file, "PPC", NULL, 0))
  2760. goto bailout;
  2761. break;
  2762. default:
  2763. if (machine_type_mismatch(file, "(unknown)", NULL, 0))
  2764. goto bailout;
  2765. }
  2766. if (endian_mismatch(file, elf32->e_ident[EI_DATA], 0))
  2767. goto bailout;
  2768. } else if ((elf64->e_ident[EI_CLASS] == ELFCLASS64) &&
  2769. ((swap16(elf64->e_type, swap) == ET_EXEC) ||
  2770. (swap16(elf64->e_type, swap) == ET_DYN)) &&
  2771. (swap32(elf64->e_version, swap) == EV_CURRENT)) {
  2772. switch (swap16(elf64->e_machine, swap))
  2773. {
  2774. case EM_IA_64:
  2775. if (machine_type_mismatch(file, "IA64", NULL, 0))
  2776. goto bailout;
  2777. break;
  2778. case EM_PPC64:
  2779. if (machine_type_mismatch(file, "PPC64", NULL, 0))
  2780. goto bailout;
  2781. break;
  2782. case EM_X86_64:
  2783. if (machine_type_mismatch(file, "X86_64", NULL, 0))
  2784. goto bailout;
  2785. break;
  2786. case EM_386:
  2787. if (machine_type_mismatch(file, "X86", NULL, 0))
  2788. goto bailout;
  2789. break;
  2790. case EM_S390:
  2791. if (machine_type_mismatch(file, "S390X", NULL, 0))
  2792. goto bailout;
  2793. break;
  2794. case EM_AARCH64:
  2795. if (machine_type_mismatch(file, "ARM64", NULL, 0))
  2796. goto bailout;
  2797. break;
  2798. default:
  2799. if (machine_type_mismatch(file, "(unknown)", NULL, 0))
  2800. goto bailout;
  2801. }
  2802. if (endian_mismatch(file, elf64->e_ident[EI_DATA], 0))
  2803. goto bailout;
  2804. }
  2805. bailout:
  2806. return(is_bfd_format(file));
  2807. }
  2808. int
  2809. is_compressed_kernel(char *file, char **tmp)
  2810. {
  2811. int len, type, fd;
  2812. char *tmpdir, *tempname;
  2813. unsigned char header[BUFSIZE];
  2814. char command[BUFSIZE];
  2815. char message[BUFSIZE];
  2816. #define GZIP (1)
  2817. #define BZIP2 (2)
  2818. #define FNAME (1 << 3)
  2819. if ((fd = open(file, O_RDONLY)) < 0)
  2820. return FALSE;
  2821. if (read(fd, header, BUFSIZE) != BUFSIZE) {
  2822. close(fd);
  2823. return FALSE;
  2824. }
  2825. close(fd);
  2826. type = 0;
  2827. if ((header[0] == 0x1f) && (header[1] == 0x8b) && (header[2] == 8)) {
  2828. if (!(header[3] & FNAME)) {
  2829. if (!(st->flags & FORCE_DEBUGINFO)) {
  2830. error(INFO, "%s: "
  2831. "original filename unknown\n",
  2832. file);
  2833. error(CONT,
  2834. "Use \"-f %s\" on command line to prevent this message.\n\n",
  2835. file);
  2836. }
  2837. } else if (!STRNEQ((char *)&header[10], "vmlinux") &&
  2838. !(st->flags & FORCE_DEBUGINFO)) {
  2839. error(INFO, "%s: compressed file name does not "
  2840. "start with \"vmlinux\"\n", &header[10]);
  2841. error(CONT,
  2842. "Use \"-f %s\" on command line to override.\n\n",
  2843. file);
  2844. return FALSE;
  2845. }
  2846. type = GZIP;
  2847. }
  2848. if ((header[0] == 'B') && (header[1] == 'Z') && (header[2] == 'h')) {
  2849. if (!STRNEQ(basename(file), "vmlinux") &&
  2850. !(st->flags & FORCE_DEBUGINFO)) {
  2851. error(INFO, "%s: compressed file name does not start "
  2852. "with \"vmlinux\"\n", file);
  2853. error(CONT,
  2854. "Use \"-f %s\" on command line to override.\n\n",
  2855. file);
  2856. return FALSE;
  2857. }
  2858. type = BZIP2;
  2859. }
  2860. if (!type)
  2861. return FALSE;
  2862. if (!(tmpdir = getenv("TMPDIR")))
  2863. tmpdir = "/var/tmp";
  2864. len = strlen(tmpdir) + strlen(basename(file)) +
  2865. strlen("_XXXXXX") + 2;
  2866. if (!(tempname = (char *)malloc(len)))
  2867. return FALSE;
  2868. sprintf(tempname, "%s/%s_XXXXXX", tmpdir, basename(file));
  2869. fd = mkstemp(tempname);
  2870. if (fd < 0) {
  2871. perror("mkstemp");
  2872. free(tempname);
  2873. return FALSE;
  2874. }
  2875. pc->cleanup = tempname;
  2876. sprintf(message, "uncompressing %s", file);
  2877. please_wait(message);
  2878. switch (type)
  2879. {
  2880. case GZIP:
  2881. sprintf(command, "%s -c %s > %s",
  2882. file_exists("/bin/gunzip", NULL) ?
  2883. "/bin/gunzip" : "/usr/bin/gunzip",
  2884. file, tempname);
  2885. break;
  2886. case BZIP2:
  2887. sprintf(command, "%s -c %s > %s",
  2888. file_exists("/bin/bunzip2", NULL) ?
  2889. "/bin/bunzip2" : "/usr/bin/bunzip2",
  2890. file, tempname);
  2891. break;
  2892. }
  2893. if (system(command) < 0) {
  2894. please_wait_done();
  2895. error(INFO, "%s of %s failed\n",
  2896. type == GZIP ? "gunzip" : "bunzip2", file);
  2897. free(tempname);
  2898. return FALSE;
  2899. }
  2900. please_wait_done();
  2901. if (is_bfd_format(tempname) && is_kernel(tempname)) {
  2902. *tmp = tempname;
  2903. return TRUE;
  2904. }
  2905. unlink(tempname);
  2906. close(fd);
  2907. free(tempname);
  2908. pc->cleanup = NULL;
  2909. return FALSE;
  2910. }
  2911. int
  2912. is_shared_object(char *file)
  2913. {
  2914. int fd, swap;
  2915. char eheader[BUFSIZE];
  2916. Elf32_Ehdr *elf32;
  2917. Elf64_Ehdr *elf64;
  2918. if (is_directory(file))
  2919. return FALSE;
  2920. if ((fd = open(file, O_RDONLY)) < 0)
  2921. return FALSE;
  2922. if (read(fd, eheader, BUFSIZE) != BUFSIZE) {
  2923. close(fd);
  2924. return FALSE;
  2925. }
  2926. close(fd);
  2927. if (!STRNEQ(eheader, ELFMAG) || eheader[EI_VERSION] != EV_CURRENT)
  2928. return FALSE;
  2929. elf32 = (Elf32_Ehdr *)&eheader[0];
  2930. elf64 = (Elf64_Ehdr *)&eheader[0];
  2931. swap = (((eheader[EI_DATA] == ELFDATA2LSB) &&
  2932. (__BYTE_ORDER == __BIG_ENDIAN)) ||
  2933. ((eheader[EI_DATA] == ELFDATA2MSB) &&
  2934. (__BYTE_ORDER == __LITTLE_ENDIAN)));
  2935. if ((elf32->e_ident[EI_CLASS] == ELFCLASS32) &&
  2936. (swap16(elf32->e_type, swap) == ET_DYN)) {
  2937. switch (swap16(elf32->e_machine, swap))
  2938. {
  2939. case EM_386:
  2940. if (machine_type("X86") || machine_type("ARM"))
  2941. return TRUE;
  2942. break;
  2943. case EM_S390:
  2944. if (machine_type("S390"))
  2945. return TRUE;
  2946. break;
  2947. case EM_ARM:
  2948. if (machine_type("ARM"))
  2949. return TRUE;
  2950. break;
  2951. case EM_PPC:
  2952. if (machine_type("PPC"))
  2953. return TRUE;
  2954. break;
  2955. }
  2956. if (CRASHDEBUG(1))
  2957. error(INFO, "%s: machine type mismatch: %d\n",
  2958. file, swap16(elf32->e_machine, swap));
  2959. return FALSE;
  2960. } else if ((elf64->e_ident[EI_CLASS] == ELFCLASS64) &&
  2961. (swap16(elf64->e_type, swap) == ET_DYN)) {
  2962. switch (swap16(elf64->e_machine, swap))
  2963. {
  2964. case EM_IA_64:
  2965. if (machine_type("IA64"))
  2966. return TRUE;
  2967. break;
  2968. case EM_PPC64:
  2969. if (machine_type("PPC64"))
  2970. return TRUE;
  2971. break;
  2972. case EM_X86_64:
  2973. if (machine_type("X86_64") || machine_type("ARM64"))
  2974. return TRUE;
  2975. break;
  2976. case EM_S390:
  2977. if (machine_type("S390X"))
  2978. return TRUE;
  2979. break;
  2980. case EM_AARCH64:
  2981. if (machine_type("ARM64"))
  2982. return TRUE;
  2983. break;
  2984. }
  2985. if (CRASHDEBUG(1))
  2986. error(INFO, "%s: machine type mismatch: %d\n",
  2987. file, swap16(elf32->e_machine, swap));
  2988. }
  2989. return FALSE;
  2990. }
  2991. /*
  2992. * Given a choice between two namelists, pick the one for gdb to use.
  2993. * For now, just check get their stats and check their sizes; the larger
  2994. * one presumably has debug data.
  2995. */
  2996. int
  2997. select_namelist(char *new)
  2998. {
  2999. struct stat stat1, stat2;
  3000. char *namep;
  3001. if (pc->server_namelist) {
  3002. pc->namelist_debug = new;
  3003. return TRUE;
  3004. }
  3005. if (!file_exists(pc->namelist, &stat1) ||
  3006. !file_exists(new, &stat2)) {
  3007. return FALSE;
  3008. }
  3009. if (stat1.st_size > stat2.st_size) {
  3010. pc->namelist_debug = pc->namelist;
  3011. if (pc->namelist_orig) {
  3012. namep = pc->namelist_debug_orig;
  3013. pc->namelist_debug_orig = pc->namelist_orig;
  3014. pc->namelist_orig = namep;
  3015. }
  3016. pc->namelist = new;
  3017. } else if (stat2.st_size > stat1.st_size)
  3018. pc->namelist_debug = new;
  3019. else {
  3020. error(INFO, "cannot distinguish %s and %s\n",
  3021. pc->namelist, new);
  3022. return FALSE;
  3023. }
  3024. return TRUE;
  3025. }
  3026. /*
  3027. * Make a sweep of a non-dump, non-ELF file to guess whether it's a
  3028. * legitimate System.map file.
  3029. */
  3030. int
  3031. is_system_map(char *s)
  3032. {
  3033. int i, lines, retval;
  3034. char *mapitems[MAXARGS];
  3035. char buf[16384];
  3036. FILE *map;
  3037. /*
  3038. * First simulate what "file" does by verifying that the first 16K
  3039. * bytes are ascii data.
  3040. */
  3041. if ((map = fopen(s, "r")) == NULL) {
  3042. error(INFO, "cannot open %s\n", s);
  3043. return FALSE;
  3044. }
  3045. retval = FALSE;
  3046. if (fread(buf, sizeof(char), 16384, map) != (16384*sizeof(char))) {
  3047. if (CRASHDEBUG(1))
  3048. error(INFO, "%s: cannot read 16K\n", s);
  3049. goto not_system_map;
  3050. }
  3051. for (i = 0; i < 16384; i++) {
  3052. if (!ascii(buf[i]))
  3053. goto not_system_map;
  3054. }
  3055. rewind(map);
  3056. for (lines = 0; lines < 100; lines++) {
  3057. if (!fgets(buf, BUFSIZE, map))
  3058. goto not_system_map;
  3059. if (parse_line(buf, mapitems) != 3)
  3060. goto not_system_map;
  3061. if ((strlen(mapitems[0]) > MAX_HEXADDR_STRLEN) ||
  3062. !hexadecimal(mapitems[0], 0) || (strlen(mapitems[1]) > 1))
  3063. goto not_system_map;
  3064. }
  3065. if ((pc->flags & SYSMAP) && !same_file("/boot/System.map", s))
  3066. error(INFO, "overriding /boot/System.map with %s\n", s);
  3067. retval = TRUE;
  3068. not_system_map:
  3069. fclose(map);
  3070. return retval;
  3071. }
  3072. /*
  3073. * Check whether a file is a known BFD format.
  3074. */
  3075. static int
  3076. is_bfd_format(char *filename)
  3077. {
  3078. #ifdef GDB_5_3
  3079. struct _bfd *bfd;
  3080. #else
  3081. struct bfd *bfd;
  3082. #endif
  3083. char **matching;
  3084. if ((bfd = bfd_openr(filename, NULL)) == NULL)
  3085. return FALSE;
  3086. if (!bfd_check_format_matches(bfd, bfd_object, &matching)) {
  3087. bfd_close(bfd);
  3088. return FALSE;
  3089. }
  3090. bfd_close(bfd);
  3091. return TRUE;
  3092. }
  3093. static int
  3094. is_binary_stripped(char *filename)
  3095. {
  3096. #ifdef GDB_5_3
  3097. struct _bfd *bfd;
  3098. #else
  3099. struct bfd *bfd;
  3100. #endif
  3101. int number_of_symbols;
  3102. if ((bfd = bfd_openr(filename, NULL)) == NULL) {
  3103. error(INFO, "cannot open ELF file: %s\n", filename);
  3104. return FALSE;
  3105. }
  3106. if (!bfd_check_format(bfd, bfd_object)) {
  3107. error(INFO, "invalid ELF file: %s\n", filename);
  3108. bfd_close(bfd);
  3109. return FALSE;
  3110. }
  3111. number_of_symbols = bfd_canonicalize_symtab(bfd, NULL);
  3112. bfd_close(bfd);
  3113. return (number_of_symbols == 0);
  3114. }
  3115. /*
  3116. * This command may be used to:
  3117. *
  3118. * 1. Translate a symbol to its value.
  3119. * 2. Translate a value to it symbol.
  3120. * 3. List all stored symbols.
  3121. * 4. Query for symbols containing a string.
  3122. * 5. Show the next and previous symbols.
  3123. */
  3124. void
  3125. cmd_sym(void)
  3126. {
  3127. int c;
  3128. struct syment *sp, *spp, *spn;
  3129. ulong value, show_flags;
  3130. ulong offset;
  3131. int next, prev, multiples, others;
  3132. char *name;
  3133. int errflag;
  3134. char buf[BUFSIZE];
  3135. next = prev = others = 0;
  3136. show_flags = SHOW_LINENUM | SHOW_RADIX();
  3137. while ((c = getopt(argcnt, args, "lLQ:q:npsMm:")) != EOF) {
  3138. switch(c)
  3139. {
  3140. case 'n':
  3141. next++;
  3142. break;
  3143. case 'p':
  3144. prev++;
  3145. break;
  3146. case 'Q':
  3147. fprintf(fp, "%d found ",
  3148. symbol_query(optarg, NULL, &sp));
  3149. if (sp)
  3150. fprintf(fp, "(%s)", sp->name);
  3151. fprintf(fp, "\n");
  3152. others++;
  3153. break;
  3154. case 'q':
  3155. if (!symbol_query(optarg, "", NULL))
  3156. fprintf(fp, "(none found)\n");
  3157. others++;
  3158. break;
  3159. case 'm':
  3160. symbol_dump(MODULE_SYMS, optarg);
  3161. others++;
  3162. break;
  3163. case 'M':
  3164. symbol_dump(MODULE_SYMS, NULL);
  3165. others++;
  3166. break;
  3167. case 'L': /* obsolete */
  3168. case 'l':
  3169. symbol_dump(KERNEL_SYMS|MODULE_SYMS, NULL);
  3170. others++;
  3171. break;
  3172. case 's':
  3173. show_flags &= ~SHOW_LINENUM;
  3174. show_flags |= SHOW_SECTION;
  3175. break;
  3176. default:
  3177. argerrs++;
  3178. break;
  3179. }
  3180. }
  3181. if (argerrs)
  3182. cmd_usage(pc->curcmd, SYNOPSIS);
  3183. if (args[optind]) {
  3184. do {
  3185. name = NULL;
  3186. multiples = 0;
  3187. sp = NULL;
  3188. show_flags &= ~SHOW_MODULE;
  3189. if (clean_arg() && hexadecimal(args[optind], 0)) {
  3190. errflag = 0;
  3191. value = htol(args[optind], RETURN_ON_ERROR,
  3192. &errflag);
  3193. if (errflag || !in_ksymbol_range(value)) {
  3194. error(INFO, "invalid address: %s\n",
  3195. args[optind]);
  3196. } else if ((sp = value_search(value, &offset))){
  3197. name = sp->name;
  3198. if (module_symbol(sp->value, NULL, NULL,
  3199. NULL, 0))
  3200. show_flags |= SHOW_MODULE;
  3201. if (prev &&
  3202. (spp = prev_symbol(NULL, sp)))
  3203. show_symbol(spp, 0, show_flags);
  3204. show_symbol(sp, offset, show_flags);
  3205. }
  3206. else if (module_symbol(value, &sp,
  3207. NULL, buf, *gdb_output_radix)) {
  3208. name = buf;
  3209. if (prev && sp &&
  3210. (spp = prev_symbol(NULL, sp)))
  3211. show_symbol(spp, 0, show_flags);
  3212. fprintf(fp, "%lx (?) %s\n",
  3213. value, buf);
  3214. } else
  3215. fprintf(fp, "symbol not found: %s\n",
  3216. args[optind]);
  3217. } else {
  3218. if ((sp = symbol_search(args[optind]))) {
  3219. multiples = symbol_name_count(sp->name);
  3220. do_multiples:
  3221. if (module_symbol(sp->value, NULL, NULL,
  3222. NULL, 0))
  3223. show_flags |= SHOW_MODULE;
  3224. name = sp->name;
  3225. if (prev &&
  3226. (spp = prev_symbol(NULL, sp)))
  3227. show_symbol(spp, 0, show_flags);
  3228. show_symbol(sp, 0, show_flags);
  3229. }
  3230. else {
  3231. fprintf(fp, "symbol not found: %s\n",
  3232. args[optind]);
  3233. fprintf(fp, "possible alternatives:\n");
  3234. if (!symbol_query(args[optind], " ",
  3235. NULL))
  3236. fprintf(fp, " (none found)\n");
  3237. }
  3238. }
  3239. if (name && next && (spn = next_symbol(NULL, sp)))
  3240. show_symbol(spn, 0, show_flags);
  3241. if (multiples > 1) {
  3242. if ((sp = symbol_search_next(name, sp)))
  3243. goto do_multiples;
  3244. }
  3245. optind++;
  3246. } while(args[optind]);
  3247. }
  3248. else if (!others)
  3249. cmd_usage(pc->curcmd, SYNOPSIS);
  3250. }
  3251. /*
  3252. * Common symbol display for cmd_sym().
  3253. */
  3254. void
  3255. show_symbol(struct syment *sp, ulong offset, ulong show_flags)
  3256. {
  3257. char buf[BUFSIZE];
  3258. char *p1;
  3259. ulong radix;
  3260. struct load_module *lm;
  3261. lm = NULL;
  3262. if (CRASHDEBUG(1))
  3263. show_flags |= SHOW_LINENUM;
  3264. switch (show_flags & (SHOW_HEX_OFFS|SHOW_DEC_OFFS))
  3265. {
  3266. case SHOW_DEC_OFFS:
  3267. radix = 10;
  3268. break;
  3269. default:
  3270. case SHOW_HEX_OFFS:
  3271. radix = 16;
  3272. break;
  3273. }
  3274. if (MODULE_START(sp)) {
  3275. p1 = sp->name + strlen("_MODULE_START_");
  3276. fprintf(fp, "%lx (%c) (%s module)", sp->value, sp->type, p1);
  3277. if (offset)
  3278. fprintf(fp, (radix == 16) ? "+0x%lx" : "+%ld",
  3279. offset);
  3280. fprintf(fp, "\n");
  3281. return;
  3282. } else if (show_flags & SHOW_MODULE)
  3283. module_symbol(sp->value, NULL, &lm, NULL, 0);
  3284. if (offset)
  3285. fprintf(fp, (radix == 16) ?
  3286. "%lx (%c) %s+0x%lx" : "%lx (%c) %s+%ld",
  3287. sp->value+offset, sp->type, sp->name, offset);
  3288. else
  3289. fprintf(fp, "%lx (%c) %s", sp->value, sp->type, sp->name);
  3290. if (lm)
  3291. fprintf(fp, " [%s]", lm->mod_name);
  3292. if (is_kernel_text(sp->value+offset) &&
  3293. (show_flags & SHOW_LINENUM))
  3294. fprintf(fp, " %s",
  3295. get_line_number(sp->value+offset, buf, TRUE));
  3296. if (show_flags & SHOW_SECTION)
  3297. fprintf(fp, " [%s]", get_section(sp->value+offset, buf));
  3298. fprintf(fp, "\n");
  3299. }
  3300. /*
  3301. * Use the gdb_interface to get a line number associated with a
  3302. * text address -- but first check whether the address gets past
  3303. * any machine-dependent line_number_hooks reference.
  3304. */
  3305. char *
  3306. get_line_number(ulong addr, char *buf, int reserved)
  3307. {
  3308. char *p;
  3309. struct gnu_request request, *req;
  3310. struct line_number_hook *lnh;
  3311. struct syment *sp;
  3312. char bldbuf[BUFSIZE], *name;
  3313. struct load_module *lm;
  3314. buf[0] = NULLCHAR;
  3315. if (NO_LINE_NUMBERS() || !is_kernel_text(addr))
  3316. return(buf);
  3317. if (module_symbol(addr, NULL, &lm, NULL, 0)) {
  3318. if (!(lm->mod_flags & MOD_LOAD_SYMS))
  3319. return(buf);
  3320. } else if (kt->flags2 & KASLR)
  3321. addr -= (kt->relocate * -1);
  3322. if ((lnh = machdep->line_number_hooks)) {
  3323. name = closest_symbol(addr);
  3324. while (lnh->func) {
  3325. if (STREQ(name, lnh->func)) {
  3326. sprintf(buf, "%s/%s",
  3327. get_build_directory(bldbuf) ?
  3328. bldbuf : "..", *(lnh->file));
  3329. break;
  3330. }
  3331. lnh++;
  3332. }
  3333. }
  3334. if (!strlen(buf)) {
  3335. req = &request;
  3336. BZERO(req, sizeof(struct gnu_request));
  3337. req->command = GNU_GET_LINE_NUMBER;
  3338. req->addr = addr;
  3339. req->buf = buf;
  3340. if ((sp = value_search(addr, NULL)))
  3341. req->name = sp->name;
  3342. gdb_interface(req);
  3343. }
  3344. while ((p = strstr(buf, "//")))
  3345. shift_string_left(p+1, 1);
  3346. return(buf);
  3347. }
  3348. static char *
  3349. get_section(ulong vaddr, char *buf)
  3350. {
  3351. int i;
  3352. asection **sec;
  3353. asection *section;
  3354. ulong start, end;
  3355. struct load_module *lm;
  3356. buf[0] = NULLCHAR;
  3357. if (module_symbol(vaddr, NULL, &lm, NULL, *gdb_output_radix)) {
  3358. if (lm->mod_flags & MOD_LOAD_SYMS) {
  3359. for (i = (lm->mod_sections-1); i >= 0; i--) {
  3360. start = lm->mod_base +
  3361. lm->mod_section_data[i].offset;
  3362. end = start + lm->mod_section_data[i].size;
  3363. if ((vaddr >= start) && (vaddr < end)) {
  3364. strcpy(buf,
  3365. lm->mod_section_data[i].name);
  3366. break;
  3367. }
  3368. }
  3369. } else
  3370. sprintf(buf, "in %s module", lm->mod_name);
  3371. } else {
  3372. sec = (asection **)st->sections;
  3373. for (i = 0; i < st->bfd->section_count; i++, sec++) {
  3374. section = *sec;
  3375. start = (ulong)bfd_get_section_vma(st->bfd, section);
  3376. end = start + (ulong)bfd_section_size(st->bfd, section);
  3377. if ((vaddr >= start) && (vaddr < end)) {
  3378. strcpy(buf, bfd_get_section_name(st->bfd,
  3379. section));
  3380. break;
  3381. }
  3382. }
  3383. }
  3384. return buf;
  3385. }
  3386. /*
  3387. * Get the kernel build directory.
  3388. */
  3389. char *
  3390. get_build_directory(char *buf)
  3391. {
  3392. char *p;
  3393. if (symbol_exists("schedule"))
  3394. get_line_number(symbol_value("schedule"), buf, FALSE);
  3395. else if (symbol_exists("do_schedule"))
  3396. get_line_number(symbol_value("do_schedule"), buf, FALSE);
  3397. else
  3398. return NULL;
  3399. if ((p = strstr(buf, "/kernel/")))
  3400. *p = NULLCHAR;
  3401. else
  3402. return(NULL);
  3403. return buf;
  3404. }
  3405. /*
  3406. * Search for all symbols containing a string.
  3407. */
  3408. int
  3409. symbol_query(char *s, char *print_pad, struct syment **spp)
  3410. {
  3411. int i;
  3412. struct syment *sp, *sp_end;
  3413. struct load_module *lm;
  3414. int cnt, search_init;
  3415. cnt = 0;
  3416. for (sp = st->symtable; sp < st->symend; sp++) {
  3417. if (strstr(sp->name, s)) {
  3418. if (print_pad) {
  3419. if (strlen(print_pad))
  3420. fprintf(fp, "%s", print_pad);
  3421. show_symbol(sp, 0, SHOW_RADIX());
  3422. }
  3423. if (spp)
  3424. *spp = sp;
  3425. cnt++;
  3426. }
  3427. }
  3428. search_init = FALSE;
  3429. for (i = 0; i < st->mods_installed; i++) {
  3430. lm = &st->load_modules[i];
  3431. if (lm->mod_flags & MOD_INIT)
  3432. search_init = TRUE;
  3433. sp = lm->mod_symtable;
  3434. sp_end = lm->mod_symend;
  3435. for ( ; sp < sp_end; sp++) {
  3436. if (MODULE_START(sp))
  3437. continue;
  3438. if (strstr(sp->name, s)) {
  3439. if (print_pad) {
  3440. if (strlen(print_pad))
  3441. fprintf(fp, "%s", print_pad);
  3442. show_symbol(sp, 0,
  3443. SHOW_RADIX()|SHOW_MODULE);
  3444. }
  3445. if (spp)
  3446. *spp = sp;
  3447. cnt++;
  3448. }
  3449. }
  3450. }
  3451. if (!search_init)
  3452. return(cnt);
  3453. for (i = 0; i < st->mods_installed; i++) {
  3454. lm = &st->load_modules[i];
  3455. if (!lm->mod_init_symtable)
  3456. continue;
  3457. sp = lm->mod_init_symtable;
  3458. sp_end = lm->mod_init_symend;
  3459. for ( ; sp < sp_end; sp++) {
  3460. if (MODULE_START(sp))
  3461. continue;
  3462. if (strstr(sp->name, s)) {
  3463. if (print_pad) {
  3464. if (strlen(print_pad))
  3465. fprintf(fp, "%s", print_pad);
  3466. show_symbol(sp, 0,
  3467. SHOW_RADIX()|SHOW_MODULE);
  3468. }
  3469. if (spp)
  3470. *spp = sp;
  3471. cnt++;
  3472. }
  3473. }
  3474. }
  3475. return(cnt);
  3476. }
  3477. /*
  3478. * Return the syment of a symbol.
  3479. */
  3480. struct syment *
  3481. symbol_search(char *s)
  3482. {
  3483. int i;
  3484. struct syment *sp_hashed, *sp, *sp_end;
  3485. struct load_module *lm;
  3486. int pseudos, search_init;
  3487. sp_hashed = symname_hash_search(s);
  3488. for (sp = sp_hashed ? sp_hashed : st->symtable; sp < st->symend; sp++) {
  3489. if (STREQ(s, sp->name))
  3490. return(sp);
  3491. }
  3492. pseudos = (strstr(s, "_MODULE_START_") || strstr(s, "_MODULE_END_"));
  3493. search_init = FALSE;
  3494. for (i = 0; i < st->mods_installed; i++) {
  3495. lm = &st->load_modules[i];
  3496. if (lm->mod_flags & MOD_INIT)
  3497. search_init = TRUE;
  3498. sp = lm->mod_symtable;
  3499. sp_end = lm->mod_symend;
  3500. for ( ; sp <= sp_end; sp++) {
  3501. if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
  3502. continue;
  3503. if (STREQ(s, sp->name))
  3504. return(sp);
  3505. }
  3506. }
  3507. if (!search_init)
  3508. return((struct syment *)NULL);
  3509. pseudos = (strstr(s, "_MODULE_INIT_START_") || strstr(s, "_MODULE_INIT_END_"));
  3510. for (i = 0; i < st->mods_installed; i++) {
  3511. lm = &st->load_modules[i];
  3512. if (!lm->mod_init_symtable)
  3513. continue;
  3514. sp = lm->mod_init_symtable;
  3515. sp_end = lm->mod_init_symend;
  3516. for ( ; sp < sp_end; sp++) {
  3517. if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
  3518. continue;
  3519. if (STREQ(s, sp->name))
  3520. return(sp);
  3521. }
  3522. }
  3523. return((struct syment *)NULL);
  3524. }
  3525. /*
  3526. * Count the number of instances of a symbol name.
  3527. */
  3528. static int
  3529. symbol_name_count(char *s)
  3530. {
  3531. int i;
  3532. struct syment *sp, *sp_end;
  3533. struct load_module *lm;
  3534. int count, pseudos, search_init;
  3535. count = 0;
  3536. for (sp = st->symtable; sp < st->symend; sp++) {
  3537. if (STREQ(s, sp->name)) {
  3538. count = sp->cnt;
  3539. break;
  3540. }
  3541. }
  3542. pseudos = (strstr(s, "_MODULE_START_") || strstr(s, "_MODULE_END_"));
  3543. search_init = FALSE;
  3544. for (i = 0; i < st->mods_installed; i++) {
  3545. lm = &st->load_modules[i];
  3546. if (lm->mod_flags & MOD_INIT)
  3547. search_init = TRUE;
  3548. sp = lm->mod_symtable;
  3549. sp_end = lm->mod_symend;
  3550. for ( ; sp < sp_end; sp++) {
  3551. if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
  3552. continue;
  3553. if (STREQ(s, sp->name))
  3554. count++;
  3555. }
  3556. }
  3557. if (!search_init)
  3558. return(count);
  3559. pseudos = (strstr(s, "_MODULE_INIT_START_") || strstr(s, "_MODULE_INIT_END_"));
  3560. for (i = 0; i < st->mods_installed; i++) {
  3561. lm = &st->load_modules[i];
  3562. if (!lm->mod_init_symtable)
  3563. continue;
  3564. sp = lm->mod_init_symtable;
  3565. sp_end = lm->mod_init_symend;
  3566. for ( ; sp < sp_end; sp++) {
  3567. if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
  3568. continue;
  3569. if (STREQ(s, sp->name))
  3570. count++;
  3571. }
  3572. }
  3573. return(count);
  3574. }
  3575. /*
  3576. * Return the syment of the next symbol with the same name of the input symbol.
  3577. */
  3578. struct syment *
  3579. symbol_search_next(char *s, struct syment *spstart)
  3580. {
  3581. int i;
  3582. struct syment *sp, *sp_end;
  3583. struct load_module *lm;
  3584. int found_start;
  3585. int pseudos, search_init;
  3586. found_start = FALSE;
  3587. for (sp = st->symtable; sp < st->symend; sp++) {
  3588. if (sp == spstart) {
  3589. found_start = TRUE;
  3590. continue;
  3591. } else if (!found_start)
  3592. continue;
  3593. if (strcmp(s, sp->name) == 0) {
  3594. return(sp);
  3595. }
  3596. }
  3597. pseudos = (strstr(s, "_MODULE_START_") || strstr(s, "_MODULE_END_"));
  3598. search_init = FALSE;
  3599. for (i = 0; i < st->mods_installed; i++) {
  3600. lm = &st->load_modules[i];
  3601. if (lm->mod_flags & MOD_INIT)
  3602. search_init = TRUE;
  3603. sp = lm->mod_symtable;
  3604. sp_end = lm->mod_symend;
  3605. for ( ; sp < sp_end; sp++) {
  3606. if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
  3607. continue;
  3608. if (sp == spstart) {
  3609. found_start = TRUE;
  3610. continue;
  3611. } else if (!found_start)
  3612. continue;
  3613. if (STREQ(s, sp->name))
  3614. return(sp);
  3615. }
  3616. }
  3617. if (!search_init)
  3618. return((struct syment *)NULL);
  3619. pseudos = (strstr(s, "_MODULE_INIT_START_") || strstr(s, "_MODULE_INIT_END_"));
  3620. for (i = 0; i < st->mods_installed; i++) {
  3621. lm = &st->load_modules[i];
  3622. if (!lm->mod_init_symtable)
  3623. continue;
  3624. sp = lm->mod_init_symtable;
  3625. sp_end = lm->mod_init_symend;
  3626. for ( ; sp < sp_end; sp++) {
  3627. if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
  3628. continue;
  3629. if (sp == spstart) {
  3630. found_start = TRUE;
  3631. continue;
  3632. } else if (!found_start)
  3633. continue;
  3634. if (STREQ(s, sp->name))
  3635. return(sp);
  3636. }
  3637. }
  3638. return((struct syment *)NULL);
  3639. }
  3640. /*
  3641. * Determine whether an address falls within the kernel's, or any module's,
  3642. * address space.
  3643. */
  3644. int
  3645. in_ksymbol_range(ulong value)
  3646. {
  3647. if ((value >= st->symtable[0].value) &&
  3648. (value <= st->symtable[st->symcnt-1].value)) {
  3649. if ((st->flags & PERCPU_SYMS) && (value < st->first_ksymbol))
  3650. return FALSE;
  3651. else
  3652. return TRUE;
  3653. }
  3654. if (module_symbol(value, NULL, NULL, NULL, *gdb_output_radix))
  3655. return TRUE;
  3656. if (machdep->value_to_symbol(value, NULL))
  3657. return TRUE;
  3658. return FALSE;
  3659. }
  3660. /*
  3661. * Determine whether an address falls within any module's address space.
  3662. * If syment or load_module pointers are passed, send them back.
  3663. * If a pointer to a name buffer is passed, stuff it with the particulars.
  3664. */
  3665. int
  3666. module_symbol(ulong value,
  3667. struct syment **spp,
  3668. struct load_module **lmp,
  3669. char *name,
  3670. ulong radix)
  3671. {
  3672. int i;
  3673. struct load_module *lm;
  3674. struct syment *sp;
  3675. char buf[BUFSIZE];
  3676. ulong offs, offset;
  3677. ulong base, end;
  3678. if (NO_MODULES())
  3679. return FALSE;
  3680. if (!radix)
  3681. radix = *gdb_output_radix;
  3682. if ((radix != 10) && (radix != 16))
  3683. radix = 16;
  3684. for (i = 0; i < st->mods_installed; i++) {
  3685. lm = &st->load_modules[i];
  3686. if (IN_MODULE(value, lm)) {
  3687. base = lm->mod_base;
  3688. end = lm->mod_base + lm->mod_size;
  3689. } else if (IN_MODULE_INIT(value, lm)) {
  3690. base = lm->mod_init_module_ptr;
  3691. end = lm->mod_init_module_ptr + lm->mod_init_size;
  3692. } else if (IN_MODULE_PERCPU(value, lm)) {
  3693. base = lm->mod_percpu;
  3694. end = lm->mod_percpu + lm->mod_percpu_size;
  3695. } else
  3696. continue;
  3697. if ((value >= base) && (value < end)) {
  3698. if (lmp)
  3699. *lmp = lm;
  3700. if (name) {
  3701. offs = value - base;
  3702. if ((sp = value_search(value, &offset))) {
  3703. if (offset)
  3704. sprintf(buf, radix == 16 ?
  3705. "%s+0x%lx" : "%s+%ld",
  3706. sp->name, offset);
  3707. else
  3708. sprintf(buf, "%s", sp->name);
  3709. strcpy(name, buf);
  3710. if (spp)
  3711. *spp = sp;
  3712. return TRUE;
  3713. }
  3714. sprintf(name, "(%s module)", lm->mod_name);
  3715. if (offs) {
  3716. sprintf(buf, radix == 16 ?
  3717. "+0x%lx" : "+%ld", offs);
  3718. strcat(name, buf);
  3719. }
  3720. }
  3721. return TRUE;
  3722. }
  3723. }
  3724. return FALSE;
  3725. }
  3726. struct syment *
  3727. value_search_module(ulong value, ulong *offset)
  3728. {
  3729. int i;
  3730. struct syment *sp, *sp_end, *spnext, *splast;
  3731. struct load_module *lm;
  3732. int search_init_sections, search_init;
  3733. search_init = FALSE;
  3734. search_init_sections = 0;
  3735. for (i = 0; i < st->mods_installed; i++) {
  3736. if (st->load_modules[i].mod_flags & MOD_INIT)
  3737. search_init_sections++;
  3738. }
  3739. retry:
  3740. for (i = 0; i < st->mods_installed; i++) {
  3741. lm = &st->load_modules[i];
  3742. if (search_init) {
  3743. if (lm->mod_init_symtable) {
  3744. sp = lm->mod_init_symtable;
  3745. sp_end = lm->mod_init_symend;
  3746. } else
  3747. continue;
  3748. } else {
  3749. sp = lm->mod_symtable;
  3750. sp_end = lm->mod_symend;
  3751. }
  3752. if (sp->value > value) /* invalid -- between modules */
  3753. break;
  3754. /*
  3755. * splast will contain the last module symbol encountered.
  3756. * Note: "__insmod_"-type symbols will be set in splast only
  3757. * when they have unique values.
  3758. */
  3759. splast = NULL;
  3760. for ( ; sp <= sp_end; sp++) {
  3761. if (value == sp->value) {
  3762. if (MODULE_END(sp) || MODULE_INIT_END(sp))
  3763. break;
  3764. if (MODULE_PSEUDO_SYMBOL(sp)) {
  3765. spnext = sp + 1;
  3766. if (MODULE_PSEUDO_SYMBOL(spnext))
  3767. continue;
  3768. if (spnext->value == value)
  3769. sp = spnext;
  3770. }
  3771. if (is_insmod_builtin(lm, sp)) {
  3772. spnext = sp+1;
  3773. if ((spnext < sp_end) &&
  3774. (value == spnext->value))
  3775. sp = spnext;
  3776. }
  3777. if (sp->name[0] == '.') {
  3778. spnext = sp+1;
  3779. if (spnext->value == value)
  3780. sp = spnext;
  3781. }
  3782. if (offset)
  3783. *offset = 0;
  3784. return((struct syment *)sp);
  3785. }
  3786. if (sp->value > value) {
  3787. sp = splast ? splast : sp - 1;
  3788. if (offset)
  3789. *offset = value - sp->value;
  3790. return(sp);
  3791. }
  3792. if (!MODULE_PSEUDO_SYMBOL(sp)) {
  3793. if (is_insmod_builtin(lm, sp)) {
  3794. if (!splast ||
  3795. (sp->value > splast->value))
  3796. splast = sp;
  3797. } else
  3798. splast = sp;
  3799. }
  3800. }
  3801. }
  3802. if (search_init_sections) {
  3803. if (!search_init) {
  3804. search_init = TRUE;
  3805. goto retry;
  3806. }
  3807. }
  3808. return((struct syment *)NULL);
  3809. }
  3810. /*
  3811. * Return the syment of the symbol closest to the value, along with
  3812. * the offset from the symbol value if requested.
  3813. */
  3814. struct syment *
  3815. value_search(ulong value, ulong *offset)
  3816. {
  3817. struct syment *sp, *spnext;
  3818. if (!in_ksymbol_range(value))
  3819. return((struct syment *)NULL);
  3820. if ((sp = machdep->value_to_symbol(value, offset)))
  3821. return sp;
  3822. if (IS_VMALLOC_ADDR(value))
  3823. goto check_modules;
  3824. if ((sp = symval_hash_search(value)) == NULL)
  3825. sp = st->symtable;
  3826. for ( ; sp < st->symend; sp++) {
  3827. if (value == sp->value) {
  3828. #if !defined(GDB_5_3) && !defined(GDB_6_0) && !defined(GDB_6_1)
  3829. if (STRNEQ(sp->name, ".text.")) {
  3830. spnext = sp+1;
  3831. if (spnext->value == value)
  3832. sp = spnext;
  3833. }
  3834. #endif
  3835. if (offset)
  3836. *offset = 0;
  3837. /*
  3838. * Avoid "SyS" and "compat_SyS" kernel syscall
  3839. * aliases by returning the real symbol name,
  3840. * which is the next symbol in the list.
  3841. */
  3842. if ((STRNEQ(sp->name, "SyS_") ||
  3843. STRNEQ(sp->name, "compat_SyS_")) &&
  3844. ((spnext = sp+1) < st->symend) &&
  3845. (spnext->value == value))
  3846. sp = spnext;
  3847. return((struct syment *)sp);
  3848. }
  3849. if (sp->value > value) {
  3850. if (offset)
  3851. *offset = value - ((sp-1)->value);
  3852. return((struct syment *)(sp-1));
  3853. }
  3854. }
  3855. check_modules:
  3856. sp = value_search_module(value, offset);
  3857. return sp;
  3858. }
  3859. ulong
  3860. highest_bss_symbol(void)
  3861. {
  3862. struct syment *sp;
  3863. ulong highest = 0;
  3864. for (sp = st->symtable; sp < st->symend; sp++) {
  3865. if ((sp->type == 'b') || (sp->type == 'B')) {
  3866. if (sp->value > highest)
  3867. highest = sp->value;
  3868. }
  3869. }
  3870. return highest;
  3871. }
  3872. /*
  3873. * Search for a value only within the base kernel's symbols,
  3874. * also avoiding the machdep->value_to_symbol() call, which will
  3875. * most likely be the prime consumer of this call.
  3876. */
  3877. struct syment *
  3878. value_search_base_kernel(ulong value, ulong *offset)
  3879. {
  3880. struct syment *sp;
  3881. if (value < st->symtable[0].value)
  3882. return((struct syment *)NULL);
  3883. if ((sp = symval_hash_search(value)) == NULL)
  3884. sp = st->symtable;
  3885. for ( ; sp < st->symend; sp++) {
  3886. if (value == sp->value) {
  3887. if (offset)
  3888. *offset = 0;
  3889. return((struct syment *)sp);
  3890. }
  3891. if (sp->value > value) {
  3892. if (offset)
  3893. *offset = value - ((sp-1)->value);
  3894. return((struct syment *)(sp-1));
  3895. }
  3896. }
  3897. /*
  3898. * If we go off the end, just use the last symbol plus offset.
  3899. */
  3900. sp = st->symend;
  3901. if (offset)
  3902. *offset = value - ((sp-1)->value);
  3903. return((struct syment *)(sp-1));
  3904. }
  3905. /*
  3906. * Allow platforms to assign symbols to their own special values.
  3907. */
  3908. struct syment *
  3909. generic_machdep_value_to_symbol(ulong value, ulong *offset)
  3910. {
  3911. return NULL;
  3912. }
  3913. /*
  3914. * For a given value, format a string containing the nearest symbol name
  3915. * plus the offset if appropriate. Display the offset in the specified
  3916. * radix (10 or 16) -- if it's 0, set it to the current pc->output_radix.
  3917. */
  3918. char *
  3919. value_to_symstr(ulong value, char *buf, ulong radix)
  3920. {
  3921. struct syment *sp;
  3922. ulong offset;
  3923. char *p1, locbuf[BUFSIZE];
  3924. struct load_module *lm;
  3925. sp = NULL;
  3926. offset = 0;
  3927. buf[0] = NULLCHAR;
  3928. if (!radix)
  3929. radix = *gdb_output_radix;
  3930. if ((radix != 10) && (radix != 16))
  3931. radix = 16;
  3932. if ((sp = value_search(value, &offset))) {
  3933. if (offset)
  3934. sprintf(buf, radix == 16 ? "%s+0x%lx" : "%s+%ld",
  3935. sp->name, offset);
  3936. else
  3937. sprintf(buf, "%s", sp->name);
  3938. }
  3939. if (module_symbol(value, NULL, NULL, locbuf, *gdb_output_radix)) {
  3940. if (sp) {
  3941. if (STRNEQ(locbuf, "_MODULE_START_"))
  3942. shift_string_left(locbuf,
  3943. strlen("_MODULE_START_"));
  3944. if ((p1 = strstr(locbuf, "+")))
  3945. *p1 = NULLCHAR;
  3946. if (offset) {
  3947. if (is_module_name(locbuf, NULL, &lm) &&
  3948. (value < lm->mod_text_start))
  3949. sprintf(buf, radix == 16 ?
  3950. "(%s module)+0x%lx" :
  3951. "(%s module)+%ld",
  3952. locbuf, offset);
  3953. else
  3954. sprintf(buf, radix == 16 ?
  3955. "%s+0x%lx" : "%s+%ld",
  3956. locbuf, offset);
  3957. } else {
  3958. if (is_module_name(locbuf, NULL, &lm) &&
  3959. (value < lm->mod_text_start))
  3960. sprintf(buf, "(%s)", locbuf);
  3961. else
  3962. sprintf(buf, "%s", locbuf);
  3963. }
  3964. } else
  3965. sprintf(buf, "%s", locbuf);
  3966. }
  3967. return(buf);
  3968. }
  3969. /*
  3970. * For a given value, return the closest (lower-in-value) symbol name.
  3971. */
  3972. char *
  3973. closest_symbol(ulong value)
  3974. {
  3975. struct syment *sp;
  3976. if ((sp = value_search(value, NULL)))
  3977. return(sp->name);
  3978. else
  3979. return(NULL);
  3980. }
  3981. /*
  3982. * Same as above, but return the closest (lower-in-value) symbol value.
  3983. */
  3984. ulong
  3985. closest_symbol_value(ulong value)
  3986. {
  3987. struct syment *sp;
  3988. if ((sp = value_search(value, NULL)))
  3989. return(sp->value);
  3990. else
  3991. return(0);
  3992. }
  3993. /*
  3994. * For a given symbol, return a pointer to the next (higher) symbol's syment.
  3995. * Either a symbol name or syment pointer may be passed as an argument.
  3996. */
  3997. struct syment *
  3998. next_symbol(char *symbol, struct syment *sp_in)
  3999. {
  4000. int i;
  4001. int found, search_init;
  4002. struct syment *sp, *sp_end;
  4003. struct load_module *lm;
  4004. char buf[BUFSIZE], *p1;
  4005. if (!symbol && !sp_in)
  4006. error(FATAL, "next_symbol: two NULL args!\n");
  4007. if (sp_in) {
  4008. found = FALSE;
  4009. for (sp = st->symtable; sp < st->symend; sp++) {
  4010. if (sp == sp_in)
  4011. found = TRUE;
  4012. else if (found) {
  4013. if (sp->value > sp_in->value)
  4014. return sp;
  4015. }
  4016. }
  4017. search_init = FALSE;
  4018. for (i = 0; i < st->mods_installed; i++) {
  4019. lm = &st->load_modules[i];
  4020. if (lm->mod_flags & MOD_INIT)
  4021. search_init = TRUE;
  4022. sp = lm->mod_symtable;
  4023. sp_end = lm->mod_symend;
  4024. for ( ; sp < sp_end; sp++) {
  4025. if (MODULE_PSEUDO_SYMBOL(sp))
  4026. continue;
  4027. if (sp == sp_in)
  4028. found = TRUE;
  4029. else if (found) {
  4030. if ((sp->value == sp_in->value) &&
  4031. is_insmod_builtin(lm, sp))
  4032. continue;
  4033. return sp;
  4034. }
  4035. }
  4036. }
  4037. for (i = 0; search_init && (i < st->mods_installed); i++) {
  4038. lm = &st->load_modules[i];
  4039. if (!lm->mod_init_symtable)
  4040. continue;
  4041. sp = lm->mod_init_symtable;
  4042. sp_end = lm->mod_init_symend;
  4043. for ( ; sp < sp_end; sp++) {
  4044. if (MODULE_PSEUDO_SYMBOL(sp))
  4045. continue;
  4046. if (sp == sp_in)
  4047. found = TRUE;
  4048. else if (found)
  4049. return sp;
  4050. }
  4051. }
  4052. return NULL;
  4053. }
  4054. /*
  4055. * Deal with a few special cases...
  4056. */
  4057. if (strstr(symbol, " module)")) {
  4058. sprintf(buf, "_MODULE_START_");
  4059. strcat(buf, &symbol[1]);
  4060. p1 = strstr(buf, " module)");
  4061. *p1 = NULLCHAR;
  4062. symbol = buf;
  4063. }
  4064. if (STREQ(symbol, "_end")) {
  4065. if (!st->mods_installed)
  4066. return NULL;
  4067. lm = &st->load_modules[0];
  4068. return lm->mod_symtable;
  4069. }
  4070. if ((sp = symbol_search(symbol))) {
  4071. sp++;
  4072. if (MODULE_END(sp)) {
  4073. sp--;
  4074. i = load_module_index(sp);
  4075. if ((i+1) == st->mods_installed)
  4076. return NULL;
  4077. lm = &st->load_modules[i+1];
  4078. sp = lm->mod_symtable;
  4079. }
  4080. return sp;
  4081. }
  4082. return NULL;
  4083. }
  4084. /*
  4085. * For a given symbol, return a pointer to the previous (lower) symbol's syment.
  4086. * Either a symbol name or syment pointer may be passed as an argument.
  4087. */
  4088. struct syment *
  4089. prev_symbol(char *symbol, struct syment *sp_in)
  4090. {
  4091. int i, search_init;
  4092. struct syment *sp, *sp_end, *sp_prev;
  4093. char buf[BUFSIZE], *p1;
  4094. struct load_module *lm;
  4095. if (!symbol && !sp_in)
  4096. error(FATAL, "prev_symbol: two NULL args!\n");
  4097. if (sp_in) {
  4098. sp_prev = NULL;
  4099. for (sp = st->symtable; sp < st->symend; sp++) {
  4100. if (sp == sp_in)
  4101. return sp_prev;
  4102. sp_prev = sp;
  4103. }
  4104. search_init = FALSE;
  4105. for (i = 0; i < st->mods_installed; i++) {
  4106. lm = &st->load_modules[i];
  4107. if (lm->mod_flags & MOD_INIT)
  4108. search_init = TRUE;
  4109. sp = lm->mod_symtable;
  4110. sp_end = lm->mod_symend;
  4111. for ( ; sp < sp_end; sp++) {
  4112. if (MODULE_PSEUDO_SYMBOL(sp))
  4113. continue;
  4114. if (sp == sp_in)
  4115. return sp_prev;
  4116. if (is_insmod_builtin(lm, sp)) {
  4117. if (sp->value > sp_prev->value)
  4118. sp_prev = sp;
  4119. } else
  4120. sp_prev = sp;
  4121. }
  4122. }
  4123. for (i = 0; search_init && (i < st->mods_installed); i++) {
  4124. lm = &st->load_modules[i];
  4125. if (!lm->mod_init_symtable)
  4126. continue;
  4127. sp = lm->mod_init_symtable;
  4128. sp_end = lm->mod_init_symend;
  4129. for ( ; sp < sp_end; sp++) {
  4130. if (MODULE_PSEUDO_SYMBOL(sp))
  4131. continue;
  4132. if (sp == sp_in)
  4133. return sp_prev;
  4134. sp_prev = sp;
  4135. }
  4136. }
  4137. return NULL;
  4138. }
  4139. if (strstr(symbol, " module)")) {
  4140. sprintf(buf, "_MODULE_START_");
  4141. strcat(buf, &symbol[1]);
  4142. p1 = strstr(buf, " module)");
  4143. *p1 = NULLCHAR;
  4144. symbol = buf;
  4145. }
  4146. if ((sp = symbol_search(symbol))) {
  4147. if (sp == st->symtable)
  4148. return((struct syment *)NULL);
  4149. if (module_symbol(sp->value, NULL, NULL, NULL, 0)) {
  4150. if (MODULE_START(sp)) {
  4151. i = load_module_index(sp);
  4152. if (i == 0)
  4153. sp = symbol_search("_end");
  4154. else {
  4155. lm = &st->load_modules[i-1];
  4156. sp = lm->mod_symend;
  4157. sp--;
  4158. }
  4159. } else
  4160. sp--;
  4161. } else
  4162. sp--;
  4163. return sp;
  4164. }
  4165. return NULL;
  4166. }
  4167. /*
  4168. * Read the specified amount of data from the given symbol's value.
  4169. */
  4170. void
  4171. get_symbol_data(char *symbol, long size, void *local)
  4172. {
  4173. struct syment *sp;
  4174. if ((sp = symbol_search(symbol)))
  4175. readmem(sp->value, KVADDR, local,
  4176. size, symbol, FAULT_ON_ERROR);
  4177. else
  4178. error(FATAL, "cannot resolve: \"%s\"\n", symbol);
  4179. }
  4180. /*
  4181. * Same as above, but allow for failure.
  4182. */
  4183. int
  4184. try_get_symbol_data(char *symbol, long size, void *local)
  4185. {
  4186. struct syment *sp;
  4187. if ((sp = symbol_search(symbol)) &&
  4188. readmem(sp->value, KVADDR, local,
  4189. size, symbol, RETURN_ON_ERROR|QUIET))
  4190. return TRUE;
  4191. return FALSE;
  4192. }
  4193. /*
  4194. * Return the value of a given symbol.
  4195. */
  4196. ulong
  4197. symbol_value(char *symbol)
  4198. {
  4199. struct syment *sp;
  4200. if (!(sp = symbol_search(symbol)))
  4201. error(FATAL, "cannot resolve \"%s\"\n", symbol);
  4202. return(sp->value);
  4203. }
  4204. /*
  4205. * Return the value of a symbol from a specific module.
  4206. */
  4207. ulong
  4208. symbol_value_module(char *symbol, char *module)
  4209. {
  4210. int i;
  4211. struct syment *sp, *sp_end;
  4212. struct load_module *lm;
  4213. for (i = 0; i < st->mods_installed; i++) {
  4214. lm = &st->load_modules[i];
  4215. if (!STREQ(module, lm->mod_name))
  4216. continue;
  4217. sp = lm->mod_symtable;
  4218. sp_end = lm->mod_symend;
  4219. for ( ; sp < sp_end; sp++) {
  4220. if (STREQ(symbol, sp->name))
  4221. return(sp->value);
  4222. }
  4223. if (lm->mod_init_symtable) {
  4224. sp = lm->mod_init_symtable;
  4225. sp_end = lm->mod_init_symend;
  4226. for ( ; sp < sp_end; sp++) {
  4227. if (STREQ(symbol, sp->name))
  4228. return(sp->value);
  4229. }
  4230. }
  4231. }
  4232. return 0;
  4233. }
  4234. /*
  4235. * Return the symbol name of a given value, with no allowance for offsets.
  4236. * Returns NULL on failure to allow for testing of a value.
  4237. */
  4238. char *
  4239. value_symbol(ulong value)
  4240. {
  4241. struct syment *sp;
  4242. ulong offset;
  4243. if ((sp = value_search(value, &offset))) {
  4244. if (offset)
  4245. return NULL;
  4246. else
  4247. return sp->name;
  4248. }
  4249. return NULL;
  4250. }
  4251. /*
  4252. * Determine whether a symbol exists.
  4253. */
  4254. int
  4255. symbol_exists(char *symbol)
  4256. {
  4257. int i;
  4258. struct syment *sp, *sp_end;
  4259. struct load_module *lm;
  4260. if ((sp = symname_hash_search(symbol)))
  4261. return TRUE;
  4262. for (i = 0; i < st->mods_installed; i++) {
  4263. lm = &st->load_modules[i];
  4264. sp = lm->mod_symtable;
  4265. sp_end = lm->mod_symend;
  4266. for ( ; sp < sp_end; sp++) {
  4267. if (STREQ(symbol, sp->name))
  4268. return(TRUE);
  4269. }
  4270. if (lm->mod_init_symtable) {
  4271. sp = lm->mod_init_symtable;
  4272. sp_end = lm->mod_init_symend;
  4273. for ( ; sp < sp_end; sp++) {
  4274. if (STREQ(symbol, sp->name))
  4275. return(TRUE);
  4276. }
  4277. }
  4278. }
  4279. return(FALSE);
  4280. }
  4281. /*
  4282. * Determine whether a per-cpu symbol exists.
  4283. * The old-style per-cpu symbol names were pre-pended with
  4284. * "per_cpu__", whereas the new-style ones (as of 2.6.34)
  4285. * are not. This function allows the symbol argument to
  4286. * use either the old- or new-sytle format, and find either
  4287. * type.
  4288. */
  4289. struct syment *
  4290. per_cpu_symbol_search(char *symbol)
  4291. {
  4292. struct syment *sp;
  4293. char old[BUFSIZE];
  4294. char *new;
  4295. if (STRNEQ(symbol, "per_cpu__")) {
  4296. if ((sp = symbol_search(symbol)))
  4297. return sp;
  4298. new = symbol + strlen("per_cpu__");
  4299. if ((sp = symbol_search(new))) {
  4300. if ((sp->type == 'V') || (is_percpu_symbol(sp)))
  4301. return sp;
  4302. if ((sp->type == 'd') &&
  4303. (st->__per_cpu_start == st->__per_cpu_end))
  4304. return sp;
  4305. }
  4306. } else {
  4307. if ((sp = symbol_search(symbol))) {
  4308. if ((sp->type == 'V') || (is_percpu_symbol(sp)))
  4309. return sp;
  4310. }
  4311. sprintf(old, "per_cpu__%s", symbol);
  4312. if ((sp = symbol_search(old)))
  4313. return sp;
  4314. }
  4315. if (CRASHDEBUG(1))
  4316. error(INFO, "per_cpu_symbol_search(%s): NULL\n", symbol);
  4317. return NULL;
  4318. }
  4319. /*
  4320. * Determine whether a static kernel symbol exists.
  4321. */
  4322. int
  4323. kernel_symbol_exists(char *symbol)
  4324. {
  4325. struct syment *sp;
  4326. if ((sp = symname_hash_search(symbol)))
  4327. return TRUE;
  4328. else
  4329. return FALSE;
  4330. }
  4331. /*
  4332. * Similar to above, but return the syment of the kernel symbol.
  4333. */
  4334. struct syment *
  4335. kernel_symbol_search(char *symbol)
  4336. {
  4337. return symname_hash_search(symbol);
  4338. }
  4339. /*
  4340. * Return the number of instances of a symbol name along with pointers to
  4341. * their syment structures.
  4342. */
  4343. int
  4344. get_syment_array(char *symbol, struct syment **sp_array, int max)
  4345. {
  4346. int i, cnt;
  4347. struct syment *sp, *sp_end;
  4348. struct load_module *lm;
  4349. cnt = 0;
  4350. for (sp = st->symtable; sp < st->symend; sp++) {
  4351. if ((*symbol == *(sp->name)) && STREQ(symbol, sp->name)) {
  4352. if (!sp_array)
  4353. return sp->cnt;
  4354. if (max) {
  4355. if (cnt == max) {
  4356. error(INFO,
  4357. "symbol count overflow (%s)\n",
  4358. symbol);
  4359. return cnt;
  4360. } else
  4361. sp_array[cnt] = sp;
  4362. }
  4363. if (sp->cnt == 1)
  4364. return 1;
  4365. cnt++;
  4366. }
  4367. }
  4368. for (i = 0; i < st->mods_installed; i++) {
  4369. lm = &st->load_modules[i];
  4370. sp = lm->mod_symtable;
  4371. sp_end = lm->mod_symend;
  4372. for ( ; sp < sp_end; sp++) {
  4373. if (STREQ(symbol, sp->name)) {
  4374. if (max && (cnt < max))
  4375. sp_array[cnt] = sp;
  4376. cnt++;
  4377. }
  4378. }
  4379. if (lm->mod_init_symtable) {
  4380. sp = lm->mod_init_symtable;
  4381. sp_end = lm->mod_init_symend;
  4382. for ( ; sp < sp_end; sp++) {
  4383. if (STREQ(symbol, sp->name)) {
  4384. if (max && (cnt < max))
  4385. sp_array[cnt] = sp;
  4386. cnt++;
  4387. }
  4388. }
  4389. }
  4390. }
  4391. return cnt;
  4392. }
  4393. /*
  4394. * Perform any datatype-related initializations here.
  4395. */
  4396. void
  4397. datatype_init(void)
  4398. {
  4399. BNEG(&offset_table, sizeof(offset_table));
  4400. BNEG(&size_table, sizeof(size_table));
  4401. BZERO(&array_table, sizeof(array_table));
  4402. }
  4403. /*
  4404. * This function is called through the following macros:
  4405. *
  4406. * #define STRUCT_SIZE(X) datatype_info((X), NULL, NULL)
  4407. * #define UNION_SIZE(X) datatype_info((X), NULL, NULL)
  4408. * #define DATATYPE_SIZE(X) datatype_info((X)->name, NULL, (X))
  4409. * #define MEMBER_OFFSET(X,Y) datatype_info((X), (Y), NULL)
  4410. * #define STRUCT_EXISTS(X) (datatype_info((X), NULL, NULL) >= 0)
  4411. * #define MEMBER_EXISTS(X,Y) (datatype_info((X), (Y), NULL) >= 0)
  4412. * #define MEMBER_SIZE(X,Y) datatype_info((X), (Y), MEMBER_SIZE_REQUEST)
  4413. * #define MEMBER_TYPE(X,Y) datatype_info((X), (Y), MEMBER_TYPE_REQUEST)
  4414. * #define ANON_MEMBER_OFFSET(X,Y) datatype_info((X), (Y), ANON_MEMBER_OFFSET_REQUEST)
  4415. *
  4416. * to determine structure or union sizes, or member offsets.
  4417. */
  4418. long
  4419. datatype_info(char *name, char *member, struct datatype_member *dm)
  4420. {
  4421. struct gnu_request *req;
  4422. long offset, size, member_size;
  4423. int member_typecode;
  4424. ulong type_found;
  4425. char buf[BUFSIZE];
  4426. if (dm == ANON_MEMBER_OFFSET_REQUEST)
  4427. return anon_member_offset(name, member);
  4428. strcpy(buf, name);
  4429. req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request));
  4430. req->command = GNU_GET_DATATYPE;
  4431. req->flags |= GNU_RETURN_ON_ERROR;
  4432. req->name = buf;
  4433. req->member = member;
  4434. req->fp = pc->nullfp;
  4435. gdb_interface(req);
  4436. if (req->flags & GNU_COMMAND_FAILED) {
  4437. FREEBUF(req);
  4438. return -1;
  4439. }
  4440. if (!req->typecode) {
  4441. sprintf(buf, "struct %s", name);
  4442. gdb_interface(req);
  4443. }
  4444. if (!req->typecode) {
  4445. sprintf(buf, "union %s", name);
  4446. gdb_interface(req);
  4447. }
  4448. member_typecode = TYPE_CODE_UNDEF;
  4449. member_size = 0;
  4450. type_found = 0;
  4451. if (CRASHDEBUG(2)) {
  4452. if (req->typecode) {
  4453. console("name: %s ", req->name);
  4454. if (member)
  4455. console("member: %s ", req->member);
  4456. console("typecode: %d%s ", req->typecode,
  4457. req->is_typedef ? " (TYPEDEF)" : "");
  4458. console("length: %ld ", req->length);
  4459. console("member_offset: %ld\n", req->member_offset);
  4460. }
  4461. else
  4462. console("%s: unknown\n", name);
  4463. }
  4464. switch (req->typecode)
  4465. {
  4466. case TYPE_CODE_STRUCT:
  4467. type_found = STRUCT_REQUEST;
  4468. size = req->length;
  4469. if (req->member_offset >= 0) {
  4470. offset = req->member_offset/BITS_PER_BYTE;
  4471. member_size = req->member_length;
  4472. member_typecode = req->member_typecode;
  4473. } else {
  4474. offset = -1;
  4475. member_size = 0;
  4476. member_typecode = TYPE_CODE_UNDEF;
  4477. }
  4478. break;
  4479. case TYPE_CODE_UNION:
  4480. type_found = UNION_REQUEST;
  4481. size = req->length;
  4482. if (req->member_offset >= 0) {
  4483. offset = req->member_offset/BITS_PER_BYTE;
  4484. member_size = req->member_length;
  4485. member_typecode = req->member_typecode;
  4486. } else {
  4487. offset = -1;
  4488. member_size = 0;
  4489. member_typecode = TYPE_CODE_UNDEF;
  4490. }
  4491. break;
  4492. case TYPE_CODE_RANGE:
  4493. case TYPE_CODE_INT:
  4494. size = req->length;
  4495. offset = 0;
  4496. switch (size)
  4497. {
  4498. case SIZEOF_64BIT:
  4499. type_found = INT64;
  4500. break;
  4501. case SIZEOF_32BIT:
  4502. type_found = INT32;
  4503. break;
  4504. case SIZEOF_16BIT:
  4505. type_found = INT16;
  4506. break;
  4507. case SIZEOF_8BIT:
  4508. type_found = INT8;
  4509. break;
  4510. }
  4511. break;
  4512. case TYPE_CODE_PTR:
  4513. size = req->length;
  4514. offset = 0;
  4515. type_found = POINTER;
  4516. break;
  4517. case TYPE_CODE_FUNC:
  4518. size = req->length;
  4519. offset = 0;
  4520. type_found = FUNCTION;
  4521. break;
  4522. case TYPE_CODE_ARRAY:
  4523. size = req->length;
  4524. offset = 0;
  4525. type_found = ARRAY;
  4526. break;
  4527. case TYPE_CODE_ENUM:
  4528. size = req->length;
  4529. offset = 0;
  4530. type_found = ENUM;
  4531. break;
  4532. default:
  4533. type_found = 0;
  4534. size = -1;
  4535. offset = -1;
  4536. break;
  4537. }
  4538. FREEBUF(req);
  4539. if (dm && (dm != MEMBER_SIZE_REQUEST) && (dm != MEMBER_TYPE_REQUEST) &&
  4540. (dm != STRUCT_SIZE_REQUEST)) {
  4541. dm->type = type_found;
  4542. dm->size = size;
  4543. dm->member_size = member_size;
  4544. dm->member_typecode = member_typecode;
  4545. dm->member_offset = offset;
  4546. if (req->is_typedef) {
  4547. dm->flags |= TYPEDEF;
  4548. }
  4549. if (req->tagname) {
  4550. dm->tagname = req->tagname;
  4551. dm->value = req->value;
  4552. }
  4553. }
  4554. if (!type_found)
  4555. return -1;
  4556. if (dm == MEMBER_SIZE_REQUEST)
  4557. return member_size;
  4558. else if (dm == MEMBER_TYPE_REQUEST)
  4559. return member_typecode;
  4560. else if (dm == STRUCT_SIZE_REQUEST) {
  4561. if ((req->typecode == TYPE_CODE_STRUCT) ||
  4562. (req->typecode == TYPE_CODE_UNION) ||
  4563. req->is_typedef)
  4564. return size;
  4565. else
  4566. return -1;
  4567. } else if (member) {
  4568. if ((req->typecode == TYPE_CODE_STRUCT) ||
  4569. (req->typecode == TYPE_CODE_UNION))
  4570. return offset;
  4571. else
  4572. return -1;
  4573. } else
  4574. return size;
  4575. }
  4576. /*
  4577. * Determine the offset of a member in an anonymous union
  4578. * in a structure or union.
  4579. */
  4580. static long
  4581. anon_member_offset(char *name, char *member)
  4582. {
  4583. char buf[BUFSIZE];
  4584. ulong value;
  4585. int type;
  4586. value = -1;
  4587. type = STRUCT_REQUEST;
  4588. sprintf(buf, "printf \"%%p\", &((struct %s *)0x0)->%s", name, member);
  4589. open_tmpfile2();
  4590. retry:
  4591. if (gdb_pass_through(buf, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
  4592. rewind(pc->tmpfile2);
  4593. if (fgets(buf, BUFSIZE, pc->tmpfile2)) {
  4594. if (hexadecimal(buf, 0))
  4595. value = htol(buf, RETURN_ON_ERROR|QUIET, NULL);
  4596. else if (STRNEQ(buf, "(nil)"))
  4597. value = 0;
  4598. }
  4599. }
  4600. if ((value == -1) && (type == STRUCT_REQUEST)) {
  4601. type = UNION_REQUEST;
  4602. sprintf(buf, "printf \"%%p\", &((union %s *)0x0)->%s", name, member);
  4603. rewind(pc->tmpfile2);
  4604. goto retry;
  4605. }
  4606. close_tmpfile2();
  4607. return value;
  4608. }
  4609. /*
  4610. * Get the basic type info for a symbol. Let the caller pass in the
  4611. * gnu_request structure to have access to the full response; in either
  4612. * case, return the type code. The member field can be used for structures
  4613. * with no type names, and if there, the member data will be filled in
  4614. * as well.
  4615. */
  4616. int
  4617. get_symbol_type(char *name, char *member, struct gnu_request *caller_req)
  4618. {
  4619. struct gnu_request *req;
  4620. int typecode;
  4621. if (!caller_req)
  4622. req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request));
  4623. else {
  4624. req = caller_req;
  4625. BZERO(req, sizeof(struct gnu_request));
  4626. }
  4627. req->command = GNU_GET_SYMBOL_TYPE;
  4628. req->name = name;
  4629. req->member = member;
  4630. req->flags = GNU_RETURN_ON_ERROR;
  4631. req->fp = pc->nullfp;
  4632. gdb_interface(req);
  4633. if (req->flags & GNU_COMMAND_FAILED)
  4634. typecode = TYPE_CODE_UNDEF;
  4635. else if (member) {
  4636. if (req->member_offset >= 0)
  4637. typecode = req->member_typecode;
  4638. else
  4639. typecode = TYPE_CODE_UNDEF;
  4640. } else
  4641. typecode = req->typecode;
  4642. if (!caller_req)
  4643. FREEBUF(req);
  4644. return(typecode);
  4645. }
  4646. int
  4647. get_symbol_length(char *symbol)
  4648. {
  4649. struct gnu_request *req;
  4650. int len;
  4651. req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request));
  4652. if (get_symbol_type(symbol, NULL, req) == TYPE_CODE_UNDEF)
  4653. error(FATAL, "cannot determine length of symbol: %s\n",
  4654. symbol);
  4655. len = (int)req->length;
  4656. FREEBUF(req);
  4657. return len;
  4658. }
  4659. /*
  4660. * Initialize the caller's restore_radix, and if valid,
  4661. * temporarily override the current output radix.
  4662. */
  4663. void
  4664. set_temporary_radix(unsigned int radix, unsigned int *restore_radix)
  4665. {
  4666. *restore_radix = *gdb_output_radix;
  4667. if ((radix == 10) || (radix == 16)) {
  4668. *gdb_output_radix = radix; \
  4669. *gdb_output_format = (*gdb_output_radix == 10) ? 0 : 'x';
  4670. }
  4671. }
  4672. /*
  4673. * Restore the output radix to the current/default value saved
  4674. * by the caller.
  4675. */
  4676. void
  4677. restore_current_radix(unsigned int restore_radix)
  4678. {
  4679. if ((restore_radix == 10) || (restore_radix == 16)) {
  4680. *gdb_output_radix = restore_radix;
  4681. *gdb_output_format = (*gdb_output_radix == 10) ? 0 : 'x';
  4682. }
  4683. }
  4684. /*
  4685. * Externally available routine to dump a structure at an address.
  4686. */
  4687. void
  4688. dump_struct(char *s, ulong addr, unsigned radix)
  4689. {
  4690. unsigned restore_radix;
  4691. long len;
  4692. restore_radix = 0;
  4693. if ((len = STRUCT_SIZE(s)) < 0)
  4694. error(FATAL, "invalid structure name: %s\n", s);
  4695. set_temporary_radix(radix, &restore_radix);
  4696. print_struct(s, addr);
  4697. restore_current_radix(restore_radix);
  4698. }
  4699. /*
  4700. * Externally available routine to dump a structure member, given the
  4701. * base structure address. The input string must be in struct.member format.
  4702. */
  4703. void
  4704. dump_struct_member(char *s, ulong addr, unsigned radix)
  4705. {
  4706. struct datatype_member datatype_member, *dm;
  4707. unsigned restore_radix;
  4708. char *buf, *p1;
  4709. restore_radix = 0;
  4710. buf = GETBUF(strlen(s)+1);
  4711. strcpy(buf, s);
  4712. p1 = strstr(buf, ".");
  4713. *p1 = NULLCHAR;
  4714. p1++;
  4715. dm = &datatype_member;
  4716. dm->name = buf;
  4717. dm->member = p1;
  4718. if (!STRUCT_EXISTS(dm->name)) {
  4719. FREEBUF(buf);
  4720. error(FATAL, "invalid structure name: %s\n", dm->name);
  4721. }
  4722. if (!MEMBER_EXISTS(dm->name, dm->member)) {
  4723. FREEBUF(buf);
  4724. error(FATAL, "invalid structure member name: %s\n",
  4725. dm->member);
  4726. }
  4727. set_temporary_radix(radix, &restore_radix);
  4728. open_tmpfile();
  4729. print_struct(dm->name, addr);
  4730. parse_for_member(dm, PARSE_FOR_DATA);
  4731. close_tmpfile();
  4732. restore_current_radix(restore_radix);
  4733. FREEBUF(buf);
  4734. }
  4735. /*
  4736. * Externally available routine to dump a union at an address.
  4737. */
  4738. void
  4739. dump_union(char *s, ulong addr, unsigned radix)
  4740. {
  4741. unsigned restore_radix;
  4742. long len;
  4743. restore_radix = 0;
  4744. if ((len = UNION_SIZE(s)) < 0)
  4745. error(FATAL, "invalid union name: %s\n", s);
  4746. set_temporary_radix(radix, &restore_radix);
  4747. print_union(s, addr);
  4748. restore_current_radix(restore_radix);
  4749. }
  4750. /*
  4751. * This command displays either a structure definition, or a formatted display
  4752. * of the contents of a structure at a specified address. If no address is
  4753. * specified, the structure size and the file in which the structure is defined
  4754. * are also displayed. A structure member may be appended to the structure
  4755. * name (in a "struct.member" format) in order to limit the scope of the data
  4756. * displayed to that particular member. Structure data is shown in hexadecimal
  4757. * format. The raw data in a structure may be dumped with the -r flag.
  4758. */
  4759. void
  4760. cmd_struct(void)
  4761. {
  4762. cmd_datatype_common(STRUCT_REQUEST);
  4763. }
  4764. /*
  4765. * This command displays either a union definition, or a formatted display
  4766. * of the contents of a union at a specified address. If no address is
  4767. * specified, the union size and the file in which the union is defined
  4768. * are also displayed. A union member may be appended to the union
  4769. * name (in a "union.member" format) in order to limit the scope of the data
  4770. * displayed to that particular member. Structure data is shown in hexadecimal
  4771. * format. The raw data in a union may be dumped with the -r flag.
  4772. */
  4773. void
  4774. cmd_union(void)
  4775. {
  4776. cmd_datatype_common(UNION_REQUEST);
  4777. }
  4778. /*
  4779. * After determining what type of data type follows the *, this routine
  4780. * has the identical functionality as cmd_struct() or cmd_union().
  4781. */
  4782. void
  4783. cmd_pointer(void)
  4784. {
  4785. cmd_datatype_common(0);
  4786. }
  4787. static void
  4788. print_struct_with_dereference(ulong addr, struct datatype_member *dm, ulong flags)
  4789. {
  4790. int indent;
  4791. char *p1;
  4792. char buf1[BUFSIZE];
  4793. char buf2[BUFSIZE];
  4794. char buf3[BUFSIZE];
  4795. struct datatype_member datatype_member, *dm1;
  4796. dm1 = &datatype_member;
  4797. open_tmpfile();
  4798. if (flags & UNION_REQUEST)
  4799. print_union(dm->name, addr);
  4800. else if (flags & STRUCT_REQUEST)
  4801. print_struct(dm->name, addr);
  4802. rewind(pc->tmpfile);
  4803. while (fgets(buf1, BUFSIZE, pc->tmpfile)) {
  4804. indent = count_leading_spaces(buf1);
  4805. if ((indent != 2) || strstr(buf1, "{") || strstr(buf1, "}")) {
  4806. print_verbatim(pc->saved_fp, buf1);
  4807. continue;
  4808. }
  4809. sprintf(buf2, "%s.", dm->name);
  4810. strcpy(buf3, &buf1[2]);
  4811. p1 = strstr(buf3, " =");
  4812. *p1 = NULLCHAR;
  4813. strcat(buf2, buf3);
  4814. if ((arg_to_datatype(buf2, dm1, RETURN_ON_ERROR) == 2) &&
  4815. dereference_pointer(addr, dm1, flags))
  4816. continue;
  4817. print_verbatim(pc->saved_fp, buf1);
  4818. }
  4819. close_tmpfile();
  4820. }
  4821. static int
  4822. dereference_pointer(ulong addr, struct datatype_member *dm, ulong flags)
  4823. {
  4824. char buf1[BUFSIZE];
  4825. char buf2[BUFSIZE];
  4826. char *typeptr, *member, *charptr, *voidptr, *p1, *sym;
  4827. int found, ptrptr, funcptr, typedef_is_ptr, use_symbol;
  4828. ulong target, value;
  4829. found = ptrptr = funcptr = typedef_is_ptr = use_symbol = FALSE;
  4830. member = GETBUF(strlen(dm->member)+4);
  4831. typeptr = charptr = voidptr = NULL;
  4832. open_tmpfile2();
  4833. whatis_datatype(dm->name, flags, pc->tmpfile2);
  4834. rewind(pc->tmpfile2);
  4835. while (fgets(buf1, BUFSIZE, pc->tmpfile2)) {
  4836. sprintf(member, " *%s;", dm->member);
  4837. if (strstr(buf1, member) && (buf1[4] != ' ')) {
  4838. typeptr = &buf1[4];
  4839. found++;
  4840. break;
  4841. }
  4842. sprintf(member, "**%s;", dm->member);
  4843. if (strstr(buf1, member) && (buf1[4] != ' ')) {
  4844. typeptr = &buf1[4];
  4845. found++;
  4846. ptrptr = TRUE;
  4847. break;
  4848. }
  4849. sprintf(member, "(*%s)(", dm->member);
  4850. if (strstr(buf1, member) && (buf1[4] != ' ')) {
  4851. typeptr = &buf1[4];
  4852. funcptr = TRUE;
  4853. found++;
  4854. break;
  4855. }
  4856. sprintf(member, " %s;", dm->member);
  4857. if (strstr(buf1, member) && (buf1[4] != ' ')) {
  4858. typeptr = &buf1[4];
  4859. typedef_is_ptr = TRUE;
  4860. strcpy(buf2, typeptr);
  4861. p1 = strstr(buf2, " ");
  4862. *p1 = NULLCHAR;
  4863. if (datatype_exists(buf2) == TYPE_CODE_PTR) {
  4864. found++;
  4865. break;
  4866. }
  4867. }
  4868. }
  4869. close_tmpfile2();
  4870. FREEBUF(member);
  4871. if (!found) {
  4872. console("%s.%s: not found!\n", dm->name, dm->member);
  4873. return FALSE;
  4874. }
  4875. if (funcptr) {
  4876. p1 = strstr(buf1, ";");
  4877. *p1 = NULLCHAR;
  4878. } else if (ptrptr) {
  4879. p1 = strstr(buf1, "**");
  4880. *(p1+2) = NULLCHAR;
  4881. charptr = voidptr = NULL;
  4882. } else if (typedef_is_ptr) {
  4883. p1 = strstr(typeptr, " ");
  4884. *p1 = NULLCHAR;
  4885. } else {
  4886. p1 = strstr(buf1, "*");
  4887. *(p1+1) = NULLCHAR;
  4888. charptr = strstr(&buf1[4], "char *");
  4889. voidptr = strstr(&buf1[4], "void *");
  4890. }
  4891. console("%s.%s typeptr: %s ",
  4892. dm->name, dm->member,
  4893. typeptr);
  4894. if (charptr)
  4895. console("[char *]");
  4896. else if (voidptr)
  4897. console("[void *]");
  4898. else if (funcptr)
  4899. console("[func *]");
  4900. else if (typedef_is_ptr)
  4901. console("[typedef is ptr]");
  4902. console("\n");
  4903. if (!readmem(addr + dm->member_offset, KVADDR,
  4904. &target, sizeof(void *), "target address",
  4905. RETURN_ON_ERROR|QUIET)) {
  4906. error(INFO, "cannot access %s.%s %lx\n",
  4907. dm->name, dm->member,
  4908. addr + dm->member_offset);
  4909. return FALSE;
  4910. }
  4911. if ((sym = value_symbol(target))) {
  4912. switch (get_symbol_type(sym, NULL, NULL))
  4913. {
  4914. case TYPE_CODE_ARRAY:
  4915. case TYPE_CODE_UNION:
  4916. case TYPE_CODE_STRUCT:
  4917. case TYPE_CODE_INT:
  4918. case TYPE_CODE_PTR:
  4919. use_symbol = TRUE;
  4920. console("use_symbol: %s\n", sym);
  4921. break;
  4922. }
  4923. }
  4924. if (funcptr) {
  4925. fprintf(pc->saved_fp, " %s = 0x%lx\n -> ",
  4926. typeptr, target);
  4927. if (sym)
  4928. fprintf(pc->saved_fp, "<%s>\n", sym);
  4929. else if (target)
  4930. fprintf(pc->saved_fp, "(unknown)\n");
  4931. else
  4932. fprintf(pc->saved_fp, "NULL\n");
  4933. return TRUE;
  4934. }
  4935. if (charptr) {
  4936. fprintf(pc->saved_fp, " %s%s = 0x%lx\n -> ", typeptr, dm->member,
  4937. target);
  4938. if (sym)
  4939. fprintf(pc->saved_fp, "<%s> ", sym);
  4940. if (!target)
  4941. fprintf(pc->saved_fp, "NULL\n");
  4942. else if (!accessible(target) || !read_string(target, buf1, BUFSIZE-1))
  4943. fprintf(pc->saved_fp, "(not accessible)\n");
  4944. else
  4945. fprintf(pc->saved_fp, "\"%s\"\n", buf1);
  4946. return TRUE;
  4947. }
  4948. if (voidptr && !use_symbol) {
  4949. fprintf(pc->saved_fp, " %s%s = 0x%lx\n -> ", typeptr, dm->member,
  4950. target);
  4951. if (sym)
  4952. fprintf(pc->saved_fp, "<%s>\n", sym);
  4953. else if (!target)
  4954. fprintf(pc->saved_fp, "NULL\n");
  4955. else if (voidptr)
  4956. fprintf(pc->saved_fp, "(unknown target type)\n");
  4957. return TRUE;
  4958. }
  4959. if (!target || !accessible(target)) {
  4960. fprintf(pc->saved_fp, " %s%s%s = 0x%lx\n -> ", typeptr,
  4961. typedef_is_ptr ? " " : "", dm->member, target);
  4962. if (!target)
  4963. fprintf(pc->saved_fp, "NULL\n");
  4964. else
  4965. fprintf(pc->saved_fp, "(not accessible)\n");
  4966. return TRUE;
  4967. }
  4968. if (ptrptr) {
  4969. fprintf(pc->saved_fp, " %s%s = 0x%lx\n -> ", typeptr, dm->member,
  4970. target);
  4971. if (sym)
  4972. fprintf(pc->saved_fp, "<%s> ", sym);
  4973. if (!target ||
  4974. !readmem(target, KVADDR, &value, sizeof(void *),
  4975. "target value", RETURN_ON_ERROR|QUIET))
  4976. fprintf(pc->saved_fp, "\n");
  4977. else
  4978. fprintf(pc->saved_fp, "%lx\n", value);
  4979. return TRUE;
  4980. }
  4981. if (use_symbol)
  4982. sprintf(buf2, "p %s\n", sym);
  4983. else
  4984. sprintf(buf2, "p *((%s)(0x%lx))\n", typeptr, target);
  4985. console("gdb command: %s", buf2);
  4986. if (!typedef_is_ptr) {
  4987. p1 = strstr(typeptr, "*");
  4988. *(p1-1) = NULLCHAR;
  4989. }
  4990. if (!datatype_exists(typeptr)) {
  4991. fprintf(pc->saved_fp,
  4992. " %s %s%s = 0x%lx\n -> (%s: no debuginfo data)\n",
  4993. typeptr, typedef_is_ptr ? "" : "*", dm->member, target,
  4994. typeptr);
  4995. return TRUE;
  4996. }
  4997. open_tmpfile2();
  4998. if (!gdb_pass_through(buf2, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
  4999. console("gdb request failed: %s\n", buf2);
  5000. close_tmpfile2();
  5001. return FALSE;
  5002. }
  5003. fprintf(pc->saved_fp, " %s %s%s = 0x%lx\n -> ", typeptr,
  5004. typedef_is_ptr ? "" : "*", dm->member, target);
  5005. rewind(pc->tmpfile2);
  5006. while (fgets(buf1, BUFSIZE, pc->tmpfile2)) {
  5007. if (buf1[0] == '$') {
  5008. if (sym)
  5009. fprintf(pc->saved_fp, "<%s> ", sym);
  5010. if (typedef_is_ptr || use_symbol) {
  5011. if (strstr(buf1, "(") && strstr(buf1, ")")) {
  5012. fprintf(pc->saved_fp, "\n");
  5013. break;
  5014. }
  5015. }
  5016. p1 = strstr(buf1, "=");
  5017. fprintf(pc->saved_fp, "%s", p1+2);
  5018. } else
  5019. fprintf(pc->saved_fp, " %s", buf1);
  5020. }
  5021. close_tmpfile2();
  5022. return TRUE;
  5023. }
  5024. static void
  5025. cmd_datatype_common(ulong flags)
  5026. {
  5027. int c;
  5028. ulong addr, aflag;
  5029. char *cpuspec;
  5030. ulong *cpus;
  5031. struct syment *sp;
  5032. ulong list_head_offset;
  5033. int count;
  5034. int argc_members;
  5035. int optind_save;
  5036. unsigned int radix, restore_radix;
  5037. struct datatype_member datatype_member, *dm;
  5038. char *separator;
  5039. char *structname, *members;
  5040. char *memberlist[MAXARGS];
  5041. dm = &datatype_member;
  5042. count = 0xdeadbeef;
  5043. aflag = addr = 0;
  5044. list_head_offset = 0;
  5045. argc_members = 0;
  5046. radix = restore_radix = 0;
  5047. separator = members = NULL;
  5048. cpuspec = NULL;
  5049. cpus = NULL;
  5050. while ((c = getopt(argcnt, args, "pxdhfuc:rvol:")) != EOF) {
  5051. switch (c)
  5052. {
  5053. case 'p':
  5054. flags |= DEREF_POINTERS;
  5055. break;
  5056. case 'd':
  5057. if (radix == 16)
  5058. error(FATAL,
  5059. "-d and -x are mutually exclusive\n");
  5060. radix = 10;
  5061. break;
  5062. case 'h':
  5063. case 'x':
  5064. if (radix == 10)
  5065. error(FATAL,
  5066. "-d and -x are mutually exclusive\n");
  5067. radix = 16;
  5068. break;
  5069. case 'c':
  5070. count = atoi(optarg);
  5071. break;
  5072. case 'r':
  5073. flags |= SHOW_RAW_DATA;
  5074. break;
  5075. case 'v':
  5076. flags |= STRUCT_VERBOSE;
  5077. break;
  5078. case 'o':
  5079. flags |= SHOW_OFFSET;
  5080. break;
  5081. case 'l':
  5082. if (IS_A_NUMBER(optarg))
  5083. list_head_offset = stol(optarg,
  5084. FAULT_ON_ERROR, NULL);
  5085. else if (arg_to_datatype(optarg,
  5086. dm, RETURN_ON_ERROR) > 1)
  5087. list_head_offset = dm->member_offset;
  5088. else
  5089. error(FATAL, "invalid -l option: %s\n",
  5090. optarg);
  5091. break;
  5092. case 'f':
  5093. if (!pc->dumpfile)
  5094. error(FATAL,
  5095. "-f option requires a dumpfile\n");
  5096. pc->curcmd_flags |= MEMTYPE_FILEADDR;
  5097. break;
  5098. case 'u':
  5099. pc->curcmd_flags |= MEMTYPE_UVADDR;
  5100. break;
  5101. default:
  5102. argerrs++;
  5103. break;
  5104. }
  5105. }
  5106. if (argerrs || !args[optind])
  5107. cmd_usage(pc->curcmd, SYNOPSIS);
  5108. if ((count_chars(args[optind], ',')+1) > MAXARGS)
  5109. error(FATAL, "too many members in comma-separated list!\n");
  5110. if ((count_chars(args[optind], '.') > 1) ||
  5111. (LASTCHAR(args[optind]) == ',') ||
  5112. (LASTCHAR(args[optind]) == '.'))
  5113. error(FATAL, "invalid format: %s\n", args[optind]);
  5114. optind_save = optind;
  5115. /*
  5116. * Take care of address and count (array).
  5117. */
  5118. while (args[++optind]) {
  5119. if (aflag && (count != 0xdeadbeef))
  5120. error(FATAL, "too many arguments!\n");
  5121. if (!aflag) {
  5122. cpuspec = strchr(args[optind], ':');
  5123. if (cpuspec)
  5124. *cpuspec++ = NULLCHAR;
  5125. }
  5126. if (clean_arg() && IS_A_NUMBER(args[optind])) {
  5127. if (aflag)
  5128. count = stol(args[optind],
  5129. FAULT_ON_ERROR, NULL);
  5130. else if (cpuspec) {
  5131. if (pc->curcmd_flags & MEMTYPE_FILEADDR)
  5132. error(FATAL, "-f option cannot be used with percpu\n");
  5133. addr = htol(args[optind], FAULT_ON_ERROR, NULL);
  5134. aflag++;
  5135. } else {
  5136. if (pc->curcmd_flags & MEMTYPE_FILEADDR)
  5137. pc->curcmd_private = stoll(args[optind],
  5138. FAULT_ON_ERROR, NULL);
  5139. else if (pc->curcmd_flags & MEMTYPE_UVADDR) {
  5140. addr = htol(args[optind], FAULT_ON_ERROR,
  5141. NULL);
  5142. } else if (!IS_KVADDR(addr = htol(args[optind],
  5143. FAULT_ON_ERROR, NULL)))
  5144. error(FATAL,
  5145. "invalid kernel virtual address: %s\n",
  5146. args[optind]);
  5147. aflag++;
  5148. }
  5149. } else if ((sp = symbol_search(args[optind]))) {
  5150. if (cpuspec && !is_percpu_symbol(sp)) {
  5151. error(WARNING,
  5152. "%s is not percpu; cpuspec ignored.\n",
  5153. sp->name);
  5154. cpuspec = NULL;
  5155. }
  5156. addr = sp->value;
  5157. aflag++;
  5158. } else {
  5159. fprintf(fp, "symbol not found: %s\n", args[optind]);
  5160. fprintf(fp, "possible alternatives:\n");
  5161. if (!symbol_query(args[optind], " ", NULL))
  5162. fprintf(fp, " (none found)\n");
  5163. goto freebuf;
  5164. }
  5165. }
  5166. if (cpuspec) {
  5167. cpus = get_cpumask_buf();
  5168. if (STREQ(cpuspec, ""))
  5169. SET_BIT(cpus, CURRENT_CONTEXT()->processor);
  5170. else
  5171. make_cpumask(cpuspec, cpus, FAULT_ON_ERROR, NULL);
  5172. }
  5173. optind = optind_save;
  5174. if (count == 0xdeadbeef)
  5175. count = 1;
  5176. else if (!aflag)
  5177. error(FATAL, "no kernel virtual address argument entered\n");
  5178. if ((flags & DEREF_POINTERS) && !aflag)
  5179. error(FATAL, "-p option requires address argument\n");
  5180. if (list_head_offset)
  5181. addr -= list_head_offset;
  5182. /*
  5183. * Handle struct.member[,member] argument format.
  5184. */
  5185. if (strstr(args[optind], ".")) {
  5186. structname = GETBUF(strlen(args[optind])+1);
  5187. strcpy(structname, args[optind]);
  5188. separator = strstr(structname, ".");
  5189. members = GETBUF(strlen(args[optind])+1);
  5190. strcpy(members, separator+1);
  5191. replace_string(members, ",", ' ');
  5192. argc_members = parse_line(members, memberlist);
  5193. } else
  5194. structname = args[optind];
  5195. if ((arg_to_datatype(structname, dm,
  5196. DATATYPE_QUERY|ANON_MEMBER_QUERY|RETURN_ON_ERROR) < 1))
  5197. error(FATAL, "invalid data structure reference: %s\n", structname);
  5198. if (! (flags & (STRUCT_REQUEST|UNION_REQUEST)) ) {
  5199. flags |= dm->type;
  5200. if (!(flags & (UNION_REQUEST|STRUCT_REQUEST)))
  5201. error(FATAL, "invalid argument");
  5202. } else if ( (flags &(STRUCT_REQUEST|UNION_REQUEST)) != dm->type) {
  5203. error(FATAL, "data type mismatch: %s is not a %s\n",
  5204. dm->name, flags & UNION_REQUEST ? "union" : "struct");
  5205. }
  5206. if ((argc_members > 1) && !aflag) {
  5207. error(INFO, flags & SHOW_OFFSET ?
  5208. "-o option not valid with multiple member format\n" :
  5209. "multiple member format not supported in this syntax\n");
  5210. *separator = NULLCHAR;
  5211. argc_members = 0;
  5212. flags |= SHOW_OFFSET;
  5213. }
  5214. if ((argc_members > 1) && aflag && (flags & SHOW_OFFSET))
  5215. error(FATAL,
  5216. "-o option not valid with multiple member format\n");
  5217. set_temporary_radix(radix, &restore_radix);
  5218. /*
  5219. * No address was passed -- dump the structure/member declaration.
  5220. */
  5221. if (!aflag) {
  5222. if (argc_members &&
  5223. !member_to_datatype(memberlist[0], dm,
  5224. ANON_MEMBER_QUERY))
  5225. error(FATAL, "invalid data structure reference: %s.%s\n",
  5226. dm->name, memberlist[0]);
  5227. do_datatype_declaration(dm, flags | (dm->flags & TYPEDEF));
  5228. } else if (cpus) {
  5229. for (c = 0; c < kt->cpus; c++) {
  5230. ulong cpuaddr;
  5231. if (!NUM_IN_BITMAP(cpus, c))
  5232. continue;
  5233. cpuaddr = addr + kt->__per_cpu_offset[c];
  5234. fprintf(fp, "[%d]: %lx\n", c, cpuaddr);
  5235. do_datatype_addr(dm, cpuaddr , count,
  5236. flags, memberlist, argc_members);
  5237. }
  5238. } else
  5239. do_datatype_addr(dm, addr, count, flags,
  5240. memberlist, argc_members);
  5241. restore_current_radix(restore_radix);
  5242. freebuf:
  5243. if (argc_members) {
  5244. FREEBUF(structname);
  5245. FREEBUF(members);
  5246. }
  5247. if (cpus)
  5248. FREEBUF(cpus);
  5249. }
  5250. static void
  5251. do_datatype_addr(struct datatype_member *dm, ulong addr, int count,
  5252. ulong flags, char **memberlist, int argc_members)
  5253. {
  5254. int i, c;
  5255. long len = dm->size;
  5256. if (count < 0) {
  5257. addr -= len * abs(count);
  5258. addr += len;
  5259. }
  5260. if (pc->curcmd_flags & MEMTYPE_FILEADDR)
  5261. addr = 0; /* unused, but parsed by gdb */
  5262. for (c = 0; c < abs(count); c++, addr += len, pc->curcmd_private += len) {
  5263. if (c)
  5264. fprintf(fp,"\n");
  5265. i = 0;
  5266. do {
  5267. if (argc_members) {
  5268. if (!member_to_datatype(memberlist[i], dm,
  5269. ANON_MEMBER_QUERY))
  5270. error(FATAL, "invalid data structure reference: %s.%s\n",
  5271. dm->name, memberlist[i]);
  5272. if (flags & SHOW_RAW_DATA)
  5273. error(FATAL,
  5274. "member-specific output not allowed with -r\n");
  5275. }
  5276. /*
  5277. * Display member addresses or data
  5278. */
  5279. if (flags & SHOW_OFFSET) {
  5280. dm->vaddr = addr;
  5281. do_datatype_declaration(dm, flags | (dm->flags & TYPEDEF));
  5282. } else if (flags & SHOW_RAW_DATA)
  5283. raw_data_dump(addr, len, flags & STRUCT_VERBOSE);
  5284. else if ((flags & DEREF_POINTERS) && !dm->member) {
  5285. print_struct_with_dereference(addr, dm, flags);
  5286. } else {
  5287. if (dm->member)
  5288. open_tmpfile();
  5289. if (flags & UNION_REQUEST)
  5290. print_union(dm->name, addr);
  5291. else if (flags & STRUCT_REQUEST)
  5292. print_struct(dm->name, addr);
  5293. if (dm->member) {
  5294. if (!((flags & DEREF_POINTERS) &&
  5295. dereference_pointer(addr, dm, flags)))
  5296. parse_for_member(dm, PARSE_FOR_DATA);
  5297. close_tmpfile();
  5298. }
  5299. }
  5300. } while (++i < argc_members);
  5301. }
  5302. }
  5303. /*
  5304. * Generic function for dumping data structure declarations, with a small
  5305. * fixup for typedefs, sizes and member offsets.
  5306. */
  5307. static void
  5308. do_datatype_declaration(struct datatype_member *dm, ulong flags)
  5309. {
  5310. long len;
  5311. char buf[BUFSIZE];
  5312. char *p1, *p2, *multiline;
  5313. FILE *sfp;
  5314. if (CRASHDEBUG(1))
  5315. dump_datatype_member(fp, dm);
  5316. open_tmpfile();
  5317. whatis_datatype(dm->name, flags, pc->tmpfile);
  5318. rewind(pc->tmpfile);
  5319. if (dm->member)
  5320. flags |= SHOW_OFFSET;
  5321. sfp = pc->saved_fp;
  5322. len = dm->size;
  5323. multiline = NULL;
  5324. while (fgets(buf, BUFSIZE, pc->tmpfile)) {
  5325. if (STRNEQ(buf, "type = ")) {
  5326. multiline = strstr(buf, "{");
  5327. if (flags & TYPEDEF)
  5328. fprintf(sfp, "typedef ");
  5329. p1 = buf + strlen("type = ");
  5330. if ((p2 = strstr(buf, "(*)()"))) {
  5331. *p2 = NULLCHAR;
  5332. fprintf(sfp, "%s(*%s)();\n",
  5333. p1, dm->name);
  5334. } else if ((p2 = strstr(buf, "()"))) {
  5335. *p2 = NULLCHAR;
  5336. fprintf(sfp, "%s(%s)();\n", p1, dm->name);
  5337. } else if (multiline)
  5338. fprintf(sfp, "%s", p1);
  5339. else
  5340. fprintf(sfp, "%s %s;\n",
  5341. strip_linefeeds(p1), dm->name);
  5342. } else {
  5343. if (multiline && STRNEQ(buf, "}") && (flags & TYPEDEF)){
  5344. if (strstr(buf, "} **()"))
  5345. fprintf(sfp, "} **(%s)();\n", dm->name);
  5346. else
  5347. fprintf(sfp, "%s %s;\n",
  5348. strip_linefeeds(buf), dm->name);
  5349. } else {
  5350. if ((flags & SHOW_OFFSET) && whitespace(buf[0]))
  5351. show_member_offset(sfp, dm, buf);
  5352. else
  5353. fprintf(sfp, "%s", buf);
  5354. }
  5355. }
  5356. }
  5357. if (!dm->member) {
  5358. switch (*gdb_output_radix)
  5359. {
  5360. default:
  5361. case 10:
  5362. fprintf(sfp, "SIZE: %ld\n", len);
  5363. break;
  5364. case 16:
  5365. fprintf(sfp, "SIZE: 0x%lx\n", len);
  5366. break;
  5367. }
  5368. }
  5369. close_tmpfile();
  5370. }
  5371. /*
  5372. * Take a argument string, which may be in "struct.member" or "union.member"
  5373. * format, figure out whether it's a structure or a union reference, and
  5374. * fill in the appropriate fields of the dataytype_member structure.
  5375. * Return 1 if it's a straight struct or union reference, 2 if it has
  5376. * a legitimate .member attached to it, or 0 if it's bogus.
  5377. */
  5378. int
  5379. arg_to_datatype(char *s, struct datatype_member *dm, ulong flags)
  5380. {
  5381. char *p1;
  5382. int both;
  5383. BZERO(dm, sizeof(struct datatype_member));
  5384. both = FALSE;
  5385. dm->name = s;
  5386. if (!(p1 = strstr(s, ".")))
  5387. both = FALSE;
  5388. else if (flags & DATATYPE_QUERY) {
  5389. *p1 = NULLCHAR;
  5390. both = FALSE;
  5391. } else {
  5392. if ((p1 == s) || !strlen(p1+1))
  5393. goto datatype_member_fatal;
  5394. *p1 = NULLCHAR;
  5395. if (strstr(p1+1, "."))
  5396. goto datatype_member_fatal;
  5397. both = TRUE;
  5398. }
  5399. if ((dm->size = DATATYPE_SIZE(dm)) < 0) {
  5400. if (flags & RETURN_ON_ERROR)
  5401. goto datatype_member_fatal;
  5402. error(FATAL,
  5403. "cannot handle \"%s\": try \"gdb whatis\" or \"gdb ptype\"\n", s);
  5404. }
  5405. if (!both)
  5406. return 1;
  5407. if (member_to_datatype(p1 + 1, dm, flags))
  5408. return 2;
  5409. datatype_member_fatal:
  5410. if (flags & RETURN_ON_ERROR) {
  5411. if (both)
  5412. *p1 = '.';
  5413. return 0;
  5414. }
  5415. if (both) {
  5416. *p1 = '.';
  5417. if (strstr(p1+1, "."))
  5418. error(FATAL, "only one %s member allowed: %s\n",
  5419. (dm->type == STRUCT_REQUEST) ? "struct" :
  5420. ((dm->type == UNION_REQUEST) ?
  5421. "union" : "struct/union"), s);
  5422. }
  5423. return (error(FATAL, "invalid argument: %s\n", s));
  5424. }
  5425. static int
  5426. member_to_datatype(char *s, struct datatype_member *dm, ulong flags)
  5427. {
  5428. dm->member = s;
  5429. if ((dm->member_offset = MEMBER_OFFSET(dm->name, s)) >= 0)
  5430. return TRUE;
  5431. if ((flags & ANON_MEMBER_QUERY) &&
  5432. ((dm->member_offset = ANON_MEMBER_OFFSET(dm->name, s)) >= 0))
  5433. return TRUE;
  5434. return FALSE;
  5435. }
  5436. /*
  5437. * debug routine -- not called on purpose by anybody.
  5438. */
  5439. static void
  5440. dump_datatype_member(FILE *ofp, struct datatype_member *dm)
  5441. {
  5442. int others;
  5443. others = 0;
  5444. fprintf(ofp, " name: %s\n", dm->name);
  5445. fprintf(ofp, " member: %s\n", dm->member);
  5446. fprintf(ofp, " type: %lx (", dm->type);
  5447. if (dm->type & STRUCT_REQUEST)
  5448. fprintf(ofp, "%sSTRUCT_REQUEST", others++ ? "|" : "");
  5449. if (dm->type & UNION_REQUEST)
  5450. fprintf(fp, "%sUNION_REQUEST", others++ ? "|" : "");
  5451. if (dm->type & INT64)
  5452. fprintf(ofp, "%sINT64", others++ ? "|" : "");
  5453. if (dm->type & INT32)
  5454. fprintf(ofp, "%sINT32", others++ ? "|" : "");
  5455. if (dm->type & INT16)
  5456. fprintf(ofp, "%sINT16", others++ ? "|" : "");
  5457. if (dm->type & INT8)
  5458. fprintf(ofp, "%sINT8", others++ ? "|" : "");
  5459. if (dm->type & POINTER)
  5460. fprintf(ofp, "%sPOINTER", others++ ? "|" : "");
  5461. if (dm->type & FUNCTION)
  5462. fprintf(ofp, "%sFUNCTION", others++ ? "|" : "");
  5463. if (dm->type & ARRAY)
  5464. fprintf(ofp, "%sARRAY", others++ ? "|" : "");
  5465. if (dm->type & ENUM)
  5466. fprintf(ofp, "%sENUM", others++ ? "|" : "");
  5467. if (dm->type & IN_UNION)
  5468. fprintf(ofp, "%sIN_UNION", others++ ? "|" : "");
  5469. if (dm->type & IN_STRUCT)
  5470. fprintf(ofp, "%sIN_STRUCT", others++ ? "|" : "");
  5471. fprintf(ofp, ")\n");
  5472. fprintf(ofp, " size: %ld\n", dm->size);
  5473. fprintf(ofp, " member_offset: %ld\n", dm->member_offset);
  5474. fprintf(ofp, " member_size: %ld\n", dm->member_size);
  5475. fprintf(ofp, "member_typecode: %d\n", dm->member_typecode);
  5476. fprintf(ofp, " flags: %lx ", dm->flags);
  5477. dump_datatype_flags(dm->flags, ofp);
  5478. fprintf(ofp, " tagname: %s\n", dm->tagname);
  5479. fprintf(ofp, " value: %ld\n", dm->value);
  5480. fprintf(ofp, " vaddr: %lx\n", dm->vaddr);
  5481. fprintf(ofp, "\n");
  5482. }
  5483. /*
  5484. * This command displays the definition of structures, unions, typedefs or
  5485. * text/data symbols:
  5486. *
  5487. * 1. For a structure name, the output is the same as if the "struct"
  5488. * command was used.
  5489. * 2. For a union name, the output is the same as if the "union" command
  5490. * was used.
  5491. * 3. For a typedef name that translates to a structure or union, the output
  5492. * is the same as if the "struct" or "union" command was used.
  5493. * 4. For a typedef name that translates to a primitive datatype, the one-line
  5494. * declaration is displayed.
  5495. * 5. For a kernel symbol name, the output is the same as if the "sym" command
  5496. * was used.
  5497. */
  5498. void
  5499. cmd_whatis(void)
  5500. {
  5501. struct datatype_member datatype_member, *dm;
  5502. struct syment *sp;
  5503. char buf[BUFSIZE];
  5504. long len;
  5505. int c;
  5506. ulong flags;
  5507. dm = &datatype_member;
  5508. flags = 0;
  5509. while ((c = getopt(argcnt, args, "o")) != EOF) {
  5510. switch(c)
  5511. {
  5512. case 'o':
  5513. flags |= SHOW_OFFSET;
  5514. break;
  5515. default:
  5516. argerrs++;
  5517. break;
  5518. }
  5519. }
  5520. if (argerrs || !args[optind])
  5521. cmd_usage(pc->curcmd, SYNOPSIS);
  5522. if (STREQ(args[optind], "struct") ||
  5523. STREQ(args[optind], "union") ||
  5524. STREQ(args[optind], "enum"))
  5525. optind++;
  5526. else if ((sp = symbol_search(args[optind]))) {
  5527. whatis_variable(sp);
  5528. return;
  5529. }
  5530. if (!args[optind])
  5531. cmd_usage(pc->curcmd, SYNOPSIS);
  5532. if (arg_to_datatype(args[optind], dm, RETURN_ON_ERROR)) {
  5533. if ((len = dm->size) < 0)
  5534. goto whatis_failure;
  5535. flags |= dm->type;
  5536. if (dm->type == ENUM) {
  5537. if (dm->tagname)
  5538. fprintf(fp, "%senum%s%s = %ld\n",
  5539. dm->flags & TYPEDEF ? "typedef " : "",
  5540. strlen(dm->tagname) ? " " : "",
  5541. dm->tagname, dm->value);
  5542. else
  5543. dump_enumerator_list(args[optind]);
  5544. return;
  5545. }
  5546. do_datatype_declaration(dm, flags | (dm->flags & TYPEDEF));
  5547. } else {
  5548. if (!gdb_whatis(concat_args(buf, 1, FALSE)))
  5549. goto whatis_failure;
  5550. }
  5551. return;
  5552. whatis_failure:
  5553. error(INFO, "cannot resolve: %s\n", concat_args(buf, 1, FALSE));
  5554. cmd_usage(pc->curcmd, SYNOPSIS);
  5555. }
  5556. /*
  5557. * Try gdb's whatis on a command string.
  5558. */
  5559. static int
  5560. gdb_whatis(char *s)
  5561. {
  5562. char buf[BUFSIZE], *p1;
  5563. open_tmpfile();
  5564. sprintf(buf, "whatis %s", s);
  5565. if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) {
  5566. close_tmpfile();
  5567. return FALSE;
  5568. }
  5569. rewind(pc->tmpfile);
  5570. while (fgets(buf, BUFSIZE, pc->tmpfile)) {
  5571. p1 = buf;
  5572. if (STRNEQ(buf, "type = "))
  5573. p1 += strlen("type = ");
  5574. fprintf(pc->saved_fp, "%s", p1);
  5575. }
  5576. close_tmpfile();
  5577. return TRUE;
  5578. }
  5579. /*
  5580. * Given the name of an enum, have gdb dump its enumerator list.
  5581. */
  5582. int
  5583. dump_enumerator_list(char *e)
  5584. {
  5585. struct gnu_request *req;
  5586. struct datatype_member datatype_member, *dm;
  5587. dm = &datatype_member;
  5588. if (!arg_to_datatype(e, dm, RETURN_ON_ERROR) ||
  5589. (dm->size < 0) || (dm->type != ENUM) || dm->tagname)
  5590. return FALSE;
  5591. req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request));
  5592. req->command = GNU_GET_DATATYPE;
  5593. req->name = e;
  5594. req->flags = GNU_PRINT_ENUMERATORS;
  5595. gdb_interface(req);
  5596. FREEBUF(req);
  5597. return TRUE;
  5598. }
  5599. /*
  5600. * Given the name of an enum, return its value.
  5601. */
  5602. int
  5603. enumerator_value(char *e, long *value)
  5604. {
  5605. struct datatype_member datatype_member, *dm;
  5606. dm = &datatype_member;
  5607. if (arg_to_datatype(e, dm, RETURN_ON_ERROR)) {
  5608. if ((dm->size >= 0) &&
  5609. (dm->type == ENUM) && dm->tagname) {
  5610. *value = dm->value;
  5611. return TRUE;
  5612. }
  5613. }
  5614. return FALSE;
  5615. }
  5616. /*
  5617. * Verify that a datatype exists, but return on error.
  5618. */
  5619. int
  5620. datatype_exists(char *s)
  5621. {
  5622. int retval;
  5623. char buf[BUFSIZE], *p;
  5624. struct gnu_request *req;
  5625. strcpy(buf, s);
  5626. if ((p = strstr(buf, ".")))
  5627. *p = NULLCHAR;
  5628. req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request));
  5629. req->command = GNU_GET_DATATYPE;
  5630. req->name = buf;
  5631. req->flags = GNU_RETURN_ON_ERROR;
  5632. req->fp = pc->nullfp;
  5633. gdb_interface(req);
  5634. retval = req->typecode;
  5635. FREEBUF(req);
  5636. return retval;
  5637. }
  5638. /*
  5639. * Set the output radix if requested, and pass it on to gdb.
  5640. */
  5641. void
  5642. cmd_p(void)
  5643. {
  5644. int c;
  5645. struct syment *sp, *percpu_sp;
  5646. unsigned radix;
  5647. int do_load_module_filter;
  5648. char buf1[BUFSIZE];
  5649. char *cpuspec;
  5650. do_load_module_filter = radix = 0;
  5651. while ((c = getopt(argcnt, args, "dhxu")) != EOF) {
  5652. switch(c)
  5653. {
  5654. case 'd':
  5655. if (radix == 16)
  5656. error(FATAL,
  5657. "-d and -x are mutually exclusive\n");
  5658. radix = 10;
  5659. break;
  5660. case 'h':
  5661. case 'x':
  5662. if (radix == 10)
  5663. error(FATAL,
  5664. "-d and -x are mutually exclusive\n");
  5665. radix = 16;
  5666. break;
  5667. case 'u':
  5668. pc->curcmd_flags |= MEMTYPE_UVADDR;
  5669. break;
  5670. default:
  5671. argerrs++;
  5672. break;
  5673. }
  5674. }
  5675. if (argerrs || !args[optind])
  5676. cmd_usage(pc->curcmd, SYNOPSIS);
  5677. cpuspec = strrchr(args[optind], ':');
  5678. if (cpuspec)
  5679. *cpuspec++ = NULLCHAR;
  5680. sp = NULL;
  5681. if ((sp = symbol_search(args[optind])) && !args[optind+1]) {
  5682. if ((percpu_sp = per_cpu_symbol_search(args[optind])) &&
  5683. display_per_cpu_info(percpu_sp, radix, cpuspec))
  5684. return;
  5685. if (module_symbol(sp->value, NULL, NULL, NULL, *gdb_output_radix))
  5686. do_load_module_filter = TRUE;
  5687. } else if ((percpu_sp = per_cpu_symbol_search(args[optind])) &&
  5688. display_per_cpu_info(percpu_sp, radix, cpuspec))
  5689. return;
  5690. else if (st->flags & LOAD_MODULE_SYMS)
  5691. do_load_module_filter = TRUE;
  5692. if (cpuspec) {
  5693. if (sp)
  5694. error(WARNING, "%s is not percpu; cpuspec ignored.\n",
  5695. sp->name);
  5696. else
  5697. /* maybe a valid C expression (e.g. ':') */
  5698. *(cpuspec-1) = ':';
  5699. }
  5700. process_gdb_output(concat_args(buf1, 0, TRUE), radix,
  5701. sp ? sp->name : NULL, do_load_module_filter);
  5702. }
  5703. static void
  5704. process_gdb_output(char *gdb_request, unsigned radix,
  5705. const char *leader, int do_load_module_filter)
  5706. {
  5707. unsigned restore_radix;
  5708. int success;
  5709. char buf1[BUFSIZE];
  5710. char *p1;
  5711. if (leader || do_load_module_filter)
  5712. open_tmpfile();
  5713. set_temporary_radix(radix, &restore_radix);
  5714. success = gdb_pass_through(gdb_request, NULL, GNU_RETURN_ON_ERROR);
  5715. if (success && (leader || do_load_module_filter)) {
  5716. int firstline;
  5717. if (leader) {
  5718. fprintf(pc->saved_fp, "%s = ", leader);
  5719. fflush(pc->saved_fp);
  5720. }
  5721. firstline = TRUE;
  5722. rewind(pc->tmpfile);
  5723. while (fgets(buf1, BUFSIZE, pc->tmpfile)) {
  5724. if (firstline &&
  5725. (p1 = strstr(buf1, "{")) &&
  5726. !STRNEQ(p1, "{\n")) {
  5727. *p1 = NULLCHAR;
  5728. fprintf(pc->saved_fp, "%s", buf1);
  5729. fprintf(pc->saved_fp, "\n {");
  5730. print_verbatim(pc->saved_fp, p1+1);
  5731. } else
  5732. print_verbatim(pc->saved_fp, do_load_module_filter ?
  5733. load_module_filter(buf1, LM_P_FILTER) :
  5734. buf1);
  5735. firstline = FALSE;
  5736. }
  5737. }
  5738. if (leader || do_load_module_filter)
  5739. close_tmpfile();
  5740. restore_current_radix(restore_radix);
  5741. if (!success)
  5742. error(FATAL, "gdb request failed: %s\n", gdb_request);
  5743. }
  5744. /*
  5745. * Get the type of an expression using gdb's "whatis" command.
  5746. * The returned string is dynamically allocated, and it should
  5747. * be passed to FREEBUF() when no longer needed.
  5748. * Return NULL if the type cannot be determined.
  5749. */
  5750. static char *
  5751. expr_type_name(const char *expr)
  5752. {
  5753. char buf[BUFSIZE], *p;
  5754. open_tmpfile();
  5755. sprintf(buf, "whatis %s", expr);
  5756. if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) {
  5757. close_tmpfile();
  5758. return NULL;
  5759. }
  5760. rewind(pc->tmpfile);
  5761. while (fgets(buf, BUFSIZE, pc->tmpfile) && !STRNEQ(buf, "type = "))
  5762. ;
  5763. p = feof(pc->tmpfile) ? NULL : buf + strlen("type = ");
  5764. close_tmpfile();
  5765. if (p) {
  5766. size_t len = strlen(clean_line(p));
  5767. /* GDB reports unknown types as <...descriptive text...> */
  5768. if (p[0] == '<' && p[len-1] == '>')
  5769. return NULL;
  5770. return strcpy(GETBUF(len + 1), p);
  5771. }
  5772. return NULL;
  5773. }
  5774. /*
  5775. * Display the datatype of the per_cpu__xxx symbol and
  5776. * the addresses of each its per-cpu instances.
  5777. */
  5778. static int
  5779. display_per_cpu_info(struct syment *sp, int radix, char *cpuspec)
  5780. {
  5781. ulong *cpus;
  5782. int c;
  5783. ulong addr;
  5784. char buf[BUFSIZE];
  5785. char leader[sizeof("&per_cpu(") + strlen(sp->name) +
  5786. sizeof(", " STR(UINT_MAX) ")")];
  5787. char *typename;
  5788. int do_load_module_filter;
  5789. if (((kt->flags & (SMP|PER_CPU_OFF)) != (SMP|PER_CPU_OFF)) ||
  5790. (!is_percpu_symbol(sp)) ||
  5791. !((sp->type == 'd') || (sp->type == 'D') || (sp->type == 'V')))
  5792. return FALSE;
  5793. if (cpuspec) {
  5794. cpus = get_cpumask_buf();
  5795. if (STREQ(cpuspec, ""))
  5796. SET_BIT(cpus, CURRENT_CONTEXT()->processor);
  5797. else
  5798. make_cpumask(cpuspec, cpus, FAULT_ON_ERROR, NULL);
  5799. } else
  5800. cpus = NULL;
  5801. typename = expr_type_name(sp->name);
  5802. if (!cpus) {
  5803. fprintf(fp, "PER-CPU DATA TYPE:\n ");
  5804. if (!typename)
  5805. fprintf(fp, "[undetermined type] %s;\n", sp->name);
  5806. else
  5807. whatis_variable(sp);
  5808. fprintf(fp, "PER-CPU ADDRESSES:\n");
  5809. }
  5810. do_load_module_filter =
  5811. module_symbol(sp->value, NULL, NULL, NULL, *gdb_output_radix);
  5812. for (c = 0; c < kt->cpus; c++) {
  5813. if (cpus && !NUM_IN_BITMAP(cpus, c))
  5814. continue;
  5815. addr = sp->value + kt->__per_cpu_offset[c];
  5816. if (!cpus)
  5817. fprintf(fp, " [%d]: %lx\n", c, addr);
  5818. else if (typename) {
  5819. snprintf(buf, sizeof buf, "p *(%s*) 0x%lx",
  5820. typename, addr);
  5821. sprintf(leader, "per_cpu(%s, %u)",
  5822. sp->name, c);
  5823. process_gdb_output(buf, radix, leader,
  5824. do_load_module_filter);
  5825. } else {
  5826. snprintf(buf, sizeof buf, "p (void*) 0x%lx", addr);
  5827. sprintf(leader, "&per_cpu(%s, %u)",
  5828. sp->name, c);
  5829. process_gdb_output(buf, radix, leader,
  5830. do_load_module_filter);
  5831. }
  5832. }
  5833. if (typename)
  5834. FREEBUF(typename);
  5835. if (cpus)
  5836. FREEBUF(cpus);
  5837. return TRUE;
  5838. }
  5839. static struct load_module *
  5840. get_module_percpu_sym_owner(struct syment *sp)
  5841. {
  5842. int i;
  5843. struct load_module *lm;
  5844. if (!IS_MODULE_SYMBOL(sp))
  5845. return NULL;
  5846. /*
  5847. * Find out percpu symbol owner module.
  5848. * If found out, sp is module's percpu symbol.
  5849. */
  5850. for (i = 0; i < st->mods_installed; i++) {
  5851. lm = &st->load_modules[i];
  5852. if (!MODULE_PERCPU_SYMS_LOADED(lm))
  5853. continue;
  5854. if (IN_MODULE_PERCPU(sp->value, lm))
  5855. return lm;
  5856. }
  5857. return NULL;
  5858. }
  5859. static int
  5860. is_percpu_symbol(struct syment *sp)
  5861. {
  5862. if (sp->value >= st->__per_cpu_start) {
  5863. if (sp->value < st->__per_cpu_end)
  5864. /* kernel percpu symbol */
  5865. return 1;
  5866. else if (get_module_percpu_sym_owner(sp))
  5867. /* module percpu symbol */
  5868. return 2;
  5869. }
  5870. return 0;
  5871. }
  5872. /*
  5873. * As a latch ditch effort before a command is thrown away by exec_command(),
  5874. * args[0] is checked to see whether it's the name of a variable, structure,
  5875. * union, or typedef. If so, args[0] is changed to the appropriate command,
  5876. * i.e., "p", "struct", "union", or "whatis", and the original args are all
  5877. * shifted into the next higer args[] location.
  5878. */
  5879. int
  5880. is_datatype_command(void)
  5881. {
  5882. int i;
  5883. long len;
  5884. char *command;
  5885. struct datatype_member datatype_member, *dm;
  5886. struct syment *sp;
  5887. char *rdarg;
  5888. char buf[BUFSIZE];
  5889. if (!args[0])
  5890. return FALSE;
  5891. strcpy(buf, args[0]);
  5892. dm = &datatype_member;
  5893. if ((sp = symbol_search(args[0])) && (argcnt == 1)) {
  5894. if (is_gdb_command(FALSE, RETURN_ON_ERROR)) {
  5895. pc->curcmd = pc->program_name;
  5896. error(FATAL,
  5897. "ambiguous command: %s (symbol and gdb command)\n",
  5898. args[0]);
  5899. }
  5900. command = "p";
  5901. } else if (STREQ(args[0], "enum"))
  5902. command = "whatis";
  5903. else if (!datatype_exists(args[0]))
  5904. return FALSE;
  5905. else if (!arg_to_datatype(buf, dm, RETURN_ON_ERROR|DATATYPE_QUERY))
  5906. return FALSE;
  5907. else {
  5908. if (is_gdb_command(FALSE, RETURN_ON_ERROR)) {
  5909. pc->curcmd = pc->program_name;
  5910. error(FATAL,
  5911. "ambiguous command: %s (symbol/data type and gdb command)\n",
  5912. args[0]);
  5913. }
  5914. if ((sp = symbol_search(args[0])) && (argcnt == 1)) {
  5915. command = "p";
  5916. dm->type = 0;
  5917. } else if ((len = DATATYPE_SIZE(dm)) < 0) {
  5918. return FALSE;
  5919. } else if (sp) {
  5920. command = "p";
  5921. dm->type = 0;
  5922. }
  5923. switch (dm->type)
  5924. {
  5925. case STRUCT_REQUEST:
  5926. if ((dm->flags & TYPEDEF) && (argcnt == 1))
  5927. command = "whatis";
  5928. else
  5929. command = "struct";
  5930. break;
  5931. case UNION_REQUEST:
  5932. if ((dm->flags & TYPEDEF) && (argcnt == 1))
  5933. command = "whatis";
  5934. else
  5935. command = "union";
  5936. break;
  5937. case POINTER:
  5938. command = "whatis";
  5939. break;
  5940. case ARRAY:
  5941. command = "whatis";
  5942. break;
  5943. case FUNCTION:
  5944. command = "whatis";
  5945. break;
  5946. case ENUM:
  5947. command = "whatis";
  5948. break;
  5949. default:
  5950. if (dm->type & INTEGER_TYPE) {
  5951. switch (dm->type)
  5952. {
  5953. case INT64: rdarg = "-64"; break;
  5954. case INT32: rdarg = "-32"; break;
  5955. case INT16: rdarg = "-16"; break;
  5956. case INT8: rdarg = "-8"; break;
  5957. default: rdarg = NULL; break;
  5958. }
  5959. if (args[1]) {
  5960. if ((sp = symbol_search(args[1]))) {
  5961. command = "p";
  5962. args[0] = args[1];
  5963. argcnt--;
  5964. } else {
  5965. command = "rd";
  5966. args[0] = rdarg;
  5967. }
  5968. } else
  5969. command = "whatis";
  5970. } else
  5971. return FALSE;
  5972. break;
  5973. }
  5974. }
  5975. for (i = argcnt; i; i--)
  5976. args[i] = args[i-1];
  5977. args[0] = command;
  5978. argcnt++;
  5979. return TRUE;
  5980. }
  5981. /*
  5982. * Given a structure name and an address, have gdb do most of the work.
  5983. */
  5984. static void
  5985. print_struct(char *s, ulong addr)
  5986. {
  5987. char buf[BUFSIZE];
  5988. if (is_typedef(s))
  5989. sprintf(buf, "output *(%s *)0x%lx", s, addr);
  5990. else
  5991. sprintf(buf, "output *(struct %s *)0x%lx", s, addr);
  5992. fprintf(fp, "struct %s ", s);
  5993. gdb_pass_through(buf, NULL, GNU_RETURN_ON_ERROR);
  5994. fprintf(fp, "\n");
  5995. }
  5996. /*
  5997. * Given a union name and an address, let gdb do the work.
  5998. */
  5999. static void
  6000. print_union(char *s, ulong addr)
  6001. {
  6002. char buf[BUFSIZE];
  6003. if (is_typedef(s))
  6004. sprintf(buf, "output *(%s *)0x%lx", s, addr);
  6005. else
  6006. sprintf(buf, "output *(union %s *)0x%lx", s, addr);
  6007. fprintf(fp, "union %s ", s);
  6008. gdb_pass_through(buf, NULL, GNU_RETURN_ON_ERROR);
  6009. }
  6010. /*
  6011. * Given a structure or union, find its definition in the datatype symbol
  6012. * file, and dump it. If the verbose flags is set, everything from the
  6013. * file is shown; otherwise the bitpos, size and id data is stripped.
  6014. */
  6015. static void
  6016. whatis_datatype(char *st, ulong flags, FILE *ofp)
  6017. {
  6018. char lookbuf[BUFSIZE];
  6019. if (flags & TYPEDEF)
  6020. sprintf(lookbuf, "ptype %s", st);
  6021. else if (flags & UNION_REQUEST)
  6022. sprintf(lookbuf, "ptype union %s", st);
  6023. else if (flags & STRUCT_REQUEST)
  6024. sprintf(lookbuf, "ptype struct %s", st);
  6025. else
  6026. return;
  6027. if (!gdb_pass_through(lookbuf, ofp, GNU_RETURN_ON_ERROR)) {
  6028. /*
  6029. * When a structure is defined using the format:
  6030. *
  6031. * typedef struct {
  6032. * yada yada yada
  6033. * } type_t;
  6034. *
  6035. * gdb says it's a structure and not a typedef. So
  6036. * if the union or struct pass-through fails, it can't
  6037. * hurt to retry it with just "ptype type_t" before
  6038. * giving up.
  6039. */
  6040. if (flags & (UNION_REQUEST|STRUCT_REQUEST)) {
  6041. sprintf(lookbuf, "ptype %s", st);
  6042. gdb_pass_through(lookbuf, ofp, 0);
  6043. }
  6044. }
  6045. }
  6046. /*
  6047. * Scan the symbol file for a variable declaration.
  6048. */
  6049. static void
  6050. whatis_variable(struct syment *sp)
  6051. {
  6052. char *p1;
  6053. char buf[BUFSIZE];
  6054. open_tmpfile();
  6055. sprintf(buf, "whatis %s", sp->name);
  6056. if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) {
  6057. close_tmpfile();
  6058. error(FATAL, "gdb request failed: whatis %s\n", sp->name);
  6059. }
  6060. rewind(pc->tmpfile);
  6061. while (fgets(buf, BUFSIZE, pc->tmpfile)) {
  6062. if (STRNEQ(buf, "type = "))
  6063. break;
  6064. }
  6065. close_tmpfile();
  6066. clean_line(buf);
  6067. if ((p1 = strstr(buf, "["))) {
  6068. shift_string_right(p1, strlen(sp->name));
  6069. BCOPY(sp->name, p1, strlen(sp->name));
  6070. p1 = buf + strlen("type = ");
  6071. fprintf(fp, "%s;\n", p1);
  6072. } else if ((p1 = strstr(buf, "("))) {
  6073. if (index(buf, '(') == rindex(buf, '(')) {
  6074. shift_string_right(p1, strlen(sp->name));
  6075. BCOPY(sp->name, p1, strlen(sp->name));
  6076. } else {
  6077. p1 = strstr(buf, ")");
  6078. shift_string_right(p1, strlen(sp->name));
  6079. BCOPY(sp->name, p1, strlen(sp->name));
  6080. }
  6081. p1 = buf + strlen("type = ");
  6082. fprintf(fp, "%s;\n", p1);
  6083. } else {
  6084. p1 = buf + strlen("type = ");
  6085. fprintf(fp, "%s%s%s;\n", p1, LASTCHAR(p1) == '*' ? "":" ",
  6086. sp->name);
  6087. }
  6088. }
  6089. /*
  6090. * Determines whether the current structure or union member is a typedef.
  6091. */
  6092. int
  6093. is_typedef(char *name)
  6094. {
  6095. struct datatype_member datatype_member, *dm;
  6096. if (!name)
  6097. drop_core("is_typedef() received NULL name string\n");
  6098. dm = &datatype_member;
  6099. BZERO(dm, sizeof(struct datatype_member));
  6100. dm->name = name;
  6101. return (DATATYPE_SIZE(dm) < 0 ? FALSE : (dm->flags & TYPEDEF));
  6102. }
  6103. static void
  6104. dump_datatype_flags(ulong flags, FILE *ofp)
  6105. {
  6106. int others;
  6107. others = 0;
  6108. fprintf(ofp, "(");
  6109. if (flags & UINT8)
  6110. fprintf(ofp, "%sUINT8", others++ ? "|" : "");
  6111. if (flags & INT8)
  6112. fprintf(ofp, "%sINT8", others++ ? "|" : "");
  6113. if (flags & UINT16)
  6114. fprintf(ofp, "%sUINT16", others++ ? "|" : "");
  6115. if (flags & INT16)
  6116. fprintf(ofp, "%sINT16", others++ ? "|" : "");
  6117. if (flags & UINT32)
  6118. fprintf(ofp, "%sUINT32", others++ ? "|" : "");
  6119. if (flags & INT32)
  6120. fprintf(ofp, "%sINT32", others++ ? "|" : "");
  6121. if (flags & UINT64)
  6122. fprintf(ofp, "%sUINT64", others++ ? "|" : "");
  6123. if (flags & INT64)
  6124. fprintf(ofp, "%sINT64", others++ ? "|" : "");
  6125. if (flags & POINTER)
  6126. fprintf(ofp, "%sPOINTER", others++ ? "|" : "");
  6127. if (flags & FUNCTION)
  6128. fprintf(ofp, "%sFUNCTION", others++ ? "|" : "");
  6129. if (flags & ARRAY)
  6130. fprintf(ofp, "%sARRAY", others++ ? "|" : "");
  6131. if (flags & ENUM)
  6132. fprintf(ofp, "%sENUM", others++ ? "|" : "");
  6133. if (flags & TYPEDEF)
  6134. fprintf(ofp, "%sTYPEDEF", others++ ? "|" : "");
  6135. if (flags & STRUCT_VERBOSE)
  6136. fprintf(ofp, "%sSTRUCT_VERBOSE", others++ ? "|" : "");
  6137. if (flags & SHOW_OFFSET)
  6138. fprintf(ofp, "%sSHOW_OFFSET", others++ ? "|" : "");
  6139. if (flags & DATATYPE_QUERY)
  6140. fprintf(ofp, "%sDATATYPE_QUERY", others++ ? "|" : "");
  6141. if (flags & ANON_MEMBER_QUERY)
  6142. fprintf(ofp, "%sANON_MEMBER_QUERY", others++ ? "|" : "");
  6143. if (flags & SHOW_RAW_DATA)
  6144. fprintf(ofp, "%sSHOW_RAW_DATA", others++ ? "|" : "");
  6145. if (flags & DEREF_POINTERS)
  6146. fprintf(ofp, "%sDEREF_POINTERS", others++ ? "|" : "");
  6147. fprintf(ofp, ")\n");
  6148. }
  6149. /*
  6150. * When a request is made to print just a member of a structure or union,
  6151. * the whole datatype is dumped to a temporary file, and this routine
  6152. * parses through it for the targeted member.
  6153. */
  6154. static void
  6155. parse_for_member(struct datatype_member *dm, ulong flag)
  6156. {
  6157. char *s;
  6158. char buf[BUFSIZE];
  6159. char lookfor1[BUFSIZE];
  6160. char lookfor2[BUFSIZE];
  6161. char lookfor3[BUFSIZE];
  6162. char lookfor4[BUFSIZE];
  6163. char lookfor5[BUFSIZE];
  6164. long curpos, last_open_bracket;
  6165. int indent, on, array, embed;
  6166. char *p1;
  6167. s = dm->member;
  6168. indent = 0;
  6169. array = FALSE;
  6170. on = 0;
  6171. embed = 0;
  6172. rewind(pc->tmpfile);
  6173. switch (flag)
  6174. {
  6175. case PARSE_FOR_DATA:
  6176. sprintf(lookfor1, " %s ", s);
  6177. sprintf(lookfor2, " %s[", s);
  6178. next_item:
  6179. while (fgets(buf, BUFSIZE, pc->tmpfile)) {
  6180. if (embed && (count_leading_spaces(buf) == embed))
  6181. embed = 0;
  6182. if (!on && !embed && strstr(buf, "= {") && !strstr(buf, lookfor1))
  6183. embed = count_leading_spaces(buf);
  6184. if (embed)
  6185. continue;
  6186. if (strstr(buf, lookfor1) || strstr(buf, lookfor2)) {
  6187. on++;
  6188. if (strstr(buf, "= {"))
  6189. indent = count_leading_spaces(buf);
  6190. if (strstr(buf, "["))
  6191. array = TRUE;
  6192. }
  6193. if (on) {
  6194. if ((indent && (on > 1) && (count_leading_spaces(buf) == indent) &&
  6195. !strstr(buf, "}")) || (buf[0] == '}')) {
  6196. break;
  6197. }
  6198. if (!indent) {
  6199. if ((p1 = strstr(buf, ", \n")))
  6200. sprintf(p1, "\n");
  6201. fprintf(pc->saved_fp, "%s", buf);
  6202. break;
  6203. }
  6204. if (strstr(buf, "}") &&
  6205. (count_leading_spaces(buf) == indent)) {
  6206. if ((p1 = strstr(buf, "}, \n")))
  6207. sprintf(p1, "}\n");
  6208. fprintf(pc->saved_fp, "%s", buf);
  6209. break;
  6210. }
  6211. fprintf(pc->saved_fp, "%s", buf);
  6212. on++;
  6213. }
  6214. }
  6215. if (array) {
  6216. on = array = FALSE;
  6217. on = 0;
  6218. goto next_item;
  6219. }
  6220. break;
  6221. case PARSE_FOR_DECLARATION:
  6222. last_open_bracket = curpos = 0;
  6223. sprintf(lookfor1, " %s;", s);
  6224. sprintf(lookfor2, "*%s;", s);
  6225. sprintf(lookfor3, " %s[", s);
  6226. sprintf(lookfor4, "*%s[", s);
  6227. sprintf(lookfor5, " %s :", s);
  6228. while (fgets(buf, BUFSIZE, pc->tmpfile)) {
  6229. indent = count_leading_spaces(buf);
  6230. switch (indent)
  6231. {
  6232. case 0:
  6233. curpos = ftell(pc->tmpfile);
  6234. continue;
  6235. case INITIAL_INDENT:
  6236. if (strstr(buf, "{"))
  6237. last_open_bracket = curpos;
  6238. break;
  6239. default:
  6240. if (!on && (indent != INITIAL_INDENT))
  6241. continue;
  6242. }
  6243. if (strstr(buf, lookfor1) ||
  6244. strstr(buf, lookfor2) ||
  6245. strstr(buf, lookfor3) ||
  6246. strstr(buf, lookfor4) ||
  6247. strstr(buf, lookfor5)) {
  6248. if (strstr(buf, "}") && !on) {
  6249. on = TRUE;
  6250. fseek(pc->tmpfile, last_open_bracket,
  6251. SEEK_SET);
  6252. } else {
  6253. print_verbatim(pc->saved_fp, buf);
  6254. if (indent == INITIAL_INDENT)
  6255. break;
  6256. }
  6257. }
  6258. else if (on)
  6259. print_verbatim(pc->saved_fp, buf);
  6260. curpos = ftell(pc->tmpfile);
  6261. }
  6262. break;
  6263. }
  6264. }
  6265. /*
  6266. * Dig out a member name from a formatted gdb structure declaration dump,
  6267. * and print its offset from the named structure passed in.
  6268. */
  6269. static int
  6270. show_member_offset(FILE *ofp, struct datatype_member *dm, char *inbuf)
  6271. {
  6272. int i, c, len;
  6273. long offset;
  6274. char *t1, *target;
  6275. char *arglist[MAXARGS];
  6276. char buf1[BUFSIZE];
  6277. char fmt[BUFSIZE];
  6278. char workbuf[BUFSIZE];
  6279. int end_of_block;
  6280. if (!STRNEQ(inbuf, " ")) {
  6281. fprintf(ofp, "rejecting: %s", inbuf);
  6282. return FALSE;
  6283. }
  6284. if (STRNEQ(inbuf, " union {"))
  6285. dm->flags |= IN_UNION;
  6286. if (STRNEQ(inbuf, " struct {"))
  6287. dm->flags |= IN_STRUCT;
  6288. end_of_block = STRNEQ(inbuf, " } ");
  6289. switch (*gdb_output_radix)
  6290. {
  6291. default:
  6292. case 10:
  6293. sprintf(buf1, "%ld", dm->size);
  6294. break;
  6295. case 16:
  6296. sprintf(buf1, "0x%lx", dm->size);
  6297. }
  6298. len = strlen(buf1) + 4;
  6299. strcpy(workbuf, inbuf);
  6300. c = parse_line(workbuf, arglist);
  6301. target = NULL;
  6302. if (strstr(inbuf, ":")) {
  6303. for (i = 0; i < c; i++) {
  6304. if (i && STREQ(arglist[i], ":")) {
  6305. target = arglist[i-1];
  6306. break;
  6307. }
  6308. }
  6309. } else if (c) {
  6310. for (i = 0; i < c; i++) {
  6311. if (STRNEQ(arglist[i], "(*")) {
  6312. target = arglist[i]+2;
  6313. if (!(t1 = strstr(target, ")")))
  6314. continue;
  6315. *t1 = NULLCHAR;
  6316. break;
  6317. }
  6318. }
  6319. if (i == c) {
  6320. target = arglist[c-1];
  6321. if (!strstr(target, ";"))
  6322. target = NULL;
  6323. }
  6324. }
  6325. if (!target)
  6326. goto do_empty_offset;
  6327. null_first_space(clean_line(replace_string(target, "*[];()", ' ')));
  6328. if (strlen(target) == 0)
  6329. goto do_empty_offset;
  6330. if (dm->member && !STREQ(dm->member, target)) {
  6331. if (end_of_block)
  6332. dm->flags &= ~(IN_UNION|IN_STRUCT);
  6333. return FALSE;
  6334. }
  6335. offset = MEMBER_OFFSET(dm->name, target);
  6336. if (offset == -1)
  6337. offset = ANON_MEMBER_OFFSET(dm->name, target);
  6338. if (offset == -1)
  6339. goto do_empty_offset;
  6340. if (end_of_block && dm->member) {
  6341. if (dm->vaddr)
  6342. sprintf(buf1, " [%lx]", offset + dm->vaddr);
  6343. else
  6344. sprintf(buf1, *gdb_output_radix == 10 ?
  6345. " [%ld]" : " [0x%lx]", offset);
  6346. sprintf(fmt, "%c%ds", '%', len+1);
  6347. fprintf(ofp, fmt, " ");
  6348. switch (dm->flags & (IN_UNION|IN_STRUCT))
  6349. {
  6350. case IN_UNION:
  6351. fprintf(ofp, "union {\n");
  6352. break;
  6353. case IN_STRUCT:
  6354. fprintf(ofp, "struct {\n");
  6355. break;
  6356. }
  6357. dm->flags &= ~(IN_UNION|IN_STRUCT);
  6358. }
  6359. if (dm->vaddr)
  6360. sprintf(buf1, " [%lx]", offset + dm->vaddr);
  6361. else
  6362. sprintf(buf1, *gdb_output_radix == 10 ? " [%ld]" : " [0x%lx]", offset);
  6363. sprintf(fmt, "%c%ds", '%', len);
  6364. fprintf(ofp, fmt, buf1);
  6365. fprintf(ofp, "%s", &inbuf[3]);
  6366. return TRUE;
  6367. do_empty_offset:
  6368. if (end_of_block)
  6369. dm->flags &= ~(IN_UNION|IN_STRUCT);
  6370. if (dm->member)
  6371. return FALSE;
  6372. len = strlen(buf1)+1;
  6373. fprintf(ofp, "%s%s", space(len), inbuf);
  6374. return FALSE;
  6375. }
  6376. /*
  6377. * Get and store the size of a "known" array. This function is only called
  6378. * once per requested array; after the first time, ARRAY_LENGTH() should be
  6379. * used.
  6380. *
  6381. * For data symbols, get_symbol_type() does the work.
  6382. * For structure member arrays, datatype_info() does the work.
  6383. * For two-dimension arrays, or if the designated function above fails,
  6384. * then just parse "whatis" or "ptype" commands as a last resort.
  6385. */
  6386. int
  6387. get_array_length(char *s, int *two_dim, long entry_size)
  6388. {
  6389. char copy[BUFSIZE];
  6390. char buf[BUFSIZE];
  6391. char lookfor1[BUFSIZE];
  6392. char lookfor2[BUFSIZE];
  6393. int retval;
  6394. struct datatype_member datatype_member, *dm;
  6395. struct gnu_request gnu_request, *req;
  6396. char *p1, *p2;
  6397. strcpy(copy, s);
  6398. dm = &datatype_member;
  6399. BZERO(dm, sizeof(struct datatype_member));
  6400. if ((retval = builtin_array_length(s, 0, two_dim)))
  6401. return retval;
  6402. /* symbol_search cannot be done with just kernel type information */
  6403. if (!(LKCD_KERNTYPES()) && symbol_search(s)) {
  6404. if (!two_dim) {
  6405. req = &gnu_request;
  6406. if ((get_symbol_type(copy, NULL, req) ==
  6407. TYPE_CODE_ARRAY) && req->target_typecode &&
  6408. req->target_length) {
  6409. retval = req->length / req->target_length;
  6410. goto store_builtin;
  6411. }
  6412. }
  6413. sprintf(buf, "whatis %s", s);
  6414. } else {
  6415. if (arg_to_datatype(copy, dm, RETURN_ON_ERROR)) {
  6416. if (!dm->member)
  6417. goto store_builtin;
  6418. datatype_info(dm->name, dm->member, dm);
  6419. switch (dm->type)
  6420. {
  6421. case UNION_REQUEST:
  6422. if (entry_size && dm->member_size &&
  6423. (dm->member_typecode == TYPE_CODE_ARRAY)) {
  6424. retval = dm->member_size/entry_size;
  6425. goto store_builtin;
  6426. }
  6427. sprintf(buf, "ptype union %s", dm->name);
  6428. break;
  6429. case STRUCT_REQUEST:
  6430. if (entry_size && dm->member_size &&
  6431. (dm->member_typecode == TYPE_CODE_ARRAY)) {
  6432. retval = dm->member_size/entry_size;
  6433. goto store_builtin;
  6434. }
  6435. sprintf(buf, "ptype struct %s", dm->name);
  6436. break;
  6437. default:
  6438. goto store_builtin;
  6439. }
  6440. sprintf(lookfor1, " %s[", dm->member);
  6441. sprintf(lookfor2, "*%s[", dm->member);
  6442. } else
  6443. goto store_builtin;
  6444. }
  6445. open_tmpfile2();
  6446. if (two_dim)
  6447. *two_dim = 0;
  6448. gdb_pass_through(buf, pc->tmpfile2, 0);
  6449. rewind(pc->tmpfile2);
  6450. while (fgets(buf, BUFSIZE, pc->tmpfile2)) {
  6451. if (STRNEQ(buf, "type = ") &&
  6452. (p1 = strstr(buf, "[")) &&
  6453. (p2 = strstr(buf, "]")) &&
  6454. (index(buf, '[') == rindex(buf, '['))) {
  6455. *p2 = NULLCHAR;
  6456. p1++;
  6457. if (strlen(p1)) {
  6458. retval = atoi(p1);
  6459. break;
  6460. }
  6461. }
  6462. if (STRNEQ(buf, "type = ") &&
  6463. (count_chars(buf, '[') == 2) &&
  6464. (count_chars(buf, ']') == 2) && two_dim) {
  6465. p1 = strstr(buf, "[");
  6466. p2 = strstr(buf, "]");
  6467. *p2 = NULLCHAR;
  6468. p1++;
  6469. if (strlen(p1))
  6470. *two_dim = atoi(p1);
  6471. else
  6472. break;
  6473. p2++;
  6474. p1 = strstr(p2, "[");
  6475. p2 = strstr(p1, "]");
  6476. p1++;
  6477. if (strlen(p1))
  6478. retval = atoi(p1);
  6479. else {
  6480. retval = 0;
  6481. *two_dim = 0;
  6482. break;
  6483. }
  6484. break;
  6485. }
  6486. if (dm->type &&
  6487. (strstr(buf, lookfor1) || strstr(buf, lookfor2)) &&
  6488. (p1 = strstr(buf, "[")) &&
  6489. (p2 = strstr(buf, "]")) &&
  6490. (index(buf, '[') == rindex(buf, '['))) {
  6491. *p2 = NULLCHAR;
  6492. p1++;
  6493. if (strlen(p1)) {
  6494. retval = atoi(p1);
  6495. break;
  6496. }
  6497. }
  6498. }
  6499. close_tmpfile2();
  6500. store_builtin:
  6501. return (builtin_array_length(s, retval, two_dim));
  6502. }
  6503. /*
  6504. * Get and store the size of a "known" array.
  6505. * A wrapper for get_array_length(), for cases in which
  6506. * the name of the result to be stored is different from the
  6507. * structure.member to be evaluated.
  6508. */
  6509. int
  6510. get_array_length_alt(char *name, char *s, int *two_dim, long entry_size)
  6511. {
  6512. int retval;
  6513. retval = get_array_length(s, two_dim, entry_size);
  6514. if (retval)
  6515. retval = builtin_array_length(name, retval, two_dim);
  6516. return retval;
  6517. }
  6518. /*
  6519. * Designed for use by non-debug kernels, but used by all.
  6520. */
  6521. int
  6522. builtin_array_length(char *s, int len, int *two_dim)
  6523. {
  6524. int *lenptr;
  6525. int *dimptr;
  6526. lenptr = dimptr = NULL;
  6527. if (STREQ(s, "kmem_cache_s.name"))
  6528. lenptr = &array_table.kmem_cache_s_name;
  6529. else if (STREQ(s, "kmem_cache_s.c_name"))
  6530. lenptr = &array_table.kmem_cache_s_c_name;
  6531. else if (STREQ(s, "kmem_cache_s.array"))
  6532. lenptr = &array_table.kmem_cache_s_array;
  6533. else if (STREQ(s, "kmem_cache.array"))
  6534. lenptr = &array_table.kmem_cache_s_array;
  6535. else if (STREQ(s, "kmem_cache_s.cpudata"))
  6536. lenptr = &array_table.kmem_cache_s_cpudata;
  6537. else if (STREQ(s, "log_buf"))
  6538. lenptr = &array_table.log_buf;
  6539. else if (STREQ(s, "irq_desc") || STREQ(s, "_irq_desc"))
  6540. lenptr = &array_table.irq_desc;
  6541. else if (STREQ(s, "irq_action"))
  6542. lenptr = &array_table.irq_action;
  6543. else if (STREQ(s, "timer_vec.vec"))
  6544. lenptr = &array_table.timer_vec_vec;
  6545. else if (STREQ(s, "timer_vec_root.vec"))
  6546. lenptr = &array_table.timer_vec_root_vec;
  6547. else if (STREQ(s, "tvec_s.vec"))
  6548. lenptr = &array_table.tvec_s_vec;
  6549. else if (STREQ(s, "tvec_root_s.vec"))
  6550. lenptr = &array_table.tvec_root_s_vec;
  6551. else if (STREQ(s, "net_device.name"))
  6552. lenptr = &array_table.net_device_name;
  6553. else if (STREQ(s, "neigh_table.hash_buckets"))
  6554. lenptr = &array_table.neigh_table_hash_buckets;
  6555. else if (STREQ(s, "neighbour.ha"))
  6556. lenptr = &array_table.neighbour_ha;
  6557. else if (STREQ(s, "swap_info"))
  6558. lenptr = &array_table.swap_info;
  6559. else if (STREQ(s, "page_hash_table"))
  6560. lenptr = &array_table.page_hash_table;
  6561. else if (STREQ(s, "pglist_data.node_zones"))
  6562. lenptr = &array_table.pglist_data_node_zones;
  6563. else if (STREQ(s, "zone_struct.free_area"))
  6564. lenptr = &array_table.zone_struct_free_area;
  6565. else if (STREQ(s, "zone.free_area"))
  6566. lenptr = &array_table.zone_free_area;
  6567. else if (STREQ(s, "prio_array.queue"))
  6568. lenptr = &array_table.prio_array_queue;
  6569. else if (STREQ(s, "height_to_maxindex"))
  6570. lenptr = &array_table.height_to_maxindex;
  6571. else if (STREQ(s, "pid_hash"))
  6572. lenptr = &array_table.pid_hash;
  6573. else if (STREQ(s, "free_area")) {
  6574. lenptr = &array_table.free_area;
  6575. if (two_dim)
  6576. dimptr = &array_table.free_area_DIMENSION;
  6577. } else if (STREQ(s, "kmem_cache.node"))
  6578. lenptr = &array_table.kmem_cache_node;
  6579. else if (STREQ(s, "kmem_cache.cpu_slab"))
  6580. lenptr = &array_table.kmem_cache_cpu_slab;
  6581. else if (STREQ(s, "rt_prio_array.queue"))
  6582. lenptr = &array_table.rt_prio_array_queue;
  6583. if (!lenptr) /* not stored */
  6584. return(len);
  6585. if (*lenptr) { /* pre-set */
  6586. if (dimptr && two_dim)
  6587. *two_dim = *dimptr;
  6588. return(*lenptr);
  6589. }
  6590. if (len) {
  6591. *lenptr = len; /* initialize passed-in value(s) */
  6592. if (dimptr && two_dim)
  6593. *dimptr = *two_dim;
  6594. return(len);
  6595. }
  6596. return(0); /* in table, but not set yet */
  6597. }
  6598. /*
  6599. * "help -o" output
  6600. */
  6601. void
  6602. dump_offset_table(char *spec, ulong makestruct)
  6603. {
  6604. char buf[BUFSIZE], *p1;
  6605. char revname[BUFSIZE];
  6606. struct new_utsname *uts;
  6607. long long data_debug;
  6608. data_debug = pc->flags & DATADEBUG;
  6609. pc->flags &= ~DATADEBUG;
  6610. uts = NULL;
  6611. if (makestruct) {
  6612. uts = &kt->utsname;
  6613. sprintf(revname, "%s_%s", pc->machine_type, uts->release);
  6614. p1 = revname + strlen(pc->machine_type);
  6615. while (*p1) {
  6616. if (((*p1 >= '0') && (*p1 <= '9')) ||
  6617. ((*p1 >= 'a') && (*p1 <= 'z')) ||
  6618. ((*p1 >= 'A') && (*p1 <= 'Z')))
  6619. p1++;
  6620. else
  6621. *p1++ = '_';
  6622. }
  6623. }
  6624. if (spec || makestruct)
  6625. open_tmpfile();
  6626. fprintf(fp, " offset_table:\n");
  6627. fprintf(fp, " list_head_next: %ld\n",
  6628. OFFSET(list_head_next));
  6629. fprintf(fp, " list_head_prev: %ld\n",
  6630. OFFSET(list_head_prev));
  6631. fprintf(fp, " task_struct_pid: %ld\n",
  6632. OFFSET(task_struct_pid));
  6633. fprintf(fp, " task_struct_state: %ld\n",
  6634. OFFSET(task_struct_state));
  6635. fprintf(fp, " task_struct_exit_state: %ld\n",
  6636. OFFSET(task_struct_exit_state));
  6637. fprintf(fp, " task_struct_comm: %ld\n",
  6638. OFFSET(task_struct_comm));
  6639. fprintf(fp, " task_struct_mm: %ld\n",
  6640. OFFSET(task_struct_mm));
  6641. fprintf(fp, " task_struct_tss: %ld\n",
  6642. OFFSET(task_struct_tss));
  6643. fprintf(fp, " task_struct_thread: %ld\n",
  6644. OFFSET(task_struct_thread));
  6645. fprintf(fp, " task_struct_active_mm: %ld\n",
  6646. OFFSET(task_struct_active_mm));
  6647. fprintf(fp, " task_struct_tss_eip: %ld\n",
  6648. OFFSET(task_struct_tss_eip));
  6649. fprintf(fp, " task_struct_tss_esp: %ld\n",
  6650. OFFSET(task_struct_tss_esp));
  6651. fprintf(fp, " task_struct_tss_ksp: %ld\n",
  6652. OFFSET(task_struct_tss_ksp));
  6653. fprintf(fp, " task_struct_thread_eip: %ld\n",
  6654. OFFSET(task_struct_thread_eip));
  6655. fprintf(fp, " task_struct_thread_esp: %ld\n",
  6656. OFFSET(task_struct_thread_esp));
  6657. fprintf(fp, " task_struct_thread_ksp: %ld\n",
  6658. OFFSET(task_struct_thread_ksp));
  6659. fprintf(fp, " task_struct_thread_context_fp: %ld\n",
  6660. OFFSET(task_struct_thread_context_fp));
  6661. fprintf(fp, " task_struct_thread_context_sp: %ld\n",
  6662. OFFSET(task_struct_thread_context_sp));
  6663. fprintf(fp, " task_struct_thread_context_pc: %ld\n",
  6664. OFFSET(task_struct_thread_context_pc));
  6665. fprintf(fp, " task_struct_processor: %ld\n",
  6666. OFFSET(task_struct_processor));
  6667. fprintf(fp, " task_struct_p_pptr: %ld\n",
  6668. OFFSET(task_struct_p_pptr));
  6669. fprintf(fp, " task_struct_parent: %ld\n",
  6670. OFFSET(task_struct_parent));
  6671. fprintf(fp, " task_struct_has_cpu: %ld\n",
  6672. OFFSET(task_struct_has_cpu));
  6673. fprintf(fp, " task_struct_cpus_runnable: %ld\n",
  6674. OFFSET(task_struct_cpus_runnable));
  6675. fprintf(fp, " task_struct_next_task: %ld\n",
  6676. OFFSET(task_struct_next_task));
  6677. fprintf(fp, " task_struct_files: %ld\n",
  6678. OFFSET(task_struct_files));
  6679. fprintf(fp, " task_struct_fs: %ld\n",
  6680. OFFSET(task_struct_fs));
  6681. fprintf(fp, " task_struct_pidhash_next: %ld\n",
  6682. OFFSET(task_struct_pidhash_next));
  6683. fprintf(fp, " task_struct_next_run: %ld\n",
  6684. OFFSET(task_struct_next_run));
  6685. fprintf(fp, " task_struct_flags: %ld\n",
  6686. OFFSET(task_struct_flags));
  6687. fprintf(fp, " task_struct_sig: %ld\n",
  6688. OFFSET(task_struct_sig));
  6689. fprintf(fp, " task_struct_signal: %ld\n",
  6690. OFFSET(task_struct_signal));
  6691. fprintf(fp, " task_struct_blocked: %ld\n",
  6692. OFFSET(task_struct_blocked));
  6693. fprintf(fp, " task_struct_sigpending: %ld\n",
  6694. OFFSET(task_struct_sigpending));
  6695. fprintf(fp, " task_struct_pending: %ld\n",
  6696. OFFSET(task_struct_pending));
  6697. fprintf(fp, " task_struct_sigqueue: %ld\n",
  6698. OFFSET(task_struct_sigqueue));
  6699. fprintf(fp, " task_struct_sighand: %ld\n",
  6700. OFFSET(task_struct_sighand));
  6701. fprintf(fp, " task_struct_run_list: %ld\n",
  6702. OFFSET(task_struct_run_list));
  6703. fprintf(fp, " task_struct_pgrp: %ld\n",
  6704. OFFSET(task_struct_pgrp));
  6705. fprintf(fp, " task_struct_tgid: %ld\n",
  6706. OFFSET(task_struct_tgid));
  6707. fprintf(fp, " task_struct_namespace: %ld\n",
  6708. OFFSET(task_struct_namespace));
  6709. fprintf(fp, " task_struct_rss_stat: %ld\n",
  6710. OFFSET(task_struct_rss_stat));
  6711. fprintf(fp, " task_rss_stat_count: %ld\n",
  6712. OFFSET(task_rss_stat_count));
  6713. fprintf(fp, " task_struct_pids: %ld\n",
  6714. OFFSET(task_struct_pids));
  6715. fprintf(fp, " task_struct_last_run: %ld\n",
  6716. OFFSET(task_struct_last_run));
  6717. fprintf(fp, " task_struct_timestamp: %ld\n",
  6718. OFFSET(task_struct_timestamp));
  6719. fprintf(fp, " task_struct_sched_info: %ld\n",
  6720. OFFSET(task_struct_sched_info));
  6721. fprintf(fp, " task_struct_rt: %ld\n",
  6722. OFFSET(task_struct_rt));
  6723. fprintf(fp, " sched_rt_entity_run_list: %ld\n",
  6724. OFFSET(sched_rt_entity_run_list));
  6725. fprintf(fp, " sched_info_last_arrival: %ld\n",
  6726. OFFSET(sched_info_last_arrival));
  6727. fprintf(fp, " task_struct_thread_info: %ld\n",
  6728. OFFSET(task_struct_thread_info));
  6729. fprintf(fp, " task_struct_nsproxy: %ld\n",
  6730. OFFSET(task_struct_nsproxy));
  6731. fprintf(fp, " task_struct_rlim: %ld\n",
  6732. OFFSET(task_struct_rlim));
  6733. fprintf(fp, " task_struct_prio: %ld\n",
  6734. OFFSET(task_struct_prio));
  6735. fprintf(fp, " task_struct_on_rq: %ld\n",
  6736. OFFSET(task_struct_on_rq));
  6737. fprintf(fp, " thread_info_task: %ld\n",
  6738. OFFSET(thread_info_task));
  6739. fprintf(fp, " thread_info_cpu: %ld\n",
  6740. OFFSET(thread_info_cpu));
  6741. fprintf(fp, " thread_info_flags: %ld\n",
  6742. OFFSET(thread_info_flags));
  6743. fprintf(fp, " thread_info_previous_esp: %ld\n",
  6744. OFFSET(thread_info_previous_esp));
  6745. fprintf(fp, " nsproxy_mnt_ns: %ld\n",
  6746. OFFSET(nsproxy_mnt_ns));
  6747. fprintf(fp, " mnt_namespace_root: %ld\n",
  6748. OFFSET(mnt_namespace_root));
  6749. fprintf(fp, " mnt_namespace_list: %ld\n",
  6750. OFFSET(mnt_namespace_list));
  6751. fprintf(fp, " pid_link_pid: %ld\n",
  6752. OFFSET(pid_link_pid));
  6753. fprintf(fp, " pid_hash_chain: %ld\n",
  6754. OFFSET(pid_hash_chain));
  6755. fprintf(fp, " pid_numbers: %ld\n",
  6756. OFFSET(pid_numbers));
  6757. fprintf(fp, " upid_nr: %ld\n",
  6758. OFFSET(upid_nr));
  6759. fprintf(fp, " upid_ns: %ld\n",
  6760. OFFSET(upid_ns));
  6761. fprintf(fp, " upid_pid_chain: %ld\n",
  6762. OFFSET(upid_pid_chain));
  6763. fprintf(fp, " pid_tasks: %ld\n",
  6764. OFFSET(pid_tasks));
  6765. fprintf(fp, " hlist_node_next: %ld\n",
  6766. OFFSET(hlist_node_next));
  6767. fprintf(fp, " hlist_node_pprev: %ld\n",
  6768. OFFSET(hlist_node_pprev));
  6769. fprintf(fp, " pid_pid_chain: %ld\n",
  6770. OFFSET(pid_pid_chain));
  6771. fprintf(fp, " thread_struct_eip: %ld\n",
  6772. OFFSET(thread_struct_eip));
  6773. fprintf(fp, " thread_struct_esp: %ld\n",
  6774. OFFSET(thread_struct_esp));
  6775. fprintf(fp, " thread_struct_ksp: %ld\n",
  6776. OFFSET(thread_struct_ksp));
  6777. fprintf(fp, " thread_struct_rip: %ld\n",
  6778. OFFSET(thread_struct_rip));
  6779. fprintf(fp, " thread_struct_rsp: %ld\n",
  6780. OFFSET(thread_struct_rsp));
  6781. fprintf(fp, " thread_struct_rsp0: %ld\n",
  6782. OFFSET(thread_struct_rsp0));
  6783. fprintf(fp, " signal_struct_count: %ld\n",
  6784. OFFSET(signal_struct_count));
  6785. fprintf(fp, " signal_struct_nr_threads: %ld\n",
  6786. OFFSET(signal_struct_nr_threads));
  6787. fprintf(fp, " signal_struct_action: %ld\n",
  6788. OFFSET(signal_struct_action));
  6789. fprintf(fp, " signal_struct_shared_pending: %ld\n",
  6790. OFFSET(signal_struct_shared_pending));
  6791. fprintf(fp, " signal_struct_rlim: %ld\n",
  6792. OFFSET(signal_struct_rlim));
  6793. fprintf(fp, " task_struct_start_time: %ld\n",
  6794. OFFSET(task_struct_start_time));
  6795. fprintf(fp, " task_struct_times: %ld\n",
  6796. OFFSET(task_struct_times));
  6797. fprintf(fp, " task_struct_cpu: %ld\n",
  6798. OFFSET(task_struct_cpu));
  6799. fprintf(fp, " task_struct_utime: %ld\n",
  6800. OFFSET(task_struct_utime));
  6801. fprintf(fp, " task_struct_stime: %ld\n",
  6802. OFFSET(task_struct_stime));
  6803. fprintf(fp, " tms_tms_utime: %ld\n",
  6804. OFFSET(tms_tms_utime));
  6805. fprintf(fp, " tms_tms_stime: %ld\n",
  6806. OFFSET(tms_tms_stime));
  6807. fprintf(fp, " timekeeper_xtime: %ld\n",
  6808. OFFSET(timekeeper_xtime));
  6809. fprintf(fp, " timekeeper_xtime_sec: %ld\n",
  6810. OFFSET(timekeeper_xtime_sec));
  6811. fprintf(fp, " k_sigaction_sa: %ld\n",
  6812. OFFSET(k_sigaction_sa));
  6813. fprintf(fp, " sigaction_sa_handler: %ld\n",
  6814. OFFSET(sigaction_sa_handler));
  6815. fprintf(fp, " sigaction_sa_flags: %ld\n",
  6816. OFFSET(sigaction_sa_flags));
  6817. fprintf(fp, " sigaction_sa_mask: %ld\n",
  6818. OFFSET(sigaction_sa_mask));
  6819. fprintf(fp, " sigpending_head: %ld\n",
  6820. OFFSET(sigpending_head));
  6821. fprintf(fp, " sigpending_signal: %ld\n",
  6822. OFFSET(sigpending_signal));
  6823. fprintf(fp, " sigpending_list: %ld\n",
  6824. OFFSET(sigpending_list));
  6825. fprintf(fp, " signal_queue_next: %ld\n",
  6826. OFFSET(signal_queue_next));
  6827. fprintf(fp, " signal_queue_info: %ld\n",
  6828. OFFSET(signal_queue_info));
  6829. fprintf(fp, " sigqueue_next: %ld\n",
  6830. OFFSET(sigqueue_next));
  6831. fprintf(fp, " sigqueue_info: %ld\n",
  6832. OFFSET(sigqueue_info));
  6833. fprintf(fp, " sigqueue_list: %ld\n",
  6834. OFFSET(sigqueue_list));
  6835. fprintf(fp, " sighand_struct_action: %ld\n",
  6836. OFFSET(sighand_struct_action));
  6837. fprintf(fp, " siginfo_si_signo: %ld\n",
  6838. OFFSET(siginfo_si_signo));
  6839. fprintf(fp, " thread_struct_fph: %ld\n",
  6840. OFFSET(thread_struct_fph));
  6841. fprintf(fp, " thread_struct_cr3: %ld\n",
  6842. OFFSET(thread_struct_cr3));
  6843. fprintf(fp, " thread_struct_ptbr: %ld\n",
  6844. OFFSET(thread_struct_ptbr));
  6845. fprintf(fp, " thread_struct_pg_tables: %ld\n",
  6846. OFFSET(thread_struct_pg_tables));
  6847. fprintf(fp, " switch_stack_r26: %ld\n",
  6848. OFFSET(switch_stack_r26));
  6849. fprintf(fp, " switch_stack_b0: %ld\n",
  6850. OFFSET(switch_stack_b0));
  6851. fprintf(fp, " switch_stack_ar_bspstore: %ld\n",
  6852. OFFSET(switch_stack_ar_bspstore));
  6853. fprintf(fp, " switch_stack_ar_pfs: %ld\n",
  6854. OFFSET(switch_stack_ar_pfs));
  6855. fprintf(fp, " switch_stack_ar_rnat: %ld\n",
  6856. OFFSET(switch_stack_ar_rnat));
  6857. fprintf(fp, " switch_stack_pr: %ld\n",
  6858. OFFSET(switch_stack_pr));
  6859. fprintf(fp, " cpuinfo_ia64_proc_freq: %ld\n",
  6860. OFFSET(cpuinfo_ia64_proc_freq));
  6861. fprintf(fp, " cpuinfo_ia64_unimpl_va_mask: %ld\n",
  6862. OFFSET(cpuinfo_ia64_unimpl_va_mask));
  6863. fprintf(fp, " cpuinfo_ia64_unimpl_pa_mask: %ld\n",
  6864. OFFSET(cpuinfo_ia64_unimpl_pa_mask));
  6865. fprintf(fp, " device_node_type: %ld\n",
  6866. OFFSET(device_node_type));
  6867. fprintf(fp, " device_node_allnext: %ld\n",
  6868. OFFSET(device_node_allnext));
  6869. fprintf(fp, " device_node_properties: %ld\n",
  6870. OFFSET(device_node_properties));
  6871. fprintf(fp, " property_name: %ld\n",
  6872. OFFSET(property_name));
  6873. fprintf(fp, " property_value: %ld\n",
  6874. OFFSET(property_value));
  6875. fprintf(fp, " property_next: %ld\n",
  6876. OFFSET(property_next));
  6877. fprintf(fp, " machdep_calls_setup_residual: %ld\n",
  6878. OFFSET(machdep_calls_setup_residual));
  6879. fprintf(fp, " RESIDUAL_VitalProductData: %ld\n",
  6880. OFFSET(RESIDUAL_VitalProductData));
  6881. fprintf(fp, " VPD_ProcessorHz: %ld\n",
  6882. OFFSET(VPD_ProcessorHz));
  6883. fprintf(fp, " bd_info_bi_intfreq: %ld\n",
  6884. OFFSET(bd_info_bi_intfreq));
  6885. fprintf(fp, " hwrpb_struct_cycle_freq: %ld\n",
  6886. OFFSET(hwrpb_struct_cycle_freq));
  6887. fprintf(fp, " hwrpb_struct_processor_offset: %ld\n",
  6888. OFFSET(hwrpb_struct_processor_offset));
  6889. fprintf(fp, " hwrpb_struct_processor_size: %ld\n",
  6890. OFFSET(hwrpb_struct_processor_size));
  6891. fprintf(fp, " percpu_struct_halt_PC: %ld\n",
  6892. OFFSET(percpu_struct_halt_PC));
  6893. fprintf(fp, " percpu_struct_halt_ra: %ld\n",
  6894. OFFSET(percpu_struct_halt_ra));
  6895. fprintf(fp, " percpu_struct_halt_pv: %ld\n",
  6896. OFFSET(percpu_struct_halt_pv));
  6897. fprintf(fp, " mm_struct_mmap: %ld\n",
  6898. OFFSET(mm_struct_mmap));
  6899. fprintf(fp, " mm_struct_pgd: %ld\n",
  6900. OFFSET(mm_struct_pgd));
  6901. fprintf(fp, " mm_struct_rss: %ld\n",
  6902. OFFSET(mm_struct_rss));
  6903. fprintf(fp, " mm_struct_anon_rss: %ld\n",
  6904. OFFSET(mm_struct_anon_rss));
  6905. fprintf(fp, " mm_struct_file_rss: %ld\n",
  6906. OFFSET(mm_struct_file_rss));
  6907. fprintf(fp, " mm_struct_total_vm: %ld\n",
  6908. OFFSET(mm_struct_total_vm));
  6909. fprintf(fp, " mm_struct_start_code: %ld\n",
  6910. OFFSET(mm_struct_start_code));
  6911. fprintf(fp, " mm_struct_arg_start: %ld\n",
  6912. OFFSET(mm_struct_arg_start));
  6913. fprintf(fp, " mm_struct_arg_end: %ld\n",
  6914. OFFSET(mm_struct_arg_end));
  6915. fprintf(fp, " mm_struct_env_start: %ld\n",
  6916. OFFSET(mm_struct_env_start));
  6917. fprintf(fp, " mm_struct_env_end: %ld\n",
  6918. OFFSET(mm_struct_env_end));
  6919. fprintf(fp, " mm_struct_rss_stat: %ld\n",
  6920. OFFSET(mm_struct_rss_stat));
  6921. fprintf(fp, " mm_rss_stat_count: %ld\n",
  6922. OFFSET(mm_rss_stat_count));
  6923. fprintf(fp, " vm_area_struct_vm_mm: %ld\n",
  6924. OFFSET(vm_area_struct_vm_mm));
  6925. fprintf(fp, " vm_area_struct_vm_next: %ld\n",
  6926. OFFSET(vm_area_struct_vm_next));
  6927. fprintf(fp, " vm_area_struct_vm_start: %ld\n",
  6928. OFFSET(vm_area_struct_vm_start));
  6929. fprintf(fp, " vm_area_struct_vm_end: %ld\n",
  6930. OFFSET(vm_area_struct_vm_end));
  6931. fprintf(fp, " vm_area_struct_vm_flags: %ld\n",
  6932. OFFSET(vm_area_struct_vm_flags));
  6933. fprintf(fp, " vm_area_struct_vm_file: %ld\n",
  6934. OFFSET(vm_area_struct_vm_file));
  6935. fprintf(fp, " vm_area_struct_vm_offset: %ld\n",
  6936. OFFSET(vm_area_struct_vm_offset));
  6937. fprintf(fp, " vm_area_struct_vm_pgoff: %ld\n",
  6938. OFFSET(vm_area_struct_vm_pgoff));
  6939. fprintf(fp, " vm_struct_addr: %ld\n",
  6940. OFFSET(vm_struct_addr));
  6941. fprintf(fp, " vm_struct_size: %ld\n",
  6942. OFFSET(vm_struct_size));
  6943. fprintf(fp, " vm_struct_next: %ld\n",
  6944. OFFSET(vm_struct_next));
  6945. fprintf(fp, " vmap_area_va_start: %ld\n",
  6946. OFFSET(vmap_area_va_start));
  6947. fprintf(fp, " vmap_area_va_end: %ld\n",
  6948. OFFSET(vmap_area_va_end));
  6949. fprintf(fp, " vmap_area_list: %ld\n",
  6950. OFFSET(vmap_area_list));
  6951. fprintf(fp, " vmap_area_vm: %ld\n",
  6952. OFFSET(vmap_area_vm));
  6953. fprintf(fp, " vmap_area_flags: %ld\n",
  6954. OFFSET(vmap_area_flags));
  6955. fprintf(fp, " module_size_of_struct: %ld\n",
  6956. OFFSET(module_size_of_struct));
  6957. fprintf(fp, " module_next: %ld\n",
  6958. OFFSET(module_next));
  6959. fprintf(fp, " module_name: %ld\n",
  6960. OFFSET(module_name));
  6961. fprintf(fp, " module_syms: %ld\n",
  6962. OFFSET(module_syms));
  6963. fprintf(fp, " module_nsyms: %ld\n",
  6964. OFFSET(module_nsyms));
  6965. fprintf(fp, " module_size: %ld\n",
  6966. OFFSET(module_size));
  6967. fprintf(fp, " module_flags: %ld\n",
  6968. OFFSET(module_flags));
  6969. fprintf(fp, " module_num_syms: %ld\n",
  6970. OFFSET(module_num_syms));
  6971. fprintf(fp, " module_gpl_syms: %ld\n",
  6972. OFFSET(module_gpl_syms));
  6973. fprintf(fp, " module_num_gpl_syms: %ld\n",
  6974. OFFSET(module_num_gpl_syms));
  6975. fprintf(fp, " module_list: %ld\n",
  6976. OFFSET(module_list));
  6977. fprintf(fp, " module_module_core: %ld\n",
  6978. OFFSET(module_module_core));
  6979. fprintf(fp, " module_core_size: %ld\n",
  6980. OFFSET(module_core_size));
  6981. fprintf(fp, " module_core_text_size: %ld\n",
  6982. OFFSET(module_core_text_size));
  6983. fprintf(fp, " module_init_size: %ld\n",
  6984. OFFSET(module_init_size));
  6985. fprintf(fp, " module_init_text_size: %ld\n",
  6986. OFFSET(module_init_text_size));
  6987. fprintf(fp, " module_module_init: %ld\n",
  6988. OFFSET(module_module_init));
  6989. fprintf(fp, " module_num_symtab: %ld\n",
  6990. OFFSET(module_num_symtab));
  6991. fprintf(fp, " module_symtab: %ld\n",
  6992. OFFSET(module_symtab));
  6993. fprintf(fp, " module_strtab: %ld\n",
  6994. OFFSET(module_strtab));
  6995. fprintf(fp, " module_percpu: %ld\n",
  6996. OFFSET(module_percpu));
  6997. fprintf(fp, " module_sect_attrs: %ld\n",
  6998. OFFSET(module_sect_attrs));
  6999. fprintf(fp, " module_sect_attrs_attrs: %ld\n",
  7000. OFFSET(module_sect_attrs_attrs));
  7001. fprintf(fp, " module_sect_attrs_nsections: %ld\n",
  7002. OFFSET(module_sect_attrs_nsections));
  7003. fprintf(fp, " module_sect_attr_mattr: %ld\n",
  7004. OFFSET(module_sect_attr_mattr));
  7005. fprintf(fp, " module_sect_attr_name: %ld\n",
  7006. OFFSET(module_sect_attr_name));
  7007. fprintf(fp, " module_sect_attr_address: %ld\n",
  7008. OFFSET(module_sect_attr_address));
  7009. fprintf(fp, " attribute_owner: %ld\n",
  7010. OFFSET(attribute_owner));
  7011. fprintf(fp, " module_sect_attr_attr: %ld\n",
  7012. OFFSET(module_sect_attr_attr));
  7013. fprintf(fp, " module_sections_attrs: %ld\n",
  7014. OFFSET(module_sections_attrs));
  7015. fprintf(fp, " module_attribute_attr: %ld\n",
  7016. OFFSET(module_attribute_attr));
  7017. fprintf(fp, " module_kallsyms_start: %ld\n",
  7018. OFFSET(module_kallsyms_start));
  7019. fprintf(fp, " kallsyms_header_sections: %ld\n",
  7020. OFFSET(kallsyms_header_sections));
  7021. fprintf(fp, " kallsyms_header_section_off: %ld\n",
  7022. OFFSET(kallsyms_header_section_off));
  7023. fprintf(fp, " kallsyms_header_symbols: %ld\n",
  7024. OFFSET(kallsyms_header_symbols));
  7025. fprintf(fp, " kallsyms_header_symbol_off: %ld\n",
  7026. OFFSET(kallsyms_header_symbol_off));
  7027. fprintf(fp, " kallsyms_header_string_off: %ld\n",
  7028. OFFSET(kallsyms_header_string_off));
  7029. fprintf(fp, " kallsyms_symbol_section_off: %ld\n",
  7030. OFFSET(kallsyms_symbol_section_off));
  7031. fprintf(fp, " kallsyms_symbol_symbol_addr: %ld\n",
  7032. OFFSET(kallsyms_symbol_symbol_addr));
  7033. fprintf(fp, " kallsyms_symbol_name_off: %ld\n",
  7034. OFFSET(kallsyms_symbol_name_off));
  7035. fprintf(fp, " kallsyms_section_start: %ld\n",
  7036. OFFSET(kallsyms_section_start));
  7037. fprintf(fp, " kallsyms_section_size: %ld\n",
  7038. OFFSET(kallsyms_section_size));
  7039. fprintf(fp, " kallsyms_section_name_off: %ld\n",
  7040. OFFSET(kallsyms_section_name_off));
  7041. fprintf(fp, " module_taints: %ld\n",
  7042. OFFSET(module_taints));
  7043. fprintf(fp, " module_license_gplok: %ld\n",
  7044. OFFSET(module_license_gplok));
  7045. fprintf(fp, " module_gpgsig_ok: %ld\n",
  7046. OFFSET(module_gpgsig_ok));
  7047. fprintf(fp, " tnt_bit: %ld\n", OFFSET(tnt_bit));
  7048. fprintf(fp, " tnt_true: %ld\n", OFFSET(tnt_true));
  7049. fprintf(fp, " tnt_false: %ld\n", OFFSET(tnt_false));
  7050. fprintf(fp, " page_next: %ld\n", OFFSET(page_next));
  7051. fprintf(fp, " page_prev: %ld\n", OFFSET(page_prev));
  7052. fprintf(fp, " page_next_hash: %ld\n",
  7053. OFFSET(page_next_hash));
  7054. fprintf(fp, " page_list: %ld\n",
  7055. OFFSET(page_list));
  7056. fprintf(fp, " page_list_next: %ld\n",
  7057. OFFSET(page_list_next));
  7058. fprintf(fp, " page_list_prev: %ld\n",
  7059. OFFSET(page_list_prev));
  7060. fprintf(fp, " page_inode: %ld\n",
  7061. OFFSET(page_inode));
  7062. fprintf(fp, " page_offset: %ld\n",
  7063. OFFSET(page_offset));
  7064. fprintf(fp, " page_count: %ld\n",
  7065. OFFSET(page_count));
  7066. fprintf(fp, " page_flags: %ld\n",
  7067. OFFSET(page_flags));
  7068. fprintf(fp, " page_mapping: %ld\n",
  7069. OFFSET(page_mapping));
  7070. fprintf(fp, " page_index: %ld\n",
  7071. OFFSET(page_index));
  7072. fprintf(fp, " page_buffers: %ld\n",
  7073. OFFSET(page_buffers));
  7074. fprintf(fp, " page_lru: %ld\n",
  7075. OFFSET(page_lru));
  7076. fprintf(fp, " page_pte: %ld\n",
  7077. OFFSET(page_pte));
  7078. fprintf(fp, " page_inuse: %ld\n",
  7079. OFFSET(page_inuse));
  7080. fprintf(fp, " page_objects: %ld\n",
  7081. OFFSET(page_objects));
  7082. fprintf(fp, " page_slab: %ld\n",
  7083. OFFSET(page_slab));
  7084. fprintf(fp, " page_slab_page: %ld\n",
  7085. OFFSET(page_slab_page));
  7086. fprintf(fp, " page_first_page: %ld\n",
  7087. OFFSET(page_first_page));
  7088. fprintf(fp, " page_freelist: %ld\n",
  7089. OFFSET(page_freelist));
  7090. fprintf(fp, " page_s_mem: %ld\n",
  7091. OFFSET(page_s_mem));
  7092. fprintf(fp, " page_active: %ld\n",
  7093. OFFSET(page_active));
  7094. fprintf(fp, " trace_print_flags_mask: %ld\n",
  7095. OFFSET(trace_print_flags_mask));
  7096. fprintf(fp, " trace_print_flags_name: %ld\n",
  7097. OFFSET(trace_print_flags_name));
  7098. fprintf(fp, " swap_info_struct_swap_file: %ld\n",
  7099. OFFSET(swap_info_struct_swap_file));
  7100. fprintf(fp, " swap_info_struct_swap_vfsmnt: %ld\n",
  7101. OFFSET(swap_info_struct_swap_vfsmnt));
  7102. fprintf(fp, " swap_info_struct_flags: %ld\n",
  7103. OFFSET(swap_info_struct_flags));
  7104. fprintf(fp, " swap_info_struct_swap_map: %ld\n",
  7105. OFFSET(swap_info_struct_swap_map));
  7106. fprintf(fp, " swap_info_struct_swap_device: %ld\n",
  7107. OFFSET(swap_info_struct_swap_device));
  7108. fprintf(fp, " swap_info_struct_prio: %ld\n",
  7109. OFFSET(swap_info_struct_prio));
  7110. fprintf(fp, " swap_info_struct_max: %ld\n",
  7111. OFFSET(swap_info_struct_max));
  7112. fprintf(fp, " swap_info_struct_pages: %ld\n",
  7113. OFFSET(swap_info_struct_pages));
  7114. fprintf(fp, " swap_info_struct_inuse_pages: %ld\n",
  7115. OFFSET(swap_info_struct_inuse_pages));
  7116. fprintf(fp, "swap_info_struct_old_block_size: %ld\n",
  7117. OFFSET(swap_info_struct_old_block_size));
  7118. fprintf(fp, " block_device_bd_inode: %ld\n",
  7119. OFFSET(block_device_bd_inode));
  7120. fprintf(fp, " block_device_bd_list: %ld\n",
  7121. OFFSET(block_device_bd_list));
  7122. fprintf(fp, " block_device_bd_disk: %ld\n",
  7123. OFFSET(block_device_bd_disk));
  7124. fprintf(fp, " address_space_nrpages: %ld\n",
  7125. OFFSET(address_space_nrpages));
  7126. fprintf(fp, " gendisk_major: %ld\n",
  7127. OFFSET(gendisk_major));
  7128. fprintf(fp, " gendisk_fops: %ld\n",
  7129. OFFSET(gendisk_fops));
  7130. fprintf(fp, " gendisk_disk_name: %ld\n",
  7131. OFFSET(gendisk_disk_name));
  7132. fprintf(fp, " irq_desc_t_status: %ld\n",
  7133. OFFSET(irq_desc_t_status));
  7134. fprintf(fp, " irq_desc_t_handler: %ld\n",
  7135. OFFSET(irq_desc_t_handler));
  7136. fprintf(fp, " irq_desc_t_chip: %ld\n",
  7137. OFFSET(irq_desc_t_chip));
  7138. fprintf(fp, " irq_desc_t_action: %ld\n",
  7139. OFFSET(irq_desc_t_action));
  7140. fprintf(fp, " irq_desc_t_depth: %ld\n",
  7141. OFFSET(irq_desc_t_depth));
  7142. fprintf(fp, " irqdesc_action: %ld\n",
  7143. OFFSET(irqdesc_action));
  7144. fprintf(fp, " irqdesc_ctl: %ld\n",
  7145. OFFSET(irqdesc_ctl));
  7146. fprintf(fp, " irqdesc_level: %ld\n",
  7147. OFFSET(irqdesc_level));
  7148. fprintf(fp, " irq_desc_t_irq_data: %ld\n",
  7149. OFFSET(irq_desc_t_irq_data));
  7150. fprintf(fp, " irq_desc_t_kstat_irqs: %ld\n",
  7151. OFFSET(irq_desc_t_kstat_irqs));
  7152. fprintf(fp, " irq_desc_t_affinity: %ld\n",
  7153. OFFSET(irq_desc_t_affinity));
  7154. fprintf(fp, " irq_data_chip: %ld\n",
  7155. OFFSET(irq_data_chip));
  7156. fprintf(fp, " irq_data_affinity: %ld\n",
  7157. OFFSET(irq_data_affinity));
  7158. fprintf(fp, " kernel_stat_irqs: %ld\n",
  7159. OFFSET(kernel_stat_irqs));
  7160. fprintf(fp, " irqaction_handler: %ld\n",
  7161. OFFSET(irqaction_handler));
  7162. fprintf(fp, " irqaction_flags: %ld\n",
  7163. OFFSET(irqaction_flags));
  7164. fprintf(fp, " irqaction_mask: %ld\n",
  7165. OFFSET(irqaction_mask));
  7166. fprintf(fp, " irqaction_name: %ld\n",
  7167. OFFSET(irqaction_name));
  7168. fprintf(fp, " irqaction_dev_id: %ld\n",
  7169. OFFSET(irqaction_dev_id));
  7170. fprintf(fp, " irqaction_next: %ld\n",
  7171. OFFSET(irqaction_next));
  7172. fprintf(fp, " hw_interrupt_type_typename: %ld\n",
  7173. OFFSET(hw_interrupt_type_typename));
  7174. fprintf(fp, " hw_interrupt_type_startup: %ld\n",
  7175. OFFSET(hw_interrupt_type_startup));
  7176. fprintf(fp, " hw_interrupt_type_shutdown: %ld\n",
  7177. OFFSET(hw_interrupt_type_shutdown));
  7178. fprintf(fp, " hw_interrupt_type_handle: %ld\n",
  7179. OFFSET(hw_interrupt_type_handle));
  7180. fprintf(fp, " hw_interrupt_type_enable: %ld\n",
  7181. OFFSET(hw_interrupt_type_enable));
  7182. fprintf(fp, " hw_interrupt_type_disable: %ld\n",
  7183. OFFSET(hw_interrupt_type_disable));
  7184. fprintf(fp, " hw_interrupt_type_ack: %ld\n",
  7185. OFFSET(hw_interrupt_type_ack));
  7186. fprintf(fp, " hw_interrupt_type_end: %ld\n",
  7187. OFFSET(hw_interrupt_type_end));
  7188. fprintf(fp, "hw_interrupt_type_set_affinity: %ld\n",
  7189. OFFSET(hw_interrupt_type_set_affinity));
  7190. fprintf(fp, " irq_chip_typename: %ld\n",
  7191. OFFSET(irq_chip_typename));
  7192. fprintf(fp, " irq_chip_startup: %ld\n",
  7193. OFFSET(irq_chip_startup));
  7194. fprintf(fp, " irq_chip_shutdown: %ld\n",
  7195. OFFSET(irq_chip_shutdown));
  7196. fprintf(fp, " irq_chip_enable: %ld\n",
  7197. OFFSET(irq_chip_enable));
  7198. fprintf(fp, " irq_chip_disable: %ld\n",
  7199. OFFSET(irq_chip_disable));
  7200. fprintf(fp, " irq_chip_ack: %ld\n",
  7201. OFFSET(irq_chip_ack));
  7202. fprintf(fp, " irq_chip_mask: %ld\n",
  7203. OFFSET(irq_chip_mask));
  7204. fprintf(fp, " irq_chip_mask_ack: %ld\n",
  7205. OFFSET(irq_chip_mask_ack));
  7206. fprintf(fp, " irq_chip_unmask: %ld\n",
  7207. OFFSET(irq_chip_unmask));
  7208. fprintf(fp, " irq_chip_eoi: %ld\n",
  7209. OFFSET(irq_chip_eoi));
  7210. fprintf(fp, " irq_chip_end: %ld\n",
  7211. OFFSET(irq_chip_end));
  7212. fprintf(fp, " irq_chip_set_affinity: %ld\n",
  7213. OFFSET(irq_chip_set_affinity));
  7214. fprintf(fp, " irq_chip_retrigger: %ld\n",
  7215. OFFSET(irq_chip_retrigger));
  7216. fprintf(fp, " irq_chip_set_type: %ld\n",
  7217. OFFSET(irq_chip_set_type));
  7218. fprintf(fp, " irq_chip_set_wake: %ld\n",
  7219. OFFSET(irq_chip_set_wake));
  7220. fprintf(fp, "irq_cpustat_t___softirq_active: %ld\n",
  7221. OFFSET(irq_cpustat_t___softirq_active));
  7222. fprintf(fp, " irq_cpustat_t___softirq_mask: %ld\n",
  7223. OFFSET(irq_cpustat_t___softirq_mask));
  7224. fprintf(fp, " files_struct_fdt: %ld\n",
  7225. OFFSET(files_struct_fdt));
  7226. fprintf(fp, " fdtable_max_fds: %ld\n",
  7227. OFFSET(fdtable_max_fds));
  7228. fprintf(fp, " fdtable_max_fdset: %ld\n",
  7229. OFFSET(fdtable_max_fdset));
  7230. fprintf(fp, " fdtable_open_fds: %ld\n",
  7231. OFFSET(fdtable_open_fds));
  7232. fprintf(fp, " fdtable_fd: %ld\n",
  7233. OFFSET(fdtable_fd));
  7234. fprintf(fp, " files_struct_max_fds: %ld\n",
  7235. OFFSET(files_struct_max_fds));
  7236. fprintf(fp, " files_struct_max_fdset: %ld\n",
  7237. OFFSET(files_struct_max_fdset));
  7238. fprintf(fp, " files_struct_open_fds: %ld\n",
  7239. OFFSET(files_struct_open_fds));
  7240. fprintf(fp, " files_struct_fd: %ld\n",
  7241. OFFSET(files_struct_fd));
  7242. fprintf(fp, " files_struct_open_fds_init: %ld\n",
  7243. OFFSET(files_struct_open_fds_init));
  7244. fprintf(fp, " file_f_dentry: %ld\n",
  7245. OFFSET(file_f_dentry));
  7246. fprintf(fp, " file_f_vfsmnt: %ld\n",
  7247. OFFSET(file_f_vfsmnt));
  7248. fprintf(fp, " file_f_count: %ld\n",
  7249. OFFSET(file_f_count));
  7250. fprintf(fp, " file_f_path: %ld\n",
  7251. OFFSET(file_f_path));
  7252. fprintf(fp, " path_mnt: %ld\n",
  7253. OFFSET(path_mnt));
  7254. fprintf(fp, " path_dentry: %ld\n",
  7255. OFFSET(path_dentry));
  7256. fprintf(fp, " fs_struct_root: %ld\n",
  7257. OFFSET(fs_struct_root));
  7258. fprintf(fp, " fs_struct_pwd: %ld\n",
  7259. OFFSET(fs_struct_pwd));
  7260. fprintf(fp, " fs_struct_rootmnt: %ld\n",
  7261. OFFSET(fs_struct_rootmnt));
  7262. fprintf(fp, " fs_struct_pwdmnt: %ld\n",
  7263. OFFSET(fs_struct_pwdmnt));
  7264. fprintf(fp, " dentry_d_inode: %ld\n",
  7265. OFFSET(dentry_d_inode));
  7266. fprintf(fp, " dentry_d_parent: %ld\n",
  7267. OFFSET(dentry_d_parent));
  7268. fprintf(fp, " dentry_d_name: %ld\n",
  7269. OFFSET(dentry_d_name));
  7270. fprintf(fp, " dentry_d_iname: %ld\n",
  7271. OFFSET(dentry_d_iname));
  7272. fprintf(fp, " dentry_d_covers: %ld\n",
  7273. OFFSET(dentry_d_covers));
  7274. fprintf(fp, " qstr_len: %ld\n", OFFSET(qstr_len));
  7275. fprintf(fp, " qstr_name: %ld\n", OFFSET(qstr_name));
  7276. fprintf(fp, " inode_i_mode: %ld\n",
  7277. OFFSET(inode_i_mode));
  7278. fprintf(fp, " inode_i_op: %ld\n",
  7279. OFFSET(inode_i_op));
  7280. fprintf(fp, " inode_i_sb: %ld\n",
  7281. OFFSET(inode_i_sb));
  7282. fprintf(fp, " inode_u: %ld\n", OFFSET(inode_u));
  7283. fprintf(fp, " inode_i_flock: %ld\n",
  7284. OFFSET(inode_i_flock));
  7285. fprintf(fp, " inode_i_fop: %ld\n",
  7286. OFFSET(inode_i_fop));
  7287. fprintf(fp, " inode_i_mapping: %ld\n",
  7288. OFFSET(inode_i_mapping));
  7289. fprintf(fp, " vfsmount_mnt_next: %ld\n",
  7290. OFFSET(vfsmount_mnt_next));
  7291. fprintf(fp, " vfsmount_mnt_devname: %ld\n",
  7292. OFFSET(vfsmount_mnt_devname));
  7293. fprintf(fp, " vfsmount_mnt_dirname: %ld\n",
  7294. OFFSET(vfsmount_mnt_dirname));
  7295. fprintf(fp, " vfsmount_mnt_sb: %ld\n",
  7296. OFFSET(vfsmount_mnt_sb));
  7297. fprintf(fp, " vfsmount_mnt_list: %ld\n",
  7298. OFFSET(vfsmount_mnt_list));
  7299. fprintf(fp, " vfsmount_mnt_mountpoint: %ld\n",
  7300. OFFSET(vfsmount_mnt_mountpoint));
  7301. fprintf(fp, " vfsmount_mnt_parent: %ld\n",
  7302. OFFSET(vfsmount_mnt_parent));
  7303. fprintf(fp, " mount_mnt_parent: %ld\n",
  7304. OFFSET(mount_mnt_parent));
  7305. fprintf(fp, " mount_mnt_mountpoint: %ld\n",
  7306. OFFSET(mount_mnt_mountpoint));
  7307. fprintf(fp, " mount_mnt_list: %ld\n",
  7308. OFFSET(mount_mnt_list));
  7309. fprintf(fp, " mount_mnt_devname: %ld\n",
  7310. OFFSET(mount_mnt_devname));
  7311. fprintf(fp, " mount_mnt: %ld\n",
  7312. OFFSET(mount_mnt));
  7313. fprintf(fp, " namespace_root: %ld\n",
  7314. OFFSET(namespace_root));
  7315. fprintf(fp, " namespace_list: %ld\n",
  7316. OFFSET(namespace_list));
  7317. fprintf(fp, " super_block_s_dirty: %ld\n",
  7318. OFFSET(super_block_s_dirty));
  7319. fprintf(fp, " super_block_s_type: %ld\n",
  7320. OFFSET(super_block_s_type));
  7321. fprintf(fp, " super_block_s_files: %ld\n",
  7322. OFFSET(super_block_s_files));
  7323. fprintf(fp, " nlm_file_f_file: %ld\n",
  7324. OFFSET(nlm_file_f_file));
  7325. fprintf(fp, " file_system_type_name: %ld\n",
  7326. OFFSET(file_system_type_name));
  7327. fprintf(fp, " file_lock_fl_owner: %ld\n",
  7328. OFFSET(file_lock_fl_owner));
  7329. fprintf(fp, " nlm_host_h_exportent: %ld\n",
  7330. OFFSET(nlm_host_h_exportent));
  7331. fprintf(fp, " svc_client_cl_ident: %ld\n",
  7332. OFFSET(svc_client_cl_ident));
  7333. fprintf(fp, " kmem_cache_s_c_nextp: %ld\n",
  7334. OFFSET(kmem_cache_s_c_nextp));
  7335. fprintf(fp, " kmem_cache_s_c_name: %ld\n",
  7336. OFFSET(kmem_cache_s_c_name));
  7337. fprintf(fp, " kmem_cache_s_c_num: %ld\n",
  7338. OFFSET(kmem_cache_s_c_num));
  7339. fprintf(fp, " kmem_cache_s_c_org_size: %ld\n",
  7340. OFFSET(kmem_cache_s_c_org_size));
  7341. fprintf(fp, " kmem_cache_s_c_flags: %ld\n",
  7342. OFFSET(kmem_cache_s_c_flags));
  7343. fprintf(fp, " kmem_cache_s_c_offset: %ld\n",
  7344. OFFSET(kmem_cache_s_c_offset));
  7345. fprintf(fp, " kmem_cache_s_c_firstp: %ld\n",
  7346. OFFSET(kmem_cache_s_c_firstp));
  7347. fprintf(fp, " kmem_cache_s_c_gfporder: %ld\n",
  7348. OFFSET(kmem_cache_s_c_gfporder));
  7349. fprintf(fp, " kmem_cache_s_c_magic: %ld\n",
  7350. OFFSET(kmem_cache_s_c_magic));
  7351. fprintf(fp, " kmem_cache_s_c_align: %ld\n",
  7352. OFFSET(kmem_cache_s_c_align));
  7353. fprintf(fp, " kmem_cache_s_num: %ld\n",
  7354. OFFSET(kmem_cache_s_num));
  7355. fprintf(fp, " kmem_cache_s_next: %ld\n",
  7356. OFFSET(kmem_cache_s_next));
  7357. fprintf(fp, " kmem_cache_s_name: %ld\n",
  7358. OFFSET(kmem_cache_s_name));
  7359. fprintf(fp, " kmem_cache_s_objsize: %ld\n",
  7360. OFFSET(kmem_cache_s_objsize));
  7361. fprintf(fp, " kmem_cache_s_flags: %ld\n",
  7362. OFFSET(kmem_cache_s_flags));
  7363. fprintf(fp, " kmem_cache_s_gfporder: %ld\n",
  7364. OFFSET(kmem_cache_s_gfporder));
  7365. fprintf(fp, " kmem_cache_s_slabs: %ld\n",
  7366. OFFSET(kmem_cache_s_slabs));
  7367. fprintf(fp, " kmem_cache_s_slabs_full: %ld\n",
  7368. OFFSET(kmem_cache_s_slabs_full));
  7369. fprintf(fp, " kmem_cache_s_slabs_partial: %ld\n",
  7370. OFFSET(kmem_cache_s_slabs_partial));
  7371. fprintf(fp, " kmem_cache_s_slabs_free: %ld\n",
  7372. OFFSET(kmem_cache_s_slabs_free));
  7373. fprintf(fp, " kmem_cache_s_cpudata: %ld\n",
  7374. OFFSET(kmem_cache_s_cpudata));
  7375. fprintf(fp, " kmem_cache_s_colour_off: %ld\n",
  7376. OFFSET(kmem_cache_s_colour_off));
  7377. fprintf(fp, " cpucache_s_avail: %ld\n",
  7378. OFFSET(cpucache_s_avail));
  7379. fprintf(fp, " cpucache_s_limit: %ld\n",
  7380. OFFSET(cpucache_s_limit));
  7381. fprintf(fp, " array_cache_avail: %ld\n",
  7382. OFFSET(array_cache_avail));
  7383. fprintf(fp, " array_cache_limit: %ld\n",
  7384. OFFSET(array_cache_limit));
  7385. fprintf(fp, " kmem_cache_s_array: %ld\n",
  7386. OFFSET(kmem_cache_s_array));
  7387. fprintf(fp, " kmem_cache_s_lists: %ld\n",
  7388. OFFSET(kmem_cache_s_lists));
  7389. fprintf(fp, " kmem_list3_slabs_partial: %ld\n",
  7390. OFFSET(kmem_list3_slabs_partial));
  7391. fprintf(fp, " kmem_list3_slabs_full: %ld\n",
  7392. OFFSET(kmem_list3_slabs_full));
  7393. fprintf(fp, " kmem_list3_slabs_free: %ld\n",
  7394. OFFSET(kmem_list3_slabs_free));
  7395. fprintf(fp, " kmem_list3_free_objects: %ld\n",
  7396. OFFSET(kmem_list3_free_objects));
  7397. fprintf(fp, " kmem_list3_shared: %ld\n",
  7398. OFFSET(kmem_list3_shared));
  7399. fprintf(fp, " kmem_slab_s_s_nextp: %ld\n",
  7400. OFFSET(kmem_slab_s_s_nextp));
  7401. fprintf(fp, " kmem_slab_s_s_freep: %ld\n",
  7402. OFFSET(kmem_slab_s_s_freep));
  7403. fprintf(fp, " kmem_slab_s_s_inuse: %ld\n",
  7404. OFFSET(kmem_slab_s_s_inuse));
  7405. fprintf(fp, " kmem_slab_s_s_mem: %ld\n",
  7406. OFFSET(kmem_slab_s_s_mem));
  7407. fprintf(fp, " kmem_slab_s_s_index: %ld\n",
  7408. OFFSET(kmem_slab_s_s_index));
  7409. fprintf(fp, " kmem_slab_s_s_offset: %ld\n",
  7410. OFFSET(kmem_slab_s_s_offset));
  7411. fprintf(fp, " kmem_slab_s_s_magic: %ld\n",
  7412. OFFSET(kmem_slab_s_s_magic));
  7413. fprintf(fp, " slab_s_list: %ld\n",
  7414. OFFSET(slab_s_list));
  7415. fprintf(fp, " slab_s_s_mem: %ld\n",
  7416. OFFSET(slab_s_s_mem));
  7417. fprintf(fp, " slab_s_inuse: %ld\n",
  7418. OFFSET(slab_s_inuse));
  7419. fprintf(fp, " slab_s_free: %ld\n",
  7420. OFFSET(slab_s_free));
  7421. fprintf(fp, " slab_list: %ld\n",
  7422. OFFSET(slab_list));
  7423. fprintf(fp, " slab_s_mem: %ld\n",
  7424. OFFSET(slab_s_mem));
  7425. fprintf(fp, " slab_inuse: %ld\n",
  7426. OFFSET(slab_inuse));
  7427. fprintf(fp, " slab_free: %ld\n",
  7428. OFFSET(slab_free));
  7429. fprintf(fp, " kmem_cache_size: %ld\n",
  7430. OFFSET(kmem_cache_size));
  7431. fprintf(fp, " kmem_cache_objsize: %ld\n",
  7432. OFFSET(kmem_cache_objsize));
  7433. fprintf(fp, " kmem_cache_offset: %ld\n",
  7434. OFFSET(kmem_cache_offset));
  7435. fprintf(fp, " kmem_cache_order: %ld\n",
  7436. OFFSET(kmem_cache_order));
  7437. fprintf(fp, " kmem_cache_local_node: %ld\n",
  7438. OFFSET(kmem_cache_local_node));
  7439. fprintf(fp, " kmem_cache_objects: %ld\n",
  7440. OFFSET(kmem_cache_objects));
  7441. fprintf(fp, " kmem_cache_inuse: %ld\n",
  7442. OFFSET(kmem_cache_inuse));
  7443. fprintf(fp, " kmem_cache_align: %ld\n",
  7444. OFFSET(kmem_cache_align));
  7445. fprintf(fp, " kmem_cache_name: %ld\n",
  7446. OFFSET(kmem_cache_name));
  7447. fprintf(fp, " kmem_cache_list: %ld\n",
  7448. OFFSET(kmem_cache_list));
  7449. fprintf(fp, " kmem_cache_node: %ld\n",
  7450. OFFSET(kmem_cache_node));
  7451. fprintf(fp, " kmem_cache_cpu_slab: %ld\n",
  7452. OFFSET(kmem_cache_cpu_slab));
  7453. fprintf(fp, " kmem_cache_cpu_partial: %ld\n",
  7454. OFFSET(kmem_cache_cpu_partial));
  7455. fprintf(fp, " kmem_cache_oo: %ld\n",
  7456. OFFSET(kmem_cache_oo));
  7457. fprintf(fp, " kmem_cache_node_nr_partial: %ld\n",
  7458. OFFSET(kmem_cache_node_nr_partial));
  7459. fprintf(fp, " kmem_cache_node_nr_slabs: %ld\n",
  7460. OFFSET(kmem_cache_node_nr_slabs));
  7461. fprintf(fp, " kmem_cache_node_partial: %ld\n",
  7462. OFFSET(kmem_cache_node_partial));
  7463. fprintf(fp, " kmem_cache_node_full: %ld\n",
  7464. OFFSET(kmem_cache_node_full));
  7465. fprintf(fp, " kmem_cache_cpu_freelist: %ld\n",
  7466. OFFSET(kmem_cache_cpu_freelist));
  7467. fprintf(fp, " kmem_cache_cpu_page: %ld\n",
  7468. OFFSET(kmem_cache_cpu_page));
  7469. fprintf(fp, " kmem_cache_cpu_node: %ld\n",
  7470. OFFSET(kmem_cache_cpu_node));
  7471. fprintf(fp, " kmem_cache_flags: %ld\n",
  7472. OFFSET(kmem_cache_flags));
  7473. fprintf(fp, " net_device_next: %ld\n",
  7474. OFFSET(net_device_next));
  7475. fprintf(fp, " net_device_name: %ld\n",
  7476. OFFSET(net_device_name));
  7477. fprintf(fp, " net_device_type: %ld\n",
  7478. OFFSET(net_device_type));
  7479. fprintf(fp, " net_device_addr_len: %ld\n",
  7480. OFFSET(net_device_addr_len));
  7481. fprintf(fp, " net_device_ip_ptr: %ld\n",
  7482. OFFSET(net_device_ip_ptr));
  7483. fprintf(fp, " net_device_dev_list: %ld\n",
  7484. OFFSET(net_device_dev_list));
  7485. fprintf(fp, " net_dev_base_head: %ld\n",
  7486. OFFSET(net_dev_base_head));
  7487. fprintf(fp, " device_next: %ld\n",
  7488. OFFSET(device_next));
  7489. fprintf(fp, " device_name: %ld\n",
  7490. OFFSET(device_name));
  7491. fprintf(fp, " device_type: %ld\n",
  7492. OFFSET(device_type));
  7493. fprintf(fp, " device_ip_ptr: %ld\n",
  7494. OFFSET(device_ip_ptr));
  7495. fprintf(fp, " device_addr_len: %ld\n",
  7496. OFFSET(device_addr_len));
  7497. fprintf(fp, " socket_sk: %ld\n", OFFSET(socket_sk));
  7498. fprintf(fp, " sock_daddr: %ld\n",
  7499. OFFSET(sock_daddr));
  7500. fprintf(fp, " sock_rcv_saddr: %ld\n",
  7501. OFFSET(sock_rcv_saddr));
  7502. fprintf(fp, " sock_dport: %ld\n",
  7503. OFFSET(sock_dport));
  7504. fprintf(fp, " sock_sport: %ld\n",
  7505. OFFSET(sock_sport));
  7506. fprintf(fp, " sock_num: %ld\n", OFFSET(sock_num));
  7507. fprintf(fp, " sock_family: %ld\n",
  7508. OFFSET(sock_family));
  7509. fprintf(fp, " sock_type: %ld\n", OFFSET(sock_type));
  7510. fprintf(fp, " sock_sk_type: %ld\n",
  7511. OFFSET(sock_sk_type));
  7512. fprintf(fp, " sock_common_skc_family: %ld\n",
  7513. OFFSET(sock_common_skc_family));
  7514. fprintf(fp, " socket_alloc_vfs_inode: %ld\n",
  7515. OFFSET(socket_alloc_vfs_inode));
  7516. fprintf(fp, " inet_sock_inet: %ld\n",
  7517. OFFSET(inet_sock_inet));
  7518. fprintf(fp, " inet_opt_daddr: %ld\n",
  7519. OFFSET(inet_opt_daddr));
  7520. fprintf(fp, " inet_opt_rcv_saddr: %ld\n",
  7521. OFFSET(inet_opt_rcv_saddr));
  7522. fprintf(fp, " inet_opt_dport: %ld\n",
  7523. OFFSET(inet_opt_dport));
  7524. fprintf(fp, " inet_opt_sport: %ld\n",
  7525. OFFSET(inet_opt_sport));
  7526. fprintf(fp, " inet_opt_num: %ld\n",
  7527. OFFSET(inet_opt_num));
  7528. fprintf(fp, " ipv6_pinfo_rcv_saddr: %ld\n",
  7529. OFFSET(ipv6_pinfo_rcv_saddr));
  7530. fprintf(fp, " ipv6_pinfo_daddr: %ld\n",
  7531. OFFSET(ipv6_pinfo_daddr));
  7532. fprintf(fp, " timer_list_list: %ld\n",
  7533. OFFSET(timer_list_list));
  7534. fprintf(fp, " timer_list_next: %ld\n",
  7535. OFFSET(timer_list_next));
  7536. fprintf(fp, " timer_list_entry: %ld\n",
  7537. OFFSET(timer_list_entry));
  7538. fprintf(fp, " timer_list_expires: %ld\n",
  7539. OFFSET(timer_list_expires));
  7540. fprintf(fp, " timer_list_function: %ld\n",
  7541. OFFSET(timer_list_function));
  7542. fprintf(fp, " timer_vec_root_vec: %ld\n",
  7543. OFFSET(timer_vec_root_vec));
  7544. fprintf(fp, " timer_vec_vec: %ld\n",
  7545. OFFSET(timer_vec_vec));
  7546. fprintf(fp, " tvec_root_s_vec: %ld\n",
  7547. OFFSET(tvec_root_s_vec));
  7548. fprintf(fp, " tvec_s_vec: %ld\n",
  7549. OFFSET(tvec_s_vec));
  7550. fprintf(fp, " tvec_t_base_s_tv1: %ld\n",
  7551. OFFSET(tvec_t_base_s_tv1));
  7552. fprintf(fp, " wait_queue_task: %ld\n",
  7553. OFFSET(wait_queue_task));
  7554. fprintf(fp, " wait_queue_next: %ld\n",
  7555. OFFSET(wait_queue_next));
  7556. fprintf(fp, " __wait_queue_task: %ld\n",
  7557. OFFSET(__wait_queue_task));
  7558. fprintf(fp, " __wait_queue_head_task_list: %ld\n",
  7559. OFFSET(__wait_queue_head_task_list));
  7560. fprintf(fp, " __wait_queue_task_list: %ld\n",
  7561. OFFSET(__wait_queue_task_list));
  7562. fprintf(fp, " pglist_data_node_zones: %ld\n",
  7563. OFFSET(pglist_data_node_zones));
  7564. fprintf(fp, " pglist_data_node_mem_map: %ld\n",
  7565. OFFSET(pglist_data_node_mem_map));
  7566. fprintf(fp, " pglist_data_node_start_paddr: %ld\n",
  7567. OFFSET(pglist_data_node_start_paddr));
  7568. fprintf(fp, " pglist_data_node_start_mapnr: %ld\n",
  7569. OFFSET(pglist_data_node_start_mapnr));
  7570. fprintf(fp, " pglist_data_node_size: %ld\n",
  7571. OFFSET(pglist_data_node_size));
  7572. fprintf(fp, " pglist_data_node_id: %ld\n",
  7573. OFFSET(pglist_data_node_id));
  7574. fprintf(fp, " pglist_data_node_next: %ld\n",
  7575. OFFSET(pglist_data_node_next));
  7576. fprintf(fp, " pglist_data_bdata: %ld\n",
  7577. OFFSET(pglist_data_bdata));
  7578. fprintf(fp, " pglist_data_nr_zones: %ld\n",
  7579. OFFSET(pglist_data_nr_zones));
  7580. fprintf(fp, " pglist_data_node_start_pfn: %ld\n",
  7581. OFFSET(pglist_data_node_start_pfn));
  7582. fprintf(fp, " pglist_data_pgdat_next: %ld\n",
  7583. OFFSET(pglist_data_pgdat_next));
  7584. fprintf(fp, "pglist_data_node_present_pages: %ld\n",
  7585. OFFSET(pglist_data_node_present_pages));
  7586. fprintf(fp, "pglist_data_node_spanned_pages: %ld\n",
  7587. OFFSET(pglist_data_node_spanned_pages));
  7588. fprintf(fp, " page_cache_bucket_chain: %ld\n",
  7589. OFFSET(page_cache_bucket_chain));
  7590. fprintf(fp, " zone_struct_free_pages: %ld\n",
  7591. OFFSET(zone_struct_free_pages));
  7592. fprintf(fp, " zone_struct_free_area: %ld\n",
  7593. OFFSET(zone_struct_free_area));
  7594. fprintf(fp, " zone_struct_zone_pgdat: %ld\n",
  7595. OFFSET(zone_struct_zone_pgdat));
  7596. fprintf(fp, " zone_struct_name: %ld\n",
  7597. OFFSET(zone_struct_name));
  7598. fprintf(fp, " zone_struct_size: %ld\n",
  7599. OFFSET(zone_struct_size));
  7600. fprintf(fp, " zone_struct_memsize: %ld\n",
  7601. OFFSET(zone_struct_memsize));
  7602. fprintf(fp, " zone_struct_zone_start_pfn: %ld\n",
  7603. OFFSET(zone_struct_zone_start_pfn));
  7604. fprintf(fp, " zone_struct_zone_start_paddr: %ld\n",
  7605. OFFSET(zone_struct_zone_start_paddr));
  7606. fprintf(fp, " zone_struct_zone_start_mapnr: %ld\n",
  7607. OFFSET(zone_struct_zone_start_mapnr));
  7608. fprintf(fp, " zone_struct_zone_mem_map: %ld\n",
  7609. OFFSET(zone_struct_zone_mem_map));
  7610. fprintf(fp, "zone_struct_inactive_clean_pages: %ld\n",
  7611. OFFSET(zone_struct_inactive_clean_pages));
  7612. fprintf(fp, "zone_struct_inactive_clean_list: %ld\n",
  7613. OFFSET(zone_struct_inactive_clean_list));
  7614. fprintf(fp, "zone_struct_inactive_dirty_pages: %ld\n",
  7615. OFFSET(zone_struct_inactive_dirty_pages));
  7616. fprintf(fp, " zone_struct_active_pages: %ld\n",
  7617. OFFSET(zone_struct_active_pages));
  7618. fprintf(fp, " zone_struct_pages_min: %ld\n",
  7619. OFFSET(zone_struct_pages_min));
  7620. fprintf(fp, " zone_struct_pages_low: %ld\n",
  7621. OFFSET(zone_struct_pages_low));
  7622. fprintf(fp, " zone_struct_pages_high: %ld\n",
  7623. OFFSET(zone_struct_pages_high));
  7624. fprintf(fp, " zone_free_pages: %ld\n",
  7625. OFFSET(zone_free_pages));
  7626. fprintf(fp, " zone_watermark: %ld\n",
  7627. OFFSET(zone_watermark));
  7628. fprintf(fp, " zone_free_area: %ld\n",
  7629. OFFSET(zone_free_area));
  7630. fprintf(fp, " zone_zone_pgdat: %ld\n",
  7631. OFFSET(zone_zone_pgdat));
  7632. fprintf(fp, " zone_zone_mem_map: %ld\n",
  7633. OFFSET(zone_zone_mem_map));
  7634. fprintf(fp, " zone_name: %ld\n",
  7635. OFFSET(zone_name));
  7636. fprintf(fp, " zone_spanned_pages: %ld\n",
  7637. OFFSET(zone_spanned_pages));
  7638. fprintf(fp, " zone_present_pages: %ld\n",
  7639. OFFSET(zone_present_pages));
  7640. fprintf(fp, " zone_zone_start_pfn: %ld\n",
  7641. OFFSET(zone_zone_start_pfn));
  7642. fprintf(fp, " zone_pages_min: %ld\n",
  7643. OFFSET(zone_pages_min));
  7644. fprintf(fp, " zone_pages_low: %ld\n",
  7645. OFFSET(zone_pages_low));
  7646. fprintf(fp, " zone_pages_high: %ld\n",
  7647. OFFSET(zone_pages_high));
  7648. fprintf(fp, " zone_vm_stat: %ld\n",
  7649. OFFSET(zone_vm_stat));
  7650. fprintf(fp, " zone_nr_active: %ld\n",
  7651. OFFSET(zone_nr_active));
  7652. fprintf(fp, " zone_nr_inactive: %ld\n",
  7653. OFFSET(zone_nr_inactive));
  7654. fprintf(fp, " zone_all_unreclaimable: %ld\n",
  7655. OFFSET(zone_all_unreclaimable));
  7656. fprintf(fp, " zone_flags: %ld\n",
  7657. OFFSET(zone_flags));
  7658. fprintf(fp, " zone_pages_scanned: %ld\n",
  7659. OFFSET(zone_pages_scanned));
  7660. fprintf(fp, " neighbour_next: %ld\n",
  7661. OFFSET(neighbour_next));
  7662. fprintf(fp, " neighbour_primary_key: %ld\n",
  7663. OFFSET(neighbour_primary_key));
  7664. fprintf(fp, " neighbour_ha: %ld\n",
  7665. OFFSET(neighbour_ha));
  7666. fprintf(fp, " neighbour_dev: %ld\n",
  7667. OFFSET(neighbour_dev));
  7668. fprintf(fp, " neighbour_nud_state: %ld\n",
  7669. OFFSET(neighbour_nud_state));
  7670. fprintf(fp, " neigh_table_hash_buckets: %ld\n",
  7671. OFFSET(neigh_table_hash_buckets));
  7672. fprintf(fp, " neigh_table_hash_mask: %ld\n",
  7673. OFFSET(neigh_table_hash_mask));
  7674. fprintf(fp, " neigh_table_hash_shift: %ld\n",
  7675. OFFSET(neigh_table_hash_shift));
  7676. fprintf(fp, " neigh_table_nht_ptr: %ld\n",
  7677. OFFSET(neigh_table_nht_ptr));
  7678. fprintf(fp, " neigh_table_key_len: %ld\n",
  7679. OFFSET(neigh_table_key_len));
  7680. fprintf(fp, " in_device_ifa_list: %ld\n",
  7681. OFFSET(in_device_ifa_list));
  7682. fprintf(fp, " in_ifaddr_ifa_next: %ld\n",
  7683. OFFSET(in_ifaddr_ifa_next));
  7684. fprintf(fp, " in_ifaddr_ifa_address: %ld\n",
  7685. OFFSET(in_ifaddr_ifa_address));
  7686. fprintf(fp, " pci_dev_global_list: %ld\n",
  7687. OFFSET(pci_dev_global_list));
  7688. fprintf(fp, " pci_dev_next: %ld\n",
  7689. OFFSET(pci_dev_next));
  7690. fprintf(fp, " pci_dev_bus: %ld\n",
  7691. OFFSET(pci_dev_bus));
  7692. fprintf(fp, " pci_dev_devfn: %ld\n",
  7693. OFFSET(pci_dev_devfn));
  7694. fprintf(fp, " pci_dev_class: %ld\n",
  7695. OFFSET(pci_dev_class));
  7696. fprintf(fp, " pci_dev_device: %ld\n",
  7697. OFFSET(pci_dev_device));
  7698. fprintf(fp, " pci_dev_vendor: %ld\n",
  7699. OFFSET(pci_dev_vendor));
  7700. fprintf(fp, " pci_bus_number: %ld\n",
  7701. OFFSET(pci_bus_number));
  7702. fprintf(fp, " resource_entry_t_from: %ld\n",
  7703. OFFSET(resource_entry_t_from));
  7704. fprintf(fp, " resource_entry_t_num: %ld\n",
  7705. OFFSET(resource_entry_t_num));
  7706. fprintf(fp, " resource_entry_t_name: %ld\n",
  7707. OFFSET(resource_entry_t_name));
  7708. fprintf(fp, " resource_entry_t_next: %ld\n",
  7709. OFFSET(resource_entry_t_next));
  7710. fprintf(fp, " resource_name: %ld\n",
  7711. OFFSET(resource_name));
  7712. fprintf(fp, " resource_start: %ld\n",
  7713. OFFSET(resource_start));
  7714. fprintf(fp, " resource_end: %ld\n",
  7715. OFFSET(resource_end));
  7716. fprintf(fp, " resource_sibling: %ld\n",
  7717. OFFSET(resource_sibling));
  7718. fprintf(fp, " resource_child: %ld\n",
  7719. OFFSET(resource_child));
  7720. fprintf(fp, " runqueue_curr: %ld\n",
  7721. OFFSET(runqueue_curr));
  7722. fprintf(fp, " runqueue_idle: %ld\n",
  7723. OFFSET(runqueue_idle));
  7724. fprintf(fp, " runqueue_active: %ld\n",
  7725. OFFSET(runqueue_active));
  7726. fprintf(fp, " runqueue_expired: %ld\n",
  7727. OFFSET(runqueue_expired));
  7728. fprintf(fp, " runqueue_arrays: %ld\n",
  7729. OFFSET(runqueue_arrays));
  7730. fprintf(fp, " runqueue_cpu: %ld\n",
  7731. OFFSET(runqueue_cpu));
  7732. fprintf(fp, " cpu_s_idle: %ld\n",
  7733. OFFSET(cpu_s_idle));
  7734. fprintf(fp, " cpu_s_curr: %ld\n",
  7735. OFFSET(cpu_s_curr));
  7736. fprintf(fp, " prio_array_queue: %ld\n",
  7737. OFFSET(prio_array_queue));
  7738. fprintf(fp, " rt_prio_array_queue: %ld\n",
  7739. OFFSET(rt_prio_array_queue));
  7740. fprintf(fp, " prio_array_nr_active: %ld\n",
  7741. OFFSET(prio_array_nr_active));
  7742. fprintf(fp, " user_regs_struct_ebp: %ld\n",
  7743. OFFSET(user_regs_struct_ebp));
  7744. fprintf(fp, " user_regs_struct_eip: %ld\n",
  7745. OFFSET(user_regs_struct_eip));
  7746. fprintf(fp, " user_regs_struct_esp: %ld\n",
  7747. OFFSET(user_regs_struct_esp));
  7748. fprintf(fp, " user_regs_struct_rip: %ld\n",
  7749. OFFSET(user_regs_struct_rip));
  7750. fprintf(fp, " user_regs_struct_rsp: %ld\n",
  7751. OFFSET(user_regs_struct_rsp));
  7752. fprintf(fp, " user_regs_struct_eflags: %ld\n",
  7753. OFFSET(user_regs_struct_eflags));
  7754. fprintf(fp, " user_regs_struct_cs: %ld\n",
  7755. OFFSET(user_regs_struct_cs));
  7756. fprintf(fp, " user_regs_struct_ss: %ld\n",
  7757. OFFSET(user_regs_struct_ss));
  7758. fprintf(fp, " user_regs_struct_eip: %ld\n",
  7759. OFFSET(user_regs_struct_eip));
  7760. fprintf(fp, " user_regs_struct_rax: %ld\n",
  7761. OFFSET(user_regs_struct_rax));
  7762. fprintf(fp, " user_regs_struct_eax: %ld\n",
  7763. OFFSET(user_regs_struct_eax));
  7764. fprintf(fp, " user_regs_struct_rbx: %ld\n",
  7765. OFFSET(user_regs_struct_rbx));
  7766. fprintf(fp, " user_regs_struct_ebx: %ld\n",
  7767. OFFSET(user_regs_struct_ebx));
  7768. fprintf(fp, " user_regs_struct_rcx: %ld\n",
  7769. OFFSET(user_regs_struct_rcx));
  7770. fprintf(fp, " user_regs_struct_ecx: %ld\n",
  7771. OFFSET(user_regs_struct_ecx));
  7772. fprintf(fp, " user_regs_struct_rdx: %ld\n",
  7773. OFFSET(user_regs_struct_rdx));
  7774. fprintf(fp, " user_regs_struct_edx: %ld\n",
  7775. OFFSET(user_regs_struct_edx));
  7776. fprintf(fp, " user_regs_struct_rsi: %ld\n",
  7777. OFFSET(user_regs_struct_rsi));
  7778. fprintf(fp, " user_regs_struct_esi: %ld\n",
  7779. OFFSET(user_regs_struct_esi));
  7780. fprintf(fp, " user_regs_struct_rdi: %ld\n",
  7781. OFFSET(user_regs_struct_rdi));
  7782. fprintf(fp, " user_regs_struct_edi: %ld\n",
  7783. OFFSET(user_regs_struct_edi));
  7784. fprintf(fp, " user_regs_struct_ds: %ld\n",
  7785. OFFSET(user_regs_struct_ds));
  7786. fprintf(fp, " user_regs_struct_es: %ld\n",
  7787. OFFSET(user_regs_struct_es));
  7788. fprintf(fp, " user_regs_struct_fs: %ld\n",
  7789. OFFSET(user_regs_struct_fs));
  7790. fprintf(fp, " user_regs_struct_gs: %ld\n",
  7791. OFFSET(user_regs_struct_gs));
  7792. fprintf(fp, " user_regs_struct_rbp: %ld\n",
  7793. OFFSET(user_regs_struct_rbp));
  7794. fprintf(fp, " user_regs_struct_r8: %ld\n",
  7795. OFFSET(user_regs_struct_r8));
  7796. fprintf(fp, " user_regs_struct_r9: %ld\n",
  7797. OFFSET(user_regs_struct_r9));
  7798. fprintf(fp, " user_regs_struct_r10: %ld\n",
  7799. OFFSET(user_regs_struct_r10));
  7800. fprintf(fp, " user_regs_struct_r11: %ld\n",
  7801. OFFSET(user_regs_struct_r11));
  7802. fprintf(fp, " user_regs_struct_r12: %ld\n",
  7803. OFFSET(user_regs_struct_r12));
  7804. fprintf(fp, " user_regs_struct_r13: %ld\n",
  7805. OFFSET(user_regs_struct_r13));
  7806. fprintf(fp, " user_regs_struct_r14: %ld\n",
  7807. OFFSET(user_regs_struct_r14));
  7808. fprintf(fp, " user_regs_struct_r15: %ld\n",
  7809. OFFSET(user_regs_struct_r15));
  7810. fprintf(fp, " e820map_nr_map: %ld\n",
  7811. OFFSET(e820map_nr_map));
  7812. fprintf(fp, " e820entry_addr: %ld\n",
  7813. OFFSET(e820entry_addr));
  7814. fprintf(fp, " e820entry_size: %ld\n",
  7815. OFFSET(e820entry_size));
  7816. fprintf(fp, " e820entry_type: %ld\n",
  7817. OFFSET(e820entry_type));
  7818. fprintf(fp, " char_device_struct_name: %ld\n",
  7819. OFFSET(char_device_struct_name));
  7820. fprintf(fp, " char_device_struct_next: %ld\n",
  7821. OFFSET(char_device_struct_next));
  7822. fprintf(fp, " char_device_struct_fops: %ld\n",
  7823. OFFSET(char_device_struct_fops));
  7824. fprintf(fp, " char_device_struct_major: %ld\n",
  7825. OFFSET(char_device_struct_major));
  7826. fprintf(fp, " char_device_struct_baseminor: %ld\n",
  7827. OFFSET(char_device_struct_baseminor));
  7828. fprintf(fp, " char_device_struct_cdev: %ld\n",
  7829. OFFSET(char_device_struct_cdev));
  7830. fprintf(fp, " cdev_ops: %ld\n", OFFSET(cdev_ops));
  7831. fprintf(fp, " probe_next: %ld\n",
  7832. OFFSET(probe_next));
  7833. fprintf(fp, " probe_dev: %ld\n",
  7834. OFFSET(probe_dev));
  7835. fprintf(fp, " probe_data: %ld\n",
  7836. OFFSET(probe_data));
  7837. fprintf(fp, " kobj_map_probes: %ld\n",
  7838. OFFSET(kobj_map_probes));
  7839. fprintf(fp, " blk_major_name_next: %ld\n",
  7840. OFFSET(blk_major_name_next));
  7841. fprintf(fp, " blk_major_name_major: %ld\n",
  7842. OFFSET(blk_major_name_major));
  7843. fprintf(fp, " blk_major_name_name: %ld\n",
  7844. OFFSET(blk_major_name_name));
  7845. fprintf(fp, " radix_tree_root_height: %ld\n",
  7846. OFFSET(radix_tree_root_height));
  7847. fprintf(fp, " radix_tree_root_rnode: %ld\n",
  7848. OFFSET(radix_tree_root_rnode));
  7849. fprintf(fp, " radix_tree_node_slots: %ld\n",
  7850. OFFSET(radix_tree_node_slots));
  7851. fprintf(fp, " radix_tree_node_height: %ld\n",
  7852. OFFSET(radix_tree_node_height));
  7853. fprintf(fp, " rb_root_rb_node: %ld\n",
  7854. OFFSET(rb_root_rb_node));
  7855. fprintf(fp, " rb_node_rb_left: %ld\n",
  7856. OFFSET(rb_node_rb_left));
  7857. fprintf(fp, " rb_node_rb_right: %ld\n",
  7858. OFFSET(rb_node_rb_right));
  7859. fprintf(fp, " x8664_pda_pcurrent: %ld\n",
  7860. OFFSET(x8664_pda_pcurrent));
  7861. fprintf(fp, " x8664_pda_data_offset: %ld\n",
  7862. OFFSET(x8664_pda_data_offset));
  7863. fprintf(fp, " x8664_pda_kernelstack: %ld\n",
  7864. OFFSET(x8664_pda_kernelstack));
  7865. fprintf(fp, " x8664_pda_irqrsp: %ld\n",
  7866. OFFSET(x8664_pda_irqrsp));
  7867. fprintf(fp, " x8664_pda_cpunumber: %ld\n",
  7868. OFFSET(x8664_pda_cpunumber));
  7869. fprintf(fp, " x8664_pda_irqstackptr: %ld\n",
  7870. OFFSET(x8664_pda_irqstackptr));
  7871. fprintf(fp, " x8664_pda_level4_pgt: %ld\n",
  7872. OFFSET(x8664_pda_level4_pgt));
  7873. fprintf(fp, " x8664_pda_me: %ld\n",
  7874. OFFSET(x8664_pda_me));
  7875. fprintf(fp, " tss_struct_ist: %ld\n",
  7876. OFFSET(tss_struct_ist));
  7877. fprintf(fp, " mem_section_section_mem_map: %ld\n",
  7878. OFFSET(mem_section_section_mem_map));
  7879. fprintf(fp, " vcpu_guest_context_user_regs: %ld\n",
  7880. OFFSET(vcpu_guest_context_user_regs));
  7881. fprintf(fp, " cpu_user_regs_eip: %ld\n",
  7882. OFFSET(cpu_user_regs_eip));
  7883. fprintf(fp, " cpu_user_regs_esp: %ld\n",
  7884. OFFSET(cpu_user_regs_esp));
  7885. fprintf(fp, " cpu_user_regs_rip: %ld\n",
  7886. OFFSET(cpu_user_regs_rip));
  7887. fprintf(fp, " cpu_user_regs_rsp: %ld\n",
  7888. OFFSET(cpu_user_regs_rsp));
  7889. fprintf(fp, " unwind_table_core: %ld\n",
  7890. OFFSET(unwind_table_core));
  7891. fprintf(fp, " unwind_table_init: %ld\n",
  7892. OFFSET(unwind_table_init));
  7893. fprintf(fp, " unwind_table_address: %ld\n",
  7894. OFFSET(unwind_table_address));
  7895. fprintf(fp, " unwind_table_size: %ld\n",
  7896. OFFSET(unwind_table_size));
  7897. fprintf(fp, " unwind_table_link: %ld\n",
  7898. OFFSET(unwind_table_link));
  7899. fprintf(fp, " unwind_table_name: %ld\n",
  7900. OFFSET(unwind_table_name));
  7901. fprintf(fp, " rq_cfs: %ld\n",
  7902. OFFSET(rq_cfs));
  7903. fprintf(fp, " rq_rt: %ld\n",
  7904. OFFSET(rq_rt));
  7905. fprintf(fp, " cfs_rq_curr: %ld\n",
  7906. OFFSET(cfs_rq_curr));
  7907. fprintf(fp, " rq_nr_running: %ld\n",
  7908. OFFSET(rq_nr_running));
  7909. fprintf(fp, " rq_timestamp: %ld\n",
  7910. OFFSET(rq_timestamp));
  7911. fprintf(fp, " task_struct_se: %ld\n",
  7912. OFFSET(task_struct_se));
  7913. fprintf(fp, " sched_entity_run_node: %ld\n",
  7914. OFFSET(sched_entity_run_node));
  7915. fprintf(fp, " sched_entity_cfs_rq: %ld\n",
  7916. OFFSET(sched_entity_cfs_rq));
  7917. fprintf(fp, " sched_entity_my_q: %ld\n",
  7918. OFFSET(sched_entity_my_q));
  7919. fprintf(fp, " sched_entity_on_rq: %ld\n",
  7920. OFFSET(sched_entity_on_rq));
  7921. fprintf(fp, " cfs_rq_nr_running: %ld\n",
  7922. OFFSET(cfs_rq_nr_running));
  7923. fprintf(fp, " cfs_rq_rb_leftmost: %ld\n",
  7924. OFFSET(cfs_rq_rb_leftmost));
  7925. fprintf(fp, " cfs_rq_tasks_timeline: %ld\n",
  7926. OFFSET(cfs_rq_tasks_timeline));
  7927. fprintf(fp, " rt_rq_active: %ld\n",
  7928. OFFSET(rt_rq_active));
  7929. fprintf(fp, " pcpu_info_vcpu: %ld\n",
  7930. OFFSET(pcpu_info_vcpu));
  7931. fprintf(fp, " pcpu_info_idle: %ld\n",
  7932. OFFSET(pcpu_info_idle));
  7933. fprintf(fp, " vcpu_struct_rq: %ld\n",
  7934. OFFSET(vcpu_struct_rq));
  7935. fprintf(fp, " s390_lowcore_psw_save_area: %ld\n",
  7936. OFFSET(s390_lowcore_psw_save_area));
  7937. fprintf(fp, " s390_stack_frame_back_chain: %ld\n",
  7938. OFFSET(s390_stack_frame_back_chain));
  7939. fprintf(fp, " s390_stack_frame_r14: %ld\n",
  7940. OFFSET(s390_stack_frame_r14));
  7941. fprintf(fp, " cpu_context_save_fp: %ld\n",
  7942. OFFSET(cpu_context_save_fp));
  7943. fprintf(fp, " cpu_context_save_sp: %ld\n",
  7944. OFFSET(cpu_context_save_sp));
  7945. fprintf(fp, " cpu_context_save_pc: %ld\n",
  7946. OFFSET(cpu_context_save_pc));
  7947. fprintf(fp, " elf_prstatus_pr_pid: %ld\n",
  7948. OFFSET(elf_prstatus_pr_pid));
  7949. fprintf(fp, " elf_prstatus_pr_reg: %ld\n",
  7950. OFFSET(elf_prstatus_pr_reg));
  7951. fprintf(fp, " irq_desc_t_name: %ld\n",
  7952. OFFSET(irq_desc_t_name));
  7953. fprintf(fp, " thread_info_cpu_context: %ld\n",
  7954. OFFSET(thread_info_cpu_context));
  7955. fprintf(fp, " unwind_table_list: %ld\n",
  7956. OFFSET(unwind_table_list));
  7957. fprintf(fp, " unwind_table_start: %ld\n",
  7958. OFFSET(unwind_table_start));
  7959. fprintf(fp, " unwind_table_stop: %ld\n",
  7960. OFFSET(unwind_table_stop));
  7961. fprintf(fp, " unwind_table_begin_addr: %ld\n",
  7962. OFFSET(unwind_table_begin_addr));
  7963. fprintf(fp, " unwind_table_end_addr: %ld\n",
  7964. OFFSET(unwind_table_end_addr));
  7965. fprintf(fp, " unwind_idx_addr: %ld\n",
  7966. OFFSET(unwind_idx_addr));
  7967. fprintf(fp, " unwind_idx_insn: %ld\n",
  7968. OFFSET(unwind_idx_insn));
  7969. fprintf(fp, " class_devices: %ld\n",
  7970. OFFSET(class_devices));
  7971. fprintf(fp, " class_p: %ld\n",
  7972. OFFSET(class_p));
  7973. fprintf(fp, " class_private_devices: %ld\n",
  7974. OFFSET(class_private_devices));
  7975. fprintf(fp, " device_knode_class: %ld\n",
  7976. OFFSET(device_knode_class));
  7977. fprintf(fp, " device_node: %ld\n",
  7978. OFFSET(device_node));
  7979. fprintf(fp, " gendisk_dev: %ld\n",
  7980. OFFSET(gendisk_dev));
  7981. fprintf(fp, " gendisk_kobj: %ld\n",
  7982. OFFSET(gendisk_kobj));
  7983. fprintf(fp, " gendisk_part0: %ld\n",
  7984. OFFSET(gendisk_part0));
  7985. fprintf(fp, " gendisk_queue: %ld\n",
  7986. OFFSET(gendisk_queue));
  7987. fprintf(fp, " hd_struct_dev: %ld\n",
  7988. OFFSET(hd_struct_dev));
  7989. fprintf(fp, " klist_k_list: %ld\n",
  7990. OFFSET(klist_k_list));
  7991. fprintf(fp, " klist_node_n_klist: %ld\n",
  7992. OFFSET(klist_node_n_klist));
  7993. fprintf(fp, " klist_node_n_node: %ld\n",
  7994. OFFSET(klist_node_n_node));
  7995. fprintf(fp, " kobject_entry: %ld\n",
  7996. OFFSET(kobject_entry));
  7997. fprintf(fp, " kset_list: %ld\n",
  7998. OFFSET(kset_list));
  7999. fprintf(fp, " request_list_count: %ld\n",
  8000. OFFSET(request_list_count));
  8001. fprintf(fp, " request_queue_in_flight: %ld\n",
  8002. OFFSET(request_queue_in_flight));
  8003. fprintf(fp, " request_queue_rq: %ld\n",
  8004. OFFSET(request_queue_rq));
  8005. fprintf(fp, " subsys_private_klist_devices: %ld\n",
  8006. OFFSET(subsys_private_klist_devices));
  8007. fprintf(fp, " subsystem_kset: %ld\n",
  8008. OFFSET(subsystem_kset));
  8009. fprintf(fp, " file_f_op: %ld\n",
  8010. OFFSET(file_f_op));
  8011. fprintf(fp, " file_private_data: %ld\n",
  8012. OFFSET(file_private_data));
  8013. fprintf(fp, " hstate_order: %ld\n",
  8014. OFFSET(hstate_order));
  8015. fprintf(fp, " hstate_nr_huge_pages: %ld\n",
  8016. OFFSET(hstate_nr_huge_pages));
  8017. fprintf(fp, " hstate_free_huge_pages: %ld\n",
  8018. OFFSET(hstate_free_huge_pages));
  8019. fprintf(fp, " hstate_name: %ld\n",
  8020. OFFSET(hstate_name));
  8021. fprintf(fp, " hugetlbfs_sb_info_hstate: %ld\n",
  8022. OFFSET(hugetlbfs_sb_info_hstate));
  8023. fprintf(fp, " idr_layer_ary: %ld\n",
  8024. OFFSET(idr_layer_ary));
  8025. fprintf(fp, " idr_layer_layer: %ld\n",
  8026. OFFSET(idr_layer_layer));
  8027. fprintf(fp, " idr_layers: %ld\n",
  8028. OFFSET(idr_layers));
  8029. fprintf(fp, " idr_top: %ld\n",
  8030. OFFSET(idr_top));
  8031. fprintf(fp, " ipc_id_ary_p: %ld\n",
  8032. OFFSET(ipc_id_ary_p));
  8033. fprintf(fp, " ipc_ids_entries: %ld\n",
  8034. OFFSET(ipc_ids_entries));
  8035. fprintf(fp, " ipc_ids_max_id: %ld\n",
  8036. OFFSET(ipc_ids_max_id));
  8037. fprintf(fp, " ipc_ids_ipcs_idr: %ld\n",
  8038. OFFSET(ipc_ids_ipcs_idr));
  8039. fprintf(fp, " ipc_ids_in_use: %ld\n",
  8040. OFFSET(ipc_ids_in_use));
  8041. fprintf(fp, " ipc_namespace_ids: %ld\n",
  8042. OFFSET(ipc_namespace_ids));
  8043. fprintf(fp, " kern_ipc_perm_deleted: %ld\n",
  8044. OFFSET(kern_ipc_perm_deleted));
  8045. fprintf(fp, " kern_ipc_perm_key: %ld\n",
  8046. OFFSET(kern_ipc_perm_key));
  8047. fprintf(fp, " kern_ipc_perm_mode: %ld\n",
  8048. OFFSET(kern_ipc_perm_mode));
  8049. fprintf(fp, " kern_ipc_perm_uid: %ld\n",
  8050. OFFSET(kern_ipc_perm_uid));
  8051. fprintf(fp, " kern_ipc_perm_id: %ld\n",
  8052. OFFSET(kern_ipc_perm_id));
  8053. fprintf(fp, " kern_ipc_perm_seq: %ld\n",
  8054. OFFSET(kern_ipc_perm_seq));
  8055. fprintf(fp, " nsproxy_ipc_ns: %ld\n",
  8056. OFFSET(nsproxy_ipc_ns));
  8057. fprintf(fp, " shmem_inode_info_swapped: %ld\n",
  8058. OFFSET(shmem_inode_info_swapped));
  8059. fprintf(fp, " shmem_inode_info_vfs_inode: %ld\n",
  8060. OFFSET(shmem_inode_info_vfs_inode));
  8061. fprintf(fp, " shm_file_data_file: %ld\n",
  8062. OFFSET(shm_file_data_file));
  8063. fprintf(fp, " shmid_kernel_shm_file: %ld\n",
  8064. OFFSET(shmid_kernel_shm_file));
  8065. fprintf(fp, " shmid_kernel_shm_nattch: %ld\n",
  8066. OFFSET(shmid_kernel_shm_nattch));
  8067. fprintf(fp, " shmid_kernel_shm_perm: %ld\n",
  8068. OFFSET(shmid_kernel_shm_perm));
  8069. fprintf(fp, " shmid_kernel_shm_segsz: %ld\n",
  8070. OFFSET(shmid_kernel_shm_segsz));
  8071. fprintf(fp, " shmid_kernel_id: %ld\n",
  8072. OFFSET(shmid_kernel_id));
  8073. fprintf(fp, " sem_array_sem_perm: %ld\n",
  8074. OFFSET(sem_array_sem_perm));
  8075. fprintf(fp, " sem_array_sem_id: %ld\n",
  8076. OFFSET(sem_array_sem_id));
  8077. fprintf(fp, " sem_array_sem_nsems: %ld\n",
  8078. OFFSET(sem_array_sem_nsems));
  8079. fprintf(fp, " msg_queue_q_perm: %ld\n",
  8080. OFFSET(msg_queue_q_perm));
  8081. fprintf(fp, " msg_queue_q_id: %ld\n",
  8082. OFFSET(msg_queue_q_id));
  8083. fprintf(fp, " msg_queue_q_cbytes: %ld\n",
  8084. OFFSET(msg_queue_q_cbytes));
  8085. fprintf(fp, " msg_queue_q_qnum: %ld\n",
  8086. OFFSET(msg_queue_q_qnum));
  8087. fprintf(fp, " super_block_s_fs_info: %ld\n",
  8088. OFFSET(super_block_s_fs_info));
  8089. fprintf(fp, " log_ts_nsec: %ld\n",
  8090. OFFSET(log_ts_nsec));
  8091. fprintf(fp, " log_len: %ld\n",
  8092. OFFSET(log_len));
  8093. fprintf(fp, " log_text_len: %ld\n",
  8094. OFFSET(log_text_len));
  8095. fprintf(fp, " log_dict_len: %ld\n",
  8096. OFFSET(log_dict_len));
  8097. fprintf(fp, " log_level: %ld\n",
  8098. OFFSET(log_level));
  8099. fprintf(fp, " log_flags_level: %ld\n",
  8100. OFFSET(log_flags_level));
  8101. fprintf(fp, " sched_rt_entity_my_q: %ld\n",
  8102. OFFSET(sched_rt_entity_my_q));
  8103. fprintf(fp, " task_group_parent: %ld\n",
  8104. OFFSET(task_group_parent));
  8105. fprintf(fp, " task_group_css: %ld\n",
  8106. OFFSET(task_group_css));
  8107. fprintf(fp, " cgroup_subsys_state_cgroup: %ld\n",
  8108. OFFSET(cgroup_subsys_state_cgroup));
  8109. fprintf(fp, " cgroup_dentry: %ld\n",
  8110. OFFSET(cgroup_dentry));
  8111. fprintf(fp, " cgroup_kn: %ld\n",
  8112. OFFSET(cgroup_kn));
  8113. fprintf(fp, " kernfs_node_name: %ld\n",
  8114. OFFSET(kernfs_node_name));
  8115. fprintf(fp, " kernfs_node_parent: %ld\n",
  8116. OFFSET(kernfs_node_parent));
  8117. fprintf(fp, " task_group_rt_rq: %ld\n",
  8118. OFFSET(task_group_rt_rq));
  8119. fprintf(fp, " rt_rq_tg: %ld\n",
  8120. OFFSET(rt_rq_tg));
  8121. fprintf(fp, " task_group_cfs_rq: %ld\n",
  8122. OFFSET(task_group_cfs_rq));
  8123. fprintf(fp, " cfs_rq_tg: %ld\n",
  8124. OFFSET(cfs_rq_tg));
  8125. fprintf(fp, " task_group_siblings: %ld\n",
  8126. OFFSET(task_group_siblings));
  8127. fprintf(fp, " task_group_children: %ld\n",
  8128. OFFSET(task_group_children));
  8129. fprintf(fp, " task_group_cfs_bandwidth: %ld\n",
  8130. OFFSET(task_group_cfs_bandwidth));
  8131. fprintf(fp, " cfs_rq_throttled: %ld\n",
  8132. OFFSET(cfs_rq_throttled));
  8133. fprintf(fp, " task_group_rt_bandwidth: %ld\n",
  8134. OFFSET(task_group_rt_bandwidth));
  8135. fprintf(fp, " rt_rq_rt_throttled: %ld\n",
  8136. OFFSET(rt_rq_rt_throttled));
  8137. fprintf(fp, " rt_rq_highest_prio: %ld\n",
  8138. OFFSET(rt_rq_highest_prio));
  8139. fprintf(fp, " rt_rq_rt_nr_running: %ld\n",
  8140. OFFSET(rt_rq_rt_nr_running));
  8141. fprintf(fp, " hrtimer_cpu_base_clock_base: %ld\n",
  8142. OFFSET(hrtimer_cpu_base_clock_base));
  8143. fprintf(fp, " hrtimer_clock_base_offset: %ld\n",
  8144. OFFSET(hrtimer_clock_base_offset));
  8145. fprintf(fp, " hrtimer_clock_base_active: %ld\n",
  8146. OFFSET(hrtimer_clock_base_active));
  8147. fprintf(fp, " hrtimer_clock_base_first: %ld\n",
  8148. OFFSET(hrtimer_clock_base_first));
  8149. fprintf(fp, " hrtimer_clock_base_get_time: %ld\n",
  8150. OFFSET(hrtimer_clock_base_get_time));
  8151. fprintf(fp, " hrtimer_base_first: %ld\n",
  8152. OFFSET(hrtimer_base_first));
  8153. fprintf(fp, " hrtimer_base_pending: %ld\n",
  8154. OFFSET(hrtimer_base_pending));
  8155. fprintf(fp, " hrtimer_base_get_time: %ld\n",
  8156. OFFSET(hrtimer_base_get_time));
  8157. fprintf(fp, " hrtimer_node: %ld\n",
  8158. OFFSET(hrtimer_node));
  8159. fprintf(fp, " hrtimer_list: %ld\n",
  8160. OFFSET(hrtimer_list));
  8161. fprintf(fp, " hrtimer_softexpires: %ld\n",
  8162. OFFSET(hrtimer_softexpires));
  8163. fprintf(fp, " hrtimer_expires: %ld\n",
  8164. OFFSET(hrtimer_expires));
  8165. fprintf(fp, " hrtimer_function: %ld\n",
  8166. OFFSET(hrtimer_function));
  8167. fprintf(fp, " timerqueue_head_next: %ld\n",
  8168. OFFSET(timerqueue_head_next));
  8169. fprintf(fp, " timerqueue_node_expires: %ld\n",
  8170. OFFSET(timerqueue_node_expires));
  8171. fprintf(fp, " timerqueue_node_node: %ld\n",
  8172. OFFSET(timerqueue_node_node));
  8173. fprintf(fp, " ktime_t_tv64: %ld\n",
  8174. OFFSET(ktime_t_tv64));
  8175. fprintf(fp, " ktime_t_sec: %ld\n",
  8176. OFFSET(ktime_t_sec));
  8177. fprintf(fp, " ktime_t_nsec: %ld\n",
  8178. OFFSET(ktime_t_nsec));
  8179. fprintf(fp, "\n size_table:\n");
  8180. fprintf(fp, " page: %ld\n", SIZE(page));
  8181. fprintf(fp, " page_flags: %ld\n", SIZE(page_flags));
  8182. fprintf(fp, " trace_print_flags: %ld\n", SIZE(trace_print_flags));
  8183. fprintf(fp, " free_area_struct: %ld\n",
  8184. SIZE(free_area_struct));
  8185. fprintf(fp, " free_area: %ld\n",
  8186. SIZE(free_area));
  8187. fprintf(fp, " zone_struct: %ld\n", SIZE(zone_struct));
  8188. fprintf(fp, " zone: %ld\n", SIZE(zone));
  8189. fprintf(fp, " kmem_slab_s: %ld\n", SIZE(kmem_slab_s));
  8190. fprintf(fp, " slab_s: %ld\n", SIZE(slab_s));
  8191. fprintf(fp, " slab: %ld\n", SIZE(slab));
  8192. fprintf(fp, " kmem_cache_s: %ld\n",
  8193. SIZE(kmem_cache_s));
  8194. fprintf(fp, " cpucache_s: %ld\n", SIZE(cpucache_s));
  8195. fprintf(fp, " array_cache: %ld\n", SIZE(array_cache));
  8196. fprintf(fp, " kmem_bufctl_t: %ld\n",
  8197. SIZE(kmem_bufctl_t));
  8198. fprintf(fp, " kmem_cache: %ld\n", SIZE(kmem_cache));
  8199. fprintf(fp, " kmem_cache_node: %ld\n", SIZE(kmem_cache_node));
  8200. fprintf(fp, " kmem_cache_cpu: %ld\n", SIZE(kmem_cache_cpu));
  8201. fprintf(fp, " swap_info_struct: %ld\n",
  8202. SIZE(swap_info_struct));
  8203. fprintf(fp, " vm_area_struct: %ld\n",
  8204. SIZE(vm_area_struct));
  8205. fprintf(fp, " mm_struct: %ld\n", SIZE(mm_struct));
  8206. fprintf(fp, " pglist_data: %ld\n", SIZE(pglist_data));
  8207. fprintf(fp, " page_cache_bucket: %ld\n",
  8208. SIZE(page_cache_bucket));
  8209. fprintf(fp, " pt_regs: %ld\n", SIZE(pt_regs));
  8210. fprintf(fp, " task_struct: %ld\n", SIZE(task_struct));
  8211. fprintf(fp, " thread_info: %ld\n", SIZE(thread_info));
  8212. fprintf(fp, " softirq_state: %ld\n",
  8213. SIZE(softirq_state));
  8214. fprintf(fp, " softirq_action: %ld\n",
  8215. SIZE(softirq_action));
  8216. fprintf(fp, " desc_struct: %ld\n", SIZE(desc_struct));
  8217. fprintf(fp, " umode_t: %ld\n", SIZE(umode_t));
  8218. fprintf(fp, " dentry: %ld\n", SIZE(dentry));
  8219. fprintf(fp, " fs_struct: %ld\n", SIZE(fs_struct));
  8220. fprintf(fp, " files_struct: %ld\n",
  8221. SIZE(files_struct));
  8222. fprintf(fp, " fdtable: %ld\n", SIZE(fdtable));
  8223. fprintf(fp, " file: %ld\n", SIZE(file));
  8224. fprintf(fp, " inode: %ld\n", SIZE(inode));
  8225. fprintf(fp, " vfsmount: %ld\n", SIZE(vfsmount));
  8226. fprintf(fp, " mount: %ld\n", SIZE(mount));
  8227. fprintf(fp, " super_block: %ld\n",
  8228. SIZE(super_block));
  8229. fprintf(fp, " irqdesc: %ld\n", SIZE(irqdesc));
  8230. fprintf(fp, " module: %ld\n", SIZE(module));
  8231. fprintf(fp, " module_sect_attr: %ld\n", SIZE(module_sect_attr));
  8232. fprintf(fp, " list_head: %ld\n", SIZE(list_head));
  8233. fprintf(fp, " hlist_head: %ld\n", SIZE(hlist_head));
  8234. fprintf(fp, " hlist_node: %ld\n", SIZE(hlist_node));
  8235. fprintf(fp, " irq_cpustat_t: %ld\n",
  8236. SIZE(irq_cpustat_t));
  8237. fprintf(fp, " cpuinfo_x86: %ld\n", SIZE(cpuinfo_x86));
  8238. fprintf(fp, " cpuinfo_ia64: %ld\n",
  8239. SIZE(cpuinfo_ia64));
  8240. fprintf(fp, " timer_list: %ld\n", SIZE(timer_list));
  8241. fprintf(fp, " timer_vec_root: %ld\n",
  8242. SIZE(timer_vec_root));
  8243. fprintf(fp, " timer_vec: %ld\n", SIZE(timer_vec));
  8244. fprintf(fp, " tvec_root_s: %ld\n",
  8245. SIZE(tvec_root_s));
  8246. fprintf(fp, " tvec_s: %ld\n", SIZE(tvec_s));
  8247. fprintf(fp, " tvec_t_base_s: %ld\n",
  8248. SIZE(tvec_t_base_s));
  8249. fprintf(fp, " wait_queue: %ld\n", SIZE(wait_queue));
  8250. fprintf(fp, " __wait_queue: %ld\n",
  8251. SIZE(__wait_queue));
  8252. fprintf(fp, " device: %ld\n", SIZE(device));
  8253. fprintf(fp, " net_device: %ld\n", SIZE(net_device));
  8254. fprintf(fp, " sock: %ld\n", SIZE(sock));
  8255. fprintf(fp, " inet_sock: %ld\n", SIZE(inet_sock));
  8256. fprintf(fp, " socket: %ld\n", SIZE(socket));
  8257. fprintf(fp, " in6_addr: %ld\n", SIZE(in6_addr));
  8258. fprintf(fp, " signal_struct: %ld\n",
  8259. SIZE(signal_struct));
  8260. fprintf(fp, " sigpending_signal: %ld\n",
  8261. SIZE(sigpending_signal));
  8262. fprintf(fp, " signal_queue: %ld\n",
  8263. SIZE(signal_queue));
  8264. fprintf(fp, " sigqueue: %ld\n", SIZE(sigqueue));
  8265. fprintf(fp, " k_sigaction: %ld\n",
  8266. SIZE(k_sigaction));
  8267. fprintf(fp, " sighand_struct: %ld\n",
  8268. SIZE(sighand_struct));
  8269. fprintf(fp, " resource_entry_t: %ld\n",
  8270. SIZE(resource_entry_t));
  8271. fprintf(fp, " resource: %ld\n", SIZE(resource));
  8272. fprintf(fp, " runqueue: %ld\n", SIZE(runqueue));
  8273. fprintf(fp, " irq_desc_t: %ld\n", SIZE(irq_desc_t));
  8274. fprintf(fp, " irq_data: %ld\n", SIZE(irq_data));
  8275. fprintf(fp, " task_union: %ld\n", SIZE(task_union));
  8276. fprintf(fp, " thread_union: %ld\n", SIZE(thread_union));
  8277. fprintf(fp, " prio_array: %ld\n", SIZE(prio_array));
  8278. fprintf(fp, " user_regs_struct: %ld\n",
  8279. SIZE(user_regs_struct));
  8280. fprintf(fp, " switch_stack: %ld\n",
  8281. SIZE(switch_stack));
  8282. fprintf(fp, " vm_area_struct_vm_flags: %ld\n",
  8283. SIZE(vm_area_struct_vm_flags));
  8284. fprintf(fp, " e820map: %ld\n", SIZE(e820map));
  8285. fprintf(fp, " e820entry: %ld\n", SIZE(e820entry));
  8286. fprintf(fp, " cpu_s: %ld\n", SIZE(cpu_s));
  8287. fprintf(fp, " pgd_t: %ld\n", SIZE(pgd_t));
  8288. fprintf(fp, " kallsyms_header: %ld\n",
  8289. SIZE(kallsyms_header));
  8290. fprintf(fp, " kallsyms_symbol: %ld\n",
  8291. SIZE(kallsyms_symbol));
  8292. fprintf(fp, " kallsyms_section: %ld\n",
  8293. SIZE(kallsyms_section));
  8294. fprintf(fp, " block_device: %ld\n",
  8295. SIZE(block_device));
  8296. fprintf(fp, " blk_major_name: %ld\n",
  8297. SIZE(blk_major_name));
  8298. fprintf(fp, " address_space: %ld\n",
  8299. SIZE(address_space));
  8300. fprintf(fp, " gendisk: %ld\n",
  8301. SIZE(gendisk));
  8302. fprintf(fp, " irq_ctx: %ld\n", SIZE(irq_ctx));
  8303. fprintf(fp, " char_device_struct: %ld\n",
  8304. SIZE(char_device_struct));
  8305. fprintf(fp, " spinlock_t: %ld\n",
  8306. SIZE(spinlock_t));
  8307. fprintf(fp, " radix_tree_root: %ld\n",
  8308. SIZE(radix_tree_root));
  8309. fprintf(fp, " radix_tree_node: %ld\n",
  8310. SIZE(radix_tree_node));
  8311. fprintf(fp, " x8664_pda: %ld\n",
  8312. SIZE(x8664_pda));
  8313. fprintf(fp, " ppc64_paca: %ld\n",
  8314. SIZE(ppc64_paca));
  8315. fprintf(fp, " gate_struct: %ld\n",
  8316. SIZE(gate_struct));
  8317. fprintf(fp, " tss_struct: %ld\n",
  8318. SIZE(tss_struct));
  8319. fprintf(fp, " task_struct_start_time: %ld\n",
  8320. SIZE(task_struct_start_time));
  8321. fprintf(fp, " task_struct_utime: %ld\n",
  8322. SIZE(task_struct_utime));
  8323. fprintf(fp, " task_struct_stime: %ld\n",
  8324. SIZE(task_struct_stime));
  8325. fprintf(fp, " cputime_t: %ld\n",
  8326. SIZE(cputime_t));
  8327. fprintf(fp, " mem_section: %ld\n",
  8328. SIZE(mem_section));
  8329. fprintf(fp, " pid_link: %ld\n",
  8330. SIZE(pid_link));
  8331. fprintf(fp, " upid: %ld\n",
  8332. SIZE(upid));
  8333. fprintf(fp, " unwind_table: %ld\n",
  8334. SIZE(unwind_table));
  8335. fprintf(fp, " rlimit: %ld\n",
  8336. SIZE(rlimit));
  8337. fprintf(fp, " cfs_rq: %ld\n",
  8338. SIZE(cfs_rq));
  8339. fprintf(fp, " pcpu_info: %ld\n",
  8340. SIZE(pcpu_info));
  8341. fprintf(fp, " vcpu_struct: %ld\n",
  8342. SIZE(vcpu_struct));
  8343. fprintf(fp, " cdev: %ld\n",
  8344. SIZE(cdev));
  8345. fprintf(fp, " probe: %ld\n",
  8346. SIZE(probe));
  8347. fprintf(fp, " kobj_map: %ld\n",
  8348. SIZE(kobj_map));
  8349. fprintf(fp, " cpu_context_save: %ld\n",
  8350. SIZE(cpu_context_save));
  8351. fprintf(fp, " elf_prstatus: %ld\n",
  8352. SIZE(elf_prstatus));
  8353. fprintf(fp, " note_buf: %ld\n",
  8354. SIZE(note_buf));
  8355. fprintf(fp, " unwind_idx: %ld\n",
  8356. SIZE(unwind_idx));
  8357. fprintf(fp, " s390_stack_frame: %ld\n",
  8358. SIZE(s390_stack_frame));
  8359. fprintf(fp, " percpu_data: %ld\n",
  8360. SIZE(percpu_data));
  8361. fprintf(fp, " sched_entity: %ld\n",
  8362. SIZE(sched_entity));
  8363. fprintf(fp, " kernel_stat: %ld\n",
  8364. SIZE(kernel_stat));
  8365. fprintf(fp, " subsystem: %ld\n",
  8366. SIZE(subsystem));
  8367. fprintf(fp, " class_private: %ld\n",
  8368. SIZE(class_private));
  8369. fprintf(fp, " rq_in_flight: %ld\n",
  8370. SIZE(rq_in_flight));
  8371. fprintf(fp, " class_private_devices: %ld\n",
  8372. SIZE(class_private_devices));
  8373. fprintf(fp, " hstate: %ld\n",
  8374. SIZE(hstate));
  8375. fprintf(fp, " ipc_ids: %ld\n",
  8376. SIZE(ipc_ids));
  8377. fprintf(fp, " shmid_kernel: %ld\n",
  8378. SIZE(shmid_kernel));
  8379. fprintf(fp, " sem_array: %ld\n",
  8380. SIZE(sem_array));
  8381. fprintf(fp, " msg_queue: %ld\n",
  8382. SIZE(msg_queue));
  8383. fprintf(fp, " log: %ld\n",
  8384. SIZE(log));
  8385. fprintf(fp, " log_level: %ld\n",
  8386. SIZE(log_level));
  8387. fprintf(fp, " rt_rq: %ld\n",
  8388. SIZE(rt_rq));
  8389. fprintf(fp, " task_group: %ld\n",
  8390. SIZE(task_group));
  8391. fprintf(fp, " vmap_area: %ld\n",
  8392. SIZE(vmap_area));
  8393. fprintf(fp, " hrtimer_clock_base: %ld\n",
  8394. SIZE(hrtimer_clock_base));
  8395. fprintf(fp, " hrtimer_base: %ld\n",
  8396. SIZE(hrtimer_base));
  8397. fprintf(fp, " tnt: %ld\n",
  8398. SIZE(tnt));
  8399. fprintf(fp, "\n array_table:\n");
  8400. /*
  8401. * Use get_array_length() for those fields not set up at init-time;
  8402. * ARRAY_LENGTH() will work for the rest.
  8403. */
  8404. fprintf(fp, " kmem_cache_s_name: %d\n",
  8405. ARRAY_LENGTH(kmem_cache_s_name));
  8406. fprintf(fp, " kmem_cache_s_c_name: %d\n",
  8407. ARRAY_LENGTH(kmem_cache_s_c_name));
  8408. fprintf(fp, " kmem_cache_s_array: %d\n",
  8409. ARRAY_LENGTH(kmem_cache_s_array));
  8410. fprintf(fp, " kmem_cache_s_cpudata: %d\n",
  8411. ARRAY_LENGTH(kmem_cache_s_cpudata));
  8412. fprintf(fp, " log_buf: %d\n",
  8413. ARRAY_LENGTH(log_buf));
  8414. fprintf(fp, " irq_desc: %d\n",
  8415. ARRAY_LENGTH(irq_desc));
  8416. fprintf(fp, " irq_action: %d\n",
  8417. ARRAY_LENGTH(irq_action));
  8418. fprintf(fp, " timer_vec_vec: %d\n",
  8419. get_array_length("timer_vec.vec", NULL, SIZE(list_head)));
  8420. fprintf(fp, " timer_vec_root_vec: %d\n",
  8421. get_array_length("timer_vec_root.vec", NULL, SIZE(list_head)));
  8422. fprintf(fp, " tvec_root_s_vec: %d\n",
  8423. get_array_length("tvec_root_s.vec", NULL, SIZE(list_head)));
  8424. fprintf(fp, " tvec_s_vec: %d\n",
  8425. get_array_length("tvec_s.vec", NULL, SIZE(list_head)));
  8426. fprintf(fp, " page_hash_table: %d\n",
  8427. ARRAY_LENGTH(page_hash_table));
  8428. fprintf(fp, " net_device_name: %d\n",
  8429. ARRAY_LENGTH(net_device_name));
  8430. fprintf(fp, " neigh_table_hash_buckets: %d\n",
  8431. get_array_length("neigh_table.hash_buckets", NULL,
  8432. sizeof(void *)));
  8433. fprintf(fp, " neighbour_ha: %d\n",
  8434. get_array_length("neighbour.ha", NULL, sizeof(char)));
  8435. fprintf(fp, " swap_info: %d\n",
  8436. get_array_length("swap_info", NULL, 0));
  8437. fprintf(fp, " pglist_data_node_zones: %d\n",
  8438. ARRAY_LENGTH(pglist_data_node_zones));
  8439. fprintf(fp, " zone_struct_free_area: %d\n",
  8440. ARRAY_LENGTH(zone_struct_free_area));
  8441. fprintf(fp, " zone_free_area: %d\n",
  8442. ARRAY_LENGTH(zone_free_area));
  8443. fprintf(fp, " free_area: %d\n",
  8444. ARRAY_LENGTH(free_area));
  8445. fprintf(fp, " free_area_DIMENSION: %d\n",
  8446. ARRAY_LENGTH(free_area_DIMENSION));
  8447. fprintf(fp, " prio_array_queue: %d\n",
  8448. get_array_length("prio_array.queue", NULL, SIZE(list_head)));
  8449. fprintf(fp, " height_to_maxindex: %d\n",
  8450. ARRAY_LENGTH(height_to_maxindex));
  8451. fprintf(fp, " pid_hash: %d\n",
  8452. ARRAY_LENGTH(pid_hash));
  8453. fprintf(fp, " kmem_cache_node: %d\n",
  8454. ARRAY_LENGTH(kmem_cache_node));
  8455. fprintf(fp, " kmem_cache_cpu_slab: %d\n",
  8456. ARRAY_LENGTH(kmem_cache_cpu_slab));
  8457. fprintf(fp, " rt_prio_array_queue: %d\n",
  8458. ARRAY_LENGTH(rt_prio_array_queue));
  8459. if (spec) {
  8460. int in_size_table, in_array_table, arrays, offsets, sizes;
  8461. in_size_table = in_array_table = arrays = offsets = sizes = 0;
  8462. rewind(pc->tmpfile);
  8463. while (fgets(buf, BUFSIZE, pc->tmpfile)) {
  8464. if (strstr(buf, "size_table:"))
  8465. in_size_table = TRUE;
  8466. if (strstr(buf, "array_table:")) {
  8467. in_array_table = TRUE;
  8468. in_size_table = FALSE;
  8469. }
  8470. if (strstr(buf, spec)) {
  8471. if (in_size_table) {
  8472. if (!sizes)
  8473. fprintf(pc->saved_fp,
  8474. "%s size_table:\n",
  8475. offsets ? "\n" : "");
  8476. sizes++;
  8477. } else if (in_array_table) {
  8478. if (!arrays)
  8479. fprintf(pc->saved_fp,
  8480. "%s array_table:\n",
  8481. offsets || sizes ?
  8482. "\n" : "");
  8483. arrays++;
  8484. } else {
  8485. if (!offsets)
  8486. fprintf(pc->saved_fp,
  8487. " offset_table:\n");
  8488. offsets++;
  8489. }
  8490. if (strstr(buf, " size_table:") ||
  8491. strstr(buf, " array_table:") ||
  8492. strstr(buf, " offset_table:"))
  8493. break;
  8494. fprintf(pc->saved_fp, "%s", buf);
  8495. }
  8496. }
  8497. close_tmpfile();
  8498. }
  8499. if (makestruct) {
  8500. fprintf(pc->saved_fp,
  8501. "static struct builtin_debug_table %s;\n\n",
  8502. revname);
  8503. rewind(pc->tmpfile);
  8504. while (fgets(buf, BUFSIZE, pc->tmpfile)) {
  8505. if (strstr(buf, " offset_table:\n")) {
  8506. fprintf(pc->saved_fp,
  8507. "static struct offset_table %s_offset_table = {\n",
  8508. revname);
  8509. continue;
  8510. }
  8511. if (strstr(buf, " size_table:\n")) {
  8512. fprintf(pc->saved_fp,
  8513. "static struct size_table %s_size_table = {\n",
  8514. revname);
  8515. continue;
  8516. }
  8517. if (strstr(buf, " array_table:\n")) {
  8518. fprintf(pc->saved_fp,
  8519. "static struct array_table %s_array_table = {\n",
  8520. revname);
  8521. continue;
  8522. }
  8523. if (STREQ(buf, "\n")) {
  8524. fprintf(pc->saved_fp, "};\n\n");
  8525. continue;
  8526. }
  8527. fprintf(pc->saved_fp, "%s,\n", strip_linefeeds(buf));
  8528. }
  8529. fprintf(pc->saved_fp, "};\n\n");
  8530. close_tmpfile();
  8531. fprintf(fp, "static struct builtin_debug_table %s = {\n",
  8532. revname);
  8533. fprintf(fp, " release: \"%s\",\n", uts->release);
  8534. fprintf(fp, " machine_type: \"%s\",\n", pc->machine_type);
  8535. fprintf(fp, " offset_table: &%s_offset_table,\n", revname);
  8536. fprintf(fp, " size_table: &%s_size_table,\n", revname);
  8537. fprintf(fp, " array_table: &%s_array_table,\n", revname);
  8538. fprintf(fp, "};\n\n");
  8539. }
  8540. pc->flags |= data_debug;
  8541. }
  8542. #define NUMARGS_CACHE_ENTRIES (100)
  8543. static struct numargs_cache {
  8544. ulong function;
  8545. int numargs;
  8546. } numargs_cache[NUMARGS_CACHE_ENTRIES] = { {0} };
  8547. static int numargs_cache_index = 0;
  8548. int
  8549. get_function_numargs(ulong callpc)
  8550. {
  8551. int i;
  8552. struct numargs_cache *na;
  8553. struct gnu_request *req;
  8554. int retval;
  8555. ulong func;
  8556. func = closest_symbol_value(callpc);
  8557. if (!func)
  8558. return -1;
  8559. for (i = 0; i < NUMARGS_CACHE_ENTRIES; i++) {
  8560. na = &numargs_cache[i];
  8561. if (!na->function) {
  8562. numargs_cache_index = i;
  8563. break;
  8564. }
  8565. if (na->function == func)
  8566. return na->numargs;
  8567. }
  8568. req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request));
  8569. req->buf = GETBUF(BUFSIZE);
  8570. req->command = GNU_FUNCTION_NUMARGS;
  8571. req->flags |= GNU_RETURN_ON_ERROR;
  8572. req->pc = func;
  8573. gdb_interface(req);
  8574. if (req->flags & GNU_COMMAND_FAILED) {
  8575. retval = -1;
  8576. goto func_done;
  8577. }
  8578. retval = (int)req->value;
  8579. func_done:
  8580. FREEBUF(req->buf);
  8581. FREEBUF(req);
  8582. numargs_cache_index %= NUMARGS_CACHE_ENTRIES;
  8583. na = &numargs_cache[numargs_cache_index++];
  8584. na->function = func;
  8585. na->numargs = retval;
  8586. return retval;
  8587. }
  8588. /*
  8589. * help -c output
  8590. */
  8591. void
  8592. dump_numargs_cache(void)
  8593. {
  8594. int i;
  8595. struct numargs_cache *na;
  8596. char buf[BUFSIZE];
  8597. fprintf(fp, "numargs_cache_index: %d\n", numargs_cache_index);
  8598. for (i = 0; i < NUMARGS_CACHE_ENTRIES; i++) {
  8599. na = &numargs_cache[i];
  8600. if (!na->function)
  8601. break;
  8602. fprintf(fp, "%lx (%s): %d\n",
  8603. na->function,
  8604. value_to_symstr(na->function, buf, 0),
  8605. na->numargs);
  8606. }
  8607. }
  8608. /*
  8609. * This is the call-back function that is passed to bfd_map_over_sections().
  8610. * Based upon the request, check whether the passed-in section has what
  8611. * the caller needs. The MODULE_SECTIONS code is tricky because it has
  8612. * to keep a running alignment value as it walks through the section
  8613. * headers in order to eventually calculate the module's base data address.
  8614. */
  8615. static void
  8616. section_header_info(bfd *bfd, asection *section, void *reqptr)
  8617. {
  8618. int i;
  8619. struct load_module *lm;
  8620. ulong request;
  8621. asection **sec;
  8622. ulong section_end_address;
  8623. request = ((ulong)reqptr);
  8624. switch (request)
  8625. {
  8626. case (ulong)KERNEL_SECTIONS:
  8627. sec = (asection **)st->sections;
  8628. for (i = 0; (i < st->bfd->section_count) && *sec; i++)
  8629. sec++;
  8630. *sec = section;
  8631. if (STREQ(bfd_get_section_name(bfd, section), ".text.init") ||
  8632. STREQ(bfd_get_section_name(bfd, section), ".init.text")) {
  8633. kt->stext_init = (ulong)
  8634. bfd_get_section_vma(bfd, section);
  8635. kt->etext_init = kt->stext_init +
  8636. (ulong)bfd_section_size(bfd, section);
  8637. }
  8638. if (STREQ(bfd_get_section_name(bfd, section), ".text")) {
  8639. st->first_section_start = (ulong)
  8640. bfd_get_section_vma(bfd, section);
  8641. }
  8642. if (STREQ(bfd_get_section_name(bfd, section), ".text") ||
  8643. STREQ(bfd_get_section_name(bfd, section), ".data")) {
  8644. if (!(bfd_get_section_flags(bfd, section) & SEC_LOAD))
  8645. st->flags |= NO_SEC_LOAD;
  8646. if (!(bfd_get_section_flags(bfd, section) &
  8647. SEC_HAS_CONTENTS))
  8648. st->flags |= NO_SEC_CONTENTS;
  8649. }
  8650. if (STREQ(bfd_get_section_name(bfd, section), ".eh_frame")) {
  8651. st->dwarf_eh_frame_file_offset = (off_t)section->filepos;
  8652. st->dwarf_eh_frame_size = (ulong)bfd_section_size(bfd, section);
  8653. }
  8654. if (STREQ(bfd_get_section_name(bfd, section), ".debug_frame")) {
  8655. st->dwarf_debug_frame_file_offset = (off_t)section->filepos;
  8656. st->dwarf_debug_frame_size = (ulong)bfd_section_size(bfd, section);
  8657. }
  8658. if (st->first_section_start != 0) {
  8659. section_end_address =
  8660. (ulong) bfd_get_section_vma(bfd, section) +
  8661. (ulong) bfd_section_size(bfd, section);
  8662. if (section_end_address > st->last_section_end)
  8663. st->last_section_end = section_end_address;
  8664. }
  8665. break;
  8666. case (ulong)MODULE_SECTIONS:
  8667. lm = st->current;
  8668. store_section_data(lm, bfd, section);
  8669. break;
  8670. case (ulong)VERIFY_SECTIONS:
  8671. if (STREQ(bfd_get_section_name(bfd, section), ".text") ||
  8672. STREQ(bfd_get_section_name(bfd, section), ".data")) {
  8673. if (!(bfd_get_section_flags(bfd, section) & SEC_LOAD))
  8674. st->flags |= NO_SEC_LOAD;
  8675. if (!(bfd_get_section_flags(bfd, section) &
  8676. SEC_HAS_CONTENTS))
  8677. st->flags |= NO_SEC_CONTENTS;
  8678. }
  8679. if (STREQ(bfd_get_section_name(bfd, section), ".eh_frame")) {
  8680. st->dwarf_eh_frame_file_offset = (off_t)section->filepos;
  8681. st->dwarf_eh_frame_size = (ulong)bfd_section_size(bfd, section);
  8682. }
  8683. if (STREQ(bfd_get_section_name(bfd, section), ".debug_frame")) {
  8684. st->dwarf_debug_frame_file_offset = (off_t)section->filepos;
  8685. st->dwarf_debug_frame_size = (ulong)bfd_section_size(bfd, section);
  8686. }
  8687. break;
  8688. default:
  8689. error(FATAL, "invalid call to section_header_info\n");
  8690. break;
  8691. }
  8692. }
  8693. /*
  8694. * Emulate insmod by calculating the priorities of each section.
  8695. * The priority number will be used later by calculate_load_order()
  8696. * to determine the the starting addresses of the text and data
  8697. * sections.
  8698. *
  8699. * insmod uses the following code sequence -- which references the actual ELF
  8700. * section header structure data:
  8701. *
  8702. * ac = 0;
  8703. * if (a->name[0] != '.' || strlen(a->name) != 10 ||
  8704. * strcmp(a->name + 5, ".init")) ac |= 32;
  8705. * if (af & SHF_ALLOC) ac |= 16;
  8706. * if (!(af & SHF_WRITE)) ac |= 8;
  8707. * if (af & SHF_EXECINSTR) ac |= 4;
  8708. * if (a->header.sh_type != SHT_NOBITS) ac |= 2;
  8709. *
  8710. * BFD abstracts the ELF section header into an asection structure, so this
  8711. * code determines the priority using the relevant logic.
  8712. */
  8713. static void
  8714. store_section_data(struct load_module *lm, bfd *bfd, asection *section)
  8715. {
  8716. int i;
  8717. int prio;
  8718. char *name;
  8719. prio = 0;
  8720. name = (char *)bfd_get_section_name(bfd, section);
  8721. if (name[0] != '.' || strlen(name) != 10 || strcmp(name + 5, ".init"))
  8722. prio |= 32;
  8723. if (section->flags & SEC_ALLOC)
  8724. prio |= 16;
  8725. if (section->flags & SEC_READONLY)
  8726. prio |= 8;
  8727. if (section->flags & SEC_CODE)
  8728. prio |= 4;
  8729. if (!STREQ(name, ".bss"))
  8730. prio |= 2;
  8731. i = lm->mod_sections;
  8732. lm->mod_section_data[i].section = section;
  8733. lm->mod_section_data[i].priority = prio;
  8734. lm->mod_section_data[i].flags = section->flags & ~SEC_FOUND;
  8735. /*
  8736. * The percpu section isn't included in kallsyms or module_core area.
  8737. */
  8738. if (lm->mod_percpu &&
  8739. (STREQ(name,".data.percpu") || STREQ(name, ".data..percpu"))) {
  8740. lm->mod_percpu_size = bfd_section_size(bfd, section);
  8741. lm->mod_section_data[i].flags |= SEC_FOUND;
  8742. }
  8743. lm->mod_section_data[i].size = bfd_section_size(bfd, section);
  8744. lm->mod_section_data[i].offset = 0;
  8745. if (strlen(name) < MAX_MOD_SEC_NAME)
  8746. strcpy(lm->mod_section_data[i].name, name);
  8747. else
  8748. strncpy(lm->mod_section_data[i].name, name, MAX_MOD_SEC_NAME-1);
  8749. lm->mod_sections += 1;
  8750. }
  8751. /*
  8752. * insmod first calculates a priority for each module section, and re-orders
  8753. * the sections from their ELF object file position -- that priority was
  8754. * determined in store_section_priority(). Now, based upon a priority-based
  8755. * ordering, this routine calculates the starting offset for each section.
  8756. * This is the code segment from insmod that is being emulated here:
  8757. *
  8758. * unsigned long
  8759. * obj_load_size (struct obj_file *f)
  8760. * {
  8761. * unsigned long dot = 0;
  8762. * struct obj_section *sec;
  8763. *
  8764. * /+ Finalize the positions of the sections relative to one another. +/
  8765. *
  8766. * for (sec = f->load_order; sec ; sec = sec->load_next)
  8767. * {
  8768. * ElfW(Addr) align;
  8769. *
  8770. * align = sec->header.sh_addralign;
  8771. * if (align && (dot & (align - 1)))
  8772. * dot = (dot | (align - 1)) + 1;
  8773. *
  8774. * sec->header.sh_addr = dot;
  8775. * dot += sec->header.sh_size;
  8776. * }
  8777. *
  8778. * return dot;
  8779. * }
  8780. *
  8781. * Another insmod hack extends the .kstrtab section with a string containing
  8782. * the name of the module. If the .kstrtab comes before the .data section,
  8783. * it in turn gets bumped up.
  8784. *
  8785. * BFD abstracts the ELF section header into an asection structure, so this
  8786. * code determines the priority using the relevant logic.
  8787. *
  8788. * Later versions of insmod do the work for us by creating pseudo-symbols
  8789. * that contain the base address of the text, rodata, data and bss sections.
  8790. * When that's the case, veer off to check_insmod_builtin() to potentially
  8791. * override the offset value calculated here.
  8792. */
  8793. static void
  8794. calculate_load_order_v1(struct load_module *lm, bfd *bfd)
  8795. {
  8796. int i;
  8797. asection *section;
  8798. ulong alignment;
  8799. ulong offset;
  8800. offset = 0;
  8801. switch (kt->flags & (KMOD_V1|KMOD_V2))
  8802. {
  8803. case KMOD_V1:
  8804. offset = lm->mod_size_of_struct;
  8805. break;
  8806. case KMOD_V2:
  8807. offset = lm->mod_base;
  8808. break;
  8809. }
  8810. qsort(&lm->mod_section_data[0], lm->mod_sections,
  8811. sizeof(struct mod_section_data), compare_prios);
  8812. for (i = (lm->mod_sections-1); i >= 0; i--) {
  8813. section = lm->mod_section_data[i].section;
  8814. alignment = power(2, bfd_get_section_alignment(bfd, section));
  8815. if (alignment && (offset & (alignment - 1)))
  8816. offset = (offset | (alignment - 1)) + 1;
  8817. lm->mod_section_data[i].offset = offset;
  8818. if (CRASHDEBUG(1))
  8819. fprintf(fp, "%12s prio: %x flags: %x offset: %lx\n",
  8820. lm->mod_section_data[i].name,
  8821. lm->mod_section_data[i].priority,
  8822. lm->mod_section_data[i].flags,
  8823. lm->mod_section_data[i].offset);
  8824. if (st->flags & INSMOD_BUILTIN)
  8825. check_insmod_builtin(lm, i, &offset);
  8826. if (STREQ(lm->mod_section_data[i].name, ".text"))
  8827. lm->mod_text_start = lm->mod_base + offset;
  8828. if (STREQ(lm->mod_section_data[i].name, ".data"))
  8829. lm->mod_data_start = lm->mod_base + offset;
  8830. if (STREQ(lm->mod_section_data[i].name, ".bss"))
  8831. lm->mod_bss_start = lm->mod_base + offset;
  8832. if (STREQ(lm->mod_section_data[i].name, ".rodata"))
  8833. lm->mod_rodata_start = lm->mod_base + offset;
  8834. offset += bfd_section_size(bfd, section);
  8835. if (STREQ(bfd_get_section_name(bfd, section), ".kstrtab"))
  8836. offset += strlen(lm->mod_name)+1;
  8837. }
  8838. }
  8839. /*
  8840. * Later versions of kmod no longer get the help from insmod,
  8841. * and while the heuristics might work, it's relatively
  8842. * straightforward to just try to match the sections in the object file
  8843. * with exported symbols.
  8844. *
  8845. * This works well if kallsyms is set, but may not work so well in other
  8846. * instances.
  8847. */
  8848. static void
  8849. calculate_load_order_v2(struct load_module *lm, bfd *bfd, int dynamic,
  8850. void *minisyms, long symcount, unsigned int size)
  8851. {
  8852. struct syment *s1, *s2;
  8853. ulong sec_start;
  8854. bfd_byte *from, *fromend;
  8855. asymbol *store;
  8856. asymbol *sym;
  8857. symbol_info syminfo;
  8858. char *secname;
  8859. int i;
  8860. if ((store = bfd_make_empty_symbol(bfd)) == NULL)
  8861. error(FATAL, "bfd_make_empty_symbol() failed\n");
  8862. s1 = lm->mod_symtable;
  8863. s2 = lm->mod_symend;
  8864. while (s1 < s2) {
  8865. ulong sym_offset = s1->value - lm->mod_base;
  8866. if (MODULE_PSEUDO_SYMBOL(s1)) {
  8867. s1++;
  8868. continue;
  8869. }
  8870. /* Skip over symbols whose sections have been identified. */
  8871. for (i = 0; i < lm->mod_sections; i++) {
  8872. if ((lm->mod_section_data[i].flags & SEC_FOUND) == 0)
  8873. continue;
  8874. if (sym_offset >= lm->mod_section_data[i].offset
  8875. && sym_offset < lm->mod_section_data[i].offset
  8876. + lm->mod_section_data[i].size) {
  8877. break;
  8878. }
  8879. }
  8880. /* Matched one of the sections. Skip symbol. */
  8881. if (i < lm->mod_sections) {
  8882. if (CRASHDEBUG(2)) {
  8883. fprintf(fp, "skip %lx %s %s\n", s1->value, s1->name,
  8884. lm->mod_section_data[i].name);
  8885. }
  8886. s1++;
  8887. continue;
  8888. }
  8889. /* Find the symbol in the object file. */
  8890. from = (bfd_byte *) minisyms;
  8891. fromend = from + symcount * size;
  8892. secname = NULL;
  8893. for (; from < fromend; from += size) {
  8894. if ((sym = bfd_minisymbol_to_symbol(bfd, dynamic, from,
  8895. store)) == NULL)
  8896. error(FATAL,
  8897. "bfd_minisymbol_to_symbol() failed\n");
  8898. bfd_get_symbol_info(bfd, sym, &syminfo);
  8899. if (CRASHDEBUG(3)) {
  8900. fprintf(fp,"matching sym %s %lx against bfd %s %lx\n",
  8901. s1->name, (long) s1->value, syminfo.name,
  8902. (long) syminfo.value);
  8903. }
  8904. if (strcmp(syminfo.name, s1->name) == 0) {
  8905. secname = (char *)bfd_get_section_name(bfd, sym->section);
  8906. break;
  8907. }
  8908. }
  8909. if (secname == NULL) {
  8910. if (CRASHDEBUG(1)) {
  8911. fprintf(fp, "symbol %s not found in module\n", s1->name);
  8912. }
  8913. s1++;
  8914. continue;
  8915. }
  8916. /* Match the section it came in. */
  8917. for (i = 0; i < lm->mod_sections; i++) {
  8918. if (STREQ(lm->mod_section_data[i].name, secname)) {
  8919. break;
  8920. }
  8921. }
  8922. if (i == lm->mod_sections) {
  8923. fprintf(fp, "?? Section %s not found for symbol %s\n",
  8924. secname, s1->name);
  8925. s1++;
  8926. continue;
  8927. }
  8928. /* Update the offset information for the section */
  8929. sec_start = s1->value - syminfo.value;
  8930. // sec_end = sec_start + lm->mod_section_data[i].size;
  8931. lm->mod_section_data[i].offset = sec_start - lm->mod_base;
  8932. lm->mod_section_data[i].flags |= SEC_FOUND;
  8933. if (CRASHDEBUG(2)) {
  8934. fprintf(fp, "update sec offset sym %s @ %lx val %lx section %s\n",
  8935. s1->name, s1->value, (ulong)syminfo.value, secname);
  8936. }
  8937. if (strcmp(secname, ".text") == 0)
  8938. lm->mod_text_start = sec_start;
  8939. if (strcmp(secname, ".bss") == 0)
  8940. lm->mod_bss_start = sec_start;
  8941. if (strcmp(secname, ".data") == 0)
  8942. lm->mod_data_start = sec_start;
  8943. if (strcmp(secname, ".data") == 0)
  8944. lm->mod_data_start = sec_start;
  8945. if (strcmp(secname, ".rodata") == 0)
  8946. lm->mod_rodata_start = sec_start;
  8947. s1++;
  8948. }
  8949. }
  8950. /*
  8951. * Later versons of insmod store basic address information of each
  8952. * module in a format that looks like the following example of the
  8953. * nfsd module:
  8954. *
  8955. * d004d000 __insmod_nfsd_O/lib/modules/2.2.17/fs/nfsd.o_M3A7EE300_V131601
  8956. * d004d054 __insmod_nfsd_S.text_L30208
  8957. * d0054840 __insmod_nfsd_S.rodata_L8930
  8958. * d0056b40 __insmod_nfsd_S.data_L1220
  8959. * d00570c0 __insmod_nfsd_S.bss_L123840
  8960. *
  8961. * When that's true, override the offset value made by calculate_load_order().
  8962. */
  8963. static void
  8964. check_insmod_builtin(struct load_module *lm, int index, ulong *offset)
  8965. {
  8966. struct syment *sp;
  8967. char buf[BUFSIZE];
  8968. ulong offs;
  8969. sprintf(buf, "__insmod_%s_S%s",
  8970. lm->mod_name,
  8971. lm->mod_section_data[index].name);
  8972. if (symbol_query(buf, NULL, &sp) == 1) {
  8973. if (CRASHDEBUG(1))
  8974. fprintf(fp, "check_insmod_builtin: %lx %s\n",
  8975. sp->value, sp->name);
  8976. offs = sp->value - lm->mod_base;
  8977. if (offs != *offset) {
  8978. if (CRASHDEBUG(1))
  8979. fprintf(fp,
  8980. "check_insmod_builtin: [%s] %s %lx != %lx\n",
  8981. lm->mod_name,
  8982. lm->mod_section_data[index].name,
  8983. offs, *offset);
  8984. *offset = offs;
  8985. }
  8986. }
  8987. }
  8988. /*
  8989. * Determine whether a module symbol is one of the insmod-created symbols
  8990. * described above.
  8991. */
  8992. static int
  8993. is_insmod_builtin(struct load_module *lm, struct syment *sp)
  8994. {
  8995. char buf[BUFSIZE];
  8996. if (!(st->flags & INSMOD_BUILTIN))
  8997. return FALSE;
  8998. sprintf(buf, "__insmod_%s_S", lm->mod_name);
  8999. if (strstr(sp->name, buf))
  9000. return TRUE;
  9001. return FALSE;
  9002. }
  9003. /*
  9004. * Modified from typical "qsort" help functions to simulate section-ordering
  9005. * done by insmod when loading modules.
  9006. */
  9007. static int
  9008. compare_prios(const void *v1, const void *v2)
  9009. {
  9010. struct mod_section_data *md1, *md2;
  9011. md1 = (struct mod_section_data *)v1;
  9012. md2 = (struct mod_section_data *)v2;
  9013. return (md1->priority < md2->priority ? -1 : 1);
  9014. }
  9015. /*
  9016. * This routine scours a module object file namelist for global text and
  9017. * data symbols, sorting and storing them in a static table for quick
  9018. * reference. This allows access to non-EXPORT_SYMBOL() symbols.
  9019. * The object file is then passed to gdb for loading of all symbolic
  9020. * and debugging data.
  9021. *
  9022. * Thanks to David Addison (addy@quadrics.com) for the suggestion.
  9023. */
  9024. int
  9025. load_module_symbols(char *modref, char *namelist, ulong base_addr)
  9026. {
  9027. static bfd *mbfd;
  9028. char **matching;
  9029. long symcount;
  9030. void *minisyms;
  9031. unsigned int size;
  9032. int result;
  9033. struct load_module *lm;
  9034. asymbol *sort_x;
  9035. asymbol *sort_y;
  9036. if (!is_module_name(modref, NULL, &lm))
  9037. error(FATAL, "%s: not a loaded module name\n", modref);
  9038. if ((lm->mod_flags & MOD_LOAD_SYMS) || strlen(lm->mod_namelist)) {
  9039. if (CRASHDEBUG(1))
  9040. fprintf(fp, "%s: module symbols are already loaded\n",
  9041. modref);
  9042. return TRUE;
  9043. }
  9044. if (CRASHDEBUG(2))
  9045. fprintf(fp, "load_module_symbols: %s %s %lx %lx\n",
  9046. modref, namelist, base_addr, kt->flags);
  9047. switch (kt->flags & (KMOD_V1|KMOD_V2))
  9048. {
  9049. case KMOD_V1:
  9050. break;
  9051. case KMOD_V2:
  9052. st->current = lm;
  9053. BZERO(lm->mod_namelist, MAX_MOD_NAMELIST);
  9054. if (strlen(namelist) < MAX_MOD_NAMELIST)
  9055. strcpy(lm->mod_namelist, namelist);
  9056. else
  9057. strncpy(lm->mod_namelist, namelist, MAX_MOD_NAMELIST-1);
  9058. if (st->flags & USE_OLD_ADD_SYM)
  9059. goto add_symbols;
  9060. }
  9061. if ((mbfd = bfd_openr(namelist, NULL)) == NULL)
  9062. error(FATAL, "cannot open object file: %s\n", namelist);
  9063. if (!bfd_check_format_matches(mbfd, bfd_object, &matching))
  9064. error(FATAL, "cannot determine object file format: %s\n",
  9065. namelist);
  9066. if (LKCD_KERNTYPES() && (file_elf_version(namelist) == EV_DWARFEXTRACT))
  9067. goto add_symbols; /* no symbols, add the debuginfo */
  9068. if (!(bfd_get_file_flags(mbfd) & HAS_SYMS))
  9069. error(FATAL, "no symbols in object file: %s\n", namelist);
  9070. symcount = bfd_read_minisymbols(mbfd, FALSE, &minisyms, &size);
  9071. if (symcount < 0)
  9072. error(FATAL, "cannot access symbol table data: %s\n",
  9073. namelist);
  9074. else if (symcount == 0)
  9075. error(FATAL, "no symbols in object file: %s\n", namelist);
  9076. if (CRASHDEBUG(2)) {
  9077. fprintf(fp, "%ld symbols found in obj file %s\n", symcount,
  9078. namelist);
  9079. }
  9080. sort_x = bfd_make_empty_symbol(mbfd);
  9081. sort_y = bfd_make_empty_symbol(mbfd);
  9082. if (sort_x == NULL || sort_y == NULL)
  9083. error(FATAL, "bfd_make_empty_symbol() failed\n");
  9084. gnu_qsort(mbfd, minisyms, symcount, size, sort_x, sort_y);
  9085. store_load_module_symbols(mbfd, FALSE, minisyms, symcount,
  9086. size, base_addr, namelist);
  9087. free(minisyms);
  9088. bfd_close(mbfd);
  9089. add_symbols:
  9090. result = add_symbol_file(st->current);
  9091. if (CRASHDEBUG(2))
  9092. check_for_dups(st->current);
  9093. st->current = NULL;
  9094. return result;
  9095. }
  9096. /*
  9097. * Add a module's symbol file data to gdb's notion of the world.
  9098. */
  9099. static int
  9100. add_symbol_file(struct load_module *lm)
  9101. {
  9102. struct gnu_request request, *req;
  9103. char buf[BUFSIZE];
  9104. int i, len;
  9105. char *secname;
  9106. req = &request;
  9107. BZERO(req, sizeof(struct gnu_request));
  9108. if ((lm->mod_flags & MOD_KALLSYMS) &&
  9109. add_symbol_file_kallsyms(lm, req))
  9110. return TRUE;
  9111. for (i = len = 0; i < lm->mod_sections; i++)
  9112. {
  9113. secname = lm->mod_section_data[i].name;
  9114. if ((lm->mod_section_data[i].flags & SEC_FOUND) &&
  9115. (!STREQ(secname, ".text") &&
  9116. !STREQ(secname, ".data.percpu") &&
  9117. !STREQ(secname, ".data..percpu"))) {
  9118. sprintf(buf, " -s %s 0x%lx", secname,
  9119. lm->mod_section_data[i].offset + lm->mod_base);
  9120. len += strlen(buf);
  9121. }
  9122. }
  9123. for (i = 0; i < lm->mod_sections; i++)
  9124. {
  9125. secname = lm->mod_section_data[i].name;
  9126. if ((lm->mod_section_data[i].flags & SEC_FOUND) &&
  9127. (STREQ(secname, ".data.percpu") ||
  9128. STREQ(secname, ".data..percpu"))) {
  9129. sprintf(buf, " -s %s 0x%lx", secname, lm->mod_percpu);
  9130. len += strlen(buf);
  9131. }
  9132. }
  9133. if (pc->curcmd_flags & MOD_READNOW)
  9134. lm->mod_flags |= MOD_DO_READNOW;
  9135. req->command = GNU_ADD_SYMBOL_FILE;
  9136. req->addr = (ulong)lm;
  9137. req->buf = GETBUF(len+BUFSIZE);
  9138. if (!CRASHDEBUG(1))
  9139. req->fp = pc->nullfp;
  9140. st->flags |= ADD_SYMBOL_FILE;
  9141. gdb_interface(req);
  9142. st->flags &= ~ADD_SYMBOL_FILE;
  9143. FREEBUF(req->buf);
  9144. sprintf(buf, "set complaints 0");
  9145. gdb_pass_through(buf, NULL, GNU_RETURN_ON_ERROR);
  9146. return(!(req->flags & GNU_COMMAND_FAILED));
  9147. }
  9148. static int
  9149. add_symbol_file_percpu(struct load_module *lm, struct gnu_request *req, int buflen)
  9150. {
  9151. char pbuf[BUFSIZE];
  9152. int i, len;
  9153. char *secname;
  9154. len = strlen(req->buf);
  9155. for (i = 0; i < lm->mod_sections; i++) {
  9156. secname = lm->mod_section_data[i].name;
  9157. if ((lm->mod_section_data[i].flags & SEC_FOUND) &&
  9158. (STREQ(secname, ".data.percpu") ||
  9159. STREQ(secname, ".data..percpu"))) {
  9160. sprintf(pbuf, " -s %s 0x%lx", secname, lm->mod_percpu);
  9161. while ((len + strlen(pbuf)) >= buflen) {
  9162. RESIZEBUF(req->buf, buflen, buflen * 2);
  9163. buflen *= 2;
  9164. }
  9165. strcat(req->buf, pbuf);
  9166. len += strlen(pbuf);
  9167. }
  9168. }
  9169. return buflen;
  9170. }
  9171. /*
  9172. * Gather the module section data from the in-kernel data structures.
  9173. */
  9174. static int
  9175. add_symbol_file_kallsyms(struct load_module *lm, struct gnu_request *req)
  9176. {
  9177. int len, buflen, done, nsections, retval;
  9178. ulong vaddr, array_entry, attribute, owner, name, address;
  9179. long name_type;
  9180. char buf[BUFSIZE];
  9181. char section_name[BUFSIZE];
  9182. ulong section_vaddr;
  9183. #if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1)
  9184. return FALSE;
  9185. #endif
  9186. if (!(st->flags & (MODSECT_VMASK|MODSECT_UNKNOWN))) {
  9187. STRUCT_SIZE_INIT(module_sect_attr, "module_sect_attr");
  9188. MEMBER_OFFSET_INIT(module_sect_attrs,
  9189. "module", "sect_attrs");
  9190. MEMBER_OFFSET_INIT(module_sect_attrs_attrs,
  9191. "module_sect_attrs", "attrs");
  9192. MEMBER_OFFSET_INIT(module_sect_attrs_nsections,
  9193. "module_sect_attrs", "nsections");
  9194. MEMBER_OFFSET_INIT(module_sect_attr_mattr,
  9195. "module_sect_attr", "mattr");
  9196. MEMBER_OFFSET_INIT(module_sect_attr_name,
  9197. "module_sect_attr", "name");
  9198. MEMBER_OFFSET_INIT(module_sect_attr_address,
  9199. "module_sect_attr", "address");
  9200. MEMBER_OFFSET_INIT(module_attribute_attr,
  9201. "module_attribute", "attr");
  9202. MEMBER_OFFSET_INIT(module_sect_attr_attr,
  9203. "module_sect_attr", "attr");
  9204. MEMBER_OFFSET_INIT(module_sections_attrs,
  9205. "module_sections", "attrs");
  9206. MEMBER_OFFSET_INIT(attribute_owner,
  9207. "attribute", "owner");
  9208. if (VALID_MEMBER(module_sect_attrs_attrs) &&
  9209. VALID_MEMBER(module_sect_attr_mattr) &&
  9210. VALID_MEMBER(module_attribute_attr) &&
  9211. VALID_MEMBER(module_sect_attrs_nsections))
  9212. st->flags |= MODSECT_V3;
  9213. else if (VALID_MEMBER(module_sect_attrs_attrs) &&
  9214. VALID_MEMBER(module_sect_attr_mattr) &&
  9215. VALID_MEMBER(module_attribute_attr))
  9216. st->flags |= MODSECT_V2;
  9217. else if (VALID_MEMBER(module_sect_attr_attr) &&
  9218. VALID_MEMBER(module_sections_attrs))
  9219. st->flags |= MODSECT_V1;
  9220. else
  9221. st->flags |= MODSECT_UNKNOWN;
  9222. if ((st->flags & MODSECT_UNKNOWN) ||
  9223. !VALID_STRUCT(module_sect_attr) ||
  9224. (INVALID_MEMBER(attribute_owner) &&
  9225. (st->flags & (MODSECT_V1|MODSECT_V2))) ||
  9226. INVALID_MEMBER(module_sect_attrs) ||
  9227. INVALID_MEMBER(module_sect_attr_name) ||
  9228. INVALID_MEMBER(module_sect_attr_address)) {
  9229. if (CRASHDEBUG(1))
  9230. error(WARNING,
  9231. "module section data structures "
  9232. "unrecognized or changed\n");
  9233. st->flags &= ~(MODSECT_VMASK);
  9234. st->flags |= MODSECT_UNKNOWN;
  9235. return FALSE;
  9236. }
  9237. } else if (st->flags & MODSECT_UNKNOWN)
  9238. return FALSE;
  9239. if (!readmem(lm->module_struct + OFFSET(module_sect_attrs),
  9240. KVADDR, &vaddr, sizeof(void *), "module.sect_attrs",
  9241. RETURN_ON_ERROR|QUIET))
  9242. return FALSE;
  9243. array_entry = attribute = 0;
  9244. switch (st->flags & MODSECT_VMASK)
  9245. {
  9246. case MODSECT_V1:
  9247. array_entry = vaddr + OFFSET(module_sections_attrs);
  9248. nsections = UNUSED;
  9249. break;
  9250. case MODSECT_V2:
  9251. array_entry = vaddr + OFFSET(module_sect_attrs_attrs);
  9252. nsections = UNUSED;
  9253. break;
  9254. case MODSECT_V3:
  9255. array_entry = vaddr + OFFSET(module_sect_attrs_attrs);
  9256. if (!readmem(vaddr + OFFSET(module_sect_attrs_nsections),
  9257. KVADDR, &nsections, sizeof(int),
  9258. "module_sect_attrs.nsections", RETURN_ON_ERROR|QUIET))
  9259. return FALSE;
  9260. if (CRASHDEBUG(2))
  9261. fprintf(fp, "nsections: %d\n", nsections);
  9262. break;
  9263. }
  9264. if (CRASHDEBUG(2))
  9265. fprintf(fp, "%s:\n", lm->mod_namelist);
  9266. name_type = MEMBER_TYPE("module_sect_attr", "name");
  9267. req->buf = GETBUF(buflen = 1024);
  9268. retval = FALSE;
  9269. for (done = FALSE; !done; array_entry += SIZE(module_sect_attr)) {
  9270. switch (st->flags & MODSECT_VMASK)
  9271. {
  9272. case MODSECT_V1:
  9273. attribute = array_entry + OFFSET(module_sect_attr_attr);
  9274. break;
  9275. case MODSECT_V2:
  9276. case MODSECT_V3:
  9277. attribute = array_entry + OFFSET(module_sect_attr_mattr)
  9278. + OFFSET(module_attribute_attr);
  9279. break;
  9280. }
  9281. if (st->flags & (MODSECT_V1|MODSECT_V2))
  9282. owner = attribute + OFFSET(attribute_owner);
  9283. else
  9284. owner = UNUSED;
  9285. address = array_entry + OFFSET(module_sect_attr_address);
  9286. switch (name_type)
  9287. {
  9288. case TYPE_CODE_ARRAY:
  9289. name = array_entry + OFFSET(module_sect_attr_name);
  9290. break;
  9291. case TYPE_CODE_PTR:
  9292. if (!readmem(array_entry + OFFSET(module_sect_attr_name),
  9293. KVADDR, &name, sizeof(void *),
  9294. "module_sect_attr.name", RETURN_ON_ERROR|QUIET)) {
  9295. done = TRUE;
  9296. retval = FALSE;
  9297. continue;
  9298. }
  9299. break;
  9300. default:
  9301. done = TRUE;
  9302. retval = FALSE;
  9303. }
  9304. if (CRASHDEBUG(2)) {
  9305. fprintf(fp, "attribute: %lx ", attribute);
  9306. if (owner == UNUSED)
  9307. fprintf(fp, " owner: (not used)");
  9308. else
  9309. fprintf(fp, " owner: %lx ", owner);
  9310. fprintf(fp, " name: %lx ", name);
  9311. fprintf(fp, " address: %lx\n", address);
  9312. }
  9313. if (nsections == UNUSED) {
  9314. if (!readmem(owner, KVADDR, &vaddr, sizeof(void *),
  9315. "attribute.owner", RETURN_ON_ERROR|QUIET)) {
  9316. done = TRUE;
  9317. continue;
  9318. }
  9319. if (lm->module_struct != vaddr) {
  9320. done = TRUE;
  9321. continue;
  9322. }
  9323. }
  9324. BZERO(section_name, BUFSIZE);
  9325. if (!read_string(name, section_name, 32)) {
  9326. done = TRUE;
  9327. retval = FALSE;
  9328. continue;
  9329. }
  9330. if (!readmem(address, KVADDR, &section_vaddr, sizeof(void *),
  9331. "module_sect_attr.address", RETURN_ON_ERROR|QUIET)) {
  9332. done = TRUE;
  9333. retval = FALSE;
  9334. continue;
  9335. }
  9336. if (CRASHDEBUG(1))
  9337. fprintf(fp, "%lx %s\n", section_vaddr, section_name);
  9338. len = strlen(req->buf);
  9339. if (STREQ(section_name, ".text")) {
  9340. sprintf(buf, "add-symbol-file %s 0x%lx %s",
  9341. lm->mod_namelist, section_vaddr,
  9342. pc->curcmd_flags & MOD_READNOW ? "-readnow" : "");
  9343. while ((len + strlen(buf)) >= buflen) {
  9344. RESIZEBUF(req->buf, buflen, buflen * 2);
  9345. buflen *= 2;
  9346. }
  9347. shift_string_right(req->buf, strlen(buf));
  9348. strncpy(req->buf, buf, strlen(buf));
  9349. retval = TRUE;
  9350. } else {
  9351. sprintf(buf, " -s %s 0x%lx", section_name, section_vaddr);
  9352. while ((len + strlen(buf)) >= buflen) {
  9353. RESIZEBUF(req->buf, buflen, buflen * 2);
  9354. buflen *= 2;
  9355. }
  9356. strcat(req->buf, buf);
  9357. }
  9358. if (nsections != UNUSED) {
  9359. if (--nsections == 0)
  9360. done = TRUE;
  9361. }
  9362. }
  9363. if (retval == FALSE) {
  9364. if (CRASHDEBUG(1))
  9365. fprintf(fp, "%s: add_symbol_file_kallsyms failed\n",
  9366. lm->mod_namelist);
  9367. FREEBUF(req->buf);
  9368. req->buf = NULL;
  9369. return FALSE;
  9370. }
  9371. /*
  9372. * Special case for per-cpu symbols
  9373. */
  9374. buflen = add_symbol_file_percpu(lm, req, buflen);
  9375. lm->mod_flags |= MOD_NOPATCH;
  9376. req->command = GNU_ADD_SYMBOL_FILE;
  9377. req->addr = (ulong)lm;
  9378. if (!CRASHDEBUG(1))
  9379. req->fp = pc->nullfp;
  9380. st->flags |= ADD_SYMBOL_FILE;
  9381. gdb_interface(req);
  9382. st->flags &= ~ADD_SYMBOL_FILE;
  9383. FREEBUF(req->buf);
  9384. sprintf(buf, "set complaints 0");
  9385. gdb_pass_through(buf, NULL, GNU_RETURN_ON_ERROR);
  9386. return(!(req->flags & GNU_COMMAND_FAILED));
  9387. }
  9388. /*
  9389. * Given a syment structure of a valid symbol, determine which
  9390. * load_module (if any) it belongs to.
  9391. */
  9392. static int
  9393. load_module_index(struct syment *sp)
  9394. {
  9395. int i;
  9396. ulong value;
  9397. struct load_module *lm;
  9398. value = sp->value;
  9399. for (i = 0; i < st->mods_installed; i++) {
  9400. lm = &st->load_modules[i];
  9401. if (IN_MODULE(value, lm))
  9402. return i;
  9403. if (IN_MODULE_INIT(value, lm))
  9404. return i;
  9405. }
  9406. return (error(FATAL, "cannot find %lx (%s) in module space\n",
  9407. sp->value, sp->name));
  9408. }
  9409. /*
  9410. * Return the syment of a kallsyms-generated module symbol.
  9411. */
  9412. static struct syment *
  9413. kallsyms_module_symbol(struct load_module *lm, symbol_info *syminfo)
  9414. {
  9415. struct syment *sp, *spx;
  9416. int cnt;
  9417. if (!(lm->mod_flags & MOD_KALLSYMS))
  9418. return NULL;
  9419. sp = NULL;
  9420. cnt = 0;
  9421. for (spx = lm->mod_ext_symtable; spx <= lm->mod_ext_symend; spx++) {
  9422. if (!STREQ(spx->name, syminfo->name))
  9423. continue;
  9424. if (spx->cnt) {
  9425. cnt++;
  9426. continue;
  9427. }
  9428. spx->cnt++;
  9429. sp = spx;
  9430. break;
  9431. }
  9432. if (CRASHDEBUG(2)) {
  9433. if (cnt)
  9434. fprintf(fp, "kallsyms [%s] %s: multiply defined\n",
  9435. lm->mod_name, syminfo->name);
  9436. if (sp)
  9437. fprintf(fp, "kallsyms [%s] %s: %lx\n",
  9438. lm->mod_name, syminfo->name, sp->value);
  9439. else
  9440. fprintf(fp, "kallsyms [%s] %s: NOT FOUND\n",
  9441. lm->mod_name, syminfo->name);
  9442. }
  9443. return sp;
  9444. }
  9445. /*
  9446. * Replace the externally-defined module symbols found in store_load_modules()
  9447. * with all the text and data symbols found in the load module object file.
  9448. */
  9449. static void
  9450. store_load_module_symbols(bfd *bfd, int dynamic, void *minisyms,
  9451. long symcount, unsigned int size, ulong base_addr, char *namelist)
  9452. {
  9453. int i;
  9454. asymbol *store;
  9455. asymbol *sym;
  9456. bfd_byte *from, *fromend;
  9457. symbol_info syminfo;
  9458. struct syment *sp, *spx;
  9459. struct load_module *lm;
  9460. char name[BUFSIZE];
  9461. char *nameptr, *secname;
  9462. long index;
  9463. long symalloc;
  9464. int found;
  9465. if ((store = bfd_make_empty_symbol(bfd)) == NULL)
  9466. error(FATAL, "bfd_make_empty_symbol() failed\n");
  9467. st->current = lm = NULL;
  9468. /*
  9469. * Find out whether this module has already been loaded. Coming
  9470. * out of this for loop, lm->mod_load_symtable will either be set to
  9471. * a reusable symbol table, or NULL if it needs to be re-malloc'd.
  9472. */
  9473. for (i = symalloc = 0; i < st->mods_installed; i++) {
  9474. lm = &st->load_modules[i];
  9475. if (lm->mod_base == base_addr) {
  9476. symalloc = symcount + lm->mod_ext_symcnt;
  9477. if (lm->mod_load_symtable &&
  9478. (lm->mod_symalloc < symalloc)) {
  9479. free(lm->mod_load_symtable);
  9480. namespace_ctl(NAMESPACE_FREE,
  9481. &lm->mod_load_namespace, NULL, NULL);
  9482. lm->mod_load_symtable = NULL;
  9483. }
  9484. break;
  9485. }
  9486. }
  9487. if (i == st->mods_installed)
  9488. error(FATAL, "cannot find module at %lx\n", base_addr);
  9489. if (!lm->mod_load_symtable) {
  9490. if ((lm->mod_load_symtable = (struct syment *)
  9491. calloc(symalloc, sizeof(struct syment))) == NULL)
  9492. error(FATAL, "module syment space malloc: %s\n",
  9493. strerror(errno));
  9494. if (!namespace_ctl(NAMESPACE_INIT, &lm->mod_load_namespace,
  9495. (void *)symalloc, NULL))
  9496. error(FATAL, "module name space malloc: %s\n",
  9497. strerror(errno));
  9498. } else
  9499. namespace_ctl(NAMESPACE_REUSE, &lm->mod_load_namespace,
  9500. NULL, NULL);
  9501. st->current = lm;
  9502. lm->mod_symalloc = symalloc;
  9503. BZERO(lm->mod_namelist, MAX_MOD_NAMELIST);
  9504. if (strlen(namelist) < MAX_MOD_NAMELIST)
  9505. strcpy(lm->mod_namelist, namelist);
  9506. else
  9507. strncpy(lm->mod_namelist, namelist, MAX_MOD_NAMELIST-1);
  9508. lm->mod_text_start = lm->mod_data_start = 0;
  9509. lm->mod_rodata_start = lm->mod_bss_start = 0;
  9510. lm->mod_load_symcnt = 0;
  9511. lm->mod_sections = 0;
  9512. for (spx = lm->mod_ext_symtable; spx <= lm->mod_ext_symend; spx++)
  9513. spx->cnt = 0;
  9514. sp = lm->mod_load_symtable;
  9515. if (!(lm->mod_section_data = (struct mod_section_data *)
  9516. malloc(sizeof(struct mod_section_data) *
  9517. (bfd->section_count+1))))
  9518. error(FATAL, "module section data array malloc: %s\n",
  9519. strerror(errno));
  9520. bfd_map_over_sections(bfd, section_header_info, MODULE_SECTIONS);
  9521. if (kt->flags & KMOD_V1)
  9522. calculate_load_order_v1(lm, bfd);
  9523. else
  9524. calculate_load_order_v2(lm, bfd, dynamic, minisyms,
  9525. symcount, size);
  9526. from = (bfd_byte *) minisyms;
  9527. fromend = from + symcount * size;
  9528. for (; from < fromend; from += size)
  9529. {
  9530. if ((sym = bfd_minisymbol_to_symbol(bfd, dynamic, from, store))
  9531. == NULL)
  9532. error(FATAL, "bfd_minisymbol_to_symbol() failed\n");
  9533. bfd_get_symbol_info(bfd, sym, &syminfo);
  9534. secname = (char *)bfd_get_section_name(bfd, sym->section);
  9535. found = 0;
  9536. if (kt->flags & KMOD_V1) {
  9537. switch (syminfo.type)
  9538. {
  9539. case 'b':
  9540. case 'B':
  9541. if (CRASHDEBUG(2))
  9542. fprintf(fp, "%08lx (%c) [%s] %s\n",
  9543. (ulong)syminfo.value,
  9544. syminfo.type, secname, syminfo.name);
  9545. if (!lm->mod_bss_start)
  9546. break;
  9547. syminfo.value += lm->mod_bss_start;
  9548. found = 1;
  9549. break;
  9550. case 'd':
  9551. case 'D':
  9552. if (CRASHDEBUG(2))
  9553. fprintf(fp, "%08lx (%c) [%s] %s\n",
  9554. (ulong)syminfo.value,
  9555. syminfo.type, secname, syminfo.name);
  9556. if (STREQ(secname, ".rodata")) {
  9557. if (!lm->mod_rodata_start)
  9558. break;
  9559. syminfo.value += lm->mod_rodata_start;
  9560. } else {
  9561. if (!lm->mod_data_start)
  9562. break;
  9563. syminfo.value += lm->mod_data_start;
  9564. }
  9565. found = 1;
  9566. break;
  9567. case 't':
  9568. case 'T':
  9569. if (CRASHDEBUG(2))
  9570. fprintf(fp, "%08lx (%c) [%s] %s\n",
  9571. (ulong)syminfo.value,
  9572. syminfo.type, secname, syminfo.name);
  9573. if (! lm->mod_text_start) {
  9574. break;
  9575. }
  9576. if ((st->flags & INSMOD_BUILTIN) &&
  9577. (STREQ(name, "init_module") ||
  9578. STREQ(name, "cleanup_module")))
  9579. break;
  9580. syminfo.value += lm->mod_text_start;
  9581. found = 1;
  9582. break;
  9583. default:
  9584. break;
  9585. }
  9586. } else {
  9587. /* Match the section it came in. */
  9588. for (i = 0; i < lm->mod_sections; i++) {
  9589. if (STREQ(lm->mod_section_data[i].name, secname)
  9590. && (lm->mod_section_data[i].flags & SEC_FOUND)) {
  9591. break;
  9592. }
  9593. }
  9594. if (i < lm->mod_sections) {
  9595. if (CRASHDEBUG(2))
  9596. fprintf(fp, "%08lx (%c) [%s] %s\n",
  9597. (ulong)syminfo.value,
  9598. syminfo.type, secname, syminfo.name);
  9599. if ((st->flags & INSMOD_BUILTIN) &&
  9600. (STREQ(name, "init_module") ||
  9601. STREQ(name, "cleanup_module")))
  9602. found = FALSE;
  9603. else if (syminfo.name[0] == '.')
  9604. found = FALSE;
  9605. else if ((spx = kallsyms_module_symbol(lm, &syminfo))) {
  9606. syminfo.value = spx->value;
  9607. found = TRUE;
  9608. } else if (lm->mod_percpu &&
  9609. (STREQ(secname, ".data.percpu") ||
  9610. STREQ(secname, ".data..percpu"))) {
  9611. syminfo.value += lm->mod_percpu;
  9612. found = TRUE;
  9613. } else {
  9614. syminfo.value += lm->mod_section_data[i].offset + lm->mod_base;
  9615. found = TRUE;
  9616. }
  9617. }
  9618. }
  9619. if (found) {
  9620. strcpy(name, syminfo.name);
  9621. strip_module_symbol_end(name);
  9622. strip_symbol_end(name, NULL);
  9623. if (machdep->verify_symbol(name, syminfo.value,
  9624. syminfo.type)) {
  9625. sp->value = syminfo.value;
  9626. sp->type = syminfo.type;
  9627. sp->flags |= MODULE_SYMBOL;
  9628. namespace_ctl(NAMESPACE_INSTALL,
  9629. &lm->mod_load_namespace, sp, name);
  9630. if (CRASHDEBUG(2))
  9631. fprintf(fp, "installing %c %08lx %s\n", syminfo.type, sp->value,
  9632. name);
  9633. sp++;
  9634. lm->mod_load_symcnt++;
  9635. }
  9636. }
  9637. }
  9638. lm->mod_load_symend = &lm->mod_load_symtable[lm->mod_load_symcnt];
  9639. /*
  9640. * Merge in any externals that didn't show up in the four
  9641. * syminfo data types accepted above, plus the two pseudo symbols.
  9642. * Note that the new syment name pointers haven't been resolved yet.
  9643. */
  9644. for (spx = lm->mod_ext_symtable; spx <= lm->mod_ext_symend; spx++) {
  9645. found = FALSE;
  9646. for (sp = lm->mod_load_symtable;
  9647. sp < lm->mod_load_symend; sp++) {
  9648. index = (long)sp->name;
  9649. nameptr = &lm->mod_load_namespace.address[index];
  9650. if (STREQ(spx->name, nameptr)) {
  9651. found = TRUE;
  9652. if (spx->value == sp->value) {
  9653. if (CRASHDEBUG(2))
  9654. fprintf(fp,
  9655. "%s: %s matches!\n",
  9656. lm->mod_name,
  9657. nameptr);
  9658. } else {
  9659. if (CRASHDEBUG(2))
  9660. fprintf(fp,
  9661. "[%s] %s: %lx != extern'd value: %lx\n",
  9662. lm->mod_name,
  9663. nameptr, sp->value,
  9664. spx->value);
  9665. }
  9666. break;
  9667. }
  9668. }
  9669. if (!found) {
  9670. if (CRASHDEBUG(2))
  9671. fprintf(fp, "append ext %s (%lx)\n",
  9672. spx->name, spx->value);
  9673. /* append it here... */
  9674. namespace_ctl(NAMESPACE_INSTALL,
  9675. &lm->mod_load_namespace,
  9676. lm->mod_load_symend, spx->name);
  9677. lm->mod_load_symend->value = spx->value;
  9678. lm->mod_load_symend->type = spx->type;
  9679. lm->mod_load_symend->flags |= MODULE_SYMBOL;
  9680. lm->mod_load_symend++;
  9681. lm->mod_load_symcnt++;
  9682. }
  9683. }
  9684. /*
  9685. * Append helpful pseudo symbols about found out sections.
  9686. * Use 'S' as its type which is never seen in existing symbols.
  9687. */
  9688. for (i = 0; (pc->curcmd_flags & MOD_SECTIONS) &&
  9689. (i < lm->mod_sections); i++) {
  9690. if (!(lm->mod_section_data[i].flags & SEC_FOUND))
  9691. continue;
  9692. /* Section start */
  9693. lm->mod_load_symend->value = lm->mod_base +
  9694. lm->mod_section_data[i].offset;
  9695. lm->mod_load_symend->type = 'S';
  9696. lm->mod_load_symend->flags |= MODULE_SYMBOL;
  9697. sprintf(name, "_MODULE_SECTION_START [%s]",
  9698. lm->mod_section_data[i].name);
  9699. namespace_ctl(NAMESPACE_INSTALL, &lm->mod_load_namespace,
  9700. lm->mod_load_symend, name);
  9701. lm->mod_load_symend++;
  9702. lm->mod_load_symcnt++;
  9703. /* Section end */
  9704. lm->mod_load_symend->value = lm->mod_base +
  9705. lm->mod_section_data[i].offset +
  9706. lm->mod_section_data[i].size;
  9707. lm->mod_load_symend->type = 'S';
  9708. lm->mod_load_symend->flags |= MODULE_SYMBOL;
  9709. sprintf(name, "_MODULE_SECTION_END [%s]",
  9710. lm->mod_section_data[i].name);
  9711. namespace_ctl(NAMESPACE_INSTALL, &lm->mod_load_namespace,
  9712. lm->mod_load_symend, name);
  9713. lm->mod_load_symend++;
  9714. lm->mod_load_symcnt++;
  9715. }
  9716. namespace_ctl(NAMESPACE_COMPLETE, &lm->mod_load_namespace,
  9717. lm->mod_load_symtable, lm->mod_load_symend);
  9718. qsort(lm->mod_load_symtable, lm->mod_load_symcnt, sizeof(struct syment),
  9719. compare_syms);
  9720. lm->mod_load_symend--;
  9721. if (!MODULE_END(lm->mod_load_symend) &&
  9722. !IN_MODULE_PERCPU(lm->mod_load_symend->value, lm))
  9723. error(INFO, "%s: last symbol: %s is not _MODULE_END_%s?\n",
  9724. lm->mod_name, lm->mod_load_symend->name, lm->mod_name);
  9725. lm->mod_symtable = lm->mod_load_symtable;
  9726. lm->mod_symend = lm->mod_load_symend;
  9727. lm->mod_flags &= ~MOD_EXT_SYMS;
  9728. lm->mod_flags |= MOD_LOAD_SYMS;
  9729. st->flags |= LOAD_MODULE_SYMS;
  9730. }
  9731. /*
  9732. * Delete a load module's symbol table. If base_addr is NULL, delete the
  9733. * complete list of modules.
  9734. */
  9735. void
  9736. delete_load_module(ulong base_addr)
  9737. {
  9738. int i;
  9739. struct load_module *lm;
  9740. struct gnu_request request, *req;
  9741. req = &request;
  9742. BZERO(req, sizeof(struct gnu_request));
  9743. req->command = GNU_DELETE_SYMBOL_FILE;
  9744. if (base_addr == ALL_MODULES) {
  9745. for (i = 0; i < st->mods_installed; i++) {
  9746. lm = &st->load_modules[i];
  9747. if (lm->mod_flags & MOD_LOAD_SYMS) {
  9748. req->name = lm->mod_namelist;
  9749. gdb_interface(req);
  9750. }
  9751. if (lm->mod_load_symtable) {
  9752. free(lm->mod_load_symtable);
  9753. namespace_ctl(NAMESPACE_FREE,
  9754. &lm->mod_load_namespace, NULL, NULL);
  9755. }
  9756. if (lm->mod_flags & MOD_REMOTE)
  9757. unlink_module(lm);
  9758. lm->mod_symtable = lm->mod_ext_symtable;
  9759. lm->mod_symend = lm->mod_ext_symend;
  9760. lm->mod_flags &= ~(MOD_LOAD_SYMS|MOD_REMOTE|MOD_NOPATCH);
  9761. lm->mod_flags |= MOD_EXT_SYMS;
  9762. lm->mod_load_symtable = NULL;
  9763. lm->mod_load_symend = NULL;
  9764. lm->mod_namelist[0] = NULLCHAR;
  9765. lm->mod_load_symcnt = lm->mod_symalloc = 0;
  9766. lm->mod_text_start = lm->mod_data_start = 0;
  9767. lm->mod_bss_start = lm->mod_rodata_start = 0;
  9768. lm->mod_sections = 0;
  9769. lm->mod_percpu_size = 0;
  9770. if (lm->mod_section_data)
  9771. free(lm->mod_section_data);
  9772. lm->mod_section_data = (struct mod_section_data *)0;
  9773. }
  9774. st->flags &= ~LOAD_MODULE_SYMS;
  9775. return;
  9776. }
  9777. st->flags &= ~LOAD_MODULE_SYMS; /* restored below (if any found) */
  9778. for (i = 0; i < st->mods_installed; i++) {
  9779. lm = &st->load_modules[i];
  9780. if (lm->mod_base == base_addr) {
  9781. if (lm->mod_flags & MOD_LOAD_SYMS) {
  9782. req->name = lm->mod_namelist;
  9783. gdb_interface(req);
  9784. }
  9785. if (lm->mod_load_symtable) {
  9786. free(lm->mod_load_symtable);
  9787. namespace_ctl(NAMESPACE_FREE,
  9788. &lm->mod_load_namespace, NULL, NULL);
  9789. }
  9790. if (lm->mod_flags & MOD_REMOTE)
  9791. unlink_module(lm);
  9792. lm->mod_symtable = lm->mod_ext_symtable;
  9793. lm->mod_symend = lm->mod_ext_symend;
  9794. lm->mod_flags &= ~(MOD_LOAD_SYMS|MOD_REMOTE|MOD_NOPATCH);
  9795. lm->mod_flags |= MOD_EXT_SYMS;
  9796. lm->mod_load_symtable = NULL;
  9797. lm->mod_load_symend = NULL;
  9798. lm->mod_namelist[0] = NULLCHAR;
  9799. lm->mod_load_symcnt = lm->mod_symalloc = 0;
  9800. lm->mod_text_start = lm->mod_data_start = 0;
  9801. lm->mod_bss_start = lm->mod_rodata_start = 0;
  9802. lm->mod_percpu_size = 0;
  9803. lm->mod_sections = 0;
  9804. if (lm->mod_section_data)
  9805. free(lm->mod_section_data);
  9806. lm->mod_section_data = (struct mod_section_data *)0;
  9807. } else if (lm->mod_flags & MOD_LOAD_SYMS)
  9808. st->flags |= LOAD_MODULE_SYMS;
  9809. }
  9810. }
  9811. /*
  9812. * Check whether a string is the name of a module. If requested, return
  9813. * the base address of the module.
  9814. */
  9815. int
  9816. is_module_name(char *s, ulong *addr, struct load_module **lmp)
  9817. {
  9818. int i;
  9819. struct load_module *lm;
  9820. if (NO_MODULES())
  9821. return FALSE;
  9822. for (i = 0; i < st->mods_installed; i++) {
  9823. lm = &st->load_modules[i];
  9824. if (STREQ(s, lm->mod_name)) {
  9825. if (addr)
  9826. *addr = lm->mod_base;
  9827. if (lmp)
  9828. *lmp = lm;
  9829. return TRUE;
  9830. }
  9831. }
  9832. return FALSE;
  9833. }
  9834. /*
  9835. * Check whether an value is the base address of a module. If requested,
  9836. * return the module name.
  9837. */
  9838. int
  9839. is_module_address(ulong check_addr, char *module_name)
  9840. {
  9841. int i;
  9842. struct load_module *lm;
  9843. if (NO_MODULES())
  9844. return FALSE;
  9845. for (i = 0; i < st->mods_installed; i++) {
  9846. lm = &st->load_modules[i];
  9847. if (check_addr == lm->mod_base) {
  9848. if (module_name)
  9849. strcpy(module_name, lm->mod_name);
  9850. return TRUE;
  9851. }
  9852. }
  9853. return FALSE;
  9854. }
  9855. /*
  9856. * In a MOD_EXT_SYMBOLS module, find a rough estimate as to where the
  9857. * .rodata section starts. The value will be used by is_kernel_text()
  9858. * when symbols are not loaded.
  9859. */
  9860. static void
  9861. find_mod_etext(struct load_module *lm)
  9862. {
  9863. ulong start, end;
  9864. char *modbuf;
  9865. ulong maxchunk, alloc;
  9866. long offset = 0;
  9867. start = roundup(lm->mod_size_of_struct, sizeof(long)) + lm->mod_base;
  9868. end = lm->mod_base + lm->mod_size;
  9869. maxchunk = MIN(end-start, KILOBYTES(32));
  9870. modbuf = GETBUF(maxchunk);
  9871. while (start < end) {
  9872. alloc = MIN(maxchunk, end-start);
  9873. readmem(start, KVADDR, modbuf, alloc,
  9874. "module rodata search chunk", FAULT_ON_ERROR);
  9875. if ((offset = rodata_search((ulong *)modbuf, alloc)) >= 0)
  9876. break;
  9877. start += alloc;
  9878. }
  9879. FREEBUF(modbuf);
  9880. if (offset >= 0)
  9881. lm->mod_etext_guess = start + offset;
  9882. else
  9883. lm->mod_etext_guess = end;
  9884. }
  9885. #define ASCII_WORD_COUNT (16/sizeof(ulong))
  9886. static long
  9887. rodata_search(ulong *buf, ulong size)
  9888. {
  9889. int i, acnt, words;
  9890. long offset;
  9891. ulong *wordptr;
  9892. words = size/sizeof(ulong);
  9893. wordptr = buf;
  9894. for (i = acnt = 0, offset = -1; i < words; i++, wordptr++) {
  9895. if (ascii_long(*wordptr)) {
  9896. if (acnt++ == 0)
  9897. offset = i * sizeof(ulong);
  9898. } else {
  9899. acnt = 0;
  9900. offset = -1;
  9901. }
  9902. if (acnt == ASCII_WORD_COUNT)
  9903. break;
  9904. }
  9905. return offset;
  9906. }
  9907. static int
  9908. ascii_long(ulong word)
  9909. {
  9910. int i, cnt;
  9911. unsigned char c;
  9912. for (i = cnt = 0; i < sizeof(ulong); i++) {
  9913. c = (unsigned char)((word >> (i*BITS_PER_BYTE)) & 0xff);
  9914. if ((c >= ' ') && (c < 0x7f))
  9915. cnt++;
  9916. }
  9917. return (cnt == sizeof(ulong));
  9918. }
  9919. /*
  9920. * Symbol sorting routines adapted from binutils/nm.c
  9921. */
  9922. /* nm.c -- Describe symbol table of a rel file.
  9923. Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
  9924. This file is part of GNU Binutils.
  9925. This program is free software; you can redistribute it and/or modify
  9926. it under the terms of the GNU General Public License as published by
  9927. the Free Software Foundation; either version 2 of the License, or
  9928. (at your option) any later version.
  9929. This program is distributed in the hope that it will be useful,
  9930. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9931. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9932. GNU General Public License for more details.
  9933. You should have received a copy of the GNU General Public License
  9934. along with this program; if not, write to the Free Software
  9935. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  9936. static bfd *gnu_sort_bfd;
  9937. static asymbol *gnu_sort_x;
  9938. static asymbol *gnu_sort_y;
  9939. #define valueof(x) ((x)->section->vma + (x)->value)
  9940. static int
  9941. non_numeric_forward(const void *P_x, const void *P_y)
  9942. {
  9943. asymbol *x, *y;
  9944. const char *xn, *yn;
  9945. x = bfd_minisymbol_to_symbol(gnu_sort_bfd, FALSE, P_x, gnu_sort_x);
  9946. y = bfd_minisymbol_to_symbol(gnu_sort_bfd, FALSE, P_y, gnu_sort_y);
  9947. if (x == NULL || y == NULL)
  9948. error(FATAL, "bfd_minisymbol_to_symbol failed\n");
  9949. xn = bfd_asymbol_name(x);
  9950. yn = bfd_asymbol_name(y);
  9951. return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
  9952. ((yn == NULL) ? 1 : strcmp (xn, yn)));
  9953. }
  9954. static int
  9955. numeric_forward(const void *P_x, const void *P_y)
  9956. {
  9957. asymbol *x, *y;
  9958. asection *xs, *ys;
  9959. x = bfd_minisymbol_to_symbol(gnu_sort_bfd, FALSE, P_x, gnu_sort_x);
  9960. y = bfd_minisymbol_to_symbol(gnu_sort_bfd, FALSE, P_y, gnu_sort_y);
  9961. if (x == NULL || y == NULL)
  9962. error(FATAL, "bfd_minisymbol_to_symbol failed\n");
  9963. if (st->_stext_vmlinux == UNINITIALIZED) {
  9964. if (STREQ(x->name, "_stext"))
  9965. st->_stext_vmlinux = valueof(x);
  9966. else if (STREQ(y->name, "_stext"))
  9967. st->_stext_vmlinux = valueof(y);
  9968. }
  9969. if (kt->flags2 & KASLR_CHECK) {
  9970. if (STREQ(x->name, "randomize_modules") ||
  9971. STREQ(y->name, "randomize_modules")) {
  9972. kt->flags2 &= ~KASLR_CHECK;
  9973. kt->flags2 |= (RELOC_AUTO|KASLR);
  9974. }
  9975. }
  9976. xs = bfd_get_section(x);
  9977. ys = bfd_get_section(y);
  9978. if (bfd_is_und_section(xs)) {
  9979. if (!bfd_is_und_section(ys))
  9980. return -1;
  9981. }
  9982. else if (bfd_is_und_section (ys))
  9983. return 1;
  9984. else if (valueof (x) != valueof (y))
  9985. return valueof (x) < valueof (y) ? -1 : 1;
  9986. return non_numeric_forward(P_x, P_y);
  9987. }
  9988. static void
  9989. gnu_qsort(bfd *bfd,
  9990. void *minisyms,
  9991. long symcount,
  9992. unsigned int size,
  9993. asymbol *x,
  9994. asymbol *y)
  9995. {
  9996. gnu_sort_bfd = bfd;
  9997. gnu_sort_x = x;
  9998. gnu_sort_y = y;
  9999. qsort(minisyms, symcount, size, numeric_forward);
  10000. }
  10001. /*
  10002. * Keep a stash of commonly-accessed text locations checked by the
  10003. * back_trace code. The saved values unsigned 32-bit values.
  10004. * The same routine is used to store and query, based upon whether
  10005. * the passed-in value and valptr args are non-zero.
  10006. */
  10007. #define TEXT_CACHE (50)
  10008. #define MAX_TEXT_CACHE (TEXT_CACHE*4)
  10009. struct text_cache_entry {
  10010. ulong vaddr;
  10011. uint32_t value;
  10012. };
  10013. static struct text_cache {
  10014. int index;
  10015. int entries;
  10016. ulong hits;
  10017. ulong refs;
  10018. struct text_cache_entry *cache;
  10019. } text_cache = { 0 };
  10020. /*
  10021. * Cache the contents of 32-bit text addresses. If "value" is set, the purpose
  10022. * is to cache it. If "valptr" is set, a query is being made for the text
  10023. * address.
  10024. */
  10025. int
  10026. text_value_cache(ulong vaddr, uint32_t value, uint32_t *valptr)
  10027. {
  10028. int i;
  10029. struct text_cache *tc;
  10030. if (!is_kernel_text(vaddr))
  10031. return FALSE;
  10032. tc = &text_cache;
  10033. if (!tc->cache) {
  10034. if (!(tc->cache = (struct text_cache_entry *)
  10035. malloc(sizeof(struct text_cache_entry) * TEXT_CACHE)))
  10036. return FALSE;
  10037. BZERO(tc->cache, sizeof(struct text_cache_entry) * TEXT_CACHE);
  10038. tc->index = 0;
  10039. tc->entries = TEXT_CACHE;
  10040. }
  10041. if (value) {
  10042. for (i = 0; i < tc->entries; i++) {
  10043. if (tc->cache[i].vaddr == vaddr)
  10044. return TRUE;
  10045. }
  10046. i = tc->index;
  10047. tc->cache[i].vaddr = vaddr;
  10048. tc->cache[i].value = value;
  10049. tc->index++;
  10050. if (tc->index == MAX_TEXT_CACHE) {
  10051. tc->index = 0;
  10052. } else if (tc->index == tc->entries) {
  10053. struct text_cache_entry *old_cache;
  10054. old_cache = tc->cache;
  10055. if ((tc->cache = (struct text_cache_entry *)
  10056. realloc(old_cache, sizeof(struct text_cache_entry) *
  10057. (TEXT_CACHE+tc->entries)))) {
  10058. BZERO(&tc->cache[tc->index],
  10059. sizeof(struct text_cache_entry) *
  10060. TEXT_CACHE);
  10061. tc->entries += TEXT_CACHE;
  10062. } else {
  10063. tc->cache = old_cache;
  10064. tc->index = 0;
  10065. }
  10066. }
  10067. return TRUE;
  10068. }
  10069. if (valptr) {
  10070. tc->refs++;
  10071. for (i = 0; i < tc->entries; i++) {
  10072. if (!tc->cache[i].vaddr)
  10073. return FALSE;
  10074. if (tc->cache[i].vaddr == vaddr) {
  10075. *valptr = tc->cache[i].value;
  10076. tc->hits++;
  10077. return TRUE;
  10078. }
  10079. }
  10080. }
  10081. return FALSE;
  10082. }
  10083. /*
  10084. * The gdb disassembler reads text memory byte-by-byte, so this routine
  10085. * acts as a front-end to the 32-bit (4-byte) text storage.
  10086. */
  10087. int
  10088. text_value_cache_byte(ulong vaddr, unsigned char *valptr)
  10089. {
  10090. int i;
  10091. int shift;
  10092. struct text_cache *tc;
  10093. ulong valtmp;
  10094. if (!is_kernel_text(vaddr))
  10095. return FALSE;
  10096. tc = &text_cache;
  10097. tc->refs++;
  10098. for (i = 0; i < tc->entries; i++) {
  10099. if (!tc->cache[i].vaddr)
  10100. return FALSE;
  10101. if ((vaddr >= tc->cache[i].vaddr) &&
  10102. (vaddr < (tc->cache[i].vaddr+SIZEOF_32BIT))) {
  10103. valtmp = tc->cache[i].value;
  10104. shift = (vaddr - tc->cache[i].vaddr) * 8;
  10105. valtmp >>= shift;
  10106. *valptr = valtmp & 0xff;
  10107. tc->hits++;
  10108. return TRUE;
  10109. }
  10110. }
  10111. return FALSE;
  10112. }
  10113. void
  10114. dump_text_value_cache(int verbose)
  10115. {
  10116. int i;
  10117. struct syment *sp;
  10118. ulong offset;
  10119. struct text_cache *tc;
  10120. tc = &text_cache;
  10121. if (!verbose) {
  10122. if (!tc->refs || !tc->cache)
  10123. return;
  10124. fprintf(stderr, " text hit rate: %2ld%% (%ld of %ld)\n",
  10125. (tc->hits * 100)/tc->refs,
  10126. (ulong)tc->hits, (ulong)tc->refs);
  10127. return;
  10128. }
  10129. for (i = 0; tc->cache && (i < tc->entries); i++) {
  10130. if (!tc->cache[i].vaddr)
  10131. break;
  10132. fprintf(fp, "[%2d]: %lx %08x ", i, tc->cache[i].vaddr,
  10133. tc->cache[i].value);
  10134. if ((sp = value_search(tc->cache[i].vaddr, &offset))) {
  10135. fprintf(fp, "(%s+", sp->name);
  10136. switch (pc->output_radix)
  10137. {
  10138. case 10:
  10139. fprintf(fp, "%ld)", offset);
  10140. break;
  10141. case 16:
  10142. fprintf(fp, "%lx)", offset);
  10143. break;
  10144. }
  10145. }
  10146. fprintf(fp, "\n");
  10147. }
  10148. fprintf(fp,
  10149. "text_cache entries: %d index: %d hit rate: %ld%% (%ld of %ld)\n",
  10150. tc->entries, tc->index,
  10151. (tc->hits * 100)/(tc->refs ? tc->refs : 1),
  10152. tc->hits, tc->refs);
  10153. }
  10154. void
  10155. clear_text_value_cache(void)
  10156. {
  10157. int i;
  10158. struct text_cache *tc;
  10159. tc = &text_cache;
  10160. tc->index = 0;
  10161. for (i = 0; tc->cache && (i < tc->entries); i++) {
  10162. tc->cache[i].vaddr = 0;
  10163. tc->cache[i].value = 0;
  10164. }
  10165. }
  10166. /*
  10167. * If a System.map file or a debug kernel was specified, the name hash
  10168. * has been filled -- so sync up gdb's notion of symbol values with
  10169. * the local values, taking dups into account. Given that gdb's
  10170. * minimal_symbol dump is sorted by value, shortcut the get_syment_array()
  10171. * call if the sp after the last one found is associated with the
  10172. * new one.
  10173. */
  10174. #define last_sp addr2
  10175. int
  10176. patch_kernel_symbol(struct gnu_request *req)
  10177. {
  10178. int i, c;
  10179. struct syment *sp_array[1000], *sp;
  10180. if (req->name == PATCH_KERNEL_SYMBOLS_START) {
  10181. if (kt->flags & RELOC_FORCE)
  10182. error(WARNING,
  10183. "\nkernel relocated [%ldMB]: patching %ld gdb minimal_symbol values\n",
  10184. kt->relocate >> 20, st->symcnt);
  10185. if (kt->flags2 & RELOC_AUTO)
  10186. error(WARNING,
  10187. "\nkernel relocated [%ldMB]: patching %ld gdb minimal_symbol values\n",
  10188. (kt->relocate * -1) >> 20, st->symcnt);
  10189. fprintf(fp, (pc->flags & SILENT) || !(pc->flags & TTY) ? "" :
  10190. "\nplease wait... (patching %ld gdb minimal_symbol values) ",
  10191. st->symcnt);
  10192. fflush(fp);
  10193. req->count = 0;
  10194. req->length = 0;
  10195. req->last_sp = 0;
  10196. return TRUE;
  10197. }
  10198. if (req->name == PATCH_KERNEL_SYMBOLS_STOP) {
  10199. fprintf(fp, (pc->flags & SILENT) || !(pc->flags & TTY) ? "" :
  10200. "\r \r");
  10201. st->flags |= GDB_SYMS_PATCHED;
  10202. return TRUE;
  10203. }
  10204. if (!req->name || !req->addr)
  10205. return FALSE;
  10206. sp = (struct syment *)req->last_sp;
  10207. sp += sp ? 1 : 0;
  10208. if (sp && (sp->cnt == 1) && !(sp->flags & SYMBOL_NAME_USED) &&
  10209. STREQ(sp->name, req->name)) {
  10210. *((ulong *)req->addr) = sp->value;
  10211. sp->flags |= SYMBOL_NAME_USED;
  10212. req->last_sp = (ulong)sp;
  10213. } else {
  10214. switch (c = get_syment_array(req->name, sp_array, 1000))
  10215. {
  10216. case 0: req->last_sp = 0;
  10217. return TRUE;
  10218. case 1:
  10219. *((ulong *)req->addr) = sp_array[0]->value;
  10220. sp_array[0]->flags |= SYMBOL_NAME_USED;
  10221. req->last_sp = (ulong)sp_array[0];
  10222. break;
  10223. default:
  10224. for (i = 0; i < c; i++) {
  10225. if (sp_array[i]->flags & SYMBOL_NAME_USED)
  10226. continue;
  10227. *((ulong *)req->addr) = sp_array[i]->value;
  10228. sp_array[i]->flags |= SYMBOL_NAME_USED;
  10229. req->last_sp = (ulong)sp_array[i];
  10230. break;
  10231. }
  10232. break;
  10233. }
  10234. }
  10235. return TRUE;
  10236. }
  10237. #undef last_sp
  10238. /*
  10239. * If the first offset/size is bogus, then use the second if it's OK.
  10240. * But if both are bogus, then check whether we're debugging datatypes,
  10241. * and act accordingly.
  10242. */
  10243. long
  10244. OFFSET_option(long offset1, long offset2, char *func, char *file, int line,
  10245. char *item1, char *item2)
  10246. {
  10247. char errmsg[BUFSIZE];
  10248. if (offset1 >= 0)
  10249. return offset1;
  10250. if (offset2 >= 0)
  10251. return offset2;
  10252. if (pc->flags & DATADEBUG) {
  10253. void *retaddr[NUMBER_STACKFRAMES] = { 0 };
  10254. SAVE_RETURN_ADDRESS(retaddr);
  10255. sprintf(errmsg,
  10256. "invalid (optional) structure member offsets: %s or %s",
  10257. item1, item2);
  10258. datatype_error(retaddr, errmsg, func, file, line);
  10259. }
  10260. return -1;
  10261. }
  10262. long
  10263. SIZE_option(long size1, long size2, char *func, char *file, int line,
  10264. char *item1, char *item2)
  10265. {
  10266. char errmsg[BUFSIZE];
  10267. if (size1 >= 0)
  10268. return size1;
  10269. if (size2 >= 0)
  10270. return size2;
  10271. if (pc->flags & DATADEBUG) {
  10272. void *retaddr[NUMBER_STACKFRAMES] = { 0 };
  10273. SAVE_RETURN_ADDRESS(retaddr);
  10274. sprintf(errmsg, "invalid (optional) structure sizes: %s or %s",
  10275. item1, item2);
  10276. datatype_error(retaddr, errmsg, func, file, line);
  10277. }
  10278. return -1;
  10279. }
  10280. /*
  10281. * Do the work of the former OFFSET() and SIZE() macros.
  10282. *
  10283. * For now verification that the offset is legitimate is only done
  10284. * if the "--data_debug" command line option was used. There
  10285. * could still be constructs like "OFFSET(x) >= 0" in the current
  10286. * code, or in user extensions. Perhaps there should be an option
  10287. * to turn it off instead?
  10288. */
  10289. long
  10290. OFFSET_verify(long offset, char *func, char *file, int line, char *item)
  10291. {
  10292. char errmsg[BUFSIZE];
  10293. if (!(pc->flags & DATADEBUG))
  10294. return offset;
  10295. if (offset < 0) {
  10296. void *retaddr[NUMBER_STACKFRAMES] = { 0 };
  10297. SAVE_RETURN_ADDRESS(retaddr);
  10298. sprintf(errmsg, "invalid structure member offset: %s",
  10299. item);
  10300. datatype_error(retaddr, errmsg, func, file, line);
  10301. }
  10302. return offset;
  10303. }
  10304. long
  10305. SIZE_verify(long size, char *func, char *file, int line, char *item)
  10306. {
  10307. char errmsg[BUFSIZE];
  10308. if (!(pc->flags & DATADEBUG))
  10309. return size;
  10310. if (size < 0) {
  10311. void *retaddr[NUMBER_STACKFRAMES] = { 0 };
  10312. SAVE_RETURN_ADDRESS(retaddr);
  10313. sprintf(errmsg, "invalid structure size: %s", item);
  10314. datatype_error(retaddr, errmsg, func, file, line);
  10315. }
  10316. return size;
  10317. }
  10318. /*
  10319. * Perform the common datatype error handling.
  10320. */
  10321. static void
  10322. datatype_error(void **retaddr, char *errmsg, char *func, char *file, int line)
  10323. {
  10324. char buf[BUFSIZE];
  10325. int fd;
  10326. fprintf(stderr, "\n%s: %s\n", pc->curcmd, errmsg);
  10327. fprintf(stderr, "%s FILE: %s LINE: %d FUNCTION: %s()\n\n",
  10328. space(strlen(pc->curcmd)), file, line, func);
  10329. fflush(stderr);
  10330. dump_trace(retaddr);
  10331. if (pc->flags & TTY) {
  10332. if ((fd = open("/dev/tty", O_RDONLY)) >= 0) {
  10333. tcsetattr(fd, TCSANOW, &pc->termios_orig);
  10334. close(fd);
  10335. }
  10336. }
  10337. if (pc->flags & DROP_CORE)
  10338. drop_core("DROP_CORE flag set: forcing a segmentation fault\n");
  10339. if (CRASHDEBUG(1))
  10340. gdb_readnow_warning();
  10341. if (pc->flags & RUNTIME) {
  10342. sprintf(buf, "%s\n%s FILE: %s LINE: %d FUNCTION: %s()\n",
  10343. errmsg, space(strlen(pc->curcmd)), file, line, func);
  10344. error(FATAL, "%s\n", buf);
  10345. }
  10346. exit(1);
  10347. }
  10348. /*
  10349. * Dump a trace leading to the improper datatype usage.
  10350. */
  10351. void
  10352. dump_trace(void **retaddr)
  10353. {
  10354. int i, c;
  10355. char *thisfile;
  10356. char *arglist[MAXARGS];
  10357. char buf[BUFSIZE];
  10358. FILE *pipe;
  10359. ulong vaddr, size, lookfor;
  10360. ulong last_vaddr, last_size;
  10361. char symbol[BUFSIZE];
  10362. const char *nm_call;
  10363. fflush(fp);
  10364. fflush(stdout);
  10365. fflush(pc->stdpipe);
  10366. thisfile = get_thisfile();
  10367. fprintf(stderr, "[%s] error trace: ", thisfile);
  10368. for (i = (NUMBER_STACKFRAMES-1); i >= 0; i--) {
  10369. if (retaddr[i])
  10370. fprintf(stderr, "%s%lx%s",
  10371. i == 3 ? "" : "=> ",
  10372. (ulong)retaddr[i],
  10373. i == 0 ? "\n" : " ");
  10374. }
  10375. fflush(stderr);
  10376. if (!file_exists("/usr/bin/nm", NULL)) {
  10377. fprintf(stderr, "crash: /usr/bin/nm: no such file\n");
  10378. return;
  10379. }
  10380. if (is_binary_stripped(thisfile))
  10381. nm_call = "/usr/bin/nm -DSBn %s";
  10382. else
  10383. nm_call = "/usr/bin/nm -BSn %s";
  10384. last_size = 0;
  10385. for (i = 0; i < NUMBER_STACKFRAMES; i++) {
  10386. if (!(lookfor = (ulong)retaddr[i]))
  10387. continue;
  10388. sprintf(buf, nm_call, thisfile);
  10389. if (!(pipe = popen(buf, "r"))) {
  10390. perror("pipe");
  10391. break;
  10392. }
  10393. last_vaddr = 0;
  10394. BZERO(symbol, BUFSIZE);
  10395. while (fgets(buf, BUFSIZE, pipe)) {
  10396. c = parse_line(strip_linefeeds(buf), arglist);
  10397. if (c != 4)
  10398. continue;
  10399. vaddr = htol(arglist[0], FAULT_ON_ERROR, NULL);
  10400. size = htol(arglist[1], FAULT_ON_ERROR, NULL);
  10401. if (vaddr > lookfor) {
  10402. if ((lookfor - last_vaddr) > last_size)
  10403. fprintf(stderr, "%s %lx: (undetermined)\n",
  10404. i == 0 ? "\n" : "",
  10405. lookfor);
  10406. else
  10407. fprintf(stderr, "%s %lx: %s+%ld\n",
  10408. i == 0 ? "\n" : "",
  10409. lookfor, symbol,
  10410. lookfor-last_vaddr);
  10411. break;
  10412. }
  10413. strcpy(symbol, arglist[3]);
  10414. last_vaddr = vaddr;
  10415. last_size = size;
  10416. }
  10417. pclose(pipe);
  10418. }
  10419. fprintf(stderr, "\n");
  10420. }
  10421. /*
  10422. * Try best to determine which executable this is.
  10423. */
  10424. static char *
  10425. get_thisfile(void)
  10426. {
  10427. char *buf1;
  10428. char buf2[BUFSIZE];
  10429. char *tok, *path;
  10430. if (pc->program_path[0] == '.' ||
  10431. pc->program_path[0] == '/')
  10432. return pc->program_path;
  10433. if ((path = getenv("PATH"))) {
  10434. strcpy(buf2, path);
  10435. } else
  10436. return pc->program_path;
  10437. buf1 = GETBUF(BUFSIZE);
  10438. tok = strtok(buf2, ":");
  10439. while (tok) {
  10440. sprintf(buf1, "%s/%s", tok, pc->program_name);
  10441. if (file_exists(buf1, NULL) && is_elf_file(buf1)) {
  10442. return buf1;
  10443. }
  10444. tok = strtok(NULL, ":");
  10445. }
  10446. return pc->program_path;
  10447. }
  10448. /*
  10449. * Check whether an address fits into any existing init_module() functions,
  10450. * and if so, return the load_module.
  10451. */
  10452. struct load_module *
  10453. init_module_function(ulong vaddr)
  10454. {
  10455. int i;
  10456. struct load_module *lm;
  10457. if (((kt->flags & (KMOD_V1|KMOD_V2)) == KMOD_V1) ||
  10458. INVALID_MEMBER(module_init_text_size) ||
  10459. INVALID_MEMBER(module_module_init))
  10460. return NULL;
  10461. for (i = 0; i < st->mods_installed; i++) {
  10462. lm = &st->load_modules[i];
  10463. if (!lm->mod_init_module_ptr || !lm->mod_init_text_size)
  10464. continue;
  10465. if ((vaddr >= lm->mod_init_module_ptr) &&
  10466. (vaddr < (lm->mod_init_module_ptr+lm->mod_init_text_size))
  10467. && accessible(vaddr))
  10468. return lm;
  10469. }
  10470. return NULL;
  10471. }