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
13 changed files
with
4521 additions
and
0 deletions
Too many changes to show.
To preserve performance only 13 of 16 files are displayed.
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 | + |