Commit 31e31b8a248ffa216223dad49f75efbdfca5df23
1 parent
e63c3dc7
This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
16 changed files
with
5791 additions
and
0 deletions
COPYING.LIB
0 → 100644
| 1 | +------------------------------------------------------------------------------ | |
| 2 | +NOTE: | |
| 3 | +Some code of the Twin package was modified for DOSEMU by the DOSEMU-team. | |
| 4 | +The original is 'Copyright 1997 Willows Software, Inc.' and generously | |
| 5 | +was put under the GNU Library General Public License. | |
| 6 | +( for more information see http://www.willows.com/ ) | |
| 7 | + | |
| 8 | +We make use of section 3 of the GNU Library General Public License | |
| 9 | +('...opt to apply the terms of the ordinary GNU General Public License...'), | |
| 10 | +because the resulting product is an integrated part of DOSEMU and | |
| 11 | +can not be considered to be a 'library' in the terms of Library License. | |
| 12 | + | |
| 13 | +Therefore, the below GNU LIBRARY GENERAL PUBLIC LICENSE applies only to the | |
| 14 | +_unchanged_ Twin package from Willows. For the DOSEMU-changed parts the normal | |
| 15 | +GNU GENERAL PUBLIC LICENSE applies. This GPL (file COPYING) can be found in | |
| 16 | +the root directory of the DOSEMU distribution. | |
| 17 | + | |
| 18 | +The act of transformation to GPL was indicated to the maintainer of the Twin | |
| 19 | +package (Rob Penrose <rob@Canopy.Com>) and he acknowledge agreement. | |
| 20 | + | |
| 21 | +Nov. 1 1997, The DOSEMU team. | |
| 22 | + | |
| 23 | +------------------------------------------------------------------------------ | |
| 24 | + GNU LIBRARY GENERAL PUBLIC LICENSE | |
| 25 | + Version 2, June 1991 | |
| 26 | + | |
| 27 | + Copyright (C) 1991 Free Software Foundation, Inc. | |
| 28 | + 675 Mass Ave, Cambridge, MA 02139, USA | |
| 29 | + Everyone is permitted to copy and distribute verbatim copies | |
| 30 | + of this license document, but changing it is not allowed. | |
| 31 | + | |
| 32 | +[This is the first released version of the library GPL. It is | |
| 33 | + numbered 2 because it goes with version 2 of the ordinary GPL.] | |
| 34 | + | |
| 35 | + Preamble | |
| 36 | + | |
| 37 | + The licenses for most software are designed to take away your | |
| 38 | +freedom to share and change it. By contrast, the GNU General Public | |
| 39 | +Licenses are intended to guarantee your freedom to share and change | |
| 40 | +free software--to make sure the software is free for all its users. | |
| 41 | + | |
| 42 | + This license, the Library General Public License, applies to some | |
| 43 | +specially designated Free Software Foundation software, and to any | |
| 44 | +other libraries whose authors decide to use it. You can use it for | |
| 45 | +your libraries, too. | |
| 46 | + | |
| 47 | + When we speak of free software, we are referring to freedom, not | |
| 48 | +price. Our General Public Licenses are designed to make sure that you | |
| 49 | +have the freedom to distribute copies of free software (and charge for | |
| 50 | +this service if you wish), that you receive source code or can get it | |
| 51 | +if you want it, that you can change the software or use pieces of it | |
| 52 | +in new free programs; and that you know you can do these things. | |
| 53 | + | |
| 54 | + To protect your rights, we need to make restrictions that forbid | |
| 55 | +anyone to deny you these rights or to ask you to surrender the rights. | |
| 56 | +These restrictions translate to certain responsibilities for you if | |
| 57 | +you distribute copies of the library, or if you modify it. | |
| 58 | + | |
| 59 | + For example, if you distribute copies of the library, whether gratis | |
| 60 | +or for a fee, you must give the recipients all the rights that we gave | |
| 61 | +you. You must make sure that they, too, receive or can get the source | |
| 62 | +code. If you link a program with the library, you must provide | |
| 63 | +complete object files to the recipients so that they can relink them | |
| 64 | +with the library, after making changes to the library and recompiling | |
| 65 | +it. And you must show them these terms so they know their rights. | |
| 66 | + | |
| 67 | + Our method of protecting your rights has two steps: (1) copyright | |
| 68 | +the library, and (2) offer you this license which gives you legal | |
| 69 | +permission to copy, distribute and/or modify the library. | |
| 70 | + | |
| 71 | + Also, for each distributor's protection, we want to make certain | |
| 72 | +that everyone understands that there is no warranty for this free | |
| 73 | +library. If the library is modified by someone else and passed on, we | |
| 74 | +want its recipients to know that what they have is not the original | |
| 75 | +version, so that any problems introduced by others will not reflect on | |
| 76 | +the original authors' reputations. | |
| 77 | + | |
| 78 | + Finally, any free program is threatened constantly by software | |
| 79 | +patents. We wish to avoid the danger that companies distributing free | |
| 80 | +software will individually obtain patent licenses, thus in effect | |
| 81 | +transforming the program into proprietary software. To prevent this, | |
| 82 | +we have made it clear that any patent must be licensed for everyone's | |
| 83 | +free use or not licensed at all. | |
| 84 | + | |
| 85 | + Most GNU software, including some libraries, is covered by the ordinary | |
| 86 | +GNU General Public License, which was designed for utility programs. This | |
| 87 | +license, the GNU Library General Public License, applies to certain | |
| 88 | +designated libraries. This license is quite different from the ordinary | |
| 89 | +one; be sure to read it in full, and don't assume that anything in it is | |
| 90 | +the same as in the ordinary license. | |
| 91 | + | |
| 92 | + The reason we have a separate public license for some libraries is that | |
| 93 | +they blur the distinction we usually make between modifying or adding to a | |
| 94 | +program and simply using it. Linking a program with a library, without | |
| 95 | +changing the library, is in some sense simply using the library, and is | |
| 96 | +analogous to running a utility program or application program. However, in | |
| 97 | +a textual and legal sense, the linked executable is a combined work, a | |
| 98 | +derivative of the original library, and the ordinary General Public License | |
| 99 | +treats it as such. | |
| 100 | + | |
| 101 | + Because of this blurred distinction, using the ordinary General | |
| 102 | +Public License for libraries did not effectively promote software | |
| 103 | +sharing, because most developers did not use the libraries. We | |
| 104 | +concluded that weaker conditions might promote sharing better. | |
| 105 | + | |
| 106 | + However, unrestricted linking of non-free programs would deprive the | |
| 107 | +users of those programs of all benefit from the free status of the | |
| 108 | +libraries themselves. This Library General Public License is intended to | |
| 109 | +permit developers of non-free programs to use free libraries, while | |
| 110 | +preserving your freedom as a user of such programs to change the free | |
| 111 | +libraries that are incorporated in them. (We have not seen how to achieve | |
| 112 | +this as regards changes in header files, but we have achieved it as regards | |
| 113 | +changes in the actual functions of the Library.) The hope is that this | |
| 114 | +will lead to faster development of free libraries. | |
| 115 | + | |
| 116 | + The precise terms and conditions for copying, distribution and | |
| 117 | +modification follow. Pay close attention to the difference between a | |
| 118 | +"work based on the library" and a "work that uses the library". The | |
| 119 | +former contains code derived from the library, while the latter only | |
| 120 | +works together with the library. | |
| 121 | + | |
| 122 | + Note that it is possible for a library to be covered by the ordinary | |
| 123 | +General Public License rather than by this special one. | |
| 124 | + | |
| 125 | + GNU LIBRARY GENERAL PUBLIC LICENSE | |
| 126 | + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
| 127 | + | |
| 128 | + 0. This License Agreement applies to any software library which | |
| 129 | +contains a notice placed by the copyright holder or other authorized | |
| 130 | +party saying it may be distributed under the terms of this Library | |
| 131 | +General Public License (also called "this License"). Each licensee is | |
| 132 | +addressed as "you". | |
| 133 | + | |
| 134 | + A "library" means a collection of software functions and/or data | |
| 135 | +prepared so as to be conveniently linked with application programs | |
| 136 | +(which use some of those functions and data) to form executables. | |
| 137 | + | |
| 138 | + The "Library", below, refers to any such software library or work | |
| 139 | +which has been distributed under these terms. A "work based on the | |
| 140 | +Library" means either the Library or any derivative work under | |
| 141 | +copyright law: that is to say, a work containing the Library or a | |
| 142 | +portion of it, either verbatim or with modifications and/or translated | |
| 143 | +straightforwardly into another language. (Hereinafter, translation is | |
| 144 | +included without limitation in the term "modification".) | |
| 145 | + | |
| 146 | + "Source code" for a work means the preferred form of the work for | |
| 147 | +making modifications to it. For a library, complete source code means | |
| 148 | +all the source code for all modules it contains, plus any associated | |
| 149 | +interface definition files, plus the scripts used to control compilation | |
| 150 | +and installation of the library. | |
| 151 | + | |
| 152 | + Activities other than copying, distribution and modification are not | |
| 153 | +covered by this License; they are outside its scope. The act of | |
| 154 | +running a program using the Library is not restricted, and output from | |
| 155 | +such a program is covered only if its contents constitute a work based | |
| 156 | +on the Library (independent of the use of the Library in a tool for | |
| 157 | +writing it). Whether that is true depends on what the Library does | |
| 158 | +and what the program that uses the Library does. | |
| 159 | + | |
| 160 | + 1. You may copy and distribute verbatim copies of the Library's | |
| 161 | +complete source code as you receive it, in any medium, provided that | |
| 162 | +you conspicuously and appropriately publish on each copy an | |
| 163 | +appropriate copyright notice and disclaimer of warranty; keep intact | |
| 164 | +all the notices that refer to this License and to the absence of any | |
| 165 | +warranty; and distribute a copy of this License along with the | |
| 166 | +Library. | |
| 167 | + | |
| 168 | + You may charge a fee for the physical act of transferring a copy, | |
| 169 | +and you may at your option offer warranty protection in exchange for a | |
| 170 | +fee. | |
| 171 | + | |
| 172 | + 2. You may modify your copy or copies of the Library or any portion | |
| 173 | +of it, thus forming a work based on the Library, and copy and | |
| 174 | +distribute such modifications or work under the terms of Section 1 | |
| 175 | +above, provided that you also meet all of these conditions: | |
| 176 | + | |
| 177 | + a) The modified work must itself be a software library. | |
| 178 | + | |
| 179 | + b) You must cause the files modified to carry prominent notices | |
| 180 | + stating that you changed the files and the date of any change. | |
| 181 | + | |
| 182 | + c) You must cause the whole of the work to be licensed at no | |
| 183 | + charge to all third parties under the terms of this License. | |
| 184 | + | |
| 185 | + d) If a facility in the modified Library refers to a function or a | |
| 186 | + table of data to be supplied by an application program that uses | |
| 187 | + the facility, other than as an argument passed when the facility | |
| 188 | + is invoked, then you must make a good faith effort to ensure that, | |
| 189 | + in the event an application does not supply such function or | |
| 190 | + table, the facility still operates, and performs whatever part of | |
| 191 | + its purpose remains meaningful. | |
| 192 | + | |
| 193 | + (For example, a function in a library to compute square roots has | |
| 194 | + a purpose that is entirely well-defined independent of the | |
| 195 | + application. Therefore, Subsection 2d requires that any | |
| 196 | + application-supplied function or table used by this function must | |
| 197 | + be optional: if the application does not supply it, the square | |
| 198 | + root function must still compute square roots.) | |
| 199 | + | |
| 200 | +These requirements apply to the modified work as a whole. If | |
| 201 | +identifiable sections of that work are not derived from the Library, | |
| 202 | +and can be reasonably considered independent and separate works in | |
| 203 | +themselves, then this License, and its terms, do not apply to those | |
| 204 | +sections when you distribute them as separate works. But when you | |
| 205 | +distribute the same sections as part of a whole which is a work based | |
| 206 | +on the Library, the distribution of the whole must be on the terms of | |
| 207 | +this License, whose permissions for other licensees extend to the | |
| 208 | +entire whole, and thus to each and every part regardless of who wrote | |
| 209 | +it. | |
| 210 | + | |
| 211 | +Thus, it is not the intent of this section to claim rights or contest | |
| 212 | +your rights to work written entirely by you; rather, the intent is to | |
| 213 | +exercise the right to control the distribution of derivative or | |
| 214 | +collective works based on the Library. | |
| 215 | + | |
| 216 | +In addition, mere aggregation of another work not based on the Library | |
| 217 | +with the Library (or with a work based on the Library) on a volume of | |
| 218 | +a storage or distribution medium does not bring the other work under | |
| 219 | +the scope of this License. | |
| 220 | + | |
| 221 | + 3. You may opt to apply the terms of the ordinary GNU General Public | |
| 222 | +License instead of this License to a given copy of the Library. To do | |
| 223 | +this, you must alter all the notices that refer to this License, so | |
| 224 | +that they refer to the ordinary GNU General Public License, version 2, | |
| 225 | +instead of to this License. (If a newer version than version 2 of the | |
| 226 | +ordinary GNU General Public License has appeared, then you can specify | |
| 227 | +that version instead if you wish.) Do not make any other change in | |
| 228 | +these notices. | |
| 229 | + | |
| 230 | + Once this change is made in a given copy, it is irreversible for | |
| 231 | +that copy, so the ordinary GNU General Public License applies to all | |
| 232 | +subsequent copies and derivative works made from that copy. | |
| 233 | + | |
| 234 | + This option is useful when you wish to copy part of the code of | |
| 235 | +the Library into a program that is not a library. | |
| 236 | + | |
| 237 | + 4. You may copy and distribute the Library (or a portion or | |
| 238 | +derivative of it, under Section 2) in object code or executable form | |
| 239 | +under the terms of Sections 1 and 2 above provided that you accompany | |
| 240 | +it with the complete corresponding machine-readable source code, which | |
| 241 | +must be distributed under the terms of Sections 1 and 2 above on a | |
| 242 | +medium customarily used for software interchange. | |
| 243 | + | |
| 244 | + If distribution of object code is made by offering access to copy | |
| 245 | +from a designated place, then offering equivalent access to copy the | |
| 246 | +source code from the same place satisfies the requirement to | |
| 247 | +distribute the source code, even though third parties are not | |
| 248 | +compelled to copy the source along with the object code. | |
| 249 | + | |
| 250 | + 5. A program that contains no derivative of any portion of the | |
| 251 | +Library, but is designed to work with the Library by being compiled or | |
| 252 | +linked with it, is called a "work that uses the Library". Such a | |
| 253 | +work, in isolation, is not a derivative work of the Library, and | |
| 254 | +therefore falls outside the scope of this License. | |
| 255 | + | |
| 256 | + However, linking a "work that uses the Library" with the Library | |
| 257 | +creates an executable that is a derivative of the Library (because it | |
| 258 | +contains portions of the Library), rather than a "work that uses the | |
| 259 | +library". The executable is therefore covered by this License. | |
| 260 | +Section 6 states terms for distribution of such executables. | |
| 261 | + | |
| 262 | + When a "work that uses the Library" uses material from a header file | |
| 263 | +that is part of the Library, the object code for the work may be a | |
| 264 | +derivative work of the Library even though the source code is not. | |
| 265 | +Whether this is true is especially significant if the work can be | |
| 266 | +linked without the Library, or if the work is itself a library. The | |
| 267 | +threshold for this to be true is not precisely defined by law. | |
| 268 | + | |
| 269 | + If such an object file uses only numerical parameters, data | |
| 270 | +structure layouts and accessors, and small macros and small inline | |
| 271 | +functions (ten lines or less in length), then the use of the object | |
| 272 | +file is unrestricted, regardless of whether it is legally a derivative | |
| 273 | +work. (Executables containing this object code plus portions of the | |
| 274 | +Library will still fall under Section 6.) | |
| 275 | + | |
| 276 | + Otherwise, if the work is a derivative of the Library, you may | |
| 277 | +distribute the object code for the work under the terms of Section 6. | |
| 278 | +Any executables containing that work also fall under Section 6, | |
| 279 | +whether or not they are linked directly with the Library itself. | |
| 280 | + | |
| 281 | + 6. As an exception to the Sections above, you may also compile or | |
| 282 | +link a "work that uses the Library" with the Library to produce a | |
| 283 | +work containing portions of the Library, and distribute that work | |
| 284 | +under terms of your choice, provided that the terms permit | |
| 285 | +modification of the work for the customer's own use and reverse | |
| 286 | +engineering for debugging such modifications. | |
| 287 | + | |
| 288 | + You must give prominent notice with each copy of the work that the | |
| 289 | +Library is used in it and that the Library and its use are covered by | |
| 290 | +this License. You must supply a copy of this License. If the work | |
| 291 | +during execution displays copyright notices, you must include the | |
| 292 | +copyright notice for the Library among them, as well as a reference | |
| 293 | +directing the user to the copy of this License. Also, you must do one | |
| 294 | +of these things: | |
| 295 | + | |
| 296 | + a) Accompany the work with the complete corresponding | |
| 297 | + machine-readable source code for the Library including whatever | |
| 298 | + changes were used in the work (which must be distributed under | |
| 299 | + Sections 1 and 2 above); and, if the work is an executable linked | |
| 300 | + with the Library, with the complete machine-readable "work that | |
| 301 | + uses the Library", as object code and/or source code, so that the | |
| 302 | + user can modify the Library and then relink to produce a modified | |
| 303 | + executable containing the modified Library. (It is understood | |
| 304 | + that the user who changes the contents of definitions files in the | |
| 305 | + Library will not necessarily be able to recompile the application | |
| 306 | + to use the modified definitions.) | |
| 307 | + | |
| 308 | + b) Accompany the work with a written offer, valid for at | |
| 309 | + least three years, to give the same user the materials | |
| 310 | + specified in Subsection 6a, above, for a charge no more | |
| 311 | + than the cost of performing this distribution. | |
| 312 | + | |
| 313 | + c) If distribution of the work is made by offering access to copy | |
| 314 | + from a designated place, offer equivalent access to copy the above | |
| 315 | + specified materials from the same place. | |
| 316 | + | |
| 317 | + d) Verify that the user has already received a copy of these | |
| 318 | + materials or that you have already sent this user a copy. | |
| 319 | + | |
| 320 | + For an executable, the required form of the "work that uses the | |
| 321 | +Library" must include any data and utility programs needed for | |
| 322 | +reproducing the executable from it. However, as a special exception, | |
| 323 | +the source code distributed need not include anything that is normally | |
| 324 | +distributed (in either source or binary form) with the major | |
| 325 | +components (compiler, kernel, and so on) of the operating system on | |
| 326 | +which the executable runs, unless that component itself accompanies | |
| 327 | +the executable. | |
| 328 | + | |
| 329 | + It may happen that this requirement contradicts the license | |
| 330 | +restrictions of other proprietary libraries that do not normally | |
| 331 | +accompany the operating system. Such a contradiction means you cannot | |
| 332 | +use both them and the Library together in an executable that you | |
| 333 | +distribute. | |
| 334 | + | |
| 335 | + 7. You may place library facilities that are a work based on the | |
| 336 | +Library side-by-side in a single library together with other library | |
| 337 | +facilities not covered by this License, and distribute such a combined | |
| 338 | +library, provided that the separate distribution of the work based on | |
| 339 | +the Library and of the other library facilities is otherwise | |
| 340 | +permitted, and provided that you do these two things: | |
| 341 | + | |
| 342 | + a) Accompany the combined library with a copy of the same work | |
| 343 | + based on the Library, uncombined with any other library | |
| 344 | + facilities. This must be distributed under the terms of the | |
| 345 | + Sections above. | |
| 346 | + | |
| 347 | + b) Give prominent notice with the combined library of the fact | |
| 348 | + that part of it is a work based on the Library, and explaining | |
| 349 | + where to find the accompanying uncombined form of the same work. | |
| 350 | + | |
| 351 | + 8. You may not copy, modify, sublicense, link with, or distribute | |
| 352 | +the Library except as expressly provided under this License. Any | |
| 353 | +attempt otherwise to copy, modify, sublicense, link with, or | |
| 354 | +distribute the Library is void, and will automatically terminate your | |
| 355 | +rights under this License. However, parties who have received copies, | |
| 356 | +or rights, from you under this License will not have their licenses | |
| 357 | +terminated so long as such parties remain in full compliance. | |
| 358 | + | |
| 359 | + 9. You are not required to accept this License, since you have not | |
| 360 | +signed it. However, nothing else grants you permission to modify or | |
| 361 | +distribute the Library or its derivative works. These actions are | |
| 362 | +prohibited by law if you do not accept this License. Therefore, by | |
| 363 | +modifying or distributing the Library (or any work based on the | |
| 364 | +Library), you indicate your acceptance of this License to do so, and | |
| 365 | +all its terms and conditions for copying, distributing or modifying | |
| 366 | +the Library or works based on it. | |
| 367 | + | |
| 368 | + 10. Each time you redistribute the Library (or any work based on the | |
| 369 | +Library), the recipient automatically receives a license from the | |
| 370 | +original licensor to copy, distribute, link with or modify the Library | |
| 371 | +subject to these terms and conditions. You may not impose any further | |
| 372 | +restrictions on the recipients' exercise of the rights granted herein. | |
| 373 | +You are not responsible for enforcing compliance by third parties to | |
| 374 | +this License. | |
| 375 | + | |
| 376 | + 11. If, as a consequence of a court judgment or allegation of patent | |
| 377 | +infringement or for any other reason (not limited to patent issues), | |
| 378 | +conditions are imposed on you (whether by court order, agreement or | |
| 379 | +otherwise) that contradict the conditions of this License, they do not | |
| 380 | +excuse you from the conditions of this License. If you cannot | |
| 381 | +distribute so as to satisfy simultaneously your obligations under this | |
| 382 | +License and any other pertinent obligations, then as a consequence you | |
| 383 | +may not distribute the Library at all. For example, if a patent | |
| 384 | +license would not permit royalty-free redistribution of the Library by | |
| 385 | +all those who receive copies directly or indirectly through you, then | |
| 386 | +the only way you could satisfy both it and this License would be to | |
| 387 | +refrain entirely from distribution of the Library. | |
| 388 | + | |
| 389 | +If any portion of this section is held invalid or unenforceable under any | |
| 390 | +particular circumstance, the balance of the section is intended to apply, | |
| 391 | +and the section as a whole is intended to apply in other circumstances. | |
| 392 | + | |
| 393 | +It is not the purpose of this section to induce you to infringe any | |
| 394 | +patents or other property right claims or to contest validity of any | |
| 395 | +such claims; this section has the sole purpose of protecting the | |
| 396 | +integrity of the free software distribution system which is | |
| 397 | +implemented by public license practices. Many people have made | |
| 398 | +generous contributions to the wide range of software distributed | |
| 399 | +through that system in reliance on consistent application of that | |
| 400 | +system; it is up to the author/donor to decide if he or she is willing | |
| 401 | +to distribute software through any other system and a licensee cannot | |
| 402 | +impose that choice. | |
| 403 | + | |
| 404 | +This section is intended to make thoroughly clear what is believed to | |
| 405 | +be a consequence of the rest of this License. | |
| 406 | + | |
| 407 | + 12. If the distribution and/or use of the Library is restricted in | |
| 408 | +certain countries either by patents or by copyrighted interfaces, the | |
| 409 | +original copyright holder who places the Library under this License may add | |
| 410 | +an explicit geographical distribution limitation excluding those countries, | |
| 411 | +so that distribution is permitted only in or among countries not thus | |
| 412 | +excluded. In such case, this License incorporates the limitation as if | |
| 413 | +written in the body of this License. | |
| 414 | + | |
| 415 | + 13. The Free Software Foundation may publish revised and/or new | |
| 416 | +versions of the Library General Public License from time to time. | |
| 417 | +Such new versions will be similar in spirit to the present version, | |
| 418 | +but may differ in detail to address new problems or concerns. | |
| 419 | + | |
| 420 | +Each version is given a distinguishing version number. If the Library | |
| 421 | +specifies a version number of this License which applies to it and | |
| 422 | +"any later version", you have the option of following the terms and | |
| 423 | +conditions either of that version or of any later version published by | |
| 424 | +the Free Software Foundation. If the Library does not specify a | |
| 425 | +license version number, you may choose any version ever published by | |
| 426 | +the Free Software Foundation. | |
| 427 | + | |
| 428 | + 14. If you wish to incorporate parts of the Library into other free | |
| 429 | +programs whose distribution conditions are incompatible with these, | |
| 430 | +write to the author to ask for permission. For software which is | |
| 431 | +copyrighted by the Free Software Foundation, write to the Free | |
| 432 | +Software Foundation; we sometimes make exceptions for this. Our | |
| 433 | +decision will be guided by the two goals of preserving the free status | |
| 434 | +of all derivatives of our free software and of promoting the sharing | |
| 435 | +and reuse of software generally. | |
| 436 | + | |
| 437 | + NO WARRANTY | |
| 438 | + | |
| 439 | + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO | |
| 440 | +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. | |
| 441 | +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR | |
| 442 | +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY | |
| 443 | +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE | |
| 444 | +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 445 | +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE | |
| 446 | +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME | |
| 447 | +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |
| 448 | + | |
| 449 | + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN | |
| 450 | +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY | |
| 451 | +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU | |
| 452 | +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR | |
| 453 | +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE | |
| 454 | +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING | |
| 455 | +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A | |
| 456 | +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF | |
| 457 | +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | |
| 458 | +DAMAGES. | |
| 459 | + | |
| 460 | + END OF TERMS AND CONDITIONS | |
| 461 | + | |
| 462 | + Appendix: How to Apply These Terms to Your New Libraries | |
| 463 | + | |
| 464 | + If you develop a new library, and you want it to be of the greatest | |
| 465 | +possible use to the public, we recommend making it free software that | |
| 466 | +everyone can redistribute and change. You can do so by permitting | |
| 467 | +redistribution under these terms (or, alternatively, under the terms of the | |
| 468 | +ordinary General Public License). | |
| 469 | + | |
| 470 | + To apply these terms, attach the following notices to the library. It is | |
| 471 | +safest to attach them to the start of each source file to most effectively | |
| 472 | +convey the exclusion of warranty; and each file should have at least the | |
| 473 | +"copyright" line and a pointer to where the full notice is found. | |
| 474 | + | |
| 475 | + <one line to give the library's name and a brief idea of what it does.> | |
| 476 | + Copyright (C) <year> <name of author> | |
| 477 | + | |
| 478 | + This library is free software; you can redistribute it and/or | |
| 479 | + modify it under the terms of the GNU Library General Public | |
| 480 | + License as published by the Free Software Foundation; either | |
| 481 | + version 2 of the License, or (at your option) any later version. | |
| 482 | + | |
| 483 | + This library is distributed in the hope that it will be useful, | |
| 484 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 485 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 486 | + Library General Public License for more details. | |
| 487 | + | |
| 488 | + You should have received a copy of the GNU Library General Public | |
| 489 | + License along with this library; if not, write to the Free | |
| 490 | + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 491 | + | |
| 492 | +Also add information on how to contact you by electronic and paper mail. | |
| 493 | + | |
| 494 | +You should also get your employer (if you work as a programmer) or your | |
| 495 | +school, if any, to sign a "copyright disclaimer" for the library, if | |
| 496 | +necessary. Here is a sample; alter the names: | |
| 497 | + | |
| 498 | + Yoyodyne, Inc., hereby disclaims all copyright interest in the | |
| 499 | + library `Frob' (a library for tweaking knobs) written by James Random Hacker. | |
| 500 | + | |
| 501 | + <signature of Ty Coon>, 1 April 1990 | |
| 502 | + Ty Coon, President of Vice | |
| 503 | + | |
| 504 | +That's all there is to it! | ... | ... |
Makefile
0 → 100644
| 1 | +CFLAGS=-Wall -O2 -g | |
| 2 | +LDFLAGS=-g | |
| 3 | +DEFINES=-D_GNU_SOURCE -DGEMU -DDOSEMU #-DNO_TRACE_MSGS | |
| 4 | + | |
| 5 | +OBJS= i386/fp87.o i386/interp_main.o i386/interp_modrm.o i386/interp_16_32.o \ | |
| 6 | + i386/interp_32_16.o i386/interp_32_32.o i386/emu-utils.o \ | |
| 7 | + i386/dis8086.o i386/emu-ldt.o | |
| 8 | +OBJS+= elfload.o main.o thunk.o syscall.o | |
| 9 | + | |
| 10 | +SRCS = $(OBJS:.o=.c) | |
| 11 | + | |
| 12 | +all: gemu | |
| 13 | + | |
| 14 | +gemu: $(OBJS) | |
| 15 | + $(CC) -Wl,-T,i386.ld $(LDFLAGS) -o $@ $(OBJS) | |
| 16 | + | |
| 17 | +depend: $(SRCS) | |
| 18 | + $(CC) -MM $(CFLAGS) $^ 1>.depend | |
| 19 | + | |
| 20 | +%.o: %.c | |
| 21 | + $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< | |
| 22 | + | |
| 23 | +clean: | |
| 24 | + rm -f *.o *~ i386/*.o i386/*~ gemu hello test1 test2 TAGS | |
| 25 | + | |
| 26 | +hello: hello.c | |
| 27 | + $(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $< | |
| 28 | + | |
| 29 | +test1: test1.c | |
| 30 | + $(CC) $(CFLAGS) -static $(LDFLAGS) -o $@ $< | |
| 31 | + | |
| 32 | +test2: test2.c | |
| 33 | + $(CC) $(CFLAGS) -static $(LDFLAGS) -o $@ $< | |
| 34 | + | |
| 35 | +ifneq ($(wildcard .depend),) | |
| 36 | +include .depend | |
| 37 | +endif | ... | ... |
TODO
0 → 100644
elf.h
0 → 100644
| 1 | +/* | |
| 2 | + * ELF register definitions.. | |
| 3 | + */ | |
| 4 | + | |
| 5 | +#include <inttypes.h> | |
| 6 | + | |
| 7 | +typedef uint32_t elf_greg_t; | |
| 8 | + | |
| 9 | +#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) | |
| 10 | +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | |
| 11 | + | |
| 12 | +typedef struct user_i387_struct elf_fpregset_t; | |
| 13 | + | |
| 14 | +/* | |
| 15 | + * This is used to ensure we don't load something for the wrong architecture. | |
| 16 | + */ | |
| 17 | +#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) ) | |
| 18 | + | |
| 19 | +/* | |
| 20 | + * These are used to set parameters in the core dumps. | |
| 21 | + */ | |
| 22 | +#define ELF_CLASS ELFCLASS32 | |
| 23 | +#define ELF_DATA ELFDATA2LSB; | |
| 24 | +#define ELF_ARCH EM_386 | |
| 25 | + | |
| 26 | + /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program | |
| 27 | + starts %edx contains a pointer to a function which might be | |
| 28 | + registered using `atexit'. This provides a mean for the | |
| 29 | + dynamic linker to call DT_FINI functions for shared libraries | |
| 30 | + that have been loaded before the code runs. | |
| 31 | + | |
| 32 | + A value of 0 tells we have no such handler. */ | |
| 33 | +#define ELF_PLAT_INIT(_r) _r->edx = 0 | |
| 34 | + | |
| 35 | +#define USE_ELF_CORE_DUMP | |
| 36 | +#define ELF_EXEC_PAGESIZE 4096 | |
| 37 | + | |
| 38 | + | |
| 39 | +typedef uint32_t Elf32_Addr; | |
| 40 | +typedef uint16_t Elf32_Half; | |
| 41 | +typedef uint32_t Elf32_Off; | |
| 42 | +typedef int32_t Elf32_Sword; | |
| 43 | +typedef uint32_t Elf32_Word; | |
| 44 | + | |
| 45 | +/* These constants are for the segment types stored in the image headers */ | |
| 46 | +#define PT_NULL 0 | |
| 47 | +#define PT_LOAD 1 | |
| 48 | +#define PT_DYNAMIC 2 | |
| 49 | +#define PT_INTERP 3 | |
| 50 | +#define PT_NOTE 4 | |
| 51 | +#define PT_SHLIB 5 | |
| 52 | +#define PT_PHDR 6 | |
| 53 | +#define PT_LOPROC 0x70000000 | |
| 54 | +#define PT_HIPROC 0x7fffffff | |
| 55 | + | |
| 56 | +/* These constants define the different elf file types */ | |
| 57 | +#define ET_NONE 0 | |
| 58 | +#define ET_REL 1 | |
| 59 | +#define ET_EXEC 2 | |
| 60 | +#define ET_DYN 3 | |
| 61 | +#define ET_CORE 4 | |
| 62 | +#define ET_LOPROC 5 | |
| 63 | +#define ET_HIPROC 6 | |
| 64 | + | |
| 65 | +/* These constants define the various ELF target machines */ | |
| 66 | +#define EM_NONE 0 | |
| 67 | +#define EM_M32 1 | |
| 68 | +#define EM_SPARC 2 | |
| 69 | +#define EM_386 3 | |
| 70 | +#define EM_68K 4 | |
| 71 | +#define EM_88K 5 | |
| 72 | +#define EM_486 6 /* Perhaps disused */ | |
| 73 | +#define EM_860 7 | |
| 74 | + | |
| 75 | +#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ | |
| 76 | + | |
| 77 | +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ | |
| 78 | + | |
| 79 | +#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */ | |
| 80 | + | |
| 81 | +#define EM_PARISC 15 /* HPPA */ | |
| 82 | + | |
| 83 | +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ | |
| 84 | + | |
| 85 | +#define EM_PPC 20 /* PowerPC */ | |
| 86 | + | |
| 87 | +/* | |
| 88 | + * This is an interim value that we will use until the committee comes | |
| 89 | + * up with a final number. | |
| 90 | + */ | |
| 91 | +#define EM_ALPHA 0x9026 | |
| 92 | + | |
| 93 | + | |
| 94 | +/* This is the info that is needed to parse the dynamic section of the file */ | |
| 95 | +#define DT_NULL 0 | |
| 96 | +#define DT_NEEDED 1 | |
| 97 | +#define DT_PLTRELSZ 2 | |
| 98 | +#define DT_PLTGOT 3 | |
| 99 | +#define DT_HASH 4 | |
| 100 | +#define DT_STRTAB 5 | |
| 101 | +#define DT_SYMTAB 6 | |
| 102 | +#define DT_RELA 7 | |
| 103 | +#define DT_RELASZ 8 | |
| 104 | +#define DT_RELAENT 9 | |
| 105 | +#define DT_STRSZ 10 | |
| 106 | +#define DT_SYMENT 11 | |
| 107 | +#define DT_INIT 12 | |
| 108 | +#define DT_FINI 13 | |
| 109 | +#define DT_SONAME 14 | |
| 110 | +#define DT_RPATH 15 | |
| 111 | +#define DT_SYMBOLIC 16 | |
| 112 | +#define DT_REL 17 | |
| 113 | +#define DT_RELSZ 18 | |
| 114 | +#define DT_RELENT 19 | |
| 115 | +#define DT_PLTREL 20 | |
| 116 | +#define DT_DEBUG 21 | |
| 117 | +#define DT_TEXTREL 22 | |
| 118 | +#define DT_JMPREL 23 | |
| 119 | +#define DT_LOPROC 0x70000000 | |
| 120 | +#define DT_HIPROC 0x7fffffff | |
| 121 | + | |
| 122 | +/* This info is needed when parsing the symbol table */ | |
| 123 | +#define STB_LOCAL 0 | |
| 124 | +#define STB_GLOBAL 1 | |
| 125 | +#define STB_WEAK 2 | |
| 126 | + | |
| 127 | +#define STT_NOTYPE 0 | |
| 128 | +#define STT_OBJECT 1 | |
| 129 | +#define STT_FUNC 2 | |
| 130 | +#define STT_SECTION 3 | |
| 131 | +#define STT_FILE 4 | |
| 132 | + | |
| 133 | +#define ELF32_ST_BIND(x) ((x) >> 4) | |
| 134 | +#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) | |
| 135 | + | |
| 136 | +/* Symbolic values for the entries in the auxiliary table | |
| 137 | + put on the initial stack */ | |
| 138 | +#define AT_NULL 0 /* end of vector */ | |
| 139 | +#define AT_IGNORE 1 /* entry should be ignored */ | |
| 140 | +#define AT_EXECFD 2 /* file descriptor of program */ | |
| 141 | +#define AT_PHDR 3 /* program headers for program */ | |
| 142 | +#define AT_PHENT 4 /* size of program header entry */ | |
| 143 | +#define AT_PHNUM 5 /* number of program headers */ | |
| 144 | +#define AT_PAGESZ 6 /* system page size */ | |
| 145 | +#define AT_BASE 7 /* base address of interpreter */ | |
| 146 | +#define AT_FLAGS 8 /* flags */ | |
| 147 | +#define AT_ENTRY 9 /* entry point of program */ | |
| 148 | +#define AT_NOTELF 10 /* program is not ELF */ | |
| 149 | +#define AT_UID 11 /* real uid */ | |
| 150 | +#define AT_EUID 12 /* effective uid */ | |
| 151 | +#define AT_GID 13 /* real gid */ | |
| 152 | +#define AT_EGID 14 /* effective gid */ | |
| 153 | + | |
| 154 | + | |
| 155 | +typedef struct dynamic{ | |
| 156 | + Elf32_Sword d_tag; | |
| 157 | + union{ | |
| 158 | + Elf32_Sword d_val; | |
| 159 | + Elf32_Addr d_ptr; | |
| 160 | + } d_un; | |
| 161 | +} Elf32_Dyn; | |
| 162 | + | |
| 163 | +typedef struct { | |
| 164 | + unsigned long long d_tag; /* entry tag value */ | |
| 165 | + union { | |
| 166 | + unsigned long long d_val; | |
| 167 | + unsigned long long d_ptr; | |
| 168 | + } d_un; | |
| 169 | +} Elf64_Dyn; | |
| 170 | + | |
| 171 | +/* The following are used with relocations */ | |
| 172 | +#define ELF32_R_SYM(x) ((x) >> 8) | |
| 173 | +#define ELF32_R_TYPE(x) ((x) & 0xff) | |
| 174 | + | |
| 175 | +#define R_386_NONE 0 | |
| 176 | +#define R_386_32 1 | |
| 177 | +#define R_386_PC32 2 | |
| 178 | +#define R_386_GOT32 3 | |
| 179 | +#define R_386_PLT32 4 | |
| 180 | +#define R_386_COPY 5 | |
| 181 | +#define R_386_GLOB_DAT 6 | |
| 182 | +#define R_386_JMP_SLOT 7 | |
| 183 | +#define R_386_RELATIVE 8 | |
| 184 | +#define R_386_GOTOFF 9 | |
| 185 | +#define R_386_GOTPC 10 | |
| 186 | +#define R_386_NUM 11 | |
| 187 | + | |
| 188 | +typedef struct elf32_rel { | |
| 189 | + Elf32_Addr r_offset; | |
| 190 | + Elf32_Word r_info; | |
| 191 | +} Elf32_Rel; | |
| 192 | + | |
| 193 | +typedef struct elf64_rel { | |
| 194 | + unsigned long long r_offset; /* Location at which to apply the action */ | |
| 195 | + unsigned long long r_info; /* index and type of relocation */ | |
| 196 | +} Elf64_Rel; | |
| 197 | + | |
| 198 | +typedef struct elf32_rela{ | |
| 199 | + Elf32_Addr r_offset; | |
| 200 | + Elf32_Word r_info; | |
| 201 | + Elf32_Sword r_addend; | |
| 202 | +} Elf32_Rela; | |
| 203 | + | |
| 204 | +typedef struct elf64_rela { | |
| 205 | + unsigned long long r_offset; /* Location at which to apply the action */ | |
| 206 | + unsigned long long r_info; /* index and type of relocation */ | |
| 207 | + unsigned long long r_addend; /* Constant addend used to compute value */ | |
| 208 | +} Elf64_Rela; | |
| 209 | + | |
| 210 | +typedef struct elf32_sym{ | |
| 211 | + Elf32_Word st_name; | |
| 212 | + Elf32_Addr st_value; | |
| 213 | + Elf32_Word st_size; | |
| 214 | + unsigned char st_info; | |
| 215 | + unsigned char st_other; | |
| 216 | + Elf32_Half st_shndx; | |
| 217 | +} Elf32_Sym; | |
| 218 | + | |
| 219 | +typedef struct elf64_sym { | |
| 220 | + unsigned int st_name; /* Symbol name, index in string tbl */ | |
| 221 | + unsigned char st_info; /* Type and binding attributes */ | |
| 222 | + unsigned char st_other; /* No defined meaning, 0 */ | |
| 223 | + unsigned short st_shndx; /* Associated section index */ | |
| 224 | + unsigned long long st_value; /* Value of the symbol */ | |
| 225 | + unsigned long long st_size; /* Associated symbol size */ | |
| 226 | +} Elf64_Sym; | |
| 227 | + | |
| 228 | + | |
| 229 | +#define EI_NIDENT 16 | |
| 230 | + | |
| 231 | +typedef struct elf32_hdr{ | |
| 232 | + unsigned char e_ident[EI_NIDENT]; | |
| 233 | + Elf32_Half e_type; | |
| 234 | + Elf32_Half e_machine; | |
| 235 | + Elf32_Word e_version; | |
| 236 | + Elf32_Addr e_entry; /* Entry point */ | |
| 237 | + Elf32_Off e_phoff; | |
| 238 | + Elf32_Off e_shoff; | |
| 239 | + Elf32_Word e_flags; | |
| 240 | + Elf32_Half e_ehsize; | |
| 241 | + Elf32_Half e_phentsize; | |
| 242 | + Elf32_Half e_phnum; | |
| 243 | + Elf32_Half e_shentsize; | |
| 244 | + Elf32_Half e_shnum; | |
| 245 | + Elf32_Half e_shstrndx; | |
| 246 | +} Elf32_Ehdr; | |
| 247 | + | |
| 248 | +typedef struct elf64_hdr { | |
| 249 | + unsigned char e_ident[16]; /* ELF "magic number" */ | |
| 250 | + short int e_type; | |
| 251 | + short unsigned int e_machine; | |
| 252 | + int e_version; | |
| 253 | + unsigned long long e_entry; /* Entry point virtual address */ | |
| 254 | + unsigned long long e_phoff; /* Program header table file offset */ | |
| 255 | + unsigned long long e_shoff; /* Section header table file offset */ | |
| 256 | + int e_flags; | |
| 257 | + short int e_ehsize; | |
| 258 | + short int e_phentsize; | |
| 259 | + short int e_phnum; | |
| 260 | + short int e_shentsize; | |
| 261 | + short int e_shnum; | |
| 262 | + short int e_shstrndx; | |
| 263 | +} Elf64_Ehdr; | |
| 264 | + | |
| 265 | +/* These constants define the permissions on sections in the program | |
| 266 | + header, p_flags. */ | |
| 267 | +#define PF_R 0x4 | |
| 268 | +#define PF_W 0x2 | |
| 269 | +#define PF_X 0x1 | |
| 270 | + | |
| 271 | +typedef struct elf32_phdr{ | |
| 272 | + Elf32_Word p_type; | |
| 273 | + Elf32_Off p_offset; | |
| 274 | + Elf32_Addr p_vaddr; | |
| 275 | + Elf32_Addr p_paddr; | |
| 276 | + Elf32_Word p_filesz; | |
| 277 | + Elf32_Word p_memsz; | |
| 278 | + Elf32_Word p_flags; | |
| 279 | + Elf32_Word p_align; | |
| 280 | +} Elf32_Phdr; | |
| 281 | + | |
| 282 | +typedef struct elf64_phdr { | |
| 283 | + int p_type; | |
| 284 | + int p_flags; | |
| 285 | + unsigned long long p_offset; /* Segment file offset */ | |
| 286 | + unsigned long long p_vaddr; /* Segment virtual address */ | |
| 287 | + unsigned long long p_paddr; /* Segment physical address */ | |
| 288 | + unsigned long long p_filesz; /* Segment size in file */ | |
| 289 | + unsigned long long p_memsz; /* Segment size in memory */ | |
| 290 | + unsigned long long p_align; /* Segment alignment, file & memory */ | |
| 291 | +} Elf64_Phdr; | |
| 292 | + | |
| 293 | +/* sh_type */ | |
| 294 | +#define SHT_NULL 0 | |
| 295 | +#define SHT_PROGBITS 1 | |
| 296 | +#define SHT_SYMTAB 2 | |
| 297 | +#define SHT_STRTAB 3 | |
| 298 | +#define SHT_RELA 4 | |
| 299 | +#define SHT_HASH 5 | |
| 300 | +#define SHT_DYNAMIC 6 | |
| 301 | +#define SHT_NOTE 7 | |
| 302 | +#define SHT_NOBITS 8 | |
| 303 | +#define SHT_REL 9 | |
| 304 | +#define SHT_SHLIB 10 | |
| 305 | +#define SHT_DYNSYM 11 | |
| 306 | +#define SHT_NUM 12 | |
| 307 | +#define SHT_LOPROC 0x70000000 | |
| 308 | +#define SHT_HIPROC 0x7fffffff | |
| 309 | +#define SHT_LOUSER 0x80000000 | |
| 310 | +#define SHT_HIUSER 0xffffffff | |
| 311 | + | |
| 312 | +/* sh_flags */ | |
| 313 | +#define SHF_WRITE 0x1 | |
| 314 | +#define SHF_ALLOC 0x2 | |
| 315 | +#define SHF_EXECINSTR 0x4 | |
| 316 | +#define SHF_MASKPROC 0xf0000000 | |
| 317 | + | |
| 318 | +/* special section indexes */ | |
| 319 | +#define SHN_UNDEF 0 | |
| 320 | +#define SHN_LORESERVE 0xff00 | |
| 321 | +#define SHN_LOPROC 0xff00 | |
| 322 | +#define SHN_HIPROC 0xff1f | |
| 323 | +#define SHN_ABS 0xfff1 | |
| 324 | +#define SHN_COMMON 0xfff2 | |
| 325 | +#define SHN_HIRESERVE 0xffff | |
| 326 | + | |
| 327 | +typedef struct { | |
| 328 | + Elf32_Word sh_name; | |
| 329 | + Elf32_Word sh_type; | |
| 330 | + Elf32_Word sh_flags; | |
| 331 | + Elf32_Addr sh_addr; | |
| 332 | + Elf32_Off sh_offset; | |
| 333 | + Elf32_Word sh_size; | |
| 334 | + Elf32_Word sh_link; | |
| 335 | + Elf32_Word sh_info; | |
| 336 | + Elf32_Word sh_addralign; | |
| 337 | + Elf32_Word sh_entsize; | |
| 338 | +} Elf32_Shdr; | |
| 339 | + | |
| 340 | +typedef struct elf64_shdr { | |
| 341 | + unsigned int sh_name; /* Section name, index in string tbl */ | |
| 342 | + unsigned int sh_type; /* Type of section */ | |
| 343 | + unsigned long long sh_flags; /* Miscellaneous section attributes */ | |
| 344 | + unsigned long long sh_addr; /* Section virtual addr at execution */ | |
| 345 | + unsigned long long sh_offset; /* Section file offset */ | |
| 346 | + unsigned long long sh_size; /* Size of section in bytes */ | |
| 347 | + unsigned int sh_link; /* Index of another section */ | |
| 348 | + unsigned int sh_info; /* Additional section information */ | |
| 349 | + unsigned long long sh_addralign; /* Section alignment */ | |
| 350 | + unsigned long long sh_entsize; /* Entry size if section holds table */ | |
| 351 | +} Elf64_Shdr; | |
| 352 | + | |
| 353 | +#define EI_MAG0 0 /* e_ident[] indexes */ | |
| 354 | +#define EI_MAG1 1 | |
| 355 | +#define EI_MAG2 2 | |
| 356 | +#define EI_MAG3 3 | |
| 357 | +#define EI_CLASS 4 | |
| 358 | +#define EI_DATA 5 | |
| 359 | +#define EI_VERSION 6 | |
| 360 | +#define EI_PAD 7 | |
| 361 | + | |
| 362 | +#define ELFMAG0 0x7f /* EI_MAG */ | |
| 363 | +#define ELFMAG1 'E' | |
| 364 | +#define ELFMAG2 'L' | |
| 365 | +#define ELFMAG3 'F' | |
| 366 | +#define ELFMAG "\177ELF" | |
| 367 | +#define SELFMAG 4 | |
| 368 | + | |
| 369 | +#define ELFCLASSNONE 0 /* EI_CLASS */ | |
| 370 | +#define ELFCLASS32 1 | |
| 371 | +#define ELFCLASS64 2 | |
| 372 | +#define ELFCLASSNUM 3 | |
| 373 | + | |
| 374 | +#define ELFDATANONE 0 /* e_ident[EI_DATA] */ | |
| 375 | +#define ELFDATA2LSB 1 | |
| 376 | +#define ELFDATA2MSB 2 | |
| 377 | + | |
| 378 | +#define EV_NONE 0 /* e_version, EI_VERSION */ | |
| 379 | +#define EV_CURRENT 1 | |
| 380 | +#define EV_NUM 2 | |
| 381 | + | |
| 382 | +/* Notes used in ET_CORE */ | |
| 383 | +#define NT_PRSTATUS 1 | |
| 384 | +#define NT_PRFPREG 2 | |
| 385 | +#define NT_PRPSINFO 3 | |
| 386 | +#define NT_TASKSTRUCT 4 | |
| 387 | + | |
| 388 | +/* Note header in a PT_NOTE section */ | |
| 389 | +typedef struct elf32_note { | |
| 390 | + Elf32_Word n_namesz; /* Name size */ | |
| 391 | + Elf32_Word n_descsz; /* Content size */ | |
| 392 | + Elf32_Word n_type; /* Content type */ | |
| 393 | +} Elf32_Nhdr; | |
| 394 | + | |
| 395 | +/* Note header in a PT_NOTE section */ | |
| 396 | +/* | |
| 397 | + * For now we use the 32 bit version of the structure until we figure | |
| 398 | + * out whether we need anything better. Note - on the Alpha, "unsigned int" | |
| 399 | + * is only 32 bits. | |
| 400 | + */ | |
| 401 | +typedef struct elf64_note { | |
| 402 | + unsigned int n_namesz; /* Name size */ | |
| 403 | + unsigned int n_descsz; /* Content size */ | |
| 404 | + unsigned int n_type; /* Content type */ | |
| 405 | +} Elf64_Nhdr; | |
| 406 | + | |
| 407 | +#define ELF_START_MMAP 0x80000000 | |
| 408 | + | |
| 409 | +#if ELF_CLASS == ELFCLASS32 | |
| 410 | + | |
| 411 | +extern Elf32_Dyn _DYNAMIC []; | |
| 412 | +#define elfhdr elf32_hdr | |
| 413 | +#define elf_phdr elf32_phdr | |
| 414 | +#define elf_note elf32_note | |
| 415 | + | |
| 416 | +#else | |
| 417 | + | |
| 418 | +extern Elf64_Dyn _DYNAMIC []; | |
| 419 | +#define elfhdr elf64_hdr | |
| 420 | +#define elf_phdr elf64_phdr | |
| 421 | +#define elf_note elf64_note | |
| 422 | + | |
| 423 | +#endif | |
| 424 | + | |
| 425 | + | ... | ... |
i386.ld
0 → 100644
| 1 | +/* ld script to make i386 Linux kernel | |
| 2 | + * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; | |
| 3 | + */ | |
| 4 | +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") | |
| 5 | +OUTPUT_ARCH(i386) | |
| 6 | +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib); | |
| 7 | +ENTRY(_start) | |
| 8 | +SECTIONS | |
| 9 | +{ | |
| 10 | + /* Read-only sections, merged into text segment: */ | |
| 11 | + . = 0x60000000 + SIZEOF_HEADERS; | |
| 12 | + .interp : { *(.interp) } | |
| 13 | + .hash : { *(.hash) } | |
| 14 | + .dynsym : { *(.dynsym) } | |
| 15 | + .dynstr : { *(.dynstr) } | |
| 16 | + .gnu.version : { *(.gnu.version) } | |
| 17 | + .gnu.version_d : { *(.gnu.version_d) } | |
| 18 | + .gnu.version_r : { *(.gnu.version_r) } | |
| 19 | + .rel.text : | |
| 20 | + { *(.rel.text) *(.rel.gnu.linkonce.t*) } | |
| 21 | + .rela.text : | |
| 22 | + { *(.rela.text) *(.rela.gnu.linkonce.t*) } | |
| 23 | + .rel.data : | |
| 24 | + { *(.rel.data) *(.rel.gnu.linkonce.d*) } | |
| 25 | + .rela.data : | |
| 26 | + { *(.rela.data) *(.rela.gnu.linkonce.d*) } | |
| 27 | + .rel.rodata : | |
| 28 | + { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } | |
| 29 | + .rela.rodata : | |
| 30 | + { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } | |
| 31 | + .rel.got : { *(.rel.got) } | |
| 32 | + .rela.got : { *(.rela.got) } | |
| 33 | + .rel.ctors : { *(.rel.ctors) } | |
| 34 | + .rela.ctors : { *(.rela.ctors) } | |
| 35 | + .rel.dtors : { *(.rel.dtors) } | |
| 36 | + .rela.dtors : { *(.rela.dtors) } | |
| 37 | + .rel.init : { *(.rel.init) } | |
| 38 | + .rela.init : { *(.rela.init) } | |
| 39 | + .rel.fini : { *(.rel.fini) } | |
| 40 | + .rela.fini : { *(.rela.fini) } | |
| 41 | + .rel.bss : { *(.rel.bss) } | |
| 42 | + .rela.bss : { *(.rela.bss) } | |
| 43 | + .rel.plt : { *(.rel.plt) } | |
| 44 | + .rela.plt : { *(.rela.plt) } | |
| 45 | + .init : { *(.init) } =0x47ff041f | |
| 46 | + .text : | |
| 47 | + { | |
| 48 | + *(.text) | |
| 49 | + /* .gnu.warning sections are handled specially by elf32.em. */ | |
| 50 | + *(.gnu.warning) | |
| 51 | + *(.gnu.linkonce.t*) | |
| 52 | + } =0x47ff041f | |
| 53 | + _etext = .; | |
| 54 | + PROVIDE (etext = .); | |
| 55 | + .fini : { *(.fini) } =0x47ff041f | |
| 56 | + .rodata : { *(.rodata) *(.gnu.linkonce.r*) } | |
| 57 | + .rodata1 : { *(.rodata1) } | |
| 58 | + .reginfo : { *(.reginfo) } | |
| 59 | + /* Adjust the address for the data segment. We want to adjust up to | |
| 60 | + the same address within the page on the next page up. */ | |
| 61 | + . = ALIGN(0x100000) + (. & (0x100000 - 1)); | |
| 62 | + .data : | |
| 63 | + { | |
| 64 | + *(.data) | |
| 65 | + *(.gnu.linkonce.d*) | |
| 66 | + CONSTRUCTORS | |
| 67 | + } | |
| 68 | + .data1 : { *(.data1) } | |
| 69 | + .ctors : | |
| 70 | + { | |
| 71 | + *(.ctors) | |
| 72 | + } | |
| 73 | + .dtors : | |
| 74 | + { | |
| 75 | + *(.dtors) | |
| 76 | + } | |
| 77 | + .plt : { *(.plt) } | |
| 78 | + .got : { *(.got.plt) *(.got) } | |
| 79 | + .dynamic : { *(.dynamic) } | |
| 80 | + /* We want the small data sections together, so single-instruction offsets | |
| 81 | + can access them all, and initialized data all before uninitialized, so | |
| 82 | + we can shorten the on-disk segment size. */ | |
| 83 | + .sdata : { *(.sdata) } | |
| 84 | + _edata = .; | |
| 85 | + PROVIDE (edata = .); | |
| 86 | + __bss_start = .; | |
| 87 | + .sbss : { *(.sbss) *(.scommon) } | |
| 88 | + .bss : | |
| 89 | + { | |
| 90 | + *(.dynbss) | |
| 91 | + *(.bss) | |
| 92 | + *(COMMON) | |
| 93 | + } | |
| 94 | + _end = . ; | |
| 95 | + PROVIDE (end = .); | |
| 96 | + /* Stabs debugging sections. */ | |
| 97 | + .stab 0 : { *(.stab) } | |
| 98 | + .stabstr 0 : { *(.stabstr) } | |
| 99 | + .stab.excl 0 : { *(.stab.excl) } | |
| 100 | + .stab.exclstr 0 : { *(.stab.exclstr) } | |
| 101 | + .stab.index 0 : { *(.stab.index) } | |
| 102 | + .stab.indexstr 0 : { *(.stab.indexstr) } | |
| 103 | + .comment 0 : { *(.comment) } | |
| 104 | + /* DWARF debug sections. | |
| 105 | + Symbols in the DWARF debugging sections are relative to the beginning | |
| 106 | + of the section so we begin them at 0. */ | |
| 107 | + /* DWARF 1 */ | |
| 108 | + .debug 0 : { *(.debug) } | |
| 109 | + .line 0 : { *(.line) } | |
| 110 | + /* GNU DWARF 1 extensions */ | |
| 111 | + .debug_srcinfo 0 : { *(.debug_srcinfo) } | |
| 112 | + .debug_sfnames 0 : { *(.debug_sfnames) } | |
| 113 | + /* DWARF 1.1 and DWARF 2 */ | |
| 114 | + .debug_aranges 0 : { *(.debug_aranges) } | |
| 115 | + .debug_pubnames 0 : { *(.debug_pubnames) } | |
| 116 | + /* DWARF 2 */ | |
| 117 | + .debug_info 0 : { *(.debug_info) } | |
| 118 | + .debug_abbrev 0 : { *(.debug_abbrev) } | |
| 119 | + .debug_line 0 : { *(.debug_line) } | |
| 120 | + .debug_frame 0 : { *(.debug_frame) } | |
| 121 | + .debug_str 0 : { *(.debug_str) } | |
| 122 | + .debug_loc 0 : { *(.debug_loc) } | |
| 123 | + .debug_macinfo 0 : { *(.debug_macinfo) } | |
| 124 | + /* SGI/MIPS DWARF 2 extensions */ | |
| 125 | + .debug_weaknames 0 : { *(.debug_weaknames) } | |
| 126 | + .debug_funcnames 0 : { *(.debug_funcnames) } | |
| 127 | + .debug_typenames 0 : { *(.debug_typenames) } | |
| 128 | + .debug_varnames 0 : { *(.debug_varnames) } | |
| 129 | + /* These must appear regardless of . */ | |
| 130 | +} | ... | ... |
linux-user/elfload.c
0 → 100644
| 1 | +/* This is the Linux kernel elf-loading code, ported into user space */ | |
| 2 | + | |
| 3 | +#include <stdio.h> | |
| 4 | +#include <sys/types.h> | |
| 5 | +#include <fcntl.h> | |
| 6 | +#include <sys/stat.h> | |
| 7 | +#include <errno.h> | |
| 8 | +#include <unistd.h> | |
| 9 | +#include <sys/mman.h> | |
| 10 | +#include <stdlib.h> | |
| 11 | +#include <string.h> | |
| 12 | + | |
| 13 | +#include "gemu.h" | |
| 14 | + | |
| 15 | +#include "linux_bin.h" | |
| 16 | +#include "elf.h" | |
| 17 | +#include "segment.h" | |
| 18 | + | |
| 19 | +/* Necessary parameters */ | |
| 20 | +#define ALPHA_PAGE_SIZE 4096 | |
| 21 | +#define X86_PAGE_SIZE 4096 | |
| 22 | + | |
| 23 | +#define ALPHA_PAGE_MASK (~(ALPHA_PAGE_SIZE-1)) | |
| 24 | +#define X86_PAGE_MASK (~(X86_PAGE_SIZE-1)) | |
| 25 | + | |
| 26 | +#define ALPHA_PAGE_ALIGN(addr) ((((addr)+ALPHA_PAGE_SIZE)-1)&ALPHA_PAGE_MASK) | |
| 27 | +#define X86_PAGE_ALIGN(addr) ((((addr)+X86_PAGE_SIZE)-1)&X86_PAGE_MASK) | |
| 28 | + | |
| 29 | +#define NGROUPS 32 | |
| 30 | + | |
| 31 | +#define X86_ELF_EXEC_PAGESIZE X86_PAGE_SIZE | |
| 32 | +#define X86_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(X86_ELF_EXEC_PAGESIZE-1)) | |
| 33 | +#define X86_ELF_PAGEOFFSET(_v) ((_v) & (X86_ELF_EXEC_PAGESIZE-1)) | |
| 34 | + | |
| 35 | +#define ALPHA_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ALPHA_PAGE_SIZE-1)) | |
| 36 | +#define ALPHA_ELF_PAGEOFFSET(_v) ((_v) & (ALPHA_PAGE_SIZE-1)) | |
| 37 | + | |
| 38 | +#define INTERPRETER_NONE 0 | |
| 39 | +#define INTERPRETER_AOUT 1 | |
| 40 | +#define INTERPRETER_ELF 2 | |
| 41 | + | |
| 42 | +#define DLINFO_ITEMS 12 | |
| 43 | + | |
| 44 | +/* Where we find X86 libraries... */ | |
| 45 | +//#define X86_DEFAULT_LIB_DIR "/usr/x86/" | |
| 46 | +#define X86_DEFAULT_LIB_DIR "/" | |
| 47 | + | |
| 48 | +//extern void * mmap4k(); | |
| 49 | +#define mmap4k(a, b, c, d, e, f) mmap((void *)(a), b, c, d, e, f) | |
| 50 | + | |
| 51 | +extern unsigned long x86_stack_size; | |
| 52 | + | |
| 53 | +static int load_aout_interp(void * exptr, int interp_fd); | |
| 54 | + | |
| 55 | +#ifdef BSWAP_NEEDED | |
| 56 | +static void bswap_ehdr(Elf32_Ehdr *ehdr) | |
| 57 | +{ | |
| 58 | + bswap16s(&ehdr->e_type); /* Object file type */ | |
| 59 | + bswap16s(&ehdr->e_machine); /* Architecture */ | |
| 60 | + bswap32s(&ehdr->e_version); /* Object file version */ | |
| 61 | + bswap32s(&ehdr->e_entry); /* Entry point virtual address */ | |
| 62 | + bswap32s(&ehdr->e_phoff); /* Program header table file offset */ | |
| 63 | + bswap32s(&ehdr->e_shoff); /* Section header table file offset */ | |
| 64 | + bswap32s(&ehdr->e_flags); /* Processor-specific flags */ | |
| 65 | + bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */ | |
| 66 | + bswap16s(&ehdr->e_phentsize); /* Program header table entry size */ | |
| 67 | + bswap16s(&ehdr->e_phnum); /* Program header table entry count */ | |
| 68 | + bswap16s(&ehdr->e_shentsize); /* Section header table entry size */ | |
| 69 | + bswap16s(&ehdr->e_shnum); /* Section header table entry count */ | |
| 70 | + bswap16s(&ehdr->e_shstrndx); /* Section header string table index */ | |
| 71 | +} | |
| 72 | + | |
| 73 | +static void bswap_phdr(Elf32_Phdr *phdr) | |
| 74 | +{ | |
| 75 | + bswap32s(&phdr->p_type); /* Segment type */ | |
| 76 | + bswap32s(&phdr->p_offset); /* Segment file offset */ | |
| 77 | + bswap32s(&phdr->p_vaddr); /* Segment virtual address */ | |
| 78 | + bswap32s(&phdr->p_paddr); /* Segment physical address */ | |
| 79 | + bswap32s(&phdr->p_filesz); /* Segment size in file */ | |
| 80 | + bswap32s(&phdr->p_memsz); /* Segment size in memory */ | |
| 81 | + bswap32s(&phdr->p_flags); /* Segment flags */ | |
| 82 | + bswap32s(&phdr->p_align); /* Segment alignment */ | |
| 83 | +} | |
| 84 | +#endif | |
| 85 | + | |
| 86 | +static void * get_free_page(void) | |
| 87 | +{ | |
| 88 | + void * retval; | |
| 89 | + | |
| 90 | + /* User-space version of kernel get_free_page. Returns a page-aligned | |
| 91 | + * page-sized chunk of memory. | |
| 92 | + */ | |
| 93 | + retval = mmap4k(0, ALPHA_PAGE_SIZE, PROT_READ|PROT_WRITE, | |
| 94 | + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |
| 95 | + | |
| 96 | + if((long)retval == -1) { | |
| 97 | + perror("get_free_page"); | |
| 98 | + exit(-1); | |
| 99 | + } | |
| 100 | + else { | |
| 101 | + return(retval); | |
| 102 | + } | |
| 103 | +} | |
| 104 | + | |
| 105 | +static void free_page(void * pageaddr) | |
| 106 | +{ | |
| 107 | + (void)munmap(pageaddr, ALPHA_PAGE_SIZE); | |
| 108 | +} | |
| 109 | + | |
| 110 | +/* | |
| 111 | + * 'copy_string()' copies argument/envelope strings from user | |
| 112 | + * memory to free pages in kernel mem. These are in a format ready | |
| 113 | + * to be put directly into the top of new user memory. | |
| 114 | + * | |
| 115 | + */ | |
| 116 | +static unsigned long copy_strings(int argc,char ** argv,unsigned long *page, | |
| 117 | + unsigned long p) | |
| 118 | +{ | |
| 119 | + char *tmp, *tmp1, *pag = NULL; | |
| 120 | + int len, offset = 0; | |
| 121 | + | |
| 122 | + if (!p) { | |
| 123 | + return 0; /* bullet-proofing */ | |
| 124 | + } | |
| 125 | + while (argc-- > 0) { | |
| 126 | + if (!(tmp1 = tmp = get_user(argv+argc))) { | |
| 127 | + fprintf(stderr, "VFS: argc is wrong"); | |
| 128 | + exit(-1); | |
| 129 | + } | |
| 130 | + while (get_user(tmp++)); | |
| 131 | + len = tmp - tmp1; | |
| 132 | + if (p < len) { /* this shouldn't happen - 128kB */ | |
| 133 | + return 0; | |
| 134 | + } | |
| 135 | + while (len) { | |
| 136 | + --p; --tmp; --len; | |
| 137 | + if (--offset < 0) { | |
| 138 | + offset = p % X86_PAGE_SIZE; | |
| 139 | + if (!(pag = (char *) page[p/X86_PAGE_SIZE]) && | |
| 140 | + !(pag = (char *) page[p/X86_PAGE_SIZE] = | |
| 141 | + (unsigned long *) get_free_page())) { | |
| 142 | + return 0; | |
| 143 | + } | |
| 144 | + } | |
| 145 | + if (len == 0 || offset == 0) { | |
| 146 | + *(pag + offset) = get_user(tmp); | |
| 147 | + } | |
| 148 | + else { | |
| 149 | + int bytes_to_copy = (len > offset) ? offset : len; | |
| 150 | + tmp -= bytes_to_copy; | |
| 151 | + p -= bytes_to_copy; | |
| 152 | + offset -= bytes_to_copy; | |
| 153 | + len -= bytes_to_copy; | |
| 154 | + memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1); | |
| 155 | + } | |
| 156 | + } | |
| 157 | + } | |
| 158 | + return p; | |
| 159 | +} | |
| 160 | + | |
| 161 | +static int in_group_p(gid_t g) | |
| 162 | +{ | |
| 163 | + /* return TRUE if we're in the specified group, FALSE otherwise */ | |
| 164 | + int ngroup; | |
| 165 | + int i; | |
| 166 | + gid_t grouplist[NGROUPS]; | |
| 167 | + | |
| 168 | + ngroup = getgroups(NGROUPS, grouplist); | |
| 169 | + for(i = 0; i < ngroup; i++) { | |
| 170 | + if(grouplist[i] == g) { | |
| 171 | + return 1; | |
| 172 | + } | |
| 173 | + } | |
| 174 | + return 0; | |
| 175 | +} | |
| 176 | + | |
| 177 | +static int count(char ** vec) | |
| 178 | +{ | |
| 179 | + int i; | |
| 180 | + | |
| 181 | + for(i = 0; *vec; i++) { | |
| 182 | + vec++; | |
| 183 | + } | |
| 184 | + | |
| 185 | + return(i); | |
| 186 | +} | |
| 187 | + | |
| 188 | +static int prepare_binprm(struct linux_binprm *bprm) | |
| 189 | +{ | |
| 190 | + struct stat st; | |
| 191 | + int mode; | |
| 192 | + int retval, id_change; | |
| 193 | + | |
| 194 | + if(fstat(bprm->fd, &st) < 0) { | |
| 195 | + return(-errno); | |
| 196 | + } | |
| 197 | + | |
| 198 | + mode = st.st_mode; | |
| 199 | + if(!S_ISREG(mode)) { /* Must be regular file */ | |
| 200 | + return(-EACCES); | |
| 201 | + } | |
| 202 | + if(!(mode & 0111)) { /* Must have at least one execute bit set */ | |
| 203 | + return(-EACCES); | |
| 204 | + } | |
| 205 | + | |
| 206 | + bprm->e_uid = geteuid(); | |
| 207 | + bprm->e_gid = getegid(); | |
| 208 | + id_change = 0; | |
| 209 | + | |
| 210 | + /* Set-uid? */ | |
| 211 | + if(mode & S_ISUID) { | |
| 212 | + bprm->e_uid = st.st_uid; | |
| 213 | + if(bprm->e_uid != geteuid()) { | |
| 214 | + id_change = 1; | |
| 215 | + } | |
| 216 | + } | |
| 217 | + | |
| 218 | + /* Set-gid? */ | |
| 219 | + /* | |
| 220 | + * If setgid is set but no group execute bit then this | |
| 221 | + * is a candidate for mandatory locking, not a setgid | |
| 222 | + * executable. | |
| 223 | + */ | |
| 224 | + if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { | |
| 225 | + bprm->e_gid = st.st_gid; | |
| 226 | + if (!in_group_p(bprm->e_gid)) { | |
| 227 | + id_change = 1; | |
| 228 | + } | |
| 229 | + } | |
| 230 | + | |
| 231 | + memset(bprm->buf, 0, sizeof(bprm->buf)); | |
| 232 | + retval = lseek(bprm->fd, 0L, SEEK_SET); | |
| 233 | + if(retval >= 0) { | |
| 234 | + retval = read(bprm->fd, bprm->buf, 128); | |
| 235 | + } | |
| 236 | + if(retval < 0) { | |
| 237 | + perror("prepare_binprm"); | |
| 238 | + exit(-1); | |
| 239 | + /* return(-errno); */ | |
| 240 | + } | |
| 241 | + else { | |
| 242 | + return(retval); | |
| 243 | + } | |
| 244 | +} | |
| 245 | + | |
| 246 | +unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm, | |
| 247 | + struct image_info * info) | |
| 248 | +{ | |
| 249 | + unsigned long stack_base; | |
| 250 | + int i; | |
| 251 | + extern unsigned long stktop; | |
| 252 | + | |
| 253 | + stack_base = X86_STACK_TOP - MAX_ARG_PAGES*X86_PAGE_SIZE; | |
| 254 | + | |
| 255 | + p += stack_base; | |
| 256 | + if (bprm->loader) { | |
| 257 | + bprm->loader += stack_base; | |
| 258 | + } | |
| 259 | + bprm->exec += stack_base; | |
| 260 | + | |
| 261 | + /* Create enough stack to hold everything. If we don't use | |
| 262 | + * it for args, we'll use it for something else... | |
| 263 | + */ | |
| 264 | + if(x86_stack_size > MAX_ARG_PAGES*X86_PAGE_SIZE) { | |
| 265 | + if((long)mmap4k((void *)(X86_STACK_TOP-x86_stack_size), x86_stack_size + X86_PAGE_SIZE, | |
| 266 | + PROT_READ | PROT_WRITE, | |
| 267 | + MAP_GROWSDOWN | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) { | |
| 268 | + perror("stk mmap"); | |
| 269 | + exit(-1); | |
| 270 | + } | |
| 271 | + } | |
| 272 | + else { | |
| 273 | + if((long)mmap4k((void *)stack_base, (MAX_ARG_PAGES+1)*X86_PAGE_SIZE, | |
| 274 | + PROT_READ | PROT_WRITE, | |
| 275 | + MAP_GROWSDOWN | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) { | |
| 276 | + perror("stk mmap"); | |
| 277 | + exit(-1); | |
| 278 | + } | |
| 279 | + } | |
| 280 | + | |
| 281 | + stktop = stack_base; | |
| 282 | + | |
| 283 | + for (i = 0 ; i < MAX_ARG_PAGES ; i++) { | |
| 284 | + if (bprm->page[i]) { | |
| 285 | + info->rss++; | |
| 286 | + | |
| 287 | + memcpy((void *)stack_base, (void *)bprm->page[i], X86_PAGE_SIZE); | |
| 288 | + free_page((void *)bprm->page[i]); | |
| 289 | + } | |
| 290 | + stack_base += X86_PAGE_SIZE; | |
| 291 | + } | |
| 292 | + return p; | |
| 293 | +} | |
| 294 | + | |
| 295 | +static void set_brk(unsigned long start, unsigned long end) | |
| 296 | +{ | |
| 297 | + /* page-align the start and end addresses... */ | |
| 298 | + start = ALPHA_PAGE_ALIGN(start); | |
| 299 | + end = ALPHA_PAGE_ALIGN(end); | |
| 300 | + if (end <= start) | |
| 301 | + return; | |
| 302 | + if((long)mmap4k(start, end - start, | |
| 303 | + PROT_READ | PROT_WRITE | PROT_EXEC, | |
| 304 | + MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) { | |
| 305 | + perror("cannot mmap brk"); | |
| 306 | + exit(-1); | |
| 307 | + } | |
| 308 | +} | |
| 309 | + | |
| 310 | + | |
| 311 | +/* We need to explicitly zero any fractional pages | |
| 312 | + after the data section (i.e. bss). This would | |
| 313 | + contain the junk from the file that should not | |
| 314 | + be in memory */ | |
| 315 | + | |
| 316 | + | |
| 317 | +static void padzero(unsigned long elf_bss) | |
| 318 | +{ | |
| 319 | + unsigned long nbyte; | |
| 320 | + char * fpnt; | |
| 321 | + | |
| 322 | + nbyte = elf_bss & (ALPHA_PAGE_SIZE-1); /* was X86_PAGE_SIZE - JRP */ | |
| 323 | + if (nbyte) { | |
| 324 | + nbyte = ALPHA_PAGE_SIZE - nbyte; | |
| 325 | + fpnt = (char *) elf_bss; | |
| 326 | + do { | |
| 327 | + *fpnt++ = 0; | |
| 328 | + } while (--nbyte); | |
| 329 | + } | |
| 330 | +} | |
| 331 | + | |
| 332 | +static unsigned int * create_elf_tables(char *p, int argc, int envc, | |
| 333 | + struct elfhdr * exec, | |
| 334 | + unsigned long load_addr, | |
| 335 | + unsigned long interp_load_addr, int ibcs, | |
| 336 | + struct image_info *info) | |
| 337 | +{ | |
| 338 | + unsigned int *argv, *envp, *dlinfo; | |
| 339 | + unsigned int *sp; | |
| 340 | + char **alpha_envp; | |
| 341 | + | |
| 342 | + /* | |
| 343 | + * Force 16 byte alignment here for generality. | |
| 344 | + */ | |
| 345 | + sp = (unsigned int *) (~15UL & (unsigned long) p); | |
| 346 | + sp -= exec ? DLINFO_ITEMS*2 : 2; | |
| 347 | + dlinfo = sp; | |
| 348 | + sp -= envc+1; | |
| 349 | + envp = sp; | |
| 350 | + sp -= argc+1; | |
| 351 | + argv = sp; | |
| 352 | + if (!ibcs) { | |
| 353 | + put_user(envp,--sp); | |
| 354 | + put_user(argv,--sp); | |
| 355 | + } | |
| 356 | + alpha_envp = (char **)malloc((envc+1) * sizeof(char *)); | |
| 357 | + | |
| 358 | +#define NEW_AUX_ENT(id, val) \ | |
| 359 | + put_user ((id), dlinfo++); \ | |
| 360 | + put_user ((val), dlinfo++) | |
| 361 | + | |
| 362 | + if (exec) { /* Put this here for an ELF program interpreter */ | |
| 363 | + struct elf_phdr * eppnt; | |
| 364 | + eppnt = (struct elf_phdr *)((unsigned long)exec->e_phoff); | |
| 365 | + | |
| 366 | + NEW_AUX_ENT (AT_PHDR, (unsigned int)(load_addr + exec->e_phoff)); | |
| 367 | + NEW_AUX_ENT (AT_PHENT, (unsigned int)(sizeof (struct elf_phdr))); | |
| 368 | + NEW_AUX_ENT (AT_PHNUM, (unsigned int)(exec->e_phnum)); | |
| 369 | + NEW_AUX_ENT (AT_PAGESZ, (unsigned int)(ALPHA_PAGE_SIZE)); | |
| 370 | + NEW_AUX_ENT (AT_BASE, (unsigned int)(interp_load_addr)); | |
| 371 | + NEW_AUX_ENT (AT_FLAGS, (unsigned int)0); | |
| 372 | + NEW_AUX_ENT (AT_ENTRY, (unsigned int) exec->e_entry); | |
| 373 | + NEW_AUX_ENT (AT_UID, (unsigned int) getuid()); | |
| 374 | + NEW_AUX_ENT (AT_EUID, (unsigned int) geteuid()); | |
| 375 | + NEW_AUX_ENT (AT_GID, (unsigned int) getgid()); | |
| 376 | + NEW_AUX_ENT (AT_EGID, (unsigned int) getegid()); | |
| 377 | + } | |
| 378 | + NEW_AUX_ENT (AT_NULL, 0); | |
| 379 | +#undef NEW_AUX_ENT | |
| 380 | + put_user((unsigned int)argc,--sp); | |
| 381 | + info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff); | |
| 382 | + while (argc-->0) { | |
| 383 | + put_user(p,argv++); | |
| 384 | + while (get_user(p++)) /* nothing */ ; | |
| 385 | + } | |
| 386 | + put_user(0,argv); | |
| 387 | + info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff); | |
| 388 | + __environ = alpha_envp; | |
| 389 | + while (envc-->0) { | |
| 390 | + *alpha_envp++ = (char *)p; | |
| 391 | + put_user(p,envp++); | |
| 392 | + while (get_user(p++)) /* nothing */ ; | |
| 393 | + } | |
| 394 | + put_user(0,envp); | |
| 395 | + *alpha_envp = 0; | |
| 396 | + info->env_end = (unsigned int)((unsigned long)p & 0xffffffff); | |
| 397 | + return sp; | |
| 398 | +} | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | +static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, | |
| 403 | + int interpreter_fd, | |
| 404 | + unsigned long *interp_load_addr) | |
| 405 | +{ | |
| 406 | + struct elf_phdr *elf_phdata = NULL; | |
| 407 | + struct elf_phdr *eppnt; | |
| 408 | + unsigned long load_addr; | |
| 409 | + int load_addr_set = 0; | |
| 410 | + int retval; | |
| 411 | + unsigned long last_bss, elf_bss; | |
| 412 | + unsigned long error; | |
| 413 | + int i; | |
| 414 | + | |
| 415 | + elf_bss = 0; | |
| 416 | + last_bss = 0; | |
| 417 | + error = 0; | |
| 418 | + | |
| 419 | + /* We put this here so that mmap will search for the *first* | |
| 420 | + * available memory... | |
| 421 | + */ | |
| 422 | + load_addr = INTERP_LOADADDR; | |
| 423 | + | |
| 424 | + /* First of all, some simple consistency checks */ | |
| 425 | + if ((interp_elf_ex->e_type != ET_EXEC && | |
| 426 | + interp_elf_ex->e_type != ET_DYN) || | |
| 427 | + !elf_check_arch(interp_elf_ex->e_machine)) { | |
| 428 | + return ~0UL; | |
| 429 | + } | |
| 430 | + | |
| 431 | + /* Now read in all of the header information */ | |
| 432 | + | |
| 433 | + if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > X86_PAGE_SIZE) | |
| 434 | + return ~0UL; | |
| 435 | + | |
| 436 | + elf_phdata = (struct elf_phdr *) | |
| 437 | + malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); | |
| 438 | + | |
| 439 | + if (!elf_phdata) | |
| 440 | + return ~0UL; | |
| 441 | + | |
| 442 | + /* | |
| 443 | + * If the size of this structure has changed, then punt, since | |
| 444 | + * we will be doing the wrong thing. | |
| 445 | + */ | |
| 446 | + if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) | |
| 447 | + { | |
| 448 | + free(elf_phdata); | |
| 449 | + return ~0UL; | |
| 450 | + } | |
| 451 | + | |
| 452 | + retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET); | |
| 453 | + if(retval >= 0) { | |
| 454 | + retval = read(interpreter_fd, | |
| 455 | + (char *) elf_phdata, | |
| 456 | + sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); | |
| 457 | + } | |
| 458 | + | |
| 459 | + if (retval < 0) { | |
| 460 | + perror("load_elf_interp"); | |
| 461 | + exit(-1); | |
| 462 | + free (elf_phdata); | |
| 463 | + return retval; | |
| 464 | + } | |
| 465 | +#ifdef BSWAP_NEEDED | |
| 466 | + eppnt = elf_phdata; | |
| 467 | + for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) { | |
| 468 | + bswap_phdr(eppnt); | |
| 469 | + } | |
| 470 | +#endif | |
| 471 | + eppnt = elf_phdata; | |
| 472 | + for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) | |
| 473 | + if (eppnt->p_type == PT_LOAD) { | |
| 474 | + int elf_type = MAP_PRIVATE | MAP_DENYWRITE; | |
| 475 | + int elf_prot = 0; | |
| 476 | + unsigned long vaddr = 0; | |
| 477 | + unsigned long k; | |
| 478 | + | |
| 479 | + if (eppnt->p_flags & PF_R) elf_prot = PROT_READ; | |
| 480 | + if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; | |
| 481 | + if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; | |
| 482 | + if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) { | |
| 483 | + elf_type |= MAP_FIXED; | |
| 484 | + vaddr = eppnt->p_vaddr; | |
| 485 | + } | |
| 486 | + error = (unsigned long)mmap4k(load_addr+X86_ELF_PAGESTART(vaddr), | |
| 487 | + eppnt->p_filesz + X86_ELF_PAGEOFFSET(eppnt->p_vaddr), | |
| 488 | + elf_prot, | |
| 489 | + elf_type, | |
| 490 | + interpreter_fd, | |
| 491 | + eppnt->p_offset - X86_ELF_PAGEOFFSET(eppnt->p_vaddr)); | |
| 492 | + | |
| 493 | + if (error > -1024UL) { | |
| 494 | + /* Real error */ | |
| 495 | + close(interpreter_fd); | |
| 496 | + free(elf_phdata); | |
| 497 | + return ~0UL; | |
| 498 | + } | |
| 499 | + | |
| 500 | + if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { | |
| 501 | + load_addr = error; | |
| 502 | + load_addr_set = 1; | |
| 503 | + } | |
| 504 | + | |
| 505 | + /* | |
| 506 | + * Find the end of the file mapping for this phdr, and keep | |
| 507 | + * track of the largest address we see for this. | |
| 508 | + */ | |
| 509 | + k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; | |
| 510 | + if (k > elf_bss) elf_bss = k; | |
| 511 | + | |
| 512 | + /* | |
| 513 | + * Do the same thing for the memory mapping - between | |
| 514 | + * elf_bss and last_bss is the bss section. | |
| 515 | + */ | |
| 516 | + k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; | |
| 517 | + if (k > last_bss) last_bss = k; | |
| 518 | + } | |
| 519 | + | |
| 520 | + /* Now use mmap to map the library into memory. */ | |
| 521 | + | |
| 522 | + close(interpreter_fd); | |
| 523 | + | |
| 524 | + /* | |
| 525 | + * Now fill out the bss section. First pad the last page up | |
| 526 | + * to the page boundary, and then perform a mmap to make sure | |
| 527 | + * that there are zeromapped pages up to and including the last | |
| 528 | + * bss page. | |
| 529 | + */ | |
| 530 | + padzero(elf_bss); | |
| 531 | + elf_bss = X86_ELF_PAGESTART(elf_bss + ALPHA_PAGE_SIZE - 1); /* What we have mapped so far */ | |
| 532 | + | |
| 533 | + /* Map the last of the bss segment */ | |
| 534 | + if (last_bss > elf_bss) { | |
| 535 | + mmap4k(elf_bss, last_bss-elf_bss, | |
| 536 | + PROT_READ|PROT_WRITE|PROT_EXEC, | |
| 537 | + MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |
| 538 | + } | |
| 539 | + free(elf_phdata); | |
| 540 | + | |
| 541 | + *interp_load_addr = load_addr; | |
| 542 | + return ((unsigned long) interp_elf_ex->e_entry) + load_addr; | |
| 543 | +} | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | +static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs, | |
| 548 | + struct image_info * info) | |
| 549 | +{ | |
| 550 | + struct elfhdr elf_ex; | |
| 551 | + struct elfhdr interp_elf_ex; | |
| 552 | + struct exec interp_ex; | |
| 553 | + int interpreter_fd = -1; /* avoid warning */ | |
| 554 | + unsigned long load_addr; | |
| 555 | + int load_addr_set = 0; | |
| 556 | + unsigned int interpreter_type = INTERPRETER_NONE; | |
| 557 | + unsigned char ibcs2_interpreter; | |
| 558 | + int i; | |
| 559 | + void * mapped_addr; | |
| 560 | + struct elf_phdr * elf_ppnt; | |
| 561 | + struct elf_phdr *elf_phdata; | |
| 562 | + unsigned long elf_bss, k, elf_brk; | |
| 563 | + int retval; | |
| 564 | + char * elf_interpreter; | |
| 565 | + unsigned long elf_entry, interp_load_addr = 0; | |
| 566 | + int status; | |
| 567 | + unsigned long start_code, end_code, end_data; | |
| 568 | + unsigned long elf_stack; | |
| 569 | + char passed_fileno[6]; | |
| 570 | + | |
| 571 | + ibcs2_interpreter = 0; | |
| 572 | + status = 0; | |
| 573 | + load_addr = 0; | |
| 574 | + elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ | |
| 575 | +#ifdef BSWAP_NEEDED | |
| 576 | + bswap_ehdr(&elf_ex); | |
| 577 | +#endif | |
| 578 | + | |
| 579 | + if (elf_ex.e_ident[0] != 0x7f || | |
| 580 | + strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) { | |
| 581 | + return -ENOEXEC; | |
| 582 | + } | |
| 583 | + | |
| 584 | + | |
| 585 | + /* First of all, some simple consistency checks */ | |
| 586 | + if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || | |
| 587 | + (! elf_check_arch(elf_ex.e_machine))) { | |
| 588 | + return -ENOEXEC; | |
| 589 | + } | |
| 590 | + | |
| 591 | + /* Now read in all of the header information */ | |
| 592 | + | |
| 593 | + elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum); | |
| 594 | + if (elf_phdata == NULL) { | |
| 595 | + return -ENOMEM; | |
| 596 | + } | |
| 597 | + | |
| 598 | + retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET); | |
| 599 | + if(retval > 0) { | |
| 600 | + retval = read(bprm->fd, (char *) elf_phdata, | |
| 601 | + elf_ex.e_phentsize * elf_ex.e_phnum); | |
| 602 | + } | |
| 603 | + | |
| 604 | + if (retval < 0) { | |
| 605 | + perror("load_elf_binary"); | |
| 606 | + exit(-1); | |
| 607 | + free (elf_phdata); | |
| 608 | + return -errno; | |
| 609 | + } | |
| 610 | + | |
| 611 | + elf_ppnt = elf_phdata; | |
| 612 | + | |
| 613 | + elf_bss = 0; | |
| 614 | + elf_brk = 0; | |
| 615 | + | |
| 616 | + | |
| 617 | + elf_stack = ~0UL; | |
| 618 | + elf_interpreter = NULL; | |
| 619 | + start_code = ~0UL; | |
| 620 | + end_code = 0; | |
| 621 | + end_data = 0; | |
| 622 | + | |
| 623 | + for(i=0;i < elf_ex.e_phnum; i++) { | |
| 624 | + if (elf_ppnt->p_type == PT_INTERP) { | |
| 625 | + if ( elf_interpreter != NULL ) | |
| 626 | + { | |
| 627 | + free (elf_phdata); | |
| 628 | + free(elf_interpreter); | |
| 629 | + close(bprm->fd); | |
| 630 | + return -EINVAL; | |
| 631 | + } | |
| 632 | + | |
| 633 | + /* This is the program interpreter used for | |
| 634 | + * shared libraries - for now assume that this | |
| 635 | + * is an a.out format binary | |
| 636 | + */ | |
| 637 | + | |
| 638 | + elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+strlen(X86_DEFAULT_LIB_DIR)); | |
| 639 | + | |
| 640 | + if (elf_interpreter == NULL) { | |
| 641 | + free (elf_phdata); | |
| 642 | + close(bprm->fd); | |
| 643 | + return -ENOMEM; | |
| 644 | + } | |
| 645 | + | |
| 646 | + strcpy(elf_interpreter, X86_DEFAULT_LIB_DIR); | |
| 647 | + retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET); | |
| 648 | + if(retval >= 0) { | |
| 649 | + retval = read(bprm->fd, | |
| 650 | + elf_interpreter+strlen(X86_DEFAULT_LIB_DIR), | |
| 651 | + elf_ppnt->p_filesz); | |
| 652 | + } | |
| 653 | + if(retval < 0) { | |
| 654 | + perror("load_elf_binary2"); | |
| 655 | + exit(-1); | |
| 656 | + } | |
| 657 | + | |
| 658 | + /* If the program interpreter is one of these two, | |
| 659 | + then assume an iBCS2 image. Otherwise assume | |
| 660 | + a native linux image. */ | |
| 661 | + | |
| 662 | + /* JRP - Need to add X86 lib dir stuff here... */ | |
| 663 | + | |
| 664 | + if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 || | |
| 665 | + strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) { | |
| 666 | + ibcs2_interpreter = 1; | |
| 667 | + } | |
| 668 | + | |
| 669 | +#if 0 | |
| 670 | + printf("Using ELF interpreter %s\n", elf_interpreter); | |
| 671 | +#endif | |
| 672 | + if (retval >= 0) { | |
| 673 | + retval = open(elf_interpreter, O_RDONLY); | |
| 674 | + if(retval >= 0) { | |
| 675 | + interpreter_fd = retval; | |
| 676 | + } | |
| 677 | + else { | |
| 678 | + perror(elf_interpreter); | |
| 679 | + exit(-1); | |
| 680 | + /* retval = -errno; */ | |
| 681 | + } | |
| 682 | + } | |
| 683 | + | |
| 684 | + if (retval >= 0) { | |
| 685 | + retval = lseek(interpreter_fd, 0, SEEK_SET); | |
| 686 | + if(retval >= 0) { | |
| 687 | + retval = read(interpreter_fd,bprm->buf,128); | |
| 688 | + } | |
| 689 | + } | |
| 690 | + if (retval >= 0) { | |
| 691 | + interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */ | |
| 692 | + interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */ | |
| 693 | + } | |
| 694 | + if (retval < 0) { | |
| 695 | + perror("load_elf_binary3"); | |
| 696 | + exit(-1); | |
| 697 | + free (elf_phdata); | |
| 698 | + free(elf_interpreter); | |
| 699 | + close(bprm->fd); | |
| 700 | + return retval; | |
| 701 | + } | |
| 702 | + } | |
| 703 | + elf_ppnt++; | |
| 704 | + } | |
| 705 | + | |
| 706 | + /* Some simple consistency checks for the interpreter */ | |
| 707 | + if (elf_interpreter){ | |
| 708 | + interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT; | |
| 709 | + | |
| 710 | + /* Now figure out which format our binary is */ | |
| 711 | + if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) && | |
| 712 | + (N_MAGIC(interp_ex) != QMAGIC)) { | |
| 713 | + interpreter_type = INTERPRETER_ELF; | |
| 714 | + } | |
| 715 | + | |
| 716 | + if (interp_elf_ex.e_ident[0] != 0x7f || | |
| 717 | + strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) { | |
| 718 | + interpreter_type &= ~INTERPRETER_ELF; | |
| 719 | + } | |
| 720 | + | |
| 721 | + if (!interpreter_type) { | |
| 722 | + free(elf_interpreter); | |
| 723 | + free(elf_phdata); | |
| 724 | + close(bprm->fd); | |
| 725 | + return -ELIBBAD; | |
| 726 | + } | |
| 727 | + } | |
| 728 | + | |
| 729 | + /* OK, we are done with that, now set up the arg stuff, | |
| 730 | + and then start this sucker up */ | |
| 731 | + | |
| 732 | + if (!bprm->sh_bang) { | |
| 733 | + char * passed_p; | |
| 734 | + | |
| 735 | + if (interpreter_type == INTERPRETER_AOUT) { | |
| 736 | + sprintf(passed_fileno, "%d", bprm->fd); | |
| 737 | + passed_p = passed_fileno; | |
| 738 | + | |
| 739 | + if (elf_interpreter) { | |
| 740 | + bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p); | |
| 741 | + bprm->argc++; | |
| 742 | + } | |
| 743 | + } | |
| 744 | + if (!bprm->p) { | |
| 745 | + if (elf_interpreter) { | |
| 746 | + free(elf_interpreter); | |
| 747 | + } | |
| 748 | + free (elf_phdata); | |
| 749 | + close(bprm->fd); | |
| 750 | + return -E2BIG; | |
| 751 | + } | |
| 752 | + } | |
| 753 | + | |
| 754 | + /* OK, This is the point of no return */ | |
| 755 | + info->end_data = 0; | |
| 756 | + info->end_code = 0; | |
| 757 | + info->start_mmap = (unsigned long)ELF_START_MMAP; | |
| 758 | + info->mmap = 0; | |
| 759 | + elf_entry = (unsigned long) elf_ex.e_entry; | |
| 760 | + | |
| 761 | + /* Do this so that we can load the interpreter, if need be. We will | |
| 762 | + change some of these later */ | |
| 763 | + info->rss = 0; | |
| 764 | + bprm->p = setup_arg_pages(bprm->p, bprm, info); | |
| 765 | + info->start_stack = bprm->p; | |
| 766 | + | |
| 767 | + /* Now we do a little grungy work by mmaping the ELF image into | |
| 768 | + * the correct location in memory. At this point, we assume that | |
| 769 | + * the image should be loaded at fixed address, not at a variable | |
| 770 | + * address. | |
| 771 | + */ | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { | |
| 776 | + if (elf_ppnt->p_type == PT_LOAD) { | |
| 777 | + int elf_prot = 0; | |
| 778 | + if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ; | |
| 779 | + if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; | |
| 780 | + if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; | |
| 781 | + | |
| 782 | + mapped_addr = mmap4k(X86_ELF_PAGESTART(elf_ppnt->p_vaddr), | |
| 783 | + (elf_ppnt->p_filesz + | |
| 784 | + X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)), | |
| 785 | + elf_prot, | |
| 786 | + (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE), | |
| 787 | + bprm->fd, | |
| 788 | + (elf_ppnt->p_offset - | |
| 789 | + X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr))); | |
| 790 | + | |
| 791 | + if((unsigned long)mapped_addr == 0xffffffffffffffff) { | |
| 792 | + perror("mmap"); | |
| 793 | + exit(-1); | |
| 794 | + } | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | +#ifdef LOW_ELF_STACK | |
| 799 | + if (X86_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack) | |
| 800 | + elf_stack = X86_ELF_PAGESTART(elf_ppnt->p_vaddr); | |
| 801 | +#endif | |
| 802 | + | |
| 803 | + if (!load_addr_set) { | |
| 804 | + load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset; | |
| 805 | + load_addr_set = 1; | |
| 806 | + } | |
| 807 | + k = elf_ppnt->p_vaddr; | |
| 808 | + if (k < start_code) start_code = k; | |
| 809 | + k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz; | |
| 810 | + if (k > elf_bss) elf_bss = k; | |
| 811 | +#if 1 | |
| 812 | + if ((elf_ppnt->p_flags & PF_X) && end_code < k) | |
| 813 | +#else | |
| 814 | + if ( !(elf_ppnt->p_flags & PF_W) && end_code < k) | |
| 815 | +#endif | |
| 816 | + end_code = k; | |
| 817 | + if (end_data < k) end_data = k; | |
| 818 | + k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz; | |
| 819 | + if (k > elf_brk) elf_brk = k; | |
| 820 | + } | |
| 821 | + } | |
| 822 | + | |
| 823 | + if (elf_interpreter) { | |
| 824 | + if (interpreter_type & 1) { | |
| 825 | + elf_entry = load_aout_interp(&interp_ex, interpreter_fd); | |
| 826 | + } | |
| 827 | + else if (interpreter_type & 2) { | |
| 828 | + elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd, | |
| 829 | + &interp_load_addr); | |
| 830 | + } | |
| 831 | + | |
| 832 | + close(interpreter_fd); | |
| 833 | + free(elf_interpreter); | |
| 834 | + | |
| 835 | + if (elf_entry == ~0UL) { | |
| 836 | + printf("Unable to load interpreter\n"); | |
| 837 | + free(elf_phdata); | |
| 838 | + exit(-1); | |
| 839 | + return 0; | |
| 840 | + } | |
| 841 | + } | |
| 842 | + | |
| 843 | + free(elf_phdata); | |
| 844 | + | |
| 845 | + if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd); | |
| 846 | + info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX); | |
| 847 | + | |
| 848 | +#ifdef LOW_ELF_STACK | |
| 849 | + info->start_stack = bprm->p = elf_stack - 4; | |
| 850 | +#endif | |
| 851 | + bprm->p = (unsigned long) | |
| 852 | + create_elf_tables((char *)bprm->p, | |
| 853 | + bprm->argc, | |
| 854 | + bprm->envc, | |
| 855 | + (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL), | |
| 856 | + load_addr, | |
| 857 | + interp_load_addr, | |
| 858 | + (interpreter_type == INTERPRETER_AOUT ? 0 : 1), | |
| 859 | + info); | |
| 860 | + if (interpreter_type == INTERPRETER_AOUT) | |
| 861 | + info->arg_start += strlen(passed_fileno) + 1; | |
| 862 | + info->start_brk = info->brk = elf_brk; | |
| 863 | + info->end_code = end_code; | |
| 864 | + info->start_code = start_code; | |
| 865 | + info->end_data = end_data; | |
| 866 | + info->start_stack = bprm->p; | |
| 867 | + | |
| 868 | + /* Calling set_brk effectively mmaps the pages that we need for the bss and break | |
| 869 | + sections */ | |
| 870 | + set_brk(elf_bss, elf_brk); | |
| 871 | + | |
| 872 | + padzero(elf_bss); | |
| 873 | + | |
| 874 | +#if 0 | |
| 875 | + printf("(start_brk) %x\n" , info->start_brk); | |
| 876 | + printf("(end_code) %x\n" , info->end_code); | |
| 877 | + printf("(start_code) %x\n" , info->start_code); | |
| 878 | + printf("(end_data) %x\n" , info->end_data); | |
| 879 | + printf("(start_stack) %x\n" , info->start_stack); | |
| 880 | + printf("(brk) %x\n" , info->brk); | |
| 881 | +#endif | |
| 882 | + | |
| 883 | + if ( info->personality == PER_SVR4 ) | |
| 884 | + { | |
| 885 | + /* Why this, you ask??? Well SVr4 maps page 0 as read-only, | |
| 886 | + and some applications "depend" upon this behavior. | |
| 887 | + Since we do not have the power to recompile these, we | |
| 888 | + emulate the SVr4 behavior. Sigh. */ | |
| 889 | + mapped_addr = mmap4k(NULL, ALPHA_PAGE_SIZE, PROT_READ | PROT_EXEC, | |
| 890 | + MAP_FIXED | MAP_PRIVATE, -1, 0); | |
| 891 | + } | |
| 892 | + | |
| 893 | +#ifdef ELF_PLAT_INIT | |
| 894 | + /* | |
| 895 | + * The ABI may specify that certain registers be set up in special | |
| 896 | + * ways (on i386 %edx is the address of a DT_FINI function, for | |
| 897 | + * example. This macro performs whatever initialization to | |
| 898 | + * the regs structure is required. | |
| 899 | + */ | |
| 900 | + ELF_PLAT_INIT(regs); | |
| 901 | +#endif | |
| 902 | + | |
| 903 | + | |
| 904 | + info->entry = elf_entry; | |
| 905 | + | |
| 906 | + return 0; | |
| 907 | +} | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | +int elf_exec(const char * filename, char ** argv, char ** envp, | |
| 912 | + struct pt_regs * regs, struct image_info *infop) | |
| 913 | +{ | |
| 914 | + struct linux_binprm bprm; | |
| 915 | + int retval; | |
| 916 | + int i; | |
| 917 | + | |
| 918 | + bprm.p = X86_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); | |
| 919 | + for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ | |
| 920 | + bprm.page[i] = 0; | |
| 921 | + retval = open(filename, O_RDONLY); | |
| 922 | + if (retval == -1) { | |
| 923 | + perror(filename); | |
| 924 | + exit(-1); | |
| 925 | + /* return retval; */ | |
| 926 | + } | |
| 927 | + else { | |
| 928 | + bprm.fd = retval; | |
| 929 | + } | |
| 930 | + bprm.filename = (char *)filename; | |
| 931 | + bprm.sh_bang = 0; | |
| 932 | + bprm.loader = 0; | |
| 933 | + bprm.exec = 0; | |
| 934 | + bprm.dont_iput = 0; | |
| 935 | + bprm.argc = count(argv); | |
| 936 | + bprm.envc = count(envp); | |
| 937 | + | |
| 938 | + retval = prepare_binprm(&bprm); | |
| 939 | + | |
| 940 | + if(retval>=0) { | |
| 941 | + bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p); | |
| 942 | + bprm.exec = bprm.p; | |
| 943 | + bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p); | |
| 944 | + bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p); | |
| 945 | + if (!bprm.p) { | |
| 946 | + retval = -E2BIG; | |
| 947 | + } | |
| 948 | + } | |
| 949 | + | |
| 950 | + if(retval>=0) { | |
| 951 | + retval = load_elf_binary(&bprm,regs,infop); | |
| 952 | + } | |
| 953 | + if(retval>=0) { | |
| 954 | + /* success. Initialize important registers */ | |
| 955 | + regs->esp = infop->start_stack; | |
| 956 | + regs->eip = infop->entry; | |
| 957 | + return retval; | |
| 958 | + } | |
| 959 | + | |
| 960 | + /* Something went wrong, return the inode and free the argument pages*/ | |
| 961 | + for (i=0 ; i<MAX_ARG_PAGES ; i++) { | |
| 962 | + free_page((void *)bprm.page[i]); | |
| 963 | + } | |
| 964 | + return(retval); | |
| 965 | +} | |
| 966 | + | |
| 967 | + | |
| 968 | +static int load_aout_interp(void * exptr, int interp_fd) | |
| 969 | +{ | |
| 970 | + printf("a.out interpreter not yet supported\n"); | |
| 971 | + return(0); | |
| 972 | +} | |
| 973 | + | ... | ... |
linux-user/ioctls.h
0 → 100644
| 1 | + /* emulated ioctl list */ | |
| 2 | + | |
| 3 | + IOCTL(TCGETS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) | |
| 4 | + IOCTL(TCGETS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) | |
| 5 | + IOCTL(TCSETSF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) | |
| 6 | + IOCTL(TCSETSW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) | |
| 7 | + IOCTL(TIOCGWINSZ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_winsize))) | |
| 8 | + IOCTL(TIOCSWINSZ, IOC_W, MK_PTR(MK_STRUCT(STRUCT_winsize))) | |
| 9 | + IOCTL(FIONREAD, IOC_R, MK_PTR(TYPE_INT)) | |
| 10 | + IOCTL(TCGETA, IOC_R, MK_PTR(TYPE_INT)) | |
| 11 | + IOCTL(TCSETA, IOC_W, MK_PTR(TYPE_INT)) | |
| 12 | + IOCTL(TCSETAW, IOC_W, MK_PTR(TYPE_INT)) | |
| 13 | + IOCTL(TCSETAF, IOC_W, MK_PTR(TYPE_INT)) | |
| 14 | + IOCTL(TCSBRK, 0, TYPE_INT) | |
| 15 | + IOCTL(TCSBRKP, 0, TYPE_INT) | |
| 16 | + IOCTL(TCXONC, 0, TYPE_INT) | |
| 17 | + IOCTL(TCFLSH, 0, TYPE_INT) | |
| 18 | + IOCTL(TIOCEXCL, 0, TYPE_NULL) | |
| 19 | + IOCTL(TIOCNXCL, 0, TYPE_NULL) | |
| 20 | + IOCTL(TIOCSCTTY, 0, TYPE_INT) | |
| 21 | + IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) | |
| 22 | + IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT)) | |
| 23 | + IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT)) | |
| 24 | + IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_INT)) | |
| 25 | + IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT)) | |
| 26 | + IOCTL(TIOCMBIS, IOC_W, MK_PTR(TYPE_INT)) | |
| 27 | + IOCTL(TIOCMBIC, IOC_W, MK_PTR(TYPE_INT)) | |
| 28 | + IOCTL(TIOCMSET, IOC_W, MK_PTR(TYPE_INT)) | |
| 29 | + IOCTL(TIOCGSOFTCAR, IOC_R, MK_PTR(TYPE_INT)) | |
| 30 | + IOCTL(TIOCSSOFTCAR, IOC_W, MK_PTR(TYPE_INT)) | |
| 31 | + IOCTL(TIOCLINUX, IOC_R | IOC_W, MK_PTR(TYPE_INT)) | |
| 32 | + IOCTL(TIOCCONS, 0, TYPE_NULL) | |
| 33 | + IOCTL(TIOCGSERIAL, IOC_R, MK_PTR(TYPE_INT)) | |
| 34 | + IOCTL(TIOCSSERIAL, IOC_W, MK_PTR(TYPE_INT)) | |
| 35 | + IOCTL(TIOCPKT, IOC_W, MK_PTR(TYPE_INT)) | |
| 36 | + IOCTL(FIONBIO, IOC_W, MK_PTR(TYPE_INT)) | |
| 37 | + IOCTL(TIOCNOTTY, 0, TYPE_NULL) | |
| 38 | + IOCTL(TIOCGETD, IOC_R, MK_PTR(TYPE_INT)) | |
| 39 | + IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT)) | |
| 40 | + IOCTL(FIOCLEX, 0, TYPE_NULL) | |
| 41 | + IOCTL(FIONCLEX, 0, TYPE_NULL) | |
| 42 | + IOCTL(FIOASYNC, IOC_W, MK_PTR(TYPE_INT)) | |
| 43 | + IOCTL(TIOCGLCKTRMIOS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) | |
| 44 | + IOCTL(TIOCSLCKTRMIOS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) | |
| 45 | + IOCTL(TIOCSERCONFIG, 0, TYPE_NULL) | |
| 46 | + IOCTL(TIOCSERGETLSR, IOC_R, MK_PTR(TYPE_INT)) | |
| 47 | + IOCTL(TIOCSERGETMULTI, IOC_R, MK_PTR(MK_STRUCT(STRUCT_serial_multiport_struct))) | |
| 48 | + IOCTL(TIOCSERSETMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_serial_multiport_struct))) | |
| 49 | + IOCTL(TIOCMIWAIT, 0, TYPE_INT) | |
| 50 | + IOCTL(TIOCGICOUNT, IOC_R, MK_PTR(MK_STRUCT(STRUCT_serial_icounter_struct))) | |
| 51 | + | |
| 52 | + IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT)) | |
| 53 | + IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) | |
| 54 | + IOCTL(BLKRRPART, 0, TYPE_NULL) | |
| 55 | + IOCTL(BLKGETSIZE, IOC_R, MK_PTR(TYPE_ULONG)) | |
| 56 | +#ifdef BLKGETSIZE64 | |
| 57 | + IOCTL(BLKGETSIZE64, IOC_R, MK_PTR(TYPE_ULONGLONG)) | |
| 58 | +#endif | |
| 59 | + IOCTL(BLKFLSBUF, 0, TYPE_NULL) | |
| 60 | + IOCTL(BLKRASET, 0, TYPE_INT) | |
| 61 | + IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG)) | |
| 62 | +#ifdef FIBMAP | |
| 63 | + IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG)) | |
| 64 | +#endif | |
| 65 | +#ifdef FIGETBSZ | |
| 66 | + IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG)) | |
| 67 | +#endif | |
| 68 | + | |
| 69 | + IOCTL(SIOCADDRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry))) | |
| 70 | + IOCTL(SIOCDELRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry))) | |
| 71 | + IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT)) | |
| 72 | + IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq))) | |
| 73 | + IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq))) | |
| 74 | + IOCTL(SIOCGIFADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 75 | + IOCTL(SIOCSIFADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 76 | + IOCTL(SIOCGIFBRDADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 77 | + IOCTL(SIOCSIFBRDADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 78 | + IOCTL(SIOCGIFDSTADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 79 | + IOCTL(SIOCSIFDSTADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 80 | + IOCTL(SIOCGIFNETMASK, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 81 | + IOCTL(SIOCSIFNETMASK, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 82 | + IOCTL(SIOCGIFHWADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 83 | + IOCTL(SIOCSIFHWADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 84 | + IOCTL(SIOCGIFTXQLEN, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 85 | + IOCTL(SIOCSIFTXQLEN, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 86 | + IOCTL(SIOCGIFMETRIC, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_int_ifreq))) | |
| 87 | + IOCTL(SIOCSIFMETRIC, IOC_W, MK_PTR(MK_STRUCT(STRUCT_int_ifreq))) | |
| 88 | + IOCTL(SIOCGIFMTU, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_int_ifreq))) | |
| 89 | + IOCTL(SIOCSIFMTU, IOC_W, MK_PTR(MK_STRUCT(STRUCT_int_ifreq))) | |
| 90 | + IOCTL(SIOCGIFMAP, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifmap_ifreq))) | |
| 91 | + IOCTL(SIOCSIFMAP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_ifmap_ifreq))) | |
| 92 | + IOCTL(SIOCGIFSLAVE, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq))) | |
| 93 | + IOCTL(SIOCSIFSLAVE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_char_ifreq))) | |
| 94 | + IOCTL(SIOCGIFMEM, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ptr_ifreq))) | |
| 95 | + IOCTL(SIOCSIFMEM, IOC_W, MK_PTR(MK_STRUCT(STRUCT_ptr_ifreq))) | |
| 96 | + IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 97 | + IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) | |
| 98 | + IOCTL(SIOCSIFLINK, 0, TYPE_NULL) | |
| 99 | + IOCTL(SIOCGIFCONF, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifconf))) | |
| 100 | + IOCTL(SIOCGIFENCAP, IOC_RW, MK_PTR(TYPE_INT)) | |
| 101 | + IOCTL(SIOCSIFENCAP, IOC_W, MK_PTR(TYPE_INT)) | |
| 102 | + IOCTL(SIOCDARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) | |
| 103 | + IOCTL(SIOCSARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) | |
| 104 | + IOCTL(SIOCGARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq))) | |
| 105 | + IOCTL(SIOCDRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) | |
| 106 | + IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) | |
| 107 | + IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq))) | |
| 108 | + | |
| 109 | + IOCTL(CDROMPAUSE, 0, TYPE_NULL) | |
| 110 | + IOCTL(CDROMSTART, 0, TYPE_NULL) | |
| 111 | + IOCTL(CDROMSTOP, 0, TYPE_NULL) | |
| 112 | + IOCTL(CDROMRESUME, 0, TYPE_NULL) | |
| 113 | + IOCTL(CDROMEJECT, 0, TYPE_NULL) | |
| 114 | + IOCTL(CDROMEJECT_SW, 0, TYPE_INT) | |
| 115 | + IOCTL(CDROMCLOSETRAY, 0, TYPE_NULL) | |
| 116 | + IOCTL(CDROMRESET, 0, TYPE_NULL) | |
| 117 | + IOCTL(CDROMPLAYMSF, IOC_W, MK_PTR(TYPE_INT)) | |
| 118 | + IOCTL(CDROMPLAYTRKIND, IOC_W, MK_PTR(TYPE_INT)) | |
| 119 | + IOCTL(CDROMREADTOCHDR, IOC_R, MK_PTR(TYPE_INT)) | |
| 120 | + IOCTL(CDROMREADTOCENTRY, IOC_RW, MK_PTR(TYPE_INT)) | |
| 121 | + IOCTL(CDROMVOLCTRL, IOC_W, MK_PTR(TYPE_INT)) | |
| 122 | + IOCTL(CDROMSUBCHNL, IOC_RW, MK_PTR(TYPE_INT)) | |
| 123 | + /* XXX: incorrect (need specific handling) */ | |
| 124 | + IOCTL(CDROMREADAUDIO, IOC_W, MK_PTR(MK_STRUCT(STRUCT_cdrom_read_audio))) | |
| 125 | + IOCTL(CDROMREADCOOKED, IOC_RW, MK_PTR(TYPE_INT)) | |
| 126 | + IOCTL(CDROMREADRAW, IOC_RW, MK_PTR(TYPE_INT)) | |
| 127 | + IOCTL(CDROMREADMODE1, IOC_RW, MK_PTR(TYPE_INT)) | |
| 128 | + IOCTL(CDROMREADMODE2, IOC_RW, MK_PTR(TYPE_INT)) | |
| 129 | + IOCTL(CDROMREADALL, IOC_RW, MK_PTR(TYPE_INT)) | |
| 130 | + IOCTL(CDROMMULTISESSION, IOC_RW, MK_PTR(TYPE_INT)) | |
| 131 | + IOCTL(CDROM_GET_UPC, IOC_R, MK_PTR(TYPE_INT)) | |
| 132 | + IOCTL(CDROMVOLREAD, IOC_R, MK_PTR(TYPE_INT)) | |
| 133 | + IOCTL(CDROMSEEK, IOC_W, MK_PTR(TYPE_INT)) | |
| 134 | + IOCTL(CDROMPLAYBLK, IOC_W, MK_PTR(TYPE_INT)) | |
| 135 | + IOCTL(CDROM_MEDIA_CHANGED, 0, TYPE_NULL) | |
| 136 | + IOCTL(CDROM_SET_OPTIONS, 0, TYPE_INT) | |
| 137 | + IOCTL(CDROM_CLEAR_OPTIONS, 0, TYPE_INT) | |
| 138 | + IOCTL(CDROM_SELECT_SPEED, 0, TYPE_INT) | |
| 139 | + IOCTL(CDROM_SELECT_DISC, 0, TYPE_INT) | |
| 140 | + IOCTL(CDROM_DRIVE_STATUS, 0, TYPE_NULL) | |
| 141 | + IOCTL(CDROM_DISC_STATUS, 0, TYPE_NULL) | |
| 142 | + IOCTL(CDROMAUDIOBUFSIZ, 0, TYPE_INT) | |
| 143 | + | |
| 144 | + IOCTL(SNDCTL_COPR_HALT, IOC_RW, MK_PTR(TYPE_INT)) | |
| 145 | + IOCTL(SNDCTL_COPR_LOAD, IOC_RW, MK_PTR(TYPE_INT)) | |
| 146 | + IOCTL(SNDCTL_COPR_RCODE, IOC_RW, MK_PTR(TYPE_INT)) | |
| 147 | + IOCTL(SNDCTL_COPR_RCVMSG, IOC_R, MK_PTR(TYPE_INT)) | |
| 148 | + IOCTL(SNDCTL_COPR_RDATA, IOC_RW, MK_PTR(TYPE_INT)) | |
| 149 | + IOCTL(SNDCTL_COPR_RESET, 0, TYPE_NULL) | |
| 150 | + IOCTL(SNDCTL_COPR_RUN, IOC_RW, MK_PTR(TYPE_INT)) | |
| 151 | + IOCTL(SNDCTL_COPR_SENDMSG, IOC_RW, MK_PTR(TYPE_INT)) | |
| 152 | + IOCTL(SNDCTL_COPR_WCODE, IOC_W, MK_PTR(TYPE_INT)) | |
| 153 | + IOCTL(SNDCTL_COPR_WDATA, IOC_W, MK_PTR(TYPE_INT)) | |
| 154 | + IOCTL(SNDCTL_DSP_CHANNELS, IOC_RW, MK_PTR(TYPE_INT)) | |
| 155 | + IOCTL(SNDCTL_DSP_GETBLKSIZE, IOC_RW, MK_PTR(TYPE_INT)) | |
| 156 | + IOCTL(SNDCTL_DSP_GETCAPS, IOC_R, MK_PTR(TYPE_INT)) | |
| 157 | + IOCTL(SNDCTL_DSP_GETFMTS, IOC_R, MK_PTR(TYPE_INT)) | |
| 158 | + IOCTL(SNDCTL_DSP_GETIPTR, IOC_R, MK_PTR(TYPE_INT)) | |
| 159 | + IOCTL(SNDCTL_DSP_GETISPACE, IOC_R, MK_PTR(TYPE_INT)) | |
| 160 | + IOCTL(SNDCTL_DSP_GETOPTR, IOC_R, MK_PTR(TYPE_INT)) | |
| 161 | + IOCTL(SNDCTL_DSP_GETOSPACE, IOC_R, MK_PTR(TYPE_INT)) | |
| 162 | + IOCTL(SNDCTL_DSP_GETTRIGGER, IOC_R, MK_PTR(TYPE_INT)) | |
| 163 | + IOCTL(SNDCTL_DSP_MAPINBUF, IOC_R, MK_PTR(TYPE_INT)) | |
| 164 | + IOCTL(SNDCTL_DSP_MAPOUTBUF, IOC_R, MK_PTR(TYPE_INT)) | |
| 165 | + IOCTL(SNDCTL_DSP_NONBLOCK, 0, TYPE_NULL) | |
| 166 | + IOCTL(SNDCTL_DSP_POST, 0, TYPE_NULL) | |
| 167 | + IOCTL(SNDCTL_DSP_RESET, 0, TYPE_NULL) | |
| 168 | + IOCTL(SNDCTL_DSP_SETDUPLEX, 0, TYPE_NULL) | |
| 169 | + IOCTL(SNDCTL_DSP_SETFMT, IOC_RW, MK_PTR(TYPE_INT)) | |
| 170 | + IOCTL(SNDCTL_DSP_SETFRAGMENT, IOC_RW, MK_PTR(TYPE_INT)) | |
| 171 | + IOCTL(SNDCTL_DSP_SETSYNCRO, 0, TYPE_NULL) | |
| 172 | + IOCTL(SNDCTL_DSP_SETTRIGGER, IOC_W, MK_PTR(TYPE_INT)) | |
| 173 | + IOCTL(SNDCTL_DSP_SPEED, IOC_RW, MK_PTR(TYPE_INT)) | |
| 174 | + IOCTL(SNDCTL_DSP_STEREO, IOC_RW, MK_PTR(TYPE_INT)) | |
| 175 | + IOCTL(SNDCTL_DSP_SUBDIVIDE, IOC_RW, MK_PTR(TYPE_INT)) | |
| 176 | + IOCTL(SNDCTL_DSP_SYNC, 0, TYPE_NULL) | |
| 177 | + IOCTL(SNDCTL_FM_4OP_ENABLE, IOC_W, MK_PTR(TYPE_INT)) | |
| 178 | + IOCTL(SNDCTL_FM_LOAD_INSTR, IOC_W, MK_PTR(TYPE_INT)) | |
| 179 | + IOCTL(SNDCTL_MIDI_INFO, IOC_RW, MK_PTR(TYPE_INT)) | |
| 180 | + IOCTL(SNDCTL_MIDI_MPUCMD, IOC_RW, MK_PTR(TYPE_INT)) | |
| 181 | + IOCTL(SNDCTL_MIDI_MPUMODE, IOC_RW, MK_PTR(TYPE_INT)) | |
| 182 | + IOCTL(SNDCTL_MIDI_PRETIME, IOC_RW, MK_PTR(TYPE_INT)) | |
| 183 | + IOCTL(SNDCTL_SEQ_CTRLRATE, IOC_RW, MK_PTR(TYPE_INT)) | |
| 184 | + IOCTL(SNDCTL_SEQ_GETINCOUNT, IOC_R, MK_PTR(TYPE_INT)) | |
| 185 | + IOCTL(SNDCTL_SEQ_GETOUTCOUNT, IOC_R, MK_PTR(TYPE_INT)) | |
| 186 | + IOCTL(SNDCTL_SEQ_NRMIDIS, IOC_R, MK_PTR(TYPE_INT)) | |
| 187 | + IOCTL(SNDCTL_SEQ_NRSYNTHS, IOC_R, MK_PTR(TYPE_INT)) | |
| 188 | + IOCTL(SNDCTL_SEQ_OUTOFBAND, IOC_W, MK_PTR(TYPE_INT)) | |
| 189 | + IOCTL(SNDCTL_SEQ_PANIC, 0, TYPE_NULL) | |
| 190 | + IOCTL(SNDCTL_SEQ_PERCMODE, IOC_W, MK_PTR(TYPE_INT)) | |
| 191 | + IOCTL(SNDCTL_SEQ_RESET, 0, TYPE_NULL) | |
| 192 | + IOCTL(SNDCTL_SEQ_RESETSAMPLES, IOC_W, MK_PTR(TYPE_INT)) | |
| 193 | + IOCTL(SNDCTL_SEQ_SYNC, 0, TYPE_NULL) | |
| 194 | + IOCTL(SNDCTL_SEQ_TESTMIDI, IOC_W, MK_PTR(TYPE_INT)) | |
| 195 | + IOCTL(SNDCTL_SEQ_THRESHOLD, IOC_W, MK_PTR(TYPE_INT)) | |
| 196 | + IOCTL(SNDCTL_SYNTH_INFO, IOC_RW, MK_PTR(TYPE_INT)) | |
| 197 | + IOCTL(SNDCTL_SYNTH_MEMAVL, IOC_RW, MK_PTR(TYPE_INT)) | |
| 198 | + IOCTL(SNDCTL_TMR_CONTINUE, 0, TYPE_NULL) | |
| 199 | + IOCTL(SNDCTL_TMR_METRONOME, IOC_W, MK_PTR(TYPE_INT)) | |
| 200 | + IOCTL(SNDCTL_TMR_SELECT, IOC_W, MK_PTR(TYPE_INT)) | |
| 201 | + IOCTL(SNDCTL_TMR_SOURCE, IOC_RW, MK_PTR(TYPE_INT)) | |
| 202 | + IOCTL(SNDCTL_TMR_START, 0, TYPE_NULL) | |
| 203 | + IOCTL(SNDCTL_TMR_STOP, 0, TYPE_NULL) | |
| 204 | + IOCTL(SNDCTL_TMR_TEMPO, IOC_RW, MK_PTR(TYPE_INT)) | |
| 205 | + IOCTL(SNDCTL_TMR_TIMEBASE, IOC_RW, MK_PTR(TYPE_INT)) | |
| 206 | + | |
| 207 | + IOCTL(SOUND_PCM_WRITE_FILTER, IOC_W | IOC_R, MK_PTR(TYPE_INT)) | |
| 208 | + IOCTL(SOUND_PCM_READ_RATE, IOC_R, MK_PTR(TYPE_INT)) | |
| 209 | + IOCTL(SOUND_PCM_READ_CHANNELS, IOC_R, MK_PTR(TYPE_INT)) | |
| 210 | + IOCTL(SOUND_PCM_READ_BITS, IOC_R, MK_PTR(TYPE_INT)) | |
| 211 | + IOCTL(SOUND_PCM_READ_FILTER, IOC_R, MK_PTR(TYPE_INT)) | |
| 212 | + IOCTL(SOUND_MIXER_INFO, IOC_R, MK_PTR(TYPE_INT)) | |
| 213 | + IOCTL(SOUND_MIXER_ACCESS, 0, TYPE_PTRVOID) | |
| 214 | + IOCTL(SOUND_MIXER_PRIVATE1, IOC_RW, MK_PTR(TYPE_INT)) | |
| 215 | + IOCTL(SOUND_MIXER_PRIVATE2, IOC_RW, MK_PTR(TYPE_INT)) | |
| 216 | + IOCTL(SOUND_MIXER_PRIVATE3, IOC_RW, MK_PTR(TYPE_INT)) | |
| 217 | + IOCTL(SOUND_MIXER_PRIVATE4, IOC_RW, MK_PTR(TYPE_INT)) | |
| 218 | + IOCTL(SOUND_MIXER_PRIVATE5, IOC_RW, MK_PTR(TYPE_INT)) | |
| 219 | + IOCTL(SOUND_MIXER_READ_VOLUME, IOC_R, MK_PTR(TYPE_INT)) | |
| 220 | + IOCTL(SOUND_MIXER_READ_BASS, IOC_R, MK_PTR(TYPE_INT)) | |
| 221 | + IOCTL(SOUND_MIXER_READ_TREBLE, IOC_R, MK_PTR(TYPE_INT)) | |
| 222 | + IOCTL(SOUND_MIXER_READ_SYNTH, IOC_R, MK_PTR(TYPE_INT)) | |
| 223 | + IOCTL(SOUND_MIXER_READ_PCM, IOC_R, MK_PTR(TYPE_INT)) | |
| 224 | + IOCTL(SOUND_MIXER_READ_SPEAKER, IOC_R, MK_PTR(TYPE_INT)) | |
| 225 | + IOCTL(SOUND_MIXER_READ_LINE, IOC_R, MK_PTR(TYPE_INT)) | |
| 226 | + IOCTL(SOUND_MIXER_READ_MIC, IOC_R, MK_PTR(TYPE_INT)) | |
| 227 | + IOCTL(SOUND_MIXER_READ_CD, IOC_R, MK_PTR(TYPE_INT)) | |
| 228 | + IOCTL(SOUND_MIXER_READ_IMIX, IOC_R, MK_PTR(TYPE_INT)) | |
| 229 | + IOCTL(SOUND_MIXER_READ_ALTPCM, IOC_R, MK_PTR(TYPE_INT)) | |
| 230 | + IOCTL(SOUND_MIXER_READ_RECLEV, IOC_R, MK_PTR(TYPE_INT)) | |
| 231 | + IOCTL(SOUND_MIXER_READ_IGAIN, IOC_R, MK_PTR(TYPE_INT)) | |
| 232 | + IOCTL(SOUND_MIXER_READ_OGAIN, IOC_R, MK_PTR(TYPE_INT)) | |
| 233 | + IOCTL(SOUND_MIXER_READ_LINE1, IOC_R, MK_PTR(TYPE_INT)) | |
| 234 | + IOCTL(SOUND_MIXER_READ_LINE2, IOC_R, MK_PTR(TYPE_INT)) | |
| 235 | + IOCTL(SOUND_MIXER_READ_LINE3, IOC_R, MK_PTR(TYPE_INT)) | |
| 236 | + IOCTL(SOUND_MIXER_READ_MUTE, IOC_R, MK_PTR(TYPE_INT)) | |
| 237 | + IOCTL(SOUND_MIXER_READ_ENHANCE, IOC_R, MK_PTR(TYPE_INT)) | |
| 238 | + IOCTL(SOUND_MIXER_READ_LOUD, IOC_R, MK_PTR(TYPE_INT)) | |
| 239 | + IOCTL(SOUND_MIXER_READ_RECSRC, IOC_R, MK_PTR(TYPE_INT)) | |
| 240 | + IOCTL(SOUND_MIXER_READ_DEVMASK, IOC_R, MK_PTR(TYPE_INT)) | |
| 241 | + IOCTL(SOUND_MIXER_READ_RECMASK, IOC_R, MK_PTR(TYPE_INT)) | |
| 242 | + IOCTL(SOUND_MIXER_READ_STEREODEVS, IOC_R, MK_PTR(TYPE_INT)) | |
| 243 | + IOCTL(SOUND_MIXER_READ_CAPS, IOC_R, MK_PTR(TYPE_INT)) | |
| 244 | + | |
| 245 | + IOCTL(SOUND_MIXER_WRITE_VOLUME, IOC_W, MK_PTR(TYPE_INT)) | |
| 246 | + IOCTL(SOUND_MIXER_WRITE_BASS, IOC_W, MK_PTR(TYPE_INT)) | |
| 247 | + IOCTL(SOUND_MIXER_WRITE_TREBLE, IOC_W, MK_PTR(TYPE_INT)) | |
| 248 | + IOCTL(SOUND_MIXER_WRITE_SYNTH, IOC_W, MK_PTR(TYPE_INT)) | |
| 249 | + IOCTL(SOUND_MIXER_WRITE_PCM, IOC_W, MK_PTR(TYPE_INT)) | |
| 250 | + IOCTL(SOUND_MIXER_WRITE_SPEAKER, IOC_W, MK_PTR(TYPE_INT)) | |
| 251 | + IOCTL(SOUND_MIXER_WRITE_LINE, IOC_W, MK_PTR(TYPE_INT)) | |
| 252 | + IOCTL(SOUND_MIXER_WRITE_MIC, IOC_W, MK_PTR(TYPE_INT)) | |
| 253 | + IOCTL(SOUND_MIXER_WRITE_CD, IOC_W, MK_PTR(TYPE_INT)) | |
| 254 | + IOCTL(SOUND_MIXER_WRITE_IMIX, IOC_W, MK_PTR(TYPE_INT)) | |
| 255 | + IOCTL(SOUND_MIXER_WRITE_ALTPCM, IOC_W, MK_PTR(TYPE_INT)) | |
| 256 | + IOCTL(SOUND_MIXER_WRITE_RECLEV, IOC_W, MK_PTR(TYPE_INT)) | |
| 257 | + IOCTL(SOUND_MIXER_WRITE_IGAIN, IOC_W, MK_PTR(TYPE_INT)) | |
| 258 | + IOCTL(SOUND_MIXER_WRITE_OGAIN, IOC_W, MK_PTR(TYPE_INT)) | |
| 259 | + IOCTL(SOUND_MIXER_WRITE_LINE1, IOC_W, MK_PTR(TYPE_INT)) | |
| 260 | + IOCTL(SOUND_MIXER_WRITE_LINE2, IOC_W, MK_PTR(TYPE_INT)) | |
| 261 | + IOCTL(SOUND_MIXER_WRITE_LINE3, IOC_W, MK_PTR(TYPE_INT)) | |
| 262 | + IOCTL(SOUND_MIXER_WRITE_MUTE, IOC_W, MK_PTR(TYPE_INT)) | |
| 263 | + IOCTL(SOUND_MIXER_WRITE_ENHANCE, IOC_W, MK_PTR(TYPE_INT)) | |
| 264 | + IOCTL(SOUND_MIXER_WRITE_LOUD, IOC_W, MK_PTR(TYPE_INT)) | |
| 265 | + IOCTL(SOUND_MIXER_WRITE_RECSRC, IOC_W, MK_PTR(TYPE_INT)) | |
| 266 | + | |
| 267 | + IOCTL(HDIO_GETGEO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_hd_geometry))) | |
| 268 | + IOCTL(HDIO_GET_UNMASKINTR, IOC_R, MK_PTR(TYPE_INT)) | |
| 269 | + IOCTL(HDIO_GET_MULTCOUNT, IOC_R, MK_PTR(TYPE_INT)) | |
| 270 | + IOCTL(HDIO_GET_IDENTITY, IOC_R, MK_PTR(TYPE_INT)) | |
| 271 | + IOCTL(HDIO_GET_KEEPSETTINGS, IOC_R, MK_PTR(TYPE_INT)) | |
| 272 | + IOCTL(HDIO_GET_NOWERR, IOC_R, MK_PTR(TYPE_INT)) | |
| 273 | + IOCTL(HDIO_GET_DMA, IOC_R, MK_PTR(TYPE_INT)) | |
| 274 | + IOCTL(HDIO_GET_32BIT, IOC_R, MK_PTR(TYPE_INT)) | |
| 275 | + IOCTL(HDIO_DRIVE_CMD, IOC_R, MK_PTR(TYPE_INT)) | |
| 276 | + IOCTL(HDIO_SET_UNMASKINTR, 0, TYPE_INT) | |
| 277 | + IOCTL(HDIO_SET_MULTCOUNT, 0, TYPE_INT) | |
| 278 | + IOCTL(HDIO_SET_KEEPSETTINGS, 0, TYPE_INT) | |
| 279 | + IOCTL(HDIO_SET_NOWERR, 0, TYPE_INT) | |
| 280 | + IOCTL(HDIO_SET_DMA, 0, TYPE_INT) | |
| 281 | + IOCTL(HDIO_SET_32BIT, 0, TYPE_INT) | |
| 282 | + IOCTL(HDIO_SET_PIO_MODE, 0, TYPE_INT) | ... | ... |
linux-user/main.c
0 → 100644
| 1 | +/* | |
| 2 | + * emu main | |
| 3 | + * | |
| 4 | + * Copyright (c) 2003 Fabrice Bellard | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License as published by | |
| 8 | + * the Free Software Foundation; either version 2 of the License, or | |
| 9 | + * (at your option) any later version. | |
| 10 | + * | |
| 11 | + * This program is distributed in the hope that it will be useful, | |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + * GNU General Public License for more details. | |
| 15 | + * | |
| 16 | + * You should have received a copy of the GNU General Public License | |
| 17 | + * along with this program; if not, write to the Free Software | |
| 18 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 19 | + */ | |
| 20 | +#include <stdlib.h> | |
| 21 | +#include <stdio.h> | |
| 22 | +#include <stdarg.h> | |
| 23 | +#include <elf.h> | |
| 24 | +#include <endian.h> | |
| 25 | +#include <errno.h> | |
| 26 | + | |
| 27 | +#include "gemu.h" | |
| 28 | + | |
| 29 | +#include "i386/hsw_interp.h" | |
| 30 | + | |
| 31 | +unsigned long x86_stack_size; | |
| 32 | +unsigned long stktop; | |
| 33 | + | |
| 34 | +void gemu_log(const char *fmt, ...) | |
| 35 | +{ | |
| 36 | + va_list ap; | |
| 37 | + | |
| 38 | + va_start(ap, fmt); | |
| 39 | + vfprintf(stderr, fmt, ap); | |
| 40 | + va_end(ap); | |
| 41 | +} | |
| 42 | + | |
| 43 | +/* virtual x86 CPU stuff */ | |
| 44 | + | |
| 45 | +extern int invoke_code16(Interp_ENV *, int, int); | |
| 46 | +extern int invoke_code32(Interp_ENV *, int); | |
| 47 | +extern char *e_print_cpuemu_regs(ENVPARAMS, int is32); | |
| 48 | +extern char *e_emu_disasm(ENVPARAMS, unsigned char *org, int is32); | |
| 49 | +extern void init_npu(void); | |
| 50 | + | |
| 51 | +Interp_ENV env_global; | |
| 52 | +Interp_ENV *envp_global; | |
| 53 | + | |
| 54 | +QWORD EMUtime = 0; | |
| 55 | + | |
| 56 | +int CEmuStat = 0; | |
| 57 | + | |
| 58 | +long instr_count; | |
| 59 | + | |
| 60 | +/* who will initialize this? */ | |
| 61 | +unsigned long io_bitmap[IO_BITMAP_SIZE+1]; | |
| 62 | + | |
| 63 | +/* debug flag, 0=disable 1..9=level */ | |
| 64 | +int d_emu = 0; | |
| 65 | + | |
| 66 | +unsigned long CRs[5] = | |
| 67 | +{ | |
| 68 | + 0x00000013, /* valid bits: 0xe005003f */ | |
| 69 | + 0x00000000, /* invalid */ | |
| 70 | + 0x00000000, | |
| 71 | + 0x00000000, | |
| 72 | + 0x00000000 | |
| 73 | +}; | |
| 74 | + | |
| 75 | +/* | |
| 76 | + * DR0-3 = linear address of breakpoint 0-3 | |
| 77 | + * DR4=5 = reserved | |
| 78 | + * DR6 b0-b3 = BP active | |
| 79 | + * b13 = BD | |
| 80 | + * b14 = BS | |
| 81 | + * b15 = BT | |
| 82 | + * DR7 b0-b1 = G:L bp#0 | |
| 83 | + * b2-b3 = G:L bp#1 | |
| 84 | + * b4-b5 = G:L bp#2 | |
| 85 | + * b6-b7 = G:L bp#3 | |
| 86 | + * b8-b9 = GE:LE | |
| 87 | + * b13 = GD | |
| 88 | + * b16-19= LLRW bp#0 LL=00(1),01(2),11(4) | |
| 89 | + * b20-23= LLRW bp#1 RW=00(x),01(w),11(rw) | |
| 90 | + * b24-27= LLRW bp#2 | |
| 91 | + * b28-31= LLRW bp#3 | |
| 92 | + */ | |
| 93 | +unsigned long DRs[8] = | |
| 94 | +{ | |
| 95 | + 0x00000000, | |
| 96 | + 0x00000000, | |
| 97 | + 0x00000000, | |
| 98 | + 0x00000000, | |
| 99 | + 0xffff1ff0, | |
| 100 | + 0x00000400, | |
| 101 | + 0xffff1ff0, | |
| 102 | + 0x00000400 | |
| 103 | +}; | |
| 104 | + | |
| 105 | +unsigned long TRs[2] = | |
| 106 | +{ | |
| 107 | + 0x00000000, | |
| 108 | + 0x00000000 | |
| 109 | +}; | |
| 110 | + | |
| 111 | +void FatalAppExit(UINT wAction, LPCSTR lpText) | |
| 112 | +{ | |
| 113 | + fprintf(stderr, "Fatal error '%s' in CPU\n", lpText); | |
| 114 | + exit(1); | |
| 115 | +} | |
| 116 | + | |
| 117 | +int e_debug_check(unsigned char *PC) | |
| 118 | +{ | |
| 119 | + register unsigned long d7 = DRs[7]; | |
| 120 | + | |
| 121 | + if (d7&0x03) { | |
| 122 | + if (d7&0x30000) return 0; /* only execute(00) bkp */ | |
| 123 | + if ((long)PC==DRs[0]) { | |
| 124 | + e_printf("DBRK: DR0 hit at %p\n",PC); | |
| 125 | + DRs[6] |= 1; | |
| 126 | + return 1; | |
| 127 | + } | |
| 128 | + } | |
| 129 | + if (d7&0x0c) { | |
| 130 | + if (d7&0x300000) return 0; | |
| 131 | + if ((long)PC==DRs[1]) { | |
| 132 | + e_printf("DBRK: DR1 hit at %p\n",PC); | |
| 133 | + DRs[6] |= 2; | |
| 134 | + return 1; | |
| 135 | + } | |
| 136 | + } | |
| 137 | + if (d7&0x30) { | |
| 138 | + if (d7&0x3000000) return 0; | |
| 139 | + if ((long)PC==DRs[2]) { | |
| 140 | + e_printf("DBRK: DR2 hit at %p\n",PC); | |
| 141 | + DRs[6] |= 4; | |
| 142 | + return 1; | |
| 143 | + } | |
| 144 | + } | |
| 145 | + if (d7&0xc0) { | |
| 146 | + if (d7&0x30000000) return 0; | |
| 147 | + if ((long)PC==DRs[3]) { | |
| 148 | + e_printf("DBRK: DR3 hit at %p\n",PC); | |
| 149 | + DRs[6] |= 8; | |
| 150 | + return 1; | |
| 151 | + } | |
| 152 | + } | |
| 153 | + return 0; | |
| 154 | +} | |
| 155 | + | |
| 156 | +/* Debug stuff */ | |
| 157 | +void logstr(unsigned long mask, const char *fmt,...) | |
| 158 | +{ | |
| 159 | + va_list ap; | |
| 160 | + | |
| 161 | + va_start(ap, fmt); | |
| 162 | + vfprintf(stderr, fmt, ap); | |
| 163 | + va_end(ap); | |
| 164 | +} | |
| 165 | + | |
| 166 | +/* unconditional message into debug log and stderr */ | |
| 167 | +#undef error | |
| 168 | +void error(const char *fmt, ...) | |
| 169 | +{ | |
| 170 | + va_list ap; | |
| 171 | + | |
| 172 | + va_start(ap, fmt); | |
| 173 | + vfprintf(stderr, fmt, ap); | |
| 174 | + va_end(ap); | |
| 175 | + exit(1); | |
| 176 | +} | |
| 177 | + | |
| 178 | +int PortIO(DWORD port, DWORD value, UINT size, BOOL is_write) | |
| 179 | +{ | |
| 180 | + fprintf(stderr, "IO: %s port=0x%lx value=0x%lx size=%d", | |
| 181 | + is_write ? "write" : "read", port, value, size); | |
| 182 | + return value; | |
| 183 | +} | |
| 184 | + | |
| 185 | +void LogProcName(WORD wSel, WORD wOff, WORD wAction) | |
| 186 | +{ | |
| 187 | + | |
| 188 | +} | |
| 189 | + | |
| 190 | +void INT_handler(int num, void *env) | |
| 191 | +{ | |
| 192 | + fprintf(stderr, "EM86: int %d\n", num); | |
| 193 | +} | |
| 194 | + | |
| 195 | +/***********************************************************/ | |
| 196 | + | |
| 197 | +/* XXX: currently we use LDT entries */ | |
| 198 | +#define __USER_CS (0x23|4) | |
| 199 | +#define __USER_DS (0x2B|4) | |
| 200 | + | |
| 201 | +void usage(void) | |
| 202 | +{ | |
| 203 | + printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n" | |
| 204 | + "usage: gemu program [arguments...]\n" | |
| 205 | + "Linux x86 emulator\n" | |
| 206 | + ); | |
| 207 | + exit(1); | |
| 208 | +} | |
| 209 | + | |
| 210 | +int main(int argc, char **argv) | |
| 211 | +{ | |
| 212 | + const char *filename; | |
| 213 | + struct pt_regs regs1, *regs = ®s1; | |
| 214 | + struct image_info info1, *info = &info1; | |
| 215 | + Interp_ENV *env; | |
| 216 | + | |
| 217 | + if (argc <= 1) | |
| 218 | + usage(); | |
| 219 | + | |
| 220 | + filename = argv[1]; | |
| 221 | + | |
| 222 | + /* Zero out regs */ | |
| 223 | + memset(regs, 0, sizeof(struct pt_regs)); | |
| 224 | + | |
| 225 | + /* Zero out image_info */ | |
| 226 | + memset(info, 0, sizeof(struct image_info)); | |
| 227 | + | |
| 228 | + if(elf_exec(filename, argv+1, __environ, regs, info) != 0) { | |
| 229 | + printf("Error loading %s\n", filename); | |
| 230 | + exit(1); | |
| 231 | + } | |
| 232 | + | |
| 233 | +#if 0 | |
| 234 | + printf("start_brk 0x%08lx\n" , info->start_brk); | |
| 235 | + printf("end_code 0x%08lx\n" , info->end_code); | |
| 236 | + printf("start_code 0x%08lx\n" , info->start_code); | |
| 237 | + printf("end_data 0x%08lx\n" , info->end_data); | |
| 238 | + printf("start_stack 0x%08lx\n" , info->start_stack); | |
| 239 | + printf("brk 0x%08lx\n" , info->brk); | |
| 240 | + printf("esp 0x%08lx\n" , regs->esp); | |
| 241 | + printf("eip 0x%08lx\n" , regs->eip); | |
| 242 | +#endif | |
| 243 | + | |
| 244 | + target_set_brk((char *)info->brk); | |
| 245 | + syscall_init(); | |
| 246 | + | |
| 247 | + env = &env_global; | |
| 248 | + envp_global = env; | |
| 249 | + memset(env, 0, sizeof(Interp_ENV)); | |
| 250 | + | |
| 251 | + env->rax.e = regs->eax; | |
| 252 | + env->rbx.e = regs->ebx; | |
| 253 | + env->rcx.e = regs->ecx; | |
| 254 | + env->rdx.e = regs->edx; | |
| 255 | + env->rsi.esi = regs->esi; | |
| 256 | + env->rdi.edi = regs->edi; | |
| 257 | + env->rbp.ebp = regs->ebp; | |
| 258 | + env->rsp.esp = regs->esp; | |
| 259 | + env->cs.cs = __USER_CS; | |
| 260 | + env->ds.ds = __USER_DS; | |
| 261 | + env->es.es = __USER_DS; | |
| 262 | + env->ss.ss = __USER_DS; | |
| 263 | + env->fs.fs = __USER_DS; | |
| 264 | + env->gs.gs = __USER_DS; | |
| 265 | + env->trans_addr = regs->eip; | |
| 266 | + | |
| 267 | + LDT[__USER_CS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32; | |
| 268 | + LDT[__USER_CS >> 3].dwSelLimit = 0xfffff; | |
| 269 | + LDT[__USER_CS >> 3].lpSelBase = NULL; | |
| 270 | + | |
| 271 | + LDT[__USER_DS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32; | |
| 272 | + LDT[__USER_DS >> 3].dwSelLimit = 0xfffff; | |
| 273 | + LDT[__USER_DS >> 3].lpSelBase = NULL; | |
| 274 | + init_npu(); | |
| 275 | + | |
| 276 | + for(;;) { | |
| 277 | + int err; | |
| 278 | + uint8_t *pc; | |
| 279 | + | |
| 280 | + err = invoke_code32(env, -1); | |
| 281 | + env->trans_addr = env->return_addr; | |
| 282 | + pc = env->seg_regs[0] + env->trans_addr; | |
| 283 | + switch(err) { | |
| 284 | + case EXCP0D_GPF: | |
| 285 | + if (pc[0] == 0xcd && pc[1] == 0x80) { | |
| 286 | + /* syscall */ | |
| 287 | + env->trans_addr += 2; | |
| 288 | + env->rax.e = do_syscall(env->rax.e, | |
| 289 | + env->rbx.e, | |
| 290 | + env->rcx.e, | |
| 291 | + env->rdx.e, | |
| 292 | + env->rsi.esi, | |
| 293 | + env->rdi.edi, | |
| 294 | + env->rbp.ebp); | |
| 295 | + } else { | |
| 296 | + goto trap_error; | |
| 297 | + } | |
| 298 | + break; | |
| 299 | + default: | |
| 300 | + trap_error: | |
| 301 | + fprintf(stderr, "GEMU: Unknown error %d, aborting\n", err); | |
| 302 | + d_emu = 9; | |
| 303 | + fprintf(stderr, "%s\n%s\n", | |
| 304 | + e_print_cpuemu_regs(env, 1), | |
| 305 | + e_emu_disasm(env,pc,1)); | |
| 306 | + abort(); | |
| 307 | + } | |
| 308 | + } | |
| 309 | + return 0; | |
| 310 | +} | ... | ... |
linux-user/qemu.h
0 → 100644
| 1 | +#ifndef GEMU_H | |
| 2 | +#define GEMU_H | |
| 3 | + | |
| 4 | +#include "thunk.h" | |
| 5 | + | |
| 6 | +struct pt_regs { | |
| 7 | + long ebx; | |
| 8 | + long ecx; | |
| 9 | + long edx; | |
| 10 | + long esi; | |
| 11 | + long edi; | |
| 12 | + long ebp; | |
| 13 | + long eax; | |
| 14 | + int xds; | |
| 15 | + int xes; | |
| 16 | + long orig_eax; | |
| 17 | + long eip; | |
| 18 | + int xcs; | |
| 19 | + long eflags; | |
| 20 | + long esp; | |
| 21 | + int xss; | |
| 22 | +}; | |
| 23 | + | |
| 24 | +/* This struct is used to hold certain information about the image. | |
| 25 | + * Basically, it replicates in user space what would be certain | |
| 26 | + * task_struct fields in the kernel | |
| 27 | + */ | |
| 28 | +struct image_info { | |
| 29 | + unsigned long start_code; | |
| 30 | + unsigned long end_code; | |
| 31 | + unsigned long end_data; | |
| 32 | + unsigned long start_brk; | |
| 33 | + unsigned long brk; | |
| 34 | + unsigned long start_mmap; | |
| 35 | + unsigned long mmap; | |
| 36 | + unsigned long rss; | |
| 37 | + unsigned long start_stack; | |
| 38 | + unsigned long arg_start; | |
| 39 | + unsigned long arg_end; | |
| 40 | + unsigned long env_start; | |
| 41 | + unsigned long env_end; | |
| 42 | + unsigned long entry; | |
| 43 | + int personality; | |
| 44 | +}; | |
| 45 | + | |
| 46 | +int elf_exec(const char * filename, char ** argv, char ** envp, | |
| 47 | + struct pt_regs * regs, struct image_info *infop); | |
| 48 | + | |
| 49 | +void target_set_brk(char *new_brk); | |
| 50 | +void syscall_init(void); | |
| 51 | +long do_syscall(int num, long arg1, long arg2, long arg3, | |
| 52 | + long arg4, long arg5, long arg6); | |
| 53 | +void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2))); | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | +#endif | ... | ... |
linux-user/signal.c
0 → 100644
| 1 | +/* | |
| 2 | + * Emulation of Linux signal handling | |
| 3 | + * | |
| 4 | + * Copyright (c) 2003 Fabrice Bellard | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License as published by | |
| 8 | + * the Free Software Foundation; either version 2 of the License, or | |
| 9 | + * (at your option) any later version. | |
| 10 | + * | |
| 11 | + * This program is distributed in the hope that it will be useful, | |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + * GNU General Public License for more details. | |
| 15 | + * | |
| 16 | + * You should have received a copy of the GNU General Public License | |
| 17 | + * along with this program; if not, write to the Free Software | |
| 18 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 19 | + */ | |
| 20 | +#include <stdlib.h> | |
| 21 | +#include <stdio.h> | |
| 22 | +#include <stdarg.h> | |
| 23 | +#include <signal.h> | |
| 24 | +#include <sys/ucontext.h> | |
| 25 | + | |
| 26 | +/* Algorithm strongly inspired from em86 : we queue the signals so | |
| 27 | + that we can handle them at precise points in the emulated code. */ | |
| 28 | + | |
| 29 | +struct emulated_sigaction { | |
| 30 | + struct target_sigaction sa; | |
| 31 | + int nb_pending; | |
| 32 | + struct target_siginfo info; | |
| 33 | +}; | |
| 34 | + | |
| 35 | +struct emulated_sigaction sigact_table[NSIG]; | |
| 36 | +int signal_pending; | |
| 37 | + | |
| 38 | +static inline int host_to_target_signal(int sig) | |
| 39 | +{ | |
| 40 | + return sig; | |
| 41 | +} | |
| 42 | + | |
| 43 | +static inline int target_to_host_signal(int sig) | |
| 44 | +{ | |
| 45 | + return sig; | |
| 46 | +} | |
| 47 | + | |
| 48 | +void signal_init(void) | |
| 49 | +{ | |
| 50 | + struct sigaction act; | |
| 51 | + int i; | |
| 52 | + | |
| 53 | + /* set all host signal handlers */ | |
| 54 | + sigemptyset(&act.sa_mask); | |
| 55 | + act.sa_flags = SA_SIGINFO; | |
| 56 | + act.sa_sigaction = host_signal_handler; | |
| 57 | + for(i = 1; i < NSIG; i++) { | |
| 58 | + sigaction(i, &sa, NULL); | |
| 59 | + } | |
| 60 | + | |
| 61 | + memset(sigact_table, 0, sizeof(sigact_table)); | |
| 62 | +} | |
| 63 | + | |
| 64 | +static void host_signal_handler(int host_signum, siginfo_t *info, | |
| 65 | + void *puc) | |
| 66 | +{ | |
| 67 | + struct ucontext *uc = puc; | |
| 68 | + int signum; | |
| 69 | + /* get target signal number */ | |
| 70 | + signum = host_to_target(host_signum); | |
| 71 | + if (signum >= TARGET_NSIG) | |
| 72 | + return; | |
| 73 | + /* we save the old mask */ | |
| 74 | + | |
| 75 | + | |
| 76 | +} | |
| 77 | + | |
| 78 | + | |
| 79 | +void process_pending_signals(void) | |
| 80 | +{ | |
| 81 | + int signum; | |
| 82 | + target_ulong _sa_handler; | |
| 83 | + | |
| 84 | + struct emulated_sigaction *esig; | |
| 85 | + | |
| 86 | + if (!signal_pending) | |
| 87 | + return; | |
| 88 | + | |
| 89 | + esig = sigact_table; | |
| 90 | + for(signum = 1; signum < TARGET_NSIG; signum++) { | |
| 91 | + if (esig->nb_pending != 0) | |
| 92 | + goto handle_signal; | |
| 93 | + esig++; | |
| 94 | + } | |
| 95 | + /* if no signal is pending, just return */ | |
| 96 | + signal_pending = 0; | |
| 97 | + return; | |
| 98 | + handle_signal: | |
| 99 | + _sa_handler = esig->sa._sa_handler; | |
| 100 | + if (_sa_handler == TARGET_SIG_DFL) { | |
| 101 | + /* default handling | |
| 102 | + } | |
| 103 | + | |
| 104 | + | |
| 105 | +} | ... | ... |
linux-user/syscall.c
0 → 100644
| 1 | +/* | |
| 2 | + * Linux syscalls | |
| 3 | + * | |
| 4 | + * Copyright (c) 2003 Fabrice Bellard | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License as published by | |
| 8 | + * the Free Software Foundation; either version 2 of the License, or | |
| 9 | + * (at your option) any later version. | |
| 10 | + * | |
| 11 | + * This program is distributed in the hope that it will be useful, | |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + * GNU General Public License for more details. | |
| 15 | + * | |
| 16 | + * You should have received a copy of the GNU General Public License | |
| 17 | + * along with this program; if not, write to the Free Software | |
| 18 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 19 | + */ | |
| 20 | +#include <stdlib.h> | |
| 21 | +#include <stdio.h> | |
| 22 | +#include <stdarg.h> | |
| 23 | +#include <elf.h> | |
| 24 | +#include <endian.h> | |
| 25 | +#include <errno.h> | |
| 26 | +#include <unistd.h> | |
| 27 | +#include <fcntl.h> | |
| 28 | +#include <sys/types.h> | |
| 29 | +#include <sys/wait.h> | |
| 30 | +#include <sys/time.h> | |
| 31 | +#include <sys/stat.h> | |
| 32 | +#include <sys/mount.h> | |
| 33 | +#include <sys/resource.h> | |
| 34 | +#include <sys/mman.h> | |
| 35 | +#include <sys/swap.h> | |
| 36 | +#include <signal.h> | |
| 37 | +#include <sched.h> | |
| 38 | +#include <sys/socket.h> | |
| 39 | +#include <sys/uio.h> | |
| 40 | +#include <sys/user.h> | |
| 41 | + | |
| 42 | +#define termios host_termios | |
| 43 | +#define winsize host_winsize | |
| 44 | +#define termio host_termio | |
| 45 | + | |
| 46 | +#include <linux/termios.h> | |
| 47 | +#include <linux/unistd.h> | |
| 48 | +#include <linux/utsname.h> | |
| 49 | +#include <linux/cdrom.h> | |
| 50 | +#include <linux/hdreg.h> | |
| 51 | +#include <linux/soundcard.h> | |
| 52 | + | |
| 53 | +#include "gemu.h" | |
| 54 | + | |
| 55 | +#define DEBUG | |
| 56 | + | |
| 57 | +#ifndef PAGE_SIZE | |
| 58 | +#define PAGE_SIZE 4096 | |
| 59 | +#define PAGE_MASK ~(PAGE_SIZE - 1) | |
| 60 | +#endif | |
| 61 | + | |
| 62 | +struct dirent { | |
| 63 | + long d_ino; | |
| 64 | + long d_off; | |
| 65 | + unsigned short d_reclen; | |
| 66 | + char d_name[256]; /* We must not include limits.h! */ | |
| 67 | +}; | |
| 68 | + | |
| 69 | +#include "syscall_defs.h" | |
| 70 | + | |
| 71 | +#ifdef TARGET_I386 | |
| 72 | +#include "syscall-i386.h" | |
| 73 | +#endif | |
| 74 | + | |
| 75 | +#define __NR_sys_uname __NR_uname | |
| 76 | +#define __NR_sys_getcwd __NR_getcwd | |
| 77 | +#define __NR_sys_statfs __NR_statfs | |
| 78 | +#define __NR_sys_fstatfs __NR_fstatfs | |
| 79 | + | |
| 80 | +_syscall0(int, gettid) | |
| 81 | +_syscall1(int,sys_uname,struct new_utsname *,buf) | |
| 82 | +_syscall2(int,sys_getcwd,char *,buf,size_t,size) | |
| 83 | +_syscall3(int, getdents, uint, fd, struct dirent *, dirp, uint, count); | |
| 84 | +_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, | |
| 85 | + loff_t *, res, uint, wh); | |
| 86 | +_syscall2(int,sys_statfs,const char *,path,struct statfs *,buf) | |
| 87 | +_syscall2(int,sys_fstatfs,int,fd,struct statfs *,buf) | |
| 88 | + | |
| 89 | +static inline long get_errno(long ret) | |
| 90 | +{ | |
| 91 | + if (ret == -1) | |
| 92 | + return -errno; | |
| 93 | + else | |
| 94 | + return ret; | |
| 95 | +} | |
| 96 | + | |
| 97 | +static inline int is_error(long ret) | |
| 98 | +{ | |
| 99 | + return (unsigned long)ret >= (unsigned long)(-4096); | |
| 100 | +} | |
| 101 | + | |
| 102 | +static char *target_brk; | |
| 103 | +static char *target_original_brk; | |
| 104 | + | |
| 105 | +void target_set_brk(char *new_brk) | |
| 106 | +{ | |
| 107 | + target_brk = new_brk; | |
| 108 | + target_original_brk = new_brk; | |
| 109 | +} | |
| 110 | + | |
| 111 | +static long do_brk(char *new_brk) | |
| 112 | +{ | |
| 113 | + char *brk_page; | |
| 114 | + long mapped_addr; | |
| 115 | + int new_alloc_size; | |
| 116 | + | |
| 117 | + if (!new_brk) | |
| 118 | + return (long)target_brk; | |
| 119 | + if (new_brk < target_original_brk) | |
| 120 | + return -ENOMEM; | |
| 121 | + | |
| 122 | + brk_page = (char *)(((unsigned long)target_brk + PAGE_SIZE - 1) & PAGE_MASK); | |
| 123 | + | |
| 124 | + /* If the new brk is less than this, set it and we're done... */ | |
| 125 | + if (new_brk < brk_page) { | |
| 126 | + target_brk = new_brk; | |
| 127 | + return (long)target_brk; | |
| 128 | + } | |
| 129 | + | |
| 130 | + /* We need to allocate more memory after the brk... */ | |
| 131 | + new_alloc_size = ((new_brk - brk_page + 1)+(PAGE_SIZE-1)) & PAGE_MASK; | |
| 132 | + mapped_addr = get_errno((long)mmap((caddr_t)brk_page, new_alloc_size, | |
| 133 | + PROT_READ|PROT_WRITE, | |
| 134 | + MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); | |
| 135 | + | |
| 136 | + if (is_error(mapped_addr)) { | |
| 137 | + return mapped_addr; | |
| 138 | + } else { | |
| 139 | + target_brk = new_brk; | |
| 140 | + return (long)target_brk; | |
| 141 | + } | |
| 142 | +} | |
| 143 | + | |
| 144 | +static inline fd_set *target_to_host_fds(fd_set *fds, | |
| 145 | + target_long *target_fds, int n) | |
| 146 | +{ | |
| 147 | +#if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN) | |
| 148 | + return (fd_set *)target_fds; | |
| 149 | +#else | |
| 150 | + int i, b; | |
| 151 | + if (target_fds) { | |
| 152 | + FD_ZERO(fds); | |
| 153 | + for(i = 0;i < n; i++) { | |
| 154 | + b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >> | |
| 155 | + (i & (TARGET_LONG_BITS - 1))) & 1; | |
| 156 | + if (b) | |
| 157 | + FD_SET(i, fds); | |
| 158 | + } | |
| 159 | + return fds; | |
| 160 | + } else { | |
| 161 | + return NULL; | |
| 162 | + } | |
| 163 | +#endif | |
| 164 | +} | |
| 165 | + | |
| 166 | +static inline void host_to_target_fds(target_long *target_fds, | |
| 167 | + fd_set *fds, int n) | |
| 168 | +{ | |
| 169 | +#if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN) | |
| 170 | + /* nothing to do */ | |
| 171 | +#else | |
| 172 | + int i, nw, j, k; | |
| 173 | + target_long v; | |
| 174 | + | |
| 175 | + if (target_fds) { | |
| 176 | + nw = n / TARGET_LONG_BITS; | |
| 177 | + k = 0; | |
| 178 | + for(i = 0;i < nw; i++) { | |
| 179 | + v = 0; | |
| 180 | + for(j = 0; j < TARGET_LONG_BITS; j++) { | |
| 181 | + v |= ((FD_ISSET(k, fds) != 0) << j); | |
| 182 | + k++; | |
| 183 | + } | |
| 184 | + target_fds[i] = tswapl(v); | |
| 185 | + } | |
| 186 | + } | |
| 187 | +#endif | |
| 188 | +} | |
| 189 | + | |
| 190 | +/* XXX: incorrect for some archs */ | |
| 191 | +static void host_to_target_old_sigset(target_ulong *old_sigset, | |
| 192 | + const sigset_t *sigset) | |
| 193 | +{ | |
| 194 | + *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff); | |
| 195 | +} | |
| 196 | + | |
| 197 | +static void target_to_host_old_sigset(sigset_t *sigset, | |
| 198 | + const target_ulong *old_sigset) | |
| 199 | +{ | |
| 200 | + sigemptyset(sigset); | |
| 201 | + *(unsigned long *)sigset = tswapl(*old_sigset); | |
| 202 | +} | |
| 203 | + | |
| 204 | + | |
| 205 | +static long do_select(long n, | |
| 206 | + target_long *target_rfds, target_long *target_wfds, | |
| 207 | + target_long *target_efds, struct target_timeval *target_tv) | |
| 208 | +{ | |
| 209 | + fd_set rfds, wfds, efds; | |
| 210 | + fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; | |
| 211 | + struct timeval tv, *tv_ptr; | |
| 212 | + long ret; | |
| 213 | + | |
| 214 | + rfds_ptr = target_to_host_fds(&rfds, target_rfds, n); | |
| 215 | + wfds_ptr = target_to_host_fds(&wfds, target_wfds, n); | |
| 216 | + efds_ptr = target_to_host_fds(&efds, target_efds, n); | |
| 217 | + | |
| 218 | + if (target_tv) { | |
| 219 | + tv.tv_sec = tswapl(target_tv->tv_sec); | |
| 220 | + tv.tv_usec = tswapl(target_tv->tv_usec); | |
| 221 | + tv_ptr = &tv; | |
| 222 | + } else { | |
| 223 | + tv_ptr = NULL; | |
| 224 | + } | |
| 225 | + ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr)); | |
| 226 | + if (!is_error(ret)) { | |
| 227 | + host_to_target_fds(target_rfds, rfds_ptr, n); | |
| 228 | + host_to_target_fds(target_wfds, wfds_ptr, n); | |
| 229 | + host_to_target_fds(target_efds, efds_ptr, n); | |
| 230 | + | |
| 231 | + if (target_tv) { | |
| 232 | + target_tv->tv_sec = tswapl(tv.tv_sec); | |
| 233 | + target_tv->tv_usec = tswapl(tv.tv_usec); | |
| 234 | + } | |
| 235 | + } | |
| 236 | + return ret; | |
| 237 | +} | |
| 238 | + | |
| 239 | +static long do_socketcall(int num, long *vptr) | |
| 240 | +{ | |
| 241 | + long ret; | |
| 242 | + | |
| 243 | + switch(num) { | |
| 244 | + case SOCKOP_socket: | |
| 245 | + ret = get_errno(socket(vptr[0], vptr[1], vptr[2])); | |
| 246 | + break; | |
| 247 | + case SOCKOP_bind: | |
| 248 | + ret = get_errno(bind(vptr[0], (struct sockaddr *)vptr[1], vptr[2])); | |
| 249 | + break; | |
| 250 | + case SOCKOP_connect: | |
| 251 | + ret = get_errno(connect(vptr[0], (struct sockaddr *)vptr[1], vptr[2])); | |
| 252 | + break; | |
| 253 | + case SOCKOP_listen: | |
| 254 | + ret = get_errno(listen(vptr[0], vptr[1])); | |
| 255 | + break; | |
| 256 | + case SOCKOP_accept: | |
| 257 | + { | |
| 258 | + socklen_t size; | |
| 259 | + size = tswap32(*(int32_t *)vptr[2]); | |
| 260 | + ret = get_errno(accept(vptr[0], (struct sockaddr *)vptr[1], &size)); | |
| 261 | + if (!is_error(ret)) | |
| 262 | + *(int32_t *)vptr[2] = size; | |
| 263 | + } | |
| 264 | + break; | |
| 265 | + case SOCKOP_getsockname: | |
| 266 | + { | |
| 267 | + socklen_t size; | |
| 268 | + size = tswap32(*(int32_t *)vptr[2]); | |
| 269 | + ret = get_errno(getsockname(vptr[0], (struct sockaddr *)vptr[1], &size)); | |
| 270 | + if (!is_error(ret)) | |
| 271 | + *(int32_t *)vptr[2] = size; | |
| 272 | + } | |
| 273 | + break; | |
| 274 | + case SOCKOP_getpeername: | |
| 275 | + { | |
| 276 | + socklen_t size; | |
| 277 | + size = tswap32(*(int32_t *)vptr[2]); | |
| 278 | + ret = get_errno(getpeername(vptr[0], (struct sockaddr *)vptr[1], &size)); | |
| 279 | + if (!is_error(ret)) | |
| 280 | + *(int32_t *)vptr[2] = size; | |
| 281 | + } | |
| 282 | + break; | |
| 283 | + case SOCKOP_socketpair: | |
| 284 | + { | |
| 285 | + int tab[2]; | |
| 286 | + int32_t *target_tab = (int32_t *)vptr[3]; | |
| 287 | + ret = get_errno(socketpair(vptr[0], vptr[1], vptr[2], tab)); | |
| 288 | + if (!is_error(ret)) { | |
| 289 | + target_tab[0] = tswap32(tab[0]); | |
| 290 | + target_tab[1] = tswap32(tab[1]); | |
| 291 | + } | |
| 292 | + } | |
| 293 | + break; | |
| 294 | + case SOCKOP_send: | |
| 295 | + ret = get_errno(send(vptr[0], (void *)vptr[1], vptr[2], vptr[3])); | |
| 296 | + break; | |
| 297 | + case SOCKOP_recv: | |
| 298 | + ret = get_errno(recv(vptr[0], (void *)vptr[1], vptr[2], vptr[3])); | |
| 299 | + break; | |
| 300 | + case SOCKOP_sendto: | |
| 301 | + ret = get_errno(sendto(vptr[0], (void *)vptr[1], vptr[2], vptr[3], | |
| 302 | + (struct sockaddr *)vptr[4], vptr[5])); | |
| 303 | + break; | |
| 304 | + case SOCKOP_recvfrom: | |
| 305 | + { | |
| 306 | + socklen_t size; | |
| 307 | + size = tswap32(*(int32_t *)vptr[5]); | |
| 308 | + ret = get_errno(recvfrom(vptr[0], (void *)vptr[1], vptr[2], | |
| 309 | + vptr[3], (struct sockaddr *)vptr[4], &size)); | |
| 310 | + if (!is_error(ret)) | |
| 311 | + *(int32_t *)vptr[5] = size; | |
| 312 | + } | |
| 313 | + break; | |
| 314 | + case SOCKOP_shutdown: | |
| 315 | + ret = get_errno(shutdown(vptr[0], vptr[1])); | |
| 316 | + break; | |
| 317 | + case SOCKOP_sendmsg: | |
| 318 | + case SOCKOP_recvmsg: | |
| 319 | + case SOCKOP_setsockopt: | |
| 320 | + case SOCKOP_getsockopt: | |
| 321 | + default: | |
| 322 | + gemu_log("Unsupported socketcall: %d\n", num); | |
| 323 | + ret = -ENOSYS; | |
| 324 | + break; | |
| 325 | + } | |
| 326 | + return ret; | |
| 327 | +} | |
| 328 | + | |
| 329 | +/* kernel structure types definitions */ | |
| 330 | +#define IFNAMSIZ 16 | |
| 331 | + | |
| 332 | +#define STRUCT(name, list...) STRUCT_ ## name, | |
| 333 | +#define STRUCT_SPECIAL(name) STRUCT_ ## name, | |
| 334 | +enum { | |
| 335 | +#include "syscall_types.h" | |
| 336 | +}; | |
| 337 | +#undef STRUCT | |
| 338 | +#undef STRUCT_SPECIAL | |
| 339 | + | |
| 340 | +#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL }; | |
| 341 | +#define STRUCT_SPECIAL(name) | |
| 342 | +#include "syscall_types.h" | |
| 343 | +#undef STRUCT | |
| 344 | +#undef STRUCT_SPECIAL | |
| 345 | + | |
| 346 | +typedef struct IOCTLEntry { | |
| 347 | + int target_cmd; | |
| 348 | + int host_cmd; | |
| 349 | + const char *name; | |
| 350 | + int access; | |
| 351 | + const argtype arg_type[3]; | |
| 352 | +} IOCTLEntry; | |
| 353 | + | |
| 354 | +#define IOC_R 0x0001 | |
| 355 | +#define IOC_W 0x0002 | |
| 356 | +#define IOC_RW (IOC_R | IOC_W) | |
| 357 | + | |
| 358 | +#define MAX_STRUCT_SIZE 4096 | |
| 359 | + | |
| 360 | +const IOCTLEntry ioctl_entries[] = { | |
| 361 | +#define IOCTL(cmd, access, types...) \ | |
| 362 | + { TARGET_ ## cmd, cmd, #cmd, access, { types } }, | |
| 363 | +#include "ioctls.h" | |
| 364 | + { 0, 0, }, | |
| 365 | +}; | |
| 366 | + | |
| 367 | +static long do_ioctl(long fd, long cmd, long arg) | |
| 368 | +{ | |
| 369 | + const IOCTLEntry *ie; | |
| 370 | + const argtype *arg_type; | |
| 371 | + long ret; | |
| 372 | + uint8_t buf_temp[MAX_STRUCT_SIZE]; | |
| 373 | + | |
| 374 | + ie = ioctl_entries; | |
| 375 | + for(;;) { | |
| 376 | + if (ie->target_cmd == 0) { | |
| 377 | + gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd); | |
| 378 | + return -ENOSYS; | |
| 379 | + } | |
| 380 | + if (ie->target_cmd == cmd) | |
| 381 | + break; | |
| 382 | + ie++; | |
| 383 | + } | |
| 384 | + arg_type = ie->arg_type; | |
| 385 | + // gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name); | |
| 386 | + switch(arg_type[0]) { | |
| 387 | + case TYPE_NULL: | |
| 388 | + /* no argument */ | |
| 389 | + ret = get_errno(ioctl(fd, ie->host_cmd)); | |
| 390 | + break; | |
| 391 | + case TYPE_PTRVOID: | |
| 392 | + case TYPE_INT: | |
| 393 | + /* int argment */ | |
| 394 | + ret = get_errno(ioctl(fd, ie->host_cmd, arg)); | |
| 395 | + break; | |
| 396 | + case TYPE_PTR: | |
| 397 | + arg_type++; | |
| 398 | + switch(ie->access) { | |
| 399 | + case IOC_R: | |
| 400 | + ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); | |
| 401 | + if (!is_error(ret)) { | |
| 402 | + thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET); | |
| 403 | + } | |
| 404 | + break; | |
| 405 | + case IOC_W: | |
| 406 | + thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST); | |
| 407 | + ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); | |
| 408 | + break; | |
| 409 | + default: | |
| 410 | + case IOC_RW: | |
| 411 | + thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST); | |
| 412 | + ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); | |
| 413 | + if (!is_error(ret)) { | |
| 414 | + thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET); | |
| 415 | + } | |
| 416 | + break; | |
| 417 | + } | |
| 418 | + break; | |
| 419 | + default: | |
| 420 | + gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]); | |
| 421 | + ret = -ENOSYS; | |
| 422 | + break; | |
| 423 | + } | |
| 424 | + return ret; | |
| 425 | +} | |
| 426 | + | |
| 427 | +bitmask_transtbl iflag_tbl[] = { | |
| 428 | + { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK }, | |
| 429 | + { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT }, | |
| 430 | + { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR }, | |
| 431 | + { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK }, | |
| 432 | + { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK }, | |
| 433 | + { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP }, | |
| 434 | + { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR }, | |
| 435 | + { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR }, | |
| 436 | + { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL }, | |
| 437 | + { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC }, | |
| 438 | + { TARGET_IXON, TARGET_IXON, IXON, IXON }, | |
| 439 | + { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY }, | |
| 440 | + { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF }, | |
| 441 | + { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL }, | |
| 442 | + { 0, 0, 0, 0 } | |
| 443 | +}; | |
| 444 | + | |
| 445 | +bitmask_transtbl oflag_tbl[] = { | |
| 446 | + { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST }, | |
| 447 | + { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC }, | |
| 448 | + { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR }, | |
| 449 | + { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL }, | |
| 450 | + { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR }, | |
| 451 | + { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET }, | |
| 452 | + { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL }, | |
| 453 | + { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL }, | |
| 454 | + { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 }, | |
| 455 | + { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 }, | |
| 456 | + { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 }, | |
| 457 | + { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 }, | |
| 458 | + { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 }, | |
| 459 | + { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 }, | |
| 460 | + { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 }, | |
| 461 | + { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 }, | |
| 462 | + { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 }, | |
| 463 | + { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 }, | |
| 464 | + { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 }, | |
| 465 | + { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 }, | |
| 466 | + { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 }, | |
| 467 | + { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 }, | |
| 468 | + { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 }, | |
| 469 | + { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 }, | |
| 470 | + { 0, 0, 0, 0 } | |
| 471 | +}; | |
| 472 | + | |
| 473 | +bitmask_transtbl cflag_tbl[] = { | |
| 474 | + { TARGET_CBAUD, TARGET_B0, CBAUD, B0 }, | |
| 475 | + { TARGET_CBAUD, TARGET_B50, CBAUD, B50 }, | |
| 476 | + { TARGET_CBAUD, TARGET_B75, CBAUD, B75 }, | |
| 477 | + { TARGET_CBAUD, TARGET_B110, CBAUD, B110 }, | |
| 478 | + { TARGET_CBAUD, TARGET_B134, CBAUD, B134 }, | |
| 479 | + { TARGET_CBAUD, TARGET_B150, CBAUD, B150 }, | |
| 480 | + { TARGET_CBAUD, TARGET_B200, CBAUD, B200 }, | |
| 481 | + { TARGET_CBAUD, TARGET_B300, CBAUD, B300 }, | |
| 482 | + { TARGET_CBAUD, TARGET_B600, CBAUD, B600 }, | |
| 483 | + { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 }, | |
| 484 | + { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 }, | |
| 485 | + { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 }, | |
| 486 | + { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 }, | |
| 487 | + { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 }, | |
| 488 | + { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 }, | |
| 489 | + { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 }, | |
| 490 | + { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 }, | |
| 491 | + { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 }, | |
| 492 | + { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 }, | |
| 493 | + { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 }, | |
| 494 | + { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 }, | |
| 495 | + { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 }, | |
| 496 | + { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 }, | |
| 497 | + { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 }, | |
| 498 | + { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB }, | |
| 499 | + { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD }, | |
| 500 | + { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB }, | |
| 501 | + { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD }, | |
| 502 | + { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL }, | |
| 503 | + { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL }, | |
| 504 | + { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS }, | |
| 505 | + { 0, 0, 0, 0 } | |
| 506 | +}; | |
| 507 | + | |
| 508 | +bitmask_transtbl lflag_tbl[] = { | |
| 509 | + { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG }, | |
| 510 | + { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON }, | |
| 511 | + { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE }, | |
| 512 | + { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO }, | |
| 513 | + { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE }, | |
| 514 | + { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK }, | |
| 515 | + { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL }, | |
| 516 | + { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH }, | |
| 517 | + { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP }, | |
| 518 | + { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL }, | |
| 519 | + { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT }, | |
| 520 | + { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE }, | |
| 521 | + { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO }, | |
| 522 | + { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN }, | |
| 523 | + { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN }, | |
| 524 | + { 0, 0, 0, 0 } | |
| 525 | +}; | |
| 526 | + | |
| 527 | +static void target_to_host_termios (void *dst, const void *src) | |
| 528 | +{ | |
| 529 | + struct host_termios *host = dst; | |
| 530 | + const struct target_termios *target = src; | |
| 531 | + | |
| 532 | + host->c_iflag = | |
| 533 | + target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl); | |
| 534 | + host->c_oflag = | |
| 535 | + target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl); | |
| 536 | + host->c_cflag = | |
| 537 | + target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl); | |
| 538 | + host->c_lflag = | |
| 539 | + target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl); | |
| 540 | + host->c_line = target->c_line; | |
| 541 | + | |
| 542 | + host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; | |
| 543 | + host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; | |
| 544 | + host->c_cc[VERASE] = target->c_cc[TARGET_VERASE]; | |
| 545 | + host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; | |
| 546 | + host->c_cc[VEOF] = target->c_cc[TARGET_VEOF]; | |
| 547 | + host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; | |
| 548 | + host->c_cc[VMIN] = target->c_cc[TARGET_VMIN]; | |
| 549 | + host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; | |
| 550 | + host->c_cc[VSTART] = target->c_cc[TARGET_VSTART]; | |
| 551 | + host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; | |
| 552 | + host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; | |
| 553 | + host->c_cc[VEOL] = target->c_cc[TARGET_VEOL]; | |
| 554 | + host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT]; | |
| 555 | + host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD]; | |
| 556 | + host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE]; | |
| 557 | + host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT]; | |
| 558 | + host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; | |
| 559 | +} | |
| 560 | + | |
| 561 | +static void host_to_target_termios (void *dst, const void *src) | |
| 562 | +{ | |
| 563 | + struct target_termios *target = dst; | |
| 564 | + const struct host_termios *host = src; | |
| 565 | + | |
| 566 | + target->c_iflag = | |
| 567 | + tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl)); | |
| 568 | + target->c_oflag = | |
| 569 | + tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl)); | |
| 570 | + target->c_cflag = | |
| 571 | + tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl)); | |
| 572 | + target->c_lflag = | |
| 573 | + tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl)); | |
| 574 | + target->c_line = host->c_line; | |
| 575 | + | |
| 576 | + target->c_cc[TARGET_VINTR] = host->c_cc[VINTR]; | |
| 577 | + target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT]; | |
| 578 | + target->c_cc[TARGET_VERASE] = host->c_cc[VERASE]; | |
| 579 | + target->c_cc[TARGET_VKILL] = host->c_cc[VKILL]; | |
| 580 | + target->c_cc[TARGET_VEOF] = host->c_cc[VEOF]; | |
| 581 | + target->c_cc[TARGET_VTIME] = host->c_cc[VTIME]; | |
| 582 | + target->c_cc[TARGET_VMIN] = host->c_cc[VMIN]; | |
| 583 | + target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC]; | |
| 584 | + target->c_cc[TARGET_VSTART] = host->c_cc[VSTART]; | |
| 585 | + target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP]; | |
| 586 | + target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP]; | |
| 587 | + target->c_cc[TARGET_VEOL] = host->c_cc[VEOL]; | |
| 588 | + target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT]; | |
| 589 | + target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD]; | |
| 590 | + target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE]; | |
| 591 | + target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT]; | |
| 592 | + target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2]; | |
| 593 | +} | |
| 594 | + | |
| 595 | +StructEntry struct_termios_def = { | |
| 596 | + .convert = { host_to_target_termios, target_to_host_termios }, | |
| 597 | + .size = { sizeof(struct target_termios), sizeof(struct host_termios) }, | |
| 598 | + .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) }, | |
| 599 | +}; | |
| 600 | + | |
| 601 | +void syscall_init(void) | |
| 602 | +{ | |
| 603 | +#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); | |
| 604 | +#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); | |
| 605 | +#include "syscall_types.h" | |
| 606 | +#undef STRUCT | |
| 607 | +#undef STRUCT_SPECIAL | |
| 608 | +} | |
| 609 | + | |
| 610 | +long do_syscall(int num, long arg1, long arg2, long arg3, | |
| 611 | + long arg4, long arg5, long arg6) | |
| 612 | +{ | |
| 613 | + long ret; | |
| 614 | + struct stat st; | |
| 615 | + struct statfs *stfs; | |
| 616 | + | |
| 617 | + // gemu_log("syscall %d\n", num); | |
| 618 | + switch(num) { | |
| 619 | + case TARGET_NR_exit: | |
| 620 | + _exit(arg1); | |
| 621 | + ret = 0; /* avoid warning */ | |
| 622 | + break; | |
| 623 | + case TARGET_NR_read: | |
| 624 | + ret = get_errno(read(arg1, (void *)arg2, arg3)); | |
| 625 | + break; | |
| 626 | + case TARGET_NR_write: | |
| 627 | + ret = get_errno(write(arg1, (void *)arg2, arg3)); | |
| 628 | + break; | |
| 629 | + case TARGET_NR_open: | |
| 630 | + ret = get_errno(open((const char *)arg1, arg2, arg3)); | |
| 631 | + break; | |
| 632 | + case TARGET_NR_close: | |
| 633 | + ret = get_errno(close(arg1)); | |
| 634 | + break; | |
| 635 | + case TARGET_NR_brk: | |
| 636 | + ret = do_brk((char *)arg1); | |
| 637 | + break; | |
| 638 | + case TARGET_NR_fork: | |
| 639 | + ret = get_errno(fork()); | |
| 640 | + break; | |
| 641 | + case TARGET_NR_waitpid: | |
| 642 | + { | |
| 643 | + int *status = (int *)arg2; | |
| 644 | + ret = get_errno(waitpid(arg1, status, arg3)); | |
| 645 | + if (!is_error(ret) && status) | |
| 646 | + tswapls((long *)&status); | |
| 647 | + } | |
| 648 | + break; | |
| 649 | + case TARGET_NR_creat: | |
| 650 | + ret = get_errno(creat((const char *)arg1, arg2)); | |
| 651 | + break; | |
| 652 | + case TARGET_NR_link: | |
| 653 | + ret = get_errno(link((const char *)arg1, (const char *)arg2)); | |
| 654 | + break; | |
| 655 | + case TARGET_NR_unlink: | |
| 656 | + ret = get_errno(unlink((const char *)arg1)); | |
| 657 | + break; | |
| 658 | + case TARGET_NR_execve: | |
| 659 | + ret = get_errno(execve((const char *)arg1, (void *)arg2, (void *)arg3)); | |
| 660 | + break; | |
| 661 | + case TARGET_NR_chdir: | |
| 662 | + ret = get_errno(chdir((const char *)arg1)); | |
| 663 | + break; | |
| 664 | + case TARGET_NR_time: | |
| 665 | + { | |
| 666 | + int *time_ptr = (int *)arg1; | |
| 667 | + ret = get_errno(time((time_t *)time_ptr)); | |
| 668 | + if (!is_error(ret) && time_ptr) | |
| 669 | + tswap32s(time_ptr); | |
| 670 | + } | |
| 671 | + break; | |
| 672 | + case TARGET_NR_mknod: | |
| 673 | + ret = get_errno(mknod((const char *)arg1, arg2, arg3)); | |
| 674 | + break; | |
| 675 | + case TARGET_NR_chmod: | |
| 676 | + ret = get_errno(chmod((const char *)arg1, arg2)); | |
| 677 | + break; | |
| 678 | + case TARGET_NR_lchown: | |
| 679 | + ret = get_errno(chown((const char *)arg1, arg2, arg3)); | |
| 680 | + break; | |
| 681 | + case TARGET_NR_break: | |
| 682 | + goto unimplemented; | |
| 683 | + case TARGET_NR_oldstat: | |
| 684 | + goto unimplemented; | |
| 685 | + case TARGET_NR_lseek: | |
| 686 | + ret = get_errno(lseek(arg1, arg2, arg3)); | |
| 687 | + break; | |
| 688 | + case TARGET_NR_getpid: | |
| 689 | + ret = get_errno(getpid()); | |
| 690 | + break; | |
| 691 | + case TARGET_NR_mount: | |
| 692 | + /* need to look at the data field */ | |
| 693 | + goto unimplemented; | |
| 694 | + case TARGET_NR_umount: | |
| 695 | + ret = get_errno(umount((const char *)arg1)); | |
| 696 | + break; | |
| 697 | + case TARGET_NR_setuid: | |
| 698 | + ret = get_errno(setuid(arg1)); | |
| 699 | + break; | |
| 700 | + case TARGET_NR_getuid: | |
| 701 | + ret = get_errno(getuid()); | |
| 702 | + break; | |
| 703 | + case TARGET_NR_stime: | |
| 704 | + { | |
| 705 | + int *time_ptr = (int *)arg1; | |
| 706 | + if (time_ptr) | |
| 707 | + tswap32s(time_ptr); | |
| 708 | + ret = get_errno(stime((time_t *)time_ptr)); | |
| 709 | + } | |
| 710 | + break; | |
| 711 | + case TARGET_NR_ptrace: | |
| 712 | + goto unimplemented; | |
| 713 | + case TARGET_NR_alarm: | |
| 714 | + ret = alarm(arg1); | |
| 715 | + break; | |
| 716 | + case TARGET_NR_oldfstat: | |
| 717 | + goto unimplemented; | |
| 718 | + case TARGET_NR_pause: | |
| 719 | + ret = get_errno(pause()); | |
| 720 | + break; | |
| 721 | + case TARGET_NR_utime: | |
| 722 | + goto unimplemented; | |
| 723 | + case TARGET_NR_stty: | |
| 724 | + goto unimplemented; | |
| 725 | + case TARGET_NR_gtty: | |
| 726 | + goto unimplemented; | |
| 727 | + case TARGET_NR_access: | |
| 728 | + ret = get_errno(access((const char *)arg1, arg2)); | |
| 729 | + break; | |
| 730 | + case TARGET_NR_nice: | |
| 731 | + ret = get_errno(nice(arg1)); | |
| 732 | + break; | |
| 733 | + case TARGET_NR_ftime: | |
| 734 | + goto unimplemented; | |
| 735 | + case TARGET_NR_sync: | |
| 736 | + ret = get_errno(sync()); | |
| 737 | + break; | |
| 738 | + case TARGET_NR_kill: | |
| 739 | + ret = get_errno(kill(arg1, arg2)); | |
| 740 | + break; | |
| 741 | + case TARGET_NR_rename: | |
| 742 | + ret = get_errno(rename((const char *)arg1, (const char *)arg2)); | |
| 743 | + break; | |
| 744 | + case TARGET_NR_mkdir: | |
| 745 | + ret = get_errno(mkdir((const char *)arg1, arg2)); | |
| 746 | + break; | |
| 747 | + case TARGET_NR_rmdir: | |
| 748 | + ret = get_errno(rmdir((const char *)arg1)); | |
| 749 | + break; | |
| 750 | + case TARGET_NR_dup: | |
| 751 | + ret = get_errno(dup(arg1)); | |
| 752 | + break; | |
| 753 | + case TARGET_NR_pipe: | |
| 754 | + { | |
| 755 | + int *pipe_ptr = (int *)arg1; | |
| 756 | + ret = get_errno(pipe(pipe_ptr)); | |
| 757 | + if (!is_error(ret)) { | |
| 758 | + tswap32s(&pipe_ptr[0]); | |
| 759 | + tswap32s(&pipe_ptr[1]); | |
| 760 | + } | |
| 761 | + } | |
| 762 | + break; | |
| 763 | + case TARGET_NR_times: | |
| 764 | + goto unimplemented; | |
| 765 | + case TARGET_NR_prof: | |
| 766 | + goto unimplemented; | |
| 767 | + case TARGET_NR_setgid: | |
| 768 | + ret = get_errno(setgid(arg1)); | |
| 769 | + break; | |
| 770 | + case TARGET_NR_getgid: | |
| 771 | + ret = get_errno(getgid()); | |
| 772 | + break; | |
| 773 | + case TARGET_NR_signal: | |
| 774 | + goto unimplemented; | |
| 775 | + case TARGET_NR_geteuid: | |
| 776 | + ret = get_errno(geteuid()); | |
| 777 | + break; | |
| 778 | + case TARGET_NR_getegid: | |
| 779 | + ret = get_errno(getegid()); | |
| 780 | + break; | |
| 781 | + case TARGET_NR_acct: | |
| 782 | + goto unimplemented; | |
| 783 | + case TARGET_NR_umount2: | |
| 784 | + ret = get_errno(umount2((const char *)arg1, arg2)); | |
| 785 | + break; | |
| 786 | + case TARGET_NR_lock: | |
| 787 | + goto unimplemented; | |
| 788 | + case TARGET_NR_ioctl: | |
| 789 | + ret = do_ioctl(arg1, arg2, arg3); | |
| 790 | + break; | |
| 791 | + case TARGET_NR_fcntl: | |
| 792 | + switch(arg2) { | |
| 793 | + case F_GETLK: | |
| 794 | + case F_SETLK: | |
| 795 | + case F_SETLKW: | |
| 796 | + goto unimplemented; | |
| 797 | + default: | |
| 798 | + ret = get_errno(fcntl(arg1, arg2, arg3)); | |
| 799 | + break; | |
| 800 | + } | |
| 801 | + break; | |
| 802 | + case TARGET_NR_mpx: | |
| 803 | + goto unimplemented; | |
| 804 | + case TARGET_NR_setpgid: | |
| 805 | + ret = get_errno(setpgid(arg1, arg2)); | |
| 806 | + break; | |
| 807 | + case TARGET_NR_ulimit: | |
| 808 | + goto unimplemented; | |
| 809 | + case TARGET_NR_oldolduname: | |
| 810 | + goto unimplemented; | |
| 811 | + case TARGET_NR_umask: | |
| 812 | + ret = get_errno(umask(arg1)); | |
| 813 | + break; | |
| 814 | + case TARGET_NR_chroot: | |
| 815 | + ret = get_errno(chroot((const char *)arg1)); | |
| 816 | + break; | |
| 817 | + case TARGET_NR_ustat: | |
| 818 | + goto unimplemented; | |
| 819 | + case TARGET_NR_dup2: | |
| 820 | + ret = get_errno(dup2(arg1, arg2)); | |
| 821 | + break; | |
| 822 | + case TARGET_NR_getppid: | |
| 823 | + ret = get_errno(getppid()); | |
| 824 | + break; | |
| 825 | + case TARGET_NR_getpgrp: | |
| 826 | + ret = get_errno(getpgrp()); | |
| 827 | + break; | |
| 828 | + case TARGET_NR_setsid: | |
| 829 | + ret = get_errno(setsid()); | |
| 830 | + break; | |
| 831 | + case TARGET_NR_sigaction: | |
| 832 | +#if 0 | |
| 833 | + { | |
| 834 | + int signum = arg1; | |
| 835 | + struct target_old_sigaction *tact = arg2, *toldact = arg3; | |
| 836 | + ret = get_errno(setsid()); | |
| 837 | + | |
| 838 | + | |
| 839 | + } | |
| 840 | + break; | |
| 841 | +#else | |
| 842 | + goto unimplemented; | |
| 843 | +#endif | |
| 844 | + case TARGET_NR_sgetmask: | |
| 845 | + goto unimplemented; | |
| 846 | + case TARGET_NR_ssetmask: | |
| 847 | + goto unimplemented; | |
| 848 | + case TARGET_NR_setreuid: | |
| 849 | + ret = get_errno(setreuid(arg1, arg2)); | |
| 850 | + break; | |
| 851 | + case TARGET_NR_setregid: | |
| 852 | + ret = get_errno(setregid(arg1, arg2)); | |
| 853 | + break; | |
| 854 | + case TARGET_NR_sigsuspend: | |
| 855 | + goto unimplemented; | |
| 856 | + case TARGET_NR_sigpending: | |
| 857 | + goto unimplemented; | |
| 858 | + case TARGET_NR_sethostname: | |
| 859 | + ret = get_errno(sethostname((const char *)arg1, arg2)); | |
| 860 | + break; | |
| 861 | + case TARGET_NR_setrlimit: | |
| 862 | + goto unimplemented; | |
| 863 | + case TARGET_NR_getrlimit: | |
| 864 | + goto unimplemented; | |
| 865 | + case TARGET_NR_getrusage: | |
| 866 | + goto unimplemented; | |
| 867 | + case TARGET_NR_gettimeofday: | |
| 868 | + { | |
| 869 | + struct target_timeval *target_tv = (void *)arg1; | |
| 870 | + struct timeval tv; | |
| 871 | + ret = get_errno(gettimeofday(&tv, NULL)); | |
| 872 | + if (!is_error(ret)) { | |
| 873 | + target_tv->tv_sec = tswapl(tv.tv_sec); | |
| 874 | + target_tv->tv_usec = tswapl(tv.tv_usec); | |
| 875 | + } | |
| 876 | + } | |
| 877 | + break; | |
| 878 | + case TARGET_NR_settimeofday: | |
| 879 | + { | |
| 880 | + struct target_timeval *target_tv = (void *)arg1; | |
| 881 | + struct timeval tv; | |
| 882 | + tv.tv_sec = tswapl(target_tv->tv_sec); | |
| 883 | + tv.tv_usec = tswapl(target_tv->tv_usec); | |
| 884 | + ret = get_errno(settimeofday(&tv, NULL)); | |
| 885 | + } | |
| 886 | + break; | |
| 887 | + case TARGET_NR_getgroups: | |
| 888 | + goto unimplemented; | |
| 889 | + case TARGET_NR_setgroups: | |
| 890 | + goto unimplemented; | |
| 891 | + case TARGET_NR_select: | |
| 892 | + goto unimplemented; | |
| 893 | + case TARGET_NR_symlink: | |
| 894 | + ret = get_errno(symlink((const char *)arg1, (const char *)arg2)); | |
| 895 | + break; | |
| 896 | + case TARGET_NR_oldlstat: | |
| 897 | + goto unimplemented; | |
| 898 | + case TARGET_NR_readlink: | |
| 899 | + ret = get_errno(readlink((const char *)arg1, (char *)arg2, arg3)); | |
| 900 | + break; | |
| 901 | + case TARGET_NR_uselib: | |
| 902 | + goto unimplemented; | |
| 903 | + case TARGET_NR_swapon: | |
| 904 | + ret = get_errno(swapon((const char *)arg1, arg2)); | |
| 905 | + break; | |
| 906 | + case TARGET_NR_reboot: | |
| 907 | + goto unimplemented; | |
| 908 | + case TARGET_NR_readdir: | |
| 909 | + goto unimplemented; | |
| 910 | +#ifdef TARGET_I386 | |
| 911 | + case TARGET_NR_mmap: | |
| 912 | + { | |
| 913 | + uint32_t v1, v2, v3, v4, v5, v6, *vptr; | |
| 914 | + vptr = (uint32_t *)arg1; | |
| 915 | + v1 = tswap32(vptr[0]); | |
| 916 | + v2 = tswap32(vptr[1]); | |
| 917 | + v3 = tswap32(vptr[2]); | |
| 918 | + v4 = tswap32(vptr[3]); | |
| 919 | + v5 = tswap32(vptr[4]); | |
| 920 | + v6 = tswap32(vptr[5]); | |
| 921 | + ret = get_errno((long)mmap((void *)v1, v2, v3, v4, v5, v6)); | |
| 922 | + } | |
| 923 | + break; | |
| 924 | +#endif | |
| 925 | +#ifdef TARGET_I386 | |
| 926 | + case TARGET_NR_mmap2: | |
| 927 | +#else | |
| 928 | + case TARGET_NR_mmap: | |
| 929 | +#endif | |
| 930 | + ret = get_errno((long)mmap((void *)arg1, arg2, arg3, arg4, arg5, arg6)); | |
| 931 | + break; | |
| 932 | + case TARGET_NR_munmap: | |
| 933 | + ret = get_errno(munmap((void *)arg1, arg2)); | |
| 934 | + break; | |
| 935 | + case TARGET_NR_truncate: | |
| 936 | + ret = get_errno(truncate((const char *)arg1, arg2)); | |
| 937 | + break; | |
| 938 | + case TARGET_NR_ftruncate: | |
| 939 | + ret = get_errno(ftruncate(arg1, arg2)); | |
| 940 | + break; | |
| 941 | + case TARGET_NR_fchmod: | |
| 942 | + ret = get_errno(fchmod(arg1, arg2)); | |
| 943 | + break; | |
| 944 | + case TARGET_NR_fchown: | |
| 945 | + ret = get_errno(fchown(arg1, arg2, arg3)); | |
| 946 | + break; | |
| 947 | + case TARGET_NR_getpriority: | |
| 948 | + ret = get_errno(getpriority(arg1, arg2)); | |
| 949 | + break; | |
| 950 | + case TARGET_NR_setpriority: | |
| 951 | + ret = get_errno(setpriority(arg1, arg2, arg3)); | |
| 952 | + break; | |
| 953 | + case TARGET_NR_profil: | |
| 954 | + goto unimplemented; | |
| 955 | + case TARGET_NR_statfs: | |
| 956 | + stfs = (void *)arg2; | |
| 957 | + ret = get_errno(sys_statfs((const char *)arg1, stfs)); | |
| 958 | + convert_statfs: | |
| 959 | + if (!is_error(ret)) { | |
| 960 | + tswap32s(&stfs->f_type); | |
| 961 | + tswap32s(&stfs->f_bsize); | |
| 962 | + tswap32s(&stfs->f_blocks); | |
| 963 | + tswap32s(&stfs->f_bfree); | |
| 964 | + tswap32s(&stfs->f_bavail); | |
| 965 | + tswap32s(&stfs->f_files); | |
| 966 | + tswap32s(&stfs->f_ffree); | |
| 967 | + tswap32s(&stfs->f_fsid.val[0]); | |
| 968 | + tswap32s(&stfs->f_fsid.val[1]); | |
| 969 | + tswap32s(&stfs->f_namelen); | |
| 970 | + } | |
| 971 | + break; | |
| 972 | + case TARGET_NR_fstatfs: | |
| 973 | + stfs = (void *)arg2; | |
| 974 | + ret = get_errno(sys_fstatfs(arg1, stfs)); | |
| 975 | + goto convert_statfs; | |
| 976 | + case TARGET_NR_ioperm: | |
| 977 | + goto unimplemented; | |
| 978 | + case TARGET_NR_socketcall: | |
| 979 | + ret = do_socketcall(arg1, (long *)arg2); | |
| 980 | + break; | |
| 981 | + case TARGET_NR_syslog: | |
| 982 | + goto unimplemented; | |
| 983 | + case TARGET_NR_setitimer: | |
| 984 | + goto unimplemented; | |
| 985 | + case TARGET_NR_getitimer: | |
| 986 | + goto unimplemented; | |
| 987 | + case TARGET_NR_stat: | |
| 988 | + ret = get_errno(stat((const char *)arg1, &st)); | |
| 989 | + goto do_stat; | |
| 990 | + case TARGET_NR_lstat: | |
| 991 | + ret = get_errno(lstat((const char *)arg1, &st)); | |
| 992 | + goto do_stat; | |
| 993 | + case TARGET_NR_fstat: | |
| 994 | + { | |
| 995 | + ret = get_errno(fstat(arg1, &st)); | |
| 996 | + do_stat: | |
| 997 | + if (!is_error(ret)) { | |
| 998 | + struct target_stat *target_st = (void *)arg2; | |
| 999 | + target_st->st_dev = tswap16(st.st_dev); | |
| 1000 | + target_st->st_ino = tswapl(st.st_ino); | |
| 1001 | + target_st->st_mode = tswap16(st.st_mode); | |
| 1002 | + target_st->st_nlink = tswap16(st.st_nlink); | |
| 1003 | + target_st->st_uid = tswap16(st.st_uid); | |
| 1004 | + target_st->st_gid = tswap16(st.st_gid); | |
| 1005 | + target_st->st_rdev = tswap16(st.st_rdev); | |
| 1006 | + target_st->st_size = tswapl(st.st_size); | |
| 1007 | + target_st->st_blksize = tswapl(st.st_blksize); | |
| 1008 | + target_st->st_blocks = tswapl(st.st_blocks); | |
| 1009 | + target_st->st_atime = tswapl(st.st_atime); | |
| 1010 | + target_st->st_mtime = tswapl(st.st_mtime); | |
| 1011 | + target_st->st_ctime = tswapl(st.st_ctime); | |
| 1012 | + } | |
| 1013 | + } | |
| 1014 | + break; | |
| 1015 | + case TARGET_NR_olduname: | |
| 1016 | + goto unimplemented; | |
| 1017 | + case TARGET_NR_iopl: | |
| 1018 | + goto unimplemented; | |
| 1019 | + case TARGET_NR_vhangup: | |
| 1020 | + ret = get_errno(vhangup()); | |
| 1021 | + break; | |
| 1022 | + case TARGET_NR_idle: | |
| 1023 | + goto unimplemented; | |
| 1024 | + case TARGET_NR_vm86old: | |
| 1025 | + goto unimplemented; | |
| 1026 | + case TARGET_NR_wait4: | |
| 1027 | + { | |
| 1028 | + int status; | |
| 1029 | + target_long *status_ptr = (void *)arg2; | |
| 1030 | + struct rusage rusage, *rusage_ptr; | |
| 1031 | + struct target_rusage *target_rusage = (void *)arg4; | |
| 1032 | + if (target_rusage) | |
| 1033 | + rusage_ptr = &rusage; | |
| 1034 | + else | |
| 1035 | + rusage_ptr = NULL; | |
| 1036 | + ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); | |
| 1037 | + if (!is_error(ret)) { | |
| 1038 | + if (status_ptr) | |
| 1039 | + *status_ptr = tswap32(status); | |
| 1040 | + if (target_rusage) { | |
| 1041 | + target_rusage->ru_utime.tv_sec = tswapl(rusage.ru_utime.tv_sec); | |
| 1042 | + target_rusage->ru_utime.tv_usec = tswapl(rusage.ru_utime.tv_usec); | |
| 1043 | + target_rusage->ru_stime.tv_sec = tswapl(rusage.ru_stime.tv_sec); | |
| 1044 | + target_rusage->ru_stime.tv_usec = tswapl(rusage.ru_stime.tv_usec); | |
| 1045 | + target_rusage->ru_maxrss = tswapl(rusage.ru_maxrss); | |
| 1046 | + target_rusage->ru_ixrss = tswapl(rusage.ru_ixrss); | |
| 1047 | + target_rusage->ru_idrss = tswapl(rusage.ru_idrss); | |
| 1048 | + target_rusage->ru_isrss = tswapl(rusage.ru_isrss); | |
| 1049 | + target_rusage->ru_minflt = tswapl(rusage.ru_minflt); | |
| 1050 | + target_rusage->ru_majflt = tswapl(rusage.ru_majflt); | |
| 1051 | + target_rusage->ru_nswap = tswapl(rusage.ru_nswap); | |
| 1052 | + target_rusage->ru_inblock = tswapl(rusage.ru_inblock); | |
| 1053 | + target_rusage->ru_oublock = tswapl(rusage.ru_oublock); | |
| 1054 | + target_rusage->ru_msgsnd = tswapl(rusage.ru_msgsnd); | |
| 1055 | + target_rusage->ru_msgrcv = tswapl(rusage.ru_msgrcv); | |
| 1056 | + target_rusage->ru_nsignals = tswapl(rusage.ru_nsignals); | |
| 1057 | + target_rusage->ru_nvcsw = tswapl(rusage.ru_nvcsw); | |
| 1058 | + target_rusage->ru_nivcsw = tswapl(rusage.ru_nivcsw); | |
| 1059 | + } | |
| 1060 | + } | |
| 1061 | + } | |
| 1062 | + break; | |
| 1063 | + case TARGET_NR_swapoff: | |
| 1064 | + ret = get_errno(swapoff((const char *)arg1)); | |
| 1065 | + break; | |
| 1066 | + case TARGET_NR_sysinfo: | |
| 1067 | + goto unimplemented; | |
| 1068 | + case TARGET_NR_ipc: | |
| 1069 | + goto unimplemented; | |
| 1070 | + case TARGET_NR_fsync: | |
| 1071 | + ret = get_errno(fsync(arg1)); | |
| 1072 | + break; | |
| 1073 | + case TARGET_NR_sigreturn: | |
| 1074 | + goto unimplemented; | |
| 1075 | + case TARGET_NR_clone: | |
| 1076 | + goto unimplemented; | |
| 1077 | + case TARGET_NR_setdomainname: | |
| 1078 | + ret = get_errno(setdomainname((const char *)arg1, arg2)); | |
| 1079 | + break; | |
| 1080 | + case TARGET_NR_uname: | |
| 1081 | + /* no need to transcode because we use the linux syscall */ | |
| 1082 | + ret = get_errno(sys_uname((struct new_utsname *)arg1)); | |
| 1083 | + break; | |
| 1084 | + case TARGET_NR_modify_ldt: | |
| 1085 | + goto unimplemented; | |
| 1086 | + case TARGET_NR_adjtimex: | |
| 1087 | + goto unimplemented; | |
| 1088 | + case TARGET_NR_mprotect: | |
| 1089 | + ret = get_errno(mprotect((void *)arg1, arg2, arg3)); | |
| 1090 | + break; | |
| 1091 | + case TARGET_NR_sigprocmask: | |
| 1092 | + { | |
| 1093 | + int how = arg1; | |
| 1094 | + sigset_t set, oldset, *set_ptr; | |
| 1095 | + target_ulong *pset = (void *)arg2, *poldset = (void *)arg3; | |
| 1096 | + | |
| 1097 | + switch(how) { | |
| 1098 | + case TARGET_SIG_BLOCK: | |
| 1099 | + how = SIG_BLOCK; | |
| 1100 | + break; | |
| 1101 | + case TARGET_SIG_UNBLOCK: | |
| 1102 | + how = SIG_UNBLOCK; | |
| 1103 | + break; | |
| 1104 | + case TARGET_SIG_SETMASK: | |
| 1105 | + how = SIG_SETMASK; | |
| 1106 | + break; | |
| 1107 | + default: | |
| 1108 | + ret = -EINVAL; | |
| 1109 | + goto fail; | |
| 1110 | + } | |
| 1111 | + | |
| 1112 | + if (pset) { | |
| 1113 | + target_to_host_old_sigset(&set, pset); | |
| 1114 | + set_ptr = &set; | |
| 1115 | + } else { | |
| 1116 | + set_ptr = NULL; | |
| 1117 | + } | |
| 1118 | + ret = get_errno(sigprocmask(arg1, set_ptr, &oldset)); | |
| 1119 | + if (!is_error(ret) && poldset) { | |
| 1120 | + host_to_target_old_sigset(poldset, &oldset); | |
| 1121 | + } | |
| 1122 | + } | |
| 1123 | + break; | |
| 1124 | + case TARGET_NR_create_module: | |
| 1125 | + case TARGET_NR_init_module: | |
| 1126 | + case TARGET_NR_delete_module: | |
| 1127 | + case TARGET_NR_get_kernel_syms: | |
| 1128 | + goto unimplemented; | |
| 1129 | + case TARGET_NR_quotactl: | |
| 1130 | + goto unimplemented; | |
| 1131 | + case TARGET_NR_getpgid: | |
| 1132 | + ret = get_errno(getpgid(arg1)); | |
| 1133 | + break; | |
| 1134 | + case TARGET_NR_fchdir: | |
| 1135 | + ret = get_errno(fchdir(arg1)); | |
| 1136 | + break; | |
| 1137 | + case TARGET_NR_bdflush: | |
| 1138 | + goto unimplemented; | |
| 1139 | + case TARGET_NR_sysfs: | |
| 1140 | + goto unimplemented; | |
| 1141 | + case TARGET_NR_personality: | |
| 1142 | + ret = get_errno(mprotect((void *)arg1, arg2, arg3)); | |
| 1143 | + break; | |
| 1144 | + case TARGET_NR_afs_syscall: | |
| 1145 | + goto unimplemented; | |
| 1146 | + case TARGET_NR_setfsuid: | |
| 1147 | + goto unimplemented; | |
| 1148 | + case TARGET_NR_setfsgid: | |
| 1149 | + goto unimplemented; | |
| 1150 | + case TARGET_NR__llseek: | |
| 1151 | + { | |
| 1152 | + int64_t res; | |
| 1153 | + ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); | |
| 1154 | + *(int64_t *)arg4 = tswap64(res); | |
| 1155 | + } | |
| 1156 | + break; | |
| 1157 | + case TARGET_NR_getdents: | |
| 1158 | +#if TARGET_LONG_SIZE != 4 | |
| 1159 | +#error not supported | |
| 1160 | +#endif | |
| 1161 | + { | |
| 1162 | + struct dirent *dirp = (void *)arg2; | |
| 1163 | + long count = arg3; | |
| 1164 | + ret = get_errno(getdents(arg1, dirp, count)); | |
| 1165 | + if (!is_error(ret)) { | |
| 1166 | + struct dirent *de; | |
| 1167 | + int len = ret; | |
| 1168 | + int reclen; | |
| 1169 | + de = dirp; | |
| 1170 | + while (len > 0) { | |
| 1171 | + reclen = tswap16(de->d_reclen); | |
| 1172 | + if (reclen > len) | |
| 1173 | + break; | |
| 1174 | + de->d_reclen = reclen; | |
| 1175 | + tswapls(&de->d_ino); | |
| 1176 | + tswapls(&de->d_off); | |
| 1177 | + de = (struct dirent *)((char *)de + reclen); | |
| 1178 | + len -= reclen; | |
| 1179 | + } | |
| 1180 | + } | |
| 1181 | + } | |
| 1182 | + break; | |
| 1183 | + case TARGET_NR__newselect: | |
| 1184 | + ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, | |
| 1185 | + (void *)arg5); | |
| 1186 | + break; | |
| 1187 | + case TARGET_NR_flock: | |
| 1188 | + goto unimplemented; | |
| 1189 | + case TARGET_NR_msync: | |
| 1190 | + ret = get_errno(msync((void *)arg1, arg2, arg3)); | |
| 1191 | + break; | |
| 1192 | + case TARGET_NR_readv: | |
| 1193 | + { | |
| 1194 | + int count = arg3; | |
| 1195 | + int i; | |
| 1196 | + struct iovec *vec; | |
| 1197 | + struct target_iovec *target_vec = (void *)arg2; | |
| 1198 | + | |
| 1199 | + vec = alloca(count * sizeof(struct iovec)); | |
| 1200 | + for(i = 0;i < count; i++) { | |
| 1201 | + vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base); | |
| 1202 | + vec[i].iov_len = tswapl(target_vec[i].iov_len); | |
| 1203 | + } | |
| 1204 | + ret = get_errno(readv(arg1, vec, count)); | |
| 1205 | + } | |
| 1206 | + break; | |
| 1207 | + case TARGET_NR_writev: | |
| 1208 | + { | |
| 1209 | + int count = arg3; | |
| 1210 | + int i; | |
| 1211 | + struct iovec *vec; | |
| 1212 | + struct target_iovec *target_vec = (void *)arg2; | |
| 1213 | + | |
| 1214 | + vec = alloca(count * sizeof(struct iovec)); | |
| 1215 | + for(i = 0;i < count; i++) { | |
| 1216 | + vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base); | |
| 1217 | + vec[i].iov_len = tswapl(target_vec[i].iov_len); | |
| 1218 | + } | |
| 1219 | + ret = get_errno(writev(arg1, vec, count)); | |
| 1220 | + } | |
| 1221 | + break; | |
| 1222 | + case TARGET_NR_getsid: | |
| 1223 | + ret = get_errno(getsid(arg1)); | |
| 1224 | + break; | |
| 1225 | + case TARGET_NR_fdatasync: | |
| 1226 | + goto unimplemented; | |
| 1227 | + case TARGET_NR__sysctl: | |
| 1228 | + goto unimplemented; | |
| 1229 | + case TARGET_NR_mlock: | |
| 1230 | + ret = get_errno(mlock((void *)arg1, arg2)); | |
| 1231 | + break; | |
| 1232 | + case TARGET_NR_munlock: | |
| 1233 | + ret = get_errno(munlock((void *)arg1, arg2)); | |
| 1234 | + break; | |
| 1235 | + case TARGET_NR_mlockall: | |
| 1236 | + ret = get_errno(mlockall(arg1)); | |
| 1237 | + break; | |
| 1238 | + case TARGET_NR_munlockall: | |
| 1239 | + ret = get_errno(munlockall()); | |
| 1240 | + break; | |
| 1241 | + case TARGET_NR_sched_setparam: | |
| 1242 | + goto unimplemented; | |
| 1243 | + case TARGET_NR_sched_getparam: | |
| 1244 | + goto unimplemented; | |
| 1245 | + case TARGET_NR_sched_setscheduler: | |
| 1246 | + goto unimplemented; | |
| 1247 | + case TARGET_NR_sched_getscheduler: | |
| 1248 | + goto unimplemented; | |
| 1249 | + case TARGET_NR_sched_yield: | |
| 1250 | + ret = get_errno(sched_yield()); | |
| 1251 | + break; | |
| 1252 | + case TARGET_NR_sched_get_priority_max: | |
| 1253 | + case TARGET_NR_sched_get_priority_min: | |
| 1254 | + case TARGET_NR_sched_rr_get_interval: | |
| 1255 | + case TARGET_NR_nanosleep: | |
| 1256 | + case TARGET_NR_mremap: | |
| 1257 | + case TARGET_NR_setresuid: | |
| 1258 | + case TARGET_NR_getresuid: | |
| 1259 | + case TARGET_NR_vm86: | |
| 1260 | + case TARGET_NR_query_module: | |
| 1261 | + case TARGET_NR_poll: | |
| 1262 | + case TARGET_NR_nfsservctl: | |
| 1263 | + case TARGET_NR_setresgid: | |
| 1264 | + case TARGET_NR_getresgid: | |
| 1265 | + case TARGET_NR_prctl: | |
| 1266 | + case TARGET_NR_rt_sigreturn: | |
| 1267 | + case TARGET_NR_rt_sigaction: | |
| 1268 | + case TARGET_NR_rt_sigprocmask: | |
| 1269 | + case TARGET_NR_rt_sigpending: | |
| 1270 | + case TARGET_NR_rt_sigtimedwait: | |
| 1271 | + case TARGET_NR_rt_sigqueueinfo: | |
| 1272 | + case TARGET_NR_rt_sigsuspend: | |
| 1273 | + case TARGET_NR_pread: | |
| 1274 | + case TARGET_NR_pwrite: | |
| 1275 | + goto unimplemented; | |
| 1276 | + case TARGET_NR_chown: | |
| 1277 | + ret = get_errno(chown((const char *)arg1, arg2, arg3)); | |
| 1278 | + break; | |
| 1279 | + case TARGET_NR_getcwd: | |
| 1280 | + ret = get_errno(sys_getcwd((char *)arg1, arg2)); | |
| 1281 | + break; | |
| 1282 | + case TARGET_NR_capget: | |
| 1283 | + case TARGET_NR_capset: | |
| 1284 | + case TARGET_NR_sigaltstack: | |
| 1285 | + case TARGET_NR_sendfile: | |
| 1286 | + case TARGET_NR_getpmsg: | |
| 1287 | + case TARGET_NR_putpmsg: | |
| 1288 | + case TARGET_NR_vfork: | |
| 1289 | + ret = get_errno(vfork()); | |
| 1290 | + break; | |
| 1291 | + case TARGET_NR_ugetrlimit: | |
| 1292 | + case TARGET_NR_truncate64: | |
| 1293 | + case TARGET_NR_ftruncate64: | |
| 1294 | + case TARGET_NR_stat64: | |
| 1295 | + case TARGET_NR_lstat64: | |
| 1296 | + case TARGET_NR_fstat64: | |
| 1297 | + case TARGET_NR_lchown32: | |
| 1298 | + case TARGET_NR_getuid32: | |
| 1299 | + case TARGET_NR_getgid32: | |
| 1300 | + case TARGET_NR_geteuid32: | |
| 1301 | + case TARGET_NR_getegid32: | |
| 1302 | + case TARGET_NR_setreuid32: | |
| 1303 | + case TARGET_NR_setregid32: | |
| 1304 | + case TARGET_NR_getgroups32: | |
| 1305 | + case TARGET_NR_setgroups32: | |
| 1306 | + case TARGET_NR_fchown32: | |
| 1307 | + case TARGET_NR_setresuid32: | |
| 1308 | + case TARGET_NR_getresuid32: | |
| 1309 | + case TARGET_NR_setresgid32: | |
| 1310 | + case TARGET_NR_getresgid32: | |
| 1311 | + case TARGET_NR_chown32: | |
| 1312 | + case TARGET_NR_setuid32: | |
| 1313 | + case TARGET_NR_setgid32: | |
| 1314 | + case TARGET_NR_setfsuid32: | |
| 1315 | + case TARGET_NR_setfsgid32: | |
| 1316 | + case TARGET_NR_pivot_root: | |
| 1317 | + case TARGET_NR_mincore: | |
| 1318 | + case TARGET_NR_madvise: | |
| 1319 | + case TARGET_NR_getdents64: | |
| 1320 | + case TARGET_NR_fcntl64: | |
| 1321 | + case TARGET_NR_security: | |
| 1322 | + goto unimplemented; | |
| 1323 | + case TARGET_NR_gettid: | |
| 1324 | + ret = get_errno(gettid()); | |
| 1325 | + break; | |
| 1326 | + case TARGET_NR_readahead: | |
| 1327 | + case TARGET_NR_setxattr: | |
| 1328 | + case TARGET_NR_lsetxattr: | |
| 1329 | + case TARGET_NR_fsetxattr: | |
| 1330 | + case TARGET_NR_getxattr: | |
| 1331 | + case TARGET_NR_lgetxattr: | |
| 1332 | + case TARGET_NR_fgetxattr: | |
| 1333 | + case TARGET_NR_listxattr: | |
| 1334 | + case TARGET_NR_llistxattr: | |
| 1335 | + case TARGET_NR_flistxattr: | |
| 1336 | + case TARGET_NR_removexattr: | |
| 1337 | + case TARGET_NR_lremovexattr: | |
| 1338 | + case TARGET_NR_fremovexattr: | |
| 1339 | + goto unimplemented; | |
| 1340 | + default: | |
| 1341 | + unimplemented: | |
| 1342 | + gemu_log("Unsupported syscall: %d\n", num); | |
| 1343 | + ret = -ENOSYS; | |
| 1344 | + break; | |
| 1345 | + } | |
| 1346 | + fail: | |
| 1347 | + return ret; | |
| 1348 | +} | |
| 1349 | + | ... | ... |
linux-user/syscall_defs.h
0 → 100644
| 1 | + | |
| 2 | +/* common syscall defines for all architectures */ | |
| 3 | + | |
| 4 | +#define SOCKOP_socket 1 | |
| 5 | +#define SOCKOP_bind 2 | |
| 6 | +#define SOCKOP_connect 3 | |
| 7 | +#define SOCKOP_listen 4 | |
| 8 | +#define SOCKOP_accept 5 | |
| 9 | +#define SOCKOP_getsockname 6 | |
| 10 | +#define SOCKOP_getpeername 7 | |
| 11 | +#define SOCKOP_socketpair 8 | |
| 12 | +#define SOCKOP_send 9 | |
| 13 | +#define SOCKOP_recv 10 | |
| 14 | +#define SOCKOP_sendto 11 | |
| 15 | +#define SOCKOP_recvfrom 12 | |
| 16 | +#define SOCKOP_shutdown 13 | |
| 17 | +#define SOCKOP_setsockopt 14 | |
| 18 | +#define SOCKOP_getsockopt 15 | |
| 19 | +#define SOCKOP_sendmsg 16 | |
| 20 | +#define SOCKOP_recvmsg 17 | |
| 21 | + | |
| 22 | +struct target_timeval { | |
| 23 | + target_long tv_sec; | |
| 24 | + target_long tv_usec; | |
| 25 | +}; | |
| 26 | + | |
| 27 | +struct target_iovec { | |
| 28 | + target_long iov_base; /* Starting address */ | |
| 29 | + target_long iov_len; /* Number of bytes */ | |
| 30 | +}; | |
| 31 | + | |
| 32 | +struct target_rusage { | |
| 33 | + struct target_timeval ru_utime; /* user time used */ | |
| 34 | + struct target_timeval ru_stime; /* system time used */ | |
| 35 | + target_long ru_maxrss; /* maximum resident set size */ | |
| 36 | + target_long ru_ixrss; /* integral shared memory size */ | |
| 37 | + target_long ru_idrss; /* integral unshared data size */ | |
| 38 | + target_long ru_isrss; /* integral unshared stack size */ | |
| 39 | + target_long ru_minflt; /* page reclaims */ | |
| 40 | + target_long ru_majflt; /* page faults */ | |
| 41 | + target_long ru_nswap; /* swaps */ | |
| 42 | + target_long ru_inblock; /* block input operations */ | |
| 43 | + target_long ru_oublock; /* block output operations */ | |
| 44 | + target_long ru_msgsnd; /* messages sent */ | |
| 45 | + target_long ru_msgrcv; /* messages received */ | |
| 46 | + target_long ru_nsignals; /* signals received */ | |
| 47 | + target_long ru_nvcsw; /* voluntary context switches */ | |
| 48 | + target_long ru_nivcsw; /* involuntary " */ | |
| 49 | +}; | |
| 50 | + | |
| 51 | +typedef struct { | |
| 52 | + int val[2]; | |
| 53 | +} kernel_fsid_t; | |
| 54 | + | |
| 55 | +struct statfs { | |
| 56 | + int f_type; | |
| 57 | + int f_bsize; | |
| 58 | + int f_blocks; | |
| 59 | + int f_bfree; | |
| 60 | + int f_bavail; | |
| 61 | + int f_files; | |
| 62 | + int f_ffree; | |
| 63 | + kernel_fsid_t f_fsid; | |
| 64 | + int f_namelen; | |
| 65 | + int f_spare[6]; | |
| 66 | +}; | |
| 67 | + | |
| 68 | +/* mostly generic signal stuff */ | |
| 69 | +#define TARGET_SIG_DFL ((target_long)0) /* default signal handling */ | |
| 70 | +#define TARGET_SIG_IGN ((target_long)1) /* ignore signal */ | |
| 71 | +#define TARGET_SIG_ERR ((target_long)-1) /* error return from signal */ | |
| 72 | + | |
| 73 | +#ifdef TARGET_MIPS | |
| 74 | +#define TARGET_NSIG 128 | |
| 75 | +#else | |
| 76 | +#define TARGET_NSIG 64 | |
| 77 | +#endif | |
| 78 | +#define TARGET_NSIG_BPW TARGET_LONG_BITS | |
| 79 | +#define TARGET_NSIG_WORDS (TARGET_NSIG / TARGET_NSIG_BPW) | |
| 80 | + | |
| 81 | +typedef struct { | |
| 82 | + target_ulong sig[TARGET_NSIG_WORDS]; | |
| 83 | +} target_sigset_t; | |
| 84 | + | |
| 85 | +/* Networking ioctls */ | |
| 86 | +#define TARGET_SIOCADDRT 0x890B /* add routing table entry */ | |
| 87 | +#define TARGET_SIOCDELRT 0x890C /* delete routing table entry */ | |
| 88 | +#define TARGET_SIOCGIFNAME 0x8910 /* get iface name */ | |
| 89 | +#define TARGET_SIOCSIFLINK 0x8911 /* set iface channel */ | |
| 90 | +#define TARGET_SIOCGIFCONF 0x8912 /* get iface list */ | |
| 91 | +#define TARGET_SIOCGIFFLAGS 0x8913 /* get flags */ | |
| 92 | +#define TARGET_SIOCSIFFLAGS 0x8914 /* set flags */ | |
| 93 | +#define TARGET_SIOCGIFADDR 0x8915 /* get PA address */ | |
| 94 | +#define TARGET_SIOCSIFADDR 0x8916 /* set PA address */ | |
| 95 | +#define TARGET_SIOCGIFDSTADDR 0x8917 /* get remote PA address */ | |
| 96 | +#define TARGET_SIOCSIFDSTADDR 0x8918 /* set remote PA address */ | |
| 97 | +#define TARGET_SIOCGIFBRDADDR 0x8919 /* get broadcast PA address */ | |
| 98 | +#define TARGET_SIOCSIFBRDADDR 0x891a /* set broadcast PA address */ | |
| 99 | +#define TARGET_SIOCGIFNETMASK 0x891b /* get network PA mask */ | |
| 100 | +#define TARGET_SIOCSIFNETMASK 0x891c /* set network PA mask */ | |
| 101 | +#define TARGET_SIOCGIFMETRIC 0x891d /* get metric */ | |
| 102 | +#define TARGET_SIOCSIFMETRIC 0x891e /* set metric */ | |
| 103 | +#define TARGET_SIOCGIFMEM 0x891f /* get memory address (BSD) */ | |
| 104 | +#define TARGET_SIOCSIFMEM 0x8920 /* set memory address (BSD) */ | |
| 105 | +#define TARGET_SIOCGIFMTU 0x8921 /* get MTU size */ | |
| 106 | +#define TARGET_SIOCSIFMTU 0x8922 /* set MTU size */ | |
| 107 | +#define TARGET_SIOCSIFHWADDR 0x8924 /* set hardware address (NI) */ | |
| 108 | +#define TARGET_SIOCGIFENCAP 0x8925 /* get/set slip encapsulation */ | |
| 109 | +#define TARGET_SIOCSIFENCAP 0x8926 | |
| 110 | +#define TARGET_SIOCGIFHWADDR 0x8927 /* Get hardware address */ | |
| 111 | +#define TARGET_SIOCGIFSLAVE 0x8929 /* Driver slaving support */ | |
| 112 | +#define TARGET_SIOCSIFSLAVE 0x8930 | |
| 113 | +#define TARGET_SIOCADDMULTI 0x8931 /* Multicast address lists */ | |
| 114 | +#define TARGET_SIOCDELMULTI 0x8932 | |
| 115 | + | |
| 116 | +/* Bridging control calls */ | |
| 117 | +#define TARGET_SIOCGIFBR 0x8940 /* Bridging support */ | |
| 118 | +#define TARGET_SIOCSIFBR 0x8941 /* Set bridging options */ | |
| 119 | + | |
| 120 | +#define TARGET_SIOCGIFTXQLEN 0x8942 /* Get the tx queue length */ | |
| 121 | +#define TARGET_SIOCSIFTXQLEN 0x8943 /* Set the tx queue length */ | |
| 122 | + | |
| 123 | +/* ARP cache control calls. */ | |
| 124 | +#define TARGET_OLD_SIOCDARP 0x8950 /* old delete ARP table entry */ | |
| 125 | +#define TARGET_OLD_SIOCGARP 0x8951 /* old get ARP table entry */ | |
| 126 | +#define TARGET_OLD_SIOCSARP 0x8952 /* old set ARP table entry */ | |
| 127 | +#define TARGET_SIOCDARP 0x8953 /* delete ARP table entry */ | |
| 128 | +#define TARGET_SIOCGARP 0x8954 /* get ARP table entry */ | |
| 129 | +#define TARGET_SIOCSARP 0x8955 /* set ARP table entry */ | |
| 130 | + | |
| 131 | +/* RARP cache control calls. */ | |
| 132 | +#define TARGET_SIOCDRARP 0x8960 /* delete RARP table entry */ | |
| 133 | +#define TARGET_SIOCGRARP 0x8961 /* get RARP table entry */ | |
| 134 | +#define TARGET_SIOCSRARP 0x8962 /* set RARP table entry */ | |
| 135 | + | |
| 136 | +/* Driver configuration calls */ | |
| 137 | +#define TARGET_SIOCGIFMAP 0x8970 /* Get device parameters */ | |
| 138 | +#define TARGET_SIOCSIFMAP 0x8971 /* Set device parameters */ | |
| 139 | + | |
| 140 | +/* DLCI configuration calls */ | |
| 141 | +#define TARGET_SIOCADDDLCI 0x8980 /* Create new DLCI device */ | |
| 142 | +#define TARGET_SIOCDELDLCI 0x8981 /* Delete DLCI device */ | |
| 143 | + | |
| 144 | + | |
| 145 | +/* From <linux/fs.h> */ | |
| 146 | + | |
| 147 | +#define TARGET_BLKROSET TARGET_IO(0x12,93) /* set device read-only (0 = read-write) */ | |
| 148 | +#define TARGET_BLKROGET TARGET_IO(0x12,94) /* get read-only status (0 = read_write) */ | |
| 149 | +#define TARGET_BLKRRPART TARGET_IO(0x12,95) /* re-read partition table */ | |
| 150 | +#define TARGET_BLKGETSIZE TARGET_IO(0x12,96) /* return device size /512 (long *arg) */ | |
| 151 | +#define TARGET_BLKFLSBUF TARGET_IO(0x12,97) /* flush buffer cache */ | |
| 152 | +#define TARGET_BLKRASET TARGET_IO(0x12,98) /* Set read ahead for block device */ | |
| 153 | +#define TARGET_BLKRAGET TARGET_IO(0x12,99) /* get current read ahead setting */ | |
| 154 | +#define TARGET_BLKFRASET TARGET_IO(0x12,100)/* set filesystem (mm/filemap.c) read-ahead */ | |
| 155 | +#define TARGET_BLKFRAGET TARGET_IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */ | |
| 156 | +#define TARGET_BLKSECTSET TARGET_IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */ | |
| 157 | +#define TARGET_BLKSECTGET TARGET_IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */ | |
| 158 | +#define TARGET_BLKSSZGET TARGET_IO(0x12,104)/* get block device sector size */ | |
| 159 | +/* A jump here: 108-111 have been used for various private purposes. */ | |
| 160 | +#define TARGET_BLKBSZGET TARGET_IOR(0x12,112,sizeof(int)) | |
| 161 | +#define TARGET_BLKBSZSET TARGET_IOW(0x12,113,sizeof(int)) | |
| 162 | +#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */ | |
| 163 | +#define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */ | |
| 164 | +#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */ | |
| 165 | + | |
| 166 | +/* cdrom commands */ | |
| 167 | +#define TARGET_CDROMPAUSE 0x5301 /* Pause Audio Operation */ | |
| 168 | +#define TARGET_CDROMRESUME 0x5302 /* Resume paused Audio Operation */ | |
| 169 | +#define TARGET_CDROMPLAYMSF 0x5303 /* Play Audio MSF (struct cdrom_msf) */ | |
| 170 | +#define TARGET_CDROMPLAYTRKIND 0x5304 /* Play Audio Track/index | |
| 171 | + (struct cdrom_ti) */ | |
| 172 | +#define TARGET_CDROMREADTOCHDR 0x5305 /* Read TOC header | |
| 173 | + (struct cdrom_tochdr) */ | |
| 174 | +#define TARGET_CDROMREADTOCENTRY 0x5306 /* Read TOC entry | |
| 175 | + (struct cdrom_tocentry) */ | |
| 176 | +#define TARGET_CDROMSTOP 0x5307 /* Stop the cdrom drive */ | |
| 177 | +#define TARGET_CDROMSTART 0x5308 /* Start the cdrom drive */ | |
| 178 | +#define TARGET_CDROMEJECT 0x5309 /* Ejects the cdrom media */ | |
| 179 | +#define TARGET_CDROMVOLCTRL 0x530a /* Control output volume | |
| 180 | + (struct cdrom_volctrl) */ | |
| 181 | +#define TARGET_CDROMSUBCHNL 0x530b /* Read subchannel data | |
| 182 | + (struct cdrom_subchnl) */ | |
| 183 | +#define TARGET_CDROMREADMODE2 0x530c /* Read TARGET_CDROM mode 2 data (2336 Bytes) | |
| 184 | + (struct cdrom_read) */ | |
| 185 | +#define TARGET_CDROMREADMODE1 0x530d /* Read TARGET_CDROM mode 1 data (2048 Bytes) | |
| 186 | + (struct cdrom_read) */ | |
| 187 | +#define TARGET_CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */ | |
| 188 | +#define TARGET_CDROMEJECT_SW 0x530f /* enable(1)/disable(0) auto-ejecting */ | |
| 189 | +#define TARGET_CDROMMULTISESSION 0x5310 /* Obtain the start-of-last-session | |
| 190 | + address of multi session disks | |
| 191 | + (struct cdrom_multisession) */ | |
| 192 | +#define TARGET_CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code" | |
| 193 | + if available (struct cdrom_mcn) */ | |
| 194 | +#define TARGET_CDROM_GET_UPC TARGET_CDROM_GET_MCN /* This one is depricated, | |
| 195 | + but here anyway for compatability */ | |
| 196 | +#define TARGET_CDROMRESET 0x5312 /* hard-reset the drive */ | |
| 197 | +#define TARGET_CDROMVOLREAD 0x5313 /* Get the drive's volume setting | |
| 198 | + (struct cdrom_volctrl) */ | |
| 199 | +#define TARGET_CDROMREADRAW 0x5314 /* read data in raw mode (2352 Bytes) | |
| 200 | + (struct cdrom_read) */ | |
| 201 | +/* | |
| 202 | + * These ioctls are used only used in aztcd.c and optcd.c | |
| 203 | + */ | |
| 204 | +#define TARGET_CDROMREADCOOKED 0x5315 /* read data in cooked mode */ | |
| 205 | +#define TARGET_CDROMSEEK 0x5316 /* seek msf address */ | |
| 206 | + | |
| 207 | +/* | |
| 208 | + * This ioctl is only used by the scsi-cd driver. | |
| 209 | + It is for playing audio in logical block addressing mode. | |
| 210 | + */ | |
| 211 | +#define TARGET_CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */ | |
| 212 | + | |
| 213 | +/* | |
| 214 | + * These ioctls are only used in optcd.c | |
| 215 | + */ | |
| 216 | +#define TARGET_CDROMREADALL 0x5318 /* read all 2646 bytes */ | |
| 217 | + | |
| 218 | +/* | |
| 219 | + * These ioctls are (now) only in ide-cd.c for controlling | |
| 220 | + * drive spindown time. They should be implemented in the | |
| 221 | + * Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10, | |
| 222 | + * GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE... | |
| 223 | + * -Erik | |
| 224 | + */ | |
| 225 | +#define TARGET_CDROMGETSPINDOWN 0x531d | |
| 226 | +#define TARGET_CDROMSETSPINDOWN 0x531e | |
| 227 | + | |
| 228 | +/* | |
| 229 | + * These ioctls are implemented through the uniform CD-ROM driver | |
| 230 | + * They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM | |
| 231 | + * drivers are eventually ported to the uniform CD-ROM driver interface. | |
| 232 | + */ | |
| 233 | +#define TARGET_CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ | |
| 234 | +#define TARGET_CDROM_SET_OPTIONS 0x5320 /* Set behavior options */ | |
| 235 | +#define TARGET_CDROM_CLEAR_OPTIONS 0x5321 /* Clear behavior options */ | |
| 236 | +#define TARGET_CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */ | |
| 237 | +#define TARGET_CDROM_SELECT_DISC 0x5323 /* Select disc (for juke-boxes) */ | |
| 238 | +#define TARGET_CDROM_MEDIA_CHANGED 0x5325 /* Check is media changed */ | |
| 239 | +#define TARGET_CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ | |
| 240 | +#define TARGET_CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */ | |
| 241 | +#define TARGET_CDROM_CHANGER_NSLOTS 0x5328 /* Get number of slots */ | |
| 242 | +#define TARGET_CDROM_LOCKDOOR 0x5329 /* lock or unlock door */ | |
| 243 | +#define TARGET_CDROM_DEBUG 0x5330 /* Turn debug messages on/off */ | |
| 244 | +#define TARGET_CDROM_GET_CAPABILITY 0x5331 /* get capabilities */ | |
| 245 | + | |
| 246 | +/* Note that scsi/scsi_ioctl.h also uses 0x5382 - 0x5386. | |
| 247 | + * Future CDROM ioctls should be kept below 0x537F | |
| 248 | + */ | |
| 249 | + | |
| 250 | +/* This ioctl is only used by sbpcd at the moment */ | |
| 251 | +#define TARGET_CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */ | |
| 252 | + /* conflict with SCSI_IOCTL_GET_IDLUN */ | |
| 253 | + | |
| 254 | +/* DVD-ROM Specific ioctls */ | |
| 255 | +#define TARGET_DVD_READ_STRUCT 0x5390 /* Read structure */ | |
| 256 | +#define TARGET_DVD_WRITE_STRUCT 0x5391 /* Write structure */ | |
| 257 | +#define TARGET_DVD_AUTH 0x5392 /* Authentication */ | |
| 258 | + | |
| 259 | +#define TARGET_CDROM_SEND_PACKET 0x5393 /* send a packet to the drive */ | |
| 260 | +#define TARGET_CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */ | |
| 261 | +#define TARGET_CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */ | |
| 262 | + | |
| 263 | +/* HD commands */ | |
| 264 | + | |
| 265 | +/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */ | |
| 266 | +#define TARGET_HDIO_GETGEO 0x0301 /* get device geometry */ | |
| 267 | +#define TARGET_HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */ | |
| 268 | +#define TARGET_HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */ | |
| 269 | +#define TARGET_HDIO_GET_IDENTITY 0x0307 /* get IDE identification info */ | |
| 270 | +#define TARGET_HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */ | |
| 271 | +#define TARGET_HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */ | |
| 272 | +#define TARGET_HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */ | |
| 273 | +#define TARGET_HDIO_GET_DMA 0x030b /* get use-dma flag */ | |
| 274 | +#define TARGET_HDIO_DRIVE_CMD 0x031f /* execute a special drive command */ | |
| 275 | + | |
| 276 | +/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */ | |
| 277 | +#define TARGET_HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */ | |
| 278 | +#define TARGET_HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */ | |
| 279 | +#define TARGET_HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */ | |
| 280 | +#define TARGET_HDIO_SET_32BIT 0x0324 /* change io_32bit flags */ | |
| 281 | +#define TARGET_HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */ | |
| 282 | +#define TARGET_HDIO_SET_DMA 0x0326 /* change use-dma flag */ | |
| 283 | +#define TARGET_HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */ | ... | ... |
linux-user/syscall_types.h
0 → 100644
| 1 | +STRUCT_SPECIAL(termios) | |
| 2 | + | |
| 3 | +STRUCT(winsize, | |
| 4 | + TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT) | |
| 5 | + | |
| 6 | +STRUCT(serial_multiport_struct, | |
| 7 | + TYPE_INT, TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_CHAR, TYPE_CHAR, | |
| 8 | + TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, | |
| 9 | + MK_ARRAY(TYPE_INT, 32)) | |
| 10 | + | |
| 11 | +STRUCT(serial_icounter_struct, | |
| 12 | + TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, MK_ARRAY(TYPE_INT, 16)) | |
| 13 | + | |
| 14 | +STRUCT(sockaddr, | |
| 15 | + TYPE_SHORT, MK_ARRAY(TYPE_CHAR, 14)) | |
| 16 | + | |
| 17 | +STRUCT(rtentry, | |
| 18 | + TYPE_ULONG, MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), | |
| 19 | + TYPE_SHORT, TYPE_SHORT, TYPE_ULONG, TYPE_PTRVOID, TYPE_SHORT, TYPE_PTRVOID, | |
| 20 | + TYPE_ULONG, TYPE_ULONG, TYPE_SHORT) | |
| 21 | + | |
| 22 | +STRUCT(ifmap, | |
| 23 | + TYPE_ULONG, TYPE_ULONG, TYPE_SHORT, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, | |
| 24 | + /* Spare 3 bytes */ | |
| 25 | + TYPE_CHAR, TYPE_CHAR, TYPE_CHAR) | |
| 26 | + | |
| 27 | +/* The *_ifreq_list arrays deal with the fact that struct ifreq has unions */ | |
| 28 | + | |
| 29 | +STRUCT(sockaddr_ifreq, | |
| 30 | + MK_ARRAY(TYPE_CHAR, IFNAMSIZ), MK_STRUCT(STRUCT_sockaddr)) | |
| 31 | + | |
| 32 | +STRUCT(short_ifreq, | |
| 33 | + MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_SHORT) | |
| 34 | + | |
| 35 | +STRUCT(int_ifreq, | |
| 36 | + MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_INT) | |
| 37 | + | |
| 38 | +STRUCT(ifmap_ifreq, | |
| 39 | + MK_ARRAY(TYPE_CHAR, IFNAMSIZ), MK_STRUCT(STRUCT_ifmap)) | |
| 40 | + | |
| 41 | +STRUCT(char_ifreq, | |
| 42 | + MK_ARRAY(TYPE_CHAR, IFNAMSIZ), | |
| 43 | + MK_ARRAY(TYPE_CHAR, IFNAMSIZ)) | |
| 44 | + | |
| 45 | +STRUCT(ptr_ifreq, | |
| 46 | + MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_PTRVOID) | |
| 47 | + | |
| 48 | +STRUCT(ifconf, | |
| 49 | + TYPE_INT, TYPE_PTRVOID) | |
| 50 | + | |
| 51 | +STRUCT(arpreq, | |
| 52 | + MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), TYPE_INT, MK_STRUCT(STRUCT_sockaddr), | |
| 53 | + MK_ARRAY(TYPE_CHAR, 16)) | |
| 54 | + | |
| 55 | +STRUCT(arpreq_old, | |
| 56 | + MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), TYPE_INT, MK_STRUCT(STRUCT_sockaddr)) | |
| 57 | + | |
| 58 | +STRUCT(cdrom_read_audio, | |
| 59 | + TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_PTRVOID, | |
| 60 | + TYPE_NULL) | |
| 61 | + | |
| 62 | +STRUCT(hd_geometry, | |
| 63 | + TYPE_CHAR, TYPE_CHAR, TYPE_SHORT, TYPE_ULONG) | |
| 64 | + | ... | ... |
syscall-i386.h
0 → 100644
| 1 | +/* from linux/unistd.h */ | |
| 2 | + | |
| 3 | +#define TARGET_NR_exit 1 | |
| 4 | +#define TARGET_NR_fork 2 | |
| 5 | +#define TARGET_NR_read 3 | |
| 6 | +#define TARGET_NR_write 4 | |
| 7 | +#define TARGET_NR_open 5 | |
| 8 | +#define TARGET_NR_close 6 | |
| 9 | +#define TARGET_NR_waitpid 7 | |
| 10 | +#define TARGET_NR_creat 8 | |
| 11 | +#define TARGET_NR_link 9 | |
| 12 | +#define TARGET_NR_unlink 10 | |
| 13 | +#define TARGET_NR_execve 11 | |
| 14 | +#define TARGET_NR_chdir 12 | |
| 15 | +#define TARGET_NR_time 13 | |
| 16 | +#define TARGET_NR_mknod 14 | |
| 17 | +#define TARGET_NR_chmod 15 | |
| 18 | +#define TARGET_NR_lchown 16 | |
| 19 | +#define TARGET_NR_break 17 | |
| 20 | +#define TARGET_NR_oldstat 18 | |
| 21 | +#define TARGET_NR_lseek 19 | |
| 22 | +#define TARGET_NR_getpid 20 | |
| 23 | +#define TARGET_NR_mount 21 | |
| 24 | +#define TARGET_NR_umount 22 | |
| 25 | +#define TARGET_NR_setuid 23 | |
| 26 | +#define TARGET_NR_getuid 24 | |
| 27 | +#define TARGET_NR_stime 25 | |
| 28 | +#define TARGET_NR_ptrace 26 | |
| 29 | +#define TARGET_NR_alarm 27 | |
| 30 | +#define TARGET_NR_oldfstat 28 | |
| 31 | +#define TARGET_NR_pause 29 | |
| 32 | +#define TARGET_NR_utime 30 | |
| 33 | +#define TARGET_NR_stty 31 | |
| 34 | +#define TARGET_NR_gtty 32 | |
| 35 | +#define TARGET_NR_access 33 | |
| 36 | +#define TARGET_NR_nice 34 | |
| 37 | +#define TARGET_NR_ftime 35 | |
| 38 | +#define TARGET_NR_sync 36 | |
| 39 | +#define TARGET_NR_kill 37 | |
| 40 | +#define TARGET_NR_rename 38 | |
| 41 | +#define TARGET_NR_mkdir 39 | |
| 42 | +#define TARGET_NR_rmdir 40 | |
| 43 | +#define TARGET_NR_dup 41 | |
| 44 | +#define TARGET_NR_pipe 42 | |
| 45 | +#define TARGET_NR_times 43 | |
| 46 | +#define TARGET_NR_prof 44 | |
| 47 | +#define TARGET_NR_brk 45 | |
| 48 | +#define TARGET_NR_setgid 46 | |
| 49 | +#define TARGET_NR_getgid 47 | |
| 50 | +#define TARGET_NR_signal 48 | |
| 51 | +#define TARGET_NR_geteuid 49 | |
| 52 | +#define TARGET_NR_getegid 50 | |
| 53 | +#define TARGET_NR_acct 51 | |
| 54 | +#define TARGET_NR_umount2 52 | |
| 55 | +#define TARGET_NR_lock 53 | |
| 56 | +#define TARGET_NR_ioctl 54 | |
| 57 | +#define TARGET_NR_fcntl 55 | |
| 58 | +#define TARGET_NR_mpx 56 | |
| 59 | +#define TARGET_NR_setpgid 57 | |
| 60 | +#define TARGET_NR_ulimit 58 | |
| 61 | +#define TARGET_NR_oldolduname 59 | |
| 62 | +#define TARGET_NR_umask 60 | |
| 63 | +#define TARGET_NR_chroot 61 | |
| 64 | +#define TARGET_NR_ustat 62 | |
| 65 | +#define TARGET_NR_dup2 63 | |
| 66 | +#define TARGET_NR_getppid 64 | |
| 67 | +#define TARGET_NR_getpgrp 65 | |
| 68 | +#define TARGET_NR_setsid 66 | |
| 69 | +#define TARGET_NR_sigaction 67 | |
| 70 | +#define TARGET_NR_sgetmask 68 | |
| 71 | +#define TARGET_NR_ssetmask 69 | |
| 72 | +#define TARGET_NR_setreuid 70 | |
| 73 | +#define TARGET_NR_setregid 71 | |
| 74 | +#define TARGET_NR_sigsuspend 72 | |
| 75 | +#define TARGET_NR_sigpending 73 | |
| 76 | +#define TARGET_NR_sethostname 74 | |
| 77 | +#define TARGET_NR_setrlimit 75 | |
| 78 | +#define TARGET_NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ | |
| 79 | +#define TARGET_NR_getrusage 77 | |
| 80 | +#define TARGET_NR_gettimeofday 78 | |
| 81 | +#define TARGET_NR_settimeofday 79 | |
| 82 | +#define TARGET_NR_getgroups 80 | |
| 83 | +#define TARGET_NR_setgroups 81 | |
| 84 | +#define TARGET_NR_select 82 | |
| 85 | +#define TARGET_NR_symlink 83 | |
| 86 | +#define TARGET_NR_oldlstat 84 | |
| 87 | +#define TARGET_NR_readlink 85 | |
| 88 | +#define TARGET_NR_uselib 86 | |
| 89 | +#define TARGET_NR_swapon 87 | |
| 90 | +#define TARGET_NR_reboot 88 | |
| 91 | +#define TARGET_NR_readdir 89 | |
| 92 | +#define TARGET_NR_mmap 90 | |
| 93 | +#define TARGET_NR_munmap 91 | |
| 94 | +#define TARGET_NR_truncate 92 | |
| 95 | +#define TARGET_NR_ftruncate 93 | |
| 96 | +#define TARGET_NR_fchmod 94 | |
| 97 | +#define TARGET_NR_fchown 95 | |
| 98 | +#define TARGET_NR_getpriority 96 | |
| 99 | +#define TARGET_NR_setpriority 97 | |
| 100 | +#define TARGET_NR_profil 98 | |
| 101 | +#define TARGET_NR_statfs 99 | |
| 102 | +#define TARGET_NR_fstatfs 100 | |
| 103 | +#define TARGET_NR_ioperm 101 | |
| 104 | +#define TARGET_NR_socketcall 102 | |
| 105 | +#define TARGET_NR_syslog 103 | |
| 106 | +#define TARGET_NR_setitimer 104 | |
| 107 | +#define TARGET_NR_getitimer 105 | |
| 108 | +#define TARGET_NR_stat 106 | |
| 109 | +#define TARGET_NR_lstat 107 | |
| 110 | +#define TARGET_NR_fstat 108 | |
| 111 | +#define TARGET_NR_olduname 109 | |
| 112 | +#define TARGET_NR_iopl 110 | |
| 113 | +#define TARGET_NR_vhangup 111 | |
| 114 | +#define TARGET_NR_idle 112 | |
| 115 | +#define TARGET_NR_vm86old 113 | |
| 116 | +#define TARGET_NR_wait4 114 | |
| 117 | +#define TARGET_NR_swapoff 115 | |
| 118 | +#define TARGET_NR_sysinfo 116 | |
| 119 | +#define TARGET_NR_ipc 117 | |
| 120 | +#define TARGET_NR_fsync 118 | |
| 121 | +#define TARGET_NR_sigreturn 119 | |
| 122 | +#define TARGET_NR_clone 120 | |
| 123 | +#define TARGET_NR_setdomainname 121 | |
| 124 | +#define TARGET_NR_uname 122 | |
| 125 | +#define TARGET_NR_modify_ldt 123 | |
| 126 | +#define TARGET_NR_adjtimex 124 | |
| 127 | +#define TARGET_NR_mprotect 125 | |
| 128 | +#define TARGET_NR_sigprocmask 126 | |
| 129 | +#define TARGET_NR_create_module 127 | |
| 130 | +#define TARGET_NR_init_module 128 | |
| 131 | +#define TARGET_NR_delete_module 129 | |
| 132 | +#define TARGET_NR_get_kernel_syms 130 | |
| 133 | +#define TARGET_NR_quotactl 131 | |
| 134 | +#define TARGET_NR_getpgid 132 | |
| 135 | +#define TARGET_NR_fchdir 133 | |
| 136 | +#define TARGET_NR_bdflush 134 | |
| 137 | +#define TARGET_NR_sysfs 135 | |
| 138 | +#define TARGET_NR_personality 136 | |
| 139 | +#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */ | |
| 140 | +#define TARGET_NR_setfsuid 138 | |
| 141 | +#define TARGET_NR_setfsgid 139 | |
| 142 | +#define TARGET_NR__llseek 140 | |
| 143 | +#define TARGET_NR_getdents 141 | |
| 144 | +#define TARGET_NR__newselect 142 | |
| 145 | +#define TARGET_NR_flock 143 | |
| 146 | +#define TARGET_NR_msync 144 | |
| 147 | +#define TARGET_NR_readv 145 | |
| 148 | +#define TARGET_NR_writev 146 | |
| 149 | +#define TARGET_NR_getsid 147 | |
| 150 | +#define TARGET_NR_fdatasync 148 | |
| 151 | +#define TARGET_NR__sysctl 149 | |
| 152 | +#define TARGET_NR_mlock 150 | |
| 153 | +#define TARGET_NR_munlock 151 | |
| 154 | +#define TARGET_NR_mlockall 152 | |
| 155 | +#define TARGET_NR_munlockall 153 | |
| 156 | +#define TARGET_NR_sched_setparam 154 | |
| 157 | +#define TARGET_NR_sched_getparam 155 | |
| 158 | +#define TARGET_NR_sched_setscheduler 156 | |
| 159 | +#define TARGET_NR_sched_getscheduler 157 | |
| 160 | +#define TARGET_NR_sched_yield 158 | |
| 161 | +#define TARGET_NR_sched_get_priority_max 159 | |
| 162 | +#define TARGET_NR_sched_get_priority_min 160 | |
| 163 | +#define TARGET_NR_sched_rr_get_interval 161 | |
| 164 | +#define TARGET_NR_nanosleep 162 | |
| 165 | +#define TARGET_NR_mremap 163 | |
| 166 | +#define TARGET_NR_setresuid 164 | |
| 167 | +#define TARGET_NR_getresuid 165 | |
| 168 | +#define TARGET_NR_vm86 166 | |
| 169 | +#define TARGET_NR_query_module 167 | |
| 170 | +#define TARGET_NR_poll 168 | |
| 171 | +#define TARGET_NR_nfsservctl 169 | |
| 172 | +#define TARGET_NR_setresgid 170 | |
| 173 | +#define TARGET_NR_getresgid 171 | |
| 174 | +#define TARGET_NR_prctl 172 | |
| 175 | +#define TARGET_NR_rt_sigreturn 173 | |
| 176 | +#define TARGET_NR_rt_sigaction 174 | |
| 177 | +#define TARGET_NR_rt_sigprocmask 175 | |
| 178 | +#define TARGET_NR_rt_sigpending 176 | |
| 179 | +#define TARGET_NR_rt_sigtimedwait 177 | |
| 180 | +#define TARGET_NR_rt_sigqueueinfo 178 | |
| 181 | +#define TARGET_NR_rt_sigsuspend 179 | |
| 182 | +#define TARGET_NR_pread 180 | |
| 183 | +#define TARGET_NR_pwrite 181 | |
| 184 | +#define TARGET_NR_chown 182 | |
| 185 | +#define TARGET_NR_getcwd 183 | |
| 186 | +#define TARGET_NR_capget 184 | |
| 187 | +#define TARGET_NR_capset 185 | |
| 188 | +#define TARGET_NR_sigaltstack 186 | |
| 189 | +#define TARGET_NR_sendfile 187 | |
| 190 | +#define TARGET_NR_getpmsg 188 /* some people actually want streams */ | |
| 191 | +#define TARGET_NR_putpmsg 189 /* some people actually want streams */ | |
| 192 | +#define TARGET_NR_vfork 190 | |
| 193 | +#define TARGET_NR_ugetrlimit 191 /* SuS compliant getrlimit */ | |
| 194 | +#define TARGET_NR_mmap2 192 | |
| 195 | +#define TARGET_NR_truncate64 193 | |
| 196 | +#define TARGET_NR_ftruncate64 194 | |
| 197 | +#define TARGET_NR_stat64 195 | |
| 198 | +#define TARGET_NR_lstat64 196 | |
| 199 | +#define TARGET_NR_fstat64 197 | |
| 200 | +#define TARGET_NR_lchown32 198 | |
| 201 | +#define TARGET_NR_getuid32 199 | |
| 202 | +#define TARGET_NR_getgid32 200 | |
| 203 | +#define TARGET_NR_geteuid32 201 | |
| 204 | +#define TARGET_NR_getegid32 202 | |
| 205 | +#define TARGET_NR_setreuid32 203 | |
| 206 | +#define TARGET_NR_setregid32 204 | |
| 207 | +#define TARGET_NR_getgroups32 205 | |
| 208 | +#define TARGET_NR_setgroups32 206 | |
| 209 | +#define TARGET_NR_fchown32 207 | |
| 210 | +#define TARGET_NR_setresuid32 208 | |
| 211 | +#define TARGET_NR_getresuid32 209 | |
| 212 | +#define TARGET_NR_setresgid32 210 | |
| 213 | +#define TARGET_NR_getresgid32 211 | |
| 214 | +#define TARGET_NR_chown32 212 | |
| 215 | +#define TARGET_NR_setuid32 213 | |
| 216 | +#define TARGET_NR_setgid32 214 | |
| 217 | +#define TARGET_NR_setfsuid32 215 | |
| 218 | +#define TARGET_NR_setfsgid32 216 | |
| 219 | +#define TARGET_NR_pivot_root 217 | |
| 220 | +#define TARGET_NR_mincore 218 | |
| 221 | +#define TARGET_NR_madvise 219 | |
| 222 | +#define TARGET_NR_madvise1 219 /* delete when C lib stub is removed */ | |
| 223 | +#define TARGET_NR_getdents64 220 | |
| 224 | +#define TARGET_NR_fcntl64 221 | |
| 225 | +#define TARGET_NR_security 223 /* syscall for security modules */ | |
| 226 | +#define TARGET_NR_gettid 224 | |
| 227 | +#define TARGET_NR_readahead 225 | |
| 228 | +#define TARGET_NR_setxattr 226 | |
| 229 | +#define TARGET_NR_lsetxattr 227 | |
| 230 | +#define TARGET_NR_fsetxattr 228 | |
| 231 | +#define TARGET_NR_getxattr 229 | |
| 232 | +#define TARGET_NR_lgetxattr 230 | |
| 233 | +#define TARGET_NR_fgetxattr 231 | |
| 234 | +#define TARGET_NR_listxattr 232 | |
| 235 | +#define TARGET_NR_llistxattr 233 | |
| 236 | +#define TARGET_NR_flistxattr 234 | |
| 237 | +#define TARGET_NR_removexattr 235 | |
| 238 | +#define TARGET_NR_lremovexattr 236 | |
| 239 | +#define TARGET_NR_fremovexattr 237 | |
| 240 | + | |
| 241 | +#define TARGET_SIG_BLOCK 0 /* for blocking signals */ | |
| 242 | +#define TARGET_SIG_UNBLOCK 1 /* for unblocking signals */ | |
| 243 | +#define TARGET_SIG_SETMASK 2 /* for setting the signal mask */ | |
| 244 | + | |
| 245 | +struct target_stat { | |
| 246 | + unsigned short st_dev; | |
| 247 | + unsigned short __pad1; | |
| 248 | + unsigned long st_ino; | |
| 249 | + unsigned short st_mode; | |
| 250 | + unsigned short st_nlink; | |
| 251 | + unsigned short st_uid; | |
| 252 | + unsigned short st_gid; | |
| 253 | + unsigned short st_rdev; | |
| 254 | + unsigned short __pad2; | |
| 255 | + unsigned long st_size; | |
| 256 | + unsigned long st_blksize; | |
| 257 | + unsigned long st_blocks; | |
| 258 | + unsigned long st_atime; | |
| 259 | + unsigned long __unused1; | |
| 260 | + unsigned long st_mtime; | |
| 261 | + unsigned long __unused2; | |
| 262 | + unsigned long st_ctime; | |
| 263 | + unsigned long __unused3; | |
| 264 | + unsigned long __unused4; | |
| 265 | + unsigned long __unused5; | |
| 266 | +}; | |
| 267 | + | |
| 268 | +/* This matches struct stat64 in glibc2.1, hence the absolutely | |
| 269 | + * insane amounts of padding around dev_t's. | |
| 270 | + */ | |
| 271 | +struct target_stat64 { | |
| 272 | + unsigned short st_dev; | |
| 273 | + unsigned char __pad0[10]; | |
| 274 | + | |
| 275 | +#define STAT64_HAS_BROKEN_ST_INO 1 | |
| 276 | + unsigned long __st_ino; | |
| 277 | + | |
| 278 | + unsigned int st_mode; | |
| 279 | + unsigned int st_nlink; | |
| 280 | + | |
| 281 | + unsigned long st_uid; | |
| 282 | + unsigned long st_gid; | |
| 283 | + | |
| 284 | + unsigned short st_rdev; | |
| 285 | + unsigned char __pad3[10]; | |
| 286 | + | |
| 287 | + long long st_size; | |
| 288 | + unsigned long st_blksize; | |
| 289 | + | |
| 290 | + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ | |
| 291 | + unsigned long __pad4; /* future possible st_blocks high bits */ | |
| 292 | + | |
| 293 | + unsigned long st_atime; | |
| 294 | + unsigned long __pad5; | |
| 295 | + | |
| 296 | + unsigned long st_mtime; | |
| 297 | + unsigned long __pad6; | |
| 298 | + | |
| 299 | + unsigned long st_ctime; | |
| 300 | + unsigned long __pad7; /* will be high 32 bits of ctime someday */ | |
| 301 | + | |
| 302 | + unsigned long long st_ino; | |
| 303 | +}; | |
| 304 | + | |
| 305 | +typedef unsigned long old_sigset_t; /* at least 32 bits */ | |
| 306 | + | |
| 307 | +struct target_old_sigaction { | |
| 308 | + target_ulong _sa_handler; | |
| 309 | + target_ulong sa_mask; | |
| 310 | + target_ulong sa_flags; | |
| 311 | + void (*sa_restorer)(void); | |
| 312 | +}; | |
| 313 | + | |
| 314 | +struct target_sigaction { | |
| 315 | + target_ulong _sa_handler; | |
| 316 | + target_sigset_t sa_mask; | |
| 317 | + target_ulong sa_flags; | |
| 318 | + target_ulong sa_restorer; | |
| 319 | +}; | |
| 320 | + | |
| 321 | +typedef union target_sigval { | |
| 322 | + int sival_int; | |
| 323 | + void *sival_ptr; | |
| 324 | +} target_sigval_t; | |
| 325 | + | |
| 326 | +#define TARGET_SI_MAX_SIZE 128 | |
| 327 | +#define TARGET_SI_PAD_SIZE ((TARGET_SI_MAX_SIZE/sizeof(int)) - 3) | |
| 328 | + | |
| 329 | +typedef struct target_siginfo { | |
| 330 | + int si_signo; | |
| 331 | + int si_errno; | |
| 332 | + int si_code; | |
| 333 | + | |
| 334 | + union { | |
| 335 | + int _pad[TARGET_SI_PAD_SIZE]; | |
| 336 | + | |
| 337 | + /* kill() */ | |
| 338 | + struct { | |
| 339 | + pid_t _pid; /* sender's pid */ | |
| 340 | + uid_t _uid; /* sender's uid */ | |
| 341 | + } _kill; | |
| 342 | + | |
| 343 | + /* POSIX.1b timers */ | |
| 344 | + struct { | |
| 345 | + unsigned int _timer1; | |
| 346 | + unsigned int _timer2; | |
| 347 | + } _timer; | |
| 348 | + | |
| 349 | + /* POSIX.1b signals */ | |
| 350 | + struct { | |
| 351 | + pid_t _pid; /* sender's pid */ | |
| 352 | + uid_t _uid; /* sender's uid */ | |
| 353 | + sigval_t _sigval; | |
| 354 | + } _rt; | |
| 355 | + | |
| 356 | + /* SIGCHLD */ | |
| 357 | + struct { | |
| 358 | + pid_t _pid; /* which child */ | |
| 359 | + uid_t _uid; /* sender's uid */ | |
| 360 | + int _status; /* exit code */ | |
| 361 | + clock_t _utime; | |
| 362 | + clock_t _stime; | |
| 363 | + } _sigchld; | |
| 364 | + | |
| 365 | + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | |
| 366 | + struct { | |
| 367 | + void *_addr; /* faulting insn/memory ref. */ | |
| 368 | + } _sigfault; | |
| 369 | + | |
| 370 | + /* SIGPOLL */ | |
| 371 | + struct { | |
| 372 | + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | |
| 373 | + int _fd; | |
| 374 | + } _sigpoll; | |
| 375 | + } _sifields; | |
| 376 | +} target_siginfo_t; | |
| 377 | + | |
| 378 | +/* ioctls */ | |
| 379 | + | |
| 380 | +/* | |
| 381 | + * The following is for compatibility across the various Linux | |
| 382 | + * platforms. The i386 ioctl numbering scheme doesn't really enforce | |
| 383 | + * a type field. De facto, however, the top 8 bits of the lower 16 | |
| 384 | + * bits are indeed used as a type field, so we might just as well make | |
| 385 | + * this explicit here. Please be sure to use the decoding macros | |
| 386 | + * below from now on. | |
| 387 | + */ | |
| 388 | +#define TARGET_IOC_NRBITS 8 | |
| 389 | +#define TARGET_IOC_TYPEBITS 8 | |
| 390 | +#define TARGET_IOC_SIZEBITS 14 | |
| 391 | +#define TARGET_IOC_DIRBITS 2 | |
| 392 | + | |
| 393 | +#define TARGET_IOC_NRMASK ((1 << TARGET_IOC_NRBITS)-1) | |
| 394 | +#define TARGET_IOC_TYPEMASK ((1 << TARGET_IOC_TYPEBITS)-1) | |
| 395 | +#define TARGET_IOC_SIZEMASK ((1 << TARGET_IOC_SIZEBITS)-1) | |
| 396 | +#define TARGET_IOC_DIRMASK ((1 << TARGET_IOC_DIRBITS)-1) | |
| 397 | + | |
| 398 | +#define TARGET_IOC_NRSHIFT 0 | |
| 399 | +#define TARGET_IOC_TYPESHIFT (TARGET_IOC_NRSHIFT+TARGET_IOC_NRBITS) | |
| 400 | +#define TARGET_IOC_SIZESHIFT (TARGET_IOC_TYPESHIFT+TARGET_IOC_TYPEBITS) | |
| 401 | +#define TARGET_IOC_DIRSHIFT (TARGET_IOC_SIZESHIFT+TARGET_IOC_SIZEBITS) | |
| 402 | + | |
| 403 | +/* | |
| 404 | + * Direction bits. | |
| 405 | + */ | |
| 406 | +#define TARGET_IOC_NONE 0U | |
| 407 | +#define TARGET_IOC_WRITE 1U | |
| 408 | +#define TARGET_IOC_READ 2U | |
| 409 | + | |
| 410 | +#define TARGET_IOC(dir,type,nr,size) \ | |
| 411 | + (((dir) << TARGET_IOC_DIRSHIFT) | \ | |
| 412 | + ((type) << TARGET_IOC_TYPESHIFT) | \ | |
| 413 | + ((nr) << TARGET_IOC_NRSHIFT) | \ | |
| 414 | + ((size) << TARGET_IOC_SIZESHIFT)) | |
| 415 | + | |
| 416 | +/* used to create numbers */ | |
| 417 | +#define TARGET_IO(type,nr) TARGET_IOC(TARGET_IOC_NONE,(type),(nr),0) | |
| 418 | +#define TARGET_IOR(type,nr,size) TARGET_IOC(TARGET_IOC_READ,(type),(nr),sizeof(size)) | |
| 419 | +#define TARGET_IOW(type,nr,size) TARGET_IOC(TARGET_IOC_WRITE,(type),(nr),sizeof(size)) | |
| 420 | +#define TARGET_IOWR(type,nr,size) TARGET_IOC(TARGET_IOC_READ|TARGET_IOC_WRITE,(type),(nr),sizeof(size)) | |
| 421 | + | |
| 422 | +/* 0x54 is just a magic number to make these relatively unique ('T') */ | |
| 423 | + | |
| 424 | +#define TARGET_TCGETS 0x5401 | |
| 425 | +#define TARGET_TCSETS 0x5402 | |
| 426 | +#define TARGET_TCSETSW 0x5403 | |
| 427 | +#define TARGET_TCSETSF 0x5404 | |
| 428 | +#define TARGET_TCGETA 0x5405 | |
| 429 | +#define TARGET_TCSETA 0x5406 | |
| 430 | +#define TARGET_TCSETAW 0x5407 | |
| 431 | +#define TARGET_TCSETAF 0x5408 | |
| 432 | +#define TARGET_TCSBRK 0x5409 | |
| 433 | +#define TARGET_TCXONC 0x540A | |
| 434 | +#define TARGET_TCFLSH 0x540B | |
| 435 | +#define TARGET_TIOCEXCL 0x540C | |
| 436 | +#define TARGET_TIOCNXCL 0x540D | |
| 437 | +#define TARGET_TIOCSCTTY 0x540E | |
| 438 | +#define TARGET_TIOCGPGRP 0x540F | |
| 439 | +#define TARGET_TIOCSPGRP 0x5410 | |
| 440 | +#define TARGET_TIOCOUTQ 0x5411 | |
| 441 | +#define TARGET_TIOCSTI 0x5412 | |
| 442 | +#define TARGET_TIOCGWINSZ 0x5413 | |
| 443 | +#define TARGET_TIOCSWINSZ 0x5414 | |
| 444 | +#define TARGET_TIOCMGET 0x5415 | |
| 445 | +#define TARGET_TIOCMBIS 0x5416 | |
| 446 | +#define TARGET_TIOCMBIC 0x5417 | |
| 447 | +#define TARGET_TIOCMSET 0x5418 | |
| 448 | +#define TARGET_TIOCGSOFTCAR 0x5419 | |
| 449 | +#define TARGET_TIOCSSOFTCAR 0x541A | |
| 450 | +#define TARGET_FIONREAD 0x541B | |
| 451 | +#define TARGET_TIOCINQ FIONREAD | |
| 452 | +#define TARGET_TIOCLINUX 0x541C | |
| 453 | +#define TARGET_TIOCCONS 0x541D | |
| 454 | +#define TARGET_TIOCGSERIAL 0x541E | |
| 455 | +#define TARGET_TIOCSSERIAL 0x541F | |
| 456 | +#define TARGET_TIOCPKT 0x5420 | |
| 457 | +#define TARGET_FIONBIO 0x5421 | |
| 458 | +#define TARGET_TIOCNOTTY 0x5422 | |
| 459 | +#define TARGET_TIOCSETD 0x5423 | |
| 460 | +#define TARGET_TIOCGETD 0x5424 | |
| 461 | +#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ | |
| 462 | +#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */ | |
| 463 | +#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ | |
| 464 | +#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ | |
| 465 | +#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ | |
| 466 | +#define TARGET_TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ | |
| 467 | +#define TARGET_TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ | |
| 468 | + | |
| 469 | +#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ | |
| 470 | +#define TARGET_FIOCLEX 0x5451 | |
| 471 | +#define TARGET_FIOASYNC 0x5452 | |
| 472 | +#define TARGET_TIOCSERCONFIG 0x5453 | |
| 473 | +#define TARGET_TIOCSERGWILD 0x5454 | |
| 474 | +#define TARGET_TIOCSERSWILD 0x5455 | |
| 475 | +#define TARGET_TIOCGLCKTRMIOS 0x5456 | |
| 476 | +#define TARGET_TIOCSLCKTRMIOS 0x5457 | |
| 477 | +#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ | |
| 478 | +#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ | |
| 479 | +#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ | |
| 480 | +#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ | |
| 481 | + | |
| 482 | +#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ | |
| 483 | +#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ | |
| 484 | +#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ | |
| 485 | +#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ | |
| 486 | + | |
| 487 | +/* Used for packet mode */ | |
| 488 | +#define TARGET_TIOCPKT_DATA 0 | |
| 489 | +#define TARGET_TIOCPKT_FLUSHREAD 1 | |
| 490 | +#define TARGET_TIOCPKT_FLUSHWRITE 2 | |
| 491 | +#define TARGET_TIOCPKT_STOP 4 | |
| 492 | +#define TARGET_TIOCPKT_START 8 | |
| 493 | +#define TARGET_TIOCPKT_NOSTOP 16 | |
| 494 | +#define TARGET_TIOCPKT_DOSTOP 32 | |
| 495 | + | |
| 496 | +#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ | |
| 497 | + | |
| 498 | +/* from asm/termbits.h */ | |
| 499 | + | |
| 500 | +#define TARGET_NCCS 19 | |
| 501 | + | |
| 502 | +struct target_termios { | |
| 503 | + unsigned int c_iflag; /* input mode flags */ | |
| 504 | + unsigned int c_oflag; /* output mode flags */ | |
| 505 | + unsigned int c_cflag; /* control mode flags */ | |
| 506 | + unsigned int c_lflag; /* local mode flags */ | |
| 507 | + unsigned char c_line; /* line discipline */ | |
| 508 | + unsigned char c_cc[TARGET_NCCS]; /* control characters */ | |
| 509 | +}; | |
| 510 | + | |
| 511 | +/* c_iflag bits */ | |
| 512 | +#define TARGET_IGNBRK 0000001 | |
| 513 | +#define TARGET_BRKINT 0000002 | |
| 514 | +#define TARGET_IGNPAR 0000004 | |
| 515 | +#define TARGET_PARMRK 0000010 | |
| 516 | +#define TARGET_INPCK 0000020 | |
| 517 | +#define TARGET_ISTRIP 0000040 | |
| 518 | +#define TARGET_INLCR 0000100 | |
| 519 | +#define TARGET_IGNCR 0000200 | |
| 520 | +#define TARGET_ICRNL 0000400 | |
| 521 | +#define TARGET_IUCLC 0001000 | |
| 522 | +#define TARGET_IXON 0002000 | |
| 523 | +#define TARGET_IXANY 0004000 | |
| 524 | +#define TARGET_IXOFF 0010000 | |
| 525 | +#define TARGET_IMAXBEL 0020000 | |
| 526 | + | |
| 527 | +/* c_oflag bits */ | |
| 528 | +#define TARGET_OPOST 0000001 | |
| 529 | +#define TARGET_OLCUC 0000002 | |
| 530 | +#define TARGET_ONLCR 0000004 | |
| 531 | +#define TARGET_OCRNL 0000010 | |
| 532 | +#define TARGET_ONOCR 0000020 | |
| 533 | +#define TARGET_ONLRET 0000040 | |
| 534 | +#define TARGET_OFILL 0000100 | |
| 535 | +#define TARGET_OFDEL 0000200 | |
| 536 | +#define TARGET_NLDLY 0000400 | |
| 537 | +#define TARGET_NL0 0000000 | |
| 538 | +#define TARGET_NL1 0000400 | |
| 539 | +#define TARGET_CRDLY 0003000 | |
| 540 | +#define TARGET_CR0 0000000 | |
| 541 | +#define TARGET_CR1 0001000 | |
| 542 | +#define TARGET_CR2 0002000 | |
| 543 | +#define TARGET_CR3 0003000 | |
| 544 | +#define TARGET_TABDLY 0014000 | |
| 545 | +#define TARGET_TAB0 0000000 | |
| 546 | +#define TARGET_TAB1 0004000 | |
| 547 | +#define TARGET_TAB2 0010000 | |
| 548 | +#define TARGET_TAB3 0014000 | |
| 549 | +#define TARGET_XTABS 0014000 | |
| 550 | +#define TARGET_BSDLY 0020000 | |
| 551 | +#define TARGET_BS0 0000000 | |
| 552 | +#define TARGET_BS1 0020000 | |
| 553 | +#define TARGET_VTDLY 0040000 | |
| 554 | +#define TARGET_VT0 0000000 | |
| 555 | +#define TARGET_VT1 0040000 | |
| 556 | +#define TARGET_FFDLY 0100000 | |
| 557 | +#define TARGET_FF0 0000000 | |
| 558 | +#define TARGET_FF1 0100000 | |
| 559 | + | |
| 560 | +/* c_cflag bit meaning */ | |
| 561 | +#define TARGET_CBAUD 0010017 | |
| 562 | +#define TARGET_B0 0000000 /* hang up */ | |
| 563 | +#define TARGET_B50 0000001 | |
| 564 | +#define TARGET_B75 0000002 | |
| 565 | +#define TARGET_B110 0000003 | |
| 566 | +#define TARGET_B134 0000004 | |
| 567 | +#define TARGET_B150 0000005 | |
| 568 | +#define TARGET_B200 0000006 | |
| 569 | +#define TARGET_B300 0000007 | |
| 570 | +#define TARGET_B600 0000010 | |
| 571 | +#define TARGET_B1200 0000011 | |
| 572 | +#define TARGET_B1800 0000012 | |
| 573 | +#define TARGET_B2400 0000013 | |
| 574 | +#define TARGET_B4800 0000014 | |
| 575 | +#define TARGET_B9600 0000015 | |
| 576 | +#define TARGET_B19200 0000016 | |
| 577 | +#define TARGET_B38400 0000017 | |
| 578 | +#define TARGET_EXTA B19200 | |
| 579 | +#define TARGET_EXTB B38400 | |
| 580 | +#define TARGET_CSIZE 0000060 | |
| 581 | +#define TARGET_CS5 0000000 | |
| 582 | +#define TARGET_CS6 0000020 | |
| 583 | +#define TARGET_CS7 0000040 | |
| 584 | +#define TARGET_CS8 0000060 | |
| 585 | +#define TARGET_CSTOPB 0000100 | |
| 586 | +#define TARGET_CREAD 0000200 | |
| 587 | +#define TARGET_PARENB 0000400 | |
| 588 | +#define TARGET_PARODD 0001000 | |
| 589 | +#define TARGET_HUPCL 0002000 | |
| 590 | +#define TARGET_CLOCAL 0004000 | |
| 591 | +#define TARGET_CBAUDEX 0010000 | |
| 592 | +#define TARGET_B57600 0010001 | |
| 593 | +#define TARGET_B115200 0010002 | |
| 594 | +#define TARGET_B230400 0010003 | |
| 595 | +#define TARGET_B460800 0010004 | |
| 596 | +#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ | |
| 597 | +#define TARGET_CRTSCTS 020000000000 /* flow control */ | |
| 598 | + | |
| 599 | +/* c_lflag bits */ | |
| 600 | +#define TARGET_ISIG 0000001 | |
| 601 | +#define TARGET_ICANON 0000002 | |
| 602 | +#define TARGET_XCASE 0000004 | |
| 603 | +#define TARGET_ECHO 0000010 | |
| 604 | +#define TARGET_ECHOE 0000020 | |
| 605 | +#define TARGET_ECHOK 0000040 | |
| 606 | +#define TARGET_ECHONL 0000100 | |
| 607 | +#define TARGET_NOFLSH 0000200 | |
| 608 | +#define TARGET_TOSTOP 0000400 | |
| 609 | +#define TARGET_ECHOCTL 0001000 | |
| 610 | +#define TARGET_ECHOPRT 0002000 | |
| 611 | +#define TARGET_ECHOKE 0004000 | |
| 612 | +#define TARGET_FLUSHO 0010000 | |
| 613 | +#define TARGET_PENDIN 0040000 | |
| 614 | +#define TARGET_IEXTEN 0100000 | |
| 615 | + | |
| 616 | +/* c_cc character offsets */ | |
| 617 | +#define TARGET_VINTR 0 | |
| 618 | +#define TARGET_VQUIT 1 | |
| 619 | +#define TARGET_VERASE 2 | |
| 620 | +#define TARGET_VKILL 3 | |
| 621 | +#define TARGET_VEOF 4 | |
| 622 | +#define TARGET_VTIME 5 | |
| 623 | +#define TARGET_VMIN 6 | |
| 624 | +#define TARGET_VSWTC 7 | |
| 625 | +#define TARGET_VSTART 8 | |
| 626 | +#define TARGET_VSTOP 9 | |
| 627 | +#define TARGET_VSUSP 10 | |
| 628 | +#define TARGET_VEOL 11 | |
| 629 | +#define TARGET_VREPRINT 12 | |
| 630 | +#define TARGET_VDISCARD 13 | |
| 631 | +#define TARGET_VWERASE 14 | |
| 632 | +#define TARGET_VLNEXT 15 | |
| 633 | +#define TARGET_VEOL2 16 | |
| 634 | + | |
| 635 | +/* soundcard defines (XXX: move them to generic file syscall_defs.h) */ | |
| 636 | + | |
| 637 | +#define TARGET_SNDCTL_COPR_HALT 0xc0144307 | |
| 638 | +#define TARGET_SNDCTL_COPR_LOAD 0xcfb04301 | |
| 639 | +#define TARGET_SNDCTL_COPR_RCODE 0xc0144303 | |
| 640 | +#define TARGET_SNDCTL_COPR_RCVMSG 0x8fa44309 | |
| 641 | +#define TARGET_SNDCTL_COPR_RDATA 0xc0144302 | |
| 642 | +#define TARGET_SNDCTL_COPR_RESET 0x00004300 | |
| 643 | +#define TARGET_SNDCTL_COPR_RUN 0xc0144306 | |
| 644 | +#define TARGET_SNDCTL_COPR_SENDMSG 0xcfa44308 | |
| 645 | +#define TARGET_SNDCTL_COPR_WCODE 0x40144305 | |
| 646 | +#define TARGET_SNDCTL_COPR_WDATA 0x40144304 | |
| 647 | +#define TARGET_SNDCTL_DSP_CHANNELS 0xc0045006 | |
| 648 | +#define TARGET_SNDCTL_DSP_GETBLKSIZE 0xc0045004 | |
| 649 | +#define TARGET_SNDCTL_DSP_GETCAPS 0x8004500f | |
| 650 | +#define TARGET_SNDCTL_DSP_GETFMTS 0x8004500b | |
| 651 | +#define TARGET_SNDCTL_DSP_GETIPTR 0x800c5011 | |
| 652 | +#define TARGET_SNDCTL_DSP_GETISPACE 0x8010500d | |
| 653 | +#define TARGET_SNDCTL_DSP_GETOPTR 0x800c5012 | |
| 654 | +#define TARGET_SNDCTL_DSP_GETOSPACE 0x8010500c | |
| 655 | +#define TARGET_SNDCTL_DSP_GETTRIGGER 0x80045010 | |
| 656 | +#define TARGET_SNDCTL_DSP_MAPINBUF 0x80085013 | |
| 657 | +#define TARGET_SNDCTL_DSP_MAPOUTBUF 0x80085014 | |
| 658 | +#define TARGET_SNDCTL_DSP_NONBLOCK 0x0000500e | |
| 659 | +#define TARGET_SNDCTL_DSP_POST 0x00005008 | |
| 660 | +#define TARGET_SNDCTL_DSP_RESET 0x00005000 | |
| 661 | +#define TARGET_SNDCTL_DSP_SAMPLESIZE 0xc0045005 | |
| 662 | +#define TARGET_SNDCTL_DSP_SETDUPLEX 0x00005016 | |
| 663 | +#define TARGET_SNDCTL_DSP_SETFMT 0xc0045005 | |
| 664 | +#define TARGET_SNDCTL_DSP_SETFRAGMENT 0xc004500a | |
| 665 | +#define TARGET_SNDCTL_DSP_SETSYNCRO 0x00005015 | |
| 666 | +#define TARGET_SNDCTL_DSP_SETTRIGGER 0x40045010 | |
| 667 | +#define TARGET_SNDCTL_DSP_SPEED 0xc0045002 | |
| 668 | +#define TARGET_SNDCTL_DSP_STEREO 0xc0045003 | |
| 669 | +#define TARGET_SNDCTL_DSP_SUBDIVIDE 0xc0045009 | |
| 670 | +#define TARGET_SNDCTL_DSP_SYNC 0x00005001 | |
| 671 | +#define TARGET_SNDCTL_FM_4OP_ENABLE 0x4004510f | |
| 672 | +#define TARGET_SNDCTL_FM_LOAD_INSTR 0x40285107 | |
| 673 | +#define TARGET_SNDCTL_MIDI_INFO 0xc074510c | |
| 674 | +#define TARGET_SNDCTL_MIDI_MPUCMD 0xc0216d02 | |
| 675 | +#define TARGET_SNDCTL_MIDI_MPUMODE 0xc0046d01 | |
| 676 | +#define TARGET_SNDCTL_MIDI_PRETIME 0xc0046d00 | |
| 677 | +#define TARGET_SNDCTL_PMGR_ACCESS 0xcfb85110 | |
| 678 | +#define TARGET_SNDCTL_PMGR_IFACE 0xcfb85001 | |
| 679 | +#define TARGET_SNDCTL_SEQ_CTRLRATE 0xc0045103 | |
| 680 | +#define TARGET_SNDCTL_SEQ_GETINCOUNT 0x80045105 | |
| 681 | +#define TARGET_SNDCTL_SEQ_GETOUTCOUNT 0x80045104 | |
| 682 | +#define TARGET_SNDCTL_SEQ_NRMIDIS 0x8004510b | |
| 683 | +#define TARGET_SNDCTL_SEQ_NRSYNTHS 0x8004510a | |
| 684 | +#define TARGET_SNDCTL_SEQ_OUTOFBAND 0x40085112 | |
| 685 | +#define TARGET_SNDCTL_SEQ_PANIC 0x00005111 | |
| 686 | +#define TARGET_SNDCTL_SEQ_PERCMODE 0x40045106 | |
| 687 | +#define TARGET_SNDCTL_SEQ_RESET 0x00005100 | |
| 688 | +#define TARGET_SNDCTL_SEQ_RESETSAMPLES 0x40045109 | |
| 689 | +#define TARGET_SNDCTL_SEQ_SYNC 0x00005101 | |
| 690 | +#define TARGET_SNDCTL_SEQ_TESTMIDI 0x40045108 | |
| 691 | +#define TARGET_SNDCTL_SEQ_THRESHOLD 0x4004510d | |
| 692 | +#define TARGET_SNDCTL_SEQ_TRESHOLD 0x4004510d | |
| 693 | +#define TARGET_SNDCTL_SYNTH_INFO 0xc08c5102 | |
| 694 | +#define TARGET_SNDCTL_SYNTH_MEMAVL 0xc004510e | |
| 695 | +#define TARGET_SNDCTL_TMR_CONTINUE 0x00005404 | |
| 696 | +#define TARGET_SNDCTL_TMR_METRONOME 0x40045407 | |
| 697 | +#define TARGET_SNDCTL_TMR_SELECT 0x40045408 | |
| 698 | +#define TARGET_SNDCTL_TMR_SOURCE 0xc0045406 | |
| 699 | +#define TARGET_SNDCTL_TMR_START 0x00005402 | |
| 700 | +#define TARGET_SNDCTL_TMR_STOP 0x00005403 | |
| 701 | +#define TARGET_SNDCTL_TMR_TEMPO 0xc0045405 | |
| 702 | +#define TARGET_SNDCTL_TMR_TIMEBASE 0xc0045401 | |
| 703 | +#define TARGET_SOUND_PCM_WRITE_FILTER 0xc0045007 | |
| 704 | +#define TARGET_SOUND_PCM_READ_RATE 0x80045002 | |
| 705 | +#define TARGET_SOUND_PCM_READ_CHANNELS 0x80045006 | |
| 706 | +#define TARGET_SOUND_PCM_READ_BITS 0x80045005 | |
| 707 | +#define TARGET_SOUND_PCM_READ_FILTER 0x80045007 | |
| 708 | +#define TARGET_SOUND_MIXER_INFO 0x80304d65 | |
| 709 | +#define TARGET_SOUND_MIXER_ACCESS 0xc0804d66 | |
| 710 | +#define TARGET_SOUND_MIXER_PRIVATE1 0xc0044d6f | |
| 711 | +#define TARGET_SOUND_MIXER_PRIVATE2 0xc0044d70 | |
| 712 | +#define TARGET_SOUND_MIXER_PRIVATE3 0xc0044d71 | |
| 713 | +#define TARGET_SOUND_MIXER_PRIVATE4 0xc0044d72 | |
| 714 | +#define TARGET_SOUND_MIXER_PRIVATE5 0xc0044d73 | |
| 715 | +#define TARGET_SOUND_MIXER_READ_VOLUME 0x80044d00 | |
| 716 | +#define TARGET_SOUND_MIXER_READ_BASS 0x80044d01 | |
| 717 | +#define TARGET_SOUND_MIXER_READ_TREBLE 0x80044d02 | |
| 718 | +#define TARGET_SOUND_MIXER_READ_SYNTH 0x80044d03 | |
| 719 | +#define TARGET_SOUND_MIXER_READ_PCM 0x80044d04 | |
| 720 | +#define TARGET_SOUND_MIXER_READ_SPEAKER 0x80044d05 | |
| 721 | +#define TARGET_SOUND_MIXER_READ_LINE 0x80044d06 | |
| 722 | +#define TARGET_SOUND_MIXER_READ_MIC 0x80044d07 | |
| 723 | +#define TARGET_SOUND_MIXER_READ_CD 0x80044d08 | |
| 724 | +#define TARGET_SOUND_MIXER_READ_IMIX 0x80044d09 | |
| 725 | +#define TARGET_SOUND_MIXER_READ_ALTPCM 0x80044d0a | |
| 726 | +#define TARGET_SOUND_MIXER_READ_RECLEV 0x80044d0b | |
| 727 | +#define TARGET_SOUND_MIXER_READ_IGAIN 0x80044d0c | |
| 728 | +#define TARGET_SOUND_MIXER_READ_OGAIN 0x80044d0d | |
| 729 | +#define TARGET_SOUND_MIXER_READ_LINE1 0x80044d0e | |
| 730 | +#define TARGET_SOUND_MIXER_READ_LINE2 0x80044d0f | |
| 731 | +#define TARGET_SOUND_MIXER_READ_LINE3 0x80044d10 | |
| 732 | +#define TARGET_SOUND_MIXER_READ_MUTE 0x80044d1f | |
| 733 | +#define TARGET_SOUND_MIXER_READ_ENHANCE 0x80044d1f | |
| 734 | +#define TARGET_SOUND_MIXER_READ_LOUD 0x80044d1f | |
| 735 | +#define TARGET_SOUND_MIXER_READ_RECSRC 0x80044dff | |
| 736 | +#define TARGET_SOUND_MIXER_READ_DEVMASK 0x80044dfe | |
| 737 | +#define TARGET_SOUND_MIXER_READ_RECMASK 0x80044dfd | |
| 738 | +#define TARGET_SOUND_MIXER_READ_STEREODEVS 0x80044dfb | |
| 739 | +#define TARGET_SOUND_MIXER_READ_CAPS 0x80044dfc | |
| 740 | +#define TARGET_SOUND_MIXER_WRITE_VOLUME 0xc0044d00 | |
| 741 | +#define TARGET_SOUND_MIXER_WRITE_BASS 0xc0044d01 | |
| 742 | +#define TARGET_SOUND_MIXER_WRITE_TREBLE 0xc0044d02 | |
| 743 | +#define TARGET_SOUND_MIXER_WRITE_SYNTH 0xc0044d03 | |
| 744 | +#define TARGET_SOUND_MIXER_WRITE_PCM 0xc0044d04 | |
| 745 | +#define TARGET_SOUND_MIXER_WRITE_SPEAKER 0xc0044d05 | |
| 746 | +#define TARGET_SOUND_MIXER_WRITE_LINE 0xc0044d06 | |
| 747 | +#define TARGET_SOUND_MIXER_WRITE_MIC 0xc0044d07 | |
| 748 | +#define TARGET_SOUND_MIXER_WRITE_CD 0xc0044d08 | |
| 749 | +#define TARGET_SOUND_MIXER_WRITE_IMIX 0xc0044d09 | |
| 750 | +#define TARGET_SOUND_MIXER_WRITE_ALTPCM 0xc0044d0a | |
| 751 | +#define TARGET_SOUND_MIXER_WRITE_RECLEV 0xc0044d0b | |
| 752 | +#define TARGET_SOUND_MIXER_WRITE_IGAIN 0xc0044d0c | |
| 753 | +#define TARGET_SOUND_MIXER_WRITE_OGAIN 0xc0044d0d | |
| 754 | +#define TARGET_SOUND_MIXER_WRITE_LINE1 0xc0044d0e | |
| 755 | +#define TARGET_SOUND_MIXER_WRITE_LINE2 0xc0044d0f | |
| 756 | +#define TARGET_SOUND_MIXER_WRITE_LINE3 0xc0044d10 | |
| 757 | +#define TARGET_SOUND_MIXER_WRITE_MUTE 0xc0044d1f | |
| 758 | +#define TARGET_SOUND_MIXER_WRITE_ENHANCE 0xc0044d1f | |
| 759 | +#define TARGET_SOUND_MIXER_WRITE_LOUD 0xc0044d1f | |
| 760 | +#define TARGET_SOUND_MIXER_WRITE_RECSRC 0xc0044dff | ... | ... |
thunk.c
0 → 100644
| 1 | +/* | |
| 2 | + * Generic thunking code to convert data between host and target CPU | |
| 3 | + * | |
| 4 | + * Copyright (c) 2003 Fabrice Bellard | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License as published by | |
| 8 | + * the Free Software Foundation; either version 2 of the License, or | |
| 9 | + * (at your option) any later version. | |
| 10 | + * | |
| 11 | + * This program is distributed in the hope that it will be useful, | |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + * GNU General Public License for more details. | |
| 15 | + * | |
| 16 | + * You should have received a copy of the GNU General Public License | |
| 17 | + * along with this program; if not, write to the Free Software | |
| 18 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 19 | + */ | |
| 20 | +#include <stdlib.h> | |
| 21 | +#include <stdio.h> | |
| 22 | +#include <stdarg.h> | |
| 23 | + | |
| 24 | +#include "gemu.h" | |
| 25 | +#include "thunk.h" | |
| 26 | + | |
| 27 | +//#define DEBUG | |
| 28 | + | |
| 29 | +#define MAX_STRUCTS 128 | |
| 30 | + | |
| 31 | +/* XXX: make it dynamic */ | |
| 32 | +static StructEntry struct_entries[MAX_STRUCTS]; | |
| 33 | + | |
| 34 | +static inline int thunk_type_size(const argtype *type_ptr, int is_host) | |
| 35 | +{ | |
| 36 | + int type, size; | |
| 37 | + const StructEntry *se; | |
| 38 | + | |
| 39 | + type = *type_ptr; | |
| 40 | + switch(type) { | |
| 41 | + case TYPE_CHAR: | |
| 42 | + return 1; | |
| 43 | + case TYPE_SHORT: | |
| 44 | + return 2; | |
| 45 | + case TYPE_INT: | |
| 46 | + return 4; | |
| 47 | + case TYPE_LONGLONG: | |
| 48 | + case TYPE_ULONGLONG: | |
| 49 | + return 8; | |
| 50 | + case TYPE_LONG: | |
| 51 | + case TYPE_ULONG: | |
| 52 | + case TYPE_PTRVOID: | |
| 53 | + case TYPE_PTR: | |
| 54 | + if (is_host) { | |
| 55 | + return HOST_LONG_SIZE; | |
| 56 | + } else { | |
| 57 | + return TARGET_LONG_SIZE; | |
| 58 | + } | |
| 59 | + break; | |
| 60 | + case TYPE_ARRAY: | |
| 61 | + size = type_ptr[1]; | |
| 62 | + return size * thunk_type_size(type_ptr + 2, is_host); | |
| 63 | + case TYPE_STRUCT: | |
| 64 | + se = struct_entries + type_ptr[1]; | |
| 65 | + return se->size[is_host]; | |
| 66 | + default: | |
| 67 | + return -1; | |
| 68 | + } | |
| 69 | +} | |
| 70 | + | |
| 71 | +static inline int thunk_type_align(const argtype *type_ptr, int is_host) | |
| 72 | +{ | |
| 73 | + int type; | |
| 74 | + const StructEntry *se; | |
| 75 | + | |
| 76 | + type = *type_ptr; | |
| 77 | + switch(type) { | |
| 78 | + case TYPE_CHAR: | |
| 79 | + return 1; | |
| 80 | + case TYPE_SHORT: | |
| 81 | + return 2; | |
| 82 | + case TYPE_INT: | |
| 83 | + return 4; | |
| 84 | + case TYPE_LONGLONG: | |
| 85 | + case TYPE_ULONGLONG: | |
| 86 | + return 8; | |
| 87 | + case TYPE_LONG: | |
| 88 | + case TYPE_ULONG: | |
| 89 | + case TYPE_PTRVOID: | |
| 90 | + case TYPE_PTR: | |
| 91 | + if (is_host) { | |
| 92 | + return HOST_LONG_SIZE; | |
| 93 | + } else { | |
| 94 | + return TARGET_LONG_SIZE; | |
| 95 | + } | |
| 96 | + break; | |
| 97 | + case TYPE_ARRAY: | |
| 98 | + return thunk_type_align(type_ptr + 2, is_host); | |
| 99 | + case TYPE_STRUCT: | |
| 100 | + se = struct_entries + type_ptr[1]; | |
| 101 | + return se->align[is_host]; | |
| 102 | + default: | |
| 103 | + return -1; | |
| 104 | + } | |
| 105 | +} | |
| 106 | + | |
| 107 | +static inline const argtype *thunk_type_next(const argtype *type_ptr) | |
| 108 | +{ | |
| 109 | + int type; | |
| 110 | + | |
| 111 | + type = *type_ptr++; | |
| 112 | + switch(type) { | |
| 113 | + case TYPE_CHAR: | |
| 114 | + case TYPE_SHORT: | |
| 115 | + case TYPE_INT: | |
| 116 | + case TYPE_LONGLONG: | |
| 117 | + case TYPE_ULONGLONG: | |
| 118 | + case TYPE_LONG: | |
| 119 | + case TYPE_ULONG: | |
| 120 | + case TYPE_PTRVOID: | |
| 121 | + return type_ptr; | |
| 122 | + case TYPE_PTR: | |
| 123 | + return thunk_type_next(type_ptr); | |
| 124 | + case TYPE_ARRAY: | |
| 125 | + return thunk_type_next(type_ptr + 1); | |
| 126 | + case TYPE_STRUCT: | |
| 127 | + return type_ptr + 1; | |
| 128 | + default: | |
| 129 | + return NULL; | |
| 130 | + } | |
| 131 | +} | |
| 132 | + | |
| 133 | +void thunk_register_struct(int id, const char *name, const argtype *types) | |
| 134 | +{ | |
| 135 | + const argtype *type_ptr; | |
| 136 | + StructEntry *se; | |
| 137 | + int nb_fields, offset, max_align, align, size, i, j; | |
| 138 | + | |
| 139 | + se = struct_entries + id; | |
| 140 | + | |
| 141 | + /* first we count the number of fields */ | |
| 142 | + type_ptr = types; | |
| 143 | + nb_fields = 0; | |
| 144 | + while (*type_ptr != TYPE_NULL) { | |
| 145 | + type_ptr = thunk_type_next(type_ptr); | |
| 146 | + nb_fields++; | |
| 147 | + } | |
| 148 | + se->field_types = types; | |
| 149 | + se->nb_fields = nb_fields; | |
| 150 | + se->name = name; | |
| 151 | +#ifdef DEBUG | |
| 152 | + printf("struct %s: id=%d nb_fields=%d\n", | |
| 153 | + se->name, id, se->nb_fields); | |
| 154 | +#endif | |
| 155 | + /* now we can alloc the data */ | |
| 156 | + | |
| 157 | + for(i = 0;i < 2; i++) { | |
| 158 | + offset = 0; | |
| 159 | + max_align = 1; | |
| 160 | + se->field_offsets[i] = malloc(nb_fields * sizeof(int)); | |
| 161 | + type_ptr = se->field_types; | |
| 162 | + for(j = 0;j < nb_fields; j++) { | |
| 163 | + size = thunk_type_size(type_ptr, i); | |
| 164 | + align = thunk_type_align(type_ptr, i); | |
| 165 | + offset = (offset + align - 1) & ~(align - 1); | |
| 166 | + se->field_offsets[i][j] = offset; | |
| 167 | + offset += size; | |
| 168 | + if (align > max_align) | |
| 169 | + max_align = align; | |
| 170 | + } | |
| 171 | + offset = (offset + max_align - 1) & ~(max_align - 1); | |
| 172 | + se->size[i] = offset; | |
| 173 | + se->align[i] = max_align; | |
| 174 | +#ifdef DEBUG | |
| 175 | + printf("%s: size=%d align=%d\n", | |
| 176 | + i == THUNK_HOST ? "host" : "target", offset, max_align); | |
| 177 | +#endif | |
| 178 | + } | |
| 179 | +} | |
| 180 | + | |
| 181 | +void thunk_register_struct_direct(int id, const char *name, StructEntry *se1) | |
| 182 | +{ | |
| 183 | + StructEntry *se; | |
| 184 | + se = struct_entries + id; | |
| 185 | + *se = *se1; | |
| 186 | + se->name = name; | |
| 187 | +} | |
| 188 | + | |
| 189 | + | |
| 190 | +/* now we can define the main conversion functions */ | |
| 191 | +const argtype *thunk_convert(void *dst, const void *src, | |
| 192 | + const argtype *type_ptr, int to_host) | |
| 193 | +{ | |
| 194 | + int type; | |
| 195 | + | |
| 196 | + type = *type_ptr++; | |
| 197 | + switch(type) { | |
| 198 | + case TYPE_CHAR: | |
| 199 | + *(uint8_t *)dst = *(uint8_t *)src; | |
| 200 | + break; | |
| 201 | + case TYPE_SHORT: | |
| 202 | + *(uint16_t *)dst = tswap16(*(uint16_t *)src); | |
| 203 | + break; | |
| 204 | + case TYPE_INT: | |
| 205 | + *(uint32_t *)dst = tswap32(*(uint32_t *)src); | |
| 206 | + break; | |
| 207 | + case TYPE_LONGLONG: | |
| 208 | + case TYPE_ULONGLONG: | |
| 209 | + *(uint64_t *)dst = tswap64(*(uint64_t *)src); | |
| 210 | + break; | |
| 211 | +#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32 | |
| 212 | + case TYPE_LONG: | |
| 213 | + case TYPE_ULONG: | |
| 214 | + case TYPE_PTRVOID: | |
| 215 | + *(uint32_t *)dst = tswap32(*(uint32_t *)src); | |
| 216 | + break; | |
| 217 | +#elif HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32 | |
| 218 | + case TYPE_LONG: | |
| 219 | + case TYPE_ULONG: | |
| 220 | + case TYPE_PTRVOID: | |
| 221 | + if (target_to_host) { | |
| 222 | + *(uint64_t *)dst = tswap32(*(uint32_t *)src); | |
| 223 | + } else { | |
| 224 | + *(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff); | |
| 225 | + } | |
| 226 | + break; | |
| 227 | +#else | |
| 228 | +#error unsupported conversion | |
| 229 | +#endif | |
| 230 | + case TYPE_ARRAY: | |
| 231 | + { | |
| 232 | + int array_length, i, dst_size, src_size; | |
| 233 | + const uint8_t *s; | |
| 234 | + uint8_t *d; | |
| 235 | + | |
| 236 | + array_length = *type_ptr++; | |
| 237 | + dst_size = thunk_type_size(type_ptr, to_host); | |
| 238 | + src_size = thunk_type_size(type_ptr, 1 - to_host); | |
| 239 | + d = dst; | |
| 240 | + s = src; | |
| 241 | + for(i = 0;i < array_length; i++) { | |
| 242 | + thunk_convert(d, s, type_ptr, to_host); | |
| 243 | + d += dst_size; | |
| 244 | + s += src_size; | |
| 245 | + } | |
| 246 | + type_ptr = thunk_type_next(type_ptr); | |
| 247 | + } | |
| 248 | + break; | |
| 249 | + case TYPE_STRUCT: | |
| 250 | + { | |
| 251 | + int i; | |
| 252 | + const StructEntry *se; | |
| 253 | + const uint8_t *s; | |
| 254 | + uint8_t *d; | |
| 255 | + const argtype *field_types; | |
| 256 | + const int *dst_offsets, *src_offsets; | |
| 257 | + | |
| 258 | + se = struct_entries + *type_ptr++; | |
| 259 | + if (se->convert[0] != NULL) { | |
| 260 | + /* specific conversion is needed */ | |
| 261 | + (*se->convert[to_host])(dst, src); | |
| 262 | + } else { | |
| 263 | + /* standard struct conversion */ | |
| 264 | + field_types = se->field_types; | |
| 265 | + dst_offsets = se->field_offsets[to_host]; | |
| 266 | + src_offsets = se->field_offsets[1 - to_host]; | |
| 267 | + d = dst; | |
| 268 | + s = src; | |
| 269 | + for(i = 0;i < se->nb_fields; i++) { | |
| 270 | + field_types = thunk_convert(d + dst_offsets[i], | |
| 271 | + s + src_offsets[i], | |
| 272 | + field_types, to_host); | |
| 273 | + } | |
| 274 | + } | |
| 275 | + } | |
| 276 | + break; | |
| 277 | + default: | |
| 278 | + fprintf(stderr, "Invalid type 0x%x\n", type); | |
| 279 | + break; | |
| 280 | + } | |
| 281 | + return type_ptr; | |
| 282 | +} | |
| 283 | + | |
| 284 | +/* from em86 */ | |
| 285 | + | |
| 286 | +/* Utility function: Table-driven functions to translate bitmasks | |
| 287 | + * between X86 and Alpha formats... | |
| 288 | + */ | |
| 289 | +unsigned int target_to_host_bitmask(unsigned int x86_mask, | |
| 290 | + bitmask_transtbl * trans_tbl) | |
| 291 | +{ | |
| 292 | + bitmask_transtbl * btp; | |
| 293 | + unsigned int alpha_mask = 0; | |
| 294 | + | |
| 295 | + for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) { | |
| 296 | + if((x86_mask & btp->x86_mask) == btp->x86_bits) { | |
| 297 | + alpha_mask |= btp->alpha_bits; | |
| 298 | + } | |
| 299 | + } | |
| 300 | + return(alpha_mask); | |
| 301 | +} | |
| 302 | + | |
| 303 | +unsigned int host_to_target_bitmask(unsigned int alpha_mask, | |
| 304 | + bitmask_transtbl * trans_tbl) | |
| 305 | +{ | |
| 306 | + bitmask_transtbl * btp; | |
| 307 | + unsigned int x86_mask = 0; | |
| 308 | + | |
| 309 | + for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) { | |
| 310 | + if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) { | |
| 311 | + x86_mask |= btp->x86_mask; | |
| 312 | + } | |
| 313 | + } | |
| 314 | + return(x86_mask); | |
| 315 | +} | ... | ... |
thunk.h
0 → 100644
| 1 | +#ifndef THUNK_H | |
| 2 | +#define THUNK_H | |
| 3 | + | |
| 4 | +#include <inttypes.h> | |
| 5 | +#include <byteswap.h> | |
| 6 | + | |
| 7 | +#undef WORDS_BIGENDIAN | |
| 8 | +#if __BYTE_ORDER == __BIG_ENDIAN | |
| 9 | +#define WORDS_BIGENDIAN | |
| 10 | +#endif | |
| 11 | + | |
| 12 | +#ifdef WORD_BIGENDIAN | |
| 13 | +#define BSWAP_NEEDED | |
| 14 | +#endif | |
| 15 | + | |
| 16 | +/* XXX: auto autoconf */ | |
| 17 | +#define TARGET_I386 | |
| 18 | +#define TARGET_LONG_BITS 32 | |
| 19 | + | |
| 20 | + | |
| 21 | +#if defined(__alpha__) | |
| 22 | +#define HOST_LONG_BITS 64 | |
| 23 | +#else | |
| 24 | +#define HOST_LONG_BITS 32 | |
| 25 | +#endif | |
| 26 | + | |
| 27 | +#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8) | |
| 28 | +#define HOST_LONG_SIZE (TARGET_LONG_BITS / 8) | |
| 29 | + | |
| 30 | +static inline uint16_t bswap16(uint16_t x) | |
| 31 | +{ | |
| 32 | + return bswap_16(x); | |
| 33 | +} | |
| 34 | + | |
| 35 | +static inline uint32_t bswap32(uint32_t x) | |
| 36 | +{ | |
| 37 | + return bswap_32(x); | |
| 38 | +} | |
| 39 | + | |
| 40 | +static inline uint64_t bswap64(uint64_t x) | |
| 41 | +{ | |
| 42 | + return bswap_64(x); | |
| 43 | +} | |
| 44 | + | |
| 45 | +static void inline bswap16s(uint16_t *s) | |
| 46 | +{ | |
| 47 | + *s = bswap16(*s); | |
| 48 | +} | |
| 49 | + | |
| 50 | +static void inline bswap32s(uint32_t *s) | |
| 51 | +{ | |
| 52 | + *s = bswap32(*s); | |
| 53 | +} | |
| 54 | + | |
| 55 | +static void inline bswap64s(uint64_t *s) | |
| 56 | +{ | |
| 57 | + *s = bswap64(*s); | |
| 58 | +} | |
| 59 | + | |
| 60 | +#ifdef BSWAP_NEEDED | |
| 61 | + | |
| 62 | +static inline uint16_t tswap16(uint16_t s) | |
| 63 | +{ | |
| 64 | + return bswap16(s); | |
| 65 | +} | |
| 66 | + | |
| 67 | +static inline uint32_t tswap32(uint32_t s) | |
| 68 | +{ | |
| 69 | + return bswap32(s); | |
| 70 | +} | |
| 71 | + | |
| 72 | +static inline uint64_t tswap64(uint64_t s) | |
| 73 | +{ | |
| 74 | + return bswap64(s); | |
| 75 | +} | |
| 76 | + | |
| 77 | +static void inline tswap16s(uint16_t *s) | |
| 78 | +{ | |
| 79 | + *s = bswap16(*s); | |
| 80 | +} | |
| 81 | + | |
| 82 | +static void inline tswap32s(uint32_t *s) | |
| 83 | +{ | |
| 84 | + *s = bswap32(*s); | |
| 85 | +} | |
| 86 | + | |
| 87 | +static void inline tswap64s(uint64_t *s) | |
| 88 | +{ | |
| 89 | + *s = bswap64(*s); | |
| 90 | +} | |
| 91 | + | |
| 92 | +#else | |
| 93 | + | |
| 94 | +static inline uint16_t tswap16(uint16_t s) | |
| 95 | +{ | |
| 96 | + return s; | |
| 97 | +} | |
| 98 | + | |
| 99 | +static inline uint32_t tswap32(uint32_t s) | |
| 100 | +{ | |
| 101 | + return s; | |
| 102 | +} | |
| 103 | + | |
| 104 | +static inline uint64_t tswap64(uint64_t s) | |
| 105 | +{ | |
| 106 | + return s; | |
| 107 | +} | |
| 108 | + | |
| 109 | +static void inline tswap16s(uint16_t *s) | |
| 110 | +{ | |
| 111 | +} | |
| 112 | + | |
| 113 | +static void inline tswap32s(uint32_t *s) | |
| 114 | +{ | |
| 115 | +} | |
| 116 | + | |
| 117 | +static void inline tswap64s(uint64_t *s) | |
| 118 | +{ | |
| 119 | +} | |
| 120 | + | |
| 121 | +#endif | |
| 122 | + | |
| 123 | +#if TARGET_LONG_SIZE == 4 | |
| 124 | +#define tswapl(s) tswap32(s) | |
| 125 | +#define tswapls(s) tswap32s((uint32_t *)(s)) | |
| 126 | +#else | |
| 127 | +#define tswapl(s) tswap64(s) | |
| 128 | +#define tswapls(s) tswap64s((uint64_t *)(s)) | |
| 129 | +#endif | |
| 130 | + | |
| 131 | +#if TARGET_LONG_SIZE == 4 | |
| 132 | +typedef int32_t target_long; | |
| 133 | +typedef uint32_t target_ulong; | |
| 134 | +#elif TARGET_LONG_SIZE == 8 | |
| 135 | +typedef int64_t target_long; | |
| 136 | +typedef uint64_t target_ulong; | |
| 137 | +#else | |
| 138 | +#error TARGET_LONG_SIZE undefined | |
| 139 | +#endif | |
| 140 | + | |
| 141 | +/* types enums definitions */ | |
| 142 | + | |
| 143 | +typedef enum argtype { | |
| 144 | + TYPE_NULL, | |
| 145 | + TYPE_CHAR, | |
| 146 | + TYPE_SHORT, | |
| 147 | + TYPE_INT, | |
| 148 | + TYPE_LONG, | |
| 149 | + TYPE_ULONG, | |
| 150 | + TYPE_PTRVOID, /* pointer on unknown data */ | |
| 151 | + TYPE_LONGLONG, | |
| 152 | + TYPE_ULONGLONG, | |
| 153 | + TYPE_PTR, | |
| 154 | + TYPE_ARRAY, | |
| 155 | + TYPE_STRUCT, | |
| 156 | +} argtype; | |
| 157 | + | |
| 158 | +#define MK_PTR(type) TYPE_PTR, type | |
| 159 | +#define MK_ARRAY(type, size) TYPE_ARRAY, size, type | |
| 160 | +#define MK_STRUCT(id) TYPE_STRUCT, id | |
| 161 | + | |
| 162 | +#define THUNK_TARGET 0 | |
| 163 | +#define THUNK_HOST 1 | |
| 164 | + | |
| 165 | +typedef struct { | |
| 166 | + /* standard struct handling */ | |
| 167 | + const argtype *field_types; | |
| 168 | + int nb_fields; | |
| 169 | + int *field_offsets[2]; | |
| 170 | + /* special handling */ | |
| 171 | + void (*convert[2])(void *dst, const void *src); | |
| 172 | + int size[2]; | |
| 173 | + int align[2]; | |
| 174 | + const char *name; | |
| 175 | +} StructEntry; | |
| 176 | + | |
| 177 | +/* Translation table for bitmasks... */ | |
| 178 | +typedef struct bitmask_transtbl { | |
| 179 | + unsigned int x86_mask; | |
| 180 | + unsigned int x86_bits; | |
| 181 | + unsigned int alpha_mask; | |
| 182 | + unsigned int alpha_bits; | |
| 183 | +} bitmask_transtbl; | |
| 184 | + | |
| 185 | +void thunk_register_struct(int id, const char *name, const argtype *types); | |
| 186 | +void thunk_register_struct_direct(int id, const char *name, StructEntry *se1); | |
| 187 | +const argtype *thunk_convert(void *dst, const void *src, | |
| 188 | + const argtype *type_ptr, int to_host); | |
| 189 | + | |
| 190 | +unsigned int target_to_host_bitmask(unsigned int x86_mask, | |
| 191 | + bitmask_transtbl * trans_tbl); | |
| 192 | +unsigned int host_to_target_bitmask(unsigned int alpha_mask, | |
| 193 | + bitmask_transtbl * trans_tbl); | |
| 194 | + | |
| 195 | +#endif | ... | ... |