restart.c 166 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434
  1. /* restart.c Copyright (C) 1989-2002 Codemist Ltd */
  2. /*
  3. * Code needed to start off Lisp when no initial heap image is available,
  4. * or to re-instate links between heap and C-coded core if there IS a
  5. * heap loaded. This code is run in a state that is in effect (in-package
  6. * "lisp").
  7. */
  8. /*
  9. * This code may be used and modified, and redistributed in binary
  10. * or source form, subject to the "CCL Public License", which should
  11. * accompany it. This license is a variant on the BSD license, and thus
  12. * permits use of code derived from this in either open and commercial
  13. * projects: but it does require that updates to this code be made
  14. * available back to the originators of the package.
  15. * Before merging other code in with this or linking this code
  16. * with other packages or libraries please check that the license terms
  17. * of the other material are compatible with those of this.
  18. */
  19. /* Signature: 3c2eae4c 16-Feb-2003 */
  20. #include <stdarg.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. #include <float.h>
  24. #include "machine.h"
  25. #include "version.h"
  26. #include "tags.h"
  27. #include "cslerror.h"
  28. #include "externs.h"
  29. #include "read.h"
  30. #include "stream.h"
  31. #include "arith.h"
  32. #include "entries.h"
  33. #ifdef TIMEOUT
  34. #include "timeout.h"
  35. #endif
  36. #ifdef ADDRESS_SIGN_UNKNOWN
  37. int32 address_sign;
  38. #endif
  39. Lisp_Object C_nil;
  40. Lisp_Object *stackbase;
  41. Lisp_Object *nilsegment;
  42. Lisp_Object *stacksegment;
  43. int32 stack_segsize = 1;
  44. char *exit_charvec = NULL;
  45. #ifdef NILSEG_EXTERNS
  46. unsigned32 byteflip;
  47. Lisp_Object codefringe;
  48. Lisp_Object volatile codelimit;
  49. Lisp_Object * volatile stacklimit;
  50. Lisp_Object fringe;
  51. Lisp_Object volatile heaplimit;
  52. Lisp_Object volatile vheaplimit;
  53. Lisp_Object vfringe;
  54. int32 nwork;
  55. int32 exit_reason;
  56. int32 exit_count;
  57. unsigned32 gensym_ser, print_precision, miscflags;
  58. int32 current_modulus, fastget_size, package_bits;
  59. Lisp_Object lisp_true, lambda, funarg, unset_var, opt_key, rest_key;
  60. Lisp_Object quote_symbol, function_symbol, comma_symbol, comma_at_symbol;
  61. Lisp_Object cons_symbol, eval_symbol, work_symbol, evalhook, applyhook;
  62. Lisp_Object macroexpand_hook, append_symbol, exit_tag;
  63. Lisp_Object exit_value, catch_tags;
  64. #ifdef COMMON
  65. Lisp_Object keyword_package;
  66. #endif
  67. Lisp_Object current_package;
  68. Lisp_Object startfn;
  69. #ifdef COMMON
  70. Lisp_Object all_packages, package_symbol, internal_symbol;
  71. Lisp_Object external_symbol, inherited_symbol;
  72. #endif
  73. Lisp_Object gensym_base, string_char_sym, boffo;
  74. #ifdef COMMON
  75. Lisp_Object key_key, allow_other_keys, aux_key;
  76. #endif
  77. Lisp_Object err_table;
  78. #ifdef COMMON
  79. Lisp_Object format_symbol;
  80. #endif
  81. Lisp_Object progn_symbol;
  82. #ifdef COMMON
  83. Lisp_Object expand_def_symbol, allow_key_key, declare_symbol, special_symbol;
  84. #endif
  85. Lisp_Object lisp_work_stream, charvec, raise_symbol, lower_symbol, echo_symbol;
  86. Lisp_Object codevec, litvec, supervisor, B_reg, savedef, comp_symbol;
  87. Lisp_Object compiler_symbol, faslvec, tracedfn, lisp_terminal_io;
  88. Lisp_Object lisp_standard_output, lisp_standard_input, lisp_error_output;
  89. Lisp_Object lisp_trace_output, lisp_debug_io, lisp_query_io;
  90. Lisp_Object prompt_thing, faslgensyms, prinl_symbol, emsg_star, redef_msg;
  91. Lisp_Object expr_symbol, fexpr_symbol, macro_symbol;
  92. Lisp_Object cl_symbols, active_stream, current_module;
  93. Lisp_Object features_symbol, lisp_package, sys_hash_table;
  94. Lisp_Object help_index, cfunarg, lex_words, get_counts, fastget_names;
  95. Lisp_Object input_libraries, output_library, current_file, break_function;
  96. Lisp_Object standard_output, standard_input, debug_io;
  97. Lisp_Object error_output, query_io, terminal_io, trace_output, fasl_stream;
  98. Lisp_Object native_code, native_symbol, traceprint_symbol, loadsource_symbol;
  99. Lisp_Object hankaku_symbol;
  100. Lisp_Object workbase[51];
  101. #endif
  102. Lisp_Object user_base_0, user_base_1, user_base_2, user_base_3, user_base_4;
  103. Lisp_Object user_base_5, user_base_6, user_base_7, user_base_8, user_base_9;
  104. Lisp_Object eq_hash_tables, equal_hash_tables;
  105. /*
  106. * On an Intel 80x86 (because I am almost forced to) and on other machines
  107. * (much more cheerfully, and for choice!) I will arrange my memory as
  108. * a number of pages. A general pool of these pages gets used
  109. * to satisfy requests for heap, vector heap and BPS space. Running
  110. * under the Phar Lap 286 DOS extender in protected mode it seemed that
  111. * all segments returned by malloc() will have their top bit (when punned
  112. * as a long int) zero. Thus even on an 80x86 I could make progress..
  113. * Ditto under the Zortech (Rational Systems) 80286 extender. Win32
  114. * (Windows NT) seems OK too, but Win32s has given me pointers with
  115. * their top bit set... Ugh! For the 80286 and small machines the pages
  116. * will be just 64 Kbytes - for larger machines I will make them a bit
  117. * bigger (typically 256 Kbytes). See PAGE_BITS in machine.h.
  118. *
  119. * Since this code was first written it has become silly to even consider
  120. * computers with 16-bit segmented addressing! It is still convenient to
  121. * allocate memory in chunks, although that does set an upper limit to the
  122. * size of any individual object: this may hurt if a user wants a big vector
  123. * and it does constrain the range of big-numbers supported by the
  124. * artithmetic.
  125. */
  126. void **pages,
  127. **heap_pages,
  128. **vheap_pages,
  129. **bps_pages,
  130. **native_pages;
  131. #ifndef NO_COPYING_GC
  132. void **new_heap_pages,
  133. **new_vheap_pages,
  134. **new_bps_pages,
  135. **new_native_pages;
  136. #endif
  137. int32 pages_count,
  138. heap_pages_count,
  139. vheap_pages_count,
  140. bps_pages_count,
  141. native_pages_count;
  142. #ifndef NO_COPYING_GC
  143. int32 new_heap_pages_count,
  144. new_vheap_pages_count,
  145. new_bps_pages_count,
  146. new_native_pages_count;
  147. #endif
  148. char program_name[64] = {0};
  149. #ifndef COMMON
  150. #ifdef CWIN
  151. /*
  152. * Could be useful for other windowed systems.
  153. */
  154. char **loadable_packages, **switches;
  155. #endif
  156. #endif
  157. int native_code_tag;
  158. int native_pages_changed;
  159. int32 native_fringe;
  160. int current_fp_rep;
  161. static int old_fp_rep;
  162. #ifndef ADDRESS_64
  163. static CSLbool flip_needed;
  164. #endif
  165. static int old_page_bits;
  166. /*
  167. * The next function is handed a page
  168. * of hard code that has just been loaded into memory and it must scan it
  169. * performing all relevant relocation. fringe give the offset within the
  170. * page that is the first byte not in use. The first 4 bytes of the page
  171. * are reserved for storing fringe from one run to the next. The exact
  172. * format of the rest must be sufficient to allow this code to scan
  173. * and correct the code, but thus far I have not defined it, and it will
  174. * anyway tend to need extension each time a new target architecture is
  175. * incorporated (to support the new and curious relocation modes tha the
  176. * new machine requires).
  177. */
  178. static void relocate_native_code(unsigned char *p, int32 n)
  179. {
  180. /*
  181. * One helpful observation here. In pretty well all other parts of CSL
  182. * there is a possibility that an image file created on one computer will
  183. * be reloaded on another and so all the code is ultra-careful to avoid
  184. * sensitivity to byte order etc etc issues. But here the native code that
  185. * is being loaded MUST have been created using the conventions of the
  186. * current computer (otherwise I should not be loading it and I will be
  187. * in huge trouble when I try to execute code from it). So direct and
  188. * simple access to data is legitimate.
  189. */
  190. int32 k = 8;
  191. term_printf("Native code page type %d size %d to be relocated\n",
  192. native_code_tag, n);
  193. while (k <= n)
  194. { unsigned char *block = p + k;
  195. int32 len = car32(block);
  196. term_printf("Block of %d bytes found\n", len);
  197. if (len == 0)
  198. { term_printf("End of native page reached\n");
  199. break;
  200. }
  201. relocate_native_function(block);
  202. k += len;
  203. }
  204. }
  205. void relocate_native_function(unsigned char *bps)
  206. {
  207. /*
  208. * Just for now I will not support native code on 64-bit machines.
  209. * This is just to save me some hassle re-working this relocation mess!
  210. */
  211. #ifndef ADDRESS_64 /* No native code for 64-bit architectures yet */
  212. /*
  213. * Each chunk of memory allocated by make-native will have its length (in
  214. * bytes) in its first 32-bit word. Next comes the offset of the
  215. * start of real code in the block. Just after that there will be a
  216. * hunk of relocation information. The code proper must not start until
  217. * after the relocation records. Relocation information is stored in the
  218. * following format as a sequence of bytes:
  219. * 0 end of relocation information.
  220. * 1 to 170/xx encode a value 0 to 169
  221. * 171 to 255/xx/yy extra byte yy extends following offset xx, and
  222. * its top bit is used to extend opcode to range
  223. * 0 to 169.
  224. * The opcode now in the range 0 to 169 is interpreted as
  225. * 169 no operation
  226. * otherwise (0-12)*(0-12) as target*mode
  227. */
  228. unsigned char *r = bps + 4;
  229. unsigned char *next;
  230. int32 n;
  231. int code;
  232. n = *r++; /* code start offset in LSB format */
  233. n |= (*r++) << 8;
  234. n |= (*r++) << 16;
  235. n |= (*r++) << 24;
  236. next = bps + n;
  237. #define RELOC_END 0
  238. while ((code = *r++) != RELOC_END)
  239. { int32 off = *r++;
  240. unsigned char *target;
  241. /*
  242. * A native compiler will have to generate a sequence of bytes that adhere to
  243. * the contorted format used here.
  244. */
  245. if (code <= 170) code--;
  246. else
  247. { int off1 = *r++;
  248. code = 2*(code-171) + (off1 >> 7);
  249. off = off | ((off1 & 0x7f) << 8);
  250. }
  251. next += off; /* address where next relocation is to be applied */
  252. #define RELOC_NOP 169
  253. /*
  254. * One might like to note that with a long offset the NOP opcode turns into
  255. * an opcode byte 0xff. And if it then has the longest possible offset one]
  256. * gets the 3-byte sequence 0xff/0xff/0xff.
  257. */
  258. if (code == RELOC_NOP) continue;
  259. #define RELOC_0_ARGS 0
  260. #define RELOC_1_ARGS 1
  261. #define RELOC_2_ARGS 2
  262. #define RELOC_3_ARGS 3
  263. #define RELOC_DIRECT_ENTRY 4
  264. #define RELOC_VAR 5
  265. #define RELOC_SELF_1 6
  266. #define RELOC_SELF_2 7
  267. switch (code % 13)
  268. {
  269. default:
  270. term_printf("Illegal relocation byte %.2x\n", code);
  271. my_exit(EXIT_FAILURE);
  272. case RELOC_SELF_1:
  273. /*
  274. * base of current native code block with an 8-bit offset.
  275. */
  276. target = bps + *r++;
  277. break;
  278. case RELOC_SELF_2:
  279. /*
  280. * base of current native code block with 15 or 23-bit offset. The first byte
  281. * is the low 8-bits of the offset. The next is the next 7 bits, with its
  282. * 0x80 bit selecting whether a third byte is needed (which it will hardly
  283. * ever be).
  284. */
  285. off = *r++;
  286. off = off + (*r++ << 8);
  287. if (off & 0x8000) off = (off & 0x7fff) + (*r++ << 15);
  288. target = bps + off;
  289. break;
  290. case RELOC_0_ARGS:
  291. /*
  292. * The next few relocation modes provide access to the C entrypoints
  293. * associated with a medium number of Lisp functions. The tables and
  294. * offsets used are documented in file "eval4.c" and are as used with the
  295. * byte-code compiler.
  296. */
  297. target = (unsigned char *)zero_arg_functions[*r++];
  298. break;
  299. case RELOC_1_ARGS:
  300. target = (unsigned char *)one_arg_functions[*r++];
  301. break;
  302. case RELOC_2_ARGS:
  303. target = (unsigned char *)two_arg_functions[*r++];
  304. break;
  305. case RELOC_3_ARGS:
  306. target = (unsigned char *)three_arg_functions[*r++];
  307. break;
  308. case RELOC_DIRECT_ENTRY:
  309. /*
  310. * There are some entrypoints into the CSL kernel that are not
  311. * called using the usual Lisp conventions but are at a lower-level.
  312. * A selection of these are visible via the table "useful_functions"
  313. * in file fns3.c. This table can be extended if a native-mode compiler
  314. * needs access to any other speciality.
  315. */
  316. target = (unsigned char *)useful_functions[*r++];
  317. break;
  318. case RELOC_VAR:
  319. /*
  320. * The function address_f_var (in fns3.c) returns the address of a Lisp
  321. * internal variable. See there for the numeric encoding used and what can
  322. * be accessed.
  323. */
  324. target = (unsigned char *)address_of_var(*r++);
  325. break;
  326. }
  327. #define RELMODE_ABSOLUTE 0
  328. #define RELMODE_RELATIVE 1
  329. #define RELMODE_REL_PLUS_4 2
  330. #define RELMODE_REL_MINUS_2 3
  331. #define RELMODE_REL_MINUS_4 4
  332. #define RELMODE_REL_OFFSET 5
  333. #define RELMODE_SPARE1 6
  334. #define RELMODE_SPARE2 7
  335. switch (code/13)
  336. {
  337. default:
  338. term_printf("Illegal relocation byte %.2x\n", code);
  339. my_exit(EXIT_FAILURE);
  340. case RELMODE_ABSOLUTE:
  341. /*
  342. * relocate by pointing a 32-bit value directly at the absolute address
  343. * of the target.
  344. */
  345. *(int32 *)next = (int32)target;
  346. break;
  347. case RELMODE_RELATIVE:
  348. /*
  349. * relocate by setting a 32-bit value of the offset from its own first
  350. * byte to the target.
  351. */
  352. *(int32 *)next = (int32)target - (int32)next;
  353. break;
  354. case RELMODE_REL_PLUS_4:
  355. /*
  356. * relocate by setting a 32-bit value of the offset from the start of the
  357. * word after it.
  358. */
  359. *(int32 *)next = (int32)target - ((int32)next + 4);
  360. break;
  361. case RELMODE_REL_MINUS_2:
  362. /*
  363. * relocate by setting a 32-bit value of the offset from the address 2 bytes
  364. * before its start. This may be used on machines where the relative address
  365. * is computed based on the start of the instruction rather than the start of
  366. * the field within the instruction that contains the offset.
  367. */
  368. *(int32 *)next = (int32)target - ((int32)next - 2);
  369. break;
  370. case RELMODE_REL_MINUS_4:
  371. /*
  372. * relocate by setting a 32-bit value of the offset from the address 4 bytes
  373. * before its start. This may be used on machines where the relative address
  374. * is computed based on the start of the instruction rather than the start of
  375. * the field within the instruction that contains the offset.
  376. */
  377. *(int32 *)next = (int32)target - ((int32)next - 4);
  378. break;
  379. case RELMODE_REL_OFFSET:
  380. /*
  381. * relocate by setting a 32-bit value of the offset from some place
  382. * offset using an 8-bit signed value from the start of the address. The
  383. * offset represents the number of bytes after the start of the address
  384. * that is to be used in the calculation. Note that the special values
  385. * -4, -2, 0 and 4 need never be used here because there are special
  386. * relocation modes for those common cases.
  387. */
  388. code = *r++;
  389. if (code & 0x80) code |= ~0xff; /* Sign extend */
  390. *(int32 *)next = (int32)target - ((int32)next + code);
  391. break;
  392. }
  393. }
  394. #endif
  395. }
  396. static int32 fread_count;
  397. static unsigned char *fread_ptr;
  398. #ifdef SIXTEEN_BIT
  399. #define FREAD_BUFFER_SIZE 0x4000 /* 16 Kbytes of buffer */
  400. #else
  401. #define FREAD_BUFFER_SIZE 0xc000 /* 48 Kbytes of buffer */
  402. #endif
  403. static unsigned char *pair_c, *char_stack;
  404. static unsigned short int *pair_prev;
  405. static void Cfread(char *p, int32 n)
  406. {
  407. /*
  408. * The decompression process does not need hashed access to see if
  409. * character-pairs have been seen before, but it can need a stack to
  410. * unwind codes that have very lengthy expansions.
  411. */
  412. int c1, k;
  413. unsigned int prev, c, next_code;
  414. int32 count = fread_count;
  415. unsigned char *ptr = fread_ptr;
  416. if (n < compression_worth_while)
  417. {
  418. #ifdef MAYBE_AVOID_A_DATA_COPY_OPERATION
  419. if (n > count)
  420. { memcpy(p, ptr, (size_t)count);
  421. p += count;
  422. n -= count;
  423. }
  424. while (n >= FREAD_BUFFER_SIZE)
  425. { count = Iread((unsigned char *)p, FREAD_BUFFER_SIZE);
  426. p += count;
  427. n -= count;
  428. }
  429. /*
  430. * Here I believe that I am in the clear using the (Lisp) stack as
  431. * a buffer area. This is because Cfread is only used to read heap images,
  432. * and when such an image is being loaded the contents of the old one
  433. * (including the stack) are not too relevant.
  434. */
  435. ptr = (unsigned char *)stack;
  436. count = Iread(ptr, FREAD_BUFFER_SIZE);
  437. #endif
  438. while (n > count)
  439. { memcpy(p, ptr, (size_t)count);
  440. p += count;
  441. n -= count;
  442. ptr = (unsigned char *)stack;
  443. count = Iread(ptr, FREAD_BUFFER_SIZE);
  444. }
  445. if (n != 0)
  446. { memcpy(p, ptr, (size_t)n);
  447. ptr += n;
  448. count -= n;
  449. }
  450. fread_count = count;
  451. fread_ptr = ptr;
  452. return;
  453. }
  454. next_code = 256;
  455. if (count == 0)
  456. { ptr = (unsigned char *)stack;
  457. count = Iread(ptr, FREAD_BUFFER_SIZE);
  458. }
  459. c = *ptr++;
  460. count--;
  461. if (count == 0)
  462. { ptr = (unsigned char *)stack;
  463. count = Iread(ptr, FREAD_BUFFER_SIZE);
  464. }
  465. c = (c << 8) | *ptr++;
  466. count--;
  467. prev = c >> 4;
  468. *p++ = (char)prev; /* The first character is not compressed */
  469. n--;
  470. while (n > 0)
  471. { if (count == 0)
  472. { ptr = (unsigned char *)stack;
  473. count = Iread(ptr, FREAD_BUFFER_SIZE);
  474. }
  475. c = ((c & 0xf) << 8) | *ptr++;
  476. count--;
  477. /*
  478. * Decode the next 12 bit character
  479. */
  480. c1 = c;
  481. k = 1;
  482. while (c1 >= 256)
  483. { char_stack[k++] = pair_c[c1];
  484. if (pair_prev[c1] > CODESIZE || k >= CODESIZE)
  485. { term_printf("Bad decoded char %x -> %x, k=%d\n", c1, pair_prev[c1], k);
  486. my_exit(EXIT_FAILURE);
  487. }
  488. c1 = pair_prev[c1];
  489. }
  490. /*
  491. * Write the decoded stuff into the output array.
  492. */
  493. n -= k;
  494. *p++ = (char)c1;
  495. while (k != 1)
  496. { *p++ = char_stack[--k];
  497. }
  498. /*
  499. * ... then build up the decoding tables ready for next time. Of course
  500. * the table building in this decoder MUST exactly match the behaviour of
  501. * the compression code above.
  502. */
  503. if (next_code >= CODESIZE) next_code = 256;
  504. else
  505. { pair_prev[next_code] = (unsigned short int)prev;
  506. pair_c[next_code] = (unsigned char)c1;
  507. next_code++;
  508. }
  509. prev = c;
  510. if (n <= 0) break;
  511. /*
  512. * read the next 12 bit character.
  513. */
  514. if (count == 0)
  515. { ptr = (unsigned char *)stack;
  516. count = Iread(ptr, FREAD_BUFFER_SIZE);
  517. }
  518. c = *ptr++;
  519. count--;
  520. if (count == 0)
  521. { ptr = (unsigned char *)stack;
  522. count = Iread(ptr, FREAD_BUFFER_SIZE);
  523. }
  524. c = (c << 8) | *ptr++;
  525. count--;
  526. /*
  527. * Decode it...
  528. */
  529. c1 = c >> 4;
  530. k = 1;
  531. while (c1 >= 256)
  532. { char_stack[k++] = pair_c[c1];
  533. if (pair_prev[c1] > CODESIZE || k >= CODESIZE)
  534. { term_printf("Bad decoded char %x -> %x, k=%d\n", c1, pair_prev[c1], k);
  535. my_exit(EXIT_FAILURE);
  536. }
  537. c1 = pair_prev[c1];
  538. }
  539. /*
  540. * Write the decoded stuff into the output array.
  541. */
  542. n -= k;
  543. *p++ = (char)c1;
  544. while (k != 1)
  545. { *p++ = char_stack[--k];
  546. }
  547. /*
  548. * ... then build up the decoding tables ready for next time. Of course
  549. * the table building in this decoder MUST exactly match the behaviour of
  550. * the compression code above.
  551. */
  552. if (next_code >= CODESIZE) next_code = 256;
  553. else
  554. { pair_prev[next_code] = (unsigned short int)prev;
  555. pair_c[next_code] = (unsigned char)c1;
  556. next_code++;
  557. }
  558. prev = c >> 4;
  559. }
  560. fread_count = count;
  561. fread_ptr = ptr;
  562. }
  563. #ifdef ADDRESS_64
  564. #define flip_bytes(a) (a)
  565. #else
  566. #define flip_bytes(a) (flip_needed ? flip_bytes_fn(a) : (a))
  567. #endif
  568. static unsigned32 flip_bytes_fn(unsigned32 x)
  569. {
  570. unsigned32 b0, b1, b2, b3;
  571. b0 = (x >> 24) & 0xffU;
  572. b1 = (x >> 8) & 0xff00U;
  573. b2 = (x << 8) & 0xff0000U;
  574. b3 = (x << 24) & 0xff000000U;
  575. return b0 | b1 | b2 | b3;
  576. }
  577. #ifdef ADDRESS_64
  578. #define flip_halfwords(a) (a)
  579. #else
  580. #define flip_halfwords(a) (flip_needed ? flip_halfwords_fn(a) : (a))
  581. static unsigned32 flip_halfwords_fn(unsigned32 x)
  582. {
  583. unsigned32 b0, b1, b2, b3;
  584. b0 = (x >> 8) & 0xffU;
  585. b1 = (x << 8) & 0xff00U;
  586. b2 = (x >> 8) & 0xff0000U;
  587. b3 = (x << 8) & 0xff000000U;
  588. return b0 | b1 | b2 | b3;
  589. }
  590. #endif
  591. void convert_fp_rep(void *p, int old_rep, int new_rep, int type)
  592. {
  593. #ifndef ADDRESS_64
  594. unsigned32 *f = (unsigned32 *)p;
  595. if (old_rep == new_rep) return;
  596. /*
  597. * type == 0 for sfloat, 1 for single float, 2 for double and 3 for extended.
  598. * in CSL mode only case 2 can arise.
  599. */
  600. /*
  601. * At present conversions involving IBM370 or VAX representations are not
  602. * supported, i.e. only IEEE floating point units are allowed for.
  603. * Extended mode is not implemented yet... i.e. I only really expect
  604. * to be using (64-bit) double precision floating point values.
  605. */
  606. if (type >= 2 && ((old_rep ^ new_rep) & FP_WORD_ORDER))
  607. { unsigned32 w = f[0];
  608. f[0] = f[1];
  609. f[1] = w;
  610. }
  611. if ((old_rep ^ new_rep) & FP_BYTE_ORDER)
  612. { f[0] = flip_bytes_fn(f[0]);
  613. if (type >= 2) f[1] = flip_bytes_fn(f[1]);
  614. }
  615. if ((old_rep|new_rep) & (FP_VAXREP|FP_IBMREP))
  616. { term_printf(
  617. "\n+++ This cross-floating representation conversion not supported\n");
  618. /*
  619. * I have not implemented conversions that involve VAX or s/370 representations
  620. */
  621. my_exit(EXIT_FAILURE);
  622. }
  623. #endif
  624. return;
  625. }
  626. static void adjust(Lisp_Object *cp)
  627. /*
  628. * If p is a pointer to an object that has moved, adjust it.
  629. */
  630. {
  631. Lisp_Object nil = C_nil, p = flip_bytes(*cp);
  632. if (p == SPID_NIL) *cp = nil;
  633. else if (is_cons(p))
  634. { intxx h = (intxx)heap_pages[(p>>PAGE_BITS) & PAGE_MASK];
  635. *cp = (Lisp_Object)((char *)quadword_align_up(h) +
  636. (p & OFFSET_MASK));
  637. }
  638. else if (is_immed_or_cons(p))
  639. {
  640. #ifdef COMMON
  641. if (is_sfloat(p))
  642. { intxx w = flip_bytes(p); /* delicate here!! */
  643. convert_fp_rep((void *)&w, old_fp_rep, current_fp_rep, 0);
  644. *cp = w;
  645. }
  646. #endif
  647. *cp = p; /* Immediate data here */
  648. }
  649. else
  650. { intxx h = (intxx)vheap_pages[(p>>PAGE_BITS) & PAGE_MASK];
  651. *cp = (Lisp_Object)((char *)doubleword_align_up(h) +
  652. (p & OFFSET_MASK));
  653. }
  654. }
  655. static void adjust_consheap(void)
  656. {
  657. nil_as_base
  658. int32 page_number;
  659. for (page_number = 0; page_number < heap_pages_count; page_number++)
  660. { void *page = heap_pages[page_number];
  661. char *low = (char *)quadword_align_up((intxx)page);
  662. char *start = low + CSL_PAGE_SIZE;
  663. int32 len = flip_bytes((unsigned32)car32(low));
  664. char *fr;
  665. qcar(low) = len;
  666. fr = low + len;
  667. fringe = (Lisp_Object)fr;
  668. heaplimit = (Lisp_Object)(low + SPARE);
  669. while (fr < start)
  670. { adjust((Lisp_Object *)fr);
  671. fr += sizeof(Lisp_Object);
  672. }
  673. }
  674. }
  675. entry_point entries_table[] =
  676. {
  677. /*
  678. * All values that can go in the function cells of symbols to stand for
  679. * special interpreter activity are kept here. In most cases where there
  680. * is an entrypoint there is a corresponding one that behaves just the
  681. * same except that it has tracing enabled.
  682. */
  683. {0, "xillegal"},
  684. {(void *)undefined1, "1undefined1"},
  685. {(void *)undefined2, "2undefined2"},
  686. {(void *)undefinedn, "nundefinedn"},
  687. {(void *)autoload1, "1autoload1"},
  688. {(void *)autoload2, "2autoload2"},
  689. {(void *)autoloadn, "nautoloadn"},
  690. {(void *)interpreted1, "1interpreted1"},
  691. {(void *)traceinterpreted1, "1traceinterpreted1"},
  692. {(void *)double_interpreted1, "1double_interpreted1"},
  693. {(void *)interpreted2, "2interpreted2"},
  694. {(void *)traceinterpreted2, "2traceinterpreted2"},
  695. {(void *)double_interpreted2, "2double_interpreted2"},
  696. {(void *)interpretedn, "ninterpretedn"},
  697. {(void *)traceinterpretedn, "ntraceinterpretedn"},
  698. {(void *)double_interpretedn, "ndouble_interpretedn"},
  699. {(void *)funarged1, "1funarged1"},
  700. {(void *)tracefunarged1, "1tracefunarged1"},
  701. {(void *)double_funarged1, "1double_funarged1"},
  702. {(void *)funarged2, "2funarged2"},
  703. {(void *)tracefunarged2, "2tracefunarged2"},
  704. {(void *)double_funarged2, "2double_funarged2"},
  705. {(void *)funargedn, "nfunargedn"},
  706. {(void *)tracefunargedn, "ntracefunargedn"},
  707. {(void *)double_funargedn, "ndouble_funargedn"},
  708. {(void *)bytecoded0, "nbytecoded0"},
  709. {(void *)tracebytecoded0, "ntracebytecoded0"},
  710. {(void *)double_bytecoded0, "ndouble_bytecoded0"},
  711. {(void *)bytecoded1, "1bytecoded1"},
  712. {(void *)tracebytecoded1, "1tracebytecoded1"},
  713. {(void *)double_bytecoded1, "1double_bytecoded1"},
  714. {(void *)bytecoded2, "2bytecoded2"},
  715. {(void *)tracebytecoded2, "2tracebytecoded2"},
  716. {(void *)double_bytecoded2, "2double_bytecoded2"},
  717. {(void *)bytecoded3, "nbytecoded3"},
  718. {(void *)tracebytecoded3, "ntracebytecoded3"},
  719. {(void *)double_bytecoded3, "ndouble_bytecoded3"},
  720. {(void *)bytecodedn, "nbytecodedn"},
  721. {(void *)tracebytecodedn, "ntracebytecodedn"},
  722. {(void *)double_bytecodedn, "ndouble_bytecodedn"},
  723. {(void *)byteopt1, "1byteopt1"},
  724. {(void *)tracebyteopt1, "1tracebyteopt1"},
  725. {(void *)double_byteopt1, "1double_byteopt1"},
  726. {(void *)byteopt2, "2byteopt2"},
  727. {(void *)tracebyteopt2, "2tracebyteopt2"},
  728. {(void *)double_byteopt2, "2double_byteopt2"},
  729. {(void *)byteoptn, "nbyteoptn"},
  730. {(void *)tracebyteoptn, "ntracebyteoptn"},
  731. {(void *)double_byteoptn, "ndouble_byteoptn"},
  732. {(void *)hardopt1, "1hardopt1"},
  733. {(void *)tracehardopt1, "1tracehardopt1"},
  734. {(void *)double_hardopt1, "1double_hardopt1"},
  735. {(void *)hardopt2, "2hardopt2"},
  736. {(void *)tracehardopt2, "2tracehardopt2"},
  737. {(void *)double_hardopt2, "2double_hardopt2"},
  738. {(void *)hardoptn, "nhardoptn"},
  739. {(void *)tracehardoptn, "ntracehardoptn"},
  740. {(void *)double_hardoptn, "ndouble_hardoptn"},
  741. {(void *)byteoptrest1, "1byteoptrest1"},
  742. {(void *)tracebyteoptrest1, "1tracebyteoptrest1"},
  743. {(void *)double_byteoptrest1, "1double_byteoptrest1"},
  744. {(void *)byteoptrest2, "2byteoptrest2"},
  745. {(void *)tracebyteoptrest2, "2tracebyteoptrest2"},
  746. {(void *)double_byteoptrest2, "2double_byteoptrest2"},
  747. {(void *)byteoptrestn, "nbyteoptrestn"},
  748. {(void *)tracebyteoptrestn, "ntracebyteoptrestn"},
  749. {(void *)double_byteoptrestn, "ndouble_byteoptrestn"},
  750. {(void *)hardoptrest1, "1hardoptrest1"},
  751. {(void *)tracehardoptrest1, "1tracehardoptrest1"},
  752. {(void *)double_hardoptrest1, "1double_hardoptrest1"},
  753. {(void *)hardoptrest2, "2hardoptrest2"},
  754. {(void *)tracehardoptrest2, "2tracehardoptrest2"},
  755. {(void *)double_hardoptrest2, "2double_hardoptrest2"},
  756. {(void *)hardoptrestn, "nhardoptrestn"},
  757. {(void *)tracehardoptrestn, "ntracehardoptrestn"},
  758. {(void *)double_hardoptrestn, "ndouble_hardoptrestn"},
  759. {(void *)too_many_1, "2too_many_1"},
  760. {(void *)wrong_no_1, "nwrong_no_1"},
  761. {(void *)too_few_2, "1too_few_2"},
  762. {(void *)wrong_no_2, "nwrong_no_2"},
  763. {(void *)wrong_no_0a, "1wrong_no_0a"},
  764. {(void *)wrong_no_0b, "2wrong_no_0b"},
  765. {(void *)wrong_no_3a, "1wrong_no_3a"},
  766. {(void *)wrong_no_3b, "2wrong_no_3b"},
  767. {(void *)wrong_no_na, "1wrong_no_na"},
  768. {(void *)wrong_no_nb, "2wrong_no_nb"},
  769. /*
  770. * As a matter of convenience I will put stream-handling functions here
  771. * too -- they are not kept in symbol headers but in stream control
  772. * blocks, but they too need careful treatment across preserve/restart.
  773. */
  774. {(void *)char_from_illegal, "Xchar_from_illegal"},
  775. {(void *)char_to_illegal, "Xchar_to_illegal"},
  776. {(void *)read_action_illegal, "Xread_action_illegal"},
  777. {(void *)write_action_illegal, "Xwrite_action_illegal"},
  778. {(void *)char_from_terminal, "Xchar_from_terminal"},
  779. {(void *)char_to_terminal, "Xchar_to_terminal"},
  780. {(void *)read_action_terminal, "Xread_action_terminal"},
  781. {(void *)write_action_terminal, "Xwrite_action_terminal"},
  782. {(void *)char_from_file, "Xchar_from_file"},
  783. {(void *)char_to_file, "Xchar_to_file"},
  784. {(void *)read_action_file, "Xread_action_file"},
  785. {(void *)read_action_output_file, "Xread_action_output_file"},
  786. {(void *)write_action_file, "Xwrite_action_file"},
  787. {(void *)binary_outchar, "Xbinary_outchar"},
  788. {(void *)char_from_list, "Xchar_from_list"},
  789. {(void *)char_to_list, "Xchar_to_list"},
  790. {(void *)code_to_list, "Xcode_to_list"},
  791. {(void *)read_action_list, "Xread_action_list"},
  792. {(void *)write_action_list, "Xwrite_action_list"},
  793. {(void *)count_character, "Xcount_character"},
  794. {(void *)char_to_pipeout, "Xchar_to_pipeout"},
  795. {(void *)write_action_pipe, "Xwrite_action_pipe"},
  796. {(void *)char_from_synonym, "Xchar_from_synonym"},
  797. {(void *)char_to_synonym, "Xchar_to_synonym"},
  798. {(void *)read_action_synonym, "Xread_action_synonym"},
  799. {(void *)write_action_synonym, "Xwrite_action_synonym"},
  800. {(void *)char_from_concatenated, "Xchar_from_concatenated"},
  801. {(void *)char_to_broadcast, "Xchar_to_broadcast"},
  802. {(void *)read_action_concatenated, "Xread_action_concatenated"},
  803. {(void *)write_action_broadcast, "Xwrite_action_broadcast"},
  804. {(void *)char_from_echo, "Xchar_from_echo"},
  805. /*
  806. * The batch here relate to function re-work that discards unwanted
  807. * extra arguments.
  808. */
  809. {(void *)f0_as_0, "n0->0"},
  810. {(void *)f1_as_0, "11->0"},
  811. {(void *)f2_as_0, "22->0"},
  812. {(void *)f3_as_0, "n3->0"},
  813. {(void *)f1_as_1, "11->1"},
  814. {(void *)f2_as_1, "22->1"},
  815. {(void *)f3_as_1, "n3->1"},
  816. {(void *)f2_as_2, "22->2"},
  817. {(void *)f3_as_2, "n3->2"},
  818. {(void *)f3_as_3, "n3->3"},
  819. #ifdef CJAVA
  820. {(void *)java0, "njava0"},
  821. {(void *)java1, "1java1"},
  822. {(void *)java2, "2java2"},
  823. {(void *)java3, "njava3"},
  824. {(void *)javan, "njavan"},
  825. #endif
  826. {NULL, "Xdummy"}
  827. };
  828. static void adjust_vecheap(void)
  829. {
  830. nil_as_base
  831. int32 page_number, i;
  832. intxx iw;
  833. for (page_number = 0; page_number < vheap_pages_count; page_number++)
  834. { void *page = vheap_pages[page_number];
  835. char *low = (char *)doubleword_align_up((intxx)page);
  836. int32 len = flip_bytes((unsigned32)car32(low));
  837. char *fr;
  838. qcar(low) = len;
  839. fr = low + len;
  840. vfringe = (Lisp_Object)fr;
  841. vheaplimit = (Lisp_Object)(low + (CSL_PAGE_SIZE - 8));
  842. low += 8;
  843. while (low < fr)
  844. { Header h = flip_bytes(*(Header *)low);
  845. *(Header *)low = h;
  846. if (is_symbol_header(h))
  847. { Lisp_Object ss = (Lisp_Object)(low + TAG_SYMBOL);
  848. adjust(&qvalue(ss));
  849. adjust(&qenv(ss));
  850. adjust(&qpname(ss));
  851. adjust(&qplist(ss));
  852. adjust(&qfastgets(ss));
  853. #ifdef COMMON
  854. adjust(&qpackage(ss));
  855. #endif
  856. /*
  857. * The mess here is because when CSL is re-loaded the position of all
  858. * C-coded entrypoints will very probably have changed since the
  859. * previous run - the set of entrypoints tested for here has to be
  860. * a complete list, except for ones established via "restart.c". Note
  861. * that setup establishes entrypoints later on, so I can afford to leave
  862. * junk in the function cells of things that will be initialised then.
  863. * Thus if a "real" function pointer left over from last time happens
  864. * to look like one of the small integers used here to stand for special
  865. * built-in cases the false-hit I get here is not important.
  866. */
  867. iw = flip_bytes(ifn1(ss));
  868. /*
  869. * Another delicacy - somebody intent on cleaning up this code may spot the
  870. * cast from a function pointer to an integer here, and decide it would be
  871. * neater to make entries_table[] contain a union type that could hide the
  872. * conversion. But that MIGHT not be good enough if sizeof(void *)==8 and
  873. * sizeof(int32)==4, but it has been arranged that all pointers used have
  874. * their 32 most significant bits all zero..... And this odd case can be
  875. * persuaded to apply on a DEC Alpha! The cast as written here really does
  876. * change data representation, but with luck does not lose any vital
  877. * information. Well that is in the "taso" case, but in other 64-bit cases
  878. * it is yet different. Ugh.
  879. */
  880. if (0 < iw && iw < entry_table_size)
  881. { if (*entries_table[iw].s != '1')
  882. { term_printf("?fn1 cell %d %s\n", iw,
  883. entries_table[iw].s);
  884. }
  885. ifn1(ss) = (intxx)entries_table[iw].p;
  886. }
  887. else ifn1(ss) = (intxx)undefined1;
  888. iw = flip_bytes(ifn2(ss));
  889. if (0 < iw && iw < entry_table_size)
  890. { if (*entries_table[iw].s != '2')
  891. { term_printf("?fn2 cell %d %s\n", iw,
  892. entries_table[iw].s);
  893. }
  894. ifn2(ss) = (intxx)entries_table[iw].p;
  895. }
  896. else ifn2(ss) = (intxx)undefined2;
  897. iw = flip_bytes(ifnn(ss));
  898. if (0 < iw && iw < entry_table_size)
  899. { if (*entries_table[iw].s != 'n')
  900. { term_printf("?fnn cell %d %s\n", iw,
  901. entries_table[iw].s);
  902. }
  903. ifnn(ss) = (intxx)entries_table[iw].p;
  904. }
  905. else ifnn(ss) = (intxx)undefinedn;
  906. qcount(ss) = flip_bytes(qcount(ss));
  907. low += symhdr_length;
  908. continue;
  909. }
  910. else switch (type_of_header(h))
  911. {
  912. #ifdef COMMON
  913. case TYPE_RATNUM:
  914. case TYPE_COMPLEX_NUM:
  915. adjust((Lisp_Object *)(low+CELL));
  916. adjust((Lisp_Object *)(low+2*CELL));
  917. break;
  918. #endif
  919. case TYPE_HASH:
  920. case TYPE_SIMPLE_VEC:
  921. case TYPE_ARRAY:
  922. case TYPE_STRUCTURE:
  923. for (i=CELL; i<doubleword_align_up(length_of_header(h)); i+=CELL)
  924. adjust((Lisp_Object *)(low+i));
  925. break;
  926. case TYPE_MIXED1:
  927. case TYPE_MIXED2:
  928. case TYPE_MIXED3:
  929. case TYPE_STREAM:
  930. for (i=CELL; i<4*CELL; i+=CELL) adjust((Lisp_Object *)(low+i));
  931. #ifndef ADDRESS_64
  932. for (; i<doubleword_align_up(length_of_header(h)); i+=4)
  933. *(unsigned32 *)(low+i) =
  934. flip_bytes(*(unsigned32 *)(low+i));
  935. #endif
  936. if (type_of_header(h) == TYPE_STREAM)
  937. { Lisp_Object ss = (Lisp_Object)(low + TAG_VECTOR);
  938. iw = elt(ss, 4);
  939. if (0 < iw && iw < entry_table_size)
  940. { if (*entries_table[iw].s != 'X')
  941. term_printf("Stream fn %d %s\n", iw, entries_table[iw].s);
  942. elt(ss, 4) = (intxx)entries_table[iw].p;
  943. }
  944. else elt(ss, 4) = (intxx)char_to_illegal;
  945. iw = elt(ss, 5);
  946. if (0 < iw && iw < entry_table_size)
  947. { if (*entries_table[iw].s != 'X')
  948. term_printf("Stream fn %d %s\n", iw, entries_table[iw].s);
  949. elt(ss, 5) = (intxx)entries_table[iw].p;
  950. }
  951. else elt(ss, 5) = (intxx)write_action_illegal;
  952. iw = elt(ss, 8);
  953. if (0 < iw && iw < entry_table_size)
  954. { if (*entries_table[iw].s != 'X')
  955. term_printf("Stream fn %d %s\n", iw, entries_table[iw].s);
  956. elt(ss, 8) = (intxx)entries_table[iw].p;
  957. }
  958. else elt(ss, 8) = (intxx)char_from_illegal;
  959. iw = elt(ss, 9);
  960. if (0 < iw && iw < entry_table_size)
  961. { if (*entries_table[iw].s != 'X')
  962. term_printf("Stream fn %d %s\n", iw, entries_table[iw].s);
  963. elt(ss, 9) = (intxx)entries_table[iw].p;
  964. }
  965. else elt(ss, 9) = (intxx)read_action_illegal;
  966. }
  967. break;
  968. case TYPE_BIGNUM:
  969. case TYPE_VEC32:
  970. #ifndef ADDRESS_64
  971. for (i=CELL; i<doubleword_align_up(length_of_header(h)); i+=4)
  972. *(unsigned32 *)(low+i) =
  973. flip_bytes(*(unsigned32 *)(low+i));
  974. #endif
  975. break;
  976. case TYPE_VEC16:
  977. #ifndef ADDRESS_64
  978. for (i=CELL; i<doubleword_align_up(length_of_header(h)); i+=4)
  979. *(unsigned32 *)(low+i) =
  980. flip_halfwords(*(unsigned32 *)(low+i));
  981. #endif
  982. break;
  983. case TYPE_DOUBLE_FLOAT:
  984. /*
  985. * note that this conversion is triggered by the vector header, not by
  986. * the pointer to the object, so punning associated with the pnames of
  987. * un-printed gensyms will not cause any confusion.
  988. */
  989. convert_fp_rep((void *)(low + 8),
  990. old_fp_rep, current_fp_rep, 2);
  991. break;
  992. #ifdef COMMON
  993. case TYPE_SINGLE_FLOAT:
  994. convert_fp_rep((void *)(low + CELL),
  995. old_fp_rep, current_fp_rep, 1);
  996. break;
  997. case TYPE_LONG_FLOAT:
  998. /* Beware - if long floats move up to 3-word values the +8 here will change */
  999. convert_fp_rep((void *)(low + 8),
  1000. old_fp_rep, current_fp_rep, 3);
  1001. break;
  1002. #endif
  1003. case TYPE_FLOAT32:
  1004. for (i=CELL; i<doubleword_align_up(length_of_header(h)); i+=4)
  1005. convert_fp_rep((void *)(low+i),
  1006. old_fp_rep, current_fp_rep, 1);
  1007. break;
  1008. case TYPE_FLOAT64:
  1009. for (i=8; i<doubleword_align_up(length_of_header(h)); i+=8)
  1010. convert_fp_rep((void *)(low+i),
  1011. old_fp_rep, current_fp_rep, 2);
  1012. break;
  1013. default:
  1014. break;
  1015. }
  1016. low += doubleword_align_up(length_of_header(h));
  1017. }
  1018. }
  1019. }
  1020. static void adjust_bpsheap(void)
  1021. /*
  1022. * This is needed so that (e.g.) headers in the code here get byte-flipped
  1023. * if necessary. Also to set codefringe.
  1024. */
  1025. {
  1026. nil_as_base
  1027. int32 page_number;
  1028. #ifdef ENVIRONMENT_VECTORS_IN_BPS_HEAP
  1029. int32 i;
  1030. #endif
  1031. codelimit = codefringe = 0;
  1032. for (page_number = 0; page_number < bps_pages_count; page_number++)
  1033. { void *page = bps_pages[page_number];
  1034. char *low = (char *)doubleword_align_up((intxx)page);
  1035. int32 len = flip_bytes((unsigned32)car32(low));
  1036. char *fr;
  1037. qcar(low) = len;
  1038. fr = low + len;
  1039. codefringe = (Lisp_Object)fr;
  1040. codelimit = (Lisp_Object)(low + 8);
  1041. while (fr < low + CSL_PAGE_SIZE)
  1042. { Header h = flip_bytes(*(Header *)fr);
  1043. *(Header *)fr = h;
  1044. #ifdef ENVIRONMENT_VECTORS_IN_BPS_HEAP
  1045. switch (type_of_header(h))
  1046. {
  1047. case TYPE_SIMPLE_VEC: /* This option not used at present */
  1048. for (i=CELL; i<doubleword_align_up(length_of_header(h)); i+=CELL)
  1049. adjust((Lisp_Object *)(fr+i));
  1050. break;
  1051. default:
  1052. break;
  1053. }
  1054. #endif
  1055. fr += doubleword_align_up(length_of_header(h));
  1056. }
  1057. }
  1058. }
  1059. void adjust_all(void)
  1060. {
  1061. int32 i;
  1062. Lisp_Object nil = C_nil;
  1063. qheader(nil) = TAG_ODDS+TYPE_SYMBOL+SYM_SPECIAL_VAR;
  1064. #ifdef COMMON
  1065. qheader(nil) |= SYM_EXTERN_IN_HOME;
  1066. #endif
  1067. qvalue(nil) = nil;
  1068. qenv(nil) = nil;
  1069. ifn1(nil) = (intxx)undefined1;
  1070. ifn2(nil) = (intxx)undefined2;
  1071. ifnn(nil) = (intxx)undefinedn;
  1072. adjust(&(qpname(nil))); /* not a gensym */
  1073. adjust(&(qplist(nil)));
  1074. adjust(&(qfastgets(nil)));
  1075. #ifdef COMMON
  1076. adjust(&(qpackage(nil)));
  1077. #endif
  1078. copy_into_nilseg(NO);
  1079. for (i = first_nil_offset; i<last_nil_offset; i++)
  1080. adjust(&BASE[i]);
  1081. copy_out_of_nilseg(NO);
  1082. adjust_consheap();
  1083. adjust_vecheap();
  1084. adjust_bpsheap();
  1085. }
  1086. static void *allocate_page(void)
  1087. {
  1088. if (pages_count == 0) fatal_error(err_no_store);
  1089. return pages[--pages_count];
  1090. }
  1091. #ifdef MEMORY_TRACE
  1092. #ifndef CHECK_ONLY
  1093. intxx memory_base, memory_size, memory_count, memory_records = 0;
  1094. unsigned char *memory_map = NULL;
  1095. static intxx memory_lowest = 0x7fffffff, memory_highest = -1;
  1096. FILE *memory_file = NULL;
  1097. void memory_comment(int n)
  1098. {
  1099. if (memory_map != NULL)
  1100. { putc(0xc0 + (n & 0x3f), memory_file);
  1101. putc(0, memory_file);
  1102. putc(0, memory_file);
  1103. }
  1104. }
  1105. int kk = 0;
  1106. static void identify_one(void *p, intxx size, int type)
  1107. {
  1108. int32 i, j;
  1109. intxx base = (intxx)p;
  1110. int32 a = 0, b = 0;
  1111. intxx da = 1, db = 1;
  1112. intxx click = size/0x400;
  1113. switch (type)
  1114. {
  1115. case 0: b = click; break;
  1116. case 1: db = -1; break;
  1117. case 2: b = click; da = db = 2; break;
  1118. case 3: da = 2; db = -2; break;
  1119. case 4: db = 0; break;
  1120. case 5: da = -1; db = 0; break;
  1121. default: b = click; da = db = 0; break;
  1122. }
  1123. if (size > 256)
  1124. { da *= (size/256);
  1125. db *= (size/256);
  1126. }
  1127. memory_count |= 0x3ff;
  1128. cmemory_reference(base);
  1129. memory_comment(kk ? 3 : 5);
  1130. kk = !kk;
  1131. for (i=0; i<32; i++)
  1132. { int x;
  1133. memory_count |= 0x3ff;
  1134. cmemory_reference(base);
  1135. for (j=0; j<0x400; j++)
  1136. { x = a + j*(size/8);
  1137. while (x > size) x -= size;
  1138. while (x < 0) x += size;
  1139. cmemory_reference(base+x);
  1140. x = b + j*(size/8);
  1141. while (x > size) x -= size;
  1142. while (x < 0) x += size;
  1143. cmemory_reference(base+x);
  1144. }
  1145. a += da;
  1146. b += db;
  1147. }
  1148. }
  1149. static void identify_page(void *p[], int32 n, int type)
  1150. {
  1151. while (n != 0)
  1152. { void *w = p[--n];
  1153. if (w != NULL) identify_one(w, CSL_PAGE_SIZE, type);
  1154. }
  1155. }
  1156. void identify_page_types()
  1157. {
  1158. identify_page(pages, pages_count, 0);
  1159. identify_page(heap_pages, heap_pages_count, 1);
  1160. identify_page(vheap_pages, vheap_pages_count, 2);
  1161. identify_page(bps_pages, bps_pages_count, 3);
  1162. identify_page(native_pages, native_pages_count, 4);
  1163. identify_one((void *)stacksegment, CSL_PAGE_SIZE, 5);
  1164. identify_one((void *)nilsegment, NIL_SEGMENT_SIZE, 6);
  1165. }
  1166. #endif /* CHECK_ONLY */
  1167. long int car_counter;
  1168. unsigned long int car_low, car_high;
  1169. Cons_Cell *memory_reference(intxx p)
  1170. {
  1171. if (p & 0x7)
  1172. { term_printf("Access to mis-aligned address %.8x\n", (int)p);
  1173. ensure_screen();
  1174. abort();
  1175. }
  1176. return (Cons_Cell *)cmemory_reference(p);
  1177. }
  1178. char *cmemory_reference(intxx p)
  1179. {
  1180. #ifdef CHECK_ONLY
  1181. return (char *)p;
  1182. #else
  1183. intxx a = p - memory_base;
  1184. if (memory_map != NULL && a >= 0 && a < memory_size)
  1185. { int bit;
  1186. a = a >> 2; /* Get a word address */
  1187. a = a >> 2; /* reduce to 4-word resolution */
  1188. if (memory_count >= car_counter &&
  1189. (unsigned long int)a >= car_low &&
  1190. (unsigned long int)a <= car_high)
  1191. { Lisp_Object nil = C_nil;
  1192. if (exception_pending()) nil = (Lisp_Object)((intxx)nil ^ 1);
  1193. interrupt_pending = 1;
  1194. #ifdef SOFTWARE_TICKS
  1195. countdown = 0;
  1196. #else
  1197. #ifdef TICK_STREAM
  1198. deal_with_tick(); /* pretend tick arrived here and now */
  1199. #endif
  1200. #endif
  1201. miscflags |= HEADLINE_FLAG | MESSAGES_FLAG;
  1202. car_counter = 0x7fffffff; /* Do not interrupt again */
  1203. }
  1204. bit = 1 << (a & 7);
  1205. a = a >> 3;
  1206. if (a < memory_lowest) memory_lowest = a;
  1207. if (a > memory_highest) memory_highest = a;
  1208. memory_map[a] |= bit;
  1209. if ((++memory_count & 0x3ff) == 0) /* Every 1024 references... */
  1210. { unsigned char *pp;
  1211. int c;
  1212. int32 run = 0, i;
  1213. /*
  1214. * I use a run-length encoded representation for the file that I write out.
  1215. * Each scan-line is stored as a collection of bytes each of which indicates
  1216. * the number of '0' items before the next '1' in the bit-vector. The encoding
  1217. * of individual lengths is as follows:
  1218. * 0 - 127 1 byte
  1219. * 128 - 16K First byte has 0x80 plus 6 bits of data (+ 1 more)
  1220. * 16K - 4M First byte has 0xc0 plus 6 bits of data (+ 2 more)
  1221. * The byte pair (0x8n, 0x00) stands for n times 4M as a a prefix to
  1222. * one of the above. This gives up to 2^28 as the max span.
  1223. * The byte pair (0x80, 0x00) can be used to terminate a line.
  1224. * Codes (0xcn, 0x00, 0x00) give 64 special codes that can be used
  1225. * to interveave comments and annotations within the stream.
  1226. */
  1227. pp = memory_map + memory_lowest;
  1228. run = 8*memory_lowest;
  1229. for (i=memory_lowest; i<=memory_highest; i++)
  1230. { c = *pp++;
  1231. if (c != 0)
  1232. { bit = 1;
  1233. while ((c & bit) == 0) run++, bit = bit << 1;
  1234. if (run >= 0x400000)
  1235. { putc(0x80 + ((run >> 22) & 0x3f), memory_file);
  1236. putc(0x00, memory_file);
  1237. run &= 0x3fffff;
  1238. }
  1239. if (run < 0x80) putc(run, memory_file);
  1240. else if (run < 0x4000)
  1241. { putc(0x80 + (run & 0x3f), memory_file);
  1242. putc((run >> 6) & 0xff, memory_file);
  1243. }
  1244. else
  1245. { putc(0xc0 + (run & 0x3f), memory_file);
  1246. putc((run >> 6) & 0xff, memory_file);
  1247. putc((run >> 14) & 0xff, memory_file);
  1248. }
  1249. c &= ~bit;
  1250. run = 0;
  1251. bit = bit << 1;
  1252. while (c != 0)
  1253. { while ((c & bit) == 0) run++, bit = bit << 1;
  1254. putc(run, memory_file);
  1255. c &= ~bit;
  1256. run = 0;
  1257. bit = bit << 1;
  1258. }
  1259. while (bit != 0x100) run++, bit = bit << 1;
  1260. }
  1261. else run += 8;
  1262. }
  1263. putc(0x80, memory_file);
  1264. putc(0x00, memory_file);
  1265. memory_lowest = 0x7fffffff;
  1266. memory_highest = -1;
  1267. memset(memory_map, 0, memory_size/32+8);
  1268. memory_records++;
  1269. }
  1270. }
  1271. return (char *)p;
  1272. #endif /* CHECK_ONLY */
  1273. }
  1274. #endif
  1275. static char *global_handle;
  1276. void *my_malloc(size_t n)
  1277. {
  1278. #ifdef NO_WORRY_ABOUT_MEMORY_PROBLEMS
  1279. return (*malloc_hook)(n);
  1280. #else
  1281. #define EXPLICIT_FREE_AT_END_OF_RUN 1
  1282. char *r = (char *)(*malloc_hook)(n+64);
  1283. int32 *p = (int32 *)quadword_align_up(r);
  1284. if (r == NULL) return NULL;
  1285. n = quadword_align_up(n);
  1286. inject_randomness((int)(intxx)r);
  1287. p[1] = 0;
  1288. ((void **)p)[0] = r; /* base address for free() */
  1289. p[2] = n; /* only permit 32-bit size */
  1290. p[3] = 0x5555aaaa;
  1291. p[4] = 0x12345678; /* Marker words for security */
  1292. p[5] = 0x3456789a;
  1293. p[6] = 0x12345678;
  1294. p[7] = 0x3456789a;
  1295. r = (char *)&p[8];
  1296. car32(r+n) = 0x87654321;
  1297. car32(r+n+4) = 0xcba98765;
  1298. return (void *)r;
  1299. #endif
  1300. }
  1301. #ifndef HOLD_BACK_MEMORY
  1302. static char *big_chunk_start, *big_chunk_end;
  1303. #endif
  1304. #ifdef EXPLICIT_FREE_AT_END_OF_RUN
  1305. static void my_free(void *r)
  1306. {
  1307. #ifdef NO_WORRY_ABOUT_MEMORY_PROBLEMS
  1308. #ifndef HOLD_BACK_MEMORY
  1309. char *rr = (char *)r;
  1310. /*
  1311. * I will not free it if the pointer is strictly inside the single big
  1312. * chunk that I grabbed at the start of the run.
  1313. */
  1314. if (rr > big_chunk_start && rr <= big_chunk_end) return;
  1315. #endif
  1316. int *p, *q, n;
  1317. *(free_hook)(r);
  1318. #else /* NO_WORRY... */
  1319. int32 *p, *q, n;
  1320. #ifndef HOLD_BACK_MEMORY
  1321. char *rr = (char *)r;
  1322. /*
  1323. * I will not free it if the pointer is strictly inside the single big
  1324. * chunk that I grabbed at the start of the run.
  1325. */
  1326. if (rr > big_chunk_start && rr <= big_chunk_end) return;
  1327. #endif
  1328. p = (int32 *)r - 8;
  1329. n = p[2];
  1330. if (p[4] != 0x12345678 ||
  1331. p[5] != 0x3456789a)
  1332. { term_printf("Corruption at start of memory block %p: %.8x %.8x\n",
  1333. r, p[4], p[5]);
  1334. ensure_screen();
  1335. my_exit(0);
  1336. }
  1337. q = (int32 *)((char *)r + n);
  1338. if (q[0] != 0x87654321 ||
  1339. q[1] != 0xcba98765)
  1340. { term_printf("Corruption at end of memory block %p: %.8x %.8x\n",
  1341. r, q[0], q[1]);
  1342. ensure_screen();
  1343. my_exit(0);
  1344. }
  1345. (*free_hook)((void *)((void **)p)[0]);
  1346. #endif
  1347. }
  1348. #endif
  1349. static void *my_malloc_1(size_t n)
  1350. /*
  1351. * This is a pretty silly function - it gobbles up 24Kbytes of
  1352. * stack and then just calls malloc - it stuffs a pointer to the
  1353. * stack-chunk into a static variable so that compilers can not
  1354. * detect (I hope!) that the array remains unused. The purpose of this
  1355. * is to make malloc fail if it is about to encroach on space that
  1356. * should be used for stack. This is relevant on small systems where
  1357. * stack and heap grow towards one another and where one space has been
  1358. * grabbed by malloc it is unavailable for stack (even if it is FREEd).
  1359. * The number 24000 is pretty arbitrary - but if I have 24K bytes of stack
  1360. * I will be able to do at least something.
  1361. * Also this code verifies that the memory addresses returned have the
  1362. * correct most significant bit. I allocate just a bit more memory than
  1363. * is really needed to leave a one-word (or so) guard-band between
  1364. * allocated blocks. This is necessary on some releases of an SGI C
  1365. * compiler (library) where blocks of memory that are word but not
  1366. * doubleword aligned can be returned.
  1367. */
  1368. {
  1369. char gobble_stack[24000];
  1370. char *r;
  1371. intxx pun, pun1;
  1372. global_handle = gobble_stack;
  1373. r = (char *)my_malloc(n+16);
  1374. pun = (intxx)r;
  1375. pun1 = (intxx)(r + n);
  1376. /*
  1377. * I will moan if the block of memory allocated spans zero.
  1378. * Note that if this does happen then something very funny is happening
  1379. * about 0 cast to a pointer (i.e. a NULL pointer) since NULL is supposed
  1380. * not to be valid as an address (?) but appears to be within the address
  1381. * range of the block of store just allocated.
  1382. */
  1383. if ((pun ^ pun1) < 0) fatal_error(err_mem_spans_zero);
  1384. /*
  1385. * Now if I get a block with the "wrong" top bit I will just return NULL
  1386. * to suggest that no more memory was available - CSL can then proceed
  1387. * or fail as it sees fit.
  1388. */
  1389. #ifdef ADDRESS_SIGN_UNKNOWN
  1390. /*
  1391. * For dynamic address sign I should not test the address sign on the
  1392. * first call - instead I just remember what it was. On subsequent calls
  1393. * I will check it.
  1394. */
  1395. if (nilsegment != NULL)
  1396. { if ((pun + address_sign) < 0) return NULL;
  1397. /* fatal_error(err_top_bit); */
  1398. }
  1399. else address_sign = pun & 0x80000000;
  1400. #else
  1401. #ifdef ADDRESSES_HAVE_TOP_BIT_SET
  1402. if (pun > 0) return NULL; /* fatal_error(err_top_bit); */
  1403. #else
  1404. if (pun < 0) return NULL; /* fatal_error(err_top_bit); */
  1405. #endif
  1406. #endif
  1407. return (void *)r;
  1408. }
  1409. static void *my_malloc_2(size_t n)
  1410. /*
  1411. * Rather like my_malloc_1(), but does NOT check the sign bit of the
  1412. * returned pointer. Provided as a place to put hooks to check memory
  1413. * allocation problems.
  1414. */
  1415. {
  1416. char gobble_stack[24000];
  1417. char *r;
  1418. global_handle = gobble_stack;
  1419. r = (char *)my_malloc(n+16);
  1420. return (void *)r;
  1421. }
  1422. static void init_heap_segments(double store_size)
  1423. /*
  1424. * This function just makes nil and the pool of page-frames available
  1425. */
  1426. {
  1427. char *memfile = "memory.use"; /* For memory statistics etc */
  1428. pages = (void **)my_malloc_2(MAX_PAGES*sizeof(void *));
  1429. heap_pages = (void **)my_malloc_2(MAX_PAGES*sizeof(void *));
  1430. vheap_pages = (void **)my_malloc_2(MAX_PAGES*sizeof(void *));
  1431. bps_pages = (void **)my_malloc_2(MAX_BPS_PAGES*sizeof(void *));
  1432. native_pages = (void **)my_malloc_2(MAX_NATIVE_PAGES*sizeof(void *));
  1433. #ifndef NO_COPYING_GC
  1434. new_heap_pages = (void **)my_malloc_2(MAX_PAGES*sizeof(void *));
  1435. new_vheap_pages = (void **)my_malloc_2(MAX_PAGES*sizeof(void *));
  1436. new_bps_pages = (void **)my_malloc_2(MAX_BPS_PAGES*sizeof(void *));
  1437. new_native_pages = (void **)my_malloc_2(MAX_NATIVE_PAGES*sizeof(void *));
  1438. #endif
  1439. pair_c = (unsigned char *)my_malloc_2(CODESIZE);
  1440. /*
  1441. * The next line is utterly unsatisfactory at present
  1442. */
  1443. char_stack = (unsigned char *)my_malloc_2(CSL_PAGE_SIZE+16 /*CODESIZE*/);
  1444. pair_prev = (unsigned short int *)
  1445. my_malloc_2(CODESIZE*sizeof(unsigned short int));
  1446. if (pages == NULL ||
  1447. #ifndef NO_COPYING_GC
  1448. new_heap_pages == NULL ||
  1449. new_vheap_pages == NULL ||
  1450. new_bps_pages == NULL ||
  1451. new_native_pages == NULL ||
  1452. #endif
  1453. heap_pages == NULL ||
  1454. vheap_pages == NULL ||
  1455. bps_pages == NULL ||
  1456. native_pages == NULL ||
  1457. pair_c == NULL ||
  1458. char_stack == NULL ||
  1459. pair_prev == NULL) fatal_error(err_no_store);
  1460. {
  1461. #ifdef COMMON
  1462. int32 free_space = 32000000; /* Try 32 Mbyte as a default heap size */
  1463. #else
  1464. int32 free_space = 32000000; /* Try 32 Mbyte as a default heap size */
  1465. #endif
  1466. int32 request = (int32)store_size;
  1467. if (request != 0) free_space = 1024*request;
  1468. free_space = free_space/(CSL_PAGE_SIZE+4);
  1469. if (free_space > MAX_PAGES) free_space = MAX_PAGES;
  1470. pages_count = heap_pages_count = vheap_pages_count =
  1471. bps_pages_count = native_pages_count = 0;
  1472. native_fringe = 0;
  1473. /*
  1474. * I grab memory using a function called my_malloc_1(), which verifies that
  1475. * all addresses used in the heap have the same top bit. The very first time
  1476. * it is called nilsegment will be NULL - that time it does less checking.
  1477. */
  1478. nilsegment = NULL;
  1479. #ifdef HOLD_BACK_MEMORY
  1480. /*
  1481. * Try to grab a bit extra since I will then hand it back. This version
  1482. * of the code MUST be used on machines where size_t (the argument to
  1483. * malloc) denotes a 16-bit value.
  1484. */
  1485. free_space += HOLD_BACK_MEMORY;
  1486. /*
  1487. * I should wait until later to grab space, I suspect... I.e. not pre-allocate
  1488. * pages for the heap now at the start of the run but wait until the garbage
  1489. * collector tells me that enlarging the CSL heap would be a good idea.
  1490. * What I do at present is to allocate a reasonable amount of memory here,
  1491. * and on small machines I will leave it at that. On large machines
  1492. * I will allocate more space (maybe) during garbage collection. I use
  1493. * the HOLD_BACK_MEMORY and (init_flags & INIT_EXPANDABLE) to control things
  1494. * in a finer way.
  1495. */
  1496. nilsegment = (Lisp_Object *)my_malloc_1(NIL_SEGMENT_SIZE);
  1497. #ifdef COMMON
  1498. /*
  1499. * NB here that NIL is tagged as a CONS not as a symbol. That means that
  1500. * qheader(nil) is BEFORE the place that might normally have been the start
  1501. * of the segment, so I add 8 to preserve alignment but to leave room for
  1502. * the header. I have made NIL_SEGMENT_SIZE large enough by a useful margin
  1503. * (in externs.h) so I should not run off th eend of it.
  1504. */
  1505. C_nil = doubleword_align_up(nilsegment) + TAG_CONS + 8;
  1506. #else
  1507. C_nil = doubleword_align_up(nilsegment) + TAG_SYMBOL;
  1508. #endif
  1509. while (pages_count < free_space)
  1510. {
  1511. /*
  1512. * I get a few bytes more than seems necessary because I will need to
  1513. * align my page frames up to a quadword boundary, and that can
  1514. * potentially waste some bytes. Actually my_malloc_1 has already
  1515. * ensured that it hands back a quadword-aligned value so maybe I do not
  1516. * need to worry here any more. However a waste of 16 bytes per page is not
  1517. * really a big issue so I will leave this.
  1518. */
  1519. void *page = (void *)my_malloc_1((size_t)(CSL_PAGE_SIZE+16));
  1520. if (page == NULL) break;
  1521. pages[pages_count++] = page;
  1522. }
  1523. /*
  1524. * Now release some memory for the operating system to play with. This
  1525. * is a bit crude, in that it can "waste" precious space on small
  1526. * machines, but on at least the Acorn Archimedes (RISCOS) and the
  1527. * Macintosh (system 7) it appears to be VITAL. I think that with memory now
  1528. * getting cheap and hardly any machines (that I want to support) not having
  1529. * virtual memory this may no longer be a big issue.
  1530. */
  1531. { int32 i;
  1532. for (i=0; i<HOLD_BACK_MEMORY; i++)
  1533. if (pages_count != 0) my_free(pages[--pages_count]);
  1534. }
  1535. #else /* HOLD_BACK_MEMORY */
  1536. #ifdef DEBUG
  1537. if (sizeof(size_t) < 4 && PAGE_BITS > 16)
  1538. { fprintf(stderr,
  1539. "This machine needs configuration with HOLD_BACK_MEMORY\n");
  1540. fprintf(stderr,
  1541. "and PAGE_BITS <= 16. Change machine.h and recompile\n");
  1542. my_exit(1);
  1543. }
  1544. #endif
  1545. { size_t n = (size_t)(NIL_SEGMENT_SIZE+free_space*(CSL_PAGE_SIZE+16));
  1546. /*
  1547. * I try to get the whole of the initial hunk of memory that I need in
  1548. * one gulp since that (maybe) gives me the best chance to obtain all
  1549. * the memory in just one half of my address space.
  1550. */
  1551. char *pool = (char *)my_malloc_1(n);
  1552. /*
  1553. * I get 8 bytes more than seems necessary because I will need to
  1554. * align my page frames up to a doubleword boundary, and that can
  1555. * potentially waste 7 bytes.
  1556. */
  1557. if (pool != NULL)
  1558. { big_chunk_start = (char *)pool;
  1559. big_chunk_end = big_chunk_start + (n-1);
  1560. #ifdef __mips__
  1561. /*
  1562. * Some versions of the C compiler on 64-bit SGI machines leave
  1563. * big_chunk_start and _end both zero despite the above. The effect is
  1564. * unimportant until the end of a run of CSL, when the test at the start
  1565. * of my_free misbehaves and a report is generated about memory "corruption".
  1566. * With LUCK the extra reference to the variables via the call to the
  1567. * dummy function will cause the compiler to behave in a more conservative
  1568. * manner and get things correct. The problem has not been seen on
  1569. * 32-bit SGI systems, but the extra dummy function call is not very
  1570. * expensive so can be tolerated in such cases.
  1571. * ACN: August 1996
  1572. */
  1573. dummy_function_call("64-bit SGI machines",
  1574. big_chunk_start, big_chunk_end);
  1575. #endif
  1576. #ifdef MEMORY_TRACE
  1577. #ifndef CHECK_ONLY
  1578. memory_base = (intxx)pool;
  1579. memory_size = n;
  1580. memory_count = 0;
  1581. memory_map = (unsigned char *)(*malloc_hook)(n/32 + 16);
  1582. if (memory_map != 0)
  1583. { memset(memory_map, 0, n/32+8);
  1584. memory_file = fopen(memfile, "wb");
  1585. if (memory_file == NULL)
  1586. { (*free_hook)(memory_map);
  1587. memory_map = 0;
  1588. }
  1589. else
  1590. { n = n/32 + 8;
  1591. putc(0, memory_file);
  1592. putc(0, memory_file);
  1593. putc(0, memory_file); /* 3 bytes to overwrite later on */
  1594. putc(n, memory_file);
  1595. putc(n>>8, memory_file);
  1596. putc(n>>16, memory_file);
  1597. memory_comment(2); /* startup code */
  1598. init_flags &= ~INIT_EXPANDABLE;
  1599. }
  1600. }
  1601. #endif
  1602. #endif
  1603. nilsegment = (Lisp_Object *)pool;
  1604. pool = pool + NIL_SEGMENT_SIZE;
  1605. #ifdef COMMON
  1606. /* NB here that NIL is tagged as a CONS not as a symbol */
  1607. C_nil = doubleword_align_up(nilsegment) + TAG_CONS + 8;
  1608. #else
  1609. C_nil = doubleword_align_up(nilsegment) + TAG_SYMBOL;
  1610. #endif
  1611. /*
  1612. * If at the end of the run I am going to free some space I had better not
  1613. * free these pages. When I free the nilsegment they all get discarded at
  1614. * once.
  1615. */
  1616. while (pages_count < free_space)
  1617. { void *page = (void *)&pool[pages_count*(CSL_PAGE_SIZE+16)];
  1618. pages[pages_count++] = page;
  1619. }
  1620. }
  1621. }
  1622. #endif
  1623. }
  1624. if (nilsegment != NULL && pages_count > 0)
  1625. { if (stack_segsize != 1)
  1626. { stacksegment =
  1627. (Lisp_Object *)my_malloc(stack_segsize*CSL_PAGE_SIZE + 16);
  1628. if (stacksegment == NULL) fatal_error(err_no_store);
  1629. }
  1630. stacksegment = (Lisp_Object *)pages[--pages_count];
  1631. }
  1632. else fatal_error(err_no_store);
  1633. MD5_Update((unsigned char *)memfile, 8);
  1634. /*
  1635. * The stack does not need to be doubleword aligned, but it does need
  1636. * to be word aligned (otherwise certain back-pointers in the garbage
  1637. * collector give trouble), so I fix it up here. Note that stacksegment
  1638. * remains pointing at the original base so that I can free() it later.
  1639. */
  1640. stackbase = (Lisp_Object *)doubleword_align_up((intxx)stacksegment);
  1641. }
  1642. #ifdef EXPLICIT_FREE_AT_END_OF_RUN
  1643. /*
  1644. * In general I will let CSL exit without bothering to free up all the
  1645. * memory that it allocated - that job can be left (to the extent that
  1646. * it is needed at all) to the run-time system. But if for some reason
  1647. * you really mind about such things here is some code to do it for you...
  1648. */
  1649. static void abandon(void *p[], int32 n)
  1650. {
  1651. while (n != 0)
  1652. { void *w = p[--n];
  1653. /*
  1654. * The test here that avoids calling free on a NULL pointer is
  1655. * certainly not needed with an ANSI compliant library - but
  1656. * rumour has it that many Unix libraries are unkind in this
  1657. * respect, and the test is pretty cheap...
  1658. */
  1659. if (w != NULL) my_free(w);
  1660. }
  1661. }
  1662. #endif
  1663. void drop_heap_segments(void)
  1664. {
  1665. #ifdef MEMORY_TRACE
  1666. #ifndef CHECK_ONLY
  1667. identify_page_types();
  1668. #endif
  1669. #endif
  1670. #ifdef EXPLICIT_FREE_AT_END_OF_RUN
  1671. abandon(pages, pages_count);
  1672. abandon(heap_pages, heap_pages_count);
  1673. abandon(vheap_pages, vheap_pages_count);
  1674. abandon(bps_pages, bps_pages_count);
  1675. abandon(native_pages, native_pages_count);
  1676. my_free(stacksegment);
  1677. my_free(nilsegment);
  1678. #endif
  1679. #ifdef MEMORY_TRACE
  1680. #ifndef CHECK_ONLY
  1681. fseek(memory_file, 0L, SEEK_SET);
  1682. putc(memory_records & 0xff, memory_file);
  1683. putc((memory_records>>8) & 0xff, memory_file);
  1684. putc((memory_records>>16) & 0xff, memory_file);
  1685. fclose(memory_file);
  1686. memory_file = NULL;
  1687. memory_map = NULL;
  1688. #endif
  1689. #endif
  1690. }
  1691. static char *find_checksum(char *name, int32 len, const setup_type *p)
  1692. {
  1693. char *n;
  1694. while (p->name != NULL) p++;
  1695. n = (char *)p->one;
  1696. if (strlen(n) == (size_t)len && memcmp(name, n, len) == 0)
  1697. return (char *)p->two;
  1698. else return NULL;
  1699. }
  1700. static Lisp_Object MS_CDECL Lcheck_c_code(Lisp_Object nil, int nargs, ...)
  1701. {
  1702. Lisp_Object name, lc1, lc2, lc3;
  1703. int32 c1=-1, c2=-1, c3=-1;
  1704. long int x1=-2, x2=-2, x3=-2;
  1705. int32 len;
  1706. va_list a;
  1707. char *p;
  1708. char *sname;
  1709. argcheck(nargs, 4, "check-c-code");
  1710. va_start(a, nargs);
  1711. name = va_arg(a, Lisp_Object);
  1712. lc1 = va_arg(a, Lisp_Object);
  1713. lc2 = va_arg(a, Lisp_Object);
  1714. lc3 = va_arg(a, Lisp_Object);
  1715. va_end(a);
  1716. if (!is_vector(name) ||
  1717. type_of_header(vechdr(name)) != TYPE_STRING ||
  1718. !is_fixnum(lc1) ||
  1719. !is_fixnum(lc2) ||
  1720. !is_fixnum(lc3)) return aerror1("check-c-code", name);
  1721. c1 = int_of_fixnum(lc1);
  1722. c2 = int_of_fixnum(lc2);
  1723. c3 = int_of_fixnum(lc3);
  1724. sname = &celt(name, 0);
  1725. len = length_of_header(vechdr(name)) - CELL;
  1726. /*
  1727. * trace_printf("+++ Checking %.*s %d %d %d\n",
  1728. * (int)len, sname, c1, c2, c3);
  1729. */
  1730. p = find_checksum(sname, len, u01_setup);
  1731. if (p == NULL) p = find_checksum(sname, len, u02_setup);
  1732. if (p == NULL) p = find_checksum(sname, len, u03_setup);
  1733. if (p == NULL) p = find_checksum(sname, len, u04_setup);
  1734. if (p == NULL) p = find_checksum(sname, len, u05_setup);
  1735. if (p == NULL) p = find_checksum(sname, len, u06_setup);
  1736. if (p == NULL) p = find_checksum(sname, len, u07_setup);
  1737. if (p == NULL) p = find_checksum(sname, len, u08_setup);
  1738. if (p == NULL) p = find_checksum(sname, len, u09_setup);
  1739. if (p == NULL) p = find_checksum(sname, len, u10_setup);
  1740. if (p == NULL) p = find_checksum(sname, len, u11_setup);
  1741. if (p == NULL) p = find_checksum(sname, len, u12_setup);
  1742. if (p == NULL) return aerror1("check-c-code", name);
  1743. if (sscanf(p, "%ld %ld %ld", &x1, &x2, &x3) != 3)
  1744. return aerror("check-c-code");
  1745. if (c1 == x1 && c2 == x2 && c3 == x3) return onevalue(nil);
  1746. err_printf("\n+++++ C code and environment files not compatible\n");
  1747. err_printf("please check, re-compile and try again\n");
  1748. return aerror("check-c-code");
  1749. }
  1750. static setup_type const restart_setup[] =
  1751. /*
  1752. * things that are in modules that do not define enough Lisp entrypoints
  1753. * to be worth giving separate entry-tables.
  1754. */
  1755. {
  1756. {"check-c-code", wrong_no_na, wrong_no_nb, Lcheck_c_code},
  1757. {"define-in-module", Ldefine_in_module, too_many_1, wrong_no_1},
  1758. {"modulep", Lmodule_exists, too_many_1, wrong_no_1},
  1759. {"start-module", Lstart_module, too_many_1, wrong_no_1},
  1760. {"write-module", Lwrite_module, too_many_1, wrong_no_1},
  1761. {"copy-module", Lcopy_module, too_many_1, wrong_no_1},
  1762. {"delete-module", Ldelete_module, too_many_1, wrong_no_1},
  1763. {"load-module", Lload_module, too_many_1, wrong_no_1},
  1764. {"list-modules", wrong_no_na, wrong_no_nb, Llist_modules},
  1765. {"writable-libraryp", Lwritable_libraryp, too_many_1, wrong_no_1},
  1766. {"library-members", Llibrary_members, too_many_1, Llibrary_members0},
  1767. {"startup-banner", Lbanner, too_many_1, wrong_no_1},
  1768. #ifdef HELP_SYSTEM
  1769. {"write-help-module", too_few_2, Lwrite_help_module, wrong_no_2},
  1770. {"help", Lhelp, Lhelp_2, Lhelp_n},
  1771. {"?", Lhelp, too_many_1, wrong_no_1},
  1772. #endif
  1773. {"set-help-file", too_few_2, Lset_help_file, wrong_no_2},
  1774. {"mapstore", Lmapstore, too_many_1, Lmapstore0},
  1775. {"verbos", Lverbos, too_many_1, wrong_no_1},
  1776. #ifdef COMMON
  1777. {"errorset", Lerrorset1, Lerrorset2, Lerrorsetn},
  1778. {"gc", Lgc, too_many_1, Lgc0},
  1779. #else
  1780. {"errorset", Lerrorset1, Lerrorset2, Lerrorsetn},
  1781. {"reclaim", Lgc, too_many_1, Lgc0},
  1782. #endif
  1783. {NULL, 0, 0, 0}
  1784. };
  1785. static void create_symbols(setup_type const s[], CSLbool restartp)
  1786. {
  1787. int i;
  1788. for (i=0; s[i].name != NULL; i++)
  1789. make_symbol(s[i].name, restartp, s[i].one, s[i].two, s[i].n);
  1790. }
  1791. static int32 defined_symbols;
  1792. static void count_symbols(setup_type const s[])
  1793. {
  1794. int i;
  1795. for (i=0; s[i].name != NULL; i++) defined_symbols++;
  1796. }
  1797. static void set_up_variables(CSLbool restartp);
  1798. static void warm_setup(void)
  1799. {
  1800. /*
  1801. * Here I need to read in the bulk of the checkpoint file.
  1802. */
  1803. Lisp_Object nil = C_nil;
  1804. int32 i;
  1805. Cfread((char *)&heap_pages_count, sizeof(heap_pages_count));
  1806. Cfread((char *)&vheap_pages_count, sizeof(vheap_pages_count));
  1807. Cfread((char *)&bps_pages_count, sizeof(bps_pages_count));
  1808. heap_pages_count = flip_bytes(heap_pages_count);
  1809. vheap_pages_count = flip_bytes(vheap_pages_count);
  1810. bps_pages_count = flip_bytes(bps_pages_count);
  1811. /*
  1812. * Here I want to arrange to have at least one free page after re-loading
  1813. * an image. If malloc can give me enough I grab it here. Note that I do
  1814. * not yet know how many pages will be needed for hard code, which is a
  1815. * bit of a nuisance!
  1816. */
  1817. i = heap_pages_count+vheap_pages_count+
  1818. bps_pages_count+1 - pages_count;
  1819. #ifdef MEMORY_TRACE
  1820. if (i > 0) fatal_error(err_no_store);
  1821. #else
  1822. while (i-- > 0)
  1823. { void *page = my_malloc_1((size_t)(CSL_PAGE_SIZE + 16));
  1824. if (page == NULL) fatal_error(err_no_store);
  1825. else pages[pages_count++] = page;
  1826. }
  1827. #endif
  1828. { char dummy[16];
  1829. Cfread(dummy, 8);
  1830. }
  1831. #ifdef MEMORY_TRACE
  1832. #ifndef CHECK_ONLY
  1833. memory_comment(6); /* vector heap */
  1834. #endif
  1835. #endif
  1836. for (i=0; i<vheap_pages_count; i++)
  1837. { intxx p;
  1838. vheap_pages[i] = allocate_page();
  1839. p = doubleword_align_up((intxx)vheap_pages[i]);
  1840. Cfread((char *)p, CSL_PAGE_SIZE);
  1841. }
  1842. { char dummy[16];
  1843. Cfread(dummy, 8);
  1844. }
  1845. #ifdef MEMORY_TRACE
  1846. #ifndef CHECK_ONLY
  1847. memory_comment(5); /* cons heap */
  1848. #endif
  1849. #endif
  1850. for (i=0; i<heap_pages_count; i++)
  1851. { intxx p;
  1852. heap_pages[i] = allocate_page();
  1853. p = quadword_align_up((intxx)heap_pages[i]);
  1854. Cfread((char *)p, CSL_PAGE_SIZE);
  1855. }
  1856. { char dummy[16];
  1857. Cfread(dummy, 8);
  1858. }
  1859. #ifdef MEMORY_TRACE
  1860. #ifndef CHECK_ONLY
  1861. memory_comment(14); /* BPS heap */
  1862. #endif
  1863. #endif
  1864. for (i=0; i<bps_pages_count; i++)
  1865. { intxx p;
  1866. bps_pages[i] = allocate_page();
  1867. p = doubleword_align_up((intxx)bps_pages[i]);
  1868. Cfread((char *)p, CSL_PAGE_SIZE);
  1869. }
  1870. { char endmsg[32];
  1871. Cfread(endmsg, 24); /* the termination record */
  1872. /*
  1873. * Although I check here I will not make the system crash if I see an
  1874. * error - at least until I have tested things and found this test
  1875. * properly reliable.
  1876. */
  1877. #ifdef COMMON
  1878. if (strncmp(endmsg, "\n\nEnd of CCL dump file\n\n", 24) != 0)
  1879. #else
  1880. if (strncmp(endmsg, "\n\nEnd of CSL dump file\n\n", 24) != 0)
  1881. #endif
  1882. { term_printf("\n+++ Bad end record |%s|\n", endmsg);
  1883. }
  1884. }
  1885. /*
  1886. * There is a delicacy here - Cfread uses Iread to read chunks of
  1887. * data from the real input file, but it never goes beyond the recorded
  1888. * end of file mark. This buffering ensures that at this stage any
  1889. * pending part-word of data will have been read - this because the
  1890. * read buffer used is a multiple of 4 bytes long. This point matters
  1891. * with regard to checksum validation on these files.
  1892. */
  1893. crypt_active = -1; /* Have read all of the initial image file */
  1894. IcloseInput(YES);
  1895. #ifdef MEMORY_TRACE
  1896. #ifndef CHECK_ONLY
  1897. memory_comment(9); /* adjusting */
  1898. #endif
  1899. #endif
  1900. inject_randomness((int)clock());
  1901. adjust_all();
  1902. #ifdef MEMORY_TRACE
  1903. #ifndef CHECK_ONLY
  1904. memory_comment(12); /* remainder of setup */
  1905. #endif
  1906. #endif
  1907. eq_hash_tables = eq_hash_table_list;
  1908. equal_hash_tables = equal_hash_table_list;
  1909. eq_hash_table_list = equal_hash_table_list = nil;
  1910. { Lisp_Object qq;
  1911. for (qq = eq_hash_tables; qq!=nil; qq=qcdr(qq))
  1912. rehash_this_table(qcar(qq));
  1913. for (qq = equal_hash_tables; qq!=nil; qq=qcdr(qq))
  1914. rehash_this_table(qcar(qq));
  1915. }
  1916. gensym_ser = flip_bytes(gensym_ser);
  1917. print_precision = flip_bytes(print_precision);
  1918. miscflags = flip_bytes(miscflags);
  1919. current_modulus = flip_bytes(current_modulus);
  1920. fastget_size = flip_bytes(fastget_size);
  1921. package_bits = flip_bytes(package_bits);
  1922. set_up_functions(1);
  1923. set_up_variables(1);
  1924. /*
  1925. * Now I have closed the main heap image, but if there is any hard machine
  1926. * code available for this architecture I should load it. When I do this
  1927. * the main heap has been loaded and relocated and all the entrypoints
  1928. * in it that relate to kernel code have been inserted.
  1929. */
  1930. if (native_code_tag != 0) /* Not worth trying if none available */
  1931. { if (!IopenRoot(NULL, -native_code_tag))
  1932. { int32 nn = Igetc() & 0xff;
  1933. nn = nn + ((Igetc() & 0xff) << 8);
  1934. native_pages_count = nn;
  1935. for (i=0; i<native_pages_count; i++)
  1936. { intxx p;
  1937. /*
  1938. * Because I did not know earlier how many pages would be needed here I
  1939. * may not have overall enough. So I expand my heap (if possible)
  1940. * when things start to look tight here.
  1941. */
  1942. if (pages_count <= 1)
  1943. { void *page = my_malloc_1((size_t)(CSL_PAGE_SIZE + 16));
  1944. if (page == NULL) fatal_error(err_no_store);
  1945. else pages[pages_count++] = page;
  1946. }
  1947. native_pages[i] = allocate_page();
  1948. p = (intxx)native_pages[i];
  1949. p = doubleword_align_up(p);
  1950. fread_count = 0;
  1951. Cfread((char *)p, CSL_PAGE_SIZE);
  1952. native_fringe = car32(p);
  1953. relocate_native_code((unsigned char *)p, native_fringe);
  1954. }
  1955. IcloseInput(YES);
  1956. }
  1957. }
  1958. /*
  1959. * Finally with a warm start I must instate the definitions of all functions
  1960. * that may have been compiled into hard code on this platform. Functions that
  1961. * may be hard-coded on SOME platform may also be in a mess and will have
  1962. * a byte-coded definition put back in place at this point. Observe that this
  1963. * happens AFTER the system has otherwise been loaded and relocated.
  1964. */
  1965. { Lisp_Object f_list = native_code, byte_code_def;
  1966. do_not_kill_native_code = 1;
  1967. while (f_list != nil)
  1968. { Lisp_Object w, fn, defs;
  1969. int32 nargs;
  1970. int instated_something = 0;
  1971. byte_code_def = nil;
  1972. w = qcar(f_list);
  1973. f_list = qcdr(f_list);
  1974. fn = qcar(w); w = qcdr(w);
  1975. nargs = int_of_fixnum(qcar(w));
  1976. defs = qcdr(w);
  1977. while (defs != nil)
  1978. { int32 n, tag, type, off;
  1979. intxx page;
  1980. void *e;
  1981. w = qcar(defs);
  1982. defs = qcdr(defs);
  1983. n = int_of_fixnum(qcar(w));
  1984. w = qcdr(w);
  1985. tag = (n >> 20) & 0xff;
  1986. type = (n >> 18) & 0x3;
  1987. page = n & 0x3ffff;
  1988. if (tag == 0)
  1989. { byte_code_def = qcdr(w);
  1990. continue;
  1991. }
  1992. if (tag != native_code_tag) continue; /* Not for me today */
  1993. instated_something = 1;
  1994. off = int_of_fixnum(qcar(w));
  1995. w = qcdr(w);
  1996. /*
  1997. * Now fn should be a symbol, the function to be defined. w is the thing to go
  1998. * into its environment cell. page and off define a location in the hard
  1999. * code space and type tells me which of the 3 function cells to put that in.
  2000. *
  2001. * I will not (yet) mess around with the removal of C definition
  2002. * flags and all the other delicacies. Note that this means attempts to
  2003. * redefine built-in functions with user-provided native code varients
  2004. * may cause all sorts of muddle! Please do not try it, but when you
  2005. * do (!) tell me and I will attempt to work out what ought to happen.
  2006. * Maybe it will all be OK provided that a consistent byte-code definition
  2007. * is in place before any native code gets generated.
  2008. */
  2009. page = (intxx)native_pages[page];
  2010. page = doubleword_align_up(page);
  2011. e = (void *)((char *)page + off);
  2012. switch (type)
  2013. {
  2014. /*
  2015. * Warning - I just support nargs being a simple integer here, with no
  2016. * fancy encoding for variable numbers of args or &rest args etc. I think
  2017. * that for native code all such cases need to be dealt with via non-zero
  2018. * type code so that the 3 individual function cells get filled in one
  2019. * by 1.
  2020. */
  2021. case 0: switch (nargs)
  2022. {
  2023. case 0: set_fns(fn, wrong_no_0a, wrong_no_0b, (n_args *)e);
  2024. break;
  2025. case 1: set_fns(fn, (one_args *)e, too_many_1, wrong_no_1);
  2026. break;
  2027. case 2: set_fns(fn, too_few_2, (two_args *)e, wrong_no_2);
  2028. break;
  2029. case 3: set_fns(fn, wrong_no_3a, wrong_no_3b, (n_args *)e);
  2030. break;
  2031. default:set_fns(fn, wrong_no_na, wrong_no_nb, (n_args *)e);
  2032. break;
  2033. }
  2034. break;
  2035. /*
  2036. * A non-zero type field allows me to fill in just one of the function cells.
  2037. * Note that I ought to arrange to get ALL of them filled in somehow, either
  2038. * by using type=0 or by using all three of type = 1,2,3.
  2039. */
  2040. case 1: ifn1(fn) = (intxx)e;
  2041. break;
  2042. case 2: ifn2(fn) = (intxx)e;
  2043. break;
  2044. case 3: ifnn(fn) = (intxx)e;
  2045. break;
  2046. }
  2047. qenv(fn) = w;
  2048. }
  2049. if (!instated_something && byte_code_def != nil)
  2050. { w = cons(fixnum_of_int(nargs), byte_code_def);
  2051. /*
  2052. * You can look at this bit of code and moan, saying "What happens if
  2053. * the call to CONS causes a garbage collection?". Well I have this policy
  2054. * that garbage collection attempts during startup should be thought of
  2055. * as fatal, and that the user should give enough memory to make it possible
  2056. * to get at least started. I hope that I do not generate much litter here
  2057. * and in other places within the startup code. Not thinking about GC
  2058. * safety leaves the code neater and easier to work with.
  2059. */
  2060. Lsymbol_set_definition(nil, fn, w);
  2061. }
  2062. }
  2063. do_not_kill_native_code = 0;
  2064. }
  2065. inject_randomness((int)clock());
  2066. }
  2067. static void cold_setup(void)
  2068. {
  2069. Lisp_Object nil = C_nil;
  2070. void *p;
  2071. p = vheap_pages[vheap_pages_count++] = allocate_page();
  2072. vfringe = (Lisp_Object)(8 + (char *)doubleword_align_up((intxx)p));
  2073. vheaplimit = (Lisp_Object)((char *)vfringe + (CSL_PAGE_SIZE - 16));
  2074. p = heap_pages[heap_pages_count++] = allocate_page();
  2075. heaplimit = quadword_align_up((intxx)p);
  2076. fringe = (Lisp_Object)((char *)heaplimit + CSL_PAGE_SIZE);
  2077. heaplimit = (Lisp_Object)((char *)heaplimit + SPARE);
  2078. codelimit = codefringe = 0; /* no BPS to start with */
  2079. miscflags = 3;
  2080. qplist(nil) = nil;
  2081. qfastgets(nil) = nil;
  2082. qenv(nil) = nil; /* points to self in undefined case */
  2083. ifn1(nil) = (intxx)undefined1;
  2084. ifn2(nil) = (intxx)undefined2;
  2085. ifnn(nil) = (intxx)undefinedn;
  2086. qheader(nil) = TAG_ODDS+TYPE_SYMBOL+SYM_SPECIAL_VAR;
  2087. qvalue(nil) = nil;
  2088. #ifdef COMMON
  2089. qpname(nil) = make_string("NIL");
  2090. #else
  2091. qpname(nil) = make_string("nil");
  2092. #endif
  2093. qcount(nil) = 0;
  2094. exit_tag = exit_value = nil;
  2095. exit_reason = UNWIND_NULL;
  2096. eq_hash_tables = equal_hash_tables = nil;
  2097. current_package = nil;
  2098. qvalue(nil) = getvector_init(sizeof(Package), nil);
  2099. #ifdef COMMON
  2100. qpackage(nil) = qvalue(nil); /* For sake of restart code */
  2101. all_packages = ncons(qvalue(nil));
  2102. #endif
  2103. packhdr_(CP) = TYPE_STRUCTURE + (packhdr_(CP) & ~header_mask);
  2104. #ifdef COMMON
  2105. packname_(CP) = make_string("LISP");
  2106. #endif
  2107. /*
  2108. * The size chosen here is only an initial size - the hash table in a package
  2109. * can grow later on if needbe - but I ought to ensure that the initial
  2110. * size is big enough for the built-in symbols that Lisp creates in
  2111. * this restart code. The size must be a power of 2.
  2112. */
  2113. packint_(CP) = getvector_init(CELL+INIT_OBVECI_SIZE, fixnum_of_int(0));
  2114. packvint_(CP) = fixnum_of_int(1);
  2115. packflags_(CP) = fixnum_of_int(++package_bits);
  2116. #ifdef COMMON
  2117. /*
  2118. * Common Lisp also has "external" symbols to allow for...
  2119. */
  2120. packnint_(CP) = fixnum_of_int(0);
  2121. packext_(CP) = getvector_init(CELL+INIT_OBVECX_SIZE, fixnum_of_int(0));
  2122. packvext_(CP) = fixnum_of_int(1);
  2123. packnext_(CP) = fixnum_of_int(1); /* Allow for nil */
  2124. { int i = (int)(hash_lisp_string(qpname(nil)) &
  2125. (INIT_OBVECX_SIZE/CELL - 1));
  2126. elt(packext_(CP), i) = nil;
  2127. }
  2128. #else
  2129. packnint_(CP) = fixnum_of_int(1); /* Allow for nil */
  2130. { int i = (int)(hash_lisp_string(qpname(nil)) &
  2131. (INIT_OBVECI_SIZE/CELL - 1));
  2132. elt(packint_(CP), i) = nil;
  2133. }
  2134. #endif
  2135. gensym_ser = 0;
  2136. print_precision = 15;
  2137. current_modulus = 1;
  2138. fastget_size = 32;
  2139. package_bits = 0;
  2140. unset_var = nil;
  2141. /*
  2142. * there had better not be a need for garbage collection here...
  2143. * ... or elsewhere in setup, since the world is not yet put together.
  2144. * Ditto interrupts.
  2145. */
  2146. #define boffo_size 256
  2147. boffo = getvector(TAG_VECTOR, TYPE_STRING, CELL+boffo_size);
  2148. memset((void *)((char *)boffo + (CELL - TAG_VECTOR)), '@', boffo_size);
  2149. #ifndef COMMON
  2150. if (current_package == nil)
  2151. { current_package = make_undefined_symbol("*package*");
  2152. qheader(current_package) |= SYM_SPECIAL_VAR;
  2153. lisp_package = qvalue(current_package) = qvalue(nil);
  2154. qvalue(nil) = nil;
  2155. }
  2156. #else
  2157. /*
  2158. * The next line has hidden depths. When it is obeyed during cold start
  2159. * the C variable current_package has the value nil, hence make_symbol
  2160. * looks in the value cell of nil to find the package to intern wrt. Once
  2161. * this has been done I can put nil back how it ought to have been!
  2162. */
  2163. current_package = make_undefined_symbol("*package*");
  2164. qheader(current_package)|= SYM_SPECIAL_VAR;
  2165. lisp_package = qvalue(current_package) = qpackage(nil);
  2166. qvalue(nil) = nil; /* Whew! */
  2167. #endif
  2168. B_reg = nil; /* safe for GC */
  2169. unset_var = make_undefined_symbol("~indefinite-value~");
  2170. qheader(unset_var) |= SYM_SPECIAL_VAR;
  2171. qvalue(unset_var) = unset_var;
  2172. Lunintern(nil, unset_var);
  2173. /*
  2174. * Now in some minor sense the world is in a self-consistent state
  2175. */
  2176. lisp_true = make_undefined_symbol("t");
  2177. qheader(lisp_true) |= SYM_SPECIAL_VAR;
  2178. qvalue(lisp_true) = lisp_true;
  2179. savedef = make_undefined_symbol("*savedef");
  2180. comma_symbol = make_undefined_symbol("~comma");
  2181. comma_at_symbol = make_undefined_symbol("~comma-at");
  2182. lambda = make_undefined_symbol("lambda");
  2183. funarg = make_undefined_symbol("funarg");
  2184. cfunarg = make_undefined_symbol("cfunarg");
  2185. opt_key = make_undefined_symbol("&optional");
  2186. rest_key = make_undefined_symbol("&rest");
  2187. #ifdef COMMON
  2188. key_key = make_undefined_symbol("&key");
  2189. allow_other_keys = make_undefined_symbol("&allow-other-keys");
  2190. aux_key = make_undefined_symbol("&aux");
  2191. #endif
  2192. work_symbol = make_undefined_symbol("~magic-internal-symbol~");
  2193. Lunintern(nil, work_symbol);
  2194. #ifndef COMMON
  2195. packid_(CP) = make_undefined_symbol("package");
  2196. #else
  2197. package_symbol = make_undefined_symbol("package");
  2198. packid_(CP) = package_symbol;
  2199. #endif
  2200. macroexpand_hook = make_undefined_symbol("*macroexpand-hook*");
  2201. qheader(macroexpand_hook) |= SYM_SPECIAL_VAR;
  2202. evalhook = make_undefined_symbol("*evalhook*");
  2203. qheader(evalhook) |= SYM_SPECIAL_VAR;
  2204. qvalue(evalhook) = nil;
  2205. applyhook = make_undefined_symbol("*applyhook*");
  2206. qheader(applyhook) |= SYM_SPECIAL_VAR;
  2207. qvalue(applyhook) = nil;
  2208. #ifdef COMMON
  2209. keyword_package = make_undefined_symbol("*keyword-package*");
  2210. qheader(keyword_package) |= SYM_SPECIAL_VAR;
  2211. qvalue(keyword_package) = make_package(make_string("KEYWORD"));
  2212. err_table = make_undefined_symbol("*ERROR-MESSAGE*");
  2213. #else
  2214. err_table = make_undefined_symbol("*error-messages*");
  2215. #endif
  2216. qheader(err_table) |= SYM_SPECIAL_VAR;
  2217. qvalue(err_table) = nil;
  2218. #ifdef COMMON
  2219. #define make_keyword(name) \
  2220. Lintern_2(nil, make_string(name), qvalue(keyword_package))
  2221. internal_symbol = make_keyword("INTERNAL");
  2222. external_symbol = make_keyword("EXTERNAL");
  2223. inherited_symbol = make_keyword("INHERITED");
  2224. allow_key_key = make_keyword("ALLOW-OTHER-KEYS");
  2225. #else
  2226. #define make_keyword(name) make_undefined_symbol(name)
  2227. #endif
  2228. gensym_base = make_string("G");
  2229. #ifdef COMMON
  2230. special_symbol = make_undefined_symbol("special");
  2231. expand_def_symbol = make_undefined_symbol("expand-definer");
  2232. format_symbol = make_undefined_symbol("format");
  2233. string_char_sym = make_undefined_symbol("string-char");
  2234. cl_symbols = make_undefined_symbol("*cl-symbols*");
  2235. /*
  2236. * cl_symbols has to be at least a vector or else I can not
  2237. * read in the Lisp file that sets its proper value...
  2238. */
  2239. qvalue(cl_symbols) = getvector_init(8*CELL, nil);
  2240. features_symbol = make_undefined_symbol("*features*");
  2241. qheader(cl_symbols) |= SYM_SPECIAL_VAR;
  2242. qheader(features_symbol) |= SYM_SPECIAL_VAR;
  2243. { Lisp_Object w;
  2244. #define make_constant(name, value) \
  2245. w = make_undefined_symbol(name); \
  2246. qheader(w) |= SYM_SPECIAL_VAR; \
  2247. qvalue(w) = value;
  2248. make_constant("most-positive-fixnum", fixnum_of_int(0x07ffffff));
  2249. make_constant("most-negative-fixnum", fixnum_of_int(0xf8000000));
  2250. /* #undef TYPE_LONG_FLOAT */
  2251. /* #define TYPE_LONG_FLOAT TYPE_DOUBLE_FLOAT */
  2252. make_constant("pi",
  2253. make_boxfloat(3.141592653589793238, TYPE_LONG_FLOAT));
  2254. }
  2255. #endif
  2256. append_symbol = make_undefined_symbol("append");
  2257. raise_symbol = make_undefined_symbol("*raise");
  2258. lower_symbol = make_undefined_symbol("*lower");
  2259. echo_symbol = make_undefined_symbol("*echo");
  2260. /*
  2261. * I think that having a built-in symbol called *hankaku even if Kanji support
  2262. * is not otherwise present is not too severe a problem, and making the
  2263. * symbol present always will help keep image files re-usable from one
  2264. * version of CSL to another.
  2265. */
  2266. hankaku_symbol = make_undefined_symbol("*hankaku");
  2267. comp_symbol = make_undefined_symbol("*comp");
  2268. compiler_symbol = make_undefined_symbol("compile");
  2269. native_symbol = make_undefined_symbol("native-compile");
  2270. traceprint_symbol = make_undefined_symbol("trace-print");
  2271. loadsource_symbol = make_symbol("load-source", 0, Lload_source, too_many_1, wrong_no_1);
  2272. prinl_symbol = make_symbol("prinl", 0, Lprin, too_many_1, wrong_no_1);
  2273. emsg_star = make_undefined_symbol("emsg*");
  2274. redef_msg = make_undefined_symbol("*redefmsg");
  2275. expr_symbol = make_undefined_symbol("expr");
  2276. fexpr_symbol = make_undefined_symbol("fexpr");
  2277. macro_symbol = make_undefined_symbol("macro");
  2278. break_function = make_undefined_symbol("*break-loop*");
  2279. qheader(raise_symbol) |= SYM_SPECIAL_VAR;
  2280. qheader(lower_symbol) |= SYM_SPECIAL_VAR;
  2281. qheader(echo_symbol) |= SYM_SPECIAL_VAR;
  2282. qheader(hankaku_symbol) |= SYM_SPECIAL_VAR;
  2283. qheader(comp_symbol) |= SYM_SPECIAL_VAR;
  2284. qheader(emsg_star) |= SYM_SPECIAL_VAR;
  2285. qheader(redef_msg) |= SYM_SPECIAL_VAR;
  2286. qheader(break_function) |= SYM_SPECIAL_VAR;
  2287. qvalue(break_function) = nil;
  2288. qheader(loadsource_symbol) |= SYM_SPECIAL_VAR;
  2289. qvalue(loadsource_symbol) = nil;
  2290. { Lisp_Object common = make_undefined_symbol("common-lisp-mode");
  2291. qheader(common) |= SYM_SPECIAL_VAR;
  2292. #ifdef COMMON
  2293. qvalue(common) = lisp_true;
  2294. qvalue(raise_symbol) = lisp_true;
  2295. qvalue(lower_symbol) = nil;
  2296. #else
  2297. qvalue(common) = nil;
  2298. qvalue(raise_symbol) = nil;
  2299. qvalue(lower_symbol) = lisp_true;
  2300. #endif
  2301. }
  2302. qvalue(echo_symbol) = nil;
  2303. qvalue(hankaku_symbol) = nil;
  2304. qvalue(comp_symbol) = nil;
  2305. qvalue(emsg_star) = nil;
  2306. qvalue(redef_msg) = lisp_true;
  2307. sys_hash_table = Lmkhash(nil, 3, fixnum_of_int(5), fixnum_of_int(2), nil);
  2308. get_counts = Lmkhash(nil, 3, fixnum_of_int(5), fixnum_of_int(0), nil);
  2309. /*
  2310. * I make the vector that can hold the names used for "fast" get tags big
  2311. * enough for the largest possible number.
  2312. */
  2313. fastget_names = getvector_init((MAX_FASTGET_SIZE+2)*CELL, SPID_NOPROP);
  2314. /*
  2315. * The next bit is a horrid fudge, used in read.c (function orderp) to
  2316. * support REDUCE. It ensures that the flag 'noncom is subject to an
  2317. * optimisation for flag/flagp that allows it to be tested for using a
  2318. * simple bit-test. This MUST use entry zero (coded as 1 here!).
  2319. * Also I insist that 'lose be the second fastget thing!
  2320. */
  2321. { Lisp_Object nc = make_undefined_symbol("noncom");
  2322. qheader(nc) |= (1L << SYM_FASTGET_SHIFT);
  2323. elt(fastget_names, 0) = nc;
  2324. nc = make_undefined_symbol("lose");
  2325. qheader(nc) |= (2L << SYM_FASTGET_SHIFT);
  2326. elt(fastget_names, 1) = nc;
  2327. }
  2328. /*
  2329. * I create the stream objects just once at cold-start time, but every time I
  2330. * restart I will fill in their components in the standard way again.
  2331. */
  2332. lisp_work_stream = make_stream_handle();
  2333. lisp_terminal_io = make_stream_handle();
  2334. lisp_standard_output = make_stream_handle();
  2335. lisp_standard_input = make_stream_handle();
  2336. lisp_error_output = make_stream_handle();
  2337. lisp_trace_output = make_stream_handle();
  2338. lisp_debug_io = make_stream_handle();
  2339. lisp_query_io = make_stream_handle();
  2340. inject_randomness((int)clock());
  2341. set_up_functions(0);
  2342. set_up_variables(0);
  2343. }
  2344. void set_up_functions(CSLbool restartp)
  2345. {
  2346. /*
  2347. * All symbols that have a pointer to C code in their function cell must
  2348. * be set up whether we are in a warm OR a cold start state, because the
  2349. * actual addresses associated with C entrypoints will vary from version
  2350. * to version of the binary of the system.
  2351. */
  2352. int i;
  2353. nil_as_base
  2354. #ifdef COMMON
  2355. /*
  2356. * In Common Lisp mode it could be that the user had something other than the
  2357. * LISP package active when the image was saved. But I want all the symbols
  2358. * that I create or restore here to be in the LISP (or sometimes keyword)
  2359. * package. So I temporarily reset the package here...
  2360. */
  2361. Lisp_Object saved_package = CP;
  2362. CP = find_package("LISP", 4);
  2363. #endif
  2364. function_symbol = make_symbol("function", restartp, function_fn, bad_special2, bad_specialn);
  2365. qheader(function_symbol)|= SYM_SPECIAL_FORM;
  2366. quote_symbol = make_symbol("quote", restartp, quote_fn, bad_special2, bad_specialn);
  2367. qheader(quote_symbol) |= SYM_SPECIAL_FORM;
  2368. progn_symbol = make_symbol("progn", restartp, progn_fn, bad_special2, bad_specialn);
  2369. qheader(progn_symbol) |= SYM_SPECIAL_FORM;
  2370. #ifdef COMMON
  2371. declare_symbol = make_symbol("declare", restartp, declare_fn, bad_special2, bad_specialn);
  2372. qheader(declare_symbol) |= SYM_SPECIAL_FORM;
  2373. #endif
  2374. cons_symbol = make_symbol("cons", restartp, too_few_2, Lcons, wrong_no_2);
  2375. eval_symbol = make_symbol("eval", restartp, Leval, too_many_1, wrong_no_1);
  2376. loadsource_symbol = make_symbol("load-source", restartp, Lload_source, too_many_1, wrong_no_1);
  2377. /*
  2378. * The main bunch of symbols can be handed using a table that
  2379. * gives names and values.
  2380. */
  2381. for (i=0; eval2_setup[i].name != NULL; i++)
  2382. qheader(make_symbol(eval2_setup[i].name,
  2383. restartp,
  2384. eval2_setup[i].one,
  2385. eval2_setup[i].two,
  2386. eval2_setup[i].n)) |= SYM_SPECIAL_FORM;
  2387. for (i=0; eval3_setup[i].name != NULL; i++)
  2388. qheader(make_symbol(eval3_setup[i].name,
  2389. restartp,
  2390. eval3_setup[i].one,
  2391. eval3_setup[i].two,
  2392. eval3_setup[i].n)) |= SYM_SPECIAL_FORM;
  2393. create_symbols(arith06_setup, restartp);
  2394. create_symbols(arith08_setup, restartp);
  2395. create_symbols(arith10_setup, restartp);
  2396. create_symbols(arith12_setup, restartp);
  2397. create_symbols(char_setup, restartp);
  2398. create_symbols(eval1_setup, restartp);
  2399. create_symbols(funcs1_setup, restartp);
  2400. create_symbols(funcs2_setup, restartp);
  2401. create_symbols(funcs3_setup, restartp);
  2402. create_symbols(print_setup, restartp);
  2403. create_symbols(read_setup, restartp);
  2404. create_symbols(restart_setup, restartp);
  2405. create_symbols(mpi_setup, restartp);
  2406. /*
  2407. * Although almost everything is mappeed into upper case in a Common Lisp
  2408. * world I will preserve the case of symbols defined un u01 to u12.
  2409. */
  2410. create_symbols(u01_setup, restartp | 2);
  2411. create_symbols(u02_setup, restartp | 2);
  2412. create_symbols(u03_setup, restartp | 2);
  2413. create_symbols(u04_setup, restartp | 2);
  2414. create_symbols(u05_setup, restartp | 2);
  2415. create_symbols(u06_setup, restartp | 2);
  2416. create_symbols(u07_setup, restartp | 2);
  2417. create_symbols(u08_setup, restartp | 2);
  2418. create_symbols(u09_setup, restartp | 2);
  2419. create_symbols(u10_setup, restartp | 2);
  2420. create_symbols(u11_setup, restartp | 2);
  2421. create_symbols(u12_setup, restartp | 2);
  2422. #ifdef NAG
  2423. create_symbols(asp_setup, restartp);
  2424. create_symbols(nag_setup, restartp);
  2425. create_symbols(socket_setup, restartp);
  2426. create_symbols(xdr_setup, restartp);
  2427. create_symbols(grep_setup, restartp);
  2428. create_symbols(axfns_setup, restartp);
  2429. create_symbols(gr_setup, restartp);
  2430. #endif
  2431. #ifdef OPENMATH
  2432. create_symbols(om_setup, restartp);
  2433. create_symbols(om_parse_setup, restartp);
  2434. #endif
  2435. #ifdef MEMORY_TRACE
  2436. #ifndef CHECK_ONLY
  2437. memory_comment(13); /* tail end of setup */
  2438. #endif
  2439. #endif
  2440. #ifdef COMMON
  2441. CP = saved_package;
  2442. #endif
  2443. }
  2444. #ifndef COMMON
  2445. #ifdef CWIN
  2446. static int MS_CDECL alpha0(const void *a, const void *b)
  2447. {
  2448. return strcmp(*(const char **)a, *(const char **)b);
  2449. }
  2450. static int MS_CDECL alpha1(const void *a, const void *b)
  2451. {
  2452. return strcmp(1+*(const char **)a, 1+*(const char **)b);
  2453. }
  2454. #endif
  2455. #endif
  2456. static void set_up_variables(CSLbool restartp)
  2457. {
  2458. Lisp_Object nil = C_nil;
  2459. int i;
  2460. #ifdef COMMON
  2461. Lisp_Object saved_package = CP;
  2462. CP = find_package("LISP", 4);
  2463. #endif
  2464. qvalue(macroexpand_hook) = make_symbol("funcall", restartp, Lfuncall1, Lfuncall2, Lfuncalln);
  2465. input_libraries = make_undefined_symbol("input-libraries");
  2466. qheader(input_libraries) |= SYM_SPECIAL_FORM;
  2467. qvalue(input_libraries) = nil;
  2468. for (i=number_of_fasl_paths-1; i>=0; i--)
  2469. qvalue(input_libraries) = cons(SPID_LIBRARY + (((int32)i)<<20),
  2470. qvalue(input_libraries));
  2471. output_library = make_undefined_symbol("output-library");
  2472. qheader(output_library) |= SYM_SPECIAL_FORM;
  2473. qvalue(output_library) = output_directory < 0 ? nil :
  2474. SPID_LIBRARY + (((int32)output_directory)<<20);
  2475. /*
  2476. * The Lisp variable lispsystem* gets set here. (in COMMON mode it is
  2477. * the variable *features*)
  2478. * Its value is a list.
  2479. * csl says I am a CSL Lisp
  2480. * (executable . "string") name of current executable (if available)
  2481. * pipes do I support open-pipe?
  2482. * (version . "string") eg "2.11"
  2483. * (name . "string") eg "MSDOS/386"
  2484. * (opsys . id) unix/msdos/riscos/win32/finder/riscos/...
  2485. * id unix/msdos etc again...
  2486. * win32s qualifier when (opsys . win32) is set
  2487. * win95 ditto
  2488. * help help mechanism provided within Lisp
  2489. * debug Lisp built with debug options
  2490. * (native . number) native code tag
  2491. * (c-code . number) u01.c through u12.c define n functions
  2492. *
  2493. * In COMMON mode the tags on the *features* list are generally in the
  2494. * keyword package. Otherwise they are just regular symbols. This makes it
  2495. * slightly hard to use code that tests this list in a generic environment!
  2496. */
  2497. {
  2498. #ifdef COMMON
  2499. Lisp_Object n = features_symbol;
  2500. Lisp_Object w;
  2501. char opsys[32];
  2502. char *p1 = opsys, *p2 = OPSYS;
  2503. while ((*p1++ = toupper(*p2++)) != 0);
  2504. *p1 = 0;
  2505. w = cons(make_keyword(opsys), nil);
  2506. #else
  2507. Lisp_Object n = make_undefined_symbol("lispsystem*");
  2508. Lisp_Object w = cons(make_keyword(OPSYS), nil), w1;
  2509. qheader(n) |= SYM_SPECIAL_VAR;
  2510. #endif
  2511. defined_symbols = 0;
  2512. count_symbols(u01_setup); count_symbols(u02_setup);
  2513. count_symbols(u03_setup); count_symbols(u04_setup);
  2514. count_symbols(u05_setup); count_symbols(u06_setup);
  2515. count_symbols(u07_setup); count_symbols(u08_setup);
  2516. count_symbols(u09_setup); count_symbols(u10_setup);
  2517. count_symbols(u11_setup); count_symbols(u12_setup);
  2518. #ifdef COMMON
  2519. /*
  2520. * A gratuitous misery here is the need to make COMMON words
  2521. * upper case.
  2522. */
  2523. w = acons(make_keyword("OPSYS"),
  2524. make_undefined_symbol(OPSYS), w);
  2525. w = acons(make_keyword("NATIVE"),
  2526. fixnum_of_int(native_code_tag), w);
  2527. w = acons(make_keyword("C-CODE"),
  2528. fixnum_of_int(defined_symbols), w);
  2529. #ifdef WINDOWS_NT
  2530. if (win32s==1) w = cons(make_keyword("WIN32S"), w);
  2531. else if (win32s==2) w = cons(make_keyword("WIN95"), w);
  2532. #endif
  2533. #ifdef PIPES
  2534. #ifdef PIPES_SOMETIMES
  2535. if (pipes_today)
  2536. #endif
  2537. w = cons(make_keyword("PIPES"), w);
  2538. #endif
  2539. #ifdef HELP_SYSTEM
  2540. w = cons(make_keyword("HELP"), w);
  2541. #endif
  2542. #ifdef DEBUG
  2543. w = cons(make_keyword("DEBUG"), w);
  2544. #endif
  2545. w = cons(make_keyword("RECORD_GET"), w);
  2546. if (program_name[0] != 0)
  2547. w = acons(make_keyword("EXECUTABLE"),
  2548. make_string(program_name), w);
  2549. w = acons(make_keyword("NAME"), make_string(IMPNAME), w);
  2550. w = acons(make_keyword("VERSION"), make_string(VERSION), w);
  2551. w = cons(make_keyword("CCL"), w);
  2552. w = cons(make_keyword("COMMON-LISP"), w);
  2553. #else /* !COMMON */
  2554. w = acons(make_keyword("opsys"),
  2555. make_undefined_symbol(OPSYS), w);
  2556. w = acons(make_keyword("native"),
  2557. fixnum_of_int(native_code_tag), w);
  2558. w = acons(make_keyword("c-code"),
  2559. fixnum_of_int(defined_symbols), w);
  2560. #ifdef WINDOWS_NT
  2561. if (win32s==1) w = cons(make_keyword("win32s"), w);
  2562. else if (win32s==2) w = cons(make_keyword("win95"), w);
  2563. #endif
  2564. #ifdef PIPES
  2565. #ifdef PIPES_SOMETIMES
  2566. if (pipes_today)
  2567. #endif
  2568. w = cons(make_keyword("pipes"), w);
  2569. #endif
  2570. #ifdef HELP_SYSTEM
  2571. w = cons(make_keyword("help"), w);
  2572. #endif
  2573. #ifdef DEBUG
  2574. w = cons(make_keyword("debug"), w);
  2575. #endif
  2576. #ifdef RECORD_GET
  2577. w = cons(make_keyword("record_get"), w);
  2578. #endif
  2579. if (program_name[0] != 0)
  2580. w = acons(make_keyword("executable"),
  2581. make_string(program_name), w);
  2582. w = acons(make_keyword("name"), make_string(IMPNAME), w);
  2583. w = acons(make_keyword("version"), make_string(VERSION), w);
  2584. w = cons(make_keyword("csl"), w);
  2585. /*
  2586. * Ha Ha a trick here - if a symbol ADDSQ is defined I view this image
  2587. * as being one for REDUCE and push that information onto lispsystem*,
  2588. * and I also reset the "about box" information (if using cwin).
  2589. */
  2590. w1 = make_undefined_symbol("addsq");
  2591. if (qfn1(w1) != undefined1)
  2592. { w = cons(make_keyword("reduce"), w);
  2593. /*
  2594. * I then inspect VERSION!* to try to see whether I have 3.6 or 3.7
  2595. */
  2596. w1 = qvalue(make_undefined_symbol("version*"));
  2597. if (is_vector(w1) &&
  2598. type_of_header(vechdr(w1)) == TYPE_STRING)
  2599. {
  2600. #ifdef CWIN
  2601. int n = length_of_header(vechdr(w1))-4;
  2602. sprintf(about_box_title, "About %.*s",
  2603. (n > 31-(int)strlen("About ") ?
  2604. 31-(int)strlen("About ") : n),
  2605. &celt(w1, 0));
  2606. sprintf(about_box_description, "%.*s",
  2607. (n > 31 ? 31 : n),
  2608. &celt(w1, 0));
  2609. /*
  2610. * 3.6 did not have copyright1!* etc info, so take it specially here.
  2611. */
  2612. if (memcmp(&celt(w1, 0), "REDUCE 3.6", 10) == 0)
  2613. { strcpy(about_box_rights_1, "Copyright RAND 1995");
  2614. strcpy(about_box_rights_2, "Copyright Codemist 1996");
  2615. }
  2616. else
  2617. { w1 = qvalue(make_undefined_symbol("copyright1*"));
  2618. if (is_vector(w1) &&
  2619. type_of_header(vechdr(w1)) == TYPE_STRING)
  2620. { n = length_of_header(vechdr(w1))-4;
  2621. sprintf(about_box_rights_1, "%.*s",
  2622. n > 31 ? 31 : n, &celt(w1, 0));
  2623. }
  2624. else strcpy(about_box_rights_1, "Copyright A C Hearn/RAND");
  2625. w1 = qvalue(make_undefined_symbol("copyright2*"));
  2626. if (is_vector(w1) &&
  2627. type_of_header(vechdr(w1)) == TYPE_STRING)
  2628. { n = length_of_header(vechdr(w1))-4;
  2629. sprintf(about_box_rights_2, "%.*s",
  2630. n > 31 ? 31 : n, &celt(w1, 0));
  2631. }
  2632. else strcpy(about_box_rights_2, "Copyright Codemist Ltd");
  2633. }
  2634. #endif
  2635. }
  2636. else
  2637. {
  2638. #ifdef CWIN
  2639. strcpy(about_box_title, "About REDUCE");
  2640. strcpy(about_box_description, "REDUCE");
  2641. strcpy(about_box_rights_1, "Copyright A C Hearn/RAND");
  2642. strcpy(about_box_rights_2, "Copyright Codemist Ltd");
  2643. #endif
  2644. }
  2645. }
  2646. #endif
  2647. qheader(n) |= SYM_SPECIAL_VAR;
  2648. qvalue(n) = w;
  2649. }
  2650. #ifdef COMMON
  2651. /*
  2652. * Floating point characteristics are taken from <float.h> where it is
  2653. * supposed that the C compiler involved has got the values correct.
  2654. * I do this every time the system is loaded rather than just when an
  2655. * image is cold-created. This is because an image file may have been created
  2656. * on a system differing from the one on which it is used. Mayve in fact
  2657. * IEEE arithmetic is ALMOST universal and I am being too cautious here?
  2658. */
  2659. { Lisp_Object w;
  2660. make_constant("short-float-epsilon",
  2661. make_sfloat(16.0*FLT_EPSILON));
  2662. make_constant("single-float-epsilon",
  2663. make_boxfloat(FLT_EPSILON, TYPE_SINGLE_FLOAT));
  2664. make_constant("double-float-epsilon",
  2665. make_boxfloat(DBL_EPSILON, TYPE_DOUBLE_FLOAT));
  2666. /* For now "long" = "double" */
  2667. make_constant("long-float-epsilon",
  2668. make_boxfloat(DBL_EPSILON, TYPE_LONG_FLOAT));
  2669. /*
  2670. * I assume that I have a radix 2 representation, and float-negative-epsilon
  2671. * is just half float-epsilon. Correct me if I am wrong...
  2672. */
  2673. make_constant("short-float-negative-epsilon",
  2674. make_sfloat(16.0*FLT_EPSILON/2.0));
  2675. make_constant("single-float-negative-epsilon",
  2676. make_boxfloat(FLT_EPSILON/2.0, TYPE_SINGLE_FLOAT));
  2677. make_constant("double-float-negative-epsilon",
  2678. make_boxfloat(DBL_EPSILON/2.0, TYPE_DOUBLE_FLOAT));
  2679. /* For now "long" = "double" */
  2680. make_constant("long-float-negative-epsilon",
  2681. make_boxfloat(DBL_EPSILON/2.0, TYPE_LONG_FLOAT));
  2682. /*
  2683. * I hope that the C header file gets extremal values correct. Note that
  2684. * because make_sfloat() truncates (rather than rounding) it should give
  2685. * correct values for most-positive-short-float etc
  2686. */
  2687. make_constant("most-positive-short-float",
  2688. make_sfloat(FLT_MAX));
  2689. make_constant("most-positive-single-float",
  2690. make_boxfloat(FLT_MAX, TYPE_SINGLE_FLOAT));
  2691. make_constant("most-positive-double-float",
  2692. make_boxfloat(DBL_MAX, TYPE_DOUBLE_FLOAT));
  2693. make_constant("most-positive-long-float",
  2694. make_boxfloat(DBL_MAX, TYPE_LONG_FLOAT));
  2695. /*
  2696. * Here I assume that the floating point representation is sign-and-magnitude
  2697. * and hence symmetric about zero.
  2698. */
  2699. make_constant("most-negative-short-float",
  2700. make_sfloat(-FLT_MAX));
  2701. make_constant("most-negative-single-float",
  2702. make_boxfloat(-FLT_MAX, TYPE_SINGLE_FLOAT));
  2703. make_constant("most-negative-double-float",
  2704. make_boxfloat(-DBL_MAX, TYPE_DOUBLE_FLOAT));
  2705. make_constant("most-negative-long-float",
  2706. make_boxfloat(-DBL_MAX, TYPE_LONG_FLOAT));
  2707. /*
  2708. * The "least-xxx" set of values did not consider the case of denormalised
  2709. * numbers too carefully in ClTl-1, so in ClTl-2 there are elaborations. I
  2710. * believe that a proper C header file <float.h> will make the macros that
  2711. * I use here refer to NORMALISED values, so the numeric results I use
  2712. * here will not be quite proper (ie there are smaller floats that are
  2713. * un-normalised). But I will ignore that worry just for now.
  2714. */
  2715. make_constant("least-positive-short-float",
  2716. make_sfloat(FLT_MIN));
  2717. make_constant("least-positive-single-float",
  2718. make_boxfloat(FLT_MIN, TYPE_SINGLE_FLOAT));
  2719. make_constant("least-positive-double-float",
  2720. make_boxfloat(DBL_MIN, TYPE_DOUBLE_FLOAT));
  2721. make_constant("least-positive-long-float",
  2722. make_boxfloat(DBL_MIN, TYPE_LONG_FLOAT));
  2723. make_constant("least-negative-short-float",
  2724. make_sfloat(-FLT_MIN));
  2725. make_constant("least-negative-single-float",
  2726. make_boxfloat(-FLT_MIN, TYPE_SINGLE_FLOAT));
  2727. make_constant("least-negative-double-float",
  2728. make_boxfloat(-DBL_MIN, TYPE_DOUBLE_FLOAT));
  2729. make_constant("least-negative-long-float",
  2730. make_boxfloat(-DBL_MIN, TYPE_LONG_FLOAT));
  2731. /*
  2732. * The bunch here are intended to be NORMALISED numbers, while the unqualified
  2733. * ones above may not be.
  2734. */
  2735. make_constant("least-positive-normalized-short-float",
  2736. make_sfloat(FLT_MIN));
  2737. make_constant("least-positive-normalized-single-float",
  2738. make_boxfloat(FLT_MIN, TYPE_SINGLE_FLOAT));
  2739. make_constant("least-positive-normalized-double-float",
  2740. make_boxfloat(DBL_MIN, TYPE_DOUBLE_FLOAT));
  2741. make_constant("least-positive-normalized-long-float",
  2742. make_boxfloat(DBL_MIN, TYPE_LONG_FLOAT));
  2743. make_constant("least-negative-normalized-short-float",
  2744. make_sfloat(-FLT_MIN));
  2745. make_constant("least-negative-normalized-single-float",
  2746. make_boxfloat(-FLT_MIN, TYPE_SINGLE_FLOAT));
  2747. make_constant("least-negative-normalized-double-float",
  2748. make_boxfloat(-DBL_MIN, TYPE_DOUBLE_FLOAT));
  2749. make_constant("least-negative-normalized-long-float",
  2750. make_boxfloat(-DBL_MIN, TYPE_LONG_FLOAT));
  2751. #ifdef UNIX_TIMES
  2752. /* /*
  2753. * ACN believes that the following is misguided, since the time-reading
  2754. * function (defined in fns1.c) that CCL provides always returns its answer
  2755. * in milliseconds. This the 1000 below is NOT as arbitrary as all that, it
  2756. * represents the unit that CCL (across all platforms) returns time
  2757. * measurements in. The UNIX_TIMES macro is set on Unix systems to
  2758. * influence whether the times() function or clock() is used to read
  2759. * time, where in the former case Unix makes it possible to separate
  2760. * user and system time.
  2761. */
  2762. /* UNIX_TIMES is set in machine.h and will usually be HZ. */
  2763. make_constant("internal-time-units-per-second",
  2764. fixnum_of_int(UNIX_TIMES));
  2765. #else
  2766. make_constant("internal-time-units-per-second",
  2767. fixnum_of_int(1000)); /* Arbitrary figure */
  2768. #endif
  2769. }
  2770. #endif
  2771. #ifdef MEMORY_TRACE
  2772. #ifndef CHECK_ONLY
  2773. memory_comment(3); /* creating symbols */
  2774. #endif
  2775. #endif
  2776. charvec = getvector_init(257*CELL, nil);
  2777. faslvec = nil;
  2778. faslgensyms = nil;
  2779. qheader(terminal_io = make_undefined_symbol("*terminal-io*"))
  2780. |= SYM_SPECIAL_VAR;
  2781. qheader(standard_input = make_undefined_symbol("*standard-input*"))
  2782. |= SYM_SPECIAL_VAR;
  2783. qheader(standard_output = make_undefined_symbol("*standard-output*"))
  2784. |= SYM_SPECIAL_VAR;
  2785. qheader(error_output = make_undefined_symbol("*error-output*"))
  2786. |= SYM_SPECIAL_VAR;
  2787. qheader(trace_output = make_undefined_symbol("*trace-output*"))
  2788. |= SYM_SPECIAL_VAR;
  2789. qheader(debug_io = make_undefined_symbol("*debug-io*"))
  2790. |= SYM_SPECIAL_VAR;
  2791. qheader(query_io = make_undefined_symbol("*query-io*"))
  2792. |= SYM_SPECIAL_VAR;
  2793. stream_type(lisp_work_stream) = make_undefined_symbol("work-stream");
  2794. { Lisp_Object f = lisp_terminal_io;
  2795. stream_type(f) = make_undefined_symbol("terminal-stream");
  2796. set_stream_read_fn(f, char_from_terminal);
  2797. set_stream_read_other(f, read_action_terminal);
  2798. set_stream_write_fn(f, char_to_terminal);
  2799. set_stream_write_other(f, write_action_terminal);
  2800. qvalue(terminal_io) = f;
  2801. f = lisp_standard_input;
  2802. stream_type(f) = make_undefined_symbol("synonym-stream");
  2803. #ifdef COMMON
  2804. /*
  2805. * If I do not have COMMON defined I will take a slight short cut here and
  2806. * make reading from *standard-input* read directly from the terminal. For
  2807. * full Common Lisp compatibility I think *standard-input* is required to
  2808. * be a synonym stream that will dynamically look at the value of the variable
  2809. * *terminal-io* every time it does anything. Ugh, since people who assign to
  2810. * or re-bind *terminal-io* seem to me to be asking for terrible trouble!
  2811. */
  2812. set_stream_read_fn(f, char_from_synonym);
  2813. #else
  2814. set_stream_read_fn(f, char_from_terminal);
  2815. #endif
  2816. set_stream_read_other(f, read_action_synonym);
  2817. stream_read_data(f) = terminal_io;
  2818. qvalue(standard_input) = f;
  2819. f = lisp_standard_output;
  2820. stream_type(f) = make_undefined_symbol("synonym-stream");
  2821. #ifdef COMMON
  2822. set_stream_write_fn(f, char_to_synonym);
  2823. #else
  2824. set_stream_write_fn(f, char_to_terminal);
  2825. #endif
  2826. set_stream_write_other(f, write_action_synonym);
  2827. stream_write_data(f) = terminal_io;
  2828. qvalue(standard_output) = f;
  2829. f = lisp_error_output;
  2830. stream_type(f) = make_undefined_symbol("synonym-stream");
  2831. #ifdef COMMON
  2832. set_stream_write_fn(f, char_to_synonym);
  2833. #else
  2834. set_stream_write_fn(f, char_to_terminal);
  2835. #endif
  2836. set_stream_write_other(f, write_action_synonym);
  2837. stream_write_data(f) = terminal_io;
  2838. qvalue(error_output) = f;
  2839. f = lisp_trace_output;
  2840. stream_type(f) = make_undefined_symbol("synonym-stream");
  2841. #ifdef COMMON
  2842. set_stream_write_fn(f, char_to_synonym);
  2843. #else
  2844. set_stream_write_fn(f, char_to_terminal);
  2845. #endif
  2846. set_stream_write_other(f, write_action_synonym);
  2847. stream_write_data(f) = terminal_io;
  2848. qvalue(trace_output) = f;
  2849. f = lisp_debug_io;
  2850. stream_type(f) = make_undefined_symbol("synonym-stream");
  2851. #ifdef COMMON
  2852. set_stream_read_fn(f, char_from_synonym);
  2853. #else
  2854. set_stream_read_fn(f, char_from_terminal);
  2855. #endif
  2856. set_stream_read_other(f, read_action_synonym);
  2857. stream_read_data(f) = terminal_io;
  2858. #ifdef COMMON
  2859. set_stream_write_fn(f, char_to_synonym);
  2860. #else
  2861. set_stream_write_fn(f, char_to_terminal);
  2862. #endif
  2863. set_stream_write_other(f, write_action_synonym);
  2864. stream_write_data(f) = terminal_io;
  2865. qvalue(debug_io) = f;
  2866. f = lisp_query_io;
  2867. stream_type(f) = make_undefined_symbol("synonym-stream");
  2868. #ifdef COMMON
  2869. set_stream_read_fn(f, char_from_synonym);
  2870. #else
  2871. set_stream_read_fn(f, char_from_terminal);
  2872. #endif
  2873. set_stream_read_other(f, read_action_synonym);
  2874. stream_read_data(f) = terminal_io;
  2875. #ifdef COMMON
  2876. set_stream_write_fn(f, char_to_synonym);
  2877. #else
  2878. set_stream_write_fn(f, char_to_terminal);
  2879. #endif
  2880. set_stream_write_other(f, write_action_synonym);
  2881. stream_write_data(f) = terminal_io;
  2882. qvalue(query_io) = f;
  2883. }
  2884. /*
  2885. * I can not handle boffo overflow very well here, but I do really hope that
  2886. * symbols spelt out on the command line will always be fairly short.
  2887. */
  2888. for (i=0; i<number_of_symbols_to_define; i++)
  2889. { CSLbool undef = undefine_this_one[i];
  2890. char *s = symbols_to_define[i];
  2891. if (undef)
  2892. { Lisp_Object n = make_undefined_symbol(s);
  2893. qvalue(n) = unset_var;
  2894. }
  2895. else
  2896. { char buffer[256];
  2897. char *p = buffer;
  2898. int c;
  2899. Lisp_Object n, v;
  2900. while ((c = *s++) != 0 && c != '=') *p++ = (char)c;
  2901. *p = 0;
  2902. n = make_undefined_symbol(buffer);
  2903. push(n);
  2904. if (c == 0) v = lisp_true;
  2905. else
  2906. {
  2907. /*
  2908. * I have been having a big difficulty here, caused by the inconsistent and
  2909. * awkward behaviours of various shells and "make" utilities. In a tidy
  2910. * and simple world I might like a command-line option -Dxx=yyy to allow
  2911. * arbitrary text for yyy terminating it at the next whitespace. Then yyy
  2912. * could be processed by the Lisp reader so that numbers, symbols, strings
  2913. * etc could be specified. However I find that things I often want to
  2914. * use involve characters such as "\" and ":" (as components of file-names
  2915. * on some machines), and sometimes "make" treats these as terminators, or
  2916. * wants to do something magic with "\". If I put things within quote marks
  2917. * then sometimes the quotes get passed through to Lisp and sometimes not.
  2918. * This is all a BIG misery in a multi-platform situation! As a fresh
  2919. * attempt to inject sanity I will always convert yyy to a Lisp string. If
  2920. * it is specified with leading and trailing '"' marks I will strip them. Thus
  2921. * both -Dxxx=yyy and -Dxxx="yyy" will leave the variable xxx set to the
  2922. * string "yyy". Then as a Lisp user I can parse the string if I need to
  2923. * interpret it as something else.
  2924. */
  2925. #ifndef PASS_PREDEFINES_THROUGH_READER
  2926. if (*s == '"') /* Convert "yyy" to just yyy */
  2927. { p = ++s;
  2928. while (*p != 0) p++;
  2929. if (*--p == '"') *p = 0;
  2930. }
  2931. #endif
  2932. v = make_string(s);
  2933. #ifdef PASS_PREDEFINES_THROUGH_READER
  2934. v = Lexplodec(nil, v);
  2935. v = Lcompress(nil, v);
  2936. /*
  2937. * The above will first make the value in -Dname=value into a string,
  2938. * then explode it into a list, and compress back - the effect is as if the
  2939. * original value had been passed through the regular Lisp READ function,
  2940. * so symbols, numbers and even s-expressions can be parsed. If the
  2941. * parsing fails I (silently) treat the value as just NIL.
  2942. */
  2943. #endif
  2944. nil = C_nil;
  2945. if (exception_pending()) v = flip_exception();
  2946. }
  2947. pop(n);
  2948. qheader(n) |= SYM_SPECIAL_VAR;
  2949. qvalue(n) = v;
  2950. }
  2951. }
  2952. #ifndef COMMON
  2953. #ifdef CWIN
  2954. /*
  2955. * Now if I have the CWIN windowed system (I might want this info elsewhere
  2956. * too if another windowed implementation of CSL can use it) I look in the
  2957. * Lisp variables
  2958. * loadable-packages!*
  2959. * switches!*
  2960. * (both expected to be lists of symbols) and copy info into a couple of
  2961. * C vectors, whence it can go to the window manager and be used to create
  2962. * suitable menus.
  2963. */
  2964. { Lisp_Object w1 = qvalue(make_undefined_symbol("loadable-packages*"));
  2965. Lisp_Object w2;
  2966. int n;
  2967. char *v;
  2968. n = 0;
  2969. for (w2=w1; consp(w2); w2=qcdr(w2)) n++; /* How many? */
  2970. loadable_packages = (char **)(*malloc_hook)((n+1)*sizeof(char *));
  2971. if (loadable_packages != NULL)
  2972. { n = 0;
  2973. for (w2=w1; consp(w2); w2=qcdr(w2))
  2974. { Lisp_Object w3 = qcar(w2);
  2975. int n1;
  2976. if (is_symbol(w3)) w3 = qpname(w3);
  2977. if (!is_vector(w3) ||
  2978. type_of_header(vechdr(w3)) != TYPE_STRING) break;
  2979. n1 = length_of_header(vechdr(w3))-4;
  2980. v = (char *)(*malloc_hook)(n1+1);
  2981. if (v == NULL) break;
  2982. memcpy(v, &celt(w3, 0), n1);
  2983. v[n1] = 0;
  2984. loadable_packages[n++] = v;
  2985. }
  2986. qsort(loadable_packages, n, sizeof(char *), alpha0);
  2987. loadable_packages[n] = NULL;
  2988. }
  2989. w1 = qvalue(make_undefined_symbol("switches*"));
  2990. n = 0;
  2991. for (w2=w1; consp(w2); w2=qcdr(w2)) n++; /* How many? */
  2992. switches = (char **)(*malloc_hook)((n+1)*sizeof(char *));
  2993. if (switches != NULL)
  2994. { n = 0;
  2995. for (w2=w1; consp(w2); w2=qcdr(w2))
  2996. { Lisp_Object w3 = qcar(w2), w4;
  2997. char sname[64];
  2998. int n1;
  2999. if (is_symbol(w3)) w3 = qpname(w3);
  3000. if (!is_vector(w3) ||
  3001. type_of_header(vechdr(w3)) != TYPE_STRING) break;
  3002. n1 = length_of_header(vechdr(w3))-4;
  3003. if (n1 > 60) break;
  3004. sprintf(sname, "*%.*s", n1, &celt(w3, 0));
  3005. w4 = make_undefined_symbol(sname);
  3006. v = (char *)(*malloc_hook)(n1+2);
  3007. if (v == NULL) break;
  3008. /*
  3009. * The first character records the current state of the switch.
  3010. */
  3011. if (qvalue(w4) == nil) v[0] = 'n';
  3012. else v[0] = 'y';
  3013. memcpy(v+1, &celt(w3, 0), n1);
  3014. v[n1+1] = 0;
  3015. switches[n++] = v;
  3016. }
  3017. qsort(switches, n, sizeof(char *), alpha1);
  3018. switches[n] = NULL;
  3019. }
  3020. }
  3021. #endif /* CWIN */
  3022. #endif /* COMMON */
  3023. #ifdef COMMON
  3024. CP = saved_package;
  3025. #endif
  3026. }
  3027. unsigned char registration_data[REGISTRATION_SIZE];
  3028. CSLbool MD5_busy;
  3029. unsigned char unpredictable[256];
  3030. static int n_unpredictable = 0;
  3031. static CSLbool unpredictable_pending = 0;
  3032. void inject_randomness(int n)
  3033. {
  3034. unpredictable[n_unpredictable++] ^= (n % 255);
  3035. if (n_unpredictable >= 256)
  3036. { n_unpredictable = 0;
  3037. unpredictable_pending = YES;
  3038. }
  3039. if (unpredictable_pending & !MD5_busy)
  3040. { MD5_Init();
  3041. MD5_Update(unpredictable, sizeof(unpredictable));
  3042. MD5_Final(unpredictable);
  3043. unpredictable_pending = NO;
  3044. }
  3045. }
  3046. /*
  3047. * For some of what follows I think I need to show that I have considered
  3048. * the issue of export regulations.
  3049. *
  3050. * What I have here is MD5 (and when and if I feel keen SHA-1). I observe
  3051. * that MD5, SHA-1 and DSA are made available as part of Sun's Java
  3052. * Development Kit in the version that can be downloade freely from their
  3053. * servers. They have a separate Java Cryptography Extension within which
  3054. * they keep things that are subject to USA export regulations. I take this
  3055. * as encouragement to believe that these three algorithms are not subject
  3056. * to USA export limits. I believe such limits to be supersets (ie more
  3057. * restrictive) than ones that apply in the UK and so feel happy about
  3058. * including the implementations that I do here. Specifically, although I
  3059. * have extracts from the SSL code which as a whole might give trouble if
  3060. * importen to the USA and the re-exported I only have the message digest
  3061. * bits that should not be so encumbered. I am aware that MD5 is now
  3062. * considered weakish with SHA-1 the improved replacement, but will take the
  3063. * view that I was not aiming for real security on anything anyway!
  3064. */
  3065. /*
  3066. * MD5 message digest code, adapted from Eric Young's version,
  3067. * for which the copyright and disclaimer notices follow. Observe that
  3068. * this code can be adapted and re-used subject to these terms being
  3069. * retained.
  3070. */
  3071. /* crypto/md/md5.c and support files */
  3072. /* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
  3073. * All rights reserved.
  3074. *
  3075. * This package is an SSL implementation written
  3076. * by Eric Young (eay@mincom.oz.au).
  3077. * The implementation was written so as to conform with Netscapes SSL.
  3078. *
  3079. * This library is free for commercial and non-commercial use as long as
  3080. * the following conditions are aheared to. The following conditions
  3081. * apply to all code found in this distribution, be it the RC4, RSA,
  3082. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  3083. * included with this distribution is covered by the same copyright terms
  3084. * except that the holder is Tim Hudson (tjh@mincom.oz.au).
  3085. *
  3086. * Copyright remains Eric Young's, and as such any Copyright notices in
  3087. * the code are not to be removed.
  3088. * If this package is used in a product, Eric Young should be given attribution
  3089. * as the author of the parts of the library used.
  3090. * This can be in the form of a textual message at program startup or
  3091. * in documentation (online or textual) provided with the package.
  3092. *
  3093. * Redistribution and use in source and binary forms, with or without
  3094. * modification, are permitted provided that the following conditions
  3095. * are met:
  3096. * 1. Redistributions of source code must retain the copyright
  3097. * notice, this list of conditions and the following disclaimer.
  3098. * 2. Redistributions in binary form must reproduce the above copyright
  3099. * notice, this list of conditions and the following disclaimer in the
  3100. * documentation and/or other materials provided with the distribution.
  3101. * 3. All advertising materials mentioning features or use of this software
  3102. * must display the following acknowledgement:
  3103. * "This product includes cryptographic software written by
  3104. * Eric Young (eay@mincom.oz.au)"
  3105. * The word 'cryptographic' can be left out if the rouines from the library
  3106. * being used are not cryptographic related :-).
  3107. * 4. If you include any Windows specific code (or a derivative thereof) from
  3108. * the apps directory (application code) you must include an acknowledgement:
  3109. * "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
  3110. *
  3111. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  3112. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  3113. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  3114. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  3115. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  3116. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  3117. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  3118. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  3119. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  3120. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  3121. * SUCH DAMAGE.
  3122. *
  3123. * The licence and distribution terms for any publically available version or
  3124. * derivative of this code cannot be changed. i.e. this code cannot simply be
  3125. * copied and put under another distribution licence
  3126. * [including the GNU Public Licence.]
  3127. */
  3128. /*
  3129. * End of Eric Young's copyright and disclaimer notice.
  3130. *
  3131. * The changes made by A C Norman remove some optimisation to leave shorter
  3132. * code (I will not be using this in speed-critical applications) and
  3133. * adjusting the style and layout to agree with other Codemist utilities.
  3134. */
  3135. #define MD5_CBLOCK 64
  3136. #define MD5_LBLOCK 16
  3137. static unsigned32 MD5_A, MD5_B, MD5_C, MD5_D;
  3138. static unsigned32 MD5_Nl;
  3139. static int MD5_num;
  3140. static unsigned32 MD5_data[MD5_CBLOCK];
  3141. #define F(x,y,z) ((((y) ^ (z)) & (x)) ^ (z))
  3142. #define G(x,y,z) ((((x) ^ (y)) & (z)) ^ (y))
  3143. #define H(x,y,z) ((x) ^ (y) ^ (z))
  3144. #define I(x,y,z) (((x) | (~(z))) ^ (y))
  3145. #define ROTATE(a,n) (((a)<<(n))|((a)>>(32-(n))))
  3146. #define R0(a,b,c,d,k,s,t) { \
  3147. a+=((k)+(t)+F((b),(c),(d))); \
  3148. a=ROTATE(a,s); \
  3149. a+=b; }
  3150. #define R1(a,b,c,d,k,s,t) { \
  3151. a+=((k)+(t)+G((b),(c),(d))); \
  3152. a=ROTATE(a,s); \
  3153. a+=b; }
  3154. #define R2(a,b,c,d,k,s,t) { \
  3155. a+=((k)+(t)+H((b),(c),(d))); \
  3156. a=ROTATE(a,s); \
  3157. a+=b; }
  3158. #define R3(a,b,c,d,k,s,t) { \
  3159. a+=((k)+(t)+I((b),(c),(d))); \
  3160. a=ROTATE(a,s); \
  3161. a+=b; }
  3162. /*
  3163. * Implemented from RFC1321 The MD5 Message-Digest Algorithm
  3164. */
  3165. void MD5_Init(void)
  3166. {
  3167. MD5_busy = YES;
  3168. MD5_A = 0x67452301;
  3169. MD5_B = 0xefcdab89;
  3170. MD5_C = 0x98badcfe;
  3171. MD5_D = 0x10325476;
  3172. MD5_Nl = 0;
  3173. MD5_num = 0;
  3174. }
  3175. static unsigned char byte_order_test[4] = {1, 0, 0, 0};
  3176. static void md5_block(void)
  3177. {
  3178. unsigned32 A=MD5_A, B=MD5_B, C=MD5_C, D=MD5_D;
  3179. int i;
  3180. /*
  3181. * Here I re-write the buffer so that it now behaves as if it is
  3182. * an array of 32-bit words in native computer representation. On
  3183. * many machines the code here will have no effect at all apart from
  3184. * consuming a little time. I do a little test first to see if
  3185. * it is really needed.
  3186. */
  3187. unsigned32 *p = MD5_data;
  3188. unsigned char *q = (unsigned char *)p;
  3189. if (((unsigned32 *)byte_order_test)[0] != 1)
  3190. { for (i=0; i<MD5_LBLOCK; i++)
  3191. { unsigned32 w = *q++;
  3192. w |= *q++ << 8;
  3193. w |= *q++ << 16;
  3194. w |= *q++ << 24;
  3195. *p++ = w;
  3196. }
  3197. }
  3198. p = MD5_data;
  3199. /* Round 0 */
  3200. R0(A,B,C,D,p[ 0], 7,0xd76aa478); R0(D,A,B,C,p[ 1],12,0xe8c7b756);
  3201. R0(C,D,A,B,p[ 2],17,0x242070db); R0(B,C,D,A,p[ 3],22,0xc1bdceee);
  3202. R0(A,B,C,D,p[ 4], 7,0xf57c0faf); R0(D,A,B,C,p[ 5],12,0x4787c62a);
  3203. R0(C,D,A,B,p[ 6],17,0xa8304613); R0(B,C,D,A,p[ 7],22,0xfd469501);
  3204. R0(A,B,C,D,p[ 8], 7,0x698098d8); R0(D,A,B,C,p[ 9],12,0x8b44f7af);
  3205. R0(C,D,A,B,p[10],17,0xffff5bb1); R0(B,C,D,A,p[11],22,0x895cd7be);
  3206. R0(A,B,C,D,p[12], 7,0x6b901122); R0(D,A,B,C,p[13],12,0xfd987193);
  3207. R0(C,D,A,B,p[14],17,0xa679438e); R0(B,C,D,A,p[15],22,0x49b40821);
  3208. /* Round 1 */
  3209. R1(A,B,C,D,p[ 1], 5,0xf61e2562); R1(D,A,B,C,p[ 6], 9,0xc040b340);
  3210. R1(C,D,A,B,p[11],14,0x265e5a51); R1(B,C,D,A,p[ 0],20,0xe9b6c7aa);
  3211. R1(A,B,C,D,p[ 5], 5,0xd62f105d); R1(D,A,B,C,p[10], 9,0x02441453);
  3212. R1(C,D,A,B,p[15],14,0xd8a1e681); R1(B,C,D,A,p[ 4],20,0xe7d3fbc8);
  3213. R1(A,B,C,D,p[ 9], 5,0x21e1cde6); R1(D,A,B,C,p[14], 9,0xc33707d6);
  3214. R1(C,D,A,B,p[ 3],14,0xf4d50d87); R1(B,C,D,A,p[ 8],20,0x455a14ed);
  3215. R1(A,B,C,D,p[13], 5,0xa9e3e905); R1(D,A,B,C,p[ 2], 9,0xfcefa3f8);
  3216. R1(C,D,A,B,p[ 7],14,0x676f02d9); R1(B,C,D,A,p[12],20,0x8d2a4c8a);
  3217. /* Round 2 */
  3218. R2(A,B,C,D,p[ 5], 4,0xfffa3942); R2(D,A,B,C,p[ 8],11,0x8771f681);
  3219. R2(C,D,A,B,p[11],16,0x6d9d6122); R2(B,C,D,A,p[14],23,0xfde5380c);
  3220. R2(A,B,C,D,p[ 1], 4,0xa4beea44); R2(D,A,B,C,p[ 4],11,0x4bdecfa9);
  3221. R2(C,D,A,B,p[ 7],16,0xf6bb4b60); R2(B,C,D,A,p[10],23,0xbebfbc70);
  3222. R2(A,B,C,D,p[13], 4,0x289b7ec6); R2(D,A,B,C,p[ 0],11,0xeaa127fa);
  3223. R2(C,D,A,B,p[ 3],16,0xd4ef3085); R2(B,C,D,A,p[ 6],23,0x04881d05);
  3224. R2(A,B,C,D,p[ 9], 4,0xd9d4d039); R2(D,A,B,C,p[12],11,0xe6db99e5);
  3225. R2(C,D,A,B,p[15],16,0x1fa27cf8); R2(B,C,D,A,p[ 2],23,0xc4ac5665);
  3226. /* Round 3 */
  3227. R3(A,B,C,D,p[ 0], 6,0xf4292244); R3(D,A,B,C,p[ 7],10,0x432aff97);
  3228. R3(C,D,A,B,p[14],15,0xab9423a7); R3(B,C,D,A,p[ 5],21,0xfc93a039);
  3229. R3(A,B,C,D,p[12], 6,0x655b59c3); R3(D,A,B,C,p[ 3],10,0x8f0ccc92);
  3230. R3(C,D,A,B,p[10],15,0xffeff47d); R3(B,C,D,A,p[ 1],21,0x85845dd1);
  3231. R3(A,B,C,D,p[ 8], 6,0x6fa87e4f); R3(D,A,B,C,p[15],10,0xfe2ce6e0);
  3232. R3(C,D,A,B,p[ 6],15,0xa3014314); R3(B,C,D,A,p[13],21,0x4e0811a1);
  3233. R3(A,B,C,D,p[ 4], 6,0xf7537e82); R3(D,A,B,C,p[11],10,0xbd3af235);
  3234. R3(C,D,A,B,p[ 2],15,0x2ad7d2bb); R3(B,C,D,A,p[ 9],21,0xeb86d391);
  3235. MD5_A += A;
  3236. MD5_B += B;
  3237. MD5_C += C;
  3238. MD5_D += D;
  3239. }
  3240. void MD5_Update(unsigned char *data, int len)
  3241. {
  3242. unsigned char *p = (unsigned char *)MD5_data;
  3243. /*
  3244. * The full MD5 procedure allows for encoding strings of up to
  3245. * around 2^64 bits. I will restrict myself to 2^32 so I can just ignore
  3246. * the high word of the bit-count.
  3247. */
  3248. MD5_Nl += len<<3; /* Counts in BITS not BYTES here */
  3249. while (len != 0)
  3250. { p[MD5_num++] = *data++;
  3251. len--;
  3252. if (MD5_num == MD5_CBLOCK)
  3253. { md5_block();
  3254. MD5_num = 0;
  3255. }
  3256. }
  3257. }
  3258. void MD5_Final(unsigned char *md)
  3259. {
  3260. unsigned32 l = MD5_Nl;
  3261. unsigned char *p = (unsigned char *)MD5_data;
  3262. p[MD5_num++] = 0x80;
  3263. if (MD5_num >= MD5_CBLOCK-8)
  3264. { while (MD5_num < MD5_CBLOCK) p[MD5_num++] = 0;
  3265. md5_block();
  3266. MD5_num = 0;
  3267. }
  3268. while (MD5_num < MD5_CBLOCK-8) p[MD5_num++] = 0;
  3269. p[MD5_num++] = (unsigned char)l;
  3270. p[MD5_num++] = (unsigned char)(l>>8);
  3271. p[MD5_num++] = (unsigned char)(l>>16);
  3272. p[MD5_num++] = (unsigned char)(l>>24);
  3273. p[MD5_num++] = 0;
  3274. p[MD5_num++] = 0;
  3275. p[MD5_num++] = 0;
  3276. p[MD5_num++] = 0;
  3277. md5_block();
  3278. p = md;
  3279. l = MD5_A;
  3280. *p++ = (unsigned char)l;
  3281. *p++ = (unsigned char)(l>>8);
  3282. *p++ = (unsigned char)(l>>16);
  3283. *p++ = (unsigned char)(l>>24);
  3284. l = MD5_B;
  3285. *p++ = (unsigned char)l;
  3286. *p++ = (unsigned char)(l>>8);
  3287. *p++ = (unsigned char)(l>>16);
  3288. *p++ = (unsigned char)(l>>24);
  3289. l = MD5_C;
  3290. *p++ = (unsigned char)l;
  3291. *p++ = (unsigned char)(l>>8);
  3292. *p++ = (unsigned char)(l>>16);
  3293. *p++ = (unsigned char)(l>>24);
  3294. l = MD5_D;
  3295. *p++ = (unsigned char)l;
  3296. *p++ = (unsigned char)(l>>8);
  3297. *p++ = (unsigned char)(l>>16);
  3298. *p++ = (unsigned char)(l>>24);
  3299. MD5_busy = NO;
  3300. }
  3301. unsigned char *MD5(unsigned char *d, int n, unsigned char *md)
  3302. {
  3303. if (n < 0) n = strlen((char *)d);
  3304. MD5_Init();
  3305. MD5_Update(d, n);
  3306. MD5_Final(md);
  3307. return md;
  3308. }
  3309. #ifdef STAND_ALONE_TESTING_OF_MD5_CODE
  3310. int main(int argc, char *argv[])
  3311. {
  3312. int i;
  3313. unsigned char mm[16];
  3314. MD5("", 0, mm);
  3315. for (i=0; i<16; i++) printf("%.2x", mm[i] & 0xff);
  3316. printf("\n");
  3317. MD5("a", 1, mm);
  3318. for (i=0; i<16; i++) printf("%.2x", mm[i] & 0xff);
  3319. printf("\n");
  3320. MD5("abc", 3, mm);
  3321. for (i=0; i<16; i++) printf("%.2x", mm[i] & 0xff);
  3322. printf("\n");
  3323. MD5("message digest", -1, mm);
  3324. for (i=0; i<16; i++) printf("%.2x", mm[i] & 0xff);
  3325. printf("\n");
  3326. MD5("abcdefghijklmnopqrstuvwxyz", -1, mm);
  3327. for (i=0; i<16; i++) printf("%.2x", mm[i] & 0xff);
  3328. printf("\n");
  3329. MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", -1, mm);
  3330. for (i=0; i<16; i++) printf("%.2x", mm[i] & 0xff);
  3331. printf("\n");
  3332. MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890", -1, mm);
  3333. for (i=0; i<16; i++) printf("%.2x", mm[i] & 0xff);
  3334. printf("\n");
  3335. return 0;
  3336. }
  3337. #endif
  3338. /*
  3339. * This is the end of the Eric Young code - what follows is Codemist
  3340. * original code again.
  3341. *
  3342. *
  3343. *
  3344. * The next bit is for an experiment in controlling access to image files
  3345. * etc. It is solely intended for use in implementing this access control
  3346. * and is not made available as something that a CSL/Reduce user can access
  3347. * directly. It favours high speed above other things, and much of its
  3348. * security in use will be based on nobody having a real incentive to
  3349. * poke at it since CSL-based images will not be expected to be of
  3350. * sufficient value to justify the effort.
  3351. */
  3352. int crypt_active;
  3353. unsigned char *crypt_buffer;
  3354. int crypt_count;
  3355. /*
  3356. * The following code was generated by running the program "gencry.c",
  3357. * within which you can find the comments that explain what is going on. The
  3358. * macro TIME_TEST could be defined to make this file more of a self-
  3359. * contained test of its performance, but to do that you probably need
  3360. * to look at the raw output from gencry.c.
  3361. *
  3362. * word length = 32
  3363. * shift register length = 65
  3364. * tap at position 18
  3365. * shuffle-buffer size = 4096
  3366. */
  3367. #ifdef TIME_TEST
  3368. #include <stdio.h>
  3369. #include <time.h>
  3370. #define N 10000000 /* parameters for time test */
  3371. #define NSTARTS 4000
  3372. #define NTINY 50000000
  3373. #define KEY "Arthurs's sample key"
  3374. typedef unsigned int unsigned32;
  3375. #endif /* TIME_TEST */
  3376. static unsigned32 lf[65], mix[4096];
  3377. #define R(x) ((x) >> 20)
  3378. #define S(x) ((x) >> 18)
  3379. #define T(x) ((x) << 13)
  3380. /*
  3381. * static unsigned char byte_order_test[] =
  3382. * {1, 0, 0, 0, 0, 0, 0, 0};
  3383. */
  3384. #define CRYPT_BLOCK_SIZE 128
  3385. void crypt_get_block(unsigned char block[CRYPT_BLOCK_SIZE])
  3386. {
  3387. unsigned32 *b = (unsigned32 *)block;
  3388. int n;
  3389. lf[0] -= lf[18]; lf[1] ^= lf[19];
  3390. lf[2] -= lf[20]; lf[3] += lf[21];
  3391. lf[4] += lf[22]; lf[5] -= lf[23];
  3392. lf[6] ^= lf[24]; lf[7] -= lf[25];
  3393. lf[8] += lf[26]; lf[9] ^= lf[27];
  3394. lf[10] -= lf[28]; lf[11] -= lf[29];
  3395. lf[12] += lf[30]; lf[13] += lf[31];
  3396. lf[14] -= lf[32]; lf[15] ^= lf[33];
  3397. lf[16] -= lf[34]; lf[17] += lf[35];
  3398. lf[18] += lf[36]; lf[19] += lf[37];
  3399. lf[20] -= lf[38]; lf[21] -= lf[39];
  3400. lf[22] ^= lf[40]; lf[23] += lf[41];
  3401. lf[24] -= lf[42]; lf[25] -= lf[43];
  3402. lf[26] += lf[44]; lf[27] += lf[45];
  3403. lf[28] -= lf[46]; lf[29] ^= lf[47];
  3404. lf[30] -= lf[48]; lf[31] += lf[49];
  3405. lf[32] -= lf[50]; lf[33] ^= lf[51];
  3406. lf[34] -= lf[52]; lf[35] ^= lf[53];
  3407. lf[36] += lf[54]; lf[37] += lf[55];
  3408. lf[38] ^= lf[56]; lf[39] ^= lf[57];
  3409. lf[40] += lf[58]; lf[41] -= lf[59];
  3410. lf[42] ^= lf[60]; lf[43] += lf[61];
  3411. lf[44] += lf[62]; lf[45] ^= lf[63];
  3412. lf[46] ^= lf[64]; lf[47] -= lf[0];
  3413. lf[48] ^= lf[1]; lf[49] ^= lf[2];
  3414. lf[50] ^= lf[3]; lf[51] ^= lf[4];
  3415. lf[52] ^= lf[5]; lf[53] ^= lf[6];
  3416. lf[54] += lf[7]; lf[55] -= lf[8];
  3417. lf[56] -= lf[9]; lf[57] ^= lf[10];
  3418. lf[58] -= lf[11]; lf[59] -= lf[12];
  3419. lf[60] ^= lf[13]; lf[61] += lf[14];
  3420. lf[62] ^= lf[15]; lf[63] -= lf[16];
  3421. lf[64] -= lf[17];
  3422. n = R(lf[0]); b[0] = mix[n]; mix[n] = (lf[54] + S(lf[29])) ^ T(lf[5]);
  3423. n = R(lf[1]); b[1] = mix[n]; mix[n] = ~(lf[39] + S(lf[47])) + T(lf[15]);
  3424. n = R(lf[2]); b[2] = mix[n]; mix[n] = (lf[25] + S(lf[14])) + T(lf[38]);
  3425. n = R(lf[4]); b[3] = mix[n]; mix[n] = ~(lf[48] - S(lf[40])) ^ T(lf[10]);
  3426. n = R(lf[5]); b[4] = mix[n]; mix[n] = (lf[44] - S(lf[55])) - T(lf[49]);
  3427. n = R(lf[6]); b[5] = mix[n]; mix[n] = ~(lf[9] ^ S(lf[37])) + T(lf[50]);
  3428. n = R(lf[8]); b[6] = mix[n]; mix[n] = (lf[64] ^ S(lf[51])) + T(lf[8]);
  3429. n = R(lf[9]); b[7] = mix[n]; mix[n] = ~(lf[11] - S(lf[35])) - T(lf[21]);
  3430. n = R(lf[10]); b[8] = mix[n]; mix[n] = (lf[20] ^ S(lf[21])) ^ T(lf[3]);
  3431. n = R(lf[12]); b[9] = mix[n]; mix[n] = ~(lf[6] ^ S(lf[31])) - T(lf[61]);
  3432. n = R(lf[13]); b[10] = mix[n]; mix[n] = (lf[3] - S(lf[16])) ^ T(lf[16]);
  3433. n = R(lf[14]); b[11] = mix[n]; mix[n] = ~(lf[17] - S(lf[53])) - T(lf[2]);
  3434. n = R(lf[16]); b[12] = mix[n]; mix[n] = (lf[27] + S(lf[42])) - T(lf[33]);
  3435. n = R(lf[17]); b[13] = mix[n]; mix[n] = ~(lf[28] + S(lf[63])) - T(lf[46]);
  3436. n = R(lf[18]); b[14] = mix[n]; mix[n] = (lf[10] - S(lf[46])) + T(lf[35]);
  3437. n = R(lf[20]); b[15] = mix[n]; mix[n] = ~(lf[53] - S(lf[10])) - T(lf[27]);
  3438. n = R(lf[21]); b[16] = mix[n]; mix[n] = (lf[4] + S(lf[18])) - T(lf[7]);
  3439. n = R(lf[22]); b[17] = mix[n]; mix[n] = ~(lf[43] + S(lf[64])) ^ T(lf[45]);
  3440. n = R(lf[24]); b[18] = mix[n]; mix[n] = (lf[14] + S(lf[26])) + T(lf[44]);
  3441. n = R(lf[25]); b[19] = mix[n]; mix[n] = ~(lf[23] ^ S(lf[38])) + T(lf[58]);
  3442. n = R(lf[26]); b[20] = mix[n]; mix[n] = (lf[47] + S(lf[59])) ^ T(lf[47]);
  3443. n = R(lf[28]); b[21] = mix[n]; mix[n] = ~(lf[63] - S(lf[36])) - T(lf[57]);
  3444. n = R(lf[29]); b[22] = mix[n]; mix[n] = (lf[56] + S(lf[4])) + T(lf[19]);
  3445. n = R(lf[30]); b[23] = mix[n]; mix[n] = ~(lf[42] - S(lf[52])) - T(lf[56]);
  3446. n = R(lf[32]); b[24] = mix[n]; mix[n] = (lf[37] + S(lf[3])) - T(lf[63]);
  3447. n = R(lf[33]); b[25] = mix[n]; mix[n] = ~(lf[32] + S(lf[1])) - T(lf[12]);
  3448. n = R(lf[34]); b[26] = mix[n]; mix[n] = (lf[62] - S(lf[39])) - T(lf[31]);
  3449. n = R(lf[36]); b[27] = mix[n]; mix[n] = ~(lf[2] ^ S(lf[44])) ^ T(lf[18]);
  3450. n = R(lf[37]); b[28] = mix[n]; mix[n] = (lf[24] ^ S(lf[50])) ^ T(lf[55]);
  3451. n = R(lf[38]); b[29] = mix[n]; mix[n] = ~(lf[22] + S(lf[27])) - T(lf[32]);
  3452. n = R(lf[40]); b[30] = mix[n]; mix[n] = (lf[51] + S(lf[33])) + T(lf[0]);
  3453. n = R(lf[41]); b[31] = mix[n]; mix[n] = ~(lf[52] ^ S(lf[19])) - T(lf[26]);
  3454. n = R(lf[42]); mix[n] = (lf[5] ^ S(lf[41])) + T(lf[28]);
  3455. n = R(lf[44]); mix[n] = ~(lf[30] ^ S(lf[15])) - T(lf[30]);
  3456. n = R(lf[45]); mix[n] = (lf[45] + S(lf[24])) ^ T(lf[51]);
  3457. n = R(lf[46]); mix[n] = ~(lf[13] + S(lf[49])) - T(lf[11]);
  3458. n = R(lf[48]); mix[n] = (lf[16] + S(lf[11])) - T(lf[39]);
  3459. n = R(lf[49]); mix[n] = ~(lf[57] - S(lf[43])) - T(lf[60]);
  3460. n = R(lf[50]); mix[n] = (lf[49] + S(lf[48])) ^ T(lf[25]);
  3461. n = R(lf[52]); mix[n] = ~(lf[34] - S(lf[22])) ^ T(lf[23]);
  3462. n = R(lf[53]); mix[n] = (lf[18] + S(lf[6])) + T(lf[1]);
  3463. n = R(lf[54]); mix[n] = ~(lf[29] + S(lf[61])) - T(lf[64]);
  3464. n = R(lf[56]); mix[n] = (lf[59] ^ S(lf[45])) - T(lf[41]);
  3465. n = R(lf[57]); mix[n] = ~(lf[36] - S(lf[32])) + T(lf[37]);
  3466. n = R(lf[58]); mix[n] = (lf[40] + S(lf[60])) + T(lf[14]);
  3467. n = R(lf[60]); mix[n] = ~(lf[1] + S(lf[56])) ^ T(lf[36]);
  3468. n = R(lf[61]); mix[n] = (lf[8] ^ S(lf[5])) ^ T(lf[17]);
  3469. n = R(lf[62]); mix[n] = ~(lf[31] ^ S(lf[17])) ^ T(lf[52]);
  3470. /* The test this way around favours Intel etc byte order */
  3471. if (((unsigned int *)byte_order_test)[0] != 1)
  3472. { int i;
  3473. for (i=0; i<32; i++)
  3474. { unsigned32 w = b[i];
  3475. unsigned32 b0, b1, b2, b3;
  3476. b0 = (w >> 24) & 0xffU;
  3477. b1 = (w >> 8) & 0xff00U;
  3478. b2 = (w << 8) & 0xff0000U;
  3479. b3 = (w << 24) & 0xff000000U;
  3480. b[i] = b0 | b1 | b2 | b3;
  3481. }
  3482. }
  3483. return;
  3484. }
  3485. void crypt_init(char *key)
  3486. {
  3487. char *pk = key;
  3488. unsigned char junk[CRYPT_BLOCK_SIZE];
  3489. int i, j;
  3490. unsigned32 w = 0;
  3491. for (i=0; i<260; i++)
  3492. { int k = *pk++;
  3493. if (k == 0) pk = key; /* Cycle key (inc. terminating 0) */
  3494. w = (w << 8) | (k & 0xff);
  3495. if ((i % 4) == 3) lf[i/4] = w;
  3496. }
  3497. for (i=0; i<4096; i++) mix[i] = 0;
  3498. for (i=0; i<8; i++)
  3499. { for (j=0; j<65; j++)
  3500. lf[j] = (lf[j] << 10) | (lf[j] >> 22);
  3501. lf[0] |= 1;
  3502. for (j=0; j<64; j++)
  3503. crypt_get_block(junk);
  3504. }
  3505. for (i=0; i<4096;)
  3506. { int j;
  3507. crypt_get_block(junk);
  3508. for (j=0; j<32; j++)
  3509. { unsigned32 r = junk[4*j];
  3510. r = (r << 8) | junk[4*j+1];
  3511. r = (r << 8) | junk[4*j+2];
  3512. r = (r << 8) | junk[4*j+3];
  3513. if (r == 0) continue;
  3514. mix[i++] ^= junk[j];
  3515. if (i == 4096) break;
  3516. }
  3517. }
  3518. for (i=0; i<192; i++)
  3519. crypt_get_block(junk);
  3520. return;
  3521. }
  3522. #ifdef TIME_TEST
  3523. /*
  3524. * The main program here does not do anything of real interest. It
  3525. * runs both the key-setup and the main loop lots of times and reports
  3526. * how long it all takes.
  3527. *
  3528. * Here is some sample output from a Pentium-II 400Mhz system
  3529. *
  3530. * [02faf080] 7.60 nanoseconds to do tiny loop
  3531. * 1.25 milliseconds to startup
  3532. * rate = 104.86 megabytes per second
  3533. * 79 a7 e1 52 2e 84 09 ce d0 3d 45 b2 52 2d b6 c7
  3534. * 9b ee 57 25 68 58 b7 44 42 51 1c c7 de 69 0f 89
  3535. * 98 6c cd 45 e0 a1 d4 04 a3 be 3d 5f 93 64 c9 d9
  3536. * b9 47 28 59 d0 99 5a 35 56 fd 89 e6 48 4f a4 88
  3537. * 7e dd 31 76 2b 8e 96 fa d0 6f d7 30 9c 3c 01 97
  3538. * 8a 54 93 c0 02 1d 26 df 31 2b 7b 92 56 51 fa 47
  3539. * 92 13 39 47 45 d2 b5 33 2b f6 cc 62 ec 73 00 40
  3540. * 66 ab 37 f5 1d 21 3a a9 b8 da 35 ac 04 f1 3b 53
  3541. *
  3542. */
  3543. int main(int argc, char *argv[])
  3544. {
  3545. clock_t c0, c1;
  3546. unsigned char r[CRYPT_BLOCK_SIZE];
  3547. int i, j = 0;
  3548. double rate;
  3549. c0 = clock();
  3550. for (i=0; i<(NTINY+1); i++) j ^= i;
  3551. c1 = clock();
  3552. printf("[%.8x] %.2f nanoseconds to do tiny loop\n", j,
  3553. 1.0e9*(double)(c1-c0)/((double)CLOCKS_PER_SEC*(double)(NTINY+1)));
  3554. c0 = clock();
  3555. for (i=0; i<NSTARTS; i++) crypt_init(KEY);
  3556. c1 = clock();
  3557. printf("%.2f milliseconds to startup\n",
  3558. 1000.0*(double)(c1-c0)/((double)CLOCKS_PER_SEC*(double)NSTARTS));
  3559. c0 = clock();
  3560. for (i=0; i<N; i++) crypt_get_block(r);
  3561. c1 = clock();
  3562. rate = (double)N*(double)CRYPT_BLOCK_SIZE*(double)CLOCKS_PER_SEC/
  3563. ((double)(c1-c0)*1.0e6);
  3564. printf("rate = %.2f megabytes per second\n", rate);
  3565. for (i=0; i<128; i++)
  3566. { printf("%.2x ", r[i]);
  3567. if ((i % 16) == 15) printf("\n");
  3568. }
  3569. return 0;
  3570. }
  3571. #endif /* TIME_TEST */
  3572. #undef R
  3573. #undef S
  3574. #undef T
  3575. /* End of generated code... */
  3576. static void get_checksum(const setup_type *p)
  3577. {
  3578. while (p->name!=NULL) p++;
  3579. if (p->one != NULL && p->two != NULL)
  3580. { unsigned char *w = (unsigned char *)p->two;
  3581. MD5_Update(w, strlen((char *)w));
  3582. }
  3583. }
  3584. void get_user_files_checksum(unsigned char *b)
  3585. {
  3586. MD5_Init();
  3587. get_checksum(u01_setup);
  3588. get_checksum(u02_setup);
  3589. get_checksum(u03_setup);
  3590. get_checksum(u04_setup);
  3591. get_checksum(u05_setup);
  3592. get_checksum(u06_setup);
  3593. get_checksum(u07_setup);
  3594. get_checksum(u08_setup);
  3595. get_checksum(u09_setup);
  3596. get_checksum(u10_setup);
  3597. get_checksum(u11_setup);
  3598. get_checksum(u12_setup);
  3599. MD5_Final(b);
  3600. }
  3601. char *crypt_keys[CRYPT_KEYS];
  3602. void setup(int restartp, double store_size)
  3603. {
  3604. int i;
  3605. Lisp_Object nil;
  3606. #ifdef TIME_TEST_CRYPTO
  3607. /* *********** Now I will time my encryption stuff... ************* */
  3608. clock_t t0 = clock(), t1;
  3609. #define TRIALS 2000
  3610. for (i=0; i<TRIALS; i++) crypt_init("Arthur\'s secret key");
  3611. t1 = clock();
  3612. term_printf("Time for crypt_init = %.2g milliseconds\n",
  3613. 1.0e3*((double)(t1-t0))/(double)CLOCKS_PER_SEC/(double)TRIALS);
  3614. #define TRIALS1 1000000
  3615. { unsigned char buffer[CRYPT_BLOCK];
  3616. t0 = clock();
  3617. for (i=0; i<TRIALS1; i++) crypt_get_block(buffer);
  3618. t1 = clock();
  3619. }
  3620. { double Mbytes = (double)TRIALS1*(double)CRYPT_BLOCK/1000000.0;
  3621. double seconds = (double)(t1-t0)/(double)CLOCKS_PER_SEC;
  3622. term_printf("Time to do 1 Mbyte = %.2g seconds\n", seconds/Mbytes);
  3623. term_printf("Ie %.4g Mbytes per sec\n", Mbytes/seconds);
  3624. }
  3625. /* **************** end of temp gunk ***************** */
  3626. #endif
  3627. crypt_active = -1;
  3628. #ifdef DEBUG
  3629. /*
  3630. * Just a sanity check so that if I add entries in this table but to
  3631. * not change the recorded size I will be warned.
  3632. */
  3633. if ((entry_table_size+1)*sizeof(entry_point) != sizeof(entries_table))
  3634. { term_printf("entry_table_size badly set up in externs.h\n");
  3635. my_exit(EXIT_FAILURE);
  3636. }
  3637. if (sizeof(int32) != 4 ||
  3638. sizeof(unsigned32) != 4 ||
  3639. #ifdef SIXTY_FOUR_BIT
  3640. sizeof(int64) != 8 ||
  3641. sizeof(unsigned64) != 8 ||
  3642. #endif
  3643. #ifndef ILP64
  3644. sizeof(int16) != 2 ||
  3645. sizeof(unsigned16) != 2 ||
  3646. #endif
  3647. sizeof(int8) != 1 ||
  3648. sizeof(unsigned8) != 1)
  3649. { term_printf("Some datatype size is wrongly set up in tags.h\n");
  3650. my_exit(EXIT_FAILURE);
  3651. }
  3652. #endif
  3653. if (restartp & 2) init_heap_segments(store_size);
  3654. restartp &= 1;
  3655. nil = C_nil;
  3656. #ifdef TIDY_UP_MEMORY_AT_START
  3657. /*
  3658. * The following should not be needed, feature on big machines could be
  3659. * expensive. The code is left in case it helps with repeatability in
  3660. * the face of accesses to uninitialised locations (ie BUGS)
  3661. */
  3662. for (i=0; i<pages_count; i++)
  3663. memset(pages[i], 0, (size_t)CSL_PAGE_SIZE+16);
  3664. memset(stacksegment, 0, (size_t)stack_segsize*CSL_PAGE_SIZE+16);
  3665. memset(nilsegment, 0, (size_t)NIL_SEGMENT_SIZE);
  3666. #endif
  3667. stack = stackbase;
  3668. exit_tag = exit_value = nil;
  3669. exit_reason = UNWIND_NULL;
  3670. if (restartp & 1)
  3671. { char junkbuf[120];
  3672. char filename[LONGEST_LEGAL_FILENAME];
  3673. if (IopenRoot(filename, 0))
  3674. { term_printf("\n+++ Image file \"%s\" can not be read\n",
  3675. filename);
  3676. my_exit(EXIT_FAILURE);
  3677. }
  3678. /*
  3679. * I read input via a buffer of size FREAD_BUFFER_SIZE, which I pre-fill
  3680. * at this stage before I even try to read anything
  3681. */
  3682. fread_ptr = (unsigned char *)stack;
  3683. fread_count = Iread(fread_ptr, FREAD_BUFFER_SIZE);
  3684. /*
  3685. * I can adjust here (automatically) for whatever compression threshold
  3686. * had been active when the image file was created.
  3687. */
  3688. compression_worth_while = 128;
  3689. crypt_active = -1;
  3690. Cfread(junkbuf, 112);
  3691. { int fg = junkbuf[111];
  3692. while (fg != 0) compression_worth_while <<= 1, fg--;
  3693. fg = junkbuf[110];
  3694. while (fg != 0) crypt_active++, fg--;
  3695. if (crypt_active >= 0 &&
  3696. crypt_active < CRYPT_KEYS &&
  3697. crypt_keys[crypt_active] != NULL)
  3698. { crypt_init(crypt_keys[crypt_active]);
  3699. if ((crypt_buffer =
  3700. (unsigned char *)(*malloc_hook)(CRYPT_BLOCK))
  3701. == NULL) crypt_active = -1; /* And will then fail */
  3702. crypt_count = 0;
  3703. }
  3704. }
  3705. if (init_flags & INIT_VERBOSE)
  3706. { term_printf("Created: %.25s\n", &junkbuf[64]);
  3707. /* Time dump was taken */
  3708. }
  3709. { unsigned char chk[16];
  3710. get_user_files_checksum(chk);
  3711. for (i=0; i<16; i++)
  3712. { if (chk[i] != (junkbuf[90+i] & 0xff))
  3713. { term_printf(
  3714. "\n+++ Image file belongs with a different version\n");
  3715. term_printf(
  3716. " of the executable file (incompatible code\n");
  3717. term_printf(
  3718. " has been optimised into C and incorporated)\n");
  3719. term_printf(
  3720. " Unable to use this image file, so stopping\n");
  3721. my_exit(EXIT_FAILURE);
  3722. }
  3723. }
  3724. }
  3725. /*
  3726. * To make things more responsive for the user I will display a
  3727. * banner rather early (before reading the bulk of the image file).
  3728. * The banner that I will display is one provided to be by PRESERVE.
  3729. */
  3730. { Ihandle save;
  3731. char b[64];
  3732. int i;
  3733. Icontext(&save);
  3734. #define BANNER_CODE (-1002)
  3735. if (IopenRoot(filename, BANNER_CODE)) b[0] = 0;
  3736. else
  3737. { for (i=0; i<64; i++) b[i] = (char)Igetc();
  3738. IcloseInput(NO);
  3739. }
  3740. Irestore_context(save);
  3741. /*
  3742. * A banner set via startup-banner takes precedence over one from preserve.
  3743. */
  3744. if (b[0] != 0)
  3745. { term_printf("%s\n", b);
  3746. ensure_screen();
  3747. }
  3748. else if (junkbuf[0] != 0)
  3749. { term_printf("%s\n", junkbuf);
  3750. ensure_screen();
  3751. }
  3752. }
  3753. #ifdef PREVIOUS_ATTEMPT_AT_AUTHENTICATION
  3754. { char username[48];
  3755. unsigned char sig[16];
  3756. unsigned32 hash;
  3757. int c1;
  3758. unsigned char *s = &registration_data[4];
  3759. MD5_Update(s, 48);
  3760. MD5_Final(sig);
  3761. if (memcmp(sig, &s[48], 16) != 0)
  3762. { term_printf("************************************\n");
  3763. term_printf("* Registration data seems corrupt *\n");
  3764. term_printf("* Please check with your supplier. *\n");
  3765. term_printf("************************************\n");
  3766. /*
  3767. * If I were really feeling confident - or possibly mean - I would
  3768. * just exit from the system here declaring that my consistency check
  3769. * had failed and that hence there was a presumption that somebody had
  3770. * tried to patch or otherwise bodge my registration-name code. At least for
  3771. * a few weeks I will not go that far, and I will expect that the annoying
  3772. * message above will do quite enough. The real security that I can enforce
  3773. * is pretty low anyway, and so overall I believe that the policy adopted
  3774. * here is probably adequate.
  3775. */
  3776. }
  3777. else
  3778. { hash = *s++;
  3779. hash |= *s++<<8;
  3780. hash |= *s++<<16;
  3781. hash |= *s++<<24;
  3782. for (c1=0;c1<44;c1++)
  3783. { hash = 69069*hash + 314159;
  3784. username[c1] = *s++ ^ (hash >> 16);
  3785. }
  3786. while (c1 > 0 && username[--c1] == ' ') username[c1] = 0;
  3787. term_printf("Registered to: %s\n", username);
  3788. }
  3789. }
  3790. #endif /* AUTHORIZATION */
  3791. /*
  3792. * From here on if crypt_active is >= 0 I will be decoding an encrypted
  3793. * image file.
  3794. */
  3795. Cfread(junkbuf, 8);
  3796. Cfread((char *)BASE, sizeof(Lisp_Object)*last_nil_offset);
  3797. copy_out_of_nilseg(YES);
  3798. #ifndef COMMON
  3799. qheader(nil) = TAG_ODDS+TYPE_SYMBOL+SYM_SPECIAL_VAR;/* BEFORE nil... */
  3800. #endif
  3801. if ((byteflip & 0xffff0000U) == 0x56780000U)
  3802. {
  3803. #ifndef ADDRESS_64
  3804. flip_needed = NO;
  3805. #endif
  3806. old_fp_rep = (int)(byteflip & FP_MASK);
  3807. old_page_bits = (int)((byteflip >> 8) & 0x1f);
  3808. }
  3809. else if ((byteflip & 0x0000ffffU) == 0x00007856U)
  3810. {
  3811. #ifndef ADDRESS_64
  3812. flip_needed = YES;
  3813. #endif
  3814. old_fp_rep = (int)(flip_bytes_fn(byteflip) & FP_MASK);
  3815. old_page_bits = (int)((flip_bytes_fn(byteflip) >> 8) & 0x1f);
  3816. }
  3817. else
  3818. { term_printf("\n+++ The checkpoint file is corrupt\n");
  3819. /*
  3820. * Note: I use different numbers to check byte-ordering on segmented feature
  3821. * non-segmented systems, since the heap image formats are not compatible.
  3822. * A result will be that use of the wrong sort of image will lead to a
  3823. * "checkpoint file corrupt" message rather than a more serious shambles.
  3824. */
  3825. my_exit(EXIT_FAILURE);
  3826. }
  3827. if (old_page_bits == 0) old_page_bits = 16; /* Old default value */
  3828. /*
  3829. * I could in fact recover in the case that old_page_bits < PAGE_BITS, since
  3830. * I could just map the old small pages into the new big ones with a little
  3831. * padding where needed. I will not do that JUST yet. In general it will
  3832. * not be possible to load an image with large pages into a CSL that only
  3833. * has small ones - eg there might be some vector that just would not fit
  3834. * in the small page size. Even discounting that worry rearranging the
  3835. * heap to allow for the discontinuities at the smaller page granularity would
  3836. * be pretty painful. Again in the limit something very much akin to the
  3837. * normal garbage collector could probably do it if it ever became really
  3838. * necessary.
  3839. */
  3840. if (old_page_bits != PAGE_BITS)
  3841. { term_printf("\n+++ The checkpoint file was made on a machine\n");
  3842. term_printf("where CSL had been configured with a different page\n");
  3843. term_printf("size. It is not usable with this version.\n");
  3844. my_exit(EXIT_FAILURE);
  3845. }
  3846. /* The saved value of NIL is not needed in this case */
  3847. }
  3848. else
  3849. {
  3850. for (i=first_nil_offset; i<last_nil_offset; i++)
  3851. BASE[i] = nil;
  3852. copy_out_of_nilseg(NO);
  3853. }
  3854. stacklimit = &stack[stack_segsize*CSL_PAGE_SIZE/4-200];
  3855. /* allow some slop at end */
  3856. byteflip = 0x56780000 |
  3857. ((int32)current_fp_rep & ~FP_WORD_ORDER) |
  3858. (((int32)PAGE_BITS) << 8);
  3859. native_pages_changed = 0;
  3860. if (restartp) warm_setup();
  3861. else cold_setup();
  3862. if (init_flags & INIT_QUIET) Lverbos(nil, fixnum_of_int(1));
  3863. if (init_flags & INIT_VERBOSE) Lverbos(nil, fixnum_of_int(3));
  3864. #ifndef HOLD_BACK_MEMORY
  3865. /*
  3866. * Here I grab more memory (if I am allowed to) until the proportion of the
  3867. * heap active at the end of garbage collection is less than 1/2. If the
  3868. * attempt to grab more memory fails I clear the bit in init_flags that
  3869. * allows me to try to expand, so I will not waste time again. If
  3870. * HOLD_BACK_MEMORY was asserted (for machines where grabbing all seemingly
  3871. * available memory may cause a crash) I do not try this operation. The
  3872. * aim of keeping the heap less than half full is an heuristic and could be
  3873. * adjusted on the basis of experience with this code.
  3874. */
  3875. if (init_flags & INIT_EXPANDABLE)
  3876. { int32 more = heap_pages_count + vheap_pages_count +
  3877. bps_pages_count + native_pages_count;
  3878. more = 3 *more - pages_count;
  3879. while (more-- > 0)
  3880. { void *page = (void *)my_malloc_1((size_t)(CSL_PAGE_SIZE + 16));
  3881. /*
  3882. * CF the code in gc.c -- I can still use my_malloc_1 here, which makes this
  3883. * code just a tiny bit safer.
  3884. */
  3885. intxx pun = (intxx)page;
  3886. intxx pun1 = (intxx)((char *)page + CSL_PAGE_SIZE + 16);
  3887. if ((pun ^ pun1) < 0) page = NULL;
  3888. #ifdef ADDRESS_SIGN_UNKNOWN
  3889. if ((pun + address_sign) < 0) page = NULL;
  3890. #else
  3891. #ifdef ADDRESSES_HAVE_TOP_BIT_SET
  3892. if (pun > 0) page = NULL;
  3893. #else
  3894. if (pun < 0) page = NULL;
  3895. #endif
  3896. #endif
  3897. if (page == NULL)
  3898. { init_flags &= ~INIT_EXPANDABLE;
  3899. break;
  3900. }
  3901. else pages[pages_count++] = page;
  3902. }
  3903. }
  3904. #endif
  3905. {
  3906. int32 w = 0;
  3907. #ifndef NO_COPYING_GC
  3908. /*
  3909. * I will make the first garbage collection a copying one if the heap is
  3910. * at most 25% full, or a sliding one if it is more full than that.
  3911. */
  3912. w = heap_pages_count + vheap_pages_count +
  3913. bps_pages_count + native_pages_count;
  3914. gc_method_is_copying = (pages_count > 3*w);
  3915. #endif
  3916. /*
  3917. * The total store allocated is that used plus that free, including the
  3918. * page set aside for the Lisp stack.
  3919. */
  3920. if (init_flags & INIT_VERBOSE)
  3921. term_printf("Memory allocation: %ld bytes\n",
  3922. (long)CSL_PAGE_SIZE*(pages_count+w+1));
  3923. }
  3924. #ifdef MEMORY_TRACE
  3925. #ifndef CHECK_ONLY
  3926. memory_comment(15);
  3927. #endif
  3928. #endif
  3929. return;
  3930. }
  3931. void copy_into_nilseg(int fg)
  3932. {
  3933. int i;
  3934. Lisp_Object nil = C_nil;
  3935. #ifdef NILSEG_EXTERNS
  3936. if (fg) /* move non list bases too */
  3937. { *(unsigned32 *)&BASE[12] = byteflip;
  3938. BASE[13] = codefringe;
  3939. *(Lisp_Object volatile *)&BASE[14] = codelimit;
  3940. /*
  3941. * The messing around here is to ensure that on 64-bit architectures
  3942. * stacklimit is kept properly aligned.
  3943. */
  3944. #ifdef COMMON
  3945. *(Lisp_Object * volatile *)&BASE[16] = stacklimit;
  3946. #else
  3947. *(Lisp_Object * volatile *)&BASE[15] = stacklimit;
  3948. #endif
  3949. BASE[18] = fringe;
  3950. *(Lisp_Object volatile *)&BASE[19] = heaplimit;
  3951. *(Lisp_Object volatile *)&BASE[20] = vheaplimit;
  3952. BASE[21] = vfringe;
  3953. *(unsigned32 *)&BASE[22] = miscflags;
  3954. *(int32 *)&BASE[24] = nwork;
  3955. *(int32 *)&BASE[25] = exit_reason;
  3956. *(int32 *)&BASE[26] = exit_count;
  3957. *(unsigned32 *)&BASE[27] = gensym_ser;
  3958. *(unsigned32 *)&BASE[28] = print_precision;
  3959. *(int32 *)&BASE[29] = current_modulus;
  3960. *(int32 *)&BASE[30] = fastget_size;
  3961. *(int32 *)&BASE[31] = package_bits;
  3962. }
  3963. /*
  3964. * Entries 50 and 51 are used for chains of hash tables, and so get
  3965. * very special individual treatment.
  3966. */
  3967. BASE[52] = current_package;
  3968. BASE[53] = B_reg;
  3969. BASE[54] = codevec;
  3970. BASE[55] = litvec;
  3971. BASE[56] = exit_tag;
  3972. BASE[57] = exit_value;
  3973. BASE[58] = catch_tags;
  3974. BASE[59] = lisp_package;
  3975. BASE[60] = boffo;
  3976. BASE[61] = charvec;
  3977. BASE[62] = sys_hash_table;
  3978. BASE[63] = help_index;
  3979. BASE[64] = gensym_base;
  3980. BASE[65] = err_table;
  3981. BASE[66] = supervisor;
  3982. BASE[67] = startfn;
  3983. BASE[68] = faslvec;
  3984. BASE[69] = tracedfn;
  3985. BASE[70] = prompt_thing;
  3986. BASE[71] = faslgensyms;
  3987. BASE[72] = cl_symbols;
  3988. BASE[73] = active_stream;
  3989. BASE[74] = current_module;
  3990. BASE[90] = append_symbol;
  3991. BASE[91] = applyhook;
  3992. BASE[92] = cfunarg;
  3993. BASE[93] = comma_at_symbol;
  3994. BASE[94] = comma_symbol;
  3995. BASE[95] = compiler_symbol;
  3996. BASE[96] = comp_symbol;
  3997. BASE[97] = cons_symbol;
  3998. BASE[98] = echo_symbol;
  3999. BASE[99] = emsg_star;
  4000. BASE[100] = evalhook;
  4001. BASE[101] = eval_symbol;
  4002. BASE[102] = expr_symbol;
  4003. BASE[103] = features_symbol;
  4004. BASE[104] = fexpr_symbol;
  4005. BASE[105] = funarg;
  4006. BASE[106] = function_symbol;
  4007. BASE[107] = lambda;
  4008. BASE[108] = lisp_true;
  4009. BASE[109] = lower_symbol;
  4010. BASE[110] = macroexpand_hook;
  4011. BASE[111] = macro_symbol;
  4012. BASE[112] = opt_key;
  4013. BASE[113] = prinl_symbol;
  4014. BASE[114] = progn_symbol;
  4015. BASE[115] = quote_symbol;
  4016. BASE[116] = raise_symbol;
  4017. BASE[117] = redef_msg;
  4018. BASE[118] = rest_key;
  4019. BASE[119] = savedef;
  4020. BASE[120] = string_char_sym;
  4021. BASE[121] = unset_var;
  4022. BASE[122] = work_symbol;
  4023. BASE[123] = lex_words;
  4024. BASE[124] = get_counts;
  4025. BASE[125] = fastget_names;
  4026. BASE[126] = input_libraries;
  4027. BASE[127] = output_library;
  4028. BASE[128] = current_file;
  4029. BASE[129] = break_function;
  4030. BASE[130] = lisp_work_stream;
  4031. BASE[131] = lisp_standard_output;
  4032. BASE[132] = lisp_standard_input;
  4033. BASE[133] = lisp_debug_io;
  4034. BASE[134] = lisp_error_output;
  4035. BASE[135] = lisp_query_io;
  4036. BASE[136] = lisp_terminal_io;
  4037. BASE[137] = lisp_trace_output;
  4038. BASE[138] = standard_output;
  4039. BASE[139] = standard_input;
  4040. BASE[140] = debug_io;
  4041. BASE[141] = error_output;
  4042. BASE[142] = query_io;
  4043. BASE[143] = terminal_io;
  4044. BASE[144] = trace_output;
  4045. BASE[145] = fasl_stream;
  4046. BASE[146] = native_code;
  4047. BASE[147] = native_symbol;
  4048. BASE[148] = traceprint_symbol;
  4049. BASE[149] = loadsource_symbol;
  4050. BASE[150] = hankaku_symbol;
  4051. #ifdef COMMON
  4052. BASE[170] = keyword_package;
  4053. BASE[171] = all_packages;
  4054. BASE[172] = package_symbol;
  4055. BASE[173] = internal_symbol;
  4056. BASE[174] = external_symbol;
  4057. BASE[175] = inherited_symbol;
  4058. BASE[176] = key_key;
  4059. BASE[177] = allow_other_keys;
  4060. BASE[178] = aux_key;
  4061. BASE[179] = format_symbol;
  4062. BASE[180] = expand_def_symbol;
  4063. BASE[181] = allow_key_key;
  4064. BASE[182] = declare_symbol;
  4065. BASE[183] = special_symbol;
  4066. #endif
  4067. for (i=0; i<=50; i++)
  4068. BASE[work_0_offset+i] = workbase[i];
  4069. #endif /* NILSEG_EXTERNS */
  4070. BASE[190] = user_base_0;
  4071. BASE[191] = user_base_1;
  4072. BASE[192] = user_base_2;
  4073. BASE[193] = user_base_3;
  4074. BASE[194] = user_base_4;
  4075. BASE[195] = user_base_5;
  4076. BASE[196] = user_base_6;
  4077. BASE[197] = user_base_7;
  4078. BASE[198] = user_base_8;
  4079. BASE[199] = user_base_9;
  4080. }
  4081. void copy_out_of_nilseg(int fg)
  4082. {
  4083. int i;
  4084. Lisp_Object nil = C_nil;
  4085. #ifdef NILSEG_EXTERNS
  4086. if (fg)
  4087. {
  4088. byteflip = *(unsigned32 *)&BASE[12];
  4089. codefringe = BASE[13];
  4090. codelimit = *(Lisp_Object volatile *)&BASE[14];
  4091. #ifdef COMMON
  4092. stacklimit = *(Lisp_Object *volatile *)&BASE[16];
  4093. #else
  4094. stacklimit = *(Lisp_Object *volatile *)&BASE[15];
  4095. #endif
  4096. fringe = BASE[18];
  4097. heaplimit = *(Lisp_Object volatile *)&BASE[19];
  4098. vheaplimit = *(Lisp_Object volatile *)&BASE[20];
  4099. vfringe = BASE[21];
  4100. miscflags = *(unsigned32 *)&BASE[22];
  4101. nwork = *(int32 *)&BASE[24];
  4102. exit_reason = *(int32 *)&BASE[25];
  4103. exit_count = *(int32 *)&BASE[26];
  4104. gensym_ser = *(unsigned32 *)&BASE[27];
  4105. print_precision = *(unsigned32 *)&BASE[28];
  4106. current_modulus = *(int32 *)&BASE[29];
  4107. fastget_size = *(int32 *)&BASE[30];
  4108. package_bits = *(int32 *)&BASE[31];
  4109. }
  4110. current_package = BASE[52];
  4111. B_reg = BASE[53];
  4112. codevec = BASE[54];
  4113. litvec = BASE[55];
  4114. exit_tag = BASE[56];
  4115. exit_value = BASE[57];
  4116. catch_tags = BASE[58];
  4117. lisp_package = BASE[59];
  4118. boffo = BASE[60];
  4119. charvec = BASE[61];
  4120. sys_hash_table = BASE[62];
  4121. help_index = BASE[63];
  4122. gensym_base = BASE[64];
  4123. err_table = BASE[65];
  4124. supervisor = BASE[66];
  4125. startfn = BASE[67];
  4126. faslvec = BASE[68];
  4127. tracedfn = BASE[69];
  4128. prompt_thing = BASE[70];
  4129. faslgensyms = BASE[71];
  4130. cl_symbols = BASE[72];
  4131. active_stream = BASE[73];
  4132. current_module = BASE[74];
  4133. append_symbol = BASE[90];
  4134. applyhook = BASE[91];
  4135. cfunarg = BASE[92];
  4136. comma_at_symbol = BASE[93];
  4137. comma_symbol = BASE[94];
  4138. compiler_symbol = BASE[95];
  4139. comp_symbol = BASE[96];
  4140. cons_symbol = BASE[97];
  4141. echo_symbol = BASE[98];
  4142. emsg_star = BASE[99];
  4143. evalhook = BASE[100];
  4144. eval_symbol = BASE[101];
  4145. expr_symbol = BASE[102];
  4146. features_symbol = BASE[103];
  4147. fexpr_symbol = BASE[104];
  4148. funarg = BASE[105];
  4149. function_symbol = BASE[106];
  4150. lambda = BASE[107];
  4151. lisp_true = BASE[108];
  4152. lower_symbol = BASE[109];
  4153. macroexpand_hook = BASE[110];
  4154. macro_symbol = BASE[111];
  4155. opt_key = BASE[112];
  4156. prinl_symbol = BASE[113];
  4157. progn_symbol = BASE[114];
  4158. quote_symbol = BASE[115];
  4159. raise_symbol = BASE[116];
  4160. redef_msg = BASE[117];
  4161. rest_key = BASE[118];
  4162. savedef = BASE[119];
  4163. string_char_sym = BASE[120];
  4164. unset_var = BASE[121];
  4165. work_symbol = BASE[122];
  4166. lex_words = BASE[123];
  4167. get_counts = BASE[124];
  4168. fastget_names = BASE[125];
  4169. input_libraries = BASE[126];
  4170. output_library = BASE[127];
  4171. current_file = BASE[128];
  4172. break_function = BASE[129];
  4173. lisp_work_stream = BASE[130];
  4174. lisp_standard_output = BASE[131];
  4175. lisp_standard_input = BASE[132];
  4176. lisp_debug_io = BASE[133];
  4177. lisp_error_output = BASE[134];
  4178. lisp_query_io = BASE[135];
  4179. lisp_terminal_io = BASE[136];
  4180. lisp_trace_output = BASE[137];
  4181. standard_output = BASE[138];
  4182. standard_input = BASE[139];
  4183. debug_io = BASE[140];
  4184. error_output = BASE[141];
  4185. query_io = BASE[142];
  4186. terminal_io = BASE[143];
  4187. trace_output = BASE[144];
  4188. fasl_stream = BASE[145];
  4189. native_code = BASE[146];
  4190. native_symbol = BASE[147];
  4191. traceprint_symbol = BASE[148];
  4192. loadsource_symbol = BASE[149];
  4193. hankaku_symbol = BASE[150];
  4194. #ifdef COMMON
  4195. keyword_package = BASE[170];
  4196. all_packages = BASE[171];
  4197. package_symbol = BASE[172];
  4198. internal_symbol = BASE[173];
  4199. external_symbol = BASE[174];
  4200. inherited_symbol = BASE[175];
  4201. key_key = BASE[176];
  4202. allow_other_keys = BASE[177];
  4203. aux_key = BASE[178];
  4204. format_symbol = BASE[179];
  4205. expand_def_symbol = BASE[180];
  4206. allow_key_key = BASE[181];
  4207. declare_symbol = BASE[182];
  4208. special_symbol = BASE[183];
  4209. #endif
  4210. for (i = 0; i<=50; i++)
  4211. workbase[i] = BASE[work_0_offset+i];
  4212. #endif /* NILSEG_EXTERNS */
  4213. user_base_0 = BASE[190];
  4214. user_base_1 = BASE[191];
  4215. user_base_2 = BASE[192];
  4216. user_base_3 = BASE[193];
  4217. user_base_4 = BASE[194];
  4218. user_base_5 = BASE[195];
  4219. user_base_6 = BASE[196];
  4220. user_base_7 = BASE[197];
  4221. user_base_8 = BASE[198];
  4222. user_base_9 = BASE[199];
  4223. }
  4224. /* end of restart.c */