traps.c 91 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348
  1. /* CRIS exception, interrupt, and trap (EIT) support
  2. Copyright (C) 2004-2022 Free Software Foundation, Inc.
  3. Contributed by Axis Communications.
  4. This file is part of the GNU simulators.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /* This must come before any other includes. */
  16. #include "defs.h"
  17. #include "portability.h"
  18. #include "sim-main.h"
  19. #include "sim-syscall.h"
  20. #include "sim-options.h"
  21. #include "sim-signal.h"
  22. #include "sim/callback.h"
  23. #include "bfd.h"
  24. /* FIXME: get rid of targ-vals.h usage everywhere else. */
  25. #include <stdlib.h>
  26. #include <stdarg.h>
  27. #include <errno.h>
  28. #ifdef HAVE_UNISTD_H
  29. #include <unistd.h>
  30. #endif
  31. #ifdef HAVE_FCNTL_H
  32. #include <fcntl.h>
  33. #endif
  34. #ifdef HAVE_SYS_PARAM_H
  35. #include <sys/param.h>
  36. #endif
  37. #ifdef HAVE_SYS_STAT_H
  38. #include <sys/stat.h>
  39. #endif
  40. /* For PATH_MAX, originally. */
  41. #ifdef HAVE_LIMITS_H
  42. #include <limits.h>
  43. #endif
  44. /* From ld/sysdep.h. */
  45. #ifdef PATH_MAX
  46. # define SIM_PATHMAX PATH_MAX
  47. #else
  48. # ifdef MAXPATHLEN
  49. # define SIM_PATHMAX MAXPATHLEN
  50. # else
  51. # define SIM_PATHMAX 1024
  52. # endif
  53. #endif
  54. /* The verbatim values are from asm-cris/unistd.h. */
  55. #define TARGET_SYS_exit 1
  56. #define TARGET_SYS_read 3
  57. #define TARGET_SYS_write 4
  58. #define TARGET_SYS_open 5
  59. #define TARGET_SYS_close 6
  60. #define TARGET_SYS_unlink 10
  61. #define TARGET_SYS_time 13
  62. #define TARGET_SYS_lseek 19
  63. #define TARGET_SYS_getpid 20
  64. #define TARGET_SYS_access 33
  65. #define TARGET_SYS_kill 37
  66. #define TARGET_SYS_rename 38
  67. #define TARGET_SYS_pipe 42
  68. #define TARGET_SYS_brk 45
  69. #define TARGET_SYS_ioctl 54
  70. #define TARGET_SYS_fcntl 55
  71. #define TARGET_SYS_getppid 64
  72. #define TARGET_SYS_setrlimit 75
  73. #define TARGET_SYS_gettimeofday 78
  74. #define TARGET_SYS_readlink 85
  75. #define TARGET_SYS_munmap 91
  76. #define TARGET_SYS_truncate 92
  77. #define TARGET_SYS_ftruncate 93
  78. #define TARGET_SYS_socketcall 102
  79. #define TARGET_SYS_stat 106
  80. #define TARGET_SYS_fstat 108
  81. #define TARGET_SYS_wait4 114
  82. #define TARGET_SYS_sigreturn 119
  83. #define TARGET_SYS_clone 120
  84. #define TARGET_SYS_uname 122
  85. #define TARGET_SYS_mprotect 125
  86. #define TARGET_SYS_llseek 140
  87. #define TARGET_SYS_writev 146
  88. #define TARGET_SYS__sysctl 149
  89. #define TARGET_SYS_sched_setparam 154
  90. #define TARGET_SYS_sched_getparam 155
  91. #define TARGET_SYS_sched_setscheduler 156
  92. #define TARGET_SYS_sched_getscheduler 157
  93. #define TARGET_SYS_sched_yield 158
  94. #define TARGET_SYS_sched_get_priority_max 159
  95. #define TARGET_SYS_sched_get_priority_min 160
  96. #define TARGET_SYS_mremap 163
  97. #define TARGET_SYS_poll 168
  98. #define TARGET_SYS_rt_sigaction 174
  99. #define TARGET_SYS_rt_sigprocmask 175
  100. #define TARGET_SYS_rt_sigsuspend 179
  101. #define TARGET_SYS_getcwd 183
  102. #define TARGET_SYS_ugetrlimit 191
  103. #define TARGET_SYS_mmap2 192
  104. #define TARGET_SYS_stat64 195
  105. #define TARGET_SYS_lstat64 196
  106. #define TARGET_SYS_fstat64 197
  107. #define TARGET_SYS_geteuid32 201
  108. #define TARGET_SYS_getuid32 199
  109. #define TARGET_SYS_getegid32 202
  110. #define TARGET_SYS_getgid32 200
  111. #define TARGET_SYS_fcntl64 221
  112. #define TARGET_SYS_set_thread_area 243
  113. #define TARGET_SYS_exit_group 252
  114. #define TARGET_PROT_READ 0x1
  115. #define TARGET_PROT_WRITE 0x2
  116. #define TARGET_PROT_EXEC 0x4
  117. #define TARGET_PROT_NONE 0x0
  118. #define TARGET_MAP_SHARED 0x01
  119. #define TARGET_MAP_PRIVATE 0x02
  120. #define TARGET_MAP_TYPE 0x0f
  121. #define TARGET_MAP_FIXED 0x10
  122. #define TARGET_MAP_ANONYMOUS 0x20
  123. #define TARGET_MAP_DENYWRITE 0x800
  124. #define TARGET_CTL_KERN 1
  125. #define TARGET_CTL_VM 2
  126. #define TARGET_CTL_NET 3
  127. #define TARGET_CTL_PROC 4
  128. #define TARGET_CTL_FS 5
  129. #define TARGET_CTL_DEBUG 6
  130. #define TARGET_CTL_DEV 7
  131. #define TARGET_CTL_BUS 8
  132. #define TARGET_CTL_ABI 9
  133. #define TARGET_CTL_KERN_VERSION 4
  134. /* linux/mman.h */
  135. #define TARGET_MREMAP_MAYMOVE 1
  136. #define TARGET_MREMAP_FIXED 2
  137. #define TARGET_TCGETS 0x5401
  138. #define TARGET_UTSNAME "#7 Thu Jan 1 00:00:00 MET 2009"
  139. /* Seconds since 1970-01-01 to the above date + 10 minutes;
  140. 'date -d "Thu Jan 1 00:00:10 MET 2009" +%s'. */
  141. #define TARGET_EPOCH 1230764410
  142. /* Milliseconds since start of run. We use the number of syscalls to
  143. avoid introducing noise in the execution time. */
  144. #define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
  145. /* Seconds as in time(2). */
  146. #define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
  147. #define TARGET_SCHED_OTHER 0
  148. #define TARGET_RLIMIT_STACK 3
  149. #define TARGET_RLIMIT_NOFILE 7
  150. #define SIM_TARGET_MAX_THREADS 64
  151. #define SIM_MAX_ALLOC_CHUNK (512*1024*1024)
  152. /* From linux/sched.h. */
  153. #define TARGET_CSIGNAL 0x000000ff
  154. #define TARGET_CLONE_VM 0x00000100
  155. #define TARGET_CLONE_FS 0x00000200
  156. #define TARGET_CLONE_FILES 0x00000400
  157. #define TARGET_CLONE_SIGHAND 0x00000800
  158. #define TARGET_CLONE_PID 0x00001000
  159. #define TARGET_CLONE_PTRACE 0x00002000
  160. #define TARGET_CLONE_VFORK 0x00004000
  161. #define TARGET_CLONE_PARENT 0x00008000
  162. #define TARGET_CLONE_THREAD 0x00010000
  163. #define TARGET_CLONE_SIGNAL (TARGET_CLONE_SIGHAND | TARGET_CLONE_THREAD)
  164. /* From asm-cris/poll.h. */
  165. #define TARGET_POLLIN 1
  166. /* From asm-cris/signal.h. */
  167. #define TARGET_SIG_BLOCK 0
  168. #define TARGET_SIG_UNBLOCK 1
  169. #define TARGET_SIG_SETMASK 2
  170. #define TARGET_SIG_DFL 0
  171. #define TARGET_SIG_IGN 1
  172. #define TARGET_SIG_ERR ((USI)-1)
  173. #define TARGET_SIGHUP 1
  174. #define TARGET_SIGINT 2
  175. #define TARGET_SIGQUIT 3
  176. #define TARGET_SIGILL 4
  177. #define TARGET_SIGTRAP 5
  178. #define TARGET_SIGABRT 6
  179. #define TARGET_SIGIOT 6
  180. #define TARGET_SIGBUS 7
  181. #define TARGET_SIGFPE 8
  182. #define TARGET_SIGKILL 9
  183. #define TARGET_SIGUSR1 10
  184. #define TARGET_SIGSEGV 11
  185. #define TARGET_SIGUSR2 12
  186. #define TARGET_SIGPIPE 13
  187. #define TARGET_SIGALRM 14
  188. #define TARGET_SIGTERM 15
  189. #define TARGET_SIGSTKFLT 16
  190. #define TARGET_SIGCHLD 17
  191. #define TARGET_SIGCONT 18
  192. #define TARGET_SIGSTOP 19
  193. #define TARGET_SIGTSTP 20
  194. #define TARGET_SIGTTIN 21
  195. #define TARGET_SIGTTOU 22
  196. #define TARGET_SIGURG 23
  197. #define TARGET_SIGXCPU 24
  198. #define TARGET_SIGXFSZ 25
  199. #define TARGET_SIGVTALRM 26
  200. #define TARGET_SIGPROF 27
  201. #define TARGET_SIGWINCH 28
  202. #define TARGET_SIGIO 29
  203. #define TARGET_SIGPOLL SIGIO
  204. /* Actually commented out in the kernel header. */
  205. #define TARGET_SIGLOST 29
  206. #define TARGET_SIGPWR 30
  207. #define TARGET_SIGSYS 31
  208. /* From include/asm-cris/signal.h. */
  209. #define TARGET_SA_NOCLDSTOP 0x00000001
  210. #define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
  211. #define TARGET_SA_SIGINFO 0x00000004
  212. #define TARGET_SA_ONSTACK 0x08000000
  213. #define TARGET_SA_RESTART 0x10000000
  214. #define TARGET_SA_NODEFER 0x40000000
  215. #define TARGET_SA_RESETHAND 0x80000000
  216. #define TARGET_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
  217. #define TARGET_SA_RESTORER 0x04000000
  218. /* From linux/wait.h. */
  219. #define TARGET_WNOHANG 1
  220. #define TARGET_WUNTRACED 2
  221. #define TARGET___WNOTHREAD 0x20000000
  222. #define TARGET___WALL 0x40000000
  223. #define TARGET___WCLONE 0x80000000
  224. /* From linux/limits.h. */
  225. #define TARGET_PIPE_BUF 4096
  226. /* From unistd.h. */
  227. #define TARGET_R_OK 4
  228. #define TARGET_W_OK 2
  229. #define TARGET_X_OK 1
  230. #define TARGET_F_OK 0
  231. static const char stat_map[] =
  232. "st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
  233. ":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
  234. ":space,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,4"
  235. ":st_ino,8";
  236. static const CB_TARGET_DEFS_MAP syscall_map[] =
  237. {
  238. { "open", CB_SYS_open, TARGET_SYS_open },
  239. { "close", CB_SYS_close, TARGET_SYS_close },
  240. { "read", CB_SYS_read, TARGET_SYS_read },
  241. { "write", CB_SYS_write, TARGET_SYS_write },
  242. { "lseek", CB_SYS_lseek, TARGET_SYS_lseek },
  243. { "unlink", CB_SYS_unlink, TARGET_SYS_unlink },
  244. { "getpid", CB_SYS_getpid, TARGET_SYS_getpid },
  245. { "fstat", CB_SYS_fstat, TARGET_SYS_fstat64 },
  246. { "lstat", CB_SYS_lstat, TARGET_SYS_lstat64 },
  247. { "stat", CB_SYS_stat, TARGET_SYS_stat64 },
  248. { "pipe", CB_SYS_pipe, TARGET_SYS_pipe },
  249. { "rename", CB_SYS_rename, TARGET_SYS_rename },
  250. { "truncate", CB_SYS_truncate, TARGET_SYS_truncate },
  251. { "ftruncate", CB_SYS_ftruncate, TARGET_SYS_ftruncate },
  252. { 0, -1, -1 }
  253. };
  254. /* An older, 32-bit-only stat mapping. */
  255. static const char stat32_map[] =
  256. "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2"
  257. ":st_gid,2:st_rdev,2:space,2:st_size,4:st_blksize,4:st_blocks,4"
  258. ":st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:space,12";
  259. /* Map for calls using the 32-bit struct stat. Primarily used by the
  260. newlib Linux mapping. */
  261. static const CB_TARGET_DEFS_MAP syscall_stat32_map[] =
  262. {
  263. { "fstat", CB_SYS_fstat, TARGET_SYS_fstat },
  264. { "stat", CB_SYS_stat, TARGET_SYS_stat },
  265. { 0, -1, -1 }
  266. };
  267. /* Giving the true value for the running sim process will lead to
  268. non-time-invariant behavior. */
  269. #define TARGET_PID 42
  270. /* Unfortunately, we don't get this from cris.cpu at the moment, and if
  271. we did, we'd still don't get a register number with the "16" offset. */
  272. #define TARGET_SRP_REGNUM (16+11)
  273. /* Extracted by applying
  274. awk '/^#define/ { printf "#ifdef %s\n { %s, %s },\n#endif\n", $2, $2, $3;}'
  275. on .../include/asm/errno.h in a GNU/Linux/CRIS installation and
  276. adjusting the synonyms. */
  277. static const CB_TARGET_DEFS_MAP errno_map[] =
  278. {
  279. #ifdef EPERM
  280. { "EPERM", EPERM, 1 },
  281. #endif
  282. #ifdef ENOENT
  283. { "ENOENT", ENOENT, 2 },
  284. #endif
  285. #ifdef ESRCH
  286. { "ESRCH", ESRCH, 3 },
  287. #endif
  288. #ifdef EINTR
  289. { "EINTR", EINTR, 4 },
  290. #endif
  291. #ifdef EIO
  292. { "EIO", EIO, 5 },
  293. #endif
  294. #ifdef ENXIO
  295. { "ENXIO", ENXIO, 6 },
  296. #endif
  297. #ifdef E2BIG
  298. { "E2BIG", E2BIG, 7 },
  299. #endif
  300. #ifdef ENOEXEC
  301. { "ENOEXEC", ENOEXEC, 8 },
  302. #endif
  303. #ifdef EBADF
  304. { "EBADF", EBADF, 9 },
  305. #endif
  306. #ifdef ECHILD
  307. { "ECHILD", ECHILD, 10 },
  308. #endif
  309. #ifdef EAGAIN
  310. { "EAGAIN", EAGAIN, 11 },
  311. #endif
  312. #ifdef ENOMEM
  313. { "ENOMEM", ENOMEM, 12 },
  314. #endif
  315. #ifdef EACCES
  316. { "EACCES", EACCES, 13 },
  317. #endif
  318. #ifdef EFAULT
  319. { "EFAULT", EFAULT, 14 },
  320. #endif
  321. #ifdef ENOTBLK
  322. { "ENOTBLK", ENOTBLK, 15 },
  323. #endif
  324. #ifdef EBUSY
  325. { "EBUSY", EBUSY, 16 },
  326. #endif
  327. #ifdef EEXIST
  328. { "EEXIST", EEXIST, 17 },
  329. #endif
  330. #ifdef EXDEV
  331. { "EXDEV", EXDEV, 18 },
  332. #endif
  333. #ifdef ENODEV
  334. { "ENODEV", ENODEV, 19 },
  335. #endif
  336. #ifdef ENOTDIR
  337. { "ENOTDIR", ENOTDIR, 20 },
  338. #endif
  339. #ifdef EISDIR
  340. { "EISDIR", EISDIR, 21 },
  341. #endif
  342. #ifdef EINVAL
  343. { "EINVAL", EINVAL, 22 },
  344. #endif
  345. #ifdef ENFILE
  346. { "ENFILE", ENFILE, 23 },
  347. #endif
  348. #ifdef EMFILE
  349. { "EMFILE", EMFILE, 24 },
  350. #endif
  351. #ifdef ENOTTY
  352. { "ENOTTY", ENOTTY, 25 },
  353. #endif
  354. #ifdef ETXTBSY
  355. { "ETXTBSY", ETXTBSY, 26 },
  356. #endif
  357. #ifdef EFBIG
  358. { "EFBIG", EFBIG, 27 },
  359. #endif
  360. #ifdef ENOSPC
  361. { "ENOSPC", ENOSPC, 28 },
  362. #endif
  363. #ifdef ESPIPE
  364. { "ESPIPE", ESPIPE, 29 },
  365. #endif
  366. #ifdef EROFS
  367. { "EROFS", EROFS, 30 },
  368. #endif
  369. #ifdef EMLINK
  370. { "EMLINK", EMLINK, 31 },
  371. #endif
  372. #ifdef EPIPE
  373. { "EPIPE", EPIPE, 32 },
  374. #endif
  375. #ifdef EDOM
  376. { "EDOM", EDOM, 33 },
  377. #endif
  378. #ifdef ERANGE
  379. { "ERANGE", ERANGE, 34 },
  380. #endif
  381. #ifdef EDEADLK
  382. { "EDEADLK", EDEADLK, 35 },
  383. #endif
  384. #ifdef ENAMETOOLONG
  385. { "ENAMETOOLONG", ENAMETOOLONG, 36 },
  386. #endif
  387. #ifdef ENOLCK
  388. { "ENOLCK", ENOLCK, 37 },
  389. #endif
  390. #ifdef ENOSYS
  391. { "ENOSYS", ENOSYS, 38 },
  392. #endif
  393. #ifdef ENOTEMPTY
  394. { "ENOTEMPTY", ENOTEMPTY, 39 },
  395. #endif
  396. #ifdef ELOOP
  397. { "ELOOP", ELOOP, 40 },
  398. #endif
  399. #ifdef EWOULDBLOCK
  400. { "EWOULDBLOCK", EWOULDBLOCK, 11 },
  401. #endif
  402. #ifdef ENOMSG
  403. { "ENOMSG", ENOMSG, 42 },
  404. #endif
  405. #ifdef EIDRM
  406. { "EIDRM", EIDRM, 43 },
  407. #endif
  408. #ifdef ECHRNG
  409. { "ECHRNG", ECHRNG, 44 },
  410. #endif
  411. #ifdef EL2NSYNC
  412. { "EL2NSYNC", EL2NSYNC, 45 },
  413. #endif
  414. #ifdef EL3HLT
  415. { "EL3HLT", EL3HLT, 46 },
  416. #endif
  417. #ifdef EL3RST
  418. { "EL3RST", EL3RST, 47 },
  419. #endif
  420. #ifdef ELNRNG
  421. { "ELNRNG", ELNRNG, 48 },
  422. #endif
  423. #ifdef EUNATCH
  424. { "EUNATCH", EUNATCH, 49 },
  425. #endif
  426. #ifdef ENOCSI
  427. { "ENOCSI", ENOCSI, 50 },
  428. #endif
  429. #ifdef EL2HLT
  430. { "EL2HLT", EL2HLT, 51 },
  431. #endif
  432. #ifdef EBADE
  433. { "EBADE", EBADE, 52 },
  434. #endif
  435. #ifdef EBADR
  436. { "EBADR", EBADR, 53 },
  437. #endif
  438. #ifdef EXFULL
  439. { "EXFULL", EXFULL, 54 },
  440. #endif
  441. #ifdef ENOANO
  442. { "ENOANO", ENOANO, 55 },
  443. #endif
  444. #ifdef EBADRQC
  445. { "EBADRQC", EBADRQC, 56 },
  446. #endif
  447. #ifdef EBADSLT
  448. { "EBADSLT", EBADSLT, 57 },
  449. #endif
  450. #ifdef EDEADLOCK
  451. { "EDEADLOCK", EDEADLOCK, 35 },
  452. #endif
  453. #ifdef EBFONT
  454. { "EBFONT", EBFONT, 59 },
  455. #endif
  456. #ifdef ENOSTR
  457. { "ENOSTR", ENOSTR, 60 },
  458. #endif
  459. #ifdef ENODATA
  460. { "ENODATA", ENODATA, 61 },
  461. #endif
  462. #ifdef ETIME
  463. { "ETIME", ETIME, 62 },
  464. #endif
  465. #ifdef ENOSR
  466. { "ENOSR", ENOSR, 63 },
  467. #endif
  468. #ifdef ENONET
  469. { "ENONET", ENONET, 64 },
  470. #endif
  471. #ifdef ENOPKG
  472. { "ENOPKG", ENOPKG, 65 },
  473. #endif
  474. #ifdef EREMOTE
  475. { "EREMOTE", EREMOTE, 66 },
  476. #endif
  477. #ifdef ENOLINK
  478. { "ENOLINK", ENOLINK, 67 },
  479. #endif
  480. #ifdef EADV
  481. { "EADV", EADV, 68 },
  482. #endif
  483. #ifdef ESRMNT
  484. { "ESRMNT", ESRMNT, 69 },
  485. #endif
  486. #ifdef ECOMM
  487. { "ECOMM", ECOMM, 70 },
  488. #endif
  489. #ifdef EPROTO
  490. { "EPROTO", EPROTO, 71 },
  491. #endif
  492. #ifdef EMULTIHOP
  493. { "EMULTIHOP", EMULTIHOP, 72 },
  494. #endif
  495. #ifdef EDOTDOT
  496. { "EDOTDOT", EDOTDOT, 73 },
  497. #endif
  498. #ifdef EBADMSG
  499. { "EBADMSG", EBADMSG, 74 },
  500. #endif
  501. #ifdef EOVERFLOW
  502. { "EOVERFLOW", EOVERFLOW, 75 },
  503. #endif
  504. #ifdef ENOTUNIQ
  505. { "ENOTUNIQ", ENOTUNIQ, 76 },
  506. #endif
  507. #ifdef EBADFD
  508. { "EBADFD", EBADFD, 77 },
  509. #endif
  510. #ifdef EREMCHG
  511. { "EREMCHG", EREMCHG, 78 },
  512. #endif
  513. #ifdef ELIBACC
  514. { "ELIBACC", ELIBACC, 79 },
  515. #endif
  516. #ifdef ELIBBAD
  517. { "ELIBBAD", ELIBBAD, 80 },
  518. #endif
  519. #ifdef ELIBSCN
  520. { "ELIBSCN", ELIBSCN, 81 },
  521. #endif
  522. #ifdef ELIBMAX
  523. { "ELIBMAX", ELIBMAX, 82 },
  524. #endif
  525. #ifdef ELIBEXEC
  526. { "ELIBEXEC", ELIBEXEC, 83 },
  527. #endif
  528. #ifdef EILSEQ
  529. { "EILSEQ", EILSEQ, 84 },
  530. #endif
  531. #ifdef ERESTART
  532. { "ERESTART", ERESTART, 85 },
  533. #endif
  534. #ifdef ESTRPIPE
  535. { "ESTRPIPE", ESTRPIPE, 86 },
  536. #endif
  537. #ifdef EUSERS
  538. { "EUSERS", EUSERS, 87 },
  539. #endif
  540. #ifdef ENOTSOCK
  541. { "ENOTSOCK", ENOTSOCK, 88 },
  542. #endif
  543. #ifdef EDESTADDRREQ
  544. { "EDESTADDRREQ", EDESTADDRREQ, 89 },
  545. #endif
  546. #ifdef EMSGSIZE
  547. { "EMSGSIZE", EMSGSIZE, 90 },
  548. #endif
  549. #ifdef EPROTOTYPE
  550. { "EPROTOTYPE", EPROTOTYPE, 91 },
  551. #endif
  552. #ifdef ENOPROTOOPT
  553. { "ENOPROTOOPT", ENOPROTOOPT, 92 },
  554. #endif
  555. #ifdef EPROTONOSUPPORT
  556. { "EPROTONOSUPPORT", EPROTONOSUPPORT, 93 },
  557. #endif
  558. #ifdef ESOCKTNOSUPPORT
  559. { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, 94 },
  560. #endif
  561. #ifdef EOPNOTSUPP
  562. { "EOPNOTSUPP", EOPNOTSUPP, 95 },
  563. #endif
  564. #ifdef EPFNOSUPPORT
  565. { "EPFNOSUPPORT", EPFNOSUPPORT, 96 },
  566. #endif
  567. #ifdef EAFNOSUPPORT
  568. { "EAFNOSUPPORT", EAFNOSUPPORT, 97 },
  569. #endif
  570. #ifdef EADDRINUSE
  571. { "EADDRINUSE", EADDRINUSE, 98 },
  572. #endif
  573. #ifdef EADDRNOTAVAIL
  574. { "EADDRNOTAVAIL", EADDRNOTAVAIL, 99 },
  575. #endif
  576. #ifdef ENETDOWN
  577. { "ENETDOWN", ENETDOWN, 100 },
  578. #endif
  579. #ifdef ENETUNREACH
  580. { "ENETUNREACH", ENETUNREACH, 101 },
  581. #endif
  582. #ifdef ENETRESET
  583. { "ENETRESET", ENETRESET, 102 },
  584. #endif
  585. #ifdef ECONNABORTED
  586. { "ECONNABORTED", ECONNABORTED, 103 },
  587. #endif
  588. #ifdef ECONNRESET
  589. { "ECONNRESET", ECONNRESET, 104 },
  590. #endif
  591. #ifdef ENOBUFS
  592. { "ENOBUFS", ENOBUFS, 105 },
  593. #endif
  594. #ifdef EISCONN
  595. { "EISCONN", EISCONN, 106 },
  596. #endif
  597. #ifdef ENOTCONN
  598. { "ENOTCONN", ENOTCONN, 107 },
  599. #endif
  600. #ifdef ESHUTDOWN
  601. { "ESHUTDOWN", ESHUTDOWN, 108 },
  602. #endif
  603. #ifdef ETOOMANYREFS
  604. { "ETOOMANYREFS", ETOOMANYREFS, 109 },
  605. #endif
  606. #ifdef ETIMEDOUT
  607. { "ETIMEDOUT", ETIMEDOUT, 110 },
  608. #endif
  609. #ifdef ECONNREFUSED
  610. { "ECONNREFUSED", ECONNREFUSED, 111 },
  611. #endif
  612. #ifdef EHOSTDOWN
  613. { "EHOSTDOWN", EHOSTDOWN, 112 },
  614. #endif
  615. #ifdef EHOSTUNREACH
  616. { "EHOSTUNREACH", EHOSTUNREACH, 113 },
  617. #endif
  618. #ifdef EALREADY
  619. { "EALREADY", EALREADY, 114 },
  620. #endif
  621. #ifdef EINPROGRESS
  622. { "EINPROGRESS", EINPROGRESS, 115 },
  623. #endif
  624. #ifdef ESTALE
  625. { "ESTALE", ESTALE, 116 },
  626. #endif
  627. #ifdef EUCLEAN
  628. { "EUCLEAN", EUCLEAN, 117 },
  629. #endif
  630. #ifdef ENOTNAM
  631. { "ENOTNAM", ENOTNAM, 118 },
  632. #endif
  633. #ifdef ENAVAIL
  634. { "ENAVAIL", ENAVAIL, 119 },
  635. #endif
  636. #ifdef EISNAM
  637. { "EISNAM", EISNAM, 120 },
  638. #endif
  639. #ifdef EREMOTEIO
  640. { "EREMOTEIO", EREMOTEIO, 121 },
  641. #endif
  642. #ifdef EDQUOT
  643. { "EDQUOT", EDQUOT, 122 },
  644. #endif
  645. #ifdef ENOMEDIUM
  646. { "ENOMEDIUM", ENOMEDIUM, 123 },
  647. #endif
  648. #ifdef EMEDIUMTYPE
  649. { "EMEDIUMTYPE", EMEDIUMTYPE, 124 },
  650. #endif
  651. { 0, 0, 0 }
  652. };
  653. /* Extracted by applying
  654. perl -ne 'if ($_ =~ /^#define/) { split;
  655. printf "#ifdef $_[1]\n { %s, 0x%x },\n#endif\n",
  656. $_[1], $_[2] =~ /^0/ ? oct($_[2]) : $_[2];}'
  657. on pertinent parts of .../include/asm/fcntl.h in a GNU/Linux/CRIS
  658. installation and removing synonyms and unnecessary items. Don't
  659. forget the end-marker. */
  660. /* These we treat specially, as they're used in the fcntl F_GETFL
  661. syscall. For consistency, open_map is also manually edited to use
  662. these macros. */
  663. #define TARGET_O_ACCMODE 0x3
  664. #define TARGET_O_RDONLY 0x0
  665. #define TARGET_O_WRONLY 0x1
  666. static const CB_TARGET_DEFS_MAP open_map[] = {
  667. #ifdef O_ACCMODE
  668. { "O_ACCMODE", O_ACCMODE, TARGET_O_ACCMODE },
  669. #endif
  670. #ifdef O_RDONLY
  671. { "O_RDONLY", O_RDONLY, TARGET_O_RDONLY },
  672. #endif
  673. #ifdef O_WRONLY
  674. { "O_WRONLY", O_WRONLY, TARGET_O_WRONLY },
  675. #endif
  676. #ifdef O_RDWR
  677. { "O_RDWR", O_RDWR, 0x2 },
  678. #endif
  679. #ifdef O_CREAT
  680. { "O_CREAT", O_CREAT, 0x40 },
  681. #endif
  682. #ifdef O_EXCL
  683. { "O_EXCL", O_EXCL, 0x80 },
  684. #endif
  685. #ifdef O_NOCTTY
  686. { "O_NOCTTY", O_NOCTTY, 0x100 },
  687. #endif
  688. #ifdef O_TRUNC
  689. { "O_TRUNC", O_TRUNC, 0x200 },
  690. #endif
  691. #ifdef O_APPEND
  692. { "O_APPEND", O_APPEND, 0x400 },
  693. #endif
  694. #ifdef O_NONBLOCK
  695. { "O_NONBLOCK", O_NONBLOCK, 0x800 },
  696. #endif
  697. #ifdef O_NDELAY
  698. { "O_NDELAY", O_NDELAY, 0x0 },
  699. #endif
  700. #ifdef O_SYNC
  701. { "O_SYNC", O_SYNC, 0x1000 },
  702. #endif
  703. #ifdef FASYNC
  704. { "FASYNC", FASYNC, 0x2000 },
  705. #endif
  706. #ifdef O_DIRECT
  707. { "O_DIRECT", O_DIRECT, 0x4000 },
  708. #endif
  709. #ifdef O_LARGEFILE
  710. { "O_LARGEFILE", O_LARGEFILE, 0x8000 },
  711. #endif
  712. #ifdef O_DIRECTORY
  713. { "O_DIRECTORY", O_DIRECTORY, 0x10000 },
  714. #endif
  715. #ifdef O_NOFOLLOW
  716. { "O_NOFOLLOW", O_NOFOLLOW, 0x20000 },
  717. #endif
  718. { 0, -1, -1 }
  719. };
  720. /* Let's be less drastic and more traceable. FIXME: mark as noreturn. */
  721. #define abort() \
  722. sim_io_error (sd, "simulator unhandled condition at %s:%d", \
  723. __FUNCTION__, __LINE__)
  724. /* Needed for the cris_pipe_nonempty and cris_pipe_empty syscalls. */
  725. static SIM_CPU *current_cpu_for_cb_callback;
  726. static USI create_map (SIM_DESC, struct cris_sim_mmapped_page **,
  727. USI addr, USI len);
  728. static USI unmap_pages (SIM_DESC, struct cris_sim_mmapped_page **,
  729. USI addr, USI len);
  730. static USI is_mapped (SIM_DESC, struct cris_sim_mmapped_page **,
  731. USI addr, USI len);
  732. static void dump_statistics (SIM_CPU *current_cpu);
  733. static void make_first_thread (SIM_CPU *current_cpu);
  734. /* When we risk running self-modified code (as in trampolines), this is
  735. called from special-case insns. The silicon CRIS CPU:s have enough
  736. cache snooping implemented making this a simulator-only issue. Tests:
  737. gcc.c-torture/execute/931002-1.c execution, -O3 -g
  738. gcc.c-torture/execute/931002-1.c execution, -O3 -fomit-frame-pointer. */
  739. void
  740. cris_flush_simulator_decode_cache (SIM_CPU *current_cpu,
  741. USI pc ATTRIBUTE_UNUSED)
  742. {
  743. SIM_DESC sd = CPU_STATE (current_cpu);
  744. #if WITH_SCACHE
  745. if (USING_SCACHE_P (sd))
  746. scache_flush_cpu (current_cpu);
  747. #endif
  748. }
  749. /* Output statistics at the end of a run. */
  750. static void
  751. dump_statistics (SIM_CPU *current_cpu)
  752. {
  753. SIM_DESC sd = CPU_STATE (current_cpu);
  754. CRIS_MISC_PROFILE *profp
  755. = CPU_CRIS_MISC_PROFILE (current_cpu);
  756. uint64_t total = profp->basic_cycle_count;
  757. /* Historically, these messages have gone to stderr, so we'll keep it
  758. that way. It's also easier to then tell it from normal program
  759. output. FIXME: Add redirect option like "run -e file". */
  760. /* The --cris-stats={basic|unaligned|schedulable|all} counts affect
  761. what's included in the "total" count only. */
  762. switch (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
  763. & FLAG_CRIS_MISC_PROFILE_ALL)
  764. {
  765. case FLAG_CRIS_MISC_PROFILE_SIMPLE:
  766. sim_io_eprintf (sd, "Basic clock cycles, total @: %" PRIu64 "\n", total);
  767. break;
  768. case (FLAG_CRIS_MISC_PROFILE_UNALIGNED | FLAG_CRIS_MISC_PROFILE_SIMPLE):
  769. total += profp->unaligned_mem_dword_count;
  770. sim_io_eprintf (sd,
  771. "Clock cycles including stall cycles for unaligned "
  772. "accesses @: %" PRIu64 "\n",
  773. total);
  774. break;
  775. case (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE | FLAG_CRIS_MISC_PROFILE_SIMPLE):
  776. total
  777. += (profp->memsrc_stall_count
  778. + profp->memraw_stall_count
  779. + profp->movemsrc_stall_count
  780. + profp->movemdst_stall_count
  781. + profp->mulsrc_stall_count
  782. + profp->jumpsrc_stall_count
  783. + profp->unaligned_mem_dword_count);
  784. sim_io_eprintf (sd, "Schedulable clock cycles, total @: %" PRIu64 "\n",
  785. total);
  786. break;
  787. case FLAG_CRIS_MISC_PROFILE_ALL:
  788. total
  789. += (profp->memsrc_stall_count
  790. + profp->memraw_stall_count
  791. + profp->movemsrc_stall_count
  792. + profp->movemdst_stall_count
  793. + profp->movemaddr_stall_count
  794. + profp->mulsrc_stall_count
  795. + profp->jumpsrc_stall_count
  796. + profp->branch_stall_count
  797. + profp->jumptarget_stall_count
  798. + profp->unaligned_mem_dword_count);
  799. sim_io_eprintf (sd, "All accounted clock cycles, total @: %" PRIu64 "\n",
  800. total);
  801. break;
  802. default:
  803. sim_engine_abort (sd, current_cpu, 0,
  804. "Internal inconsistency at %s:%d",
  805. __FILE__, __LINE__);
  806. }
  807. /* For v32, unaligned_mem_dword_count should always be 0. For
  808. v10, memsrc_stall_count should always be 0. */
  809. sim_io_eprintf (sd, "Memory source stall cycles: %" PRIu64 "\n",
  810. profp->memsrc_stall_count + profp->unaligned_mem_dword_count);
  811. sim_io_eprintf (sd, "Memory read-after-write stall cycles: %" PRIu64 "\n",
  812. profp->memraw_stall_count);
  813. sim_io_eprintf (sd, "Movem source stall cycles: %" PRIu64 "\n",
  814. profp->movemsrc_stall_count);
  815. sim_io_eprintf (sd, "Movem destination stall cycles: %" PRIu64 "\n",
  816. profp->movemdst_stall_count);
  817. sim_io_eprintf (sd, "Movem address stall cycles: %" PRIu64 "\n",
  818. profp->movemaddr_stall_count);
  819. sim_io_eprintf (sd, "Multiplication source stall cycles: %" PRIu64 "\n",
  820. profp->mulsrc_stall_count);
  821. sim_io_eprintf (sd, "Jump source stall cycles: %" PRIu64 "\n",
  822. profp->jumpsrc_stall_count);
  823. sim_io_eprintf (sd, "Branch misprediction stall cycles: %" PRIu64 "\n",
  824. profp->branch_stall_count);
  825. sim_io_eprintf (sd, "Jump target stall cycles: %" PRIu64 "\n",
  826. profp->jumptarget_stall_count);
  827. }
  828. /* Check whether any part of [addr .. addr + len - 1] is already mapped.
  829. Return 1 if a overlap detected, 0 otherwise. */
  830. static USI
  831. is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED,
  832. struct cris_sim_mmapped_page **rootp,
  833. USI addr, USI len)
  834. {
  835. struct cris_sim_mmapped_page *mapp;
  836. if (len == 0 || (len & 8191))
  837. abort ();
  838. /* Iterate over the reverse-address sorted pages until we find a page in
  839. or lower than the checked area. */
  840. for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
  841. if (mapp->addr < addr + len && mapp->addr >= addr)
  842. return 1;
  843. return 0;
  844. }
  845. /* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
  846. Return 1 if the whole area is mapped, 0 otherwise. */
  847. static USI
  848. is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED,
  849. struct cris_sim_mmapped_page **rootp,
  850. USI addr, USI len)
  851. {
  852. struct cris_sim_mmapped_page *mapp;
  853. if (len == 0 || (len & 8191))
  854. abort ();
  855. /* Iterate over the reverse-address sorted pages until we find a page
  856. lower than the checked area. */
  857. for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
  858. if (addr == mapp->addr && len == 8192)
  859. return 1;
  860. else if (addr + len > mapp->addr)
  861. len -= 8192;
  862. return 0;
  863. }
  864. /* Provide a prototype to silence -Wmissing-prototypes. */
  865. void cris_dump_map (SIM_CPU *current_cpu);
  866. /* Debug helper; to be run from gdb. */
  867. void
  868. cris_dump_map (SIM_CPU *current_cpu)
  869. {
  870. struct cris_sim_mmapped_page *mapp;
  871. USI start, end;
  872. for (mapp = current_cpu->highest_mmapped_page,
  873. start = mapp == NULL ? 0 : mapp->addr + 8192,
  874. end = mapp == NULL ? 0 : mapp->addr + 8191;
  875. mapp != NULL;
  876. mapp = mapp->prev)
  877. {
  878. if (mapp->addr != start - 8192)
  879. {
  880. sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
  881. end = mapp->addr + 8191;
  882. }
  883. start = mapp->addr;
  884. }
  885. if (current_cpu->highest_mmapped_page != NULL)
  886. sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
  887. }
  888. /* Create mmapped memory. ADDR is -1 if any address will do. Caller
  889. must make sure that the address isn't already mapped. */
  890. static USI
  891. create_map (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
  892. USI len)
  893. {
  894. struct cris_sim_mmapped_page *mapp;
  895. struct cris_sim_mmapped_page **higher_prevp = rootp;
  896. USI new_addr = 0x40000000;
  897. if (addr != (USI) -1)
  898. new_addr = addr;
  899. else if (*rootp && rootp[0]->addr >= new_addr)
  900. new_addr = rootp[0]->addr + 8192;
  901. if (len != 8192)
  902. {
  903. USI page_addr;
  904. if (len & 8191)
  905. /* Which is better: return an error for this, or just round it up? */
  906. abort ();
  907. /* Do a recursive call for each page in the request. */
  908. for (page_addr = new_addr; len != 0; page_addr += 8192, len -= 8192)
  909. if (create_map (sd, rootp, page_addr, 8192) >= (USI) -8191)
  910. abort ();
  911. return new_addr;
  912. }
  913. for (mapp = *rootp;
  914. mapp != NULL && mapp->addr > new_addr;
  915. mapp = mapp->prev)
  916. higher_prevp = &mapp->prev;
  917. /* Assert for consistency that we don't create duplicate maps. */
  918. if (is_mapped (sd, rootp, new_addr, len))
  919. abort ();
  920. /* Allocate the new page, on the next higher page from the last one
  921. allocated, and link in the new descriptor before previous ones. */
  922. mapp = malloc (sizeof (*mapp));
  923. if (mapp == NULL)
  924. return (USI) -ENOMEM;
  925. sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
  926. new_addr, len,
  927. 0, NULL, NULL);
  928. mapp->addr = new_addr;
  929. mapp->prev = *higher_prevp;
  930. *higher_prevp = mapp;
  931. return new_addr;
  932. }
  933. /* Unmap one or more pages. */
  934. static USI
  935. unmap_pages (SIM_DESC sd, struct cris_sim_mmapped_page **rootp, USI addr,
  936. USI len)
  937. {
  938. struct cris_sim_mmapped_page *mapp;
  939. struct cris_sim_mmapped_page **higher_prevp = rootp;
  940. if (len != 8192)
  941. {
  942. USI page_addr;
  943. int ret = 0;
  944. if (len & 8191)
  945. /* Which is better: return an error for this, or just round it up? */
  946. abort ();
  947. /* Loop backwards to make each call is O(1) over the number of pages
  948. allocated, if we're unmapping from the high end of the pages. */
  949. for (page_addr = addr + len - 8192;
  950. page_addr > addr;
  951. page_addr -= 8192)
  952. if (unmap_pages (sd, rootp, page_addr, 8192))
  953. ret = EINVAL;
  954. if (unmap_pages (sd, rootp, addr, 8192))
  955. ret = EINVAL;
  956. return ret;
  957. }
  958. for (mapp = *rootp; mapp != NULL && mapp->addr > addr; mapp = mapp->prev)
  959. higher_prevp = &mapp->prev;
  960. if (mapp == NULL || mapp->addr != addr)
  961. return EINVAL;
  962. *higher_prevp = mapp->prev;
  963. sim_core_detach (sd, NULL, 0, 0, addr);
  964. free (mapp);
  965. return 0;
  966. }
  967. /* The semantic code invokes this for illegal (unrecognized) instructions. */
  968. SEM_PC
  969. sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
  970. {
  971. SIM_DESC sd = CPU_STATE (current_cpu);
  972. sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
  973. return vpc;
  974. }
  975. /* Swap one context for another. */
  976. static void
  977. schedule (SIM_CPU *current_cpu, int next)
  978. {
  979. /* Need to mark context-switches in the trace output. */
  980. if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags
  981. & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE))
  982. cris_trace_printf (CPU_STATE (current_cpu), current_cpu,
  983. "\t#:%d\n", next);
  984. /* Copy the current context (if there is one) to its slot. */
  985. if (current_cpu->thread_data[current_cpu->threadno].cpu_context)
  986. memcpy (current_cpu->thread_data[current_cpu->threadno].cpu_context,
  987. &current_cpu->cpu_data_placeholder,
  988. current_cpu->thread_cpu_data_size);
  989. /* Copy the new context from its slot. */
  990. memcpy (&current_cpu->cpu_data_placeholder,
  991. current_cpu->thread_data[next].cpu_context,
  992. current_cpu->thread_cpu_data_size);
  993. /* Update needed stuff to indicate the new context. */
  994. current_cpu->threadno = next;
  995. /* Handle pending signals. */
  996. if (current_cpu->thread_data[next].sigpending
  997. /* We don't run nested signal handlers. This means that pause(2)
  998. and sigsuspend(2) do not work in sighandlers, but that
  999. shouldn't be too hard a restriction. It also greatly
  1000. simplifies the code. */
  1001. && current_cpu->thread_data[next].cpu_context_atsignal == NULL)
  1002. {
  1003. int sig;
  1004. /* See if there's really a pending, non-blocked handler. We don't
  1005. queue signals, so just use the first one in ascending order. */
  1006. for (sig = 0; sig < 64; sig++)
  1007. if (current_cpu->thread_data[next].sigdata[sig].pending
  1008. && !current_cpu->thread_data[next].sigdata[sig].blocked)
  1009. {
  1010. bfd_byte regbuf[4];
  1011. USI sp;
  1012. int i;
  1013. USI blocked;
  1014. USI pc = sim_pc_get (current_cpu);
  1015. /* It's simpler to save the CPU context inside the simulator
  1016. than on the stack. */
  1017. current_cpu->thread_data[next].cpu_context_atsignal
  1018. = (*current_cpu
  1019. ->make_thread_cpu_data) (current_cpu,
  1020. current_cpu->thread_data[next]
  1021. .cpu_context);
  1022. (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
  1023. sp = bfd_getl32 (regbuf);
  1024. /* Make sure we have an aligned stack. */
  1025. sp &= ~3;
  1026. /* Make room for the signal frame, aligned. FIXME: Check that
  1027. the memory exists, map it in if absent. (BTW, should also
  1028. implement on-access automatic stack allocation). */
  1029. sp -= 20;
  1030. /* This isn't the same signal frame as the kernel uses, because
  1031. we don't want to bother getting all registers on and off the
  1032. stack. */
  1033. /* First, we store the currently blocked signals. */
  1034. blocked = 0;
  1035. for (i = 0; i < 32; i++)
  1036. blocked
  1037. |= current_cpu->thread_data[next].sigdata[i + 1].blocked << i;
  1038. sim_core_write_aligned_4 (current_cpu, pc, 0, sp, blocked);
  1039. blocked = 0;
  1040. for (i = 0; i < 31; i++)
  1041. blocked
  1042. |= current_cpu->thread_data[next].sigdata[i + 33].blocked << i;
  1043. sim_core_write_aligned_4 (current_cpu, pc, 0, sp + 4, blocked);
  1044. /* Then, the actual instructions. This is CPU-specific, but we
  1045. use instructions from the common subset for v10 and v32 which
  1046. should be safe for the time being but could be parametrized
  1047. if need be. */
  1048. /* MOVU.W [PC+],R9. */
  1049. sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 8, 0x9c5f);
  1050. /* .WORD TARGET_SYS_sigreturn. */
  1051. sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 10,
  1052. TARGET_SYS_sigreturn);
  1053. /* BREAK 13. */
  1054. sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 12, 0xe93d);
  1055. /* NOP (on v32; it's SETF on v10, but is the correct compatible
  1056. instruction. Still, it doesn't matter because v10 has no
  1057. delay slot for BREAK so it will not be executed). */
  1058. sim_core_write_aligned_2 (current_cpu, pc, 0, sp + 16, 0x05b0);
  1059. /* Modify registers to hold the right values for the sighandler
  1060. context: updated stackpointer and return address pointing to
  1061. the sigreturn stub. */
  1062. bfd_putl32 (sp, regbuf);
  1063. (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
  1064. bfd_putl32 (sp + 8, regbuf);
  1065. (*CPU_REG_STORE (current_cpu)) (current_cpu, TARGET_SRP_REGNUM,
  1066. regbuf, 4);
  1067. current_cpu->thread_data[next].sigdata[sig].pending = 0;
  1068. /* Block this signal (for the duration of the sighandler). */
  1069. current_cpu->thread_data[next].sigdata[sig].blocked = 1;
  1070. sim_pc_set (current_cpu, current_cpu->sighandler[sig]);
  1071. bfd_putl32 (sig, regbuf);
  1072. (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10,
  1073. regbuf, 4);
  1074. /* We ignore a SA_SIGINFO flag in the sigaction call; the code I
  1075. needed all this for, specifies a SA_SIGINFO call but treats it
  1076. like an ordinary sighandler; only the signal number argument is
  1077. inspected. To make future need to implement SA_SIGINFO
  1078. correctly possible, we set the siginfo argument register to a
  1079. magic (hopefully non-address) number. (NB: then, you should
  1080. just need to pass the siginfo argument; it seems you probably
  1081. don't need to implement the specific rt_sigreturn.) */
  1082. bfd_putl32 (0xbad5161f, regbuf);
  1083. (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R11,
  1084. regbuf, 4);
  1085. /* The third argument is unused and the kernel sets it to 0. */
  1086. bfd_putl32 (0, regbuf);
  1087. (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R12,
  1088. regbuf, 4);
  1089. return;
  1090. }
  1091. /* No, there actually was no pending signal for this thread. Reset
  1092. this flag. */
  1093. current_cpu->thread_data[next].sigpending = 0;
  1094. }
  1095. }
  1096. /* Reschedule the simplest possible way until something else is absolutely
  1097. necessary:
  1098. - A. Find the next process (round-robin) that doesn't have at_syscall
  1099. set, schedule it.
  1100. - B. If there is none, just run the next process, round-robin.
  1101. - Clear at_syscall for the current process. */
  1102. static void
  1103. reschedule (SIM_CPU *current_cpu)
  1104. {
  1105. SIM_DESC sd = CPU_STATE (current_cpu);
  1106. int i;
  1107. /* Iterate over all thread slots, because after a few thread creations
  1108. and exits, we don't know where the live ones are. */
  1109. for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
  1110. i != current_cpu->threadno;
  1111. i = (i + 1) % SIM_TARGET_MAX_THREADS)
  1112. if (current_cpu->thread_data[i].cpu_context
  1113. && current_cpu->thread_data[i].at_syscall == 0)
  1114. {
  1115. schedule (current_cpu, i);
  1116. return;
  1117. }
  1118. /* Pick any next live thread. */
  1119. for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
  1120. i != current_cpu->threadno;
  1121. i = (i + 1) % SIM_TARGET_MAX_THREADS)
  1122. if (current_cpu->thread_data[i].cpu_context)
  1123. {
  1124. schedule (current_cpu, i);
  1125. return;
  1126. }
  1127. /* More than one live thread, but we couldn't find the next one? */
  1128. abort ();
  1129. }
  1130. /* Set up everything to receive (or IGN) an incoming signal to the
  1131. current context. */
  1132. static int
  1133. deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid)
  1134. {
  1135. int i;
  1136. USI pc = sim_pc_get (current_cpu);
  1137. /* Find the thread index of the pid. */
  1138. for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
  1139. /* Apparently it's ok to send signals to zombies (so a check for
  1140. current_cpu->thread_data[i].cpu_context != NULL would be
  1141. wrong). */
  1142. if (current_cpu->thread_data[i].threadid == pid - TARGET_PID)
  1143. {
  1144. if (sig < 64)
  1145. switch (current_cpu->sighandler[sig])
  1146. {
  1147. case TARGET_SIG_DFL:
  1148. switch (sig)
  1149. {
  1150. /* The following according to the glibc
  1151. documentation. (The kernel code has non-obvious
  1152. execution paths.) */
  1153. case TARGET_SIGFPE:
  1154. case TARGET_SIGILL:
  1155. case TARGET_SIGSEGV:
  1156. case TARGET_SIGBUS:
  1157. case TARGET_SIGABRT:
  1158. case TARGET_SIGTRAP:
  1159. case TARGET_SIGSYS:
  1160. case TARGET_SIGTERM:
  1161. case TARGET_SIGINT:
  1162. case TARGET_SIGQUIT:
  1163. case TARGET_SIGKILL:
  1164. case TARGET_SIGHUP:
  1165. case TARGET_SIGALRM:
  1166. case TARGET_SIGVTALRM:
  1167. case TARGET_SIGPROF:
  1168. case TARGET_SIGSTOP:
  1169. case TARGET_SIGPIPE:
  1170. case TARGET_SIGLOST:
  1171. case TARGET_SIGXCPU:
  1172. case TARGET_SIGXFSZ:
  1173. case TARGET_SIGUSR1:
  1174. case TARGET_SIGUSR2:
  1175. sim_io_eprintf (CPU_STATE (current_cpu),
  1176. "Exiting pid %d due to signal %d\n",
  1177. pid, sig);
  1178. sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
  1179. NULL, pc, sim_stopped,
  1180. sig == TARGET_SIGABRT
  1181. ? SIM_SIGABRT : SIM_SIGILL);
  1182. return 0;
  1183. /* The default for all other signals is to be ignored. */
  1184. default:
  1185. return 0;
  1186. }
  1187. case TARGET_SIG_IGN:
  1188. switch (sig)
  1189. {
  1190. case TARGET_SIGKILL:
  1191. case TARGET_SIGSTOP:
  1192. /* Can't ignore these signals. */
  1193. sim_io_eprintf (CPU_STATE (current_cpu),
  1194. "Exiting pid %d due to signal %d\n",
  1195. pid, sig);
  1196. sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
  1197. NULL, pc, sim_stopped, SIM_SIGILL);
  1198. return 0;
  1199. default:
  1200. return 0;
  1201. }
  1202. break;
  1203. default:
  1204. /* Mark the signal as pending, making schedule () check
  1205. closer. The signal will be handled when the thread is
  1206. scheduled and the signal is unblocked. */
  1207. current_cpu->thread_data[i].sigdata[sig].pending = 1;
  1208. current_cpu->thread_data[i].sigpending = 1;
  1209. return 0;
  1210. }
  1211. else
  1212. {
  1213. sim_io_eprintf (CPU_STATE (current_cpu),
  1214. "Unimplemented signal: %d\n", sig);
  1215. sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc,
  1216. sim_stopped, SIM_SIGILL);
  1217. }
  1218. }
  1219. return
  1220. -cb_host_to_target_errno (STATE_CALLBACK (CPU_STATE (current_cpu)),
  1221. ESRCH);
  1222. }
  1223. /* Make the vector and the first item, the main thread. */
  1224. static void
  1225. make_first_thread (SIM_CPU *current_cpu)
  1226. {
  1227. SIM_DESC sd = CPU_STATE (current_cpu);
  1228. current_cpu->thread_data
  1229. = xcalloc (1,
  1230. SIM_TARGET_MAX_THREADS
  1231. * sizeof (current_cpu->thread_data[0]));
  1232. current_cpu->thread_data[0].cpu_context
  1233. = (*current_cpu->make_thread_cpu_data) (current_cpu,
  1234. &current_cpu
  1235. ->cpu_data_placeholder);
  1236. current_cpu->thread_data[0].parent_threadid = -1;
  1237. /* For good measure. */
  1238. if (TARGET_SIG_DFL != 0)
  1239. abort ();
  1240. }
  1241. /* Handle unknown system calls. Returns (if it does) the syscall
  1242. return value. */
  1243. static USI
  1244. cris_unknown_syscall (SIM_CPU *current_cpu, USI pc, char *s, ...)
  1245. {
  1246. SIM_DESC sd = CPU_STATE (current_cpu);
  1247. host_callback *cb = STATE_CALLBACK (sd);
  1248. if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP
  1249. || cris_unknown_syscall_action == CRIS_USYSC_MSG_ENOSYS)
  1250. {
  1251. va_list ap;
  1252. va_start (ap, s);
  1253. sim_io_evprintf (sd, s, ap);
  1254. va_end (ap);
  1255. if (cris_unknown_syscall_action == CRIS_USYSC_MSG_STOP)
  1256. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
  1257. }
  1258. return -cb_host_to_target_errno (cb, ENOSYS);
  1259. }
  1260. /* Main function: the handler of the "break 13" syscall insn. */
  1261. USI
  1262. cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
  1263. USI arg2, USI arg3, USI arg4, USI arg5, USI arg6,
  1264. USI pc)
  1265. {
  1266. CB_SYSCALL s;
  1267. SIM_DESC sd = CPU_STATE (current_cpu);
  1268. host_callback *cb = STATE_CALLBACK (sd);
  1269. int retval;
  1270. int threadno = current_cpu->threadno;
  1271. current_cpu->syscalls++;
  1272. CB_SYSCALL_INIT (&s);
  1273. s.func = callnum;
  1274. s.arg1 = arg1;
  1275. s.arg2 = arg2;
  1276. s.arg3 = arg3;
  1277. /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need
  1278. to sign-extend the lseek offset to be passed as a signed number,
  1279. else we'll truncate it to something > 2GB on hosts where sizeof
  1280. long > sizeof USI. We avoid doing it for all syscalls, as arg2 is
  1281. e.g. an address for some syscalls. */
  1282. if (callnum == TARGET_SYS_lseek)
  1283. s.arg2 = (SI) arg2;
  1284. if (callnum == TARGET_SYS_exit_group
  1285. || (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0))
  1286. {
  1287. if (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
  1288. & FLAG_CRIS_MISC_PROFILE_ALL)
  1289. dump_statistics (current_cpu);
  1290. sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
  1291. }
  1292. s.p1 = (PTR) sd;
  1293. s.p2 = (PTR) current_cpu;
  1294. s.read_mem = sim_syscall_read_mem;
  1295. s.write_mem = sim_syscall_write_mem;
  1296. current_cpu_for_cb_callback = current_cpu;
  1297. if (cb_syscall (cb, &s) != CB_RC_OK)
  1298. {
  1299. sim_engine_abort (sd, current_cpu, pc,
  1300. "Break 13: invalid %d? Returned %ld\n", callnum,
  1301. s.result);
  1302. }
  1303. retval = s.result == -1 ? -s.errcode : s.result;
  1304. if (s.errcode != 0 && s.errcode == cb_host_to_target_errno (cb, ENOSYS))
  1305. {
  1306. /* If the generic simulator call said ENOSYS, then let's try the
  1307. ones we know ourselves.
  1308. The convention is to provide *very limited* functionality on an
  1309. as-needed basis, only what's covered by the test-suite, tests
  1310. added when functionality changes and abort with a descriptive
  1311. message for *everything* else. Where there's no test-case, we
  1312. just abort. */
  1313. switch (callnum)
  1314. {
  1315. case 0:
  1316. /* It's a pretty safe bet that the "old setup() system call"
  1317. number will not be re-used; we can't say the same for higher
  1318. numbers. We treat this simulator-generated call as "wait
  1319. forever"; we re-run this insn. The wait is ended by a
  1320. callback. Sanity check that this is the reason we got
  1321. here. */
  1322. if (current_cpu->thread_data == NULL
  1323. || (current_cpu->thread_data[threadno].pipe_write_fd == 0))
  1324. goto unimplemented_syscall;
  1325. sim_pc_set (current_cpu, pc);
  1326. retval = arg1;
  1327. break;
  1328. case TARGET_SYS_fcntl64:
  1329. case TARGET_SYS_fcntl:
  1330. switch (arg2)
  1331. {
  1332. case 1:
  1333. /* F_GETFD.
  1334. Glibc checks stdin, stdout and stderr fd:s for
  1335. close-on-exec security sanity. We just need to provide a
  1336. OK return value. If we really need to have a
  1337. close-on-exec flag true, we could just do a real fcntl
  1338. here. */
  1339. retval = 0;
  1340. break;
  1341. case 2:
  1342. /* F_SETFD. Just ignore attempts to set the close-on-exec
  1343. flag. */
  1344. retval = 0;
  1345. break;
  1346. case 3:
  1347. /* F_GETFL. Check for the special case for open+fdopen. */
  1348. if (current_cpu->last_syscall == TARGET_SYS_open
  1349. && arg1 == current_cpu->last_open_fd)
  1350. {
  1351. retval = current_cpu->last_open_flags & TARGET_O_ACCMODE;
  1352. break;
  1353. }
  1354. else if (arg1 == 0)
  1355. {
  1356. /* Because we can't freopen fd:s 0, 1, 2 to mean
  1357. something else than stdin, stdout and stderr
  1358. (sim/common/syscall.c:cb_syscall special cases fd
  1359. 0, 1 and 2), we know what flags that we can
  1360. sanely return for these fd:s. */
  1361. retval = TARGET_O_RDONLY;
  1362. break;
  1363. }
  1364. else if (arg1 == 1 || arg1 == 2)
  1365. {
  1366. retval = TARGET_O_WRONLY;
  1367. break;
  1368. }
  1369. /* FALLTHROUGH */
  1370. default:
  1371. /* Nothing else is implemented. */
  1372. retval
  1373. = cris_unknown_syscall (current_cpu, pc,
  1374. "Unimplemented %s syscall "
  1375. "(fd: 0x%lx: cmd: 0x%lx arg: "
  1376. "0x%lx)\n",
  1377. callnum == TARGET_SYS_fcntl
  1378. ? "fcntl" : "fcntl64",
  1379. (unsigned long) (USI) arg1,
  1380. (unsigned long) (USI) arg2,
  1381. (unsigned long) (USI) arg3);
  1382. break;
  1383. }
  1384. break;
  1385. case TARGET_SYS_uname:
  1386. {
  1387. /* Fill in a few constants to appease glibc. */
  1388. static char sim_utsname[6][65] =
  1389. {
  1390. "Linux",
  1391. "sim-target",
  1392. "2.6.27",
  1393. TARGET_UTSNAME,
  1394. "cris", /* Overwritten below. */
  1395. "localdomain"
  1396. };
  1397. /* Having the hardware type in Linux equal to the bfd
  1398. printable name is deliberate: if you make config.guess
  1399. work on your Linux-type system the usual way, it
  1400. probably will; either the bfd printable_name or the
  1401. ambiguous arch_name. */
  1402. strcpy (sim_utsname[4], STATE_ARCHITECTURE (sd)->printable_name);
  1403. if ((s.write_mem) (cb, &s, arg1, (const char *) sim_utsname,
  1404. sizeof (sim_utsname))
  1405. != sizeof (sim_utsname))
  1406. retval = -cb_host_to_target_errno (cb, EFAULT);
  1407. else
  1408. retval = 0;
  1409. break;
  1410. }
  1411. case TARGET_SYS_geteuid32:
  1412. /* We tell the truth with these. Maybe we shouldn't, but it
  1413. should match the "stat" information. */
  1414. retval = geteuid ();
  1415. break;
  1416. case TARGET_SYS_getuid32:
  1417. retval = getuid ();
  1418. break;
  1419. case TARGET_SYS_getegid32:
  1420. retval = getegid ();
  1421. break;
  1422. case TARGET_SYS_getgid32:
  1423. retval = getgid ();
  1424. break;
  1425. case TARGET_SYS_brk:
  1426. /* Most often, we just return the argument, like the Linux
  1427. kernel. */
  1428. retval = arg1;
  1429. if (arg1 == 0)
  1430. retval = current_cpu->endbrk;
  1431. else if (arg1 <= current_cpu->endmem)
  1432. current_cpu->endbrk = arg1;
  1433. else
  1434. {
  1435. USI new_end = (arg1 + 8191) & ~8191;
  1436. /* If the simulator wants to brk more than a certain very
  1437. large amount, something is wrong. FIXME: Return an error
  1438. or abort? Have command-line selectable? */
  1439. if (new_end - current_cpu->endmem > SIM_MAX_ALLOC_CHUNK)
  1440. {
  1441. current_cpu->endbrk = current_cpu->endmem;
  1442. retval = current_cpu->endmem;
  1443. break;
  1444. }
  1445. sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
  1446. current_cpu->endmem,
  1447. new_end - current_cpu->endmem,
  1448. 0, NULL, NULL);
  1449. current_cpu->endbrk = arg1;
  1450. current_cpu->endmem = new_end;
  1451. }
  1452. break;
  1453. case TARGET_SYS_getpid:
  1454. /* Correct until CLONE_THREAD is implemented. */
  1455. retval = current_cpu->thread_data == NULL
  1456. ? TARGET_PID
  1457. : TARGET_PID + current_cpu->thread_data[threadno].threadid;
  1458. break;
  1459. case TARGET_SYS_getppid:
  1460. /* Correct until CLONE_THREAD is implemented. */
  1461. retval = current_cpu->thread_data == NULL
  1462. ? TARGET_PID - 1
  1463. : (TARGET_PID
  1464. + current_cpu->thread_data[threadno].parent_threadid);
  1465. break;
  1466. case TARGET_SYS_mmap2:
  1467. {
  1468. USI addr = arg1;
  1469. USI len = arg2;
  1470. USI prot = arg3;
  1471. USI flags = arg4;
  1472. USI fd = arg5;
  1473. USI pgoff = arg6;
  1474. /* At 2.6.27, Linux (many (all?) ports, in the mmap2 syscalls)
  1475. still masked away this bit, so let's just ignore
  1476. it. */
  1477. flags &= ~TARGET_MAP_DENYWRITE;
  1478. /* If the simulator wants to mmap more than the very large
  1479. limit, something is wrong. FIXME: Return an error or
  1480. abort? Have command-line selectable? */
  1481. if (len > SIM_MAX_ALLOC_CHUNK)
  1482. {
  1483. retval = -cb_host_to_target_errno (cb, ENOMEM);
  1484. break;
  1485. }
  1486. if ((prot != (TARGET_PROT_READ | TARGET_PROT_WRITE)
  1487. && (prot
  1488. != (TARGET_PROT_READ
  1489. | TARGET_PROT_WRITE
  1490. | TARGET_PROT_EXEC))
  1491. && (prot != (TARGET_PROT_READ | TARGET_PROT_EXEC))
  1492. && prot != TARGET_PROT_READ)
  1493. || (flags != (TARGET_MAP_ANONYMOUS | TARGET_MAP_PRIVATE)
  1494. && flags != TARGET_MAP_PRIVATE
  1495. && flags != (TARGET_MAP_ANONYMOUS
  1496. | TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
  1497. && flags != (TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
  1498. && flags != TARGET_MAP_SHARED)
  1499. || (fd != (USI) -1
  1500. && prot != TARGET_PROT_READ
  1501. && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
  1502. && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
  1503. || (fd == (USI) -1 && pgoff != 0)
  1504. || (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS)))
  1505. {
  1506. retval
  1507. = cris_unknown_syscall (current_cpu, pc,
  1508. "Unimplemented mmap2 call "
  1509. "(0x%lx, 0x%lx, 0x%lx, "
  1510. "0x%lx, 0x%lx, 0x%lx)\n",
  1511. (unsigned long) arg1,
  1512. (unsigned long) arg2,
  1513. (unsigned long) arg3,
  1514. (unsigned long) arg4,
  1515. (unsigned long) arg5,
  1516. (unsigned long) arg6);
  1517. break;
  1518. }
  1519. else if (fd != (USI) -1)
  1520. {
  1521. /* Map a file. */
  1522. USI newaddr;
  1523. USI pos;
  1524. /* A non-aligned argument is allowed for files. */
  1525. USI newlen = (len + 8191) & ~8191;
  1526. /* We only support read, read|exec, and read|write,
  1527. which we should already have checked. Check again
  1528. anyway. */
  1529. if (prot != TARGET_PROT_READ
  1530. && prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
  1531. && prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
  1532. abort ();
  1533. if (flags & TARGET_MAP_FIXED)
  1534. unmap_pages (sd, &current_cpu->highest_mmapped_page,
  1535. addr, newlen);
  1536. else if (is_mapped (sd, &current_cpu->highest_mmapped_page,
  1537. addr, newlen))
  1538. addr = 0;
  1539. newaddr
  1540. = create_map (sd, &current_cpu->highest_mmapped_page,
  1541. addr != 0 || (flags & TARGET_MAP_FIXED)
  1542. ? addr : -1,
  1543. newlen);
  1544. if (newaddr >= (USI) -8191)
  1545. {
  1546. abort ();
  1547. retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
  1548. break;
  1549. }
  1550. /* We were asked for MAP_FIXED, but couldn't. */
  1551. if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
  1552. {
  1553. abort ();
  1554. unmap_pages (sd, &current_cpu->highest_mmapped_page,
  1555. newaddr, newlen);
  1556. retval = -cb_host_to_target_errno (cb, EINVAL);
  1557. break;
  1558. }
  1559. /* Find the current position in the file. */
  1560. s.func = TARGET_SYS_lseek;
  1561. s.arg1 = fd;
  1562. s.arg2 = 0;
  1563. s.arg3 = SEEK_CUR;
  1564. if (cb_syscall (cb, &s) != CB_RC_OK)
  1565. abort ();
  1566. pos = s.result;
  1567. if (s.result < 0)
  1568. abort ();
  1569. /* Move to the correct offset in the file. */
  1570. s.func = TARGET_SYS_lseek;
  1571. s.arg1 = fd;
  1572. s.arg2 = pgoff*8192;
  1573. s.arg3 = SEEK_SET;
  1574. if (cb_syscall (cb, &s) != CB_RC_OK)
  1575. abort ();
  1576. if (s.result < 0)
  1577. abort ();
  1578. /* Use the standard read callback to read in "len"
  1579. bytes. */
  1580. s.func = TARGET_SYS_read;
  1581. s.arg1 = fd;
  1582. s.arg2 = newaddr;
  1583. s.arg3 = len;
  1584. if (cb_syscall (cb, &s) != CB_RC_OK)
  1585. abort ();
  1586. /* If the result is a page or more lesser than what
  1587. was requested, something went wrong. */
  1588. if (len >= 8192 && (USI) s.result <= len - 8192)
  1589. abort ();
  1590. /* After reading, we need to go back to the previous
  1591. position in the file. */
  1592. s.func = TARGET_SYS_lseek;
  1593. s.arg1 = fd;
  1594. s.arg2 = pos;
  1595. s.arg3 = SEEK_SET;
  1596. if (cb_syscall (cb, &s) != CB_RC_OK)
  1597. abort ();
  1598. if (pos != (USI) s.result)
  1599. abort ();
  1600. retval = newaddr;
  1601. }
  1602. else
  1603. {
  1604. USI newlen = (len + 8191) & ~8191;
  1605. USI newaddr;
  1606. if (flags & TARGET_MAP_FIXED)
  1607. unmap_pages (sd, &current_cpu->highest_mmapped_page,
  1608. addr, newlen);
  1609. else if (is_mapped (sd, &current_cpu->highest_mmapped_page,
  1610. addr, newlen))
  1611. addr = 0;
  1612. newaddr = create_map (sd, &current_cpu->highest_mmapped_page,
  1613. addr != 0 || (flags & TARGET_MAP_FIXED)
  1614. ? addr : -1,
  1615. newlen);
  1616. if (newaddr >= (USI) -8191)
  1617. retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
  1618. else
  1619. retval = newaddr;
  1620. if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
  1621. {
  1622. abort ();
  1623. unmap_pages (sd, &current_cpu->highest_mmapped_page,
  1624. newaddr, newlen);
  1625. retval = -cb_host_to_target_errno (cb, EINVAL);
  1626. break;
  1627. }
  1628. }
  1629. break;
  1630. }
  1631. case TARGET_SYS_mprotect:
  1632. {
  1633. /* We only cover the case of linuxthreads mprotecting out
  1634. its stack guard page and of dynamic loading mprotecting
  1635. away the data (for some reason the whole library, then
  1636. mprotects away the data part and mmap-FIX:es it again. */
  1637. USI addr = arg1;
  1638. USI len = arg2;
  1639. USI prot = arg3;
  1640. if (prot != TARGET_PROT_NONE
  1641. || !is_mapped_only (sd, &current_cpu->highest_mmapped_page,
  1642. addr, (len + 8191) & ~8191))
  1643. {
  1644. retval
  1645. = cris_unknown_syscall (current_cpu, pc,
  1646. "Unimplemented mprotect call "
  1647. "(0x%lx, 0x%lx, 0x%lx)\n",
  1648. (unsigned long) arg1,
  1649. (unsigned long) arg2,
  1650. (unsigned long) arg3);
  1651. break;
  1652. }
  1653. /* Just ignore this. We could make this equal to munmap,
  1654. but then we'd have to make sure no anon mmaps gets this
  1655. address before a subsequent MAP_FIXED mmap intended to
  1656. override it. */
  1657. retval = 0;
  1658. break;
  1659. }
  1660. case TARGET_SYS_ioctl:
  1661. {
  1662. /* We support only a very limited functionality: checking
  1663. stdout with TCGETS to perform the isatty function. The
  1664. TCGETS ioctl isn't actually performed or the result used by
  1665. an isatty () caller in a "hello, world" program; only the
  1666. return value is then used. Maybe we shouldn't care about
  1667. the environment of the simulator regarding isatty, but
  1668. that's been working before, in the xsim simulator. */
  1669. if (arg2 == TARGET_TCGETS && arg1 == 1)
  1670. retval = isatty (1) ? 0 : cb_host_to_target_errno (cb, EINVAL);
  1671. else
  1672. retval = -cb_host_to_target_errno (cb, EINVAL);
  1673. break;
  1674. }
  1675. case TARGET_SYS_munmap:
  1676. {
  1677. USI addr = arg1;
  1678. USI len = arg2;
  1679. USI result
  1680. = unmap_pages (sd, &current_cpu->highest_mmapped_page, addr,
  1681. len);
  1682. retval = result != 0 ? -cb_host_to_target_errno (cb, result) : 0;
  1683. break;
  1684. }
  1685. case TARGET_SYS_wait4:
  1686. {
  1687. int i;
  1688. USI pid = arg1;
  1689. USI saddr = arg2;
  1690. USI options = arg3;
  1691. USI rusagep = arg4;
  1692. /* FIXME: We're not properly implementing __WCLONE, and we
  1693. don't really need the special casing so we might as well
  1694. make this general. */
  1695. if ((!(pid == (USI) -1
  1696. && options == (TARGET___WCLONE | TARGET_WNOHANG)
  1697. && saddr != 0)
  1698. && !(pid > 0
  1699. && (options == TARGET___WCLONE
  1700. || options == TARGET___WALL)))
  1701. || rusagep != 0
  1702. || current_cpu->thread_data == NULL)
  1703. {
  1704. retval
  1705. = cris_unknown_syscall (current_cpu, pc,
  1706. "Unimplemented wait4 call "
  1707. "(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
  1708. (unsigned long) arg1,
  1709. (unsigned long) arg2,
  1710. (unsigned long) arg3,
  1711. (unsigned long) arg4);
  1712. break;
  1713. }
  1714. if (pid == (USI) -1)
  1715. for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
  1716. {
  1717. if (current_cpu->thread_data[threadno].threadid
  1718. == current_cpu->thread_data[i].parent_threadid
  1719. && current_cpu->thread_data[i].threadid != 0
  1720. && current_cpu->thread_data[i].cpu_context == NULL)
  1721. {
  1722. /* A zombied child. Get the exit value and clear the
  1723. zombied entry so it will be reused. */
  1724. sim_core_write_unaligned_4 (current_cpu, pc, 0, saddr,
  1725. current_cpu
  1726. ->thread_data[i].exitval);
  1727. retval
  1728. = current_cpu->thread_data[i].threadid + TARGET_PID;
  1729. memset (&current_cpu->thread_data[i], 0,
  1730. sizeof (current_cpu->thread_data[i]));
  1731. goto outer_break;
  1732. }
  1733. }
  1734. else
  1735. {
  1736. /* We're waiting for a specific PID. If we don't find
  1737. it zombied on this run, rerun the syscall. */
  1738. for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
  1739. if (pid == current_cpu->thread_data[i].threadid + TARGET_PID
  1740. && current_cpu->thread_data[i].cpu_context == NULL)
  1741. {
  1742. if (saddr != 0)
  1743. /* Get the exit value if the caller wants it. */
  1744. sim_core_write_unaligned_4 (current_cpu, pc, 0,
  1745. saddr,
  1746. current_cpu
  1747. ->thread_data[i]
  1748. .exitval);
  1749. retval
  1750. = current_cpu->thread_data[i].threadid + TARGET_PID;
  1751. memset (&current_cpu->thread_data[i], 0,
  1752. sizeof (current_cpu->thread_data[i]));
  1753. goto outer_break;
  1754. }
  1755. sim_pc_set (current_cpu, pc);
  1756. }
  1757. retval = -cb_host_to_target_errno (cb, ECHILD);
  1758. outer_break:
  1759. break;
  1760. }
  1761. case TARGET_SYS_rt_sigaction:
  1762. {
  1763. USI signum = arg1;
  1764. USI old_sa = arg3;
  1765. USI new_sa = arg2;
  1766. /* The kernel says:
  1767. struct sigaction {
  1768. __sighandler_t sa_handler;
  1769. unsigned long sa_flags;
  1770. void (*sa_restorer)(void);
  1771. sigset_t sa_mask;
  1772. }; */
  1773. if (old_sa != 0)
  1774. {
  1775. sim_core_write_unaligned_4 (current_cpu, pc, 0, old_sa + 0,
  1776. current_cpu->sighandler[signum]);
  1777. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 4, 0);
  1778. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 8, 0);
  1779. /* We'll assume _NSIG_WORDS is 2 for the kernel. */
  1780. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 12, 0);
  1781. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 16, 0);
  1782. }
  1783. if (new_sa != 0)
  1784. {
  1785. USI target_sa_handler
  1786. = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa);
  1787. USI target_sa_flags
  1788. = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 4);
  1789. USI target_sa_restorer
  1790. = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 8);
  1791. USI target_sa_mask_low
  1792. = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 12);
  1793. USI target_sa_mask_high
  1794. = sim_core_read_unaligned_4 (current_cpu, pc, 0, new_sa + 16);
  1795. /* We won't interrupt a syscall so we won't restart it,
  1796. but a signal(2) call ends up syscalling rt_sigaction
  1797. with this flag, so we have to handle it. The
  1798. sa_restorer field contains garbage when not
  1799. TARGET_SA_RESTORER, so don't look at it. For the
  1800. time being, we don't nest sighandlers, so we
  1801. ignore the sa_mask, which simplifies things. */
  1802. if ((target_sa_flags != 0
  1803. && target_sa_flags != TARGET_SA_RESTART
  1804. && target_sa_flags != (TARGET_SA_RESTART|TARGET_SA_SIGINFO))
  1805. || target_sa_handler == 0)
  1806. {
  1807. retval
  1808. = cris_unknown_syscall (current_cpu, pc,
  1809. "Unimplemented rt_sigaction "
  1810. "syscall "
  1811. "(0x%lx, 0x%lx: "
  1812. "[0x%x, 0x%x, 0x%x, "
  1813. "{0x%x, 0x%x}], 0x%lx)\n",
  1814. (unsigned long) arg1,
  1815. (unsigned long) arg2,
  1816. target_sa_handler,
  1817. target_sa_flags,
  1818. target_sa_restorer,
  1819. target_sa_mask_low,
  1820. target_sa_mask_high,
  1821. (unsigned long) arg3);
  1822. break;
  1823. }
  1824. current_cpu->sighandler[signum] = target_sa_handler;
  1825. /* Because we may have unblocked signals, one may now be
  1826. pending, if there are threads, that is. */
  1827. if (current_cpu->thread_data)
  1828. current_cpu->thread_data[threadno].sigpending = 1;
  1829. }
  1830. retval = 0;
  1831. break;
  1832. }
  1833. case TARGET_SYS_mremap:
  1834. {
  1835. USI addr = arg1;
  1836. USI old_len = arg2;
  1837. USI new_len = arg3;
  1838. USI flags = arg4;
  1839. USI new_addr = arg5;
  1840. USI mapped_addr;
  1841. if (new_len == old_len)
  1842. /* The program and/or library is possibly confused but
  1843. this is a valid call. Happens with ipps-1.40 on file
  1844. svs_all. */
  1845. retval = addr;
  1846. else if (new_len < old_len)
  1847. {
  1848. /* Shrinking is easy. */
  1849. if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
  1850. addr + new_len, old_len - new_len) != 0)
  1851. retval = -cb_host_to_target_errno (cb, EINVAL);
  1852. else
  1853. retval = addr;
  1854. }
  1855. else if (! is_mapped (sd, &current_cpu->highest_mmapped_page,
  1856. addr + old_len, new_len - old_len))
  1857. {
  1858. /* If the extension isn't mapped, we can just add it. */
  1859. mapped_addr
  1860. = create_map (sd, &current_cpu->highest_mmapped_page,
  1861. addr + old_len, new_len - old_len);
  1862. if (mapped_addr > (USI) -8192)
  1863. retval = -cb_host_to_target_errno (cb, -(SI) mapped_addr);
  1864. else
  1865. retval = addr;
  1866. }
  1867. else if (flags & TARGET_MREMAP_MAYMOVE)
  1868. {
  1869. /* Create a whole new map and copy the contents
  1870. block-by-block there. We ignore the new_addr argument
  1871. for now. */
  1872. char buf[8192];
  1873. USI prev_addr = addr;
  1874. USI prev_len = old_len;
  1875. mapped_addr
  1876. = create_map (sd, &current_cpu->highest_mmapped_page,
  1877. -1, new_len);
  1878. if (mapped_addr > (USI) -8192)
  1879. {
  1880. retval = -cb_host_to_target_errno (cb, -(SI) new_addr);
  1881. break;
  1882. }
  1883. retval = mapped_addr;
  1884. for (; old_len > 0;
  1885. old_len -= 8192, mapped_addr += 8192, addr += 8192)
  1886. {
  1887. if (sim_core_read_buffer (sd, current_cpu, read_map, buf,
  1888. addr, 8192) != 8192
  1889. || sim_core_write_buffer (sd, current_cpu, 0, buf,
  1890. mapped_addr, 8192) != 8192)
  1891. abort ();
  1892. }
  1893. if (unmap_pages (sd, &current_cpu->highest_mmapped_page,
  1894. prev_addr, prev_len) != 0)
  1895. abort ();
  1896. }
  1897. else
  1898. retval = -cb_host_to_target_errno (cb, -ENOMEM);
  1899. break;
  1900. }
  1901. case TARGET_SYS_poll:
  1902. {
  1903. int npollfds = arg2;
  1904. int timeout = arg3;
  1905. SI ufds = arg1;
  1906. SI fd = -1;
  1907. HI events = -1;
  1908. HI revents = 0;
  1909. struct stat buf;
  1910. int i;
  1911. /* The kernel says:
  1912. struct pollfd {
  1913. int fd;
  1914. short events;
  1915. short revents;
  1916. }; */
  1917. /* Check that this is the expected poll call from
  1918. linuxthreads/manager.c; we don't support anything else.
  1919. Remember, fd == 0 isn't supported. */
  1920. if (npollfds != 1
  1921. || ((fd = sim_core_read_unaligned_4 (current_cpu, pc,
  1922. 0, ufds)) <= 0)
  1923. || ((events = sim_core_read_unaligned_2 (current_cpu, pc,
  1924. 0, ufds + 4))
  1925. != TARGET_POLLIN)
  1926. || ((cb->to_fstat) (cb, fd, &buf) != 0
  1927. || (buf.st_mode & S_IFIFO) == 0)
  1928. || current_cpu->thread_data == NULL)
  1929. {
  1930. retval
  1931. = cris_unknown_syscall (current_cpu, pc,
  1932. "Unimplemented poll syscall "
  1933. "(0x%lx: [0x%x, 0x%x, x], "
  1934. "0x%lx, 0x%lx)\n",
  1935. (unsigned long) arg1, fd, events,
  1936. (unsigned long) arg2,
  1937. (unsigned long) arg3);
  1938. break;
  1939. }
  1940. retval = 0;
  1941. /* Iterate over threads; find a marker that a writer is
  1942. sleeping, waiting for a reader. */
  1943. for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
  1944. if (current_cpu->thread_data[i].cpu_context != NULL
  1945. && current_cpu->thread_data[i].pipe_read_fd == fd)
  1946. {
  1947. revents = TARGET_POLLIN;
  1948. retval = 1;
  1949. break;
  1950. }
  1951. /* Timeout decreases with whatever time passed between the
  1952. last syscall and this. That's not exactly right for the
  1953. first call, but it's close enough that it isn't
  1954. worthwhile to complicate matters by making that a special
  1955. case. */
  1956. timeout
  1957. -= (TARGET_TIME_MS (current_cpu)
  1958. - (current_cpu->thread_data[threadno].last_execution));
  1959. /* Arrange to repeat this syscall until timeout or event,
  1960. decreasing timeout at each iteration. */
  1961. if (timeout > 0 && revents == 0)
  1962. {
  1963. bfd_byte timeout_buf[4];
  1964. bfd_putl32 (timeout, timeout_buf);
  1965. (*CPU_REG_STORE (current_cpu)) (current_cpu,
  1966. H_GR_R12, timeout_buf, 4);
  1967. sim_pc_set (current_cpu, pc);
  1968. retval = arg1;
  1969. break;
  1970. }
  1971. sim_core_write_unaligned_2 (current_cpu, pc, 0, ufds + 4 + 2,
  1972. revents);
  1973. break;
  1974. }
  1975. case TARGET_SYS_time:
  1976. {
  1977. retval = (int) (*cb->time) (cb);
  1978. /* At time of this writing, CB_SYSCALL_time doesn't do the
  1979. part of setting *arg1 to the return value. */
  1980. if (arg1)
  1981. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, retval);
  1982. break;
  1983. }
  1984. case TARGET_SYS_gettimeofday:
  1985. if (arg1 != 0)
  1986. {
  1987. USI ts = TARGET_TIME (current_cpu);
  1988. USI tms = TARGET_TIME_MS (current_cpu);
  1989. /* First dword is seconds since TARGET_EPOCH. */
  1990. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1, ts);
  1991. /* Second dword is microseconds. */
  1992. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg1 + 4,
  1993. (tms % 1000) * 1000);
  1994. }
  1995. if (arg2 != 0)
  1996. {
  1997. /* Time-zone info is always cleared. */
  1998. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, 0);
  1999. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, 0);
  2000. }
  2001. retval = 0;
  2002. break;
  2003. case TARGET_SYS_llseek:
  2004. {
  2005. /* If it fits, tweak parameters to fit the "generic" 32-bit
  2006. lseek and use that. */
  2007. SI fd = arg1;
  2008. SI offs_hi = arg2;
  2009. SI offs_lo = arg3;
  2010. SI resultp = arg4;
  2011. SI whence = arg5;
  2012. retval = 0;
  2013. if (!((offs_hi == 0 && offs_lo >= 0)
  2014. || (offs_hi == -1 && offs_lo < 0)))
  2015. {
  2016. retval
  2017. = cris_unknown_syscall (current_cpu, pc,
  2018. "Unimplemented llseek offset,"
  2019. " fd %d: 0x%x:0x%x\n",
  2020. fd, (unsigned) arg2,
  2021. (unsigned) arg3);
  2022. break;
  2023. }
  2024. s.func = TARGET_SYS_lseek;
  2025. s.arg2 = offs_lo;
  2026. s.arg3 = whence;
  2027. if (cb_syscall (cb, &s) != CB_RC_OK)
  2028. {
  2029. sim_io_eprintf (sd, "Break 13: invalid %d? Returned %ld\n", callnum,
  2030. s.result);
  2031. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGILL);
  2032. }
  2033. if (s.result < 0)
  2034. retval = -s.errcode;
  2035. else
  2036. {
  2037. sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp,
  2038. s.result);
  2039. sim_core_write_unaligned_4 (current_cpu, pc, 0, resultp + 4,
  2040. s.result < 0 ? -1 : 0);
  2041. }
  2042. break;
  2043. }
  2044. /* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
  2045. where:
  2046. struct iovec {
  2047. void *iov_base; Starting address
  2048. size_t iov_len; Number of bytes to transfer
  2049. }; */
  2050. case TARGET_SYS_writev:
  2051. {
  2052. SI fd = arg1;
  2053. SI iov = arg2;
  2054. SI iovcnt = arg3;
  2055. SI retcnt = 0;
  2056. int i;
  2057. /* We'll ignore strict error-handling and just do multiple write calls. */
  2058. for (i = 0; i < iovcnt; i++)
  2059. {
  2060. int sysret;
  2061. USI iov_base
  2062. = sim_core_read_unaligned_4 (current_cpu, pc, 0,
  2063. iov + 8*i);
  2064. USI iov_len
  2065. = sim_core_read_unaligned_4 (current_cpu, pc, 0,
  2066. iov + 8*i + 4);
  2067. s.func = TARGET_SYS_write;
  2068. s.arg1 = fd;
  2069. s.arg2 = iov_base;
  2070. s.arg3 = iov_len;
  2071. if (cb_syscall (cb, &s) != CB_RC_OK)
  2072. abort ();
  2073. sysret = s.result == -1 ? -s.errcode : s.result;
  2074. if (sysret != iov_len)
  2075. {
  2076. if (i != 0)
  2077. abort ();
  2078. retcnt = sysret;
  2079. break;
  2080. }
  2081. retcnt += iov_len;
  2082. }
  2083. retval = retcnt;
  2084. }
  2085. break;
  2086. /* This one does have a generic callback function, but at the time
  2087. of this writing, cb_syscall does not have code for it, and we
  2088. need target-specific code for the threads implementation
  2089. anyway. */
  2090. case TARGET_SYS_kill:
  2091. {
  2092. USI pid = arg1;
  2093. USI sig = arg2;
  2094. retval = 0;
  2095. /* At kill(2), glibc sets signal masks such that the thread
  2096. machinery is initialized. Still, there is and was only
  2097. one thread. */
  2098. if (current_cpu->max_threadid == 0)
  2099. {
  2100. if (pid != TARGET_PID)
  2101. {
  2102. retval = -cb_host_to_target_errno (cb, EPERM);
  2103. break;
  2104. }
  2105. /* FIXME: Signal infrastructure (target-to-sim mapping). */
  2106. if (sig == TARGET_SIGABRT)
  2107. /* A call "abort ()", i.e. "kill (getpid(), SIGABRT)" is
  2108. the end-point for failing GCC test-cases. */
  2109. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
  2110. SIM_SIGABRT);
  2111. else
  2112. {
  2113. sim_io_eprintf (sd, "Unimplemented signal: %d\n", sig);
  2114. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
  2115. SIM_SIGILL);
  2116. }
  2117. /* This will not be reached. */
  2118. abort ();
  2119. }
  2120. else
  2121. retval = deliver_signal (current_cpu, sig, pid);
  2122. break;
  2123. }
  2124. case TARGET_SYS_rt_sigprocmask:
  2125. {
  2126. int i;
  2127. USI how = arg1;
  2128. USI newsetp = arg2;
  2129. USI oldsetp = arg3;
  2130. if (how != TARGET_SIG_BLOCK
  2131. && how != TARGET_SIG_SETMASK
  2132. && how != TARGET_SIG_UNBLOCK)
  2133. {
  2134. retval
  2135. = cris_unknown_syscall (current_cpu, pc,
  2136. "Unimplemented rt_sigprocmask "
  2137. "syscall (0x%x, 0x%x, 0x%x)\n",
  2138. arg1, arg2, arg3);
  2139. break;
  2140. }
  2141. if (newsetp)
  2142. {
  2143. USI set_low
  2144. = sim_core_read_unaligned_4 (current_cpu, pc, 0,
  2145. newsetp);
  2146. USI set_high
  2147. = sim_core_read_unaligned_4 (current_cpu, pc, 0,
  2148. newsetp + 4);
  2149. /* The sigmask is kept in the per-thread data, so we may
  2150. need to create the first one. */
  2151. if (current_cpu->thread_data == NULL)
  2152. make_first_thread (current_cpu);
  2153. if (how == TARGET_SIG_SETMASK)
  2154. for (i = 0; i < 64; i++)
  2155. current_cpu->thread_data[threadno].sigdata[i].blocked = 0;
  2156. for (i = 0; i < 32; i++)
  2157. if ((set_low & (1 << i)))
  2158. current_cpu->thread_data[threadno].sigdata[i + 1].blocked
  2159. = (how != TARGET_SIG_UNBLOCK);
  2160. for (i = 0; i < 31; i++)
  2161. if ((set_high & (1 << i)))
  2162. current_cpu->thread_data[threadno].sigdata[i + 33].blocked
  2163. = (how != TARGET_SIG_UNBLOCK);
  2164. /* The mask changed, so a signal may be unblocked for
  2165. execution. */
  2166. current_cpu->thread_data[threadno].sigpending = 1;
  2167. }
  2168. if (oldsetp != 0)
  2169. {
  2170. USI set_low = 0;
  2171. USI set_high = 0;
  2172. for (i = 0; i < 32; i++)
  2173. if (current_cpu->thread_data[threadno]
  2174. .sigdata[i + 1].blocked)
  2175. set_low |= 1 << i;
  2176. for (i = 0; i < 31; i++)
  2177. if (current_cpu->thread_data[threadno]
  2178. .sigdata[i + 33].blocked)
  2179. set_high |= 1 << i;
  2180. sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 0, set_low);
  2181. sim_core_write_unaligned_4 (current_cpu, pc, 0, oldsetp + 4, set_high);
  2182. }
  2183. retval = 0;
  2184. break;
  2185. }
  2186. case TARGET_SYS_sigreturn:
  2187. {
  2188. int i;
  2189. bfd_byte regbuf[4];
  2190. int was_sigsuspended;
  2191. if (current_cpu->thread_data == NULL
  2192. /* The CPU context is saved with the simulator data, not
  2193. on the stack as in the real world. */
  2194. || (current_cpu->thread_data[threadno].cpu_context_atsignal
  2195. == NULL))
  2196. {
  2197. retval
  2198. = cris_unknown_syscall (current_cpu, pc,
  2199. "Invalid sigreturn syscall: "
  2200. "no signal handler active "
  2201. "(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
  2202. "0x%lx, 0x%lx)\n",
  2203. (unsigned long) arg1,
  2204. (unsigned long) arg2,
  2205. (unsigned long) arg3,
  2206. (unsigned long) arg4,
  2207. (unsigned long) arg5,
  2208. (unsigned long) arg6);
  2209. break;
  2210. }
  2211. was_sigsuspended
  2212. = current_cpu->thread_data[threadno].sigsuspended;
  2213. /* Restore the sigmask, either from the stack copy made when
  2214. the sighandler was called, or from the saved state
  2215. specifically for sigsuspend(2). */
  2216. if (was_sigsuspended)
  2217. {
  2218. current_cpu->thread_data[threadno].sigsuspended = 0;
  2219. for (i = 0; i < 64; i++)
  2220. current_cpu->thread_data[threadno].sigdata[i].blocked
  2221. = current_cpu->thread_data[threadno]
  2222. .sigdata[i].blocked_suspendsave;
  2223. }
  2224. else
  2225. {
  2226. USI sp;
  2227. USI set_low;
  2228. USI set_high;
  2229. (*CPU_REG_FETCH (current_cpu)) (current_cpu,
  2230. H_GR_SP, regbuf, 4);
  2231. sp = bfd_getl32 (regbuf);
  2232. set_low
  2233. = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp);
  2234. set_high
  2235. = sim_core_read_unaligned_4 (current_cpu, pc, 0, sp + 4);
  2236. for (i = 0; i < 32; i++)
  2237. current_cpu->thread_data[threadno].sigdata[i + 1].blocked
  2238. = (set_low & (1 << i)) != 0;
  2239. for (i = 0; i < 31; i++)
  2240. current_cpu->thread_data[threadno].sigdata[i + 33].blocked
  2241. = (set_high & (1 << i)) != 0;
  2242. }
  2243. /* The mask changed, so a signal may be unblocked for
  2244. execution. */
  2245. current_cpu->thread_data[threadno].sigpending = 1;
  2246. memcpy (&current_cpu->cpu_data_placeholder,
  2247. current_cpu->thread_data[threadno].cpu_context_atsignal,
  2248. current_cpu->thread_cpu_data_size);
  2249. free (current_cpu->thread_data[threadno].cpu_context_atsignal);
  2250. current_cpu->thread_data[threadno].cpu_context_atsignal = NULL;
  2251. /* The return value must come from the saved R10. */
  2252. (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, regbuf, 4);
  2253. retval = bfd_getl32 (regbuf);
  2254. /* We must also break the "sigsuspension loop". */
  2255. if (was_sigsuspended)
  2256. sim_pc_set (current_cpu, sim_pc_get (current_cpu) + 2);
  2257. break;
  2258. }
  2259. case TARGET_SYS_rt_sigsuspend:
  2260. {
  2261. USI newsetp = arg1;
  2262. USI setsize = arg2;
  2263. if (setsize != 8)
  2264. {
  2265. retval
  2266. = cris_unknown_syscall (current_cpu, pc,
  2267. "Unimplemented rt_sigsuspend syscall"
  2268. " arguments (0x%lx, 0x%lx)\n",
  2269. (unsigned long) arg1,
  2270. (unsigned long) arg2);
  2271. break;
  2272. }
  2273. /* Don't change the signal mask if we're already in
  2274. sigsuspend state (i.e. this syscall is a rerun). */
  2275. else if (!current_cpu->thread_data[threadno].sigsuspended)
  2276. {
  2277. USI set_low
  2278. = sim_core_read_unaligned_4 (current_cpu, pc, 0,
  2279. newsetp);
  2280. USI set_high
  2281. = sim_core_read_unaligned_4 (current_cpu, pc, 0,
  2282. newsetp + 4);
  2283. int i;
  2284. /* Save the current sigmask and insert the user-supplied
  2285. one. */
  2286. for (i = 0; i < 32; i++)
  2287. {
  2288. current_cpu->thread_data[threadno]
  2289. .sigdata[i + 1].blocked_suspendsave
  2290. = current_cpu->thread_data[threadno]
  2291. .sigdata[i + 1].blocked;
  2292. current_cpu->thread_data[threadno]
  2293. .sigdata[i + 1].blocked = (set_low & (1 << i)) != 0;
  2294. }
  2295. for (i = 0; i < 31; i++)
  2296. {
  2297. current_cpu->thread_data[threadno]
  2298. .sigdata[i + 33].blocked_suspendsave
  2299. = current_cpu->thread_data[threadno]
  2300. .sigdata[i + 33].blocked;
  2301. current_cpu->thread_data[threadno]
  2302. .sigdata[i + 33].blocked = (set_high & (1 << i)) != 0;
  2303. }
  2304. current_cpu->thread_data[threadno].sigsuspended = 1;
  2305. /* The mask changed, so a signal may be unblocked for
  2306. execution. */
  2307. current_cpu->thread_data[threadno].sigpending = 1;
  2308. }
  2309. /* Because we don't use arg1 (newsetp) when this syscall is
  2310. rerun, it doesn't matter that we overwrite it with the
  2311. (constant) return value. */
  2312. retval = -cb_host_to_target_errno (cb, EINTR);
  2313. sim_pc_set (current_cpu, pc);
  2314. break;
  2315. }
  2316. /* Add case labels here for other syscalls using the 32-bit
  2317. "struct stat", provided they have a corresponding simulator
  2318. function of course. */
  2319. case TARGET_SYS_stat:
  2320. case TARGET_SYS_fstat:
  2321. {
  2322. /* As long as the infrastructure doesn't cache anything
  2323. related to the stat mapping, this trick gets us a dual
  2324. "struct stat"-type mapping in the least error-prone way. */
  2325. const char *saved_map = cb->stat_map;
  2326. CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
  2327. cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_stat32_map;
  2328. cb->stat_map = stat32_map;
  2329. if (cb_syscall (cb, &s) != CB_RC_OK)
  2330. {
  2331. abort ();
  2332. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
  2333. SIM_SIGILL);
  2334. }
  2335. retval = s.result == -1 ? -s.errcode : s.result;
  2336. cb->stat_map = saved_map;
  2337. cb->syscall_map = saved_syscall_map;
  2338. break;
  2339. }
  2340. case TARGET_SYS_getcwd:
  2341. {
  2342. USI buf = arg1;
  2343. USI size = arg2;
  2344. char *cwd = xmalloc (SIM_PATHMAX);
  2345. if (cwd != getcwd (cwd, SIM_PATHMAX))
  2346. abort ();
  2347. /* FIXME: When and if we support chdir, we need something
  2348. a bit more elaborate. */
  2349. if (simulator_sysroot[0] != '\0')
  2350. strcpy (cwd, "/");
  2351. retval = -cb_host_to_target_errno (cb, ERANGE);
  2352. if (strlen (cwd) + 1 <= size)
  2353. {
  2354. retval = strlen (cwd) + 1;
  2355. if (sim_core_write_buffer (sd, current_cpu, 0, cwd,
  2356. buf, retval)
  2357. != (unsigned int) retval)
  2358. retval = -cb_host_to_target_errno (cb, EFAULT);
  2359. }
  2360. free (cwd);
  2361. break;
  2362. }
  2363. case TARGET_SYS_access:
  2364. {
  2365. SI path = arg1;
  2366. SI mode = arg2;
  2367. char *pbuf = xmalloc (SIM_PATHMAX);
  2368. int i;
  2369. int o = 0;
  2370. int hmode = 0;
  2371. if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
  2372. {
  2373. strcpy (pbuf, simulator_sysroot);
  2374. o += strlen (simulator_sysroot);
  2375. }
  2376. for (i = 0; i + o < SIM_PATHMAX; i++)
  2377. {
  2378. pbuf[i + o]
  2379. = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
  2380. if (pbuf[i + o] == 0)
  2381. break;
  2382. }
  2383. if (i + o == SIM_PATHMAX)
  2384. {
  2385. retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
  2386. break;
  2387. }
  2388. /* Assert that we don't get calls for files for which we
  2389. don't have support. */
  2390. if (strncmp (pbuf + strlen (simulator_sysroot),
  2391. "/proc/", 6) == 0)
  2392. abort ();
  2393. #define X_AFLAG(x) if (mode & TARGET_ ## x) hmode |= x
  2394. X_AFLAG (R_OK);
  2395. X_AFLAG (W_OK);
  2396. X_AFLAG (X_OK);
  2397. X_AFLAG (F_OK);
  2398. #undef X_AFLAG
  2399. if (access (pbuf, hmode) != 0)
  2400. retval = -cb_host_to_target_errno (cb, errno);
  2401. else
  2402. retval = 0;
  2403. free (pbuf);
  2404. break;
  2405. }
  2406. case TARGET_SYS_readlink:
  2407. {
  2408. SI path = arg1;
  2409. SI buf = arg2;
  2410. SI bufsiz = arg3;
  2411. char *pbuf = xmalloc (SIM_PATHMAX);
  2412. char *lbuf = xmalloc (SIM_PATHMAX);
  2413. char *lbuf_alloc = lbuf;
  2414. int nchars = -1;
  2415. int i;
  2416. int o = 0;
  2417. if (sim_core_read_unaligned_1 (current_cpu, pc, 0, path) == '/')
  2418. {
  2419. strcpy (pbuf, simulator_sysroot);
  2420. o += strlen (simulator_sysroot);
  2421. }
  2422. for (i = 0; i + o < SIM_PATHMAX; i++)
  2423. {
  2424. pbuf[i + o]
  2425. = sim_core_read_unaligned_1 (current_cpu, pc, 0, path + i);
  2426. if (pbuf[i + o] == 0)
  2427. break;
  2428. }
  2429. if (i + o == SIM_PATHMAX)
  2430. {
  2431. retval = -cb_host_to_target_errno (cb, ENAMETOOLONG);
  2432. break;
  2433. }
  2434. /* Intervene calls for certain files expected in the target
  2435. proc file system. */
  2436. if (strcmp (pbuf + strlen (simulator_sysroot),
  2437. "/proc/" XSTRING (TARGET_PID) "/exe") == 0)
  2438. {
  2439. char *argv0
  2440. = (STATE_PROG_ARGV (sd) != NULL
  2441. ? *STATE_PROG_ARGV (sd) : NULL);
  2442. if (argv0 == NULL || *argv0 == '.')
  2443. {
  2444. retval
  2445. = cris_unknown_syscall (current_cpu, pc,
  2446. "Unimplemented readlink syscall "
  2447. "(0x%lx: [\"%s\"], 0x%lx)\n",
  2448. (unsigned long) arg1, pbuf,
  2449. (unsigned long) arg2);
  2450. break;
  2451. }
  2452. else if (*argv0 == '/')
  2453. {
  2454. if (strncmp (simulator_sysroot, argv0,
  2455. strlen (simulator_sysroot)) == 0)
  2456. argv0 += strlen (simulator_sysroot);
  2457. strcpy (lbuf, argv0);
  2458. nchars = strlen (argv0) + 1;
  2459. }
  2460. else
  2461. {
  2462. if (getcwd (lbuf, SIM_PATHMAX) != NULL
  2463. && strlen (lbuf) + 2 + strlen (argv0) < SIM_PATHMAX)
  2464. {
  2465. if (strncmp (simulator_sysroot, lbuf,
  2466. strlen (simulator_sysroot)) == 0)
  2467. lbuf += strlen (simulator_sysroot);
  2468. strcat (lbuf, "/");
  2469. strcat (lbuf, argv0);
  2470. nchars = strlen (lbuf) + 1;
  2471. }
  2472. else
  2473. abort ();
  2474. }
  2475. }
  2476. else
  2477. nchars = readlink (pbuf, lbuf, SIM_PATHMAX);
  2478. /* We trust that the readlink result returns a *relative*
  2479. link, or one already adjusted for the file-path-prefix.
  2480. (We can't generally tell the difference, so we go with
  2481. the easiest decision; no adjustment.) */
  2482. if (nchars == -1)
  2483. {
  2484. retval = -cb_host_to_target_errno (cb, errno);
  2485. break;
  2486. }
  2487. if (bufsiz < nchars)
  2488. nchars = bufsiz;
  2489. if (sim_core_write_buffer (sd, current_cpu, write_map, lbuf,
  2490. buf, nchars) != (unsigned int) nchars)
  2491. retval = -cb_host_to_target_errno (cb, EFAULT);
  2492. else
  2493. retval = nchars;
  2494. free (pbuf);
  2495. free (lbuf_alloc);
  2496. break;
  2497. }
  2498. case TARGET_SYS_sched_getscheduler:
  2499. {
  2500. USI pid = arg1;
  2501. /* FIXME: Search (other) existing threads. */
  2502. if (pid != 0 && pid != TARGET_PID)
  2503. retval = -cb_host_to_target_errno (cb, ESRCH);
  2504. else
  2505. retval = TARGET_SCHED_OTHER;
  2506. break;
  2507. }
  2508. case TARGET_SYS_sched_getparam:
  2509. {
  2510. USI pid = arg1;
  2511. USI paramp = arg2;
  2512. /* The kernel says:
  2513. struct sched_param {
  2514. int sched_priority;
  2515. }; */
  2516. if (pid != 0 && pid != TARGET_PID)
  2517. retval = -cb_host_to_target_errno (cb, ESRCH);
  2518. else
  2519. {
  2520. /* FIXME: Save scheduler setting before threads are
  2521. created too. */
  2522. sim_core_write_unaligned_4 (current_cpu, pc, 0, paramp,
  2523. current_cpu->thread_data != NULL
  2524. ? (current_cpu
  2525. ->thread_data[threadno]
  2526. .priority)
  2527. : 0);
  2528. retval = 0;
  2529. }
  2530. break;
  2531. }
  2532. case TARGET_SYS_sched_setparam:
  2533. {
  2534. USI pid = arg1;
  2535. USI paramp = arg2;
  2536. if ((pid != 0 && pid != TARGET_PID)
  2537. || sim_core_read_unaligned_4 (current_cpu, pc, 0,
  2538. paramp) != 0)
  2539. retval = -cb_host_to_target_errno (cb, EINVAL);
  2540. else
  2541. retval = 0;
  2542. break;
  2543. }
  2544. case TARGET_SYS_sched_setscheduler:
  2545. {
  2546. USI pid = arg1;
  2547. USI policy = arg2;
  2548. USI paramp = arg3;
  2549. if ((pid != 0 && pid != TARGET_PID)
  2550. || policy != TARGET_SCHED_OTHER
  2551. || sim_core_read_unaligned_4 (current_cpu, pc, 0,
  2552. paramp) != 0)
  2553. retval = -cb_host_to_target_errno (cb, EINVAL);
  2554. else
  2555. /* FIXME: Save scheduler setting to be read in later
  2556. sched_getparam calls. */
  2557. retval = 0;
  2558. break;
  2559. }
  2560. case TARGET_SYS_sched_yield:
  2561. /* We reschedule to the next thread after a syscall anyway, so
  2562. we don't have to do anything here than to set the return
  2563. value. */
  2564. retval = 0;
  2565. break;
  2566. case TARGET_SYS_sched_get_priority_min:
  2567. case TARGET_SYS_sched_get_priority_max:
  2568. if (arg1 != 0)
  2569. retval = -cb_host_to_target_errno (cb, EINVAL);
  2570. else
  2571. retval = 0;
  2572. break;
  2573. case TARGET_SYS_ugetrlimit:
  2574. {
  2575. unsigned int curlim, maxlim;
  2576. if (arg1 != TARGET_RLIMIT_STACK && arg1 != TARGET_RLIMIT_NOFILE)
  2577. {
  2578. retval = -cb_host_to_target_errno (cb, EINVAL);
  2579. break;
  2580. }
  2581. /* The kernel says:
  2582. struct rlimit {
  2583. unsigned long rlim_cur;
  2584. unsigned long rlim_max;
  2585. }; */
  2586. if (arg1 == TARGET_RLIMIT_NOFILE)
  2587. {
  2588. /* Sadly a very low limit. Better not lie, though. */
  2589. maxlim = curlim = MAX_CALLBACK_FDS;
  2590. }
  2591. else /* arg1 == TARGET_RLIMIT_STACK */
  2592. {
  2593. maxlim = 0xffffffff;
  2594. curlim = 0x800000;
  2595. }
  2596. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2, curlim);
  2597. sim_core_write_unaligned_4 (current_cpu, pc, 0, arg2 + 4, maxlim);
  2598. retval = 0;
  2599. break;
  2600. }
  2601. case TARGET_SYS_setrlimit:
  2602. if (arg1 != TARGET_RLIMIT_STACK)
  2603. {
  2604. retval = -cb_host_to_target_errno (cb, EINVAL);
  2605. break;
  2606. }
  2607. /* FIXME: Save values for future ugetrlimit calls. */
  2608. retval = 0;
  2609. break;
  2610. /* Provide a very limited subset of the sysctl functions, and
  2611. abort for the rest. */
  2612. case TARGET_SYS__sysctl:
  2613. {
  2614. /* The kernel says:
  2615. struct __sysctl_args {
  2616. int *name;
  2617. int nlen;
  2618. void *oldval;
  2619. size_t *oldlenp;
  2620. void *newval;
  2621. size_t newlen;
  2622. unsigned long __unused[4];
  2623. }; */
  2624. SI name = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1);
  2625. SI name0 = name == 0
  2626. ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name);
  2627. SI name1 = name == 0
  2628. ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, name + 4);
  2629. SI nlen
  2630. = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 4);
  2631. SI oldval
  2632. = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 8);
  2633. SI oldlenp
  2634. = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 12);
  2635. SI oldlen = oldlenp == 0
  2636. ? 0 : sim_core_read_unaligned_4 (current_cpu, pc, 0, oldlenp);
  2637. SI newval
  2638. = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 16);
  2639. SI newlen
  2640. = sim_core_read_unaligned_4 (current_cpu, pc, 0, arg1 + 20);
  2641. if (name0 == TARGET_CTL_KERN && name1 == TARGET_CTL_KERN_VERSION)
  2642. {
  2643. SI to_write = oldlen < (SI) sizeof (TARGET_UTSNAME)
  2644. ? oldlen : (SI) sizeof (TARGET_UTSNAME);
  2645. sim_core_write_unaligned_4 (current_cpu, pc, 0, oldlenp,
  2646. sizeof (TARGET_UTSNAME));
  2647. if (sim_core_write_buffer (sd, current_cpu, write_map,
  2648. TARGET_UTSNAME, oldval,
  2649. to_write)
  2650. != (unsigned int) to_write)
  2651. retval = -cb_host_to_target_errno (cb, EFAULT);
  2652. else
  2653. retval = 0;
  2654. break;
  2655. }
  2656. retval
  2657. = cris_unknown_syscall (current_cpu, pc,
  2658. "Unimplemented _sysctl syscall "
  2659. "(0x%lx: [0x%lx, 0x%lx],"
  2660. " 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
  2661. (unsigned long) name,
  2662. (unsigned long) name0,
  2663. (unsigned long) name1,
  2664. (unsigned long) nlen,
  2665. (unsigned long) oldval,
  2666. (unsigned long) oldlenp,
  2667. (unsigned long) newval,
  2668. (unsigned long) newlen);
  2669. break;
  2670. }
  2671. case TARGET_SYS_exit:
  2672. {
  2673. /* Here for all but the last thread. */
  2674. int i;
  2675. int pid
  2676. = current_cpu->thread_data[threadno].threadid + TARGET_PID;
  2677. int ppid
  2678. = (current_cpu->thread_data[threadno].parent_threadid
  2679. + TARGET_PID);
  2680. int exitsig = current_cpu->thread_data[threadno].exitsig;
  2681. /* Any children are now all orphans. */
  2682. for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
  2683. if (current_cpu->thread_data[i].parent_threadid
  2684. == current_cpu->thread_data[threadno].threadid)
  2685. /* Make getppid(2) return 1 for them, poor little ones. */
  2686. current_cpu->thread_data[i].parent_threadid = -TARGET_PID + 1;
  2687. /* Free the cpu context data. When the parent has received
  2688. the exit status, we'll clear the entry too. */
  2689. free (current_cpu->thread_data[threadno].cpu_context);
  2690. current_cpu->thread_data[threadno].cpu_context = NULL;
  2691. current_cpu->m1threads--;
  2692. if (arg1 != 0)
  2693. {
  2694. sim_io_eprintf (sd, "Thread %d exited with status %d\n",
  2695. pid, arg1);
  2696. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped,
  2697. SIM_SIGILL);
  2698. }
  2699. /* Still, we may want to support non-zero exit values. */
  2700. current_cpu->thread_data[threadno].exitval = arg1 << 8;
  2701. if (exitsig)
  2702. deliver_signal (current_cpu, exitsig, ppid);
  2703. break;
  2704. }
  2705. case TARGET_SYS_clone:
  2706. {
  2707. int nthreads = current_cpu->m1threads + 1;
  2708. void *thread_cpu_data;
  2709. bfd_byte old_sp_buf[4];
  2710. bfd_byte sp_buf[4];
  2711. const bfd_byte zeros[4] = { 0, 0, 0, 0 };
  2712. int i;
  2713. /* That's right, the syscall clone arguments are reversed
  2714. compared to sys_clone notes in clone(2) and compared to
  2715. other Linux ports (i.e. it's the same order as in the
  2716. clone(2) libcall). */
  2717. USI flags = arg2;
  2718. USI newsp = arg1;
  2719. if (nthreads == SIM_TARGET_MAX_THREADS)
  2720. {
  2721. retval = -cb_host_to_target_errno (cb, EAGAIN);
  2722. break;
  2723. }
  2724. /* FIXME: Implement the low byte. */
  2725. if ((flags & ~TARGET_CSIGNAL) !=
  2726. (TARGET_CLONE_VM
  2727. | TARGET_CLONE_FS
  2728. | TARGET_CLONE_FILES
  2729. | TARGET_CLONE_SIGHAND)
  2730. || newsp == 0)
  2731. {
  2732. retval
  2733. = cris_unknown_syscall (current_cpu, pc,
  2734. "Unimplemented clone syscall "
  2735. "(0x%lx, 0x%lx)\n",
  2736. (unsigned long) arg1,
  2737. (unsigned long) arg2);
  2738. break;
  2739. }
  2740. if (current_cpu->thread_data == NULL)
  2741. make_first_thread (current_cpu);
  2742. /* The created thread will get the new SP and a cleared R10.
  2743. Since it's created out of a copy of the old thread and we
  2744. don't have a set-register-function that just take the
  2745. cpu_data as a parameter, we set the childs values first,
  2746. and write back or overwrite them in the parent after the
  2747. copy. */
  2748. (*CPU_REG_FETCH (current_cpu)) (current_cpu,
  2749. H_GR_SP, old_sp_buf, 4);
  2750. bfd_putl32 (newsp, sp_buf);
  2751. (*CPU_REG_STORE (current_cpu)) (current_cpu,
  2752. H_GR_SP, sp_buf, 4);
  2753. (*CPU_REG_STORE (current_cpu)) (current_cpu,
  2754. H_GR_R10, (bfd_byte *) zeros, 4);
  2755. thread_cpu_data
  2756. = (*current_cpu
  2757. ->make_thread_cpu_data) (current_cpu,
  2758. &current_cpu->cpu_data_placeholder);
  2759. (*CPU_REG_STORE (current_cpu)) (current_cpu,
  2760. H_GR_SP, old_sp_buf, 4);
  2761. retval = ++current_cpu->max_threadid + TARGET_PID;
  2762. /* Find an unused slot. After a few threads have been created
  2763. and exited, the array is expected to be a bit fragmented.
  2764. We don't reuse the first entry, though, that of the
  2765. original thread. */
  2766. for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
  2767. if (current_cpu->thread_data[i].cpu_context == NULL
  2768. /* Don't reuse a zombied entry. */
  2769. && current_cpu->thread_data[i].threadid == 0)
  2770. break;
  2771. memcpy (&current_cpu->thread_data[i],
  2772. &current_cpu->thread_data[threadno],
  2773. sizeof (current_cpu->thread_data[i]));
  2774. current_cpu->thread_data[i].cpu_context = thread_cpu_data;
  2775. current_cpu->thread_data[i].cpu_context_atsignal = NULL;
  2776. current_cpu->thread_data[i].threadid = current_cpu->max_threadid;
  2777. current_cpu->thread_data[i].parent_threadid
  2778. = current_cpu->thread_data[threadno].threadid;
  2779. current_cpu->thread_data[i].pipe_read_fd = 0;
  2780. current_cpu->thread_data[i].pipe_write_fd = 0;
  2781. current_cpu->thread_data[i].at_syscall = 0;
  2782. current_cpu->thread_data[i].sigpending = 0;
  2783. current_cpu->thread_data[i].sigsuspended = 0;
  2784. current_cpu->thread_data[i].exitsig = flags & TARGET_CSIGNAL;
  2785. current_cpu->m1threads = nthreads;
  2786. break;
  2787. }
  2788. /* Better watch these in case they do something necessary. */
  2789. case TARGET_SYS_socketcall:
  2790. retval = -cb_host_to_target_errno (cb, ENOSYS);
  2791. break;
  2792. case TARGET_SYS_set_thread_area:
  2793. /* Do the same error check as Linux. */
  2794. if (arg1 & 255)
  2795. {
  2796. retval = -cb_host_to_target_errno (cb, EINVAL);
  2797. break;
  2798. }
  2799. (*current_cpu->set_target_thread_data) (current_cpu, arg1);
  2800. retval = 0;
  2801. break;
  2802. unimplemented_syscall:
  2803. default:
  2804. retval
  2805. = cris_unknown_syscall (current_cpu, pc,
  2806. "Unimplemented syscall: %d "
  2807. "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
  2808. callnum, arg1, arg2, arg3, arg4, arg5,
  2809. arg6);
  2810. }
  2811. }
  2812. /* Minimal support for fcntl F_GETFL as used in open+fdopen. */
  2813. if (callnum == TARGET_SYS_open)
  2814. {
  2815. current_cpu->last_open_fd = retval;
  2816. current_cpu->last_open_flags = arg2;
  2817. }
  2818. current_cpu->last_syscall = callnum;
  2819. /* A system call is a rescheduling point. For the time being, we don't
  2820. reschedule anywhere else. */
  2821. if (current_cpu->m1threads != 0
  2822. /* We need to schedule off from an exiting thread that is the
  2823. second-last one. */
  2824. || (current_cpu->thread_data != NULL
  2825. && current_cpu->thread_data[threadno].cpu_context == NULL))
  2826. {
  2827. bfd_byte retval_buf[4];
  2828. current_cpu->thread_data[threadno].last_execution
  2829. = TARGET_TIME_MS (current_cpu);
  2830. bfd_putl32 (retval, retval_buf);
  2831. (*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
  2832. current_cpu->thread_data[threadno].at_syscall = 1;
  2833. reschedule (current_cpu);
  2834. (*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
  2835. retval = bfd_getl32 (retval_buf);
  2836. }
  2837. return retval;
  2838. }
  2839. /* Callback from simulator write saying that the pipe at (reader, writer)
  2840. is now non-empty (so the writer should wait until the pipe is empty, at
  2841. least not write to this or any other pipe). Simplest is to just wait
  2842. until the pipe is empty. */
  2843. static void
  2844. cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
  2845. int reader, int writer)
  2846. {
  2847. SIM_CPU *cpu = current_cpu_for_cb_callback;
  2848. const bfd_byte zeros[4] = { 0, 0, 0, 0 };
  2849. /* It's the current thread: we just have to re-run the current
  2850. syscall instruction (presumably "break 13") and change the syscall
  2851. to the special simulator-wait code. Oh, and set a marker that
  2852. we're waiting, so we can disambiguate the special call from a
  2853. program error.
  2854. This function may be called multiple times between cris_pipe_empty,
  2855. but we must avoid e.g. decreasing PC every time. Check fd markers
  2856. to tell. */
  2857. if (cpu->thread_data == NULL)
  2858. {
  2859. sim_io_eprintf (CPU_STATE (cpu),
  2860. "Terminating simulation due to writing pipe rd:wr %d:%d"
  2861. " from one single thread\n", reader, writer);
  2862. sim_engine_halt (CPU_STATE (cpu), cpu,
  2863. NULL, sim_pc_get (cpu), sim_stopped, SIM_SIGILL);
  2864. }
  2865. else if (cpu->thread_data[cpu->threadno].pipe_write_fd == 0)
  2866. {
  2867. cpu->thread_data[cpu->threadno].pipe_write_fd = writer;
  2868. cpu->thread_data[cpu->threadno].pipe_read_fd = reader;
  2869. /* FIXME: We really shouldn't change registers other than R10 in
  2870. syscalls (like R9), here or elsewhere. */
  2871. (*CPU_REG_STORE (cpu)) (cpu, H_GR_R9, (bfd_byte *) zeros, 4);
  2872. sim_pc_set (cpu, sim_pc_get (cpu) - 2);
  2873. }
  2874. }
  2875. /* Callback from simulator close or read call saying that the pipe at
  2876. (reader, writer) is now empty (so the writer can write again, perhaps
  2877. leave a waiting state). If there are bytes remaining, they couldn't be
  2878. consumed (perhaps due to the pipe closing). */
  2879. static void
  2880. cris_pipe_empty (host_callback *cb,
  2881. int reader,
  2882. int writer)
  2883. {
  2884. int i;
  2885. SIM_CPU *cpu = current_cpu_for_cb_callback;
  2886. SIM_DESC sd = CPU_STATE (current_cpu_for_cb_callback);
  2887. bfd_byte r10_buf[4];
  2888. int remaining
  2889. = cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size;
  2890. /* We need to find the thread that waits for this pipe. */
  2891. for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
  2892. if (cpu->thread_data[i].cpu_context
  2893. && cpu->thread_data[i].pipe_write_fd == writer)
  2894. {
  2895. int retval;
  2896. /* Temporarily switch to this cpu context, so we can change the
  2897. PC by ordinary calls. */
  2898. memcpy (cpu->thread_data[cpu->threadno].cpu_context,
  2899. &cpu->cpu_data_placeholder,
  2900. cpu->thread_cpu_data_size);
  2901. memcpy (&cpu->cpu_data_placeholder,
  2902. cpu->thread_data[i].cpu_context,
  2903. cpu->thread_cpu_data_size);
  2904. /* The return value is supposed to contain the number of
  2905. written bytes, which is the number of bytes requested and
  2906. returned at the write call. You might think the right
  2907. thing is to adjust the return-value to be only the
  2908. *consumed* number of bytes, but it isn't. We're only
  2909. called if the pipe buffer is fully consumed or it is being
  2910. closed, possibly with remaining bytes. For the latter
  2911. case, the writer is still supposed to see success for
  2912. PIPE_BUF bytes (a constant which we happen to know and is
  2913. unlikely to change). The return value may also be a
  2914. negative number; an error value. This case is covered
  2915. because "remaining" is always >= 0. */
  2916. (*CPU_REG_FETCH (cpu)) (cpu, H_GR_R10, r10_buf, 4);
  2917. retval = (int) bfd_getl_signed_32 (r10_buf);
  2918. if (retval - remaining > TARGET_PIPE_BUF)
  2919. {
  2920. bfd_putl32 (retval - remaining, r10_buf);
  2921. (*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4);
  2922. }
  2923. sim_pc_set (cpu, sim_pc_get (cpu) + 2);
  2924. memcpy (cpu->thread_data[i].cpu_context,
  2925. &cpu->cpu_data_placeholder,
  2926. cpu->thread_cpu_data_size);
  2927. memcpy (&cpu->cpu_data_placeholder,
  2928. cpu->thread_data[cpu->threadno].cpu_context,
  2929. cpu->thread_cpu_data_size);
  2930. cpu->thread_data[i].pipe_read_fd = 0;
  2931. cpu->thread_data[i].pipe_write_fd = 0;
  2932. return;
  2933. }
  2934. abort ();
  2935. }
  2936. /* We have a simulator-specific notion of time. See TARGET_TIME. */
  2937. static int64_t
  2938. cris_time (host_callback *cb ATTRIBUTE_UNUSED)
  2939. {
  2940. return TARGET_TIME (current_cpu_for_cb_callback);
  2941. }
  2942. static int
  2943. cris_getpid (host_callback *cb ATTRIBUTE_UNUSED)
  2944. {
  2945. return TARGET_PID;
  2946. }
  2947. /* Set target-specific callback data. */
  2948. void
  2949. cris_set_callbacks (host_callback *cb)
  2950. {
  2951. /* Yeargh, have to cast away constness to avoid warnings. */
  2952. cb->syscall_map = (CB_TARGET_DEFS_MAP *) syscall_map;
  2953. cb->errno_map = (CB_TARGET_DEFS_MAP *) errno_map;
  2954. cb->getpid = cris_getpid;
  2955. /* The kernel stat64 layout. If we see a file > 2G, the "long"
  2956. parameter to cb_store_target_endian will make st_size negative.
  2957. Similarly for st_ino. FIXME: Find a 64-bit type, and use it
  2958. *unsigned*, and/or add syntax for signed-ness. */
  2959. cb->stat_map = stat_map;
  2960. cb->open_map = (CB_TARGET_DEFS_MAP *) open_map;
  2961. cb->pipe_nonempty = cris_pipe_nonempty;
  2962. cb->pipe_empty = cris_pipe_empty;
  2963. cb->time = cris_time;
  2964. }
  2965. /* Process an address exception. */
  2966. void
  2967. cris_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
  2968. unsigned int map, int nr_bytes, address_word addr,
  2969. transfer_type transfer, sim_core_signals sig)
  2970. {
  2971. sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
  2972. transfer, sig);
  2973. }