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 | + | ... | ... |