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
This commit is contained in:
parent
e63c3dc74b
commit
31e31b8a24
504
COPYING.LIB
Normal file
504
COPYING.LIB
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
------------------------------------------------------------------------------
|
||||||
|
NOTE:
|
||||||
|
Some code of the Twin package was modified for DOSEMU by the DOSEMU-team.
|
||||||
|
The original is 'Copyright 1997 Willows Software, Inc.' and generously
|
||||||
|
was put under the GNU Library General Public License.
|
||||||
|
( for more information see http://www.willows.com/ )
|
||||||
|
|
||||||
|
We make use of section 3 of the GNU Library General Public License
|
||||||
|
('...opt to apply the terms of the ordinary GNU General Public License...'),
|
||||||
|
because the resulting product is an integrated part of DOSEMU and
|
||||||
|
can not be considered to be a 'library' in the terms of Library License.
|
||||||
|
|
||||||
|
Therefore, the below GNU LIBRARY GENERAL PUBLIC LICENSE applies only to the
|
||||||
|
_unchanged_ Twin package from Willows. For the DOSEMU-changed parts the normal
|
||||||
|
GNU GENERAL PUBLIC LICENSE applies. This GPL (file COPYING) can be found in
|
||||||
|
the root directory of the DOSEMU distribution.
|
||||||
|
|
||||||
|
The act of transformation to GPL was indicated to the maintainer of the Twin
|
||||||
|
package (Rob Penrose <rob@Canopy.Com>) and he acknowledge agreement.
|
||||||
|
|
||||||
|
Nov. 1 1997, The DOSEMU team.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||||
|
675 Mass Ave, Cambridge, MA 02139, USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the library GPL. It is
|
||||||
|
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Library General Public License, applies to some
|
||||||
|
specially designated Free Software Foundation software, and to any
|
||||||
|
other libraries whose authors decide to use it. You can use it for
|
||||||
|
your libraries, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link a program with the library, you must provide
|
||||||
|
complete object files to the recipients so that they can relink them
|
||||||
|
with the library, after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
Our method of protecting your rights has two steps: (1) copyright
|
||||||
|
the library, and (2) offer you this license which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
Also, for each distributor's protection, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
library. If the library is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original
|
||||||
|
version, so that any problems introduced by others will not reflect on
|
||||||
|
the original authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that companies distributing free
|
||||||
|
software will individually obtain patent licenses, thus in effect
|
||||||
|
transforming the program into proprietary software. To prevent this,
|
||||||
|
we have made it clear that any patent must be licensed for everyone's
|
||||||
|
free use or not licensed at all.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary
|
||||||
|
GNU General Public License, which was designed for utility programs. This
|
||||||
|
license, the GNU Library General Public License, applies to certain
|
||||||
|
designated libraries. This license is quite different from the ordinary
|
||||||
|
one; be sure to read it in full, and don't assume that anything in it is
|
||||||
|
the same as in the ordinary license.
|
||||||
|
|
||||||
|
The reason we have a separate public license for some libraries is that
|
||||||
|
they blur the distinction we usually make between modifying or adding to a
|
||||||
|
program and simply using it. Linking a program with a library, without
|
||||||
|
changing the library, is in some sense simply using the library, and is
|
||||||
|
analogous to running a utility program or application program. However, in
|
||||||
|
a textual and legal sense, the linked executable is a combined work, a
|
||||||
|
derivative of the original library, and the ordinary General Public License
|
||||||
|
treats it as such.
|
||||||
|
|
||||||
|
Because of this blurred distinction, using the ordinary General
|
||||||
|
Public License for libraries did not effectively promote software
|
||||||
|
sharing, because most developers did not use the libraries. We
|
||||||
|
concluded that weaker conditions might promote sharing better.
|
||||||
|
|
||||||
|
However, unrestricted linking of non-free programs would deprive the
|
||||||
|
users of those programs of all benefit from the free status of the
|
||||||
|
libraries themselves. This Library General Public License is intended to
|
||||||
|
permit developers of non-free programs to use free libraries, while
|
||||||
|
preserving your freedom as a user of such programs to change the free
|
||||||
|
libraries that are incorporated in them. (We have not seen how to achieve
|
||||||
|
this as regards changes in header files, but we have achieved it as regards
|
||||||
|
changes in the actual functions of the Library.) The hope is that this
|
||||||
|
will lead to faster development of free libraries.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, while the latter only
|
||||||
|
works together with the library.
|
||||||
|
|
||||||
|
Note that it is possible for a library to be covered by the ordinary
|
||||||
|
General Public License rather than by this special one.
|
||||||
|
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library which
|
||||||
|
contains a notice placed by the copyright holder or other authorized
|
||||||
|
party saying it may be distributed under the terms of this Library
|
||||||
|
General Public License (also called "this License"). Each licensee is
|
||||||
|
addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also compile or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
c) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
d) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the source code distributed need not include anything that is normally
|
||||||
|
distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Library General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Appendix: How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
37
Makefile
Normal file
37
Makefile
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
CFLAGS=-Wall -O2 -g
|
||||||
|
LDFLAGS=-g
|
||||||
|
DEFINES=-D_GNU_SOURCE -DGEMU -DDOSEMU #-DNO_TRACE_MSGS
|
||||||
|
|
||||||
|
OBJS= i386/fp87.o i386/interp_main.o i386/interp_modrm.o i386/interp_16_32.o \
|
||||||
|
i386/interp_32_16.o i386/interp_32_32.o i386/emu-utils.o \
|
||||||
|
i386/dis8086.o i386/emu-ldt.o
|
||||||
|
OBJS+= elfload.o main.o thunk.o syscall.o
|
||||||
|
|
||||||
|
SRCS = $(OBJS:.o=.c)
|
||||||
|
|
||||||
|
all: gemu
|
||||||
|
|
||||||
|
gemu: $(OBJS)
|
||||||
|
$(CC) -Wl,-T,i386.ld $(LDFLAGS) -o $@ $(OBJS)
|
||||||
|
|
||||||
|
depend: $(SRCS)
|
||||||
|
$(CC) -MM $(CFLAGS) $^ 1>.depend
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *~ i386/*.o i386/*~ gemu hello test1 test2 TAGS
|
||||||
|
|
||||||
|
hello: hello.c
|
||||||
|
$(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
test1: test1.c
|
||||||
|
$(CC) $(CFLAGS) -static $(LDFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
test2: test2.c
|
||||||
|
$(CC) $(CFLAGS) -static $(LDFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
ifneq ($(wildcard .depend),)
|
||||||
|
include .depend
|
||||||
|
endif
|
2
TODO
Normal file
2
TODO
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
- swap all elf paramters
|
||||||
|
- fix printf for doubles (fp87.c bug ?)
|
425
elf.h
Normal file
425
elf.h
Normal file
@ -0,0 +1,425 @@
|
|||||||
|
/*
|
||||||
|
* ELF register definitions..
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
typedef uint32_t elf_greg_t;
|
||||||
|
|
||||||
|
#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
|
||||||
|
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||||
|
|
||||||
|
typedef struct user_i387_struct elf_fpregset_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is used to ensure we don't load something for the wrong architecture.
|
||||||
|
*/
|
||||||
|
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are used to set parameters in the core dumps.
|
||||||
|
*/
|
||||||
|
#define ELF_CLASS ELFCLASS32
|
||||||
|
#define ELF_DATA ELFDATA2LSB;
|
||||||
|
#define ELF_ARCH EM_386
|
||||||
|
|
||||||
|
/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
|
||||||
|
starts %edx contains a pointer to a function which might be
|
||||||
|
registered using `atexit'. This provides a mean for the
|
||||||
|
dynamic linker to call DT_FINI functions for shared libraries
|
||||||
|
that have been loaded before the code runs.
|
||||||
|
|
||||||
|
A value of 0 tells we have no such handler. */
|
||||||
|
#define ELF_PLAT_INIT(_r) _r->edx = 0
|
||||||
|
|
||||||
|
#define USE_ELF_CORE_DUMP
|
||||||
|
#define ELF_EXEC_PAGESIZE 4096
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint32_t Elf32_Addr;
|
||||||
|
typedef uint16_t Elf32_Half;
|
||||||
|
typedef uint32_t Elf32_Off;
|
||||||
|
typedef int32_t Elf32_Sword;
|
||||||
|
typedef uint32_t Elf32_Word;
|
||||||
|
|
||||||
|
/* These constants are for the segment types stored in the image headers */
|
||||||
|
#define PT_NULL 0
|
||||||
|
#define PT_LOAD 1
|
||||||
|
#define PT_DYNAMIC 2
|
||||||
|
#define PT_INTERP 3
|
||||||
|
#define PT_NOTE 4
|
||||||
|
#define PT_SHLIB 5
|
||||||
|
#define PT_PHDR 6
|
||||||
|
#define PT_LOPROC 0x70000000
|
||||||
|
#define PT_HIPROC 0x7fffffff
|
||||||
|
|
||||||
|
/* These constants define the different elf file types */
|
||||||
|
#define ET_NONE 0
|
||||||
|
#define ET_REL 1
|
||||||
|
#define ET_EXEC 2
|
||||||
|
#define ET_DYN 3
|
||||||
|
#define ET_CORE 4
|
||||||
|
#define ET_LOPROC 5
|
||||||
|
#define ET_HIPROC 6
|
||||||
|
|
||||||
|
/* These constants define the various ELF target machines */
|
||||||
|
#define EM_NONE 0
|
||||||
|
#define EM_M32 1
|
||||||
|
#define EM_SPARC 2
|
||||||
|
#define EM_386 3
|
||||||
|
#define EM_68K 4
|
||||||
|
#define EM_88K 5
|
||||||
|
#define EM_486 6 /* Perhaps disused */
|
||||||
|
#define EM_860 7
|
||||||
|
|
||||||
|
#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
|
||||||
|
|
||||||
|
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
|
||||||
|
|
||||||
|
#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */
|
||||||
|
|
||||||
|
#define EM_PARISC 15 /* HPPA */
|
||||||
|
|
||||||
|
#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
|
||||||
|
|
||||||
|
#define EM_PPC 20 /* PowerPC */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an interim value that we will use until the committee comes
|
||||||
|
* up with a final number.
|
||||||
|
*/
|
||||||
|
#define EM_ALPHA 0x9026
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the info that is needed to parse the dynamic section of the file */
|
||||||
|
#define DT_NULL 0
|
||||||
|
#define DT_NEEDED 1
|
||||||
|
#define DT_PLTRELSZ 2
|
||||||
|
#define DT_PLTGOT 3
|
||||||
|
#define DT_HASH 4
|
||||||
|
#define DT_STRTAB 5
|
||||||
|
#define DT_SYMTAB 6
|
||||||
|
#define DT_RELA 7
|
||||||
|
#define DT_RELASZ 8
|
||||||
|
#define DT_RELAENT 9
|
||||||
|
#define DT_STRSZ 10
|
||||||
|
#define DT_SYMENT 11
|
||||||
|
#define DT_INIT 12
|
||||||
|
#define DT_FINI 13
|
||||||
|
#define DT_SONAME 14
|
||||||
|
#define DT_RPATH 15
|
||||||
|
#define DT_SYMBOLIC 16
|
||||||
|
#define DT_REL 17
|
||||||
|
#define DT_RELSZ 18
|
||||||
|
#define DT_RELENT 19
|
||||||
|
#define DT_PLTREL 20
|
||||||
|
#define DT_DEBUG 21
|
||||||
|
#define DT_TEXTREL 22
|
||||||
|
#define DT_JMPREL 23
|
||||||
|
#define DT_LOPROC 0x70000000
|
||||||
|
#define DT_HIPROC 0x7fffffff
|
||||||
|
|
||||||
|
/* This info is needed when parsing the symbol table */
|
||||||
|
#define STB_LOCAL 0
|
||||||
|
#define STB_GLOBAL 1
|
||||||
|
#define STB_WEAK 2
|
||||||
|
|
||||||
|
#define STT_NOTYPE 0
|
||||||
|
#define STT_OBJECT 1
|
||||||
|
#define STT_FUNC 2
|
||||||
|
#define STT_SECTION 3
|
||||||
|
#define STT_FILE 4
|
||||||
|
|
||||||
|
#define ELF32_ST_BIND(x) ((x) >> 4)
|
||||||
|
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||||
|
|
||||||
|
/* Symbolic values for the entries in the auxiliary table
|
||||||
|
put on the initial stack */
|
||||||
|
#define AT_NULL 0 /* end of vector */
|
||||||
|
#define AT_IGNORE 1 /* entry should be ignored */
|
||||||
|
#define AT_EXECFD 2 /* file descriptor of program */
|
||||||
|
#define AT_PHDR 3 /* program headers for program */
|
||||||
|
#define AT_PHENT 4 /* size of program header entry */
|
||||||
|
#define AT_PHNUM 5 /* number of program headers */
|
||||||
|
#define AT_PAGESZ 6 /* system page size */
|
||||||
|
#define AT_BASE 7 /* base address of interpreter */
|
||||||
|
#define AT_FLAGS 8 /* flags */
|
||||||
|
#define AT_ENTRY 9 /* entry point of program */
|
||||||
|
#define AT_NOTELF 10 /* program is not ELF */
|
||||||
|
#define AT_UID 11 /* real uid */
|
||||||
|
#define AT_EUID 12 /* effective uid */
|
||||||
|
#define AT_GID 13 /* real gid */
|
||||||
|
#define AT_EGID 14 /* effective gid */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct dynamic{
|
||||||
|
Elf32_Sword d_tag;
|
||||||
|
union{
|
||||||
|
Elf32_Sword d_val;
|
||||||
|
Elf32_Addr d_ptr;
|
||||||
|
} d_un;
|
||||||
|
} Elf32_Dyn;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long long d_tag; /* entry tag value */
|
||||||
|
union {
|
||||||
|
unsigned long long d_val;
|
||||||
|
unsigned long long d_ptr;
|
||||||
|
} d_un;
|
||||||
|
} Elf64_Dyn;
|
||||||
|
|
||||||
|
/* The following are used with relocations */
|
||||||
|
#define ELF32_R_SYM(x) ((x) >> 8)
|
||||||
|
#define ELF32_R_TYPE(x) ((x) & 0xff)
|
||||||
|
|
||||||
|
#define R_386_NONE 0
|
||||||
|
#define R_386_32 1
|
||||||
|
#define R_386_PC32 2
|
||||||
|
#define R_386_GOT32 3
|
||||||
|
#define R_386_PLT32 4
|
||||||
|
#define R_386_COPY 5
|
||||||
|
#define R_386_GLOB_DAT 6
|
||||||
|
#define R_386_JMP_SLOT 7
|
||||||
|
#define R_386_RELATIVE 8
|
||||||
|
#define R_386_GOTOFF 9
|
||||||
|
#define R_386_GOTPC 10
|
||||||
|
#define R_386_NUM 11
|
||||||
|
|
||||||
|
typedef struct elf32_rel {
|
||||||
|
Elf32_Addr r_offset;
|
||||||
|
Elf32_Word r_info;
|
||||||
|
} Elf32_Rel;
|
||||||
|
|
||||||
|
typedef struct elf64_rel {
|
||||||
|
unsigned long long r_offset; /* Location at which to apply the action */
|
||||||
|
unsigned long long r_info; /* index and type of relocation */
|
||||||
|
} Elf64_Rel;
|
||||||
|
|
||||||
|
typedef struct elf32_rela{
|
||||||
|
Elf32_Addr r_offset;
|
||||||
|
Elf32_Word r_info;
|
||||||
|
Elf32_Sword r_addend;
|
||||||
|
} Elf32_Rela;
|
||||||
|
|
||||||
|
typedef struct elf64_rela {
|
||||||
|
unsigned long long r_offset; /* Location at which to apply the action */
|
||||||
|
unsigned long long r_info; /* index and type of relocation */
|
||||||
|
unsigned long long r_addend; /* Constant addend used to compute value */
|
||||||
|
} Elf64_Rela;
|
||||||
|
|
||||||
|
typedef struct elf32_sym{
|
||||||
|
Elf32_Word st_name;
|
||||||
|
Elf32_Addr st_value;
|
||||||
|
Elf32_Word st_size;
|
||||||
|
unsigned char st_info;
|
||||||
|
unsigned char st_other;
|
||||||
|
Elf32_Half st_shndx;
|
||||||
|
} Elf32_Sym;
|
||||||
|
|
||||||
|
typedef struct elf64_sym {
|
||||||
|
unsigned int st_name; /* Symbol name, index in string tbl */
|
||||||
|
unsigned char st_info; /* Type and binding attributes */
|
||||||
|
unsigned char st_other; /* No defined meaning, 0 */
|
||||||
|
unsigned short st_shndx; /* Associated section index */
|
||||||
|
unsigned long long st_value; /* Value of the symbol */
|
||||||
|
unsigned long long st_size; /* Associated symbol size */
|
||||||
|
} Elf64_Sym;
|
||||||
|
|
||||||
|
|
||||||
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
|
typedef struct elf32_hdr{
|
||||||
|
unsigned char e_ident[EI_NIDENT];
|
||||||
|
Elf32_Half e_type;
|
||||||
|
Elf32_Half e_machine;
|
||||||
|
Elf32_Word e_version;
|
||||||
|
Elf32_Addr e_entry; /* Entry point */
|
||||||
|
Elf32_Off e_phoff;
|
||||||
|
Elf32_Off e_shoff;
|
||||||
|
Elf32_Word e_flags;
|
||||||
|
Elf32_Half e_ehsize;
|
||||||
|
Elf32_Half e_phentsize;
|
||||||
|
Elf32_Half e_phnum;
|
||||||
|
Elf32_Half e_shentsize;
|
||||||
|
Elf32_Half e_shnum;
|
||||||
|
Elf32_Half e_shstrndx;
|
||||||
|
} Elf32_Ehdr;
|
||||||
|
|
||||||
|
typedef struct elf64_hdr {
|
||||||
|
unsigned char e_ident[16]; /* ELF "magic number" */
|
||||||
|
short int e_type;
|
||||||
|
short unsigned int e_machine;
|
||||||
|
int e_version;
|
||||||
|
unsigned long long e_entry; /* Entry point virtual address */
|
||||||
|
unsigned long long e_phoff; /* Program header table file offset */
|
||||||
|
unsigned long long e_shoff; /* Section header table file offset */
|
||||||
|
int e_flags;
|
||||||
|
short int e_ehsize;
|
||||||
|
short int e_phentsize;
|
||||||
|
short int e_phnum;
|
||||||
|
short int e_shentsize;
|
||||||
|
short int e_shnum;
|
||||||
|
short int e_shstrndx;
|
||||||
|
} Elf64_Ehdr;
|
||||||
|
|
||||||
|
/* These constants define the permissions on sections in the program
|
||||||
|
header, p_flags. */
|
||||||
|
#define PF_R 0x4
|
||||||
|
#define PF_W 0x2
|
||||||
|
#define PF_X 0x1
|
||||||
|
|
||||||
|
typedef struct elf32_phdr{
|
||||||
|
Elf32_Word p_type;
|
||||||
|
Elf32_Off p_offset;
|
||||||
|
Elf32_Addr p_vaddr;
|
||||||
|
Elf32_Addr p_paddr;
|
||||||
|
Elf32_Word p_filesz;
|
||||||
|
Elf32_Word p_memsz;
|
||||||
|
Elf32_Word p_flags;
|
||||||
|
Elf32_Word p_align;
|
||||||
|
} Elf32_Phdr;
|
||||||
|
|
||||||
|
typedef struct elf64_phdr {
|
||||||
|
int p_type;
|
||||||
|
int p_flags;
|
||||||
|
unsigned long long p_offset; /* Segment file offset */
|
||||||
|
unsigned long long p_vaddr; /* Segment virtual address */
|
||||||
|
unsigned long long p_paddr; /* Segment physical address */
|
||||||
|
unsigned long long p_filesz; /* Segment size in file */
|
||||||
|
unsigned long long p_memsz; /* Segment size in memory */
|
||||||
|
unsigned long long p_align; /* Segment alignment, file & memory */
|
||||||
|
} Elf64_Phdr;
|
||||||
|
|
||||||
|
/* sh_type */
|
||||||
|
#define SHT_NULL 0
|
||||||
|
#define SHT_PROGBITS 1
|
||||||
|
#define SHT_SYMTAB 2
|
||||||
|
#define SHT_STRTAB 3
|
||||||
|
#define SHT_RELA 4
|
||||||
|
#define SHT_HASH 5
|
||||||
|
#define SHT_DYNAMIC 6
|
||||||
|
#define SHT_NOTE 7
|
||||||
|
#define SHT_NOBITS 8
|
||||||
|
#define SHT_REL 9
|
||||||
|
#define SHT_SHLIB 10
|
||||||
|
#define SHT_DYNSYM 11
|
||||||
|
#define SHT_NUM 12
|
||||||
|
#define SHT_LOPROC 0x70000000
|
||||||
|
#define SHT_HIPROC 0x7fffffff
|
||||||
|
#define SHT_LOUSER 0x80000000
|
||||||
|
#define SHT_HIUSER 0xffffffff
|
||||||
|
|
||||||
|
/* sh_flags */
|
||||||
|
#define SHF_WRITE 0x1
|
||||||
|
#define SHF_ALLOC 0x2
|
||||||
|
#define SHF_EXECINSTR 0x4
|
||||||
|
#define SHF_MASKPROC 0xf0000000
|
||||||
|
|
||||||
|
/* special section indexes */
|
||||||
|
#define SHN_UNDEF 0
|
||||||
|
#define SHN_LORESERVE 0xff00
|
||||||
|
#define SHN_LOPROC 0xff00
|
||||||
|
#define SHN_HIPROC 0xff1f
|
||||||
|
#define SHN_ABS 0xfff1
|
||||||
|
#define SHN_COMMON 0xfff2
|
||||||
|
#define SHN_HIRESERVE 0xffff
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word sh_name;
|
||||||
|
Elf32_Word sh_type;
|
||||||
|
Elf32_Word sh_flags;
|
||||||
|
Elf32_Addr sh_addr;
|
||||||
|
Elf32_Off sh_offset;
|
||||||
|
Elf32_Word sh_size;
|
||||||
|
Elf32_Word sh_link;
|
||||||
|
Elf32_Word sh_info;
|
||||||
|
Elf32_Word sh_addralign;
|
||||||
|
Elf32_Word sh_entsize;
|
||||||
|
} Elf32_Shdr;
|
||||||
|
|
||||||
|
typedef struct elf64_shdr {
|
||||||
|
unsigned int sh_name; /* Section name, index in string tbl */
|
||||||
|
unsigned int sh_type; /* Type of section */
|
||||||
|
unsigned long long sh_flags; /* Miscellaneous section attributes */
|
||||||
|
unsigned long long sh_addr; /* Section virtual addr at execution */
|
||||||
|
unsigned long long sh_offset; /* Section file offset */
|
||||||
|
unsigned long long sh_size; /* Size of section in bytes */
|
||||||
|
unsigned int sh_link; /* Index of another section */
|
||||||
|
unsigned int sh_info; /* Additional section information */
|
||||||
|
unsigned long long sh_addralign; /* Section alignment */
|
||||||
|
unsigned long long sh_entsize; /* Entry size if section holds table */
|
||||||
|
} Elf64_Shdr;
|
||||||
|
|
||||||
|
#define EI_MAG0 0 /* e_ident[] indexes */
|
||||||
|
#define EI_MAG1 1
|
||||||
|
#define EI_MAG2 2
|
||||||
|
#define EI_MAG3 3
|
||||||
|
#define EI_CLASS 4
|
||||||
|
#define EI_DATA 5
|
||||||
|
#define EI_VERSION 6
|
||||||
|
#define EI_PAD 7
|
||||||
|
|
||||||
|
#define ELFMAG0 0x7f /* EI_MAG */
|
||||||
|
#define ELFMAG1 'E'
|
||||||
|
#define ELFMAG2 'L'
|
||||||
|
#define ELFMAG3 'F'
|
||||||
|
#define ELFMAG "\177ELF"
|
||||||
|
#define SELFMAG 4
|
||||||
|
|
||||||
|
#define ELFCLASSNONE 0 /* EI_CLASS */
|
||||||
|
#define ELFCLASS32 1
|
||||||
|
#define ELFCLASS64 2
|
||||||
|
#define ELFCLASSNUM 3
|
||||||
|
|
||||||
|
#define ELFDATANONE 0 /* e_ident[EI_DATA] */
|
||||||
|
#define ELFDATA2LSB 1
|
||||||
|
#define ELFDATA2MSB 2
|
||||||
|
|
||||||
|
#define EV_NONE 0 /* e_version, EI_VERSION */
|
||||||
|
#define EV_CURRENT 1
|
||||||
|
#define EV_NUM 2
|
||||||
|
|
||||||
|
/* Notes used in ET_CORE */
|
||||||
|
#define NT_PRSTATUS 1
|
||||||
|
#define NT_PRFPREG 2
|
||||||
|
#define NT_PRPSINFO 3
|
||||||
|
#define NT_TASKSTRUCT 4
|
||||||
|
|
||||||
|
/* Note header in a PT_NOTE section */
|
||||||
|
typedef struct elf32_note {
|
||||||
|
Elf32_Word n_namesz; /* Name size */
|
||||||
|
Elf32_Word n_descsz; /* Content size */
|
||||||
|
Elf32_Word n_type; /* Content type */
|
||||||
|
} Elf32_Nhdr;
|
||||||
|
|
||||||
|
/* Note header in a PT_NOTE section */
|
||||||
|
/*
|
||||||
|
* For now we use the 32 bit version of the structure until we figure
|
||||||
|
* out whether we need anything better. Note - on the Alpha, "unsigned int"
|
||||||
|
* is only 32 bits.
|
||||||
|
*/
|
||||||
|
typedef struct elf64_note {
|
||||||
|
unsigned int n_namesz; /* Name size */
|
||||||
|
unsigned int n_descsz; /* Content size */
|
||||||
|
unsigned int n_type; /* Content type */
|
||||||
|
} Elf64_Nhdr;
|
||||||
|
|
||||||
|
#define ELF_START_MMAP 0x80000000
|
||||||
|
|
||||||
|
#if ELF_CLASS == ELFCLASS32
|
||||||
|
|
||||||
|
extern Elf32_Dyn _DYNAMIC [];
|
||||||
|
#define elfhdr elf32_hdr
|
||||||
|
#define elf_phdr elf32_phdr
|
||||||
|
#define elf_note elf32_note
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern Elf64_Dyn _DYNAMIC [];
|
||||||
|
#define elfhdr elf64_hdr
|
||||||
|
#define elf_phdr elf64_phdr
|
||||||
|
#define elf_note elf64_note
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
130
i386.ld
Normal file
130
i386.ld
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/* ld script to make i386 Linux kernel
|
||||||
|
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
|
||||||
|
*/
|
||||||
|
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||||
|
OUTPUT_ARCH(i386)
|
||||||
|
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
|
||||||
|
ENTRY(_start)
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* Read-only sections, merged into text segment: */
|
||||||
|
. = 0x60000000 + SIZEOF_HEADERS;
|
||||||
|
.interp : { *(.interp) }
|
||||||
|
.hash : { *(.hash) }
|
||||||
|
.dynsym : { *(.dynsym) }
|
||||||
|
.dynstr : { *(.dynstr) }
|
||||||
|
.gnu.version : { *(.gnu.version) }
|
||||||
|
.gnu.version_d : { *(.gnu.version_d) }
|
||||||
|
.gnu.version_r : { *(.gnu.version_r) }
|
||||||
|
.rel.text :
|
||||||
|
{ *(.rel.text) *(.rel.gnu.linkonce.t*) }
|
||||||
|
.rela.text :
|
||||||
|
{ *(.rela.text) *(.rela.gnu.linkonce.t*) }
|
||||||
|
.rel.data :
|
||||||
|
{ *(.rel.data) *(.rel.gnu.linkonce.d*) }
|
||||||
|
.rela.data :
|
||||||
|
{ *(.rela.data) *(.rela.gnu.linkonce.d*) }
|
||||||
|
.rel.rodata :
|
||||||
|
{ *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
|
||||||
|
.rela.rodata :
|
||||||
|
{ *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
|
||||||
|
.rel.got : { *(.rel.got) }
|
||||||
|
.rela.got : { *(.rela.got) }
|
||||||
|
.rel.ctors : { *(.rel.ctors) }
|
||||||
|
.rela.ctors : { *(.rela.ctors) }
|
||||||
|
.rel.dtors : { *(.rel.dtors) }
|
||||||
|
.rela.dtors : { *(.rela.dtors) }
|
||||||
|
.rel.init : { *(.rel.init) }
|
||||||
|
.rela.init : { *(.rela.init) }
|
||||||
|
.rel.fini : { *(.rel.fini) }
|
||||||
|
.rela.fini : { *(.rela.fini) }
|
||||||
|
.rel.bss : { *(.rel.bss) }
|
||||||
|
.rela.bss : { *(.rela.bss) }
|
||||||
|
.rel.plt : { *(.rel.plt) }
|
||||||
|
.rela.plt : { *(.rela.plt) }
|
||||||
|
.init : { *(.init) } =0x47ff041f
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.text)
|
||||||
|
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||||
|
*(.gnu.warning)
|
||||||
|
*(.gnu.linkonce.t*)
|
||||||
|
} =0x47ff041f
|
||||||
|
_etext = .;
|
||||||
|
PROVIDE (etext = .);
|
||||||
|
.fini : { *(.fini) } =0x47ff041f
|
||||||
|
.rodata : { *(.rodata) *(.gnu.linkonce.r*) }
|
||||||
|
.rodata1 : { *(.rodata1) }
|
||||||
|
.reginfo : { *(.reginfo) }
|
||||||
|
/* Adjust the address for the data segment. We want to adjust up to
|
||||||
|
the same address within the page on the next page up. */
|
||||||
|
. = ALIGN(0x100000) + (. & (0x100000 - 1));
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
*(.gnu.linkonce.d*)
|
||||||
|
CONSTRUCTORS
|
||||||
|
}
|
||||||
|
.data1 : { *(.data1) }
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
*(.ctors)
|
||||||
|
}
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
*(.dtors)
|
||||||
|
}
|
||||||
|
.plt : { *(.plt) }
|
||||||
|
.got : { *(.got.plt) *(.got) }
|
||||||
|
.dynamic : { *(.dynamic) }
|
||||||
|
/* We want the small data sections together, so single-instruction offsets
|
||||||
|
can access them all, and initialized data all before uninitialized, so
|
||||||
|
we can shorten the on-disk segment size. */
|
||||||
|
.sdata : { *(.sdata) }
|
||||||
|
_edata = .;
|
||||||
|
PROVIDE (edata = .);
|
||||||
|
__bss_start = .;
|
||||||
|
.sbss : { *(.sbss) *(.scommon) }
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
*(.dynbss)
|
||||||
|
*(.bss)
|
||||||
|
*(COMMON)
|
||||||
|
}
|
||||||
|
_end = . ;
|
||||||
|
PROVIDE (end = .);
|
||||||
|
/* Stabs debugging sections. */
|
||||||
|
.stab 0 : { *(.stab) }
|
||||||
|
.stabstr 0 : { *(.stabstr) }
|
||||||
|
.stab.excl 0 : { *(.stab.excl) }
|
||||||
|
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||||
|
.stab.index 0 : { *(.stab.index) }
|
||||||
|
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||||
|
.comment 0 : { *(.comment) }
|
||||||
|
/* DWARF debug sections.
|
||||||
|
Symbols in the DWARF debugging sections are relative to the beginning
|
||||||
|
of the section so we begin them at 0. */
|
||||||
|
/* DWARF 1 */
|
||||||
|
.debug 0 : { *(.debug) }
|
||||||
|
.line 0 : { *(.line) }
|
||||||
|
/* GNU DWARF 1 extensions */
|
||||||
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
/* DWARF 1.1 and DWARF 2 */
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
/* DWARF 2 */
|
||||||
|
.debug_info 0 : { *(.debug_info) }
|
||||||
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||||
|
.debug_line 0 : { *(.debug_line) }
|
||||||
|
.debug_frame 0 : { *(.debug_frame) }
|
||||||
|
.debug_str 0 : { *(.debug_str) }
|
||||||
|
.debug_loc 0 : { *(.debug_loc) }
|
||||||
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
/* SGI/MIPS DWARF 2 extensions */
|
||||||
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||||
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||||
|
.debug_typenames 0 : { *(.debug_typenames) }
|
||||||
|
.debug_varnames 0 : { *(.debug_varnames) }
|
||||||
|
/* These must appear regardless of . */
|
||||||
|
}
|
973
linux-user/elfload.c
Normal file
973
linux-user/elfload.c
Normal file
@ -0,0 +1,973 @@
|
|||||||
|
/* This is the Linux kernel elf-loading code, ported into user space */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gemu.h"
|
||||||
|
|
||||||
|
#include "linux_bin.h"
|
||||||
|
#include "elf.h"
|
||||||
|
#include "segment.h"
|
||||||
|
|
||||||
|
/* Necessary parameters */
|
||||||
|
#define ALPHA_PAGE_SIZE 4096
|
||||||
|
#define X86_PAGE_SIZE 4096
|
||||||
|
|
||||||
|
#define ALPHA_PAGE_MASK (~(ALPHA_PAGE_SIZE-1))
|
||||||
|
#define X86_PAGE_MASK (~(X86_PAGE_SIZE-1))
|
||||||
|
|
||||||
|
#define ALPHA_PAGE_ALIGN(addr) ((((addr)+ALPHA_PAGE_SIZE)-1)&ALPHA_PAGE_MASK)
|
||||||
|
#define X86_PAGE_ALIGN(addr) ((((addr)+X86_PAGE_SIZE)-1)&X86_PAGE_MASK)
|
||||||
|
|
||||||
|
#define NGROUPS 32
|
||||||
|
|
||||||
|
#define X86_ELF_EXEC_PAGESIZE X86_PAGE_SIZE
|
||||||
|
#define X86_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(X86_ELF_EXEC_PAGESIZE-1))
|
||||||
|
#define X86_ELF_PAGEOFFSET(_v) ((_v) & (X86_ELF_EXEC_PAGESIZE-1))
|
||||||
|
|
||||||
|
#define ALPHA_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ALPHA_PAGE_SIZE-1))
|
||||||
|
#define ALPHA_ELF_PAGEOFFSET(_v) ((_v) & (ALPHA_PAGE_SIZE-1))
|
||||||
|
|
||||||
|
#define INTERPRETER_NONE 0
|
||||||
|
#define INTERPRETER_AOUT 1
|
||||||
|
#define INTERPRETER_ELF 2
|
||||||
|
|
||||||
|
#define DLINFO_ITEMS 12
|
||||||
|
|
||||||
|
/* Where we find X86 libraries... */
|
||||||
|
//#define X86_DEFAULT_LIB_DIR "/usr/x86/"
|
||||||
|
#define X86_DEFAULT_LIB_DIR "/"
|
||||||
|
|
||||||
|
//extern void * mmap4k();
|
||||||
|
#define mmap4k(a, b, c, d, e, f) mmap((void *)(a), b, c, d, e, f)
|
||||||
|
|
||||||
|
extern unsigned long x86_stack_size;
|
||||||
|
|
||||||
|
static int load_aout_interp(void * exptr, int interp_fd);
|
||||||
|
|
||||||
|
#ifdef BSWAP_NEEDED
|
||||||
|
static void bswap_ehdr(Elf32_Ehdr *ehdr)
|
||||||
|
{
|
||||||
|
bswap16s(&ehdr->e_type); /* Object file type */
|
||||||
|
bswap16s(&ehdr->e_machine); /* Architecture */
|
||||||
|
bswap32s(&ehdr->e_version); /* Object file version */
|
||||||
|
bswap32s(&ehdr->e_entry); /* Entry point virtual address */
|
||||||
|
bswap32s(&ehdr->e_phoff); /* Program header table file offset */
|
||||||
|
bswap32s(&ehdr->e_shoff); /* Section header table file offset */
|
||||||
|
bswap32s(&ehdr->e_flags); /* Processor-specific flags */
|
||||||
|
bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
|
||||||
|
bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
|
||||||
|
bswap16s(&ehdr->e_phnum); /* Program header table entry count */
|
||||||
|
bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
|
||||||
|
bswap16s(&ehdr->e_shnum); /* Section header table entry count */
|
||||||
|
bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bswap_phdr(Elf32_Phdr *phdr)
|
||||||
|
{
|
||||||
|
bswap32s(&phdr->p_type); /* Segment type */
|
||||||
|
bswap32s(&phdr->p_offset); /* Segment file offset */
|
||||||
|
bswap32s(&phdr->p_vaddr); /* Segment virtual address */
|
||||||
|
bswap32s(&phdr->p_paddr); /* Segment physical address */
|
||||||
|
bswap32s(&phdr->p_filesz); /* Segment size in file */
|
||||||
|
bswap32s(&phdr->p_memsz); /* Segment size in memory */
|
||||||
|
bswap32s(&phdr->p_flags); /* Segment flags */
|
||||||
|
bswap32s(&phdr->p_align); /* Segment alignment */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void * get_free_page(void)
|
||||||
|
{
|
||||||
|
void * retval;
|
||||||
|
|
||||||
|
/* User-space version of kernel get_free_page. Returns a page-aligned
|
||||||
|
* page-sized chunk of memory.
|
||||||
|
*/
|
||||||
|
retval = mmap4k(0, ALPHA_PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||||
|
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||||
|
|
||||||
|
if((long)retval == -1) {
|
||||||
|
perror("get_free_page");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return(retval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_page(void * pageaddr)
|
||||||
|
{
|
||||||
|
(void)munmap(pageaddr, ALPHA_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'copy_string()' copies argument/envelope strings from user
|
||||||
|
* memory to free pages in kernel mem. These are in a format ready
|
||||||
|
* to be put directly into the top of new user memory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
|
||||||
|
unsigned long p)
|
||||||
|
{
|
||||||
|
char *tmp, *tmp1, *pag = NULL;
|
||||||
|
int len, offset = 0;
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
return 0; /* bullet-proofing */
|
||||||
|
}
|
||||||
|
while (argc-- > 0) {
|
||||||
|
if (!(tmp1 = tmp = get_user(argv+argc))) {
|
||||||
|
fprintf(stderr, "VFS: argc is wrong");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
while (get_user(tmp++));
|
||||||
|
len = tmp - tmp1;
|
||||||
|
if (p < len) { /* this shouldn't happen - 128kB */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (len) {
|
||||||
|
--p; --tmp; --len;
|
||||||
|
if (--offset < 0) {
|
||||||
|
offset = p % X86_PAGE_SIZE;
|
||||||
|
if (!(pag = (char *) page[p/X86_PAGE_SIZE]) &&
|
||||||
|
!(pag = (char *) page[p/X86_PAGE_SIZE] =
|
||||||
|
(unsigned long *) get_free_page())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (len == 0 || offset == 0) {
|
||||||
|
*(pag + offset) = get_user(tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int bytes_to_copy = (len > offset) ? offset : len;
|
||||||
|
tmp -= bytes_to_copy;
|
||||||
|
p -= bytes_to_copy;
|
||||||
|
offset -= bytes_to_copy;
|
||||||
|
len -= bytes_to_copy;
|
||||||
|
memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int in_group_p(gid_t g)
|
||||||
|
{
|
||||||
|
/* return TRUE if we're in the specified group, FALSE otherwise */
|
||||||
|
int ngroup;
|
||||||
|
int i;
|
||||||
|
gid_t grouplist[NGROUPS];
|
||||||
|
|
||||||
|
ngroup = getgroups(NGROUPS, grouplist);
|
||||||
|
for(i = 0; i < ngroup; i++) {
|
||||||
|
if(grouplist[i] == g) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count(char ** vec)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; *vec; i++) {
|
||||||
|
vec++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prepare_binprm(struct linux_binprm *bprm)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
int mode;
|
||||||
|
int retval, id_change;
|
||||||
|
|
||||||
|
if(fstat(bprm->fd, &st) < 0) {
|
||||||
|
return(-errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = st.st_mode;
|
||||||
|
if(!S_ISREG(mode)) { /* Must be regular file */
|
||||||
|
return(-EACCES);
|
||||||
|
}
|
||||||
|
if(!(mode & 0111)) { /* Must have at least one execute bit set */
|
||||||
|
return(-EACCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
bprm->e_uid = geteuid();
|
||||||
|
bprm->e_gid = getegid();
|
||||||
|
id_change = 0;
|
||||||
|
|
||||||
|
/* Set-uid? */
|
||||||
|
if(mode & S_ISUID) {
|
||||||
|
bprm->e_uid = st.st_uid;
|
||||||
|
if(bprm->e_uid != geteuid()) {
|
||||||
|
id_change = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set-gid? */
|
||||||
|
/*
|
||||||
|
* If setgid is set but no group execute bit then this
|
||||||
|
* is a candidate for mandatory locking, not a setgid
|
||||||
|
* executable.
|
||||||
|
*/
|
||||||
|
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
|
||||||
|
bprm->e_gid = st.st_gid;
|
||||||
|
if (!in_group_p(bprm->e_gid)) {
|
||||||
|
id_change = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(bprm->buf, 0, sizeof(bprm->buf));
|
||||||
|
retval = lseek(bprm->fd, 0L, SEEK_SET);
|
||||||
|
if(retval >= 0) {
|
||||||
|
retval = read(bprm->fd, bprm->buf, 128);
|
||||||
|
}
|
||||||
|
if(retval < 0) {
|
||||||
|
perror("prepare_binprm");
|
||||||
|
exit(-1);
|
||||||
|
/* return(-errno); */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return(retval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
|
||||||
|
struct image_info * info)
|
||||||
|
{
|
||||||
|
unsigned long stack_base;
|
||||||
|
int i;
|
||||||
|
extern unsigned long stktop;
|
||||||
|
|
||||||
|
stack_base = X86_STACK_TOP - MAX_ARG_PAGES*X86_PAGE_SIZE;
|
||||||
|
|
||||||
|
p += stack_base;
|
||||||
|
if (bprm->loader) {
|
||||||
|
bprm->loader += stack_base;
|
||||||
|
}
|
||||||
|
bprm->exec += stack_base;
|
||||||
|
|
||||||
|
/* Create enough stack to hold everything. If we don't use
|
||||||
|
* it for args, we'll use it for something else...
|
||||||
|
*/
|
||||||
|
if(x86_stack_size > MAX_ARG_PAGES*X86_PAGE_SIZE) {
|
||||||
|
if((long)mmap4k((void *)(X86_STACK_TOP-x86_stack_size), x86_stack_size + X86_PAGE_SIZE,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_GROWSDOWN | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
|
||||||
|
perror("stk mmap");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if((long)mmap4k((void *)stack_base, (MAX_ARG_PAGES+1)*X86_PAGE_SIZE,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_GROWSDOWN | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
|
||||||
|
perror("stk mmap");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stktop = stack_base;
|
||||||
|
|
||||||
|
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
|
||||||
|
if (bprm->page[i]) {
|
||||||
|
info->rss++;
|
||||||
|
|
||||||
|
memcpy((void *)stack_base, (void *)bprm->page[i], X86_PAGE_SIZE);
|
||||||
|
free_page((void *)bprm->page[i]);
|
||||||
|
}
|
||||||
|
stack_base += X86_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_brk(unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
/* page-align the start and end addresses... */
|
||||||
|
start = ALPHA_PAGE_ALIGN(start);
|
||||||
|
end = ALPHA_PAGE_ALIGN(end);
|
||||||
|
if (end <= start)
|
||||||
|
return;
|
||||||
|
if((long)mmap4k(start, end - start,
|
||||||
|
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||||
|
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
|
||||||
|
perror("cannot mmap brk");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* We need to explicitly zero any fractional pages
|
||||||
|
after the data section (i.e. bss). This would
|
||||||
|
contain the junk from the file that should not
|
||||||
|
be in memory */
|
||||||
|
|
||||||
|
|
||||||
|
static void padzero(unsigned long elf_bss)
|
||||||
|
{
|
||||||
|
unsigned long nbyte;
|
||||||
|
char * fpnt;
|
||||||
|
|
||||||
|
nbyte = elf_bss & (ALPHA_PAGE_SIZE-1); /* was X86_PAGE_SIZE - JRP */
|
||||||
|
if (nbyte) {
|
||||||
|
nbyte = ALPHA_PAGE_SIZE - nbyte;
|
||||||
|
fpnt = (char *) elf_bss;
|
||||||
|
do {
|
||||||
|
*fpnt++ = 0;
|
||||||
|
} while (--nbyte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int * create_elf_tables(char *p, int argc, int envc,
|
||||||
|
struct elfhdr * exec,
|
||||||
|
unsigned long load_addr,
|
||||||
|
unsigned long interp_load_addr, int ibcs,
|
||||||
|
struct image_info *info)
|
||||||
|
{
|
||||||
|
unsigned int *argv, *envp, *dlinfo;
|
||||||
|
unsigned int *sp;
|
||||||
|
char **alpha_envp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force 16 byte alignment here for generality.
|
||||||
|
*/
|
||||||
|
sp = (unsigned int *) (~15UL & (unsigned long) p);
|
||||||
|
sp -= exec ? DLINFO_ITEMS*2 : 2;
|
||||||
|
dlinfo = sp;
|
||||||
|
sp -= envc+1;
|
||||||
|
envp = sp;
|
||||||
|
sp -= argc+1;
|
||||||
|
argv = sp;
|
||||||
|
if (!ibcs) {
|
||||||
|
put_user(envp,--sp);
|
||||||
|
put_user(argv,--sp);
|
||||||
|
}
|
||||||
|
alpha_envp = (char **)malloc((envc+1) * sizeof(char *));
|
||||||
|
|
||||||
|
#define NEW_AUX_ENT(id, val) \
|
||||||
|
put_user ((id), dlinfo++); \
|
||||||
|
put_user ((val), dlinfo++)
|
||||||
|
|
||||||
|
if (exec) { /* Put this here for an ELF program interpreter */
|
||||||
|
struct elf_phdr * eppnt;
|
||||||
|
eppnt = (struct elf_phdr *)((unsigned long)exec->e_phoff);
|
||||||
|
|
||||||
|
NEW_AUX_ENT (AT_PHDR, (unsigned int)(load_addr + exec->e_phoff));
|
||||||
|
NEW_AUX_ENT (AT_PHENT, (unsigned int)(sizeof (struct elf_phdr)));
|
||||||
|
NEW_AUX_ENT (AT_PHNUM, (unsigned int)(exec->e_phnum));
|
||||||
|
NEW_AUX_ENT (AT_PAGESZ, (unsigned int)(ALPHA_PAGE_SIZE));
|
||||||
|
NEW_AUX_ENT (AT_BASE, (unsigned int)(interp_load_addr));
|
||||||
|
NEW_AUX_ENT (AT_FLAGS, (unsigned int)0);
|
||||||
|
NEW_AUX_ENT (AT_ENTRY, (unsigned int) exec->e_entry);
|
||||||
|
NEW_AUX_ENT (AT_UID, (unsigned int) getuid());
|
||||||
|
NEW_AUX_ENT (AT_EUID, (unsigned int) geteuid());
|
||||||
|
NEW_AUX_ENT (AT_GID, (unsigned int) getgid());
|
||||||
|
NEW_AUX_ENT (AT_EGID, (unsigned int) getegid());
|
||||||
|
}
|
||||||
|
NEW_AUX_ENT (AT_NULL, 0);
|
||||||
|
#undef NEW_AUX_ENT
|
||||||
|
put_user((unsigned int)argc,--sp);
|
||||||
|
info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
|
||||||
|
while (argc-->0) {
|
||||||
|
put_user(p,argv++);
|
||||||
|
while (get_user(p++)) /* nothing */ ;
|
||||||
|
}
|
||||||
|
put_user(0,argv);
|
||||||
|
info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
|
||||||
|
__environ = alpha_envp;
|
||||||
|
while (envc-->0) {
|
||||||
|
*alpha_envp++ = (char *)p;
|
||||||
|
put_user(p,envp++);
|
||||||
|
while (get_user(p++)) /* nothing */ ;
|
||||||
|
}
|
||||||
|
put_user(0,envp);
|
||||||
|
*alpha_envp = 0;
|
||||||
|
info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
|
||||||
|
int interpreter_fd,
|
||||||
|
unsigned long *interp_load_addr)
|
||||||
|
{
|
||||||
|
struct elf_phdr *elf_phdata = NULL;
|
||||||
|
struct elf_phdr *eppnt;
|
||||||
|
unsigned long load_addr;
|
||||||
|
int load_addr_set = 0;
|
||||||
|
int retval;
|
||||||
|
unsigned long last_bss, elf_bss;
|
||||||
|
unsigned long error;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
elf_bss = 0;
|
||||||
|
last_bss = 0;
|
||||||
|
error = 0;
|
||||||
|
|
||||||
|
/* We put this here so that mmap will search for the *first*
|
||||||
|
* available memory...
|
||||||
|
*/
|
||||||
|
load_addr = INTERP_LOADADDR;
|
||||||
|
|
||||||
|
/* First of all, some simple consistency checks */
|
||||||
|
if ((interp_elf_ex->e_type != ET_EXEC &&
|
||||||
|
interp_elf_ex->e_type != ET_DYN) ||
|
||||||
|
!elf_check_arch(interp_elf_ex->e_machine)) {
|
||||||
|
return ~0UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now read in all of the header information */
|
||||||
|
|
||||||
|
if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > X86_PAGE_SIZE)
|
||||||
|
return ~0UL;
|
||||||
|
|
||||||
|
elf_phdata = (struct elf_phdr *)
|
||||||
|
malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
|
||||||
|
|
||||||
|
if (!elf_phdata)
|
||||||
|
return ~0UL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the size of this structure has changed, then punt, since
|
||||||
|
* we will be doing the wrong thing.
|
||||||
|
*/
|
||||||
|
if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
|
||||||
|
{
|
||||||
|
free(elf_phdata);
|
||||||
|
return ~0UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
|
||||||
|
if(retval >= 0) {
|
||||||
|
retval = read(interpreter_fd,
|
||||||
|
(char *) elf_phdata,
|
||||||
|
sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval < 0) {
|
||||||
|
perror("load_elf_interp");
|
||||||
|
exit(-1);
|
||||||
|
free (elf_phdata);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
#ifdef BSWAP_NEEDED
|
||||||
|
eppnt = elf_phdata;
|
||||||
|
for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
|
||||||
|
bswap_phdr(eppnt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
eppnt = elf_phdata;
|
||||||
|
for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
|
||||||
|
if (eppnt->p_type == PT_LOAD) {
|
||||||
|
int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
|
||||||
|
int elf_prot = 0;
|
||||||
|
unsigned long vaddr = 0;
|
||||||
|
unsigned long k;
|
||||||
|
|
||||||
|
if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
|
||||||
|
if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
|
||||||
|
if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
|
||||||
|
if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
|
||||||
|
elf_type |= MAP_FIXED;
|
||||||
|
vaddr = eppnt->p_vaddr;
|
||||||
|
}
|
||||||
|
error = (unsigned long)mmap4k(load_addr+X86_ELF_PAGESTART(vaddr),
|
||||||
|
eppnt->p_filesz + X86_ELF_PAGEOFFSET(eppnt->p_vaddr),
|
||||||
|
elf_prot,
|
||||||
|
elf_type,
|
||||||
|
interpreter_fd,
|
||||||
|
eppnt->p_offset - X86_ELF_PAGEOFFSET(eppnt->p_vaddr));
|
||||||
|
|
||||||
|
if (error > -1024UL) {
|
||||||
|
/* Real error */
|
||||||
|
close(interpreter_fd);
|
||||||
|
free(elf_phdata);
|
||||||
|
return ~0UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
|
||||||
|
load_addr = error;
|
||||||
|
load_addr_set = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the end of the file mapping for this phdr, and keep
|
||||||
|
* track of the largest address we see for this.
|
||||||
|
*/
|
||||||
|
k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
|
||||||
|
if (k > elf_bss) elf_bss = k;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the same thing for the memory mapping - between
|
||||||
|
* elf_bss and last_bss is the bss section.
|
||||||
|
*/
|
||||||
|
k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
|
||||||
|
if (k > last_bss) last_bss = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now use mmap to map the library into memory. */
|
||||||
|
|
||||||
|
close(interpreter_fd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now fill out the bss section. First pad the last page up
|
||||||
|
* to the page boundary, and then perform a mmap to make sure
|
||||||
|
* that there are zeromapped pages up to and including the last
|
||||||
|
* bss page.
|
||||||
|
*/
|
||||||
|
padzero(elf_bss);
|
||||||
|
elf_bss = X86_ELF_PAGESTART(elf_bss + ALPHA_PAGE_SIZE - 1); /* What we have mapped so far */
|
||||||
|
|
||||||
|
/* Map the last of the bss segment */
|
||||||
|
if (last_bss > elf_bss) {
|
||||||
|
mmap4k(elf_bss, last_bss-elf_bss,
|
||||||
|
PROT_READ|PROT_WRITE|PROT_EXEC,
|
||||||
|
MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||||
|
}
|
||||||
|
free(elf_phdata);
|
||||||
|
|
||||||
|
*interp_load_addr = load_addr;
|
||||||
|
return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs,
|
||||||
|
struct image_info * info)
|
||||||
|
{
|
||||||
|
struct elfhdr elf_ex;
|
||||||
|
struct elfhdr interp_elf_ex;
|
||||||
|
struct exec interp_ex;
|
||||||
|
int interpreter_fd = -1; /* avoid warning */
|
||||||
|
unsigned long load_addr;
|
||||||
|
int load_addr_set = 0;
|
||||||
|
unsigned int interpreter_type = INTERPRETER_NONE;
|
||||||
|
unsigned char ibcs2_interpreter;
|
||||||
|
int i;
|
||||||
|
void * mapped_addr;
|
||||||
|
struct elf_phdr * elf_ppnt;
|
||||||
|
struct elf_phdr *elf_phdata;
|
||||||
|
unsigned long elf_bss, k, elf_brk;
|
||||||
|
int retval;
|
||||||
|
char * elf_interpreter;
|
||||||
|
unsigned long elf_entry, interp_load_addr = 0;
|
||||||
|
int status;
|
||||||
|
unsigned long start_code, end_code, end_data;
|
||||||
|
unsigned long elf_stack;
|
||||||
|
char passed_fileno[6];
|
||||||
|
|
||||||
|
ibcs2_interpreter = 0;
|
||||||
|
status = 0;
|
||||||
|
load_addr = 0;
|
||||||
|
elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
|
||||||
|
#ifdef BSWAP_NEEDED
|
||||||
|
bswap_ehdr(&elf_ex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (elf_ex.e_ident[0] != 0x7f ||
|
||||||
|
strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
|
||||||
|
return -ENOEXEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* First of all, some simple consistency checks */
|
||||||
|
if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
|
||||||
|
(! elf_check_arch(elf_ex.e_machine))) {
|
||||||
|
return -ENOEXEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now read in all of the header information */
|
||||||
|
|
||||||
|
elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
|
||||||
|
if (elf_phdata == NULL) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
|
||||||
|
if(retval > 0) {
|
||||||
|
retval = read(bprm->fd, (char *) elf_phdata,
|
||||||
|
elf_ex.e_phentsize * elf_ex.e_phnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval < 0) {
|
||||||
|
perror("load_elf_binary");
|
||||||
|
exit(-1);
|
||||||
|
free (elf_phdata);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
elf_ppnt = elf_phdata;
|
||||||
|
|
||||||
|
elf_bss = 0;
|
||||||
|
elf_brk = 0;
|
||||||
|
|
||||||
|
|
||||||
|
elf_stack = ~0UL;
|
||||||
|
elf_interpreter = NULL;
|
||||||
|
start_code = ~0UL;
|
||||||
|
end_code = 0;
|
||||||
|
end_data = 0;
|
||||||
|
|
||||||
|
for(i=0;i < elf_ex.e_phnum; i++) {
|
||||||
|
if (elf_ppnt->p_type == PT_INTERP) {
|
||||||
|
if ( elf_interpreter != NULL )
|
||||||
|
{
|
||||||
|
free (elf_phdata);
|
||||||
|
free(elf_interpreter);
|
||||||
|
close(bprm->fd);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the program interpreter used for
|
||||||
|
* shared libraries - for now assume that this
|
||||||
|
* is an a.out format binary
|
||||||
|
*/
|
||||||
|
|
||||||
|
elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+strlen(X86_DEFAULT_LIB_DIR));
|
||||||
|
|
||||||
|
if (elf_interpreter == NULL) {
|
||||||
|
free (elf_phdata);
|
||||||
|
close(bprm->fd);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(elf_interpreter, X86_DEFAULT_LIB_DIR);
|
||||||
|
retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
|
||||||
|
if(retval >= 0) {
|
||||||
|
retval = read(bprm->fd,
|
||||||
|
elf_interpreter+strlen(X86_DEFAULT_LIB_DIR),
|
||||||
|
elf_ppnt->p_filesz);
|
||||||
|
}
|
||||||
|
if(retval < 0) {
|
||||||
|
perror("load_elf_binary2");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the program interpreter is one of these two,
|
||||||
|
then assume an iBCS2 image. Otherwise assume
|
||||||
|
a native linux image. */
|
||||||
|
|
||||||
|
/* JRP - Need to add X86 lib dir stuff here... */
|
||||||
|
|
||||||
|
if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
|
||||||
|
strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
|
||||||
|
ibcs2_interpreter = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("Using ELF interpreter %s\n", elf_interpreter);
|
||||||
|
#endif
|
||||||
|
if (retval >= 0) {
|
||||||
|
retval = open(elf_interpreter, O_RDONLY);
|
||||||
|
if(retval >= 0) {
|
||||||
|
interpreter_fd = retval;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
perror(elf_interpreter);
|
||||||
|
exit(-1);
|
||||||
|
/* retval = -errno; */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval >= 0) {
|
||||||
|
retval = lseek(interpreter_fd, 0, SEEK_SET);
|
||||||
|
if(retval >= 0) {
|
||||||
|
retval = read(interpreter_fd,bprm->buf,128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (retval >= 0) {
|
||||||
|
interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
|
||||||
|
interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
|
||||||
|
}
|
||||||
|
if (retval < 0) {
|
||||||
|
perror("load_elf_binary3");
|
||||||
|
exit(-1);
|
||||||
|
free (elf_phdata);
|
||||||
|
free(elf_interpreter);
|
||||||
|
close(bprm->fd);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elf_ppnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some simple consistency checks for the interpreter */
|
||||||
|
if (elf_interpreter){
|
||||||
|
interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
|
||||||
|
|
||||||
|
/* Now figure out which format our binary is */
|
||||||
|
if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
|
||||||
|
(N_MAGIC(interp_ex) != QMAGIC)) {
|
||||||
|
interpreter_type = INTERPRETER_ELF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interp_elf_ex.e_ident[0] != 0x7f ||
|
||||||
|
strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
|
||||||
|
interpreter_type &= ~INTERPRETER_ELF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interpreter_type) {
|
||||||
|
free(elf_interpreter);
|
||||||
|
free(elf_phdata);
|
||||||
|
close(bprm->fd);
|
||||||
|
return -ELIBBAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OK, we are done with that, now set up the arg stuff,
|
||||||
|
and then start this sucker up */
|
||||||
|
|
||||||
|
if (!bprm->sh_bang) {
|
||||||
|
char * passed_p;
|
||||||
|
|
||||||
|
if (interpreter_type == INTERPRETER_AOUT) {
|
||||||
|
sprintf(passed_fileno, "%d", bprm->fd);
|
||||||
|
passed_p = passed_fileno;
|
||||||
|
|
||||||
|
if (elf_interpreter) {
|
||||||
|
bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
|
||||||
|
bprm->argc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bprm->p) {
|
||||||
|
if (elf_interpreter) {
|
||||||
|
free(elf_interpreter);
|
||||||
|
}
|
||||||
|
free (elf_phdata);
|
||||||
|
close(bprm->fd);
|
||||||
|
return -E2BIG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OK, This is the point of no return */
|
||||||
|
info->end_data = 0;
|
||||||
|
info->end_code = 0;
|
||||||
|
info->start_mmap = (unsigned long)ELF_START_MMAP;
|
||||||
|
info->mmap = 0;
|
||||||
|
elf_entry = (unsigned long) elf_ex.e_entry;
|
||||||
|
|
||||||
|
/* Do this so that we can load the interpreter, if need be. We will
|
||||||
|
change some of these later */
|
||||||
|
info->rss = 0;
|
||||||
|
bprm->p = setup_arg_pages(bprm->p, bprm, info);
|
||||||
|
info->start_stack = bprm->p;
|
||||||
|
|
||||||
|
/* Now we do a little grungy work by mmaping the ELF image into
|
||||||
|
* the correct location in memory. At this point, we assume that
|
||||||
|
* the image should be loaded at fixed address, not at a variable
|
||||||
|
* address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
|
||||||
|
if (elf_ppnt->p_type == PT_LOAD) {
|
||||||
|
int elf_prot = 0;
|
||||||
|
if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
|
||||||
|
if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
|
||||||
|
if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
|
||||||
|
|
||||||
|
mapped_addr = mmap4k(X86_ELF_PAGESTART(elf_ppnt->p_vaddr),
|
||||||
|
(elf_ppnt->p_filesz +
|
||||||
|
X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
|
||||||
|
elf_prot,
|
||||||
|
(MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
|
||||||
|
bprm->fd,
|
||||||
|
(elf_ppnt->p_offset -
|
||||||
|
X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
|
||||||
|
|
||||||
|
if((unsigned long)mapped_addr == 0xffffffffffffffff) {
|
||||||
|
perror("mmap");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LOW_ELF_STACK
|
||||||
|
if (X86_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
|
||||||
|
elf_stack = X86_ELF_PAGESTART(elf_ppnt->p_vaddr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!load_addr_set) {
|
||||||
|
load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
|
||||||
|
load_addr_set = 1;
|
||||||
|
}
|
||||||
|
k = elf_ppnt->p_vaddr;
|
||||||
|
if (k < start_code) start_code = k;
|
||||||
|
k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
|
||||||
|
if (k > elf_bss) elf_bss = k;
|
||||||
|
#if 1
|
||||||
|
if ((elf_ppnt->p_flags & PF_X) && end_code < k)
|
||||||
|
#else
|
||||||
|
if ( !(elf_ppnt->p_flags & PF_W) && end_code < k)
|
||||||
|
#endif
|
||||||
|
end_code = k;
|
||||||
|
if (end_data < k) end_data = k;
|
||||||
|
k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
|
||||||
|
if (k > elf_brk) elf_brk = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elf_interpreter) {
|
||||||
|
if (interpreter_type & 1) {
|
||||||
|
elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
|
||||||
|
}
|
||||||
|
else if (interpreter_type & 2) {
|
||||||
|
elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
|
||||||
|
&interp_load_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(interpreter_fd);
|
||||||
|
free(elf_interpreter);
|
||||||
|
|
||||||
|
if (elf_entry == ~0UL) {
|
||||||
|
printf("Unable to load interpreter\n");
|
||||||
|
free(elf_phdata);
|
||||||
|
exit(-1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(elf_phdata);
|
||||||
|
|
||||||
|
if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
|
||||||
|
info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
|
||||||
|
|
||||||
|
#ifdef LOW_ELF_STACK
|
||||||
|
info->start_stack = bprm->p = elf_stack - 4;
|
||||||
|
#endif
|
||||||
|
bprm->p = (unsigned long)
|
||||||
|
create_elf_tables((char *)bprm->p,
|
||||||
|
bprm->argc,
|
||||||
|
bprm->envc,
|
||||||
|
(interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
|
||||||
|
load_addr,
|
||||||
|
interp_load_addr,
|
||||||
|
(interpreter_type == INTERPRETER_AOUT ? 0 : 1),
|
||||||
|
info);
|
||||||
|
if (interpreter_type == INTERPRETER_AOUT)
|
||||||
|
info->arg_start += strlen(passed_fileno) + 1;
|
||||||
|
info->start_brk = info->brk = elf_brk;
|
||||||
|
info->end_code = end_code;
|
||||||
|
info->start_code = start_code;
|
||||||
|
info->end_data = end_data;
|
||||||
|
info->start_stack = bprm->p;
|
||||||
|
|
||||||
|
/* Calling set_brk effectively mmaps the pages that we need for the bss and break
|
||||||
|
sections */
|
||||||
|
set_brk(elf_bss, elf_brk);
|
||||||
|
|
||||||
|
padzero(elf_bss);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("(start_brk) %x\n" , info->start_brk);
|
||||||
|
printf("(end_code) %x\n" , info->end_code);
|
||||||
|
printf("(start_code) %x\n" , info->start_code);
|
||||||
|
printf("(end_data) %x\n" , info->end_data);
|
||||||
|
printf("(start_stack) %x\n" , info->start_stack);
|
||||||
|
printf("(brk) %x\n" , info->brk);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( info->personality == PER_SVR4 )
|
||||||
|
{
|
||||||
|
/* Why this, you ask??? Well SVr4 maps page 0 as read-only,
|
||||||
|
and some applications "depend" upon this behavior.
|
||||||
|
Since we do not have the power to recompile these, we
|
||||||
|
emulate the SVr4 behavior. Sigh. */
|
||||||
|
mapped_addr = mmap4k(NULL, ALPHA_PAGE_SIZE, PROT_READ | PROT_EXEC,
|
||||||
|
MAP_FIXED | MAP_PRIVATE, -1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ELF_PLAT_INIT
|
||||||
|
/*
|
||||||
|
* The ABI may specify that certain registers be set up in special
|
||||||
|
* ways (on i386 %edx is the address of a DT_FINI function, for
|
||||||
|
* example. This macro performs whatever initialization to
|
||||||
|
* the regs structure is required.
|
||||||
|
*/
|
||||||
|
ELF_PLAT_INIT(regs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
info->entry = elf_entry;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int elf_exec(const char * filename, char ** argv, char ** envp,
|
||||||
|
struct pt_regs * regs, struct image_info *infop)
|
||||||
|
{
|
||||||
|
struct linux_binprm bprm;
|
||||||
|
int retval;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bprm.p = X86_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
|
||||||
|
for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
|
||||||
|
bprm.page[i] = 0;
|
||||||
|
retval = open(filename, O_RDONLY);
|
||||||
|
if (retval == -1) {
|
||||||
|
perror(filename);
|
||||||
|
exit(-1);
|
||||||
|
/* return retval; */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bprm.fd = retval;
|
||||||
|
}
|
||||||
|
bprm.filename = (char *)filename;
|
||||||
|
bprm.sh_bang = 0;
|
||||||
|
bprm.loader = 0;
|
||||||
|
bprm.exec = 0;
|
||||||
|
bprm.dont_iput = 0;
|
||||||
|
bprm.argc = count(argv);
|
||||||
|
bprm.envc = count(envp);
|
||||||
|
|
||||||
|
retval = prepare_binprm(&bprm);
|
||||||
|
|
||||||
|
if(retval>=0) {
|
||||||
|
bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
|
||||||
|
bprm.exec = bprm.p;
|
||||||
|
bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
|
||||||
|
bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
|
||||||
|
if (!bprm.p) {
|
||||||
|
retval = -E2BIG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(retval>=0) {
|
||||||
|
retval = load_elf_binary(&bprm,regs,infop);
|
||||||
|
}
|
||||||
|
if(retval>=0) {
|
||||||
|
/* success. Initialize important registers */
|
||||||
|
regs->esp = infop->start_stack;
|
||||||
|
regs->eip = infop->entry;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Something went wrong, return the inode and free the argument pages*/
|
||||||
|
for (i=0 ; i<MAX_ARG_PAGES ; i++) {
|
||||||
|
free_page((void *)bprm.page[i]);
|
||||||
|
}
|
||||||
|
return(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int load_aout_interp(void * exptr, int interp_fd)
|
||||||
|
{
|
||||||
|
printf("a.out interpreter not yet supported\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
282
linux-user/ioctls.h
Normal file
282
linux-user/ioctls.h
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
/* emulated ioctl list */
|
||||||
|
|
||||||
|
IOCTL(TCGETS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||||
|
IOCTL(TCGETS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||||
|
IOCTL(TCSETSF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||||
|
IOCTL(TCSETSW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||||
|
IOCTL(TIOCGWINSZ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_winsize)))
|
||||||
|
IOCTL(TIOCSWINSZ, IOC_W, MK_PTR(MK_STRUCT(STRUCT_winsize)))
|
||||||
|
IOCTL(FIONREAD, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TCGETA, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TCSETA, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TCSETAW, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TCSETAF, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TCSBRK, 0, TYPE_INT)
|
||||||
|
IOCTL(TCSBRKP, 0, TYPE_INT)
|
||||||
|
IOCTL(TCXONC, 0, TYPE_INT)
|
||||||
|
IOCTL(TCFLSH, 0, TYPE_INT)
|
||||||
|
IOCTL(TIOCEXCL, 0, TYPE_NULL)
|
||||||
|
IOCTL(TIOCNXCL, 0, TYPE_NULL)
|
||||||
|
IOCTL(TIOCSCTTY, 0, TYPE_INT)
|
||||||
|
IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCMBIS, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCMBIC, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCMSET, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCGSOFTCAR, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCSSOFTCAR, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCLINUX, IOC_R | IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCCONS, 0, TYPE_NULL)
|
||||||
|
IOCTL(TIOCGSERIAL, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCSSERIAL, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCPKT, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(FIONBIO, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCNOTTY, 0, TYPE_NULL)
|
||||||
|
IOCTL(TIOCGETD, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(FIOCLEX, 0, TYPE_NULL)
|
||||||
|
IOCTL(FIONCLEX, 0, TYPE_NULL)
|
||||||
|
IOCTL(FIOASYNC, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCGLCKTRMIOS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||||
|
IOCTL(TIOCSLCKTRMIOS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||||
|
IOCTL(TIOCSERCONFIG, 0, TYPE_NULL)
|
||||||
|
IOCTL(TIOCSERGETLSR, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(TIOCSERGETMULTI, IOC_R, MK_PTR(MK_STRUCT(STRUCT_serial_multiport_struct)))
|
||||||
|
IOCTL(TIOCSERSETMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_serial_multiport_struct)))
|
||||||
|
IOCTL(TIOCMIWAIT, 0, TYPE_INT)
|
||||||
|
IOCTL(TIOCGICOUNT, IOC_R, MK_PTR(MK_STRUCT(STRUCT_serial_icounter_struct)))
|
||||||
|
|
||||||
|
IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(BLKRRPART, 0, TYPE_NULL)
|
||||||
|
IOCTL(BLKGETSIZE, IOC_R, MK_PTR(TYPE_ULONG))
|
||||||
|
#ifdef BLKGETSIZE64
|
||||||
|
IOCTL(BLKGETSIZE64, IOC_R, MK_PTR(TYPE_ULONGLONG))
|
||||||
|
#endif
|
||||||
|
IOCTL(BLKFLSBUF, 0, TYPE_NULL)
|
||||||
|
IOCTL(BLKRASET, 0, TYPE_INT)
|
||||||
|
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
|
||||||
|
#ifdef FIBMAP
|
||||||
|
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
|
||||||
|
#endif
|
||||||
|
#ifdef FIGETBSZ
|
||||||
|
IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IOCTL(SIOCADDRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
|
||||||
|
IOCTL(SIOCDELRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
|
||||||
|
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
|
||||||
|
IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
|
||||||
|
IOCTL(SIOCGIFADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCSIFADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCGIFBRDADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCSIFBRDADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCGIFDSTADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCSIFDSTADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCGIFNETMASK, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCSIFNETMASK, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCGIFHWADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCSIFHWADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCGIFTXQLEN, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCSIFTXQLEN, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCGIFMETRIC, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
|
||||||
|
IOCTL(SIOCSIFMETRIC, IOC_W, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
|
||||||
|
IOCTL(SIOCGIFMTU, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
|
||||||
|
IOCTL(SIOCSIFMTU, IOC_W, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
|
||||||
|
IOCTL(SIOCGIFMAP, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifmap_ifreq)))
|
||||||
|
IOCTL(SIOCSIFMAP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_ifmap_ifreq)))
|
||||||
|
IOCTL(SIOCGIFSLAVE, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
|
||||||
|
IOCTL(SIOCSIFSLAVE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
|
||||||
|
IOCTL(SIOCGIFMEM, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ptr_ifreq)))
|
||||||
|
IOCTL(SIOCSIFMEM, IOC_W, MK_PTR(MK_STRUCT(STRUCT_ptr_ifreq)))
|
||||||
|
IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||||
|
IOCTL(SIOCSIFLINK, 0, TYPE_NULL)
|
||||||
|
IOCTL(SIOCGIFCONF, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifconf)))
|
||||||
|
IOCTL(SIOCGIFENCAP, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SIOCSIFENCAP, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SIOCDARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||||
|
IOCTL(SIOCSARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||||
|
IOCTL(SIOCGARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||||
|
IOCTL(SIOCDRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||||
|
IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||||
|
IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||||
|
|
||||||
|
IOCTL(CDROMPAUSE, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROMSTART, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROMSTOP, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROMRESUME, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROMEJECT, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROMEJECT_SW, 0, TYPE_INT)
|
||||||
|
IOCTL(CDROMCLOSETRAY, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROMRESET, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROMPLAYMSF, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMPLAYTRKIND, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMREADTOCHDR, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMREADTOCENTRY, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMVOLCTRL, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMSUBCHNL, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
/* XXX: incorrect (need specific handling) */
|
||||||
|
IOCTL(CDROMREADAUDIO, IOC_W, MK_PTR(MK_STRUCT(STRUCT_cdrom_read_audio)))
|
||||||
|
IOCTL(CDROMREADCOOKED, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMREADRAW, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMREADMODE1, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMREADMODE2, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMREADALL, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMMULTISESSION, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROM_GET_UPC, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMVOLREAD, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMSEEK, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROMPLAYBLK, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(CDROM_MEDIA_CHANGED, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROM_SET_OPTIONS, 0, TYPE_INT)
|
||||||
|
IOCTL(CDROM_CLEAR_OPTIONS, 0, TYPE_INT)
|
||||||
|
IOCTL(CDROM_SELECT_SPEED, 0, TYPE_INT)
|
||||||
|
IOCTL(CDROM_SELECT_DISC, 0, TYPE_INT)
|
||||||
|
IOCTL(CDROM_DRIVE_STATUS, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROM_DISC_STATUS, 0, TYPE_NULL)
|
||||||
|
IOCTL(CDROMAUDIOBUFSIZ, 0, TYPE_INT)
|
||||||
|
|
||||||
|
IOCTL(SNDCTL_COPR_HALT, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_COPR_LOAD, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_COPR_RCODE, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_COPR_RCVMSG, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_COPR_RDATA, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_COPR_RESET, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_COPR_RUN, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_COPR_SENDMSG, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_COPR_WCODE, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_COPR_WDATA, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_CHANNELS, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_GETBLKSIZE, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_GETCAPS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_GETFMTS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_GETIPTR, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_GETISPACE, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_GETOPTR, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_GETOSPACE, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_GETTRIGGER, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_MAPINBUF, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_MAPOUTBUF, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_NONBLOCK, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_DSP_POST, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_DSP_RESET, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_DSP_SETDUPLEX, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_DSP_SETFMT, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_SETFRAGMENT, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_SETSYNCRO, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_DSP_SETTRIGGER, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_SPEED, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_STEREO, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_SUBDIVIDE, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_DSP_SYNC, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_FM_4OP_ENABLE, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_FM_LOAD_INSTR, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_MIDI_INFO, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_MIDI_MPUCMD, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_MIDI_MPUMODE, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_MIDI_PRETIME, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_CTRLRATE, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_GETINCOUNT, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_GETOUTCOUNT, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_NRMIDIS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_NRSYNTHS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_OUTOFBAND, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_PANIC, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_SEQ_PERCMODE, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_RESET, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_SEQ_RESETSAMPLES, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_SYNC, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_SEQ_TESTMIDI, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SEQ_THRESHOLD, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SYNTH_INFO, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_SYNTH_MEMAVL, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_TMR_CONTINUE, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_TMR_METRONOME, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_TMR_SELECT, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_TMR_SOURCE, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_TMR_START, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_TMR_STOP, 0, TYPE_NULL)
|
||||||
|
IOCTL(SNDCTL_TMR_TEMPO, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SNDCTL_TMR_TIMEBASE, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
|
||||||
|
IOCTL(SOUND_PCM_WRITE_FILTER, IOC_W | IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_PCM_READ_RATE, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_PCM_READ_CHANNELS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_PCM_READ_BITS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_PCM_READ_FILTER, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_INFO, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_ACCESS, 0, TYPE_PTRVOID)
|
||||||
|
IOCTL(SOUND_MIXER_PRIVATE1, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_PRIVATE2, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_PRIVATE3, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_PRIVATE4, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_PRIVATE5, IOC_RW, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_VOLUME, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_BASS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_TREBLE, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_SYNTH, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_PCM, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_SPEAKER, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_LINE, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_MIC, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_CD, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_IMIX, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_ALTPCM, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_RECLEV, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_IGAIN, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_OGAIN, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_LINE1, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_LINE2, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_LINE3, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_MUTE, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_ENHANCE, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_LOUD, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_RECSRC, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_DEVMASK, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_RECMASK, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_STEREODEVS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_READ_CAPS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_VOLUME, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_BASS, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_TREBLE, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_SYNTH, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_PCM, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_SPEAKER, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_LINE, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_MIC, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_CD, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_IMIX, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_ALTPCM, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_RECLEV, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_IGAIN, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_OGAIN, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_LINE1, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_LINE2, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_LINE3, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_MUTE, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_ENHANCE, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_LOUD, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(SOUND_MIXER_WRITE_RECSRC, IOC_W, MK_PTR(TYPE_INT))
|
||||||
|
|
||||||
|
IOCTL(HDIO_GETGEO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_hd_geometry)))
|
||||||
|
IOCTL(HDIO_GET_UNMASKINTR, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(HDIO_GET_MULTCOUNT, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(HDIO_GET_IDENTITY, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(HDIO_GET_KEEPSETTINGS, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(HDIO_GET_NOWERR, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(HDIO_GET_DMA, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(HDIO_GET_32BIT, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(HDIO_DRIVE_CMD, IOC_R, MK_PTR(TYPE_INT))
|
||||||
|
IOCTL(HDIO_SET_UNMASKINTR, 0, TYPE_INT)
|
||||||
|
IOCTL(HDIO_SET_MULTCOUNT, 0, TYPE_INT)
|
||||||
|
IOCTL(HDIO_SET_KEEPSETTINGS, 0, TYPE_INT)
|
||||||
|
IOCTL(HDIO_SET_NOWERR, 0, TYPE_INT)
|
||||||
|
IOCTL(HDIO_SET_DMA, 0, TYPE_INT)
|
||||||
|
IOCTL(HDIO_SET_32BIT, 0, TYPE_INT)
|
||||||
|
IOCTL(HDIO_SET_PIO_MODE, 0, TYPE_INT)
|
310
linux-user/main.c
Normal file
310
linux-user/main.c
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
* emu main
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Fabrice Bellard
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <elf.h>
|
||||||
|
#include <endian.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "gemu.h"
|
||||||
|
|
||||||
|
#include "i386/hsw_interp.h"
|
||||||
|
|
||||||
|
unsigned long x86_stack_size;
|
||||||
|
unsigned long stktop;
|
||||||
|
|
||||||
|
void gemu_log(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* virtual x86 CPU stuff */
|
||||||
|
|
||||||
|
extern int invoke_code16(Interp_ENV *, int, int);
|
||||||
|
extern int invoke_code32(Interp_ENV *, int);
|
||||||
|
extern char *e_print_cpuemu_regs(ENVPARAMS, int is32);
|
||||||
|
extern char *e_emu_disasm(ENVPARAMS, unsigned char *org, int is32);
|
||||||
|
extern void init_npu(void);
|
||||||
|
|
||||||
|
Interp_ENV env_global;
|
||||||
|
Interp_ENV *envp_global;
|
||||||
|
|
||||||
|
QWORD EMUtime = 0;
|
||||||
|
|
||||||
|
int CEmuStat = 0;
|
||||||
|
|
||||||
|
long instr_count;
|
||||||
|
|
||||||
|
/* who will initialize this? */
|
||||||
|
unsigned long io_bitmap[IO_BITMAP_SIZE+1];
|
||||||
|
|
||||||
|
/* debug flag, 0=disable 1..9=level */
|
||||||
|
int d_emu = 0;
|
||||||
|
|
||||||
|
unsigned long CRs[5] =
|
||||||
|
{
|
||||||
|
0x00000013, /* valid bits: 0xe005003f */
|
||||||
|
0x00000000, /* invalid */
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DR0-3 = linear address of breakpoint 0-3
|
||||||
|
* DR4=5 = reserved
|
||||||
|
* DR6 b0-b3 = BP active
|
||||||
|
* b13 = BD
|
||||||
|
* b14 = BS
|
||||||
|
* b15 = BT
|
||||||
|
* DR7 b0-b1 = G:L bp#0
|
||||||
|
* b2-b3 = G:L bp#1
|
||||||
|
* b4-b5 = G:L bp#2
|
||||||
|
* b6-b7 = G:L bp#3
|
||||||
|
* b8-b9 = GE:LE
|
||||||
|
* b13 = GD
|
||||||
|
* b16-19= LLRW bp#0 LL=00(1),01(2),11(4)
|
||||||
|
* b20-23= LLRW bp#1 RW=00(x),01(w),11(rw)
|
||||||
|
* b24-27= LLRW bp#2
|
||||||
|
* b28-31= LLRW bp#3
|
||||||
|
*/
|
||||||
|
unsigned long DRs[8] =
|
||||||
|
{
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0xffff1ff0,
|
||||||
|
0x00000400,
|
||||||
|
0xffff1ff0,
|
||||||
|
0x00000400
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned long TRs[2] =
|
||||||
|
{
|
||||||
|
0x00000000,
|
||||||
|
0x00000000
|
||||||
|
};
|
||||||
|
|
||||||
|
void FatalAppExit(UINT wAction, LPCSTR lpText)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Fatal error '%s' in CPU\n", lpText);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int e_debug_check(unsigned char *PC)
|
||||||
|
{
|
||||||
|
register unsigned long d7 = DRs[7];
|
||||||
|
|
||||||
|
if (d7&0x03) {
|
||||||
|
if (d7&0x30000) return 0; /* only execute(00) bkp */
|
||||||
|
if ((long)PC==DRs[0]) {
|
||||||
|
e_printf("DBRK: DR0 hit at %p\n",PC);
|
||||||
|
DRs[6] |= 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (d7&0x0c) {
|
||||||
|
if (d7&0x300000) return 0;
|
||||||
|
if ((long)PC==DRs[1]) {
|
||||||
|
e_printf("DBRK: DR1 hit at %p\n",PC);
|
||||||
|
DRs[6] |= 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (d7&0x30) {
|
||||||
|
if (d7&0x3000000) return 0;
|
||||||
|
if ((long)PC==DRs[2]) {
|
||||||
|
e_printf("DBRK: DR2 hit at %p\n",PC);
|
||||||
|
DRs[6] |= 4;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (d7&0xc0) {
|
||||||
|
if (d7&0x30000000) return 0;
|
||||||
|
if ((long)PC==DRs[3]) {
|
||||||
|
e_printf("DBRK: DR3 hit at %p\n",PC);
|
||||||
|
DRs[6] |= 8;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Debug stuff */
|
||||||
|
void logstr(unsigned long mask, const char *fmt,...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unconditional message into debug log and stderr */
|
||||||
|
#undef error
|
||||||
|
void error(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PortIO(DWORD port, DWORD value, UINT size, BOOL is_write)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "IO: %s port=0x%lx value=0x%lx size=%d",
|
||||||
|
is_write ? "write" : "read", port, value, size);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogProcName(WORD wSel, WORD wOff, WORD wAction)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void INT_handler(int num, void *env)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "EM86: int %d\n", num);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************/
|
||||||
|
|
||||||
|
/* XXX: currently we use LDT entries */
|
||||||
|
#define __USER_CS (0x23|4)
|
||||||
|
#define __USER_DS (0x2B|4)
|
||||||
|
|
||||||
|
void usage(void)
|
||||||
|
{
|
||||||
|
printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n"
|
||||||
|
"usage: gemu program [arguments...]\n"
|
||||||
|
"Linux x86 emulator\n"
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *filename;
|
||||||
|
struct pt_regs regs1, *regs = ®s1;
|
||||||
|
struct image_info info1, *info = &info1;
|
||||||
|
Interp_ENV *env;
|
||||||
|
|
||||||
|
if (argc <= 1)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
filename = argv[1];
|
||||||
|
|
||||||
|
/* Zero out regs */
|
||||||
|
memset(regs, 0, sizeof(struct pt_regs));
|
||||||
|
|
||||||
|
/* Zero out image_info */
|
||||||
|
memset(info, 0, sizeof(struct image_info));
|
||||||
|
|
||||||
|
if(elf_exec(filename, argv+1, __environ, regs, info) != 0) {
|
||||||
|
printf("Error loading %s\n", filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("start_brk 0x%08lx\n" , info->start_brk);
|
||||||
|
printf("end_code 0x%08lx\n" , info->end_code);
|
||||||
|
printf("start_code 0x%08lx\n" , info->start_code);
|
||||||
|
printf("end_data 0x%08lx\n" , info->end_data);
|
||||||
|
printf("start_stack 0x%08lx\n" , info->start_stack);
|
||||||
|
printf("brk 0x%08lx\n" , info->brk);
|
||||||
|
printf("esp 0x%08lx\n" , regs->esp);
|
||||||
|
printf("eip 0x%08lx\n" , regs->eip);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
target_set_brk((char *)info->brk);
|
||||||
|
syscall_init();
|
||||||
|
|
||||||
|
env = &env_global;
|
||||||
|
envp_global = env;
|
||||||
|
memset(env, 0, sizeof(Interp_ENV));
|
||||||
|
|
||||||
|
env->rax.e = regs->eax;
|
||||||
|
env->rbx.e = regs->ebx;
|
||||||
|
env->rcx.e = regs->ecx;
|
||||||
|
env->rdx.e = regs->edx;
|
||||||
|
env->rsi.esi = regs->esi;
|
||||||
|
env->rdi.edi = regs->edi;
|
||||||
|
env->rbp.ebp = regs->ebp;
|
||||||
|
env->rsp.esp = regs->esp;
|
||||||
|
env->cs.cs = __USER_CS;
|
||||||
|
env->ds.ds = __USER_DS;
|
||||||
|
env->es.es = __USER_DS;
|
||||||
|
env->ss.ss = __USER_DS;
|
||||||
|
env->fs.fs = __USER_DS;
|
||||||
|
env->gs.gs = __USER_DS;
|
||||||
|
env->trans_addr = regs->eip;
|
||||||
|
|
||||||
|
LDT[__USER_CS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
|
||||||
|
LDT[__USER_CS >> 3].dwSelLimit = 0xfffff;
|
||||||
|
LDT[__USER_CS >> 3].lpSelBase = NULL;
|
||||||
|
|
||||||
|
LDT[__USER_DS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
|
||||||
|
LDT[__USER_DS >> 3].dwSelLimit = 0xfffff;
|
||||||
|
LDT[__USER_DS >> 3].lpSelBase = NULL;
|
||||||
|
init_npu();
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
int err;
|
||||||
|
uint8_t *pc;
|
||||||
|
|
||||||
|
err = invoke_code32(env, -1);
|
||||||
|
env->trans_addr = env->return_addr;
|
||||||
|
pc = env->seg_regs[0] + env->trans_addr;
|
||||||
|
switch(err) {
|
||||||
|
case EXCP0D_GPF:
|
||||||
|
if (pc[0] == 0xcd && pc[1] == 0x80) {
|
||||||
|
/* syscall */
|
||||||
|
env->trans_addr += 2;
|
||||||
|
env->rax.e = do_syscall(env->rax.e,
|
||||||
|
env->rbx.e,
|
||||||
|
env->rcx.e,
|
||||||
|
env->rdx.e,
|
||||||
|
env->rsi.esi,
|
||||||
|
env->rdi.edi,
|
||||||
|
env->rbp.ebp);
|
||||||
|
} else {
|
||||||
|
goto trap_error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
trap_error:
|
||||||
|
fprintf(stderr, "GEMU: Unknown error %d, aborting\n", err);
|
||||||
|
d_emu = 9;
|
||||||
|
fprintf(stderr, "%s\n%s\n",
|
||||||
|
e_print_cpuemu_regs(env, 1),
|
||||||
|
e_emu_disasm(env,pc,1));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
57
linux-user/qemu.h
Normal file
57
linux-user/qemu.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef GEMU_H
|
||||||
|
#define GEMU_H
|
||||||
|
|
||||||
|
#include "thunk.h"
|
||||||
|
|
||||||
|
struct pt_regs {
|
||||||
|
long ebx;
|
||||||
|
long ecx;
|
||||||
|
long edx;
|
||||||
|
long esi;
|
||||||
|
long edi;
|
||||||
|
long ebp;
|
||||||
|
long eax;
|
||||||
|
int xds;
|
||||||
|
int xes;
|
||||||
|
long orig_eax;
|
||||||
|
long eip;
|
||||||
|
int xcs;
|
||||||
|
long eflags;
|
||||||
|
long esp;
|
||||||
|
int xss;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This struct is used to hold certain information about the image.
|
||||||
|
* Basically, it replicates in user space what would be certain
|
||||||
|
* task_struct fields in the kernel
|
||||||
|
*/
|
||||||
|
struct image_info {
|
||||||
|
unsigned long start_code;
|
||||||
|
unsigned long end_code;
|
||||||
|
unsigned long end_data;
|
||||||
|
unsigned long start_brk;
|
||||||
|
unsigned long brk;
|
||||||
|
unsigned long start_mmap;
|
||||||
|
unsigned long mmap;
|
||||||
|
unsigned long rss;
|
||||||
|
unsigned long start_stack;
|
||||||
|
unsigned long arg_start;
|
||||||
|
unsigned long arg_end;
|
||||||
|
unsigned long env_start;
|
||||||
|
unsigned long env_end;
|
||||||
|
unsigned long entry;
|
||||||
|
int personality;
|
||||||
|
};
|
||||||
|
|
||||||
|
int elf_exec(const char * filename, char ** argv, char ** envp,
|
||||||
|
struct pt_regs * regs, struct image_info *infop);
|
||||||
|
|
||||||
|
void target_set_brk(char *new_brk);
|
||||||
|
void syscall_init(void);
|
||||||
|
long do_syscall(int num, long arg1, long arg2, long arg3,
|
||||||
|
long arg4, long arg5, long arg6);
|
||||||
|
void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
105
linux-user/signal.c
Normal file
105
linux-user/signal.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Emulation of Linux signal handling
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Fabrice Bellard
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/ucontext.h>
|
||||||
|
|
||||||
|
/* Algorithm strongly inspired from em86 : we queue the signals so
|
||||||
|
that we can handle them at precise points in the emulated code. */
|
||||||
|
|
||||||
|
struct emulated_sigaction {
|
||||||
|
struct target_sigaction sa;
|
||||||
|
int nb_pending;
|
||||||
|
struct target_siginfo info;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct emulated_sigaction sigact_table[NSIG];
|
||||||
|
int signal_pending;
|
||||||
|
|
||||||
|
static inline int host_to_target_signal(int sig)
|
||||||
|
{
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int target_to_host_signal(int sig)
|
||||||
|
{
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
void signal_init(void)
|
||||||
|
{
|
||||||
|
struct sigaction act;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* set all host signal handlers */
|
||||||
|
sigemptyset(&act.sa_mask);
|
||||||
|
act.sa_flags = SA_SIGINFO;
|
||||||
|
act.sa_sigaction = host_signal_handler;
|
||||||
|
for(i = 1; i < NSIG; i++) {
|
||||||
|
sigaction(i, &sa, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(sigact_table, 0, sizeof(sigact_table));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void host_signal_handler(int host_signum, siginfo_t *info,
|
||||||
|
void *puc)
|
||||||
|
{
|
||||||
|
struct ucontext *uc = puc;
|
||||||
|
int signum;
|
||||||
|
/* get target signal number */
|
||||||
|
signum = host_to_target(host_signum);
|
||||||
|
if (signum >= TARGET_NSIG)
|
||||||
|
return;
|
||||||
|
/* we save the old mask */
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void process_pending_signals(void)
|
||||||
|
{
|
||||||
|
int signum;
|
||||||
|
target_ulong _sa_handler;
|
||||||
|
|
||||||
|
struct emulated_sigaction *esig;
|
||||||
|
|
||||||
|
if (!signal_pending)
|
||||||
|
return;
|
||||||
|
|
||||||
|
esig = sigact_table;
|
||||||
|
for(signum = 1; signum < TARGET_NSIG; signum++) {
|
||||||
|
if (esig->nb_pending != 0)
|
||||||
|
goto handle_signal;
|
||||||
|
esig++;
|
||||||
|
}
|
||||||
|
/* if no signal is pending, just return */
|
||||||
|
signal_pending = 0;
|
||||||
|
return;
|
||||||
|
handle_signal:
|
||||||
|
_sa_handler = esig->sa._sa_handler;
|
||||||
|
if (_sa_handler == TARGET_SIG_DFL) {
|
||||||
|
/* default handling
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
1349
linux-user/syscall.c
Normal file
1349
linux-user/syscall.c
Normal file
File diff suppressed because it is too large
Load Diff
283
linux-user/syscall_defs.h
Normal file
283
linux-user/syscall_defs.h
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
|
||||||
|
/* common syscall defines for all architectures */
|
||||||
|
|
||||||
|
#define SOCKOP_socket 1
|
||||||
|
#define SOCKOP_bind 2
|
||||||
|
#define SOCKOP_connect 3
|
||||||
|
#define SOCKOP_listen 4
|
||||||
|
#define SOCKOP_accept 5
|
||||||
|
#define SOCKOP_getsockname 6
|
||||||
|
#define SOCKOP_getpeername 7
|
||||||
|
#define SOCKOP_socketpair 8
|
||||||
|
#define SOCKOP_send 9
|
||||||
|
#define SOCKOP_recv 10
|
||||||
|
#define SOCKOP_sendto 11
|
||||||
|
#define SOCKOP_recvfrom 12
|
||||||
|
#define SOCKOP_shutdown 13
|
||||||
|
#define SOCKOP_setsockopt 14
|
||||||
|
#define SOCKOP_getsockopt 15
|
||||||
|
#define SOCKOP_sendmsg 16
|
||||||
|
#define SOCKOP_recvmsg 17
|
||||||
|
|
||||||
|
struct target_timeval {
|
||||||
|
target_long tv_sec;
|
||||||
|
target_long tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct target_iovec {
|
||||||
|
target_long iov_base; /* Starting address */
|
||||||
|
target_long iov_len; /* Number of bytes */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct target_rusage {
|
||||||
|
struct target_timeval ru_utime; /* user time used */
|
||||||
|
struct target_timeval ru_stime; /* system time used */
|
||||||
|
target_long ru_maxrss; /* maximum resident set size */
|
||||||
|
target_long ru_ixrss; /* integral shared memory size */
|
||||||
|
target_long ru_idrss; /* integral unshared data size */
|
||||||
|
target_long ru_isrss; /* integral unshared stack size */
|
||||||
|
target_long ru_minflt; /* page reclaims */
|
||||||
|
target_long ru_majflt; /* page faults */
|
||||||
|
target_long ru_nswap; /* swaps */
|
||||||
|
target_long ru_inblock; /* block input operations */
|
||||||
|
target_long ru_oublock; /* block output operations */
|
||||||
|
target_long ru_msgsnd; /* messages sent */
|
||||||
|
target_long ru_msgrcv; /* messages received */
|
||||||
|
target_long ru_nsignals; /* signals received */
|
||||||
|
target_long ru_nvcsw; /* voluntary context switches */
|
||||||
|
target_long ru_nivcsw; /* involuntary " */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int val[2];
|
||||||
|
} kernel_fsid_t;
|
||||||
|
|
||||||
|
struct statfs {
|
||||||
|
int f_type;
|
||||||
|
int f_bsize;
|
||||||
|
int f_blocks;
|
||||||
|
int f_bfree;
|
||||||
|
int f_bavail;
|
||||||
|
int f_files;
|
||||||
|
int f_ffree;
|
||||||
|
kernel_fsid_t f_fsid;
|
||||||
|
int f_namelen;
|
||||||
|
int f_spare[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* mostly generic signal stuff */
|
||||||
|
#define TARGET_SIG_DFL ((target_long)0) /* default signal handling */
|
||||||
|
#define TARGET_SIG_IGN ((target_long)1) /* ignore signal */
|
||||||
|
#define TARGET_SIG_ERR ((target_long)-1) /* error return from signal */
|
||||||
|
|
||||||
|
#ifdef TARGET_MIPS
|
||||||
|
#define TARGET_NSIG 128
|
||||||
|
#else
|
||||||
|
#define TARGET_NSIG 64
|
||||||
|
#endif
|
||||||
|
#define TARGET_NSIG_BPW TARGET_LONG_BITS
|
||||||
|
#define TARGET_NSIG_WORDS (TARGET_NSIG / TARGET_NSIG_BPW)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
target_ulong sig[TARGET_NSIG_WORDS];
|
||||||
|
} target_sigset_t;
|
||||||
|
|
||||||
|
/* Networking ioctls */
|
||||||
|
#define TARGET_SIOCADDRT 0x890B /* add routing table entry */
|
||||||
|
#define TARGET_SIOCDELRT 0x890C /* delete routing table entry */
|
||||||
|
#define TARGET_SIOCGIFNAME 0x8910 /* get iface name */
|
||||||
|
#define TARGET_SIOCSIFLINK 0x8911 /* set iface channel */
|
||||||
|
#define TARGET_SIOCGIFCONF 0x8912 /* get iface list */
|
||||||
|
#define TARGET_SIOCGIFFLAGS 0x8913 /* get flags */
|
||||||
|
#define TARGET_SIOCSIFFLAGS 0x8914 /* set flags */
|
||||||
|
#define TARGET_SIOCGIFADDR 0x8915 /* get PA address */
|
||||||
|
#define TARGET_SIOCSIFADDR 0x8916 /* set PA address */
|
||||||
|
#define TARGET_SIOCGIFDSTADDR 0x8917 /* get remote PA address */
|
||||||
|
#define TARGET_SIOCSIFDSTADDR 0x8918 /* set remote PA address */
|
||||||
|
#define TARGET_SIOCGIFBRDADDR 0x8919 /* get broadcast PA address */
|
||||||
|
#define TARGET_SIOCSIFBRDADDR 0x891a /* set broadcast PA address */
|
||||||
|
#define TARGET_SIOCGIFNETMASK 0x891b /* get network PA mask */
|
||||||
|
#define TARGET_SIOCSIFNETMASK 0x891c /* set network PA mask */
|
||||||
|
#define TARGET_SIOCGIFMETRIC 0x891d /* get metric */
|
||||||
|
#define TARGET_SIOCSIFMETRIC 0x891e /* set metric */
|
||||||
|
#define TARGET_SIOCGIFMEM 0x891f /* get memory address (BSD) */
|
||||||
|
#define TARGET_SIOCSIFMEM 0x8920 /* set memory address (BSD) */
|
||||||
|
#define TARGET_SIOCGIFMTU 0x8921 /* get MTU size */
|
||||||
|
#define TARGET_SIOCSIFMTU 0x8922 /* set MTU size */
|
||||||
|
#define TARGET_SIOCSIFHWADDR 0x8924 /* set hardware address (NI) */
|
||||||
|
#define TARGET_SIOCGIFENCAP 0x8925 /* get/set slip encapsulation */
|
||||||
|
#define TARGET_SIOCSIFENCAP 0x8926
|
||||||
|
#define TARGET_SIOCGIFHWADDR 0x8927 /* Get hardware address */
|
||||||
|
#define TARGET_SIOCGIFSLAVE 0x8929 /* Driver slaving support */
|
||||||
|
#define TARGET_SIOCSIFSLAVE 0x8930
|
||||||
|
#define TARGET_SIOCADDMULTI 0x8931 /* Multicast address lists */
|
||||||
|
#define TARGET_SIOCDELMULTI 0x8932
|
||||||
|
|
||||||
|
/* Bridging control calls */
|
||||||
|
#define TARGET_SIOCGIFBR 0x8940 /* Bridging support */
|
||||||
|
#define TARGET_SIOCSIFBR 0x8941 /* Set bridging options */
|
||||||
|
|
||||||
|
#define TARGET_SIOCGIFTXQLEN 0x8942 /* Get the tx queue length */
|
||||||
|
#define TARGET_SIOCSIFTXQLEN 0x8943 /* Set the tx queue length */
|
||||||
|
|
||||||
|
/* ARP cache control calls. */
|
||||||
|
#define TARGET_OLD_SIOCDARP 0x8950 /* old delete ARP table entry */
|
||||||
|
#define TARGET_OLD_SIOCGARP 0x8951 /* old get ARP table entry */
|
||||||
|
#define TARGET_OLD_SIOCSARP 0x8952 /* old set ARP table entry */
|
||||||
|
#define TARGET_SIOCDARP 0x8953 /* delete ARP table entry */
|
||||||
|
#define TARGET_SIOCGARP 0x8954 /* get ARP table entry */
|
||||||
|
#define TARGET_SIOCSARP 0x8955 /* set ARP table entry */
|
||||||
|
|
||||||
|
/* RARP cache control calls. */
|
||||||
|
#define TARGET_SIOCDRARP 0x8960 /* delete RARP table entry */
|
||||||
|
#define TARGET_SIOCGRARP 0x8961 /* get RARP table entry */
|
||||||
|
#define TARGET_SIOCSRARP 0x8962 /* set RARP table entry */
|
||||||
|
|
||||||
|
/* Driver configuration calls */
|
||||||
|
#define TARGET_SIOCGIFMAP 0x8970 /* Get device parameters */
|
||||||
|
#define TARGET_SIOCSIFMAP 0x8971 /* Set device parameters */
|
||||||
|
|
||||||
|
/* DLCI configuration calls */
|
||||||
|
#define TARGET_SIOCADDDLCI 0x8980 /* Create new DLCI device */
|
||||||
|
#define TARGET_SIOCDELDLCI 0x8981 /* Delete DLCI device */
|
||||||
|
|
||||||
|
|
||||||
|
/* From <linux/fs.h> */
|
||||||
|
|
||||||
|
#define TARGET_BLKROSET TARGET_IO(0x12,93) /* set device read-only (0 = read-write) */
|
||||||
|
#define TARGET_BLKROGET TARGET_IO(0x12,94) /* get read-only status (0 = read_write) */
|
||||||
|
#define TARGET_BLKRRPART TARGET_IO(0x12,95) /* re-read partition table */
|
||||||
|
#define TARGET_BLKGETSIZE TARGET_IO(0x12,96) /* return device size /512 (long *arg) */
|
||||||
|
#define TARGET_BLKFLSBUF TARGET_IO(0x12,97) /* flush buffer cache */
|
||||||
|
#define TARGET_BLKRASET TARGET_IO(0x12,98) /* Set read ahead for block device */
|
||||||
|
#define TARGET_BLKRAGET TARGET_IO(0x12,99) /* get current read ahead setting */
|
||||||
|
#define TARGET_BLKFRASET TARGET_IO(0x12,100)/* set filesystem (mm/filemap.c) read-ahead */
|
||||||
|
#define TARGET_BLKFRAGET TARGET_IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */
|
||||||
|
#define TARGET_BLKSECTSET TARGET_IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
|
||||||
|
#define TARGET_BLKSECTGET TARGET_IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
|
||||||
|
#define TARGET_BLKSSZGET TARGET_IO(0x12,104)/* get block device sector size */
|
||||||
|
/* A jump here: 108-111 have been used for various private purposes. */
|
||||||
|
#define TARGET_BLKBSZGET TARGET_IOR(0x12,112,sizeof(int))
|
||||||
|
#define TARGET_BLKBSZSET TARGET_IOW(0x12,113,sizeof(int))
|
||||||
|
#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */
|
||||||
|
#define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */
|
||||||
|
#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */
|
||||||
|
|
||||||
|
/* cdrom commands */
|
||||||
|
#define TARGET_CDROMPAUSE 0x5301 /* Pause Audio Operation */
|
||||||
|
#define TARGET_CDROMRESUME 0x5302 /* Resume paused Audio Operation */
|
||||||
|
#define TARGET_CDROMPLAYMSF 0x5303 /* Play Audio MSF (struct cdrom_msf) */
|
||||||
|
#define TARGET_CDROMPLAYTRKIND 0x5304 /* Play Audio Track/index
|
||||||
|
(struct cdrom_ti) */
|
||||||
|
#define TARGET_CDROMREADTOCHDR 0x5305 /* Read TOC header
|
||||||
|
(struct cdrom_tochdr) */
|
||||||
|
#define TARGET_CDROMREADTOCENTRY 0x5306 /* Read TOC entry
|
||||||
|
(struct cdrom_tocentry) */
|
||||||
|
#define TARGET_CDROMSTOP 0x5307 /* Stop the cdrom drive */
|
||||||
|
#define TARGET_CDROMSTART 0x5308 /* Start the cdrom drive */
|
||||||
|
#define TARGET_CDROMEJECT 0x5309 /* Ejects the cdrom media */
|
||||||
|
#define TARGET_CDROMVOLCTRL 0x530a /* Control output volume
|
||||||
|
(struct cdrom_volctrl) */
|
||||||
|
#define TARGET_CDROMSUBCHNL 0x530b /* Read subchannel data
|
||||||
|
(struct cdrom_subchnl) */
|
||||||
|
#define TARGET_CDROMREADMODE2 0x530c /* Read TARGET_CDROM mode 2 data (2336 Bytes)
|
||||||
|
(struct cdrom_read) */
|
||||||
|
#define TARGET_CDROMREADMODE1 0x530d /* Read TARGET_CDROM mode 1 data (2048 Bytes)
|
||||||
|
(struct cdrom_read) */
|
||||||
|
#define TARGET_CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */
|
||||||
|
#define TARGET_CDROMEJECT_SW 0x530f /* enable(1)/disable(0) auto-ejecting */
|
||||||
|
#define TARGET_CDROMMULTISESSION 0x5310 /* Obtain the start-of-last-session
|
||||||
|
address of multi session disks
|
||||||
|
(struct cdrom_multisession) */
|
||||||
|
#define TARGET_CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code"
|
||||||
|
if available (struct cdrom_mcn) */
|
||||||
|
#define TARGET_CDROM_GET_UPC TARGET_CDROM_GET_MCN /* This one is depricated,
|
||||||
|
but here anyway for compatability */
|
||||||
|
#define TARGET_CDROMRESET 0x5312 /* hard-reset the drive */
|
||||||
|
#define TARGET_CDROMVOLREAD 0x5313 /* Get the drive's volume setting
|
||||||
|
(struct cdrom_volctrl) */
|
||||||
|
#define TARGET_CDROMREADRAW 0x5314 /* read data in raw mode (2352 Bytes)
|
||||||
|
(struct cdrom_read) */
|
||||||
|
/*
|
||||||
|
* These ioctls are used only used in aztcd.c and optcd.c
|
||||||
|
*/
|
||||||
|
#define TARGET_CDROMREADCOOKED 0x5315 /* read data in cooked mode */
|
||||||
|
#define TARGET_CDROMSEEK 0x5316 /* seek msf address */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This ioctl is only used by the scsi-cd driver.
|
||||||
|
It is for playing audio in logical block addressing mode.
|
||||||
|
*/
|
||||||
|
#define TARGET_CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These ioctls are only used in optcd.c
|
||||||
|
*/
|
||||||
|
#define TARGET_CDROMREADALL 0x5318 /* read all 2646 bytes */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These ioctls are (now) only in ide-cd.c for controlling
|
||||||
|
* drive spindown time. They should be implemented in the
|
||||||
|
* Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10,
|
||||||
|
* GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE...
|
||||||
|
* -Erik
|
||||||
|
*/
|
||||||
|
#define TARGET_CDROMGETSPINDOWN 0x531d
|
||||||
|
#define TARGET_CDROMSETSPINDOWN 0x531e
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These ioctls are implemented through the uniform CD-ROM driver
|
||||||
|
* They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM
|
||||||
|
* drivers are eventually ported to the uniform CD-ROM driver interface.
|
||||||
|
*/
|
||||||
|
#define TARGET_CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */
|
||||||
|
#define TARGET_CDROM_SET_OPTIONS 0x5320 /* Set behavior options */
|
||||||
|
#define TARGET_CDROM_CLEAR_OPTIONS 0x5321 /* Clear behavior options */
|
||||||
|
#define TARGET_CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
|
||||||
|
#define TARGET_CDROM_SELECT_DISC 0x5323 /* Select disc (for juke-boxes) */
|
||||||
|
#define TARGET_CDROM_MEDIA_CHANGED 0x5325 /* Check is media changed */
|
||||||
|
#define TARGET_CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */
|
||||||
|
#define TARGET_CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */
|
||||||
|
#define TARGET_CDROM_CHANGER_NSLOTS 0x5328 /* Get number of slots */
|
||||||
|
#define TARGET_CDROM_LOCKDOOR 0x5329 /* lock or unlock door */
|
||||||
|
#define TARGET_CDROM_DEBUG 0x5330 /* Turn debug messages on/off */
|
||||||
|
#define TARGET_CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
|
||||||
|
|
||||||
|
/* Note that scsi/scsi_ioctl.h also uses 0x5382 - 0x5386.
|
||||||
|
* Future CDROM ioctls should be kept below 0x537F
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This ioctl is only used by sbpcd at the moment */
|
||||||
|
#define TARGET_CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */
|
||||||
|
/* conflict with SCSI_IOCTL_GET_IDLUN */
|
||||||
|
|
||||||
|
/* DVD-ROM Specific ioctls */
|
||||||
|
#define TARGET_DVD_READ_STRUCT 0x5390 /* Read structure */
|
||||||
|
#define TARGET_DVD_WRITE_STRUCT 0x5391 /* Write structure */
|
||||||
|
#define TARGET_DVD_AUTH 0x5392 /* Authentication */
|
||||||
|
|
||||||
|
#define TARGET_CDROM_SEND_PACKET 0x5393 /* send a packet to the drive */
|
||||||
|
#define TARGET_CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */
|
||||||
|
#define TARGET_CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */
|
||||||
|
|
||||||
|
/* HD commands */
|
||||||
|
|
||||||
|
/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */
|
||||||
|
#define TARGET_HDIO_GETGEO 0x0301 /* get device geometry */
|
||||||
|
#define TARGET_HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */
|
||||||
|
#define TARGET_HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */
|
||||||
|
#define TARGET_HDIO_GET_IDENTITY 0x0307 /* get IDE identification info */
|
||||||
|
#define TARGET_HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */
|
||||||
|
#define TARGET_HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */
|
||||||
|
#define TARGET_HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */
|
||||||
|
#define TARGET_HDIO_GET_DMA 0x030b /* get use-dma flag */
|
||||||
|
#define TARGET_HDIO_DRIVE_CMD 0x031f /* execute a special drive command */
|
||||||
|
|
||||||
|
/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
|
||||||
|
#define TARGET_HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */
|
||||||
|
#define TARGET_HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */
|
||||||
|
#define TARGET_HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */
|
||||||
|
#define TARGET_HDIO_SET_32BIT 0x0324 /* change io_32bit flags */
|
||||||
|
#define TARGET_HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */
|
||||||
|
#define TARGET_HDIO_SET_DMA 0x0326 /* change use-dma flag */
|
||||||
|
#define TARGET_HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */
|
64
linux-user/syscall_types.h
Normal file
64
linux-user/syscall_types.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
STRUCT_SPECIAL(termios)
|
||||||
|
|
||||||
|
STRUCT(winsize,
|
||||||
|
TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT)
|
||||||
|
|
||||||
|
STRUCT(serial_multiport_struct,
|
||||||
|
TYPE_INT, TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_CHAR, TYPE_CHAR,
|
||||||
|
TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT,
|
||||||
|
MK_ARRAY(TYPE_INT, 32))
|
||||||
|
|
||||||
|
STRUCT(serial_icounter_struct,
|
||||||
|
TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, MK_ARRAY(TYPE_INT, 16))
|
||||||
|
|
||||||
|
STRUCT(sockaddr,
|
||||||
|
TYPE_SHORT, MK_ARRAY(TYPE_CHAR, 14))
|
||||||
|
|
||||||
|
STRUCT(rtentry,
|
||||||
|
TYPE_ULONG, MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr),
|
||||||
|
TYPE_SHORT, TYPE_SHORT, TYPE_ULONG, TYPE_PTRVOID, TYPE_SHORT, TYPE_PTRVOID,
|
||||||
|
TYPE_ULONG, TYPE_ULONG, TYPE_SHORT)
|
||||||
|
|
||||||
|
STRUCT(ifmap,
|
||||||
|
TYPE_ULONG, TYPE_ULONG, TYPE_SHORT, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR,
|
||||||
|
/* Spare 3 bytes */
|
||||||
|
TYPE_CHAR, TYPE_CHAR, TYPE_CHAR)
|
||||||
|
|
||||||
|
/* The *_ifreq_list arrays deal with the fact that struct ifreq has unions */
|
||||||
|
|
||||||
|
STRUCT(sockaddr_ifreq,
|
||||||
|
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), MK_STRUCT(STRUCT_sockaddr))
|
||||||
|
|
||||||
|
STRUCT(short_ifreq,
|
||||||
|
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_SHORT)
|
||||||
|
|
||||||
|
STRUCT(int_ifreq,
|
||||||
|
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_INT)
|
||||||
|
|
||||||
|
STRUCT(ifmap_ifreq,
|
||||||
|
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), MK_STRUCT(STRUCT_ifmap))
|
||||||
|
|
||||||
|
STRUCT(char_ifreq,
|
||||||
|
MK_ARRAY(TYPE_CHAR, IFNAMSIZ),
|
||||||
|
MK_ARRAY(TYPE_CHAR, IFNAMSIZ))
|
||||||
|
|
||||||
|
STRUCT(ptr_ifreq,
|
||||||
|
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_PTRVOID)
|
||||||
|
|
||||||
|
STRUCT(ifconf,
|
||||||
|
TYPE_INT, TYPE_PTRVOID)
|
||||||
|
|
||||||
|
STRUCT(arpreq,
|
||||||
|
MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), TYPE_INT, MK_STRUCT(STRUCT_sockaddr),
|
||||||
|
MK_ARRAY(TYPE_CHAR, 16))
|
||||||
|
|
||||||
|
STRUCT(arpreq_old,
|
||||||
|
MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), TYPE_INT, MK_STRUCT(STRUCT_sockaddr))
|
||||||
|
|
||||||
|
STRUCT(cdrom_read_audio,
|
||||||
|
TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_PTRVOID,
|
||||||
|
TYPE_NULL)
|
||||||
|
|
||||||
|
STRUCT(hd_geometry,
|
||||||
|
TYPE_CHAR, TYPE_CHAR, TYPE_SHORT, TYPE_ULONG)
|
||||||
|
|
760
syscall-i386.h
Normal file
760
syscall-i386.h
Normal file
@ -0,0 +1,760 @@
|
|||||||
|
/* from linux/unistd.h */
|
||||||
|
|
||||||
|
#define TARGET_NR_exit 1
|
||||||
|
#define TARGET_NR_fork 2
|
||||||
|
#define TARGET_NR_read 3
|
||||||
|
#define TARGET_NR_write 4
|
||||||
|
#define TARGET_NR_open 5
|
||||||
|
#define TARGET_NR_close 6
|
||||||
|
#define TARGET_NR_waitpid 7
|
||||||
|
#define TARGET_NR_creat 8
|
||||||
|
#define TARGET_NR_link 9
|
||||||
|
#define TARGET_NR_unlink 10
|
||||||
|
#define TARGET_NR_execve 11
|
||||||
|
#define TARGET_NR_chdir 12
|
||||||
|
#define TARGET_NR_time 13
|
||||||
|
#define TARGET_NR_mknod 14
|
||||||
|
#define TARGET_NR_chmod 15
|
||||||
|
#define TARGET_NR_lchown 16
|
||||||
|
#define TARGET_NR_break 17
|
||||||
|
#define TARGET_NR_oldstat 18
|
||||||
|
#define TARGET_NR_lseek 19
|
||||||
|
#define TARGET_NR_getpid 20
|
||||||
|
#define TARGET_NR_mount 21
|
||||||
|
#define TARGET_NR_umount 22
|
||||||
|
#define TARGET_NR_setuid 23
|
||||||
|
#define TARGET_NR_getuid 24
|
||||||
|
#define TARGET_NR_stime 25
|
||||||
|
#define TARGET_NR_ptrace 26
|
||||||
|
#define TARGET_NR_alarm 27
|
||||||
|
#define TARGET_NR_oldfstat 28
|
||||||
|
#define TARGET_NR_pause 29
|
||||||
|
#define TARGET_NR_utime 30
|
||||||
|
#define TARGET_NR_stty 31
|
||||||
|
#define TARGET_NR_gtty 32
|
||||||
|
#define TARGET_NR_access 33
|
||||||
|
#define TARGET_NR_nice 34
|
||||||
|
#define TARGET_NR_ftime 35
|
||||||
|
#define TARGET_NR_sync 36
|
||||||
|
#define TARGET_NR_kill 37
|
||||||
|
#define TARGET_NR_rename 38
|
||||||
|
#define TARGET_NR_mkdir 39
|
||||||
|
#define TARGET_NR_rmdir 40
|
||||||
|
#define TARGET_NR_dup 41
|
||||||
|
#define TARGET_NR_pipe 42
|
||||||
|
#define TARGET_NR_times 43
|
||||||
|
#define TARGET_NR_prof 44
|
||||||
|
#define TARGET_NR_brk 45
|
||||||
|
#define TARGET_NR_setgid 46
|
||||||
|
#define TARGET_NR_getgid 47
|
||||||
|
#define TARGET_NR_signal 48
|
||||||
|
#define TARGET_NR_geteuid 49
|
||||||
|
#define TARGET_NR_getegid 50
|
||||||
|
#define TARGET_NR_acct 51
|
||||||
|
#define TARGET_NR_umount2 52
|
||||||
|
#define TARGET_NR_lock 53
|
||||||
|
#define TARGET_NR_ioctl 54
|
||||||
|
#define TARGET_NR_fcntl 55
|
||||||
|
#define TARGET_NR_mpx 56
|
||||||
|
#define TARGET_NR_setpgid 57
|
||||||
|
#define TARGET_NR_ulimit 58
|
||||||
|
#define TARGET_NR_oldolduname 59
|
||||||
|
#define TARGET_NR_umask 60
|
||||||
|
#define TARGET_NR_chroot 61
|
||||||
|
#define TARGET_NR_ustat 62
|
||||||
|
#define TARGET_NR_dup2 63
|
||||||
|
#define TARGET_NR_getppid 64
|
||||||
|
#define TARGET_NR_getpgrp 65
|
||||||
|
#define TARGET_NR_setsid 66
|
||||||
|
#define TARGET_NR_sigaction 67
|
||||||
|
#define TARGET_NR_sgetmask 68
|
||||||
|
#define TARGET_NR_ssetmask 69
|
||||||
|
#define TARGET_NR_setreuid 70
|
||||||
|
#define TARGET_NR_setregid 71
|
||||||
|
#define TARGET_NR_sigsuspend 72
|
||||||
|
#define TARGET_NR_sigpending 73
|
||||||
|
#define TARGET_NR_sethostname 74
|
||||||
|
#define TARGET_NR_setrlimit 75
|
||||||
|
#define TARGET_NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */
|
||||||
|
#define TARGET_NR_getrusage 77
|
||||||
|
#define TARGET_NR_gettimeofday 78
|
||||||
|
#define TARGET_NR_settimeofday 79
|
||||||
|
#define TARGET_NR_getgroups 80
|
||||||
|
#define TARGET_NR_setgroups 81
|
||||||
|
#define TARGET_NR_select 82
|
||||||
|
#define TARGET_NR_symlink 83
|
||||||
|
#define TARGET_NR_oldlstat 84
|
||||||
|
#define TARGET_NR_readlink 85
|
||||||
|
#define TARGET_NR_uselib 86
|
||||||
|
#define TARGET_NR_swapon 87
|
||||||
|
#define TARGET_NR_reboot 88
|
||||||
|
#define TARGET_NR_readdir 89
|
||||||
|
#define TARGET_NR_mmap 90
|
||||||
|
#define TARGET_NR_munmap 91
|
||||||
|
#define TARGET_NR_truncate 92
|
||||||
|
#define TARGET_NR_ftruncate 93
|
||||||
|
#define TARGET_NR_fchmod 94
|
||||||
|
#define TARGET_NR_fchown 95
|
||||||
|
#define TARGET_NR_getpriority 96
|
||||||
|
#define TARGET_NR_setpriority 97
|
||||||
|
#define TARGET_NR_profil 98
|
||||||
|
#define TARGET_NR_statfs 99
|
||||||
|
#define TARGET_NR_fstatfs 100
|
||||||
|
#define TARGET_NR_ioperm 101
|
||||||
|
#define TARGET_NR_socketcall 102
|
||||||
|
#define TARGET_NR_syslog 103
|
||||||
|
#define TARGET_NR_setitimer 104
|
||||||
|
#define TARGET_NR_getitimer 105
|
||||||
|
#define TARGET_NR_stat 106
|
||||||
|
#define TARGET_NR_lstat 107
|
||||||
|
#define TARGET_NR_fstat 108
|
||||||
|
#define TARGET_NR_olduname 109
|
||||||
|
#define TARGET_NR_iopl 110
|
||||||
|
#define TARGET_NR_vhangup 111
|
||||||
|
#define TARGET_NR_idle 112
|
||||||
|
#define TARGET_NR_vm86old 113
|
||||||
|
#define TARGET_NR_wait4 114
|
||||||
|
#define TARGET_NR_swapoff 115
|
||||||
|
#define TARGET_NR_sysinfo 116
|
||||||
|
#define TARGET_NR_ipc 117
|
||||||
|
#define TARGET_NR_fsync 118
|
||||||
|
#define TARGET_NR_sigreturn 119
|
||||||
|
#define TARGET_NR_clone 120
|
||||||
|
#define TARGET_NR_setdomainname 121
|
||||||
|
#define TARGET_NR_uname 122
|
||||||
|
#define TARGET_NR_modify_ldt 123
|
||||||
|
#define TARGET_NR_adjtimex 124
|
||||||
|
#define TARGET_NR_mprotect 125
|
||||||
|
#define TARGET_NR_sigprocmask 126
|
||||||
|
#define TARGET_NR_create_module 127
|
||||||
|
#define TARGET_NR_init_module 128
|
||||||
|
#define TARGET_NR_delete_module 129
|
||||||
|
#define TARGET_NR_get_kernel_syms 130
|
||||||
|
#define TARGET_NR_quotactl 131
|
||||||
|
#define TARGET_NR_getpgid 132
|
||||||
|
#define TARGET_NR_fchdir 133
|
||||||
|
#define TARGET_NR_bdflush 134
|
||||||
|
#define TARGET_NR_sysfs 135
|
||||||
|
#define TARGET_NR_personality 136
|
||||||
|
#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */
|
||||||
|
#define TARGET_NR_setfsuid 138
|
||||||
|
#define TARGET_NR_setfsgid 139
|
||||||
|
#define TARGET_NR__llseek 140
|
||||||
|
#define TARGET_NR_getdents 141
|
||||||
|
#define TARGET_NR__newselect 142
|
||||||
|
#define TARGET_NR_flock 143
|
||||||
|
#define TARGET_NR_msync 144
|
||||||
|
#define TARGET_NR_readv 145
|
||||||
|
#define TARGET_NR_writev 146
|
||||||
|
#define TARGET_NR_getsid 147
|
||||||
|
#define TARGET_NR_fdatasync 148
|
||||||
|
#define TARGET_NR__sysctl 149
|
||||||
|
#define TARGET_NR_mlock 150
|
||||||
|
#define TARGET_NR_munlock 151
|
||||||
|
#define TARGET_NR_mlockall 152
|
||||||
|
#define TARGET_NR_munlockall 153
|
||||||
|
#define TARGET_NR_sched_setparam 154
|
||||||
|
#define TARGET_NR_sched_getparam 155
|
||||||
|
#define TARGET_NR_sched_setscheduler 156
|
||||||
|
#define TARGET_NR_sched_getscheduler 157
|
||||||
|
#define TARGET_NR_sched_yield 158
|
||||||
|
#define TARGET_NR_sched_get_priority_max 159
|
||||||
|
#define TARGET_NR_sched_get_priority_min 160
|
||||||
|
#define TARGET_NR_sched_rr_get_interval 161
|
||||||
|
#define TARGET_NR_nanosleep 162
|
||||||
|
#define TARGET_NR_mremap 163
|
||||||
|
#define TARGET_NR_setresuid 164
|
||||||
|
#define TARGET_NR_getresuid 165
|
||||||
|
#define TARGET_NR_vm86 166
|
||||||
|
#define TARGET_NR_query_module 167
|
||||||
|
#define TARGET_NR_poll 168
|
||||||
|
#define TARGET_NR_nfsservctl 169
|
||||||
|
#define TARGET_NR_setresgid 170
|
||||||
|
#define TARGET_NR_getresgid 171
|
||||||
|
#define TARGET_NR_prctl 172
|
||||||
|
#define TARGET_NR_rt_sigreturn 173
|
||||||
|
#define TARGET_NR_rt_sigaction 174
|
||||||
|
#define TARGET_NR_rt_sigprocmask 175
|
||||||
|
#define TARGET_NR_rt_sigpending 176
|
||||||
|
#define TARGET_NR_rt_sigtimedwait 177
|
||||||
|
#define TARGET_NR_rt_sigqueueinfo 178
|
||||||
|
#define TARGET_NR_rt_sigsuspend 179
|
||||||
|
#define TARGET_NR_pread 180
|
||||||
|
#define TARGET_NR_pwrite 181
|
||||||
|
#define TARGET_NR_chown 182
|
||||||
|
#define TARGET_NR_getcwd 183
|
||||||
|
#define TARGET_NR_capget 184
|
||||||
|
#define TARGET_NR_capset 185
|
||||||
|
#define TARGET_NR_sigaltstack 186
|
||||||
|
#define TARGET_NR_sendfile 187
|
||||||
|
#define TARGET_NR_getpmsg 188 /* some people actually want streams */
|
||||||
|
#define TARGET_NR_putpmsg 189 /* some people actually want streams */
|
||||||
|
#define TARGET_NR_vfork 190
|
||||||
|
#define TARGET_NR_ugetrlimit 191 /* SuS compliant getrlimit */
|
||||||
|
#define TARGET_NR_mmap2 192
|
||||||
|
#define TARGET_NR_truncate64 193
|
||||||
|
#define TARGET_NR_ftruncate64 194
|
||||||
|
#define TARGET_NR_stat64 195
|
||||||
|
#define TARGET_NR_lstat64 196
|
||||||
|
#define TARGET_NR_fstat64 197
|
||||||
|
#define TARGET_NR_lchown32 198
|
||||||
|
#define TARGET_NR_getuid32 199
|
||||||
|
#define TARGET_NR_getgid32 200
|
||||||
|
#define TARGET_NR_geteuid32 201
|
||||||
|
#define TARGET_NR_getegid32 202
|
||||||
|
#define TARGET_NR_setreuid32 203
|
||||||
|
#define TARGET_NR_setregid32 204
|
||||||
|
#define TARGET_NR_getgroups32 205
|
||||||
|
#define TARGET_NR_setgroups32 206
|
||||||
|
#define TARGET_NR_fchown32 207
|
||||||
|
#define TARGET_NR_setresuid32 208
|
||||||
|
#define TARGET_NR_getresuid32 209
|
||||||
|
#define TARGET_NR_setresgid32 210
|
||||||
|
#define TARGET_NR_getresgid32 211
|
||||||
|
#define TARGET_NR_chown32 212
|
||||||
|
#define TARGET_NR_setuid32 213
|
||||||
|
#define TARGET_NR_setgid32 214
|
||||||
|
#define TARGET_NR_setfsuid32 215
|
||||||
|
#define TARGET_NR_setfsgid32 216
|
||||||
|
#define TARGET_NR_pivot_root 217
|
||||||
|
#define TARGET_NR_mincore 218
|
||||||
|
#define TARGET_NR_madvise 219
|
||||||
|
#define TARGET_NR_madvise1 219 /* delete when C lib stub is removed */
|
||||||
|
#define TARGET_NR_getdents64 220
|
||||||
|
#define TARGET_NR_fcntl64 221
|
||||||
|
#define TARGET_NR_security 223 /* syscall for security modules */
|
||||||
|
#define TARGET_NR_gettid 224
|
||||||
|
#define TARGET_NR_readahead 225
|
||||||
|
#define TARGET_NR_setxattr 226
|
||||||
|
#define TARGET_NR_lsetxattr 227
|
||||||
|
#define TARGET_NR_fsetxattr 228
|
||||||
|
#define TARGET_NR_getxattr 229
|
||||||
|
#define TARGET_NR_lgetxattr 230
|
||||||
|
#define TARGET_NR_fgetxattr 231
|
||||||
|
#define TARGET_NR_listxattr 232
|
||||||
|
#define TARGET_NR_llistxattr 233
|
||||||
|
#define TARGET_NR_flistxattr 234
|
||||||
|
#define TARGET_NR_removexattr 235
|
||||||
|
#define TARGET_NR_lremovexattr 236
|
||||||
|
#define TARGET_NR_fremovexattr 237
|
||||||
|
|
||||||
|
#define TARGET_SIG_BLOCK 0 /* for blocking signals */
|
||||||
|
#define TARGET_SIG_UNBLOCK 1 /* for unblocking signals */
|
||||||
|
#define TARGET_SIG_SETMASK 2 /* for setting the signal mask */
|
||||||
|
|
||||||
|
struct target_stat {
|
||||||
|
unsigned short st_dev;
|
||||||
|
unsigned short __pad1;
|
||||||
|
unsigned long st_ino;
|
||||||
|
unsigned short st_mode;
|
||||||
|
unsigned short st_nlink;
|
||||||
|
unsigned short st_uid;
|
||||||
|
unsigned short st_gid;
|
||||||
|
unsigned short st_rdev;
|
||||||
|
unsigned short __pad2;
|
||||||
|
unsigned long st_size;
|
||||||
|
unsigned long st_blksize;
|
||||||
|
unsigned long st_blocks;
|
||||||
|
unsigned long st_atime;
|
||||||
|
unsigned long __unused1;
|
||||||
|
unsigned long st_mtime;
|
||||||
|
unsigned long __unused2;
|
||||||
|
unsigned long st_ctime;
|
||||||
|
unsigned long __unused3;
|
||||||
|
unsigned long __unused4;
|
||||||
|
unsigned long __unused5;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This matches struct stat64 in glibc2.1, hence the absolutely
|
||||||
|
* insane amounts of padding around dev_t's.
|
||||||
|
*/
|
||||||
|
struct target_stat64 {
|
||||||
|
unsigned short st_dev;
|
||||||
|
unsigned char __pad0[10];
|
||||||
|
|
||||||
|
#define STAT64_HAS_BROKEN_ST_INO 1
|
||||||
|
unsigned long __st_ino;
|
||||||
|
|
||||||
|
unsigned int st_mode;
|
||||||
|
unsigned int st_nlink;
|
||||||
|
|
||||||
|
unsigned long st_uid;
|
||||||
|
unsigned long st_gid;
|
||||||
|
|
||||||
|
unsigned short st_rdev;
|
||||||
|
unsigned char __pad3[10];
|
||||||
|
|
||||||
|
long long st_size;
|
||||||
|
unsigned long st_blksize;
|
||||||
|
|
||||||
|
unsigned long st_blocks; /* Number 512-byte blocks allocated. */
|
||||||
|
unsigned long __pad4; /* future possible st_blocks high bits */
|
||||||
|
|
||||||
|
unsigned long st_atime;
|
||||||
|
unsigned long __pad5;
|
||||||
|
|
||||||
|
unsigned long st_mtime;
|
||||||
|
unsigned long __pad6;
|
||||||
|
|
||||||
|
unsigned long st_ctime;
|
||||||
|
unsigned long __pad7; /* will be high 32 bits of ctime someday */
|
||||||
|
|
||||||
|
unsigned long long st_ino;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef unsigned long old_sigset_t; /* at least 32 bits */
|
||||||
|
|
||||||
|
struct target_old_sigaction {
|
||||||
|
target_ulong _sa_handler;
|
||||||
|
target_ulong sa_mask;
|
||||||
|
target_ulong sa_flags;
|
||||||
|
void (*sa_restorer)(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct target_sigaction {
|
||||||
|
target_ulong _sa_handler;
|
||||||
|
target_sigset_t sa_mask;
|
||||||
|
target_ulong sa_flags;
|
||||||
|
target_ulong sa_restorer;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef union target_sigval {
|
||||||
|
int sival_int;
|
||||||
|
void *sival_ptr;
|
||||||
|
} target_sigval_t;
|
||||||
|
|
||||||
|
#define TARGET_SI_MAX_SIZE 128
|
||||||
|
#define TARGET_SI_PAD_SIZE ((TARGET_SI_MAX_SIZE/sizeof(int)) - 3)
|
||||||
|
|
||||||
|
typedef struct target_siginfo {
|
||||||
|
int si_signo;
|
||||||
|
int si_errno;
|
||||||
|
int si_code;
|
||||||
|
|
||||||
|
union {
|
||||||
|
int _pad[TARGET_SI_PAD_SIZE];
|
||||||
|
|
||||||
|
/* kill() */
|
||||||
|
struct {
|
||||||
|
pid_t _pid; /* sender's pid */
|
||||||
|
uid_t _uid; /* sender's uid */
|
||||||
|
} _kill;
|
||||||
|
|
||||||
|
/* POSIX.1b timers */
|
||||||
|
struct {
|
||||||
|
unsigned int _timer1;
|
||||||
|
unsigned int _timer2;
|
||||||
|
} _timer;
|
||||||
|
|
||||||
|
/* POSIX.1b signals */
|
||||||
|
struct {
|
||||||
|
pid_t _pid; /* sender's pid */
|
||||||
|
uid_t _uid; /* sender's uid */
|
||||||
|
sigval_t _sigval;
|
||||||
|
} _rt;
|
||||||
|
|
||||||
|
/* SIGCHLD */
|
||||||
|
struct {
|
||||||
|
pid_t _pid; /* which child */
|
||||||
|
uid_t _uid; /* sender's uid */
|
||||||
|
int _status; /* exit code */
|
||||||
|
clock_t _utime;
|
||||||
|
clock_t _stime;
|
||||||
|
} _sigchld;
|
||||||
|
|
||||||
|
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
||||||
|
struct {
|
||||||
|
void *_addr; /* faulting insn/memory ref. */
|
||||||
|
} _sigfault;
|
||||||
|
|
||||||
|
/* SIGPOLL */
|
||||||
|
struct {
|
||||||
|
int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
|
||||||
|
int _fd;
|
||||||
|
} _sigpoll;
|
||||||
|
} _sifields;
|
||||||
|
} target_siginfo_t;
|
||||||
|
|
||||||
|
/* ioctls */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following is for compatibility across the various Linux
|
||||||
|
* platforms. The i386 ioctl numbering scheme doesn't really enforce
|
||||||
|
* a type field. De facto, however, the top 8 bits of the lower 16
|
||||||
|
* bits are indeed used as a type field, so we might just as well make
|
||||||
|
* this explicit here. Please be sure to use the decoding macros
|
||||||
|
* below from now on.
|
||||||
|
*/
|
||||||
|
#define TARGET_IOC_NRBITS 8
|
||||||
|
#define TARGET_IOC_TYPEBITS 8
|
||||||
|
#define TARGET_IOC_SIZEBITS 14
|
||||||
|
#define TARGET_IOC_DIRBITS 2
|
||||||
|
|
||||||
|
#define TARGET_IOC_NRMASK ((1 << TARGET_IOC_NRBITS)-1)
|
||||||
|
#define TARGET_IOC_TYPEMASK ((1 << TARGET_IOC_TYPEBITS)-1)
|
||||||
|
#define TARGET_IOC_SIZEMASK ((1 << TARGET_IOC_SIZEBITS)-1)
|
||||||
|
#define TARGET_IOC_DIRMASK ((1 << TARGET_IOC_DIRBITS)-1)
|
||||||
|
|
||||||
|
#define TARGET_IOC_NRSHIFT 0
|
||||||
|
#define TARGET_IOC_TYPESHIFT (TARGET_IOC_NRSHIFT+TARGET_IOC_NRBITS)
|
||||||
|
#define TARGET_IOC_SIZESHIFT (TARGET_IOC_TYPESHIFT+TARGET_IOC_TYPEBITS)
|
||||||
|
#define TARGET_IOC_DIRSHIFT (TARGET_IOC_SIZESHIFT+TARGET_IOC_SIZEBITS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Direction bits.
|
||||||
|
*/
|
||||||
|
#define TARGET_IOC_NONE 0U
|
||||||
|
#define TARGET_IOC_WRITE 1U
|
||||||
|
#define TARGET_IOC_READ 2U
|
||||||
|
|
||||||
|
#define TARGET_IOC(dir,type,nr,size) \
|
||||||
|
(((dir) << TARGET_IOC_DIRSHIFT) | \
|
||||||
|
((type) << TARGET_IOC_TYPESHIFT) | \
|
||||||
|
((nr) << TARGET_IOC_NRSHIFT) | \
|
||||||
|
((size) << TARGET_IOC_SIZESHIFT))
|
||||||
|
|
||||||
|
/* used to create numbers */
|
||||||
|
#define TARGET_IO(type,nr) TARGET_IOC(TARGET_IOC_NONE,(type),(nr),0)
|
||||||
|
#define TARGET_IOR(type,nr,size) TARGET_IOC(TARGET_IOC_READ,(type),(nr),sizeof(size))
|
||||||
|
#define TARGET_IOW(type,nr,size) TARGET_IOC(TARGET_IOC_WRITE,(type),(nr),sizeof(size))
|
||||||
|
#define TARGET_IOWR(type,nr,size) TARGET_IOC(TARGET_IOC_READ|TARGET_IOC_WRITE,(type),(nr),sizeof(size))
|
||||||
|
|
||||||
|
/* 0x54 is just a magic number to make these relatively unique ('T') */
|
||||||
|
|
||||||
|
#define TARGET_TCGETS 0x5401
|
||||||
|
#define TARGET_TCSETS 0x5402
|
||||||
|
#define TARGET_TCSETSW 0x5403
|
||||||
|
#define TARGET_TCSETSF 0x5404
|
||||||
|
#define TARGET_TCGETA 0x5405
|
||||||
|
#define TARGET_TCSETA 0x5406
|
||||||
|
#define TARGET_TCSETAW 0x5407
|
||||||
|
#define TARGET_TCSETAF 0x5408
|
||||||
|
#define TARGET_TCSBRK 0x5409
|
||||||
|
#define TARGET_TCXONC 0x540A
|
||||||
|
#define TARGET_TCFLSH 0x540B
|
||||||
|
#define TARGET_TIOCEXCL 0x540C
|
||||||
|
#define TARGET_TIOCNXCL 0x540D
|
||||||
|
#define TARGET_TIOCSCTTY 0x540E
|
||||||
|
#define TARGET_TIOCGPGRP 0x540F
|
||||||
|
#define TARGET_TIOCSPGRP 0x5410
|
||||||
|
#define TARGET_TIOCOUTQ 0x5411
|
||||||
|
#define TARGET_TIOCSTI 0x5412
|
||||||
|
#define TARGET_TIOCGWINSZ 0x5413
|
||||||
|
#define TARGET_TIOCSWINSZ 0x5414
|
||||||
|
#define TARGET_TIOCMGET 0x5415
|
||||||
|
#define TARGET_TIOCMBIS 0x5416
|
||||||
|
#define TARGET_TIOCMBIC 0x5417
|
||||||
|
#define TARGET_TIOCMSET 0x5418
|
||||||
|
#define TARGET_TIOCGSOFTCAR 0x5419
|
||||||
|
#define TARGET_TIOCSSOFTCAR 0x541A
|
||||||
|
#define TARGET_FIONREAD 0x541B
|
||||||
|
#define TARGET_TIOCINQ FIONREAD
|
||||||
|
#define TARGET_TIOCLINUX 0x541C
|
||||||
|
#define TARGET_TIOCCONS 0x541D
|
||||||
|
#define TARGET_TIOCGSERIAL 0x541E
|
||||||
|
#define TARGET_TIOCSSERIAL 0x541F
|
||||||
|
#define TARGET_TIOCPKT 0x5420
|
||||||
|
#define TARGET_FIONBIO 0x5421
|
||||||
|
#define TARGET_TIOCNOTTY 0x5422
|
||||||
|
#define TARGET_TIOCSETD 0x5423
|
||||||
|
#define TARGET_TIOCGETD 0x5424
|
||||||
|
#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
|
||||||
|
#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */
|
||||||
|
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
|
||||||
|
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
|
||||||
|
#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */
|
||||||
|
#define TARGET_TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
|
||||||
|
#define TARGET_TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
|
||||||
|
|
||||||
|
#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */
|
||||||
|
#define TARGET_FIOCLEX 0x5451
|
||||||
|
#define TARGET_FIOASYNC 0x5452
|
||||||
|
#define TARGET_TIOCSERCONFIG 0x5453
|
||||||
|
#define TARGET_TIOCSERGWILD 0x5454
|
||||||
|
#define TARGET_TIOCSERSWILD 0x5455
|
||||||
|
#define TARGET_TIOCGLCKTRMIOS 0x5456
|
||||||
|
#define TARGET_TIOCSLCKTRMIOS 0x5457
|
||||||
|
#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */
|
||||||
|
#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */
|
||||||
|
#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */
|
||||||
|
#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
|
||||||
|
|
||||||
|
#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
|
||||||
|
#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
|
||||||
|
#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
|
||||||
|
#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
|
||||||
|
|
||||||
|
/* Used for packet mode */
|
||||||
|
#define TARGET_TIOCPKT_DATA 0
|
||||||
|
#define TARGET_TIOCPKT_FLUSHREAD 1
|
||||||
|
#define TARGET_TIOCPKT_FLUSHWRITE 2
|
||||||
|
#define TARGET_TIOCPKT_STOP 4
|
||||||
|
#define TARGET_TIOCPKT_START 8
|
||||||
|
#define TARGET_TIOCPKT_NOSTOP 16
|
||||||
|
#define TARGET_TIOCPKT_DOSTOP 32
|
||||||
|
|
||||||
|
#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
|
||||||
|
|
||||||
|
/* from asm/termbits.h */
|
||||||
|
|
||||||
|
#define TARGET_NCCS 19
|
||||||
|
|
||||||
|
struct target_termios {
|
||||||
|
unsigned int c_iflag; /* input mode flags */
|
||||||
|
unsigned int c_oflag; /* output mode flags */
|
||||||
|
unsigned int c_cflag; /* control mode flags */
|
||||||
|
unsigned int c_lflag; /* local mode flags */
|
||||||
|
unsigned char c_line; /* line discipline */
|
||||||
|
unsigned char c_cc[TARGET_NCCS]; /* control characters */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* c_iflag bits */
|
||||||
|
#define TARGET_IGNBRK 0000001
|
||||||
|
#define TARGET_BRKINT 0000002
|
||||||
|
#define TARGET_IGNPAR 0000004
|
||||||
|
#define TARGET_PARMRK 0000010
|
||||||
|
#define TARGET_INPCK 0000020
|
||||||
|
#define TARGET_ISTRIP 0000040
|
||||||
|
#define TARGET_INLCR 0000100
|
||||||
|
#define TARGET_IGNCR 0000200
|
||||||
|
#define TARGET_ICRNL 0000400
|
||||||
|
#define TARGET_IUCLC 0001000
|
||||||
|
#define TARGET_IXON 0002000
|
||||||
|
#define TARGET_IXANY 0004000
|
||||||
|
#define TARGET_IXOFF 0010000
|
||||||
|
#define TARGET_IMAXBEL 0020000
|
||||||
|
|
||||||
|
/* c_oflag bits */
|
||||||
|
#define TARGET_OPOST 0000001
|
||||||
|
#define TARGET_OLCUC 0000002
|
||||||
|
#define TARGET_ONLCR 0000004
|
||||||
|
#define TARGET_OCRNL 0000010
|
||||||
|
#define TARGET_ONOCR 0000020
|
||||||
|
#define TARGET_ONLRET 0000040
|
||||||
|
#define TARGET_OFILL 0000100
|
||||||
|
#define TARGET_OFDEL 0000200
|
||||||
|
#define TARGET_NLDLY 0000400
|
||||||
|
#define TARGET_NL0 0000000
|
||||||
|
#define TARGET_NL1 0000400
|
||||||
|
#define TARGET_CRDLY 0003000
|
||||||
|
#define TARGET_CR0 0000000
|
||||||
|
#define TARGET_CR1 0001000
|
||||||
|
#define TARGET_CR2 0002000
|
||||||
|
#define TARGET_CR3 0003000
|
||||||
|
#define TARGET_TABDLY 0014000
|
||||||
|
#define TARGET_TAB0 0000000
|
||||||
|
#define TARGET_TAB1 0004000
|
||||||
|
#define TARGET_TAB2 0010000
|
||||||
|
#define TARGET_TAB3 0014000
|
||||||
|
#define TARGET_XTABS 0014000
|
||||||
|
#define TARGET_BSDLY 0020000
|
||||||
|
#define TARGET_BS0 0000000
|
||||||
|
#define TARGET_BS1 0020000
|
||||||
|
#define TARGET_VTDLY 0040000
|
||||||
|
#define TARGET_VT0 0000000
|
||||||
|
#define TARGET_VT1 0040000
|
||||||
|
#define TARGET_FFDLY 0100000
|
||||||
|
#define TARGET_FF0 0000000
|
||||||
|
#define TARGET_FF1 0100000
|
||||||
|
|
||||||
|
/* c_cflag bit meaning */
|
||||||
|
#define TARGET_CBAUD 0010017
|
||||||
|
#define TARGET_B0 0000000 /* hang up */
|
||||||
|
#define TARGET_B50 0000001
|
||||||
|
#define TARGET_B75 0000002
|
||||||
|
#define TARGET_B110 0000003
|
||||||
|
#define TARGET_B134 0000004
|
||||||
|
#define TARGET_B150 0000005
|
||||||
|
#define TARGET_B200 0000006
|
||||||
|
#define TARGET_B300 0000007
|
||||||
|
#define TARGET_B600 0000010
|
||||||
|
#define TARGET_B1200 0000011
|
||||||
|
#define TARGET_B1800 0000012
|
||||||
|
#define TARGET_B2400 0000013
|
||||||
|
#define TARGET_B4800 0000014
|
||||||
|
#define TARGET_B9600 0000015
|
||||||
|
#define TARGET_B19200 0000016
|
||||||
|
#define TARGET_B38400 0000017
|
||||||
|
#define TARGET_EXTA B19200
|
||||||
|
#define TARGET_EXTB B38400
|
||||||
|
#define TARGET_CSIZE 0000060
|
||||||
|
#define TARGET_CS5 0000000
|
||||||
|
#define TARGET_CS6 0000020
|
||||||
|
#define TARGET_CS7 0000040
|
||||||
|
#define TARGET_CS8 0000060
|
||||||
|
#define TARGET_CSTOPB 0000100
|
||||||
|
#define TARGET_CREAD 0000200
|
||||||
|
#define TARGET_PARENB 0000400
|
||||||
|
#define TARGET_PARODD 0001000
|
||||||
|
#define TARGET_HUPCL 0002000
|
||||||
|
#define TARGET_CLOCAL 0004000
|
||||||
|
#define TARGET_CBAUDEX 0010000
|
||||||
|
#define TARGET_B57600 0010001
|
||||||
|
#define TARGET_B115200 0010002
|
||||||
|
#define TARGET_B230400 0010003
|
||||||
|
#define TARGET_B460800 0010004
|
||||||
|
#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */
|
||||||
|
#define TARGET_CRTSCTS 020000000000 /* flow control */
|
||||||
|
|
||||||
|
/* c_lflag bits */
|
||||||
|
#define TARGET_ISIG 0000001
|
||||||
|
#define TARGET_ICANON 0000002
|
||||||
|
#define TARGET_XCASE 0000004
|
||||||
|
#define TARGET_ECHO 0000010
|
||||||
|
#define TARGET_ECHOE 0000020
|
||||||
|
#define TARGET_ECHOK 0000040
|
||||||
|
#define TARGET_ECHONL 0000100
|
||||||
|
#define TARGET_NOFLSH 0000200
|
||||||
|
#define TARGET_TOSTOP 0000400
|
||||||
|
#define TARGET_ECHOCTL 0001000
|
||||||
|
#define TARGET_ECHOPRT 0002000
|
||||||
|
#define TARGET_ECHOKE 0004000
|
||||||
|
#define TARGET_FLUSHO 0010000
|
||||||
|
#define TARGET_PENDIN 0040000
|
||||||
|
#define TARGET_IEXTEN 0100000
|
||||||
|
|
||||||
|
/* c_cc character offsets */
|
||||||
|
#define TARGET_VINTR 0
|
||||||
|
#define TARGET_VQUIT 1
|
||||||
|
#define TARGET_VERASE 2
|
||||||
|
#define TARGET_VKILL 3
|
||||||
|
#define TARGET_VEOF 4
|
||||||
|
#define TARGET_VTIME 5
|
||||||
|
#define TARGET_VMIN 6
|
||||||
|
#define TARGET_VSWTC 7
|
||||||
|
#define TARGET_VSTART 8
|
||||||
|
#define TARGET_VSTOP 9
|
||||||
|
#define TARGET_VSUSP 10
|
||||||
|
#define TARGET_VEOL 11
|
||||||
|
#define TARGET_VREPRINT 12
|
||||||
|
#define TARGET_VDISCARD 13
|
||||||
|
#define TARGET_VWERASE 14
|
||||||
|
#define TARGET_VLNEXT 15
|
||||||
|
#define TARGET_VEOL2 16
|
||||||
|
|
||||||
|
/* soundcard defines (XXX: move them to generic file syscall_defs.h) */
|
||||||
|
|
||||||
|
#define TARGET_SNDCTL_COPR_HALT 0xc0144307
|
||||||
|
#define TARGET_SNDCTL_COPR_LOAD 0xcfb04301
|
||||||
|
#define TARGET_SNDCTL_COPR_RCODE 0xc0144303
|
||||||
|
#define TARGET_SNDCTL_COPR_RCVMSG 0x8fa44309
|
||||||
|
#define TARGET_SNDCTL_COPR_RDATA 0xc0144302
|
||||||
|
#define TARGET_SNDCTL_COPR_RESET 0x00004300
|
||||||
|
#define TARGET_SNDCTL_COPR_RUN 0xc0144306
|
||||||
|
#define TARGET_SNDCTL_COPR_SENDMSG 0xcfa44308
|
||||||
|
#define TARGET_SNDCTL_COPR_WCODE 0x40144305
|
||||||
|
#define TARGET_SNDCTL_COPR_WDATA 0x40144304
|
||||||
|
#define TARGET_SNDCTL_DSP_CHANNELS 0xc0045006
|
||||||
|
#define TARGET_SNDCTL_DSP_GETBLKSIZE 0xc0045004
|
||||||
|
#define TARGET_SNDCTL_DSP_GETCAPS 0x8004500f
|
||||||
|
#define TARGET_SNDCTL_DSP_GETFMTS 0x8004500b
|
||||||
|
#define TARGET_SNDCTL_DSP_GETIPTR 0x800c5011
|
||||||
|
#define TARGET_SNDCTL_DSP_GETISPACE 0x8010500d
|
||||||
|
#define TARGET_SNDCTL_DSP_GETOPTR 0x800c5012
|
||||||
|
#define TARGET_SNDCTL_DSP_GETOSPACE 0x8010500c
|
||||||
|
#define TARGET_SNDCTL_DSP_GETTRIGGER 0x80045010
|
||||||
|
#define TARGET_SNDCTL_DSP_MAPINBUF 0x80085013
|
||||||
|
#define TARGET_SNDCTL_DSP_MAPOUTBUF 0x80085014
|
||||||
|
#define TARGET_SNDCTL_DSP_NONBLOCK 0x0000500e
|
||||||
|
#define TARGET_SNDCTL_DSP_POST 0x00005008
|
||||||
|
#define TARGET_SNDCTL_DSP_RESET 0x00005000
|
||||||
|
#define TARGET_SNDCTL_DSP_SAMPLESIZE 0xc0045005
|
||||||
|
#define TARGET_SNDCTL_DSP_SETDUPLEX 0x00005016
|
||||||
|
#define TARGET_SNDCTL_DSP_SETFMT 0xc0045005
|
||||||
|
#define TARGET_SNDCTL_DSP_SETFRAGMENT 0xc004500a
|
||||||
|
#define TARGET_SNDCTL_DSP_SETSYNCRO 0x00005015
|
||||||
|
#define TARGET_SNDCTL_DSP_SETTRIGGER 0x40045010
|
||||||
|
#define TARGET_SNDCTL_DSP_SPEED 0xc0045002
|
||||||
|
#define TARGET_SNDCTL_DSP_STEREO 0xc0045003
|
||||||
|
#define TARGET_SNDCTL_DSP_SUBDIVIDE 0xc0045009
|
||||||
|
#define TARGET_SNDCTL_DSP_SYNC 0x00005001
|
||||||
|
#define TARGET_SNDCTL_FM_4OP_ENABLE 0x4004510f
|
||||||
|
#define TARGET_SNDCTL_FM_LOAD_INSTR 0x40285107
|
||||||
|
#define TARGET_SNDCTL_MIDI_INFO 0xc074510c
|
||||||
|
#define TARGET_SNDCTL_MIDI_MPUCMD 0xc0216d02
|
||||||
|
#define TARGET_SNDCTL_MIDI_MPUMODE 0xc0046d01
|
||||||
|
#define TARGET_SNDCTL_MIDI_PRETIME 0xc0046d00
|
||||||
|
#define TARGET_SNDCTL_PMGR_ACCESS 0xcfb85110
|
||||||
|
#define TARGET_SNDCTL_PMGR_IFACE 0xcfb85001
|
||||||
|
#define TARGET_SNDCTL_SEQ_CTRLRATE 0xc0045103
|
||||||
|
#define TARGET_SNDCTL_SEQ_GETINCOUNT 0x80045105
|
||||||
|
#define TARGET_SNDCTL_SEQ_GETOUTCOUNT 0x80045104
|
||||||
|
#define TARGET_SNDCTL_SEQ_NRMIDIS 0x8004510b
|
||||||
|
#define TARGET_SNDCTL_SEQ_NRSYNTHS 0x8004510a
|
||||||
|
#define TARGET_SNDCTL_SEQ_OUTOFBAND 0x40085112
|
||||||
|
#define TARGET_SNDCTL_SEQ_PANIC 0x00005111
|
||||||
|
#define TARGET_SNDCTL_SEQ_PERCMODE 0x40045106
|
||||||
|
#define TARGET_SNDCTL_SEQ_RESET 0x00005100
|
||||||
|
#define TARGET_SNDCTL_SEQ_RESETSAMPLES 0x40045109
|
||||||
|
#define TARGET_SNDCTL_SEQ_SYNC 0x00005101
|
||||||
|
#define TARGET_SNDCTL_SEQ_TESTMIDI 0x40045108
|
||||||
|
#define TARGET_SNDCTL_SEQ_THRESHOLD 0x4004510d
|
||||||
|
#define TARGET_SNDCTL_SEQ_TRESHOLD 0x4004510d
|
||||||
|
#define TARGET_SNDCTL_SYNTH_INFO 0xc08c5102
|
||||||
|
#define TARGET_SNDCTL_SYNTH_MEMAVL 0xc004510e
|
||||||
|
#define TARGET_SNDCTL_TMR_CONTINUE 0x00005404
|
||||||
|
#define TARGET_SNDCTL_TMR_METRONOME 0x40045407
|
||||||
|
#define TARGET_SNDCTL_TMR_SELECT 0x40045408
|
||||||
|
#define TARGET_SNDCTL_TMR_SOURCE 0xc0045406
|
||||||
|
#define TARGET_SNDCTL_TMR_START 0x00005402
|
||||||
|
#define TARGET_SNDCTL_TMR_STOP 0x00005403
|
||||||
|
#define TARGET_SNDCTL_TMR_TEMPO 0xc0045405
|
||||||
|
#define TARGET_SNDCTL_TMR_TIMEBASE 0xc0045401
|
||||||
|
#define TARGET_SOUND_PCM_WRITE_FILTER 0xc0045007
|
||||||
|
#define TARGET_SOUND_PCM_READ_RATE 0x80045002
|
||||||
|
#define TARGET_SOUND_PCM_READ_CHANNELS 0x80045006
|
||||||
|
#define TARGET_SOUND_PCM_READ_BITS 0x80045005
|
||||||
|
#define TARGET_SOUND_PCM_READ_FILTER 0x80045007
|
||||||
|
#define TARGET_SOUND_MIXER_INFO 0x80304d65
|
||||||
|
#define TARGET_SOUND_MIXER_ACCESS 0xc0804d66
|
||||||
|
#define TARGET_SOUND_MIXER_PRIVATE1 0xc0044d6f
|
||||||
|
#define TARGET_SOUND_MIXER_PRIVATE2 0xc0044d70
|
||||||
|
#define TARGET_SOUND_MIXER_PRIVATE3 0xc0044d71
|
||||||
|
#define TARGET_SOUND_MIXER_PRIVATE4 0xc0044d72
|
||||||
|
#define TARGET_SOUND_MIXER_PRIVATE5 0xc0044d73
|
||||||
|
#define TARGET_SOUND_MIXER_READ_VOLUME 0x80044d00
|
||||||
|
#define TARGET_SOUND_MIXER_READ_BASS 0x80044d01
|
||||||
|
#define TARGET_SOUND_MIXER_READ_TREBLE 0x80044d02
|
||||||
|
#define TARGET_SOUND_MIXER_READ_SYNTH 0x80044d03
|
||||||
|
#define TARGET_SOUND_MIXER_READ_PCM 0x80044d04
|
||||||
|
#define TARGET_SOUND_MIXER_READ_SPEAKER 0x80044d05
|
||||||
|
#define TARGET_SOUND_MIXER_READ_LINE 0x80044d06
|
||||||
|
#define TARGET_SOUND_MIXER_READ_MIC 0x80044d07
|
||||||
|
#define TARGET_SOUND_MIXER_READ_CD 0x80044d08
|
||||||
|
#define TARGET_SOUND_MIXER_READ_IMIX 0x80044d09
|
||||||
|
#define TARGET_SOUND_MIXER_READ_ALTPCM 0x80044d0a
|
||||||
|
#define TARGET_SOUND_MIXER_READ_RECLEV 0x80044d0b
|
||||||
|
#define TARGET_SOUND_MIXER_READ_IGAIN 0x80044d0c
|
||||||
|
#define TARGET_SOUND_MIXER_READ_OGAIN 0x80044d0d
|
||||||
|
#define TARGET_SOUND_MIXER_READ_LINE1 0x80044d0e
|
||||||
|
#define TARGET_SOUND_MIXER_READ_LINE2 0x80044d0f
|
||||||
|
#define TARGET_SOUND_MIXER_READ_LINE3 0x80044d10
|
||||||
|
#define TARGET_SOUND_MIXER_READ_MUTE 0x80044d1f
|
||||||
|
#define TARGET_SOUND_MIXER_READ_ENHANCE 0x80044d1f
|
||||||
|
#define TARGET_SOUND_MIXER_READ_LOUD 0x80044d1f
|
||||||
|
#define TARGET_SOUND_MIXER_READ_RECSRC 0x80044dff
|
||||||
|
#define TARGET_SOUND_MIXER_READ_DEVMASK 0x80044dfe
|
||||||
|
#define TARGET_SOUND_MIXER_READ_RECMASK 0x80044dfd
|
||||||
|
#define TARGET_SOUND_MIXER_READ_STEREODEVS 0x80044dfb
|
||||||
|
#define TARGET_SOUND_MIXER_READ_CAPS 0x80044dfc
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_VOLUME 0xc0044d00
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_BASS 0xc0044d01
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_TREBLE 0xc0044d02
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_SYNTH 0xc0044d03
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_PCM 0xc0044d04
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_SPEAKER 0xc0044d05
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_LINE 0xc0044d06
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_MIC 0xc0044d07
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_CD 0xc0044d08
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_IMIX 0xc0044d09
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_ALTPCM 0xc0044d0a
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_RECLEV 0xc0044d0b
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_IGAIN 0xc0044d0c
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_OGAIN 0xc0044d0d
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_LINE1 0xc0044d0e
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_LINE2 0xc0044d0f
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_LINE3 0xc0044d10
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_MUTE 0xc0044d1f
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_ENHANCE 0xc0044d1f
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_LOUD 0xc0044d1f
|
||||||
|
#define TARGET_SOUND_MIXER_WRITE_RECSRC 0xc0044dff
|
315
thunk.c
Normal file
315
thunk.c
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
/*
|
||||||
|
* Generic thunking code to convert data between host and target CPU
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 Fabrice Bellard
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "gemu.h"
|
||||||
|
#include "thunk.h"
|
||||||
|
|
||||||
|
//#define DEBUG
|
||||||
|
|
||||||
|
#define MAX_STRUCTS 128
|
||||||
|
|
||||||
|
/* XXX: make it dynamic */
|
||||||
|
static StructEntry struct_entries[MAX_STRUCTS];
|
||||||
|
|
||||||
|
static inline int thunk_type_size(const argtype *type_ptr, int is_host)
|
||||||
|
{
|
||||||
|
int type, size;
|
||||||
|
const StructEntry *se;
|
||||||
|
|
||||||
|
type = *type_ptr;
|
||||||
|
switch(type) {
|
||||||
|
case TYPE_CHAR:
|
||||||
|
return 1;
|
||||||
|
case TYPE_SHORT:
|
||||||
|
return 2;
|
||||||
|
case TYPE_INT:
|
||||||
|
return 4;
|
||||||
|
case TYPE_LONGLONG:
|
||||||
|
case TYPE_ULONGLONG:
|
||||||
|
return 8;
|
||||||
|
case TYPE_LONG:
|
||||||
|
case TYPE_ULONG:
|
||||||
|
case TYPE_PTRVOID:
|
||||||
|
case TYPE_PTR:
|
||||||
|
if (is_host) {
|
||||||
|
return HOST_LONG_SIZE;
|
||||||
|
} else {
|
||||||
|
return TARGET_LONG_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_ARRAY:
|
||||||
|
size = type_ptr[1];
|
||||||
|
return size * thunk_type_size(type_ptr + 2, is_host);
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
se = struct_entries + type_ptr[1];
|
||||||
|
return se->size[is_host];
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int thunk_type_align(const argtype *type_ptr, int is_host)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
const StructEntry *se;
|
||||||
|
|
||||||
|
type = *type_ptr;
|
||||||
|
switch(type) {
|
||||||
|
case TYPE_CHAR:
|
||||||
|
return 1;
|
||||||
|
case TYPE_SHORT:
|
||||||
|
return 2;
|
||||||
|
case TYPE_INT:
|
||||||
|
return 4;
|
||||||
|
case TYPE_LONGLONG:
|
||||||
|
case TYPE_ULONGLONG:
|
||||||
|
return 8;
|
||||||
|
case TYPE_LONG:
|
||||||
|
case TYPE_ULONG:
|
||||||
|
case TYPE_PTRVOID:
|
||||||
|
case TYPE_PTR:
|
||||||
|
if (is_host) {
|
||||||
|
return HOST_LONG_SIZE;
|
||||||
|
} else {
|
||||||
|
return TARGET_LONG_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_ARRAY:
|
||||||
|
return thunk_type_align(type_ptr + 2, is_host);
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
se = struct_entries + type_ptr[1];
|
||||||
|
return se->align[is_host];
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const argtype *thunk_type_next(const argtype *type_ptr)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
|
||||||
|
type = *type_ptr++;
|
||||||
|
switch(type) {
|
||||||
|
case TYPE_CHAR:
|
||||||
|
case TYPE_SHORT:
|
||||||
|
case TYPE_INT:
|
||||||
|
case TYPE_LONGLONG:
|
||||||
|
case TYPE_ULONGLONG:
|
||||||
|
case TYPE_LONG:
|
||||||
|
case TYPE_ULONG:
|
||||||
|
case TYPE_PTRVOID:
|
||||||
|
return type_ptr;
|
||||||
|
case TYPE_PTR:
|
||||||
|
return thunk_type_next(type_ptr);
|
||||||
|
case TYPE_ARRAY:
|
||||||
|
return thunk_type_next(type_ptr + 1);
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
return type_ptr + 1;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void thunk_register_struct(int id, const char *name, const argtype *types)
|
||||||
|
{
|
||||||
|
const argtype *type_ptr;
|
||||||
|
StructEntry *se;
|
||||||
|
int nb_fields, offset, max_align, align, size, i, j;
|
||||||
|
|
||||||
|
se = struct_entries + id;
|
||||||
|
|
||||||
|
/* first we count the number of fields */
|
||||||
|
type_ptr = types;
|
||||||
|
nb_fields = 0;
|
||||||
|
while (*type_ptr != TYPE_NULL) {
|
||||||
|
type_ptr = thunk_type_next(type_ptr);
|
||||||
|
nb_fields++;
|
||||||
|
}
|
||||||
|
se->field_types = types;
|
||||||
|
se->nb_fields = nb_fields;
|
||||||
|
se->name = name;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("struct %s: id=%d nb_fields=%d\n",
|
||||||
|
se->name, id, se->nb_fields);
|
||||||
|
#endif
|
||||||
|
/* now we can alloc the data */
|
||||||
|
|
||||||
|
for(i = 0;i < 2; i++) {
|
||||||
|
offset = 0;
|
||||||
|
max_align = 1;
|
||||||
|
se->field_offsets[i] = malloc(nb_fields * sizeof(int));
|
||||||
|
type_ptr = se->field_types;
|
||||||
|
for(j = 0;j < nb_fields; j++) {
|
||||||
|
size = thunk_type_size(type_ptr, i);
|
||||||
|
align = thunk_type_align(type_ptr, i);
|
||||||
|
offset = (offset + align - 1) & ~(align - 1);
|
||||||
|
se->field_offsets[i][j] = offset;
|
||||||
|
offset += size;
|
||||||
|
if (align > max_align)
|
||||||
|
max_align = align;
|
||||||
|
}
|
||||||
|
offset = (offset + max_align - 1) & ~(max_align - 1);
|
||||||
|
se->size[i] = offset;
|
||||||
|
se->align[i] = max_align;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("%s: size=%d align=%d\n",
|
||||||
|
i == THUNK_HOST ? "host" : "target", offset, max_align);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void thunk_register_struct_direct(int id, const char *name, StructEntry *se1)
|
||||||
|
{
|
||||||
|
StructEntry *se;
|
||||||
|
se = struct_entries + id;
|
||||||
|
*se = *se1;
|
||||||
|
se->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* now we can define the main conversion functions */
|
||||||
|
const argtype *thunk_convert(void *dst, const void *src,
|
||||||
|
const argtype *type_ptr, int to_host)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
|
||||||
|
type = *type_ptr++;
|
||||||
|
switch(type) {
|
||||||
|
case TYPE_CHAR:
|
||||||
|
*(uint8_t *)dst = *(uint8_t *)src;
|
||||||
|
break;
|
||||||
|
case TYPE_SHORT:
|
||||||
|
*(uint16_t *)dst = tswap16(*(uint16_t *)src);
|
||||||
|
break;
|
||||||
|
case TYPE_INT:
|
||||||
|
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
|
||||||
|
break;
|
||||||
|
case TYPE_LONGLONG:
|
||||||
|
case TYPE_ULONGLONG:
|
||||||
|
*(uint64_t *)dst = tswap64(*(uint64_t *)src);
|
||||||
|
break;
|
||||||
|
#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32
|
||||||
|
case TYPE_LONG:
|
||||||
|
case TYPE_ULONG:
|
||||||
|
case TYPE_PTRVOID:
|
||||||
|
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
|
||||||
|
break;
|
||||||
|
#elif HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32
|
||||||
|
case TYPE_LONG:
|
||||||
|
case TYPE_ULONG:
|
||||||
|
case TYPE_PTRVOID:
|
||||||
|
if (target_to_host) {
|
||||||
|
*(uint64_t *)dst = tswap32(*(uint32_t *)src);
|
||||||
|
} else {
|
||||||
|
*(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
#error unsupported conversion
|
||||||
|
#endif
|
||||||
|
case TYPE_ARRAY:
|
||||||
|
{
|
||||||
|
int array_length, i, dst_size, src_size;
|
||||||
|
const uint8_t *s;
|
||||||
|
uint8_t *d;
|
||||||
|
|
||||||
|
array_length = *type_ptr++;
|
||||||
|
dst_size = thunk_type_size(type_ptr, to_host);
|
||||||
|
src_size = thunk_type_size(type_ptr, 1 - to_host);
|
||||||
|
d = dst;
|
||||||
|
s = src;
|
||||||
|
for(i = 0;i < array_length; i++) {
|
||||||
|
thunk_convert(d, s, type_ptr, to_host);
|
||||||
|
d += dst_size;
|
||||||
|
s += src_size;
|
||||||
|
}
|
||||||
|
type_ptr = thunk_type_next(type_ptr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const StructEntry *se;
|
||||||
|
const uint8_t *s;
|
||||||
|
uint8_t *d;
|
||||||
|
const argtype *field_types;
|
||||||
|
const int *dst_offsets, *src_offsets;
|
||||||
|
|
||||||
|
se = struct_entries + *type_ptr++;
|
||||||
|
if (se->convert[0] != NULL) {
|
||||||
|
/* specific conversion is needed */
|
||||||
|
(*se->convert[to_host])(dst, src);
|
||||||
|
} else {
|
||||||
|
/* standard struct conversion */
|
||||||
|
field_types = se->field_types;
|
||||||
|
dst_offsets = se->field_offsets[to_host];
|
||||||
|
src_offsets = se->field_offsets[1 - to_host];
|
||||||
|
d = dst;
|
||||||
|
s = src;
|
||||||
|
for(i = 0;i < se->nb_fields; i++) {
|
||||||
|
field_types = thunk_convert(d + dst_offsets[i],
|
||||||
|
s + src_offsets[i],
|
||||||
|
field_types, to_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Invalid type 0x%x\n", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return type_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* from em86 */
|
||||||
|
|
||||||
|
/* Utility function: Table-driven functions to translate bitmasks
|
||||||
|
* between X86 and Alpha formats...
|
||||||
|
*/
|
||||||
|
unsigned int target_to_host_bitmask(unsigned int x86_mask,
|
||||||
|
bitmask_transtbl * trans_tbl)
|
||||||
|
{
|
||||||
|
bitmask_transtbl * btp;
|
||||||
|
unsigned int alpha_mask = 0;
|
||||||
|
|
||||||
|
for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
|
||||||
|
if((x86_mask & btp->x86_mask) == btp->x86_bits) {
|
||||||
|
alpha_mask |= btp->alpha_bits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(alpha_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int host_to_target_bitmask(unsigned int alpha_mask,
|
||||||
|
bitmask_transtbl * trans_tbl)
|
||||||
|
{
|
||||||
|
bitmask_transtbl * btp;
|
||||||
|
unsigned int x86_mask = 0;
|
||||||
|
|
||||||
|
for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
|
||||||
|
if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) {
|
||||||
|
x86_mask |= btp->x86_mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(x86_mask);
|
||||||
|
}
|
195
thunk.h
Normal file
195
thunk.h
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
#ifndef THUNK_H
|
||||||
|
#define THUNK_H
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <byteswap.h>
|
||||||
|
|
||||||
|
#undef WORDS_BIGENDIAN
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
#define WORDS_BIGENDIAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WORD_BIGENDIAN
|
||||||
|
#define BSWAP_NEEDED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* XXX: auto autoconf */
|
||||||
|
#define TARGET_I386
|
||||||
|
#define TARGET_LONG_BITS 32
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__alpha__)
|
||||||
|
#define HOST_LONG_BITS 64
|
||||||
|
#else
|
||||||
|
#define HOST_LONG_BITS 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
|
||||||
|
#define HOST_LONG_SIZE (TARGET_LONG_BITS / 8)
|
||||||
|
|
||||||
|
static inline uint16_t bswap16(uint16_t x)
|
||||||
|
{
|
||||||
|
return bswap_16(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t bswap32(uint32_t x)
|
||||||
|
{
|
||||||
|
return bswap_32(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t bswap64(uint64_t x)
|
||||||
|
{
|
||||||
|
return bswap_64(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline bswap16s(uint16_t *s)
|
||||||
|
{
|
||||||
|
*s = bswap16(*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline bswap32s(uint32_t *s)
|
||||||
|
{
|
||||||
|
*s = bswap32(*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline bswap64s(uint64_t *s)
|
||||||
|
{
|
||||||
|
*s = bswap64(*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BSWAP_NEEDED
|
||||||
|
|
||||||
|
static inline uint16_t tswap16(uint16_t s)
|
||||||
|
{
|
||||||
|
return bswap16(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t tswap32(uint32_t s)
|
||||||
|
{
|
||||||
|
return bswap32(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t tswap64(uint64_t s)
|
||||||
|
{
|
||||||
|
return bswap64(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline tswap16s(uint16_t *s)
|
||||||
|
{
|
||||||
|
*s = bswap16(*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline tswap32s(uint32_t *s)
|
||||||
|
{
|
||||||
|
*s = bswap32(*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline tswap64s(uint64_t *s)
|
||||||
|
{
|
||||||
|
*s = bswap64(*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline uint16_t tswap16(uint16_t s)
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t tswap32(uint32_t s)
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t tswap64(uint64_t s)
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline tswap16s(uint16_t *s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline tswap32s(uint32_t *s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline tswap64s(uint64_t *s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TARGET_LONG_SIZE == 4
|
||||||
|
#define tswapl(s) tswap32(s)
|
||||||
|
#define tswapls(s) tswap32s((uint32_t *)(s))
|
||||||
|
#else
|
||||||
|
#define tswapl(s) tswap64(s)
|
||||||
|
#define tswapls(s) tswap64s((uint64_t *)(s))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TARGET_LONG_SIZE == 4
|
||||||
|
typedef int32_t target_long;
|
||||||
|
typedef uint32_t target_ulong;
|
||||||
|
#elif TARGET_LONG_SIZE == 8
|
||||||
|
typedef int64_t target_long;
|
||||||
|
typedef uint64_t target_ulong;
|
||||||
|
#else
|
||||||
|
#error TARGET_LONG_SIZE undefined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* types enums definitions */
|
||||||
|
|
||||||
|
typedef enum argtype {
|
||||||
|
TYPE_NULL,
|
||||||
|
TYPE_CHAR,
|
||||||
|
TYPE_SHORT,
|
||||||
|
TYPE_INT,
|
||||||
|
TYPE_LONG,
|
||||||
|
TYPE_ULONG,
|
||||||
|
TYPE_PTRVOID, /* pointer on unknown data */
|
||||||
|
TYPE_LONGLONG,
|
||||||
|
TYPE_ULONGLONG,
|
||||||
|
TYPE_PTR,
|
||||||
|
TYPE_ARRAY,
|
||||||
|
TYPE_STRUCT,
|
||||||
|
} argtype;
|
||||||
|
|
||||||
|
#define MK_PTR(type) TYPE_PTR, type
|
||||||
|
#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
|
||||||
|
#define MK_STRUCT(id) TYPE_STRUCT, id
|
||||||
|
|
||||||
|
#define THUNK_TARGET 0
|
||||||
|
#define THUNK_HOST 1
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* standard struct handling */
|
||||||
|
const argtype *field_types;
|
||||||
|
int nb_fields;
|
||||||
|
int *field_offsets[2];
|
||||||
|
/* special handling */
|
||||||
|
void (*convert[2])(void *dst, const void *src);
|
||||||
|
int size[2];
|
||||||
|
int align[2];
|
||||||
|
const char *name;
|
||||||
|
} StructEntry;
|
||||||
|
|
||||||
|
/* Translation table for bitmasks... */
|
||||||
|
typedef struct bitmask_transtbl {
|
||||||
|
unsigned int x86_mask;
|
||||||
|
unsigned int x86_bits;
|
||||||
|
unsigned int alpha_mask;
|
||||||
|
unsigned int alpha_bits;
|
||||||
|
} bitmask_transtbl;
|
||||||
|
|
||||||
|
void thunk_register_struct(int id, const char *name, const argtype *types);
|
||||||
|
void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
|
||||||
|
const argtype *thunk_convert(void *dst, const void *src,
|
||||||
|
const argtype *type_ptr, int to_host);
|
||||||
|
|
||||||
|
unsigned int target_to_host_bitmask(unsigned int x86_mask,
|
||||||
|
bitmask_transtbl * trans_tbl);
|
||||||
|
unsigned int host_to_target_bitmask(unsigned int alpha_mask,
|
||||||
|
bitmask_transtbl * trans_tbl);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user