From 6a161fa938d2d56703db46c08b6f821b7d3e0207 Mon Sep 17 00:00:00 2001 From: okuji Date: Fri, 27 Dec 2002 08:53:07 +0000 Subject: [PATCH] Initial revision --- .cvsignore | 8 + AUTHORS | 1 + COPYING | 340 ++ ChangeLog | 4 + INSTALL | 157 + Makefile.in | 259 ++ NEWS | 12 + README | 26 + THANKS | 16 + TODO | 37 + aclocal.m4 | 292 ++ autogen.sh | 11 + boot/i386/pc/boot.S | 487 +++ boot/i386/pc/diskboot.S | 387 ++ conf/i386-pc.mk | 379 ++ conf/i386-pc.rmk | 65 + config.guess | 1321 +++++++ config.h.in | 78 + config.sub | 1443 ++++++++ configure | 5745 ++++++++++++++++++++++++++++++ configure.ac | 124 + disk/i386/pc/biosdisk.c | 335 ++ disk/i386/pc/partition.c | 248 ++ fs/fat.c | 756 ++++ genkernsyms.sh | 15 + genmk.rb | 269 ++ genmodsrc.sh | 48 + gensymlist.sh | 65 + include/grub/boot.h | 28 + include/grub/device.h | 44 + include/grub/disk.h | 119 + include/grub/dl.h | 86 + include/grub/elf.h | 2314 ++++++++++++ include/grub/err.h | 59 + include/grub/file.h | 73 + include/grub/fs.h | 63 + include/grub/i386/pc/biosdisk.h | 47 + include/grub/i386/pc/boot.h | 83 + include/grub/i386/pc/console.h | 55 + include/grub/i386/pc/init.h | 50 + include/grub/i386/pc/kernel.h | 29 + include/grub/i386/pc/loader.h | 29 + include/grub/i386/pc/memory.h | 67 + include/grub/i386/pc/partition.h | 243 ++ include/grub/i386/types.h | 32 + include/grub/kernel.h | 61 + include/grub/loader.h | 37 + include/grub/misc.h | 47 + include/grub/mm.h | 39 + include/grub/net.h | 73 + include/grub/rescue.h | 37 + include/grub/symbol.h | 40 + include/grub/term.h | 120 + include/grub/types.h | 141 + include/grub/util/misc.h | 40 + include/grub/util/resolve.h | 36 + install-sh | 251 ++ kern/device.c | 99 + kern/disk.c | 474 +++ kern/dl.c | 599 ++++ kern/err.c | 61 + kern/file.c | 158 + kern/fs.c | 224 ++ kern/i386/dl.c | 126 + kern/i386/pc/init.c | 114 + kern/i386/pc/startup.S | 1377 +++++++ kern/loader.c | 67 + kern/main.c | 86 + kern/misc.c | 377 ++ kern/mm.c | 352 ++ kern/rescue.c | 576 +++ kern/term.c | 153 + loader/i386/pc/chainloader.c | 137 + mkinstalldirs | 40 + stamp-h.in | 1 + term/i386/pc/console.c | 76 + util/genmoddep.c | 279 ++ util/i386/pc/grub-mkimage.c | 223 ++ util/misc.c | 137 + util/resolve.c | 257 ++ 80 files changed, 23264 insertions(+) create mode 100644 .cvsignore create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 THANKS create mode 100644 TODO create mode 100644 aclocal.m4 create mode 100644 autogen.sh create mode 100644 boot/i386/pc/boot.S create mode 100644 boot/i386/pc/diskboot.S create mode 100644 conf/i386-pc.mk create mode 100644 conf/i386-pc.rmk create mode 100644 config.guess create mode 100644 config.h.in create mode 100644 config.sub create mode 100644 configure create mode 100644 configure.ac create mode 100644 disk/i386/pc/biosdisk.c create mode 100644 disk/i386/pc/partition.c create mode 100644 fs/fat.c create mode 100644 genkernsyms.sh create mode 100644 genmk.rb create mode 100644 genmodsrc.sh create mode 100644 gensymlist.sh create mode 100644 include/grub/boot.h create mode 100644 include/grub/device.h create mode 100644 include/grub/disk.h create mode 100644 include/grub/dl.h create mode 100644 include/grub/elf.h create mode 100644 include/grub/err.h create mode 100644 include/grub/file.h create mode 100644 include/grub/fs.h create mode 100644 include/grub/i386/pc/biosdisk.h create mode 100644 include/grub/i386/pc/boot.h create mode 100644 include/grub/i386/pc/console.h create mode 100644 include/grub/i386/pc/init.h create mode 100644 include/grub/i386/pc/kernel.h create mode 100644 include/grub/i386/pc/loader.h create mode 100644 include/grub/i386/pc/memory.h create mode 100644 include/grub/i386/pc/partition.h create mode 100644 include/grub/i386/types.h create mode 100644 include/grub/kernel.h create mode 100644 include/grub/loader.h create mode 100644 include/grub/misc.h create mode 100644 include/grub/mm.h create mode 100644 include/grub/net.h create mode 100644 include/grub/rescue.h create mode 100644 include/grub/symbol.h create mode 100644 include/grub/term.h create mode 100644 include/grub/types.h create mode 100644 include/grub/util/misc.h create mode 100644 include/grub/util/resolve.h create mode 100644 install-sh create mode 100644 kern/device.c create mode 100644 kern/disk.c create mode 100644 kern/dl.c create mode 100644 kern/err.c create mode 100644 kern/file.c create mode 100644 kern/fs.c create mode 100644 kern/i386/dl.c create mode 100644 kern/i386/pc/init.c create mode 100644 kern/i386/pc/startup.S create mode 100644 kern/loader.c create mode 100644 kern/main.c create mode 100644 kern/misc.c create mode 100644 kern/mm.c create mode 100644 kern/rescue.c create mode 100644 kern/term.c create mode 100644 loader/i386/pc/chainloader.c create mode 100644 mkinstalldirs create mode 100644 stamp-h.in create mode 100644 term/i386/pc/console.c create mode 100644 util/genmoddep.c create mode 100644 util/i386/pc/grub-mkimage.c create mode 100644 util/misc.c create mode 100644 util/resolve.c diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 000000000..91983cf81 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,8 @@ +Makefile +config.cache +config.h +config.log +config.status +stamp-h +stamp-h1 +autom4te.cache diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..aacc8399e --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Yoshinori K. Okuji designed and implemented everything. diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..eeb586b39 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, 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 software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, 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 redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. 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. + + + Copyright (C) 19yy + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..be5328821 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,4 @@ +2002-12-27 Yoshinori K. Okuji + + * Changelog: New file. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..228029e42 --- /dev/null +++ b/INSTALL @@ -0,0 +1,157 @@ +-*- Text -*- + +This is the PUPA. Welcome. + +This file contains instructions for compiling and installing the PUPA. + +The Requirements +================ + +PUPA depends on some software packages installed into your system. If +you don't have any of them, please obtain and install them before +configuring the PUPA. + +* GCC 2.95 or later +* GNU Make +* GNU binutils 2.9.1.0.23 or later +* Other standard GNU/Unix tools + +If you'd like to develop PUPA, these below are also required. + +* Ruby 1.6 or later +* Autoconf 2.53 or later + +Configuring the PUPA +==================== + +The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a +file `config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + +If you need to do unusual things to compile the package, please try to +figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + +The file `configure.ac' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + + +Building the PUPA +================= + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and + type `./configure' to configure the package for your system. If + you're using `csh' on an old version of System V, you might need + to type `sh ./configure' instead to prevent `csh' from trying to + execute `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. `cd' to the directory where you want the object files +and executables to go and run the `configure' script. `configure' +automatically checks for the source code in the directory that +`configure' is in and in `..'. + + +Installation Names +================== + +By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix by giving `configure' the option `--prefix=PATH'. + +You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If +you give `configure' the option `--exec-prefix=PATH', the package will +use PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + +In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for +particular kinds of files. Run `configure --help' for a list of the +directories you can set and what kinds of files go in them. + +If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' +the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Please note, however, that the PUPA knows where it is located in the +filesystem. If you have installed it in an unusual location, the +system might not work properly, or at all. The chief utility of these +options for the PUPA is to allow you to "install" in some alternate +location, and then copy these to the actual root filesystem later. + + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 000000000..9dfca542c --- /dev/null +++ b/Makefile.in @@ -0,0 +1,259 @@ +# -*- makefile -*- +# +# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. +# Copyright (C) 2002 Yoshinori K. Okuji +# +# This Makefile.in is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +### The configure script will replace these variables. + +SHELL = /bin/sh + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +pkgdatadir = $(datadir)/@PACKAGE_TARNAME@/$(host_cpu)-$(host_vendor) +pkglibdir = $(libdir)/@PACKAGE_TARNAME@ + +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + +host_cpu = @host_cpu@ +host_vendor = @host_vendor@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ + +mkinstalldirs = $(srcdir)/mkinstalldirs + +CC = @CC@ +CFLAGS = @CFLAGS@ +CPPFLAGS = -I. -Iinclude -I$(srcdir)/include -Wall -W +BUILD_CC = @CC@ +BUILD_CFLAGS = -g -O2 +BUILD_CPPFLAGS = -I. -Iinclude -I$(srcdir)/include -Wall -W \ + -DPUPA_DATADIR=\"$(pkgdatadir)\" +OBJCOPY = @OBJCOPY@ +STRIP = @STRIP@ +NM = @NM@ +RUBY = @RUBY@ + +### General variables. + +RMKFILES = $(addprefix conf/,i386-pc.rmk) +MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES)) + +COMMON_DISTFILES = AUTHORS COPYING ChangeLog INSTALL NEWS README \ + THANKS TODO Makefile.in aclocal.m4 autogen.sh config.guess \ + config.h.in config.sub configure configure.ac genkernsyms.sh \ + genmk.rb genmodsrc.sh gensymlist.sh install-sh mkinstalldirs \ + stamp-h.in + +BOOT_DISTFILES = $(addprefix boot/i386/pc/,boot.S diskboot.S) + +CONF_DISTFILES = $(RMKFILES) $(MKFILES) + +DISK_DISTFILES = $(addprefix disk/i386/pc/,biosdisk.c partition.c) + +FS_DISTFILES = $(addprefix fs/,fat.c) + +INCLUDE_DISTFILES = $(addprefix include/pupa/,boot.h device.h disk.h \ + dl.h elf.h err.h file.h fs.h kernel.h loader.h misc.h mm.h \ + net.h rescue.h symbol.h term.h types.h) \ + $(addprefix include/pupa/util/,misc.h resolve.h) \ + include/pupa/i386/types.h \ + $(addprefix include/pupa/i386/pc/,biosdisk.h boot.h \ + console.h init.h kernel.h loader.h memory.h partition.h) + +KERN_DISTFILES = $(addprefix kern/,device.c disk.c dl.c err.c file.c \ + fs.c loader.c main.c misc.c mm.c rescue.c term.c) \ + kern/i386/dl.c \ + $(addprefix kern/i386/pc/,init.c startup.S) + +LOADER_DISTFILES = $(addprefix loader/i386/pc/,chainloader.c) + +TERM_DISTFILES = $(addprefix term/i386/pc/,console.c) + +UTIL_DISTFILES = $(addprefix util/,genmoddep.c misc.c resolve.c) \ + util/i386/pc/pupa-mkimage.c + +DISTFILES = $(COMMON_DISTFILES) $(BOOT_DISTFILES) $(CONF_DISTFILES) \ + $(DISK_DISTFILES) $(FS_DISTFILES) $(INCLUDE_DISTFILES) \ + $(KERN_DISTFILES) $(LOADER_DISTFILES) $(TERM_DISTFILES) \ + $(UTIL_DISTFILES) + +DATA = $(pkgdata_IMAGES) $(pkgdata_MODULES) +PROGRAMS = $(bin_UTILITIES) $(sbin_UTILITIES) +SCRIPTS = + +CLEANFILES = +MOSTLYCLEANFILES = +DISTCLEANFILES = config.status config.cache config.log config.h \ + Makefile stamp-h include/pupa/cpu include/pupa/machine +MAINTAINER_CLEANFILES = $(srcdir)/configure $(addprefix $(srcdir)/,$(MKFILES)) + +# The default target. +all: all-local + +### Include an arch-specific Makefile. +$(addprefix $(srcdir)/,$(MKFILES)): %.mk: %.rmk genmk.rb + if test "x$(RUBY)" = x; then \ + touch $@; \ + else \ + $(RUBY) $(srcdir)/genmk.rb < $< > $@; \ + fi + +include $(srcdir)/conf/$(host_cpu)-$(host_vendor).mk + +### General targets. + +all-local: $(PROGRAMS) $(DATA) $(SCRIPTS) + +install: install-local + +install-local: all + $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) + @list='$(pkgdata_IMAGES) $(pkgdata_MODULES)'; for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)"; fi; \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(pkgdatadir)/$$dest; \ + done + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_UTILITIES)'; for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)"; fi; \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ + done + +install-strip: + $(MAKE) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" install + +uninstall: + @list='$(pkgdata_IMAGES) $(pkgdata_MODULES)'; for file in $$list; do \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + rm -f $(DESTDIR)$(pkgdatadir)/$$dest; \ + done + @list = '$(bin_UTILITIES)'; for file in $$list; do \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + rm -f $(DESTDIR)$(bindir)/$$dest; \ + done + +clean: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +mostlyclean: clean + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +distclean: mostlyclean + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + -rm -rf $(srcdir)/autom4te.cache + +maintainer-clean: distclean + -test -z "$(MAINTAINER_CLEANFILES)" || rm -f $(MAINTAINER_CLEANFILES) + +info: + +dvi: + +distdir=$(PACKAGE_TARNAME)-$(PACKAGE_VERSION) + +distdir: $(DISTFILES) + -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir) + $(mkinstalldirs) $(distdir) + for i in $(DISTFILES); do \ + dir=`echo "$$i" | sed 's:/[^/]*$$::'`; \ + if test -d $(srcdir)/$$dir; then \ + $(mkinstalldirs) $(distdir)/$$dir; \ + fi; \ + cp -p $(srcdir)/$$i $(distdir)/$$i || exit 1; \ + done + chmod -R a+r $(distdir) + +GZIP_ENV = --best + +dist: distdir + tar chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir) + +distcheck: dist + -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir) + GZIP=$(GZIP_ENV) gzip -cd $(distdir).tar.gz | tar xf - + chmod -R a-w $(distdir) + chmod a+w $(distdir) + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + chmod a-w $(distdir) + dc_instdir=`CDPATH=: && cd $(distdir)/=inst && pwd` \ + && cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_instdir \ + && $(MAKE) all dvi check install uninstall \ + && (test `find $$dc_instdir -type f -print | wc -l` -le 1 \ + || (echo "Error: files left after uninstall" 1>&2; \ + exit 1)) \ + && $(MAKE) dist distclean \ + && rm -f $(distdir).tar.gz \ + && (test `find . -type f -print | wc -l` -eq 0 \ + || (echo "Error: files left after distclean" 1>&2; \ + exit 1)) + -chmod -R a+w $(distdir) > /dev/null 2>&1; rm -rf $(distdir) + @echo "$(distdir).tar.gz is ready for distribution" | \ + sed 'h;s/./=/g;p;x;p;x' + +check: + +.SUFFIX: +.SUFFIX: .c .o .S .d + +# Regenerate configure and Makefile automatically. +$(srcdir)/configure: configure.ac aclocal.m4 + cd $(srcdir) && autoconf + +$(srcdir)/config.h.in: stamp-h.in +$(srcdir)/stamp-h.in: configure.ac aclocal.m4 + cd $(srcdir) && autoheader + echo timestamp > $(srcdir)/stamp-h.in + +config.h: stamp-h +stamp-h: config.h.in config.status + ./config.status + +Makefile: Makefile.in config.status + ./config.status + +config.status: configure + ./config.status --recheck + +.PHONY: all install install-strip uninstall clean mostlyclean distclean +.PHONY: maintainer-clean info dvi dist check + +# Prevent an overflow. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..65ce9a0dc --- /dev/null +++ b/NEWS @@ -0,0 +1,12 @@ +New in 0.6 - 2002-12-27, Yoshinori K. Okuji: + +* The chainloader and the FAT filesystem are modularized. + +* The structure of the source tree is a bit changed. + +* Support for building loadable modules is added. + +* Some generic parts of pupa-mkimage are segregated. + +* Some documentation files are added, according to the GNU Coding + Standards. diff --git a/README b/README new file mode 100644 index 000000000..867f47583 --- /dev/null +++ b/README @@ -0,0 +1,26 @@ +This is PUPA, the Preliminary Universal Programming Architecture for +GRUB. PUPA is a research project for the next generation of GNU GRUB. +The most important goal is to make GNU GRUB cleaner, safer, more robust, +more powerful, and more portable. + +See the file NEWS for a description of recent changes to PUPA. + +See the file INSTALL for instructions on how to build and install the +PUPA data and program files. + +Please visit the official web page of PUPA, for more information. +The URL is . + + + +Because PUPA is still in developmental stage, PUPA is not for general +use (yet). For now, you can install PUPA into a floppy by these +instructions: + +$ configure && make +$ ./pupa-mkimage -v -d . -o core.img chain fat +$ dd if=boot.img of=/dev/fd0 bs=512 count=1 +$ dd if=core.img of=/dev/fd0 bs=512 seek=1 + +It would be easier to use Bochs than a real +machine. diff --git a/THANKS b/THANKS new file mode 100644 index 000000000..6c0277094 --- /dev/null +++ b/THANKS @@ -0,0 +1,16 @@ +PUPA would not be what it is today without the invaluable help of +everybody who was kind enough to spend time testing it and reporting +bugs. + +The following people made especially gracious contributions of their +time and energy in helping to track down bugs, add new features, and +generally assist in the PUPA maintainership process: + +NIIBE Yutaka +Tsuneyoshi Yasuo + +Also, we thank the projects GNU GRUB and GNU Automake. Some code were +stolen from them. + +This project is supported by Information-technology Promotion Agency, +Japan. diff --git a/TODO b/TODO new file mode 100644 index 000000000..cd57f7198 --- /dev/null +++ b/TODO @@ -0,0 +1,37 @@ +-*- Mode: Outline -*- + +Before working on anything in this file, it's very important that you +make contact with the core PUPA developers. Things herein might be +slightly out of date or otherwise not easy to understand at first +glance. So write to first. + +Priorities: + Reported bugs generally have top priority. + Non-reported and non-encountered bugs (things we know don't work, + but don't really impede things) have lower priority. + Things in this file are ranked with one to three !; the more, the + higher priority. + + +* Add more filesystems (such as ext2fs, ffs, and reiserfs). ! + +* Add support for internationalization. !!! + +* Add more loaders (such as Multiboot, Linux and FreeBSD). !! + +* Implement an installer. !!! + +* Add more terminals (such as serial). ! + +* Implement a normal mode. !!! + +* Write a manual. + +* Shrink the kernel code. + +* Add support for compressed files. + +* Add support for network devices. + +* Compress the core image and decompress it at loading time, to make it + smaller. ? diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 000000000..9f8e1e715 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,292 @@ +dnl pupa_ASM_USCORE checks if C symbols get an underscore after +dnl compiling to assembler. +dnl Written by Pavel Roskin. Based on grub_ASM_EXT_C written by +dnl Erich Boleyn and modified by Yoshinori K. Okuji. +AC_DEFUN(pupa_ASM_USCORE, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([if C symbols get an underscore after compilation]) +AC_CACHE_VAL(pupa_cv_asm_uscore, +[cat > conftest.c <<\EOF +int +func (int *list) +{ + *list = 0; + return *list; +} +EOF + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then + true +else + AC_MSG_ERROR([${CC-cc} failed to produce assembly code]) +fi + +if grep _func conftest.s >/dev/null 2>&1; then + pupa_cv_asm_uscore=yes +else + pupa_cv_asm_uscore=no +fi + +rm -f conftest*]) + +if test "x$pupa_cv_asm_uscore" = xyes; then + AC_DEFINE_UNQUOTED([HAVE_ASM_USCORE], $pupa_cv_asm_uscore, + [Define if C symbols get an underscore after compilation]) +fi + +AC_MSG_RESULT([$pupa_cv_asm_uscore]) +]) + + +dnl Some versions of `objcopy -O binary' vary their output depending +dnl on the link address. +AC_DEFUN(pupa_PROG_OBJCOPY_ABSOLUTE, +[AC_MSG_CHECKING([whether ${OBJCOPY} works for absolute addresses]) +AC_CACHE_VAL(pupa_cv_prog_objcopy_absolute, +[cat > conftest.c <<\EOF +void +cmain (void) +{ + *((int *) 0x1000) = 2; +} +EOF + +if AC_TRY_EVAL(ac_compile) && test -s conftest.o; then : +else + AC_MSG_ERROR([${CC-cc} cannot compile C source code]) +fi +pupa_cv_prog_objcopy_absolute=yes +for link_addr in 2000 8000 7C00; do + if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then : + else + AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr]) + fi + if AC_TRY_COMMAND([${OBJCOPY-objcopy} -O binary conftest.exec conftest]); then : + else + AC_MSG_ERROR([${OBJCOPY-objcopy} cannot create binary files]) + fi + if test ! -f conftest.old || AC_TRY_COMMAND([cmp -s conftest.old conftest]); then + mv -f conftest conftest.old + else + pupa_cv_prog_objcopy_absolute=no + break + fi +done +rm -f conftest*]) +AC_MSG_RESULT([$pupa_cv_prog_objcopy_absolute]) + +if test "x$pupa_cv_prog_objcopy_absolute" = xno; then + AC_MSG_ERROR([PUPA requires a working absolute objcopy; upgrade your binutils]) +fi +]) + + +dnl Mass confusion! +dnl Older versions of GAS interpret `.code16' to mean ``generate 32-bit +dnl instructions, but implicitly insert addr32 and data32 bytes so +dnl that the code works in real mode''. +dnl +dnl Newer versions of GAS interpret `.code16' to mean ``generate 16-bit +dnl instructions,'' which seems right. This requires the programmer +dnl to explicitly insert addr32 and data32 instructions when they want +dnl them. +dnl +dnl We only support the newer versions, because the old versions cause +dnl major pain, by requiring manual assembly to get 16-bit instructions into +dnl asm files. +AC_DEFUN(pupa_I386_ASM_ADDR32, +[AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([pupa_I386_ASM_PREFIX_REQUIREMENT]) +AC_MSG_CHECKING([for .code16 addr32 assembler support]) +AC_CACHE_VAL(pupa_cv_i386_asm_addr32, +[cat > conftest.s.in <<\EOF + .code16 +l1: @ADDR32@ movb %al, l1 +EOF + +if test "x$pupa_cv_i386_asm_prefix_requirement" = xyes; then + sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s +else + sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s +fi + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then + pupa_cv_i386_asm_addr32=yes +else + pupa_cv_i386_asm_addr32=no +fi + +rm -f conftest*]) + +AC_MSG_RESULT([$pupa_cv_i386_asm_addr32])]) + + +dnl Later versions of GAS requires that addr32 and data32 prefixes +dnl appear in the same lines as the instructions they modify, while +dnl earlier versions requires that they appear in separate lines. +AC_DEFUN(pupa_I386_ASM_PREFIX_REQUIREMENT, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(dnl +[whether addr32 must be in the same line as the instruction]) +AC_CACHE_VAL(pupa_cv_i386_asm_prefix_requirement, +[cat > conftest.s <<\EOF + .code16 +l1: addr32 movb %al, l1 +EOF + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then + pupa_cv_i386_asm_prefix_requirement=yes +else + pupa_cv_i386_asm_prefix_requirement=no +fi + +rm -f conftest*]) + +if test "x$pupa_cv_i386_asm_prefix_requirement" = xyes; then + pupa_tmp_addr32="addr32" + pupa_tmp_data32="data32" +else + pupa_tmp_addr32="addr32;" + pupa_tmp_data32="data32;" +fi + +AC_DEFINE_UNQUOTED([ADDR32], $pupa_tmp_addr32, + [Define it to \"addr32\" or \"addr32;\" to make GAS happy]) +AC_DEFINE_UNQUOTED([DATA32], $pupa_tmp_data32, + [Define it to \"data32\" or \"data32;\" to make GAS happy]) + +AC_MSG_RESULT([$pupa_cv_i386_asm_prefix_requirement])]) + + +dnl Older versions of GAS require that absolute indirect calls/jumps are +dnl not prefixed with `*', while later versions warn if not prefixed. +AC_DEFUN(pupa_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(dnl +[whether an absolute indirect call/jump must not be prefixed with an asterisk]) +AC_CACHE_VAL(pupa_cv_i386_asm_absolute_without_asterisk, +[cat > conftest.s <<\EOF + lcall *(offset) +offset: + .long 0 + .word 0 +EOF + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then + pupa_cv_i386_asm_absolute_without_asterisk=no +else + pupa_cv_i386_asm_absolute_without_asterisk=yes +fi + +rm -f conftest*]) + +if test "x$pupa_cv_i386_asm_absolute_without_asterisk" = xyes; then + AC_DEFINE([ABSOLUTE_WITHOUT_ASTERISK], 1, + [Define it if GAS requires that absolute indirect calls/jumps are not prefixed with an asterisk]) +fi + +AC_MSG_RESULT([$pupa_cv_i386_asm_absolute_without_asterisk])]) + + +dnl Check what symbol is defined as a start symbol. +dnl Written by Yoshinori K. Okuji. +AC_DEFUN(pupa_CHECK_START_SYMBOL, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([if start is defined by the compiler]) +AC_CACHE_VAL(pupa_cv_check_start_symbol, +[AC_TRY_LINK([], [asm ("incl start")], + pupa_cv_check_start_symbol=yes, + pupa_cv_check_start_symbol=no)]) + +AC_MSG_RESULT([$pupa_cv_check_start_symbol]) + +AC_MSG_CHECKING([if _start is defined by the compiler]) +AC_CACHE_VAL(pupa_cv_check_uscore_start_symbol, +[AC_TRY_LINK([], [asm ("incl _start")], + pupa_cv_check_uscore_start_symbol=yes, + pupa_cv_check_uscore_start_symbol=no)]) + +AC_MSG_RESULT([$pupa_cv_check_uscore_start_symbol]) + +AH_TEMPLATE([START_SYMBOL], [Define it to either start or _start]) + +if test "x$pupa_cv_check_start_symbol" = xyes; then + AC_DEFINE([START_SYMBOL], [start]) +elif test "x$pupa_cv_check_uscore_start_symbol" = xyes; then + AC_DEFINE([START_SYMBOL], [_start]) +else + AC_MSG_ERROR([neither start nor _start is defined]) +fi +]) + +dnl Check what symbol is defined as a bss start symbol. +dnl Written by Michael Hohmoth and Yoshinori K. Okuji. +AC_DEFUN(pupa_CHECK_BSS_START_SYMBOL, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([if __bss_start is defined by the compiler]) +AC_CACHE_VAL(pupa_cv_check_uscore_uscore_bss_start_symbol, +[AC_TRY_LINK([], [asm ("incl __bss_start")], + pupa_cv_check_uscore_uscore_bss_start_symbol=yes, + pupa_cv_check_uscore_uscore_bss_start_symbol=no)]) + +AC_MSG_RESULT([$pupa_cv_check_uscore_uscore_bss_start_symbol]) + +AC_MSG_CHECKING([if edata is defined by the compiler]) +AC_CACHE_VAL(pupa_cv_check_edata_symbol, +[AC_TRY_LINK([], [asm ("incl edata")], + pupa_cv_check_edata_symbol=yes, + pupa_cv_check_edata_symbol=no)]) + +AC_MSG_RESULT([$pupa_cv_check_edata_symbol]) + +AC_MSG_CHECKING([if _edata is defined by the compiler]) +AC_CACHE_VAL(pupa_cv_check_uscore_edata_symbol, +[AC_TRY_LINK([], [asm ("incl _edata")], + pupa_cv_check_uscore_edata_symbol=yes, + pupa_cv_check_uscore_edata_symbol=no)]) + +AC_MSG_RESULT([$pupa_cv_check_uscore_edata_symbol]) + +AH_TEMPLATE([BSS_START_SYMBOL], [Define it to one of __bss_start, edata and _edata]) + +if test "x$pupa_cv_check_uscore_uscore_bss_start_symbol" = xyes; then + AC_DEFINE([BSS_START_SYMBOL], [__bss_start]) +elif test "x$pupa_cv_check_edata_symbol" = xyes; then + AC_DEFINE([BSS_START_SYMBOL], [edata]) +elif test "x$pupa_cv_check_uscore_edata_symbol" = xyes; then + AC_DEFINE([BSS_START_SYMBOL], [_edata]) +else + AC_MSG_ERROR([none of __bss_start, edata or _edata is defined]) +fi +]) + +dnl Check what symbol is defined as an end symbol. +dnl Written by Yoshinori K. Okuji. +AC_DEFUN(pupa_CHECK_END_SYMBOL, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([if end is defined by the compiler]) +AC_CACHE_VAL(pupa_cv_check_end_symbol, +[AC_TRY_LINK([], [asm ("incl end")], + pupa_cv_check_end_symbol=yes, + pupa_cv_check_end_symbol=no)]) + +AC_MSG_RESULT([$pupa_cv_check_end_symbol]) + +AC_MSG_CHECKING([if _end is defined by the compiler]) +AC_CACHE_VAL(pupa_cv_check_uscore_end_symbol, +[AC_TRY_LINK([], [asm ("incl _end")], + pupa_cv_check_uscore_end_symbol=yes, + pupa_cv_check_uscore_end_symbol=no)]) + +AC_MSG_RESULT([$pupa_cv_check_uscore_end_symbol]) + +AH_TEMPLATE([END_SYMBOL], [Define it to either end or _end]) + +if test "x$pupa_cv_check_end_symbol" = xyes; then + AC_DEFINE([END_SYMBOL], [end]) +elif test "x$pupa_cv_check_uscore_end_symbol" = xyes; then + AC_DEFINE([END_SYMBOL], [_end]) +else + AC_MSG_ERROR([neither end nor _end is defined]) +fi +]) diff --git a/autogen.sh b/autogen.sh new file mode 100644 index 000000000..387bea731 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,11 @@ +#! /bin/sh + +set -e + +autoconf +autoheader +for rmk in conf/*.rmk; do + ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'` +done + +exit 0 diff --git a/boot/i386/pc/boot.S b/boot/i386/pc/boot.S new file mode 100644 index 000000000..dd3c66796 --- /dev/null +++ b/boot/i386/pc/boot.S @@ -0,0 +1,487 @@ +/* -*-Asm-*- */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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 +#include + +/* + * defines for the code go here + */ + + /* Absolute addresses + This makes the assembler generate the address without support + from the linker. (ELF can't relocate 16-bit addresses!) */ +#define ABS(x) (x-_start+0x7c00) + + /* Print message string */ +#define MSG(x) movw $ABS(x), %si; call message + + /* XXX: binutils-2.9.1.0.x doesn't produce a short opcode for this. */ +#define MOV_MEM_TO_AL(x) .byte 0xa0; .word x + + .file "boot.S" + + .text + + /* Tell GAS to generate 16-bit instructions so that this code works + in real mode. */ + .code16 + +.globl _start; _start: + /* + * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00 + */ + + /* + * Beginning of the sector is compatible with the FAT/HPFS BIOS + * parameter block. + */ + + jmp after_BPB + nop /* do I care about this ??? */ + + /* + * This space is for the BIOS parameter block!!!! Don't change + * the first jump, nor start the code anywhere but right after + * this area. + */ + + . = _start + 4 + + /* scratch space */ +mode: + .byte 0 +disk_address_packet: +sectors: + .long 0 +heads: + .long 0 +cylinders: + .word 0 +sector_start: + .byte 0 +head_start: + .byte 0 +cylinder_start: + .word 0 + /* more space... */ + + . = _start + PUPA_BOOT_MACHINE_BPBEND + + /* + * End of BIOS parameter block. + */ + +boot_version: + .byte PUPA_BOOT_VERSION_MAJOR, PUPA_BOOT_VERSION_MINOR +boot_drive: + .byte 0xff /* the disk to load kernel from */ + /* 0xff means use the boot drive */ +force_lba: + .byte 0 +kernel_address: + .word PUPA_BOOT_MACHINE_KERNEL_ADDR +kernel_sector: + .long 1 +kernel_segment: + .word PUPA_BOOT_MACHINE_KERNEL_SEG + +after_BPB: + +/* general setup */ + cli /* we're not safe here! */ + + /* + * ljmp to the next instruction because some bogus BIOSes + * jump to 07C0:0000 instead of 0000:7C00. + */ + ljmp $0, $ABS(real_start) + +real_start: + + /* set up %ds and %ss as offset from 0 */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + + /* set up the REAL stack */ + movw $PUPA_BOOT_MACHINE_STACK_SEG, %sp + + sti /* we're safe again */ + + /* + * Check if we have a forced disk reference here + */ + MOV_MEM_TO_AL(ABS(boot_drive)) /* movb ABS(boot_drive), %al */ + cmpb $0xff, %al + je 1f + movb %al, %dl +1: + /* save drive reference first thing! */ + pushw %dx + + /* print a notification message on the screen */ + MSG(notification_string) + + /* do not probe LBA if the drive is a floppy */ + testb $PUPA_BOOT_MACHINE_BIOS_HD_FLAG, %dl + jz chs_mode + + /* check if LBA is supported */ + movb $0x41, %ah + movw $0x55aa, %bx + int $0x13 + + /* + * %dl may have been clobbered by INT 13, AH=41H. + * This happens, for example, with AST BIOS 1.04. + */ + popw %dx + pushw %dx + + /* use CHS if fails */ + jc chs_mode + cmpw $0xaa55, %bx + jne chs_mode + + /* check if AH=0x42 is supported if FORCE_LBA is zero */ + MOV_MEM_TO_AL(ABS(force_lba)) /* movb ABS(force_lba), %al */ + testb %al, %al + jnz lba_mode + andw $1, %cx + jz chs_mode + +lba_mode: + /* save the total number of sectors */ + movl 0x10(%si), %ecx + + /* set %si to the disk address packet */ + movw $ABS(disk_address_packet), %si + + /* set the mode to non-zero */ + movb $1, -1(%si) + + movl ABS(kernel_sector), %ebx + + /* the size and the reserved byte */ + movw $0x0010, (%si) + + /* the blocks */ + movw $1, 2(%si) + + /* the absolute address (low 32 bits) */ + movl %ebx, 8(%si) + + /* the segment of buffer address */ + movw $PUPA_BOOT_MACHINE_BUFFER_SEG, 6(%si) + + xorl %eax, %eax + movw %ax, 4(%si) + movl %eax, 12(%si) + +/* + * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory + * Call with %ah = 0x42 + * %dl = drive number + * %ds:%si = segment:offset of disk address packet + * Return: + * %al = 0x0 on success; err code on failure + */ + + movb $0x42, %ah + int $0x13 + + /* LBA read is not supported, so fallback to CHS. */ + jc chs_mode + + movw $PUPA_BOOT_MACHINE_BUFFER_SEG, %bx + jmp copy_buffer + +chs_mode: + /* + * Determine the hard disk geometry from the BIOS! + * We do this first, so that LS-120 IDE floppies work correctly. + */ + movb $8, %ah + int $0x13 + jnc final_init + + /* + * The call failed, so maybe use the floppy probe instead. + */ + testb $PUPA_BOOT_MACHINE_BIOS_HD_FLAG, %dl + jz floppy_probe + + /* Nope, we definitely have a hard disk, and we're screwed. */ + jmp hd_probe_error + +final_init: + + movw $ABS(sectors), %si + + /* set the mode to zero */ + movb $0, -1(%si) + + /* save number of heads */ + xorl %eax, %eax + movb %dh, %al + incw %ax + movl %eax, 4(%si) + + xorw %dx, %dx + movb %cl, %dl + shlw $2, %dx + movb %ch, %al + movb %dh, %ah + + /* save number of cylinders */ + incw %ax + movw %ax, 8(%si) + + xorw %ax, %ax + movb %dl, %al + shrb $2, %al + + /* save number of sectors */ + movl %eax, (%si) + +setup_sectors: + /* load logical sector start (bottom half) */ + movl ABS(kernel_sector), %eax + + /* zero %edx */ + xorl %edx, %edx + + /* divide by number of sectors */ + divl (%si) + + /* save sector start */ + movb %dl, 10(%si) + + xorl %edx, %edx /* zero %edx */ + divl 4(%si) /* divide by number of heads */ + + /* save head start */ + movb %dl, 11(%si) + + /* save cylinder start */ + movw %ax, 12(%si) + + /* do we need too many cylinders? */ + cmpw 8(%si), %ax + jge geometry_error + +/* + * This is the loop for taking care of BIOS geometry translation (ugh!) + */ + + /* get high bits of cylinder */ + movb 13(%si), %dl + + shlb $6, %dl /* shift left by 6 bits */ + movb 10(%si), %cl /* get sector */ + + incb %cl /* normalize sector (sectors go + from 1-N, not 0-(N-1) ) */ + orb %dl, %cl /* composite together */ + movb 12(%si), %ch /* sector+hcyl in cl, cylinder in ch */ + + /* restore %dx */ + popw %dx + + /* head number */ + movb 11(%si), %dh + +/* + * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory + * Call with %ah = 0x2 + * %al = number of sectors + * %ch = cylinder + * %cl = sector (bits 6-7 are high bits of "cylinder") + * %dh = head + * %dl = drive (0x80 for hard disk, 0x0 for floppy disk) + * %es:%bx = segment:offset of buffer + * Return: + * %al = 0x0 on success; err code on failure + */ + + movw $PUPA_BOOT_MACHINE_BUFFER_SEG, %bx + movw %bx, %es /* load %es segment with disk buffer */ + + xorw %bx, %bx /* %bx = 0, put it at 0 in the segment */ + movw $0x0201, %ax /* function 2 */ + int $0x13 + + jc read_error + + movw %es, %bx + +copy_buffer: + movw ABS(kernel_segment), %es + + /* + * We need to save %cx and %si because the startup code in + * kernel uses them without initializing them. + */ + pusha + pushw %ds + + movw $0x100, %cx + movw %bx, %ds + xorw %si, %si + xorw %di, %di + + cld + + rep + movsw + + popw %ds + popa + + /* boot kernel */ + jmp *(kernel_address) + +/* END OF MAIN LOOP */ + +/* + * BIOS Geometry translation error (past the end of the disk geometry!). + */ +geometry_error: + MSG(geometry_error_string) + jmp general_error + +/* + * Disk probe failure. + */ +hd_probe_error: + MSG(hd_probe_error_string) + jmp general_error + +/* + * Read error on the disk. + */ +read_error: + MSG(read_error_string) + +general_error: + MSG(general_error_string) + +/* go here when you need to stop the machine hard after an error condition */ +stop: jmp stop + +notification_string: .string "PUPA " +geometry_error_string: .string "Geom" +hd_probe_error_string: .string "Hard Disk" +read_error_string: .string "Read" +general_error_string: .string " Error" + +/* + * message: write the string pointed to by %si + * + * WARNING: trashes %si, %ax, and %bx + */ + + /* + * Use BIOS "int 10H Function 0Eh" to write character in teletype mode + * %ah = 0xe %al = character + * %bh = page %bl = foreground color (graphics modes) + */ +1: + movw $0x0001, %bx + movb $0xe, %ah + int $0x10 /* display a byte */ +message: + lodsb + cmpb $0, %al + jne 1b /* if not end of string, jmp to display */ + ret + + /* + * Windows NT breaks compatibility by embedding a magic + * number here. + */ + + . = _start + PUPA_BOOT_MACHINE_WINDOWS_NT_MAGIC +nt_magic: + .long 0 + .word 0 + + /* + * This is where an MBR would go if on a hard disk. The code + * here isn't even referenced unless we're on a floppy. Kinda + * sneaky, huh? + */ + +part_start: + . = _start + PUPA_BOOT_MACHINE_PART_START + +probe_values: + .byte 36, 18, 15, 9, 0 + +floppy_probe: +/* + * Perform floppy probe. + */ + + movw $ABS(probe_values-1), %si + +probe_loop: + /* reset floppy controller INT 13h AH=0 */ + xorw %ax, %ax + int $0x13 + + incw %si + movb (%si), %cl + + /* if number of sectors is 0, display error and die */ + cmpb $0, %cl + jne 1f + +/* + * Floppy disk probe failure. + */ + MSG(fd_probe_error_string) + jmp general_error + +fd_probe_error_string: .string "Floppy" + +1: + /* perform read */ + movw $PUPA_BOOT_MACHINE_BUFFER_SEG, %bx + movw $0x201, %ax + movb $0, %ch + movb $0, %dh + int $0x13 + + /* if error, jump to "probe_loop" */ + jc probe_loop + + /* %cl is already the correct value! */ + movb $1, %dh + movb $79, %ch + + jmp final_init + + . = _start + PUPA_BOOT_MACHINE_PART_END + +/* the last 2 bytes in the sector 0 contain the signature */ + .word PUPA_BOOT_MACHINE_SIGNATURE diff --git a/boot/i386/pc/diskboot.S b/boot/i386/pc/diskboot.S new file mode 100644 index 000000000..da1e02a17 --- /dev/null +++ b/boot/i386/pc/diskboot.S @@ -0,0 +1,387 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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 + +/* + * defines for the code go here + */ + + /* Absolute addresses + This makes the assembler generate the address without support + from the linker. (ELF can't relocate 16-bit addresses!) */ +#define ABS(x) (x-_start+PUPA_BOOT_MACHINE_KERNEL_ADDR) + + /* Print message string */ +#define MSG(x) movw $ABS(x), %si; call message + + .file "diskboot.S" + + .text + + /* Tell GAS to generate 16-bit instructions so that this code works + in real mode. */ + .code16 + + .globl start, _start +start: +_start: + /* + * _start is loaded at 0x2000 and is jumped to with + * CS:IP 0:0x2000 in kernel. + */ + + /* + * we continue to use the stack for boot.img and assume that + * some registers are set to correct values. See boot.S + * for more information. + */ + + /* save drive reference first thing! */ + pushw %dx + + /* print a notification message on the screen */ + pushw %si + MSG(notification_string) + popw %si + + /* this sets up for the first run through "bootloop" */ + movw $ABS(firstlist - PUPA_BOOT_MACHINE_LIST_SIZE), %di + + /* save the sector number of the second sector in %ebp */ + movl (%di), %ebp + + /* this is the loop for reading the rest of the kernel in */ +bootloop: + + /* check the number of sectors to read */ + cmpw $0, 4(%di) + + /* if zero, go to the start function */ + je bootit + +setup_sectors: + /* check if we use LBA or CHS */ + cmpb $0, -1(%si) + + /* jump to chs_mode if zero */ + je chs_mode + +lba_mode: + /* load logical sector start */ + movl (%di), %ebx + + /* the maximum is limited to 0x7f because of Phoenix EDD */ + xorl %eax, %eax + movb $0x7f, %al + + /* how many do we really want to read? */ + cmpw %ax, 4(%di) /* compare against total number of sectors */ + + /* which is greater? */ + jg 1f + + /* if less than, set to total */ + movw 4(%di), %ax + +1: + /* subtract from total */ + subw %ax, 4(%di) + + /* add into logical sector start */ + addl %eax, (%di) + + /* set up disk address packet */ + + /* the size and the reserved byte */ + movw $0x0010, (%si) + + /* the number of sectors */ + movw %ax, 2(%si) + + /* the absolute address (low 32 bits) */ + movl %ebx, 8(%si) + + /* the segment of buffer address */ + movw $PUPA_BOOT_MACHINE_BUFFER_SEG, 6(%si) + + /* save %ax from destruction! */ + pushw %ax + + /* zero %eax */ + xorl %eax, %eax + + /* the offset of buffer address */ + movw %ax, 4(%si) + + /* the absolute address (high 32 bits) */ + movl %eax, 12(%si) + + +/* + * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory + * Call with %ah = 0x42 + * %dl = drive number + * %ds:%si = segment:offset of disk address packet + * Return: + * %al = 0x0 on success; err code on failure + */ + + movb $0x42, %ah + int $0x13 + + jc read_error + + movw $PUPA_BOOT_MACHINE_BUFFER_SEG, %bx + jmp copy_buffer + +chs_mode: + /* load logical sector start (bottom half) */ + movl (%di), %eax + + /* zero %edx */ + xorl %edx, %edx + + /* divide by number of sectors */ + divl (%si) + + /* save sector start */ + movb %dl, 10(%si) + + xorl %edx, %edx /* zero %edx */ + divl 4(%si) /* divide by number of heads */ + + /* save head start */ + movb %dl, 11(%si) + + /* save cylinder start */ + movw %ax, 12(%si) + + /* do we need too many cylinders? */ + cmpw 8(%si), %ax + jge geometry_error + + /* determine the maximum sector length of this read */ + movw (%si), %ax /* get number of sectors per track/head */ + + /* subtract sector start */ + subb 10(%si), %al + + /* how many do we really want to read? */ + cmpw %ax, 4(%di) /* compare against total number of sectors */ + + + /* which is greater? */ + jg 2f + + /* if less than, set to total */ + movw 4(%di), %ax + +2: + /* subtract from total */ + subw %ax, 4(%di) + + /* add into logical sector start */ + addl %eax, (%di) + +/* + * This is the loop for taking care of BIOS geometry translation (ugh!) + */ + + /* get high bits of cylinder */ + movb 13(%si), %dl + + shlb $6, %dl /* shift left by 6 bits */ + movb 10(%si), %cl /* get sector */ + + incb %cl /* normalize sector (sectors go + from 1-N, not 0-(N-1) ) */ + orb %dl, %cl /* composite together */ + movb 12(%si), %ch /* sector+hcyl in cl, cylinder in ch */ + + /* restore %dx */ + popw %dx + pushw %dx + + /* head number */ + movb 11(%si), %dh + + pushw %ax /* save %ax from destruction! */ + +/* + * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory + * Call with %ah = 0x2 + * %al = number of sectors + * %ch = cylinder + * %cl = sector (bits 6-7 are high bits of "cylinder") + * %dh = head + * %dl = drive (0x80 for hard disk, 0x0 for floppy disk) + * %es:%bx = segment:offset of buffer + * Return: + * %al = 0x0 on success; err code on failure + */ + + movw $PUPA_BOOT_MACHINE_BUFFER_SEG, %bx + movw %bx, %es /* load %es segment with disk buffer */ + + xorw %bx, %bx /* %bx = 0, put it at 0 in the segment */ + movb $0x2, %ah /* function 2 */ + int $0x13 + + jc read_error + + /* save source segment */ + movw %es, %bx + +copy_buffer: + + /* load addresses for copy from disk buffer to destination */ + movw 6(%di), %es /* load destination segment */ + + /* restore %ax */ + popw %ax + + /* determine the next possible destination address (presuming + 512 byte sectors!) */ + shlw $5, %ax /* shift %ax five bits to the left */ + addw %ax, 6(%di) /* add the corrected value to the destination + address for next time */ + + /* save addressing regs */ + pusha + pushw %ds + + /* get the copy length */ + shlw $3, %ax + movw %ax, %cx + + xorw %di, %di /* zero offset of destination addresses */ + xorw %si, %si /* zero offset of source addresses */ + movw %bx, %ds /* restore the source segment */ + + cld /* sets the copy direction to forward */ + + /* perform copy */ + rep /* sets a repeat */ + movsw /* this runs the actual copy */ + + /* restore addressing regs and print a dot with correct DS + (MSG modifies SI, which is saved, and unused AX and BX) */ + popw %ds + MSG(notification_step) + popa + + /* check if finished with this dataset */ + cmpw $0, 4(%di) + jne setup_sectors + + /* update position to load from */ + subw $PUPA_BOOT_MACHINE_LIST_SIZE, %di + + /* jump to bootloop */ + jmp bootloop + +/* END OF MAIN LOOP */ + +bootit: + /* print a newline */ + MSG(notification_done) + popw %dx /* this makes sure %dl is our "boot" drive */ + ljmp $0, $(PUPA_BOOT_MACHINE_KERNEL_ADDR + 0x200) + + +/* + * BIOS Geometry translation error (past the end of the disk geometry!). + */ +geometry_error: + MSG(geometry_error_string) + jmp general_error + +/* + * Read error on the disk. + */ +read_error: + MSG(read_error_string) + +general_error: + MSG(general_error_string) + +/* go here when you need to stop the machine hard after an error condition */ +stop: jmp stop + +notification_string: .string "Loading kernel" + +notification_step: .string "." +notification_done: .string "\r\n" + +geometry_error_string: .string "Geom" +read_error_string: .string "Read" +general_error_string: .string " Error" + +/* + * message: write the string pointed to by %si + * + * WARNING: trashes %si, %ax, and %bx + */ + + /* + * Use BIOS "int 10H Function 0Eh" to write character in teletype mode + * %ah = 0xe %al = character + * %bh = page %bl = foreground color (graphics modes) + */ +1: + movw $0x0001, %bx + movb $0xe, %ah + int $0x10 /* display a byte */ + + incw %si +message: + movb (%si), %al + cmpb $0, %al + jne 1b /* if not end of string, jmp to display */ + ret +lastlist: + +/* + * This area is an empty space between the main body of code below which + * grows up (fixed after compilation, but between releases it may change + * in size easily), and the lists of sectors to read, which grows down + * from a fixed top location. + */ + + .word 0 + .word 0 + + . = _start + 0x200 - PUPA_BOOT_MACHINE_LIST_SIZE + + /* fill the first data listing with the default */ +blocklist_default_start: + /* this is the sector start parameter, in logical sectors from + the start of the disk, sector 0 */ + .long 2 +blocklist_default_len: + /* this is the number of sectors to read the command "install" + will fill this up */ + .word 0 +blocklist_default_seg: + /* this is the segment of the starting address to load the data into */ + .word (PUPA_BOOT_MACHINE_KERNEL_SEG + 0x20) + +firstlist: /* this label has to be after the list data!!! */ diff --git a/conf/i386-pc.mk b/conf/i386-pc.mk new file mode 100644 index 000000000..ee4880b77 --- /dev/null +++ b/conf/i386-pc.mk @@ -0,0 +1,379 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -fno-builtin +COMMON_CFLAGS = -fno-builtin + +# Images. +pkgdata_IMAGES = boot.img diskboot.img kernel.img + +# For boot.img. +boot_img_SOURCES = boot/i386/pc/boot.S +CLEANFILES += boot.img boot.exec boot_img-boot_i386_pc_boot.o +MOSTLYCLEANFILES += boot_img-boot_i386_pc_boot.d + +boot.img: boot.exec + $(OBJCOPY) -O binary -R .note -R .comment $< $@ + +boot.exec: boot_img-boot_i386_pc_boot.o + $(CC) $(LDFLAGS) $(boot_img_LDFLAGS) -o $@ $^ + +boot_img-boot_i386_pc_boot.o: boot/i386/pc/boot.S + $(CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(CPPFLAGS) -DASM_FILE=1 $(ASFLAGS) $(boot_img_ASFLAGS) -c -o $@ $< + +boot_img-boot_i386_pc_boot.d: boot/i386/pc/boot.S + set -e; $(CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(CPPFLAGS) -DASM_FILE=1 $(ASFLAGS) $(boot_img_ASFLAGS) -M $< | sed 's,boot\.o[ :]*,boot_img-boot_i386_pc_boot.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include boot_img-boot_i386_pc_boot.d + +boot_img_ASFLAGS = $(COMMON_ASFLAGS) +boot_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00 + +# For diskboot.img. +diskboot_img_SOURCES = boot/i386/pc/diskboot.S +CLEANFILES += diskboot.img diskboot.exec diskboot_img-boot_i386_pc_diskboot.o +MOSTLYCLEANFILES += diskboot_img-boot_i386_pc_diskboot.d + +diskboot.img: diskboot.exec + $(OBJCOPY) -O binary -R .note -R .comment $< $@ + +diskboot.exec: diskboot_img-boot_i386_pc_diskboot.o + $(CC) $(LDFLAGS) $(diskboot_img_LDFLAGS) -o $@ $^ + +diskboot_img-boot_i386_pc_diskboot.o: boot/i386/pc/diskboot.S + $(CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(CPPFLAGS) -DASM_FILE=1 $(ASFLAGS) $(diskboot_img_ASFLAGS) -c -o $@ $< + +diskboot_img-boot_i386_pc_diskboot.d: boot/i386/pc/diskboot.S + set -e; $(CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(CPPFLAGS) -DASM_FILE=1 $(ASFLAGS) $(diskboot_img_ASFLAGS) -M $< | sed 's,diskboot\.o[ :]*,diskboot_img-boot_i386_pc_diskboot.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include diskboot_img-boot_i386_pc_diskboot.d + +diskboot_img_ASFLAGS = $(COMMON_ASFLAGS) +diskboot_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,8000 + +# For kernel.img. +kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/i386/dl.c kern/i386/pc/init.c disk/i386/pc/partition.c \ + disk/i386/pc/biosdisk.c \ + term/i386/pc/console.c \ + symlist.c +CLEANFILES += kernel.img kernel.exec kernel_img-kern_i386_pc_startup.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_loader.o kernel_img-kern_rescue.o kernel_img-kern_term.o kernel_img-kern_i386_dl.o kernel_img-kern_i386_pc_init.o kernel_img-disk_i386_pc_partition.o kernel_img-disk_i386_pc_biosdisk.o kernel_img-term_i386_pc_console.o kernel_img-symlist.o +MOSTLYCLEANFILES += kernel_img-kern_i386_pc_startup.d kernel_img-kern_main.d kernel_img-kern_device.d kernel_img-kern_disk.d kernel_img-kern_dl.d kernel_img-kern_file.d kernel_img-kern_fs.d kernel_img-kern_err.d kernel_img-kern_misc.d kernel_img-kern_mm.d kernel_img-kern_loader.d kernel_img-kern_rescue.d kernel_img-kern_term.d kernel_img-kern_i386_dl.d kernel_img-kern_i386_pc_init.d kernel_img-disk_i386_pc_partition.d kernel_img-disk_i386_pc_biosdisk.d kernel_img-term_i386_pc_console.d kernel_img-symlist.d + +kernel.img: kernel.exec + $(OBJCOPY) -O binary -R .note -R .comment $< $@ + +kernel.exec: kernel_img-kern_i386_pc_startup.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_loader.o kernel_img-kern_rescue.o kernel_img-kern_term.o kernel_img-kern_i386_dl.o kernel_img-kern_i386_pc_init.o kernel_img-disk_i386_pc_partition.o kernel_img-disk_i386_pc_biosdisk.o kernel_img-term_i386_pc_console.o kernel_img-symlist.o + $(CC) $(LDFLAGS) $(kernel_img_LDFLAGS) -o $@ $^ + +kernel_img-kern_i386_pc_startup.o: kern/i386/pc/startup.S + $(CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(CPPFLAGS) -DASM_FILE=1 $(ASFLAGS) $(kernel_img_ASFLAGS) -c -o $@ $< + +kernel_img-kern_i386_pc_startup.d: kern/i386/pc/startup.S + set -e; $(CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(CPPFLAGS) -DASM_FILE=1 $(ASFLAGS) $(kernel_img_ASFLAGS) -M $< | sed 's,startup\.o[ :]*,kernel_img-kern_i386_pc_startup.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_i386_pc_startup.d + +kernel_img-kern_main.o: kern/main.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_main.d: kern/main.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,main\.o[ :]*,kernel_img-kern_main.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_main.d + +kernel_img-kern_device.o: kern/device.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_device.d: kern/device.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,device\.o[ :]*,kernel_img-kern_device.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_device.d + +kernel_img-kern_disk.o: kern/disk.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_disk.d: kern/disk.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,disk\.o[ :]*,kernel_img-kern_disk.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_disk.d + +kernel_img-kern_dl.o: kern/dl.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_dl.d: kern/dl.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,dl\.o[ :]*,kernel_img-kern_dl.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_dl.d + +kernel_img-kern_file.o: kern/file.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_file.d: kern/file.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,file\.o[ :]*,kernel_img-kern_file.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_file.d + +kernel_img-kern_fs.o: kern/fs.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_fs.d: kern/fs.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,fs\.o[ :]*,kernel_img-kern_fs.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_fs.d + +kernel_img-kern_err.o: kern/err.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_err.d: kern/err.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,err\.o[ :]*,kernel_img-kern_err.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_err.d + +kernel_img-kern_misc.o: kern/misc.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_misc.d: kern/misc.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,misc\.o[ :]*,kernel_img-kern_misc.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_misc.d + +kernel_img-kern_mm.o: kern/mm.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_mm.d: kern/mm.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,mm\.o[ :]*,kernel_img-kern_mm.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_mm.d + +kernel_img-kern_loader.o: kern/loader.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_loader.d: kern/loader.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,loader\.o[ :]*,kernel_img-kern_loader.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_loader.d + +kernel_img-kern_rescue.o: kern/rescue.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_rescue.d: kern/rescue.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,rescue\.o[ :]*,kernel_img-kern_rescue.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_rescue.d + +kernel_img-kern_term.o: kern/term.c + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_term.d: kern/term.c + set -e; $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,term\.o[ :]*,kernel_img-kern_term.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_term.d + +kernel_img-kern_i386_dl.o: kern/i386/dl.c + $(CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_i386_dl.d: kern/i386/dl.c + set -e; $(CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,dl\.o[ :]*,kernel_img-kern_i386_dl.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_i386_dl.d + +kernel_img-kern_i386_pc_init.o: kern/i386/pc/init.c + $(CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-kern_i386_pc_init.d: kern/i386/pc/init.c + set -e; $(CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,init\.o[ :]*,kernel_img-kern_i386_pc_init.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-kern_i386_pc_init.d + +kernel_img-disk_i386_pc_partition.o: disk/i386/pc/partition.c + $(CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-disk_i386_pc_partition.d: disk/i386/pc/partition.c + set -e; $(CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,partition\.o[ :]*,kernel_img-disk_i386_pc_partition.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-disk_i386_pc_partition.d + +kernel_img-disk_i386_pc_biosdisk.o: disk/i386/pc/biosdisk.c + $(CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-disk_i386_pc_biosdisk.d: disk/i386/pc/biosdisk.c + set -e; $(CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,biosdisk\.o[ :]*,kernel_img-disk_i386_pc_biosdisk.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-disk_i386_pc_biosdisk.d + +kernel_img-term_i386_pc_console.o: term/i386/pc/console.c + $(CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-term_i386_pc_console.d: term/i386/pc/console.c + set -e; $(CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,console\.o[ :]*,kernel_img-term_i386_pc_console.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-term_i386_pc_console.d + +kernel_img-symlist.o: symlist.c + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -c -o $@ $< + +kernel_img-symlist.d: symlist.c + set -e; $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) $(kernel_img_CFLAGS) -M $< | sed 's,symlist\.o[ :]*,kernel_img-symlist.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include kernel_img-symlist.d + +kernel_img_HEADERS = boot.h device.h disk.h dl.h elf.h err.h \ + file.h fs.h kernel.h loader.h misc.h mm.h net.h rescue.h symbol.h \ + term.h types.h machine/biosdisk.h machine/boot.h \ + machine/console.h machine/init.h machine/memory.h \ + machine/loader.h machine/partition.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,8200 + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/pupa/,$(kernel_img_HEADERS)) gensymlist.sh + sh $(srcdir)/gensymlist.sh $(filter %.h,$^) > $@ + +kernel_syms.lst: $(addprefix include/pupa/,$(kernel_img_HEADERS)) genkernsyms.sh + sh $(srcdir)/genkernsyms.sh $(filter %h,$^) > $@ + +# Utilities. +bin_UTILITIES = pupa-mkimage +noinst_UTILITIES = genmoddep + +# For pupa-mkimage. +pupa_mkimage_SOURCES = util/i386/pc/pupa-mkimage.c util/misc.c \ + util/resolve.c +CLEANFILES += pupa-mkimage pupa_mkimage-util_i386_pc_pupa_mkimage.o pupa_mkimage-util_misc.o pupa_mkimage-util_resolve.o +MOSTLYCLEANFILES += pupa_mkimage-util_i386_pc_pupa_mkimage.d pupa_mkimage-util_misc.d pupa_mkimage-util_resolve.d + +pupa-mkimage: pupa_mkimage-util_i386_pc_pupa_mkimage.o pupa_mkimage-util_misc.o pupa_mkimage-util_resolve.o + $(BUILD_CC) $(BUILD_LDFLAGS) $(pupa_mkimage_LDFLAGS) -o $@ $^ + +pupa_mkimage-util_i386_pc_pupa_mkimage.o: util/i386/pc/pupa-mkimage.c + $(BUILD_CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(pupa_mkimage_CFLAGS) -c -o $@ $< + +pupa_mkimage-util_i386_pc_pupa_mkimage.d: util/i386/pc/pupa-mkimage.c + set -e; $(BUILD_CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(pupa_mkimage_CFLAGS) -M $< | sed 's,pupa\-mkimage\.o[ :]*,pupa_mkimage-util_i386_pc_pupa_mkimage.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include pupa_mkimage-util_i386_pc_pupa_mkimage.d + +pupa_mkimage-util_misc.o: util/misc.c + $(BUILD_CC) -Iutil -I$(srcdir)/util $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(pupa_mkimage_CFLAGS) -c -o $@ $< + +pupa_mkimage-util_misc.d: util/misc.c + set -e; $(BUILD_CC) -Iutil -I$(srcdir)/util $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(pupa_mkimage_CFLAGS) -M $< | sed 's,misc\.o[ :]*,pupa_mkimage-util_misc.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include pupa_mkimage-util_misc.d + +pupa_mkimage-util_resolve.o: util/resolve.c + $(BUILD_CC) -Iutil -I$(srcdir)/util $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(pupa_mkimage_CFLAGS) -c -o $@ $< + +pupa_mkimage-util_resolve.d: util/resolve.c + set -e; $(BUILD_CC) -Iutil -I$(srcdir)/util $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(pupa_mkimage_CFLAGS) -M $< | sed 's,resolve\.o[ :]*,pupa_mkimage-util_resolve.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include pupa_mkimage-util_resolve.d + + +# For genmoddep. +genmoddep_SOURCES = util/genmoddep.c +CLEANFILES += genmoddep genmoddep-util_genmoddep.o +MOSTLYCLEANFILES += genmoddep-util_genmoddep.d + +genmoddep: genmoddep-util_genmoddep.o + $(BUILD_CC) $(BUILD_LDFLAGS) $(genmoddep_LDFLAGS) -o $@ $^ + +genmoddep-util_genmoddep.o: util/genmoddep.c + $(BUILD_CC) -Iutil -I$(srcdir)/util $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(genmoddep_CFLAGS) -c -o $@ $< + +genmoddep-util_genmoddep.d: util/genmoddep.c + set -e; $(BUILD_CC) -Iutil -I$(srcdir)/util $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(genmoddep_CFLAGS) -M $< | sed 's,genmoddep\.o[ :]*,genmoddep-util_genmoddep.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include genmoddep-util_genmoddep.d + + +# Modules. +pkgdata_MODULES = chain.mod fat.mod + +# For chain.mod. +chain_mod_SOURCES = loader/i386/pc/chainloader.c +CLEANFILES += chain.mod mod-chain.o mod-chain.c pre-chain.o chain_mod-loader_i386_pc_chainloader.o def-chain.lst und-chain.lst +MOSTLYCLEANFILES += chain_mod-loader_i386_pc_chainloader.d +DEFSYMFILES += def-chain.lst +UNDSYMFILES += und-chain.lst + +chain.mod: pre-chain.o mod-chain.o + -rm -f $@ + $(LD) -r -o $@ $^ + $(STRIP) --strip-unneeded -K pupa_mod_init -K pupa_mod_fini -R .note -R .comment $@ + +pre-chain.o: chain_mod-loader_i386_pc_chainloader.o + -rm -f $@ + $(LD) -r -o $@ $^ + +mod-chain.o: mod-chain.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + +mod-chain.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'chain' $< > $@ || (rm -f $@; exit 1) + +def-chain.lst: pre-chain.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 chain/' > $@ + +und-chain.lst: pre-chain.o + echo 'chain' > $@ + $(NM) -u -P -p $< >> $@ + +chain_mod-loader_i386_pc_chainloader.o: loader/i386/pc/chainloader.c + $(CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(CPPFLAGS) $(CFLAGS) $(chain_mod_CFLAGS) -c -o $@ $< + +chain_mod-loader_i386_pc_chainloader.d: loader/i386/pc/chainloader.c + set -e; $(CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(CPPFLAGS) $(CFLAGS) $(chain_mod_CFLAGS) -M $< | sed 's,chainloader\.o[ :]*,chain_mod-loader_i386_pc_chainloader.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include chain_mod-loader_i386_pc_chainloader.d + +chain_mod_CFLAGS = $(COMMON_CFLAGS) + +# For fat.mod. +fat_mod_SOURCES = fs/fat.c +CLEANFILES += fat.mod mod-fat.o mod-fat.c pre-fat.o fat_mod-fs_fat.o def-fat.lst und-fat.lst +MOSTLYCLEANFILES += fat_mod-fs_fat.d +DEFSYMFILES += def-fat.lst +UNDSYMFILES += und-fat.lst + +fat.mod: pre-fat.o mod-fat.o + -rm -f $@ + $(LD) -r -o $@ $^ + $(STRIP) --strip-unneeded -K pupa_mod_init -K pupa_mod_fini -R .note -R .comment $@ + +pre-fat.o: fat_mod-fs_fat.o + -rm -f $@ + $(LD) -r -o $@ $^ + +mod-fat.o: mod-fat.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + +mod-fat.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'fat' $< > $@ || (rm -f $@; exit 1) + +def-fat.lst: pre-fat.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fat/' > $@ + +und-fat.lst: pre-fat.o + echo 'fat' > $@ + $(NM) -u -P -p $< >> $@ + +fat_mod-fs_fat.o: fs/fat.c + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) $(fat_mod_CFLAGS) -c -o $@ $< + +fat_mod-fs_fat.d: fs/fat.c + set -e; $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) $(fat_mod_CFLAGS) -M $< | sed 's,fat\.o[ :]*,fat_mod-fs_fat.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include fat_mod-fs_fat.d + +fat_mod_CFLAGS = $(COMMON_CFLAGS) +CLEANFILES += moddep.lst +pkgdata_DATA += moddep.lst +moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep + cat $(DEFSYMFILES) /dev/null | ./genmoddep $(UNDSYMFILES) > $@ \ + || (rm -f $@; exit 1) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk new file mode 100644 index 000000000..9f72c7e46 --- /dev/null +++ b/conf/i386-pc.rmk @@ -0,0 +1,65 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -fno-builtin +COMMON_CFLAGS = -fno-builtin + +# Images. +pkgdata_IMAGES = boot.img diskboot.img kernel.img + +# For boot.img. +boot_img_SOURCES = boot/i386/pc/boot.S +boot_img_ASFLAGS = $(COMMON_ASFLAGS) +boot_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00 + +# For diskboot.img. +diskboot_img_SOURCES = boot/i386/pc/diskboot.S +diskboot_img_ASFLAGS = $(COMMON_ASFLAGS) +diskboot_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,8000 + +# For kernel.img. +kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/i386/dl.c kern/i386/pc/init.c disk/i386/pc/partition.c \ + disk/i386/pc/biosdisk.c \ + term/i386/pc/console.c \ + symlist.c +kernel_img_HEADERS = boot.h device.h disk.h dl.h elf.h err.h \ + file.h fs.h kernel.h loader.h misc.h mm.h net.h rescue.h symbol.h \ + term.h types.h machine/biosdisk.h machine/boot.h \ + machine/console.h machine/init.h machine/memory.h \ + machine/loader.h machine/partition.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,8200 + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/pupa/,$(kernel_img_HEADERS)) gensymlist.sh + sh $(srcdir)/gensymlist.sh $(filter %.h,$^) > $@ + +kernel_syms.lst: $(addprefix include/pupa/,$(kernel_img_HEADERS)) genkernsyms.sh + sh $(srcdir)/genkernsyms.sh $(filter %h,$^) > $@ + +# Utilities. +bin_UTILITIES = pupa-mkimage +noinst_UTILITIES = genmoddep + +# For pupa-mkimage. +pupa_mkimage_SOURCES = util/i386/pc/pupa-mkimage.c util/misc.c \ + util/resolve.c + +# For genmoddep. +genmoddep_SOURCES = util/genmoddep.c + +# Modules. +pkgdata_MODULES = chain.mod fat.mod + +# For chain.mod. +chain_mod_SOURCES = loader/i386/pc/chainloader.c +chain_mod_CFLAGS = $(COMMON_CFLAGS) + +# For fat.mod. +fat_mod_SOURCES = fs/fat.c +fat_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/config.guess b/config.guess new file mode 100644 index 000000000..ed2e03b7f --- /dev/null +++ b/config.guess @@ -0,0 +1,1321 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-20' + +# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c ; + for c in cc gcc c89 c99 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $dummy.c $dummy.o $dummy.rel ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 000000000..44ab1f719 --- /dev/null +++ b/config.h.in @@ -0,0 +1,78 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define it if GAS requires that absolute indirect calls/jumps are not + prefixed with an asterisk */ +#undef ABSOLUTE_WITHOUT_ASTERISK + +/* Define it to "addr32" or "addr32;" to make GAS happy */ +#undef ADDR32 + +/* Define it to one of __bss_start, edata and _edata */ +#undef BSS_START_SYMBOL + +/* Define it to "data32" or "data32;" to make GAS happy */ +#undef DATA32 + +/* Define it to either end or _end */ +#undef END_SYMBOL + +/* Define if C symbols get an underscore after compilation */ +#undef HAVE_ASM_USCORE + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of a `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of a `void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P + +/* Define it to either start or _start */ +#undef START_SYMBOL + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN diff --git a/config.sub b/config.sub new file mode 100644 index 000000000..299f3f4c5 --- /dev/null +++ b/config.sub @@ -0,0 +1,1443 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-04-26' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 | mipsisa64 \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* ) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100644 index 000000000..45a328b60 --- /dev/null +++ b/configure @@ -0,0 +1,5745 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.53 for PUPA 0.6. +# +# Report bugs to . +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + + +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# NLS nuisances. +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +(set +x; test -n "`(LANG=C; export LANG) 2>&1`") && + { $as_unset LANG || test "${LANG+set}" != set; } || + { LANG=C; export LANG; } +(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") && + { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } || + { LC_ALL=C; export LC_ALL; } +(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") && + { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } || + { LC_TIME=C; export LC_TIME; } +(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") && + { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } || + { LC_CTYPE=C; export LC_CTYPE; } +(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") && + { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } || + { LANGUAGE=C; export LANGUAGE; } +(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") && + { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } || + { LC_COLLATE=C; export LC_COLLATE; } +(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") && + { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } || + { LC_NUMERIC=C; export LC_NUMERIC; } +(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") && + { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } || + { LC_MESSAGES=C; export LC_MESSAGES; } + + +# Name of the executable. +as_me=`(basename "$0") 2>/dev/null || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; } + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='PUPA' +PACKAGE_TARNAME='pupa' +PACKAGE_VERSION='0.6' +PACKAGE_STRING='PUPA 0.6' +PACKAGE_BUGREPORT='okuji@enbug.org' + +ac_unique_file="include/pupa/dl.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures PUPA 0.6 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of PUPA 0.6:";; + esac + cat <<\_ACEOF + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +PUPA configure 0.6 +generated by GNU Autoconf 2.53 + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by PUPA $as_me 0.6, which was +generated by GNU Autoconf 2.53. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell meta-characters. +ac_configure_args= +ac_sep= +for ac_arg +do + case $ac_arg in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n ) continue ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + ac_sep=" " ;; + esac + # Get rid of the leading space. +done + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core core.* *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ac_config_headers="$ac_config_headers config.h" + + +# Checks for build and host systems. +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + +case "$host_cpu" in + i[3456]86) host_cpu=i386 ;; + *) { { echo "$as_me:$LINENO: error: unsupported CPU type" >&5 +echo "$as_me: error: unsupported CPU type" >&2;} + { (exit 1); exit 1; }; } ;; +esac + +case "$host_cpu"-"$host_vendor" in + i386-*) host_vendor=pc ;; + *) { { echo "$as_me:$LINENO: error: unsupported machine type" >&5 +echo "$as_me: error: unsupported machine type" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + + + +# Checks for programs. +if test "x$CFLAGS" = x; then + default_CFLAGS=yes +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$as_dir/$ac_word" ${1+"$@"} + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +for ac_file in `ls a_out.exe a.exe conftest.exe 2>/dev/null; + ls a.out conftest 2>/dev/null; + ls a.* conftest.* 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb | *.xSYM ) ;; + a.out ) # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool --akim. + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables" >&5 +echo "$as_me: error: C compiler cannot create executables" >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +$ac_declaration +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_declaration +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Must be GCC. +test "x$GCC" = xyes || { { echo "$as_me:$LINENO: error: GCC is required" >&5 +echo "$as_me: error: GCC is required" >&2;} + { (exit 1); exit 1; }; } + +if test "x$default_CFLAGS" = xyes; then + # debug flags. + tmp_CFLAGS="-Wall -W -g" + + # optimization flags. + echo "$as_me:$LINENO: checking whether optimization for size works" >&5 +echo $ECHO_N "checking whether optimization for size works... $ECHO_C" >&6 +if test "${size_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + CFLAGS=-Os + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + size_flag=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +size_flag=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $size_flag" >&5 +echo "${ECHO_T}$size_flag" >&6 + if test "x$size_flag" = xyes; then + tmp_CFLAGS="$tmp_CFLAGS -Os" + else + tmp_CFLAGS="$tmp_CFLAGS -O2 -fno-strength-reduce -fno-unroll-loops" + fi + + # Force no alignment to save space on i386. + if test "x$host_cpu" = xi386; then + echo "$as_me:$LINENO: checking whether -falign-loops works" >&5 +echo $ECHO_N "checking whether -falign-loops works... $ECHO_C" >&6 +if test "${falign_loop_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + CFLAGS="-falign-loops=1" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + falign_loop_flag=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +falign_loop_flag=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $falign_loop_flag" >&5 +echo "${ECHO_T}$falign_loop_flag" >&6 + + if test "x$falign_loop_flag" = xyes; then + tmp_CFLAGS="$tmp_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1" + else + tmp_CFLAGS="$tmp_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1" + fi + fi + + CFLAGS="$tmp_CFLAGS" +fi + + +# Defined in aclocal.m4. + +echo "$as_me:$LINENO: checking if C symbols get an underscore after compilation" >&5 +echo $ECHO_N "checking if C symbols get an underscore after compilation... $ECHO_C" >&6 +if test "${pupa_cv_asm_uscore+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.c <<\EOF +int +func (int *list) +{ + *list = 0; + return *list; +} +EOF + +if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.s; then + true +else + { { echo "$as_me:$LINENO: error: ${CC-cc} failed to produce assembly code" >&5 +echo "$as_me: error: ${CC-cc} failed to produce assembly code" >&2;} + { (exit 1); exit 1; }; } +fi + +if grep _func conftest.s >/dev/null 2>&1; then + pupa_cv_asm_uscore=yes +else + pupa_cv_asm_uscore=no +fi + +rm -f conftest* +fi + + +if test "x$pupa_cv_asm_uscore" = xyes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_ASM_USCORE $pupa_cv_asm_uscore +_ACEOF + +fi + +echo "$as_me:$LINENO: result: $pupa_cv_asm_uscore" >&5 +echo "${ECHO_T}$pupa_cv_asm_uscore" >&6 + + +echo "$as_me:$LINENO: checking if start is defined by the compiler" >&5 +echo $ECHO_N "checking if start is defined by the compiler... $ECHO_C" >&6 +if test "${pupa_cv_check_start_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +asm ("incl start") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + pupa_cv_check_start_symbol=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +pupa_cv_check_start_symbol=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi + + +echo "$as_me:$LINENO: result: $pupa_cv_check_start_symbol" >&5 +echo "${ECHO_T}$pupa_cv_check_start_symbol" >&6 + +echo "$as_me:$LINENO: checking if _start is defined by the compiler" >&5 +echo $ECHO_N "checking if _start is defined by the compiler... $ECHO_C" >&6 +if test "${pupa_cv_check_uscore_start_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +asm ("incl _start") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + pupa_cv_check_uscore_start_symbol=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +pupa_cv_check_uscore_start_symbol=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi + + +echo "$as_me:$LINENO: result: $pupa_cv_check_uscore_start_symbol" >&5 +echo "${ECHO_T}$pupa_cv_check_uscore_start_symbol" >&6 + + + + +if test "x$pupa_cv_check_start_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define START_SYMBOL start +_ACEOF + +elif test "x$pupa_cv_check_uscore_start_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define START_SYMBOL _start +_ACEOF + +else + { { echo "$as_me:$LINENO: error: neither start nor _start is defined" >&5 +echo "$as_me: error: neither start nor _start is defined" >&2;} + { (exit 1); exit 1; }; } +fi + + +echo "$as_me:$LINENO: checking if __bss_start is defined by the compiler" >&5 +echo $ECHO_N "checking if __bss_start is defined by the compiler... $ECHO_C" >&6 +if test "${pupa_cv_check_uscore_uscore_bss_start_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +asm ("incl __bss_start") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + pupa_cv_check_uscore_uscore_bss_start_symbol=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +pupa_cv_check_uscore_uscore_bss_start_symbol=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi + + +echo "$as_me:$LINENO: result: $pupa_cv_check_uscore_uscore_bss_start_symbol" >&5 +echo "${ECHO_T}$pupa_cv_check_uscore_uscore_bss_start_symbol" >&6 + +echo "$as_me:$LINENO: checking if edata is defined by the compiler" >&5 +echo $ECHO_N "checking if edata is defined by the compiler... $ECHO_C" >&6 +if test "${pupa_cv_check_edata_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +asm ("incl edata") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + pupa_cv_check_edata_symbol=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +pupa_cv_check_edata_symbol=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi + + +echo "$as_me:$LINENO: result: $pupa_cv_check_edata_symbol" >&5 +echo "${ECHO_T}$pupa_cv_check_edata_symbol" >&6 + +echo "$as_me:$LINENO: checking if _edata is defined by the compiler" >&5 +echo $ECHO_N "checking if _edata is defined by the compiler... $ECHO_C" >&6 +if test "${pupa_cv_check_uscore_edata_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +asm ("incl _edata") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + pupa_cv_check_uscore_edata_symbol=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +pupa_cv_check_uscore_edata_symbol=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi + + +echo "$as_me:$LINENO: result: $pupa_cv_check_uscore_edata_symbol" >&5 +echo "${ECHO_T}$pupa_cv_check_uscore_edata_symbol" >&6 + + + + +if test "x$pupa_cv_check_uscore_uscore_bss_start_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define BSS_START_SYMBOL __bss_start +_ACEOF + +elif test "x$pupa_cv_check_edata_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define BSS_START_SYMBOL edata +_ACEOF + +elif test "x$pupa_cv_check_uscore_edata_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define BSS_START_SYMBOL _edata +_ACEOF + +else + { { echo "$as_me:$LINENO: error: none of __bss_start, edata or _edata is defined" >&5 +echo "$as_me: error: none of __bss_start, edata or _edata is defined" >&2;} + { (exit 1); exit 1; }; } +fi + + +echo "$as_me:$LINENO: checking if end is defined by the compiler" >&5 +echo $ECHO_N "checking if end is defined by the compiler... $ECHO_C" >&6 +if test "${pupa_cv_check_end_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +asm ("incl end") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + pupa_cv_check_end_symbol=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +pupa_cv_check_end_symbol=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi + + +echo "$as_me:$LINENO: result: $pupa_cv_check_end_symbol" >&5 +echo "${ECHO_T}$pupa_cv_check_end_symbol" >&6 + +echo "$as_me:$LINENO: checking if _end is defined by the compiler" >&5 +echo $ECHO_N "checking if _end is defined by the compiler... $ECHO_C" >&6 +if test "${pupa_cv_check_uscore_end_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +asm ("incl _end") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + pupa_cv_check_uscore_end_symbol=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +pupa_cv_check_uscore_end_symbol=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi + + +echo "$as_me:$LINENO: result: $pupa_cv_check_uscore_end_symbol" >&5 +echo "${ECHO_T}$pupa_cv_check_uscore_end_symbol" >&6 + + + + +if test "x$pupa_cv_check_end_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define END_SYMBOL end +_ACEOF + +elif test "x$pupa_cv_check_uscore_end_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define END_SYMBOL _end +_ACEOF + +else + { { echo "$as_me:$LINENO: error: neither end nor _end is defined" >&5 +echo "$as_me: error: neither end nor _end is defined" >&2;} + { (exit 1); exit 1; }; } +fi + + +if test "x$host_cpu" = xi386; then + +echo "$as_me:$LINENO: checking whether addr32 must be in the same line as the instruction" >&5 +echo $ECHO_N "checking whether addr32 must be in the same line as the instruction... $ECHO_C" >&6 +if test "${pupa_cv_i386_asm_prefix_requirement+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<\EOF + .code16 +l1: addr32 movb %al, l1 +EOF + +if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.o; then + pupa_cv_i386_asm_prefix_requirement=yes +else + pupa_cv_i386_asm_prefix_requirement=no +fi + +rm -f conftest* +fi + + +if test "x$pupa_cv_i386_asm_prefix_requirement" = xyes; then + pupa_tmp_addr32="addr32" + pupa_tmp_data32="data32" +else + pupa_tmp_addr32="addr32;" + pupa_tmp_data32="data32;" +fi + + +cat >>confdefs.h <<_ACEOF +#define ADDR32 $pupa_tmp_addr32 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define DATA32 $pupa_tmp_data32 +_ACEOF + + +echo "$as_me:$LINENO: result: $pupa_cv_i386_asm_prefix_requirement" >&5 +echo "${ECHO_T}$pupa_cv_i386_asm_prefix_requirement" >&6 + + +echo "$as_me:$LINENO: checking for .code16 addr32 assembler support" >&5 +echo $ECHO_N "checking for .code16 addr32 assembler support... $ECHO_C" >&6 +if test "${pupa_cv_i386_asm_addr32+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s.in <<\EOF + .code16 +l1: @ADDR32@ movb %al, l1 +EOF + +if test "x$pupa_cv_i386_asm_prefix_requirement" = xyes; then + sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s +else + sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s +fi + +if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.o; then + pupa_cv_i386_asm_addr32=yes +else + pupa_cv_i386_asm_addr32=no +fi + +rm -f conftest* +fi + + +echo "$as_me:$LINENO: result: $pupa_cv_i386_asm_addr32" >&5 +echo "${ECHO_T}$pupa_cv_i386_asm_addr32" >&6 + +echo "$as_me:$LINENO: checking whether an absolute indirect call/jump must not be prefixed with an asterisk" >&5 +echo $ECHO_N "checking whether an absolute indirect call/jump must not be prefixed with an asterisk... $ECHO_C" >&6 +if test "${pupa_cv_i386_asm_absolute_without_asterisk+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<\EOF + lcall *(offset) +offset: + .long 0 + .word 0 +EOF + +if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.o; then + pupa_cv_i386_asm_absolute_without_asterisk=no +else + pupa_cv_i386_asm_absolute_without_asterisk=yes +fi + +rm -f conftest* +fi + + +if test "x$pupa_cv_i386_asm_absolute_without_asterisk" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define ABSOLUTE_WITHOUT_ASTERISK 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: result: $pupa_cv_i386_asm_absolute_without_asterisk" >&5 +echo "${ECHO_T}$pupa_cv_i386_asm_absolute_without_asterisk" >&6 +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="${MAKE}"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. +set dummy ${ac_tool_prefix}objcopy; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_OBJCOPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$OBJCOPY"; then + ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +OBJCOPY=$ac_cv_prog_OBJCOPY +if test -n "$OBJCOPY"; then + echo "$as_me:$LINENO: result: $OBJCOPY" >&5 +echo "${ECHO_T}$OBJCOPY" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_OBJCOPY"; then + ac_ct_OBJCOPY=$OBJCOPY + # Extract the first word of "objcopy", so it can be a program name with args. +set dummy objcopy; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_OBJCOPY"; then + ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJCOPY="objcopy" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY +if test -n "$ac_ct_OBJCOPY"; then + echo "$as_me:$LINENO: result: $ac_ct_OBJCOPY" >&5 +echo "${ECHO_T}$ac_ct_OBJCOPY" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + OBJCOPY=$ac_ct_OBJCOPY +else + OBJCOPY="$ac_cv_prog_OBJCOPY" +fi + +echo "$as_me:$LINENO: checking whether ${OBJCOPY} works for absolute addresses" >&5 +echo $ECHO_N "checking whether ${OBJCOPY} works for absolute addresses... $ECHO_C" >&6 +if test "${pupa_cv_prog_objcopy_absolute+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.c <<\EOF +void +cmain (void) +{ + *((int *) 0x1000) = 2; +} +EOF + +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest.o; then : +else + { { echo "$as_me:$LINENO: error: ${CC-cc} cannot compile C source code" >&5 +echo "$as_me: error: ${CC-cc} cannot compile C source code" >&2;} + { (exit 1); exit 1; }; } +fi +pupa_cv_prog_objcopy_absolute=yes +for link_addr in 2000 8000 7C00; do + if { ac_try='${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then : + else + { { echo "$as_me:$LINENO: error: ${CC-cc} cannot link at address $link_addr" >&5 +echo "$as_me: error: ${CC-cc} cannot link at address $link_addr" >&2;} + { (exit 1); exit 1; }; } + fi + if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then : + else + { { echo "$as_me:$LINENO: error: ${OBJCOPY-objcopy} cannot create binary files" >&5 +echo "$as_me: error: ${OBJCOPY-objcopy} cannot create binary files" >&2;} + { (exit 1); exit 1; }; } + fi + if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + mv -f conftest conftest.old + else + pupa_cv_prog_objcopy_absolute=no + break + fi +done +rm -f conftest* +fi + +echo "$as_me:$LINENO: result: $pupa_cv_prog_objcopy_absolute" >&5 +echo "${ECHO_T}$pupa_cv_prog_objcopy_absolute" >&6 + +if test "x$pupa_cv_prog_objcopy_absolute" = xno; then + { { echo "$as_me:$LINENO: error: PUPA requires a working absolute objcopy; upgrade your binutils" >&5 +echo "$as_me: error: PUPA requires a working absolute objcopy; upgrade your binutils" >&2;} + { (exit 1); exit 1; }; } +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args. +set dummy ${ac_tool_prefix}nm; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NM="${ac_tool_prefix}nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + echo "$as_me:$LINENO: result: $NM" >&5 +echo "${ECHO_T}$NM" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_NM"; then + ac_ct_NM=$NM + # Extract the first word of "nm", so it can be a program name with args. +set dummy nm; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NM="nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + echo "$as_me:$LINENO: result: $ac_ct_NM" >&5 +echo "${ECHO_T}$ac_ct_NM" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + NM=$ac_ct_NM +else + NM="$ac_cv_prog_NM" +fi + + +# This is not a "must". +# Extract the first word of "ruby", so it can be a program name with args. +set dummy ruby; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_RUBY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $RUBY in + [\\/]* | ?:[\\/]*) + ac_cv_path_RUBY="$RUBY" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_RUBY="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +RUBY=$ac_cv_path_RUBY + +if test -n "$RUBY"; then + echo "$as_me:$LINENO: result: $RUBY" >&5 +echo "${ECHO_T}$RUBY" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + +# For cross-compiling. +if test "x$build" = "x$host"; then + BUILD_CC="$CC" + +else + for ac_prog in gcc egcs cc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_BUILD_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$BUILD_CC"; then + ac_cv_prog_BUILD_CC="$BUILD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_BUILD_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +BUILD_CC=$ac_cv_prog_BUILD_CC +if test -n "$BUILD_CC"; then + echo "$as_me:$LINENO: result: $BUILD_CC" >&5 +echo "${ECHO_T}$BUILD_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$BUILD_CC" && break +done +test -n "$BUILD_CC" || BUILD_CC="{ { echo "$as_me:$LINENO: error: none of gcc, egcs and cc is found. set BUILD_CC manually." >&5 +echo "$as_me: error: none of gcc, egcs and cc is found. set BUILD_CC manually." >&2;} + { (exit 1); exit 1; }; }" + +fi + +# Test the C compiler for the build environment. +pupa_tmp_CC="$CC" +CC="$BUILD_CC" +echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_c_bigendian=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianess by grep'ing values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if fgrep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if fgrep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +int +main () +{ + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianess +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianess +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include +#include + +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +echo "$as_me:$LINENO: checking for void *" >&5 +echo $ECHO_N "checking for void *... $ECHO_C" >&6 +if test "${ac_cv_type_void_p+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +if ((void * *) 0) + return 0; +if (sizeof (void *)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_void_p=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_void_p=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_void_p" >&5 +echo "${ECHO_T}$ac_cv_type_void_p" >&6 + +echo "$as_me:$LINENO: checking size of void *" >&5 +echo $ECHO_N "checking size of void *... $ECHO_C" >&6 +if test "${ac_cv_sizeof_void_p+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_void_p" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (void *))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (void *))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (void *))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (void *))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (void *))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_void_p=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (void *), 77" >&5 +echo "$as_me: error: cannot compute sizeof (void *), 77" >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 +echo "$as_me: error: cannot run test program while cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +long longval () { return (long) (sizeof (void *)); } +unsigned long ulongval () { return (long) (sizeof (void *)); } +#include +#include +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (void *))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (void *)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (void *)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_void_p=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (void *), 77" >&5 +echo "$as_me: error: cannot compute sizeof (void *), 77" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_void_p=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_void_p" >&5 +echo "${ECHO_T}$ac_cv_sizeof_void_p" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +_ACEOF + + +echo "$as_me:$LINENO: checking for long" >&5 +echo $ECHO_N "checking for long... $ECHO_C" >&6 +if test "${ac_cv_type_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +if ((long *) 0) + return 0; +if (sizeof (long)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_long=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_long=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 +echo "${ECHO_T}$ac_cv_type_long" >&6 + +echo "$as_me:$LINENO: checking size of long" >&5 +echo $ECHO_N "checking size of long... $ECHO_C" >&6 +if test "${ac_cv_sizeof_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_long" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77" >&5 +echo "$as_me: error: cannot compute sizeof (long), 77" >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 +echo "$as_me: error: cannot run test program while cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +long longval () { return (long) (sizeof (long)); } +unsigned long ulongval () { return (long) (sizeof (long)); } +#include +#include +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (long))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (long)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (long)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77" >&5 +echo "$as_me: error: cannot compute sizeof (long), 77" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_long=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + +CC="$pupa_tmp_CC" + +# Output files. +ac_config_links="$ac_config_links include/pupa/cpu:include/pupa/$host_cpu include/pupa/machine:include/pupa/$host_cpu/$host_vendor" + +ac_config_files="$ac_config_files Makefile" + +ac_config_files="$ac_config_files stamp-h" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overriden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if cmp -s $cache_file confcache; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# NLS nuisances. +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +(set +x; test -n "`(LANG=C; export LANG) 2>&1`") && + { $as_unset LANG || test "${LANG+set}" != set; } || + { LANG=C; export LANG; } +(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") && + { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } || + { LC_ALL=C; export LC_ALL; } +(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") && + { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } || + { LC_TIME=C; export LC_TIME; } +(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") && + { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } || + { LC_CTYPE=C; export LC_CTYPE; } +(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") && + { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } || + { LANGUAGE=C; export LANGUAGE; } +(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") && + { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } || + { LC_COLLATE=C; export LC_COLLATE; } +(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") && + { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } || + { LC_NUMERIC=C; export LC_NUMERIC; } +(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") && + { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } || + { LC_MESSAGES=C; export LC_MESSAGES; } + + +# Name of the executable. +as_me=`(basename "$0") 2>/dev/null || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; } + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by PUPA $as_me 0.6, which was +generated by GNU Autoconf 2.53. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration links: +$config_links + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +PUPA config.status 0.6 +configured by $0, generated by GNU Autoconf 2.53, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + shift + set dummy "$ac_option" "$ac_optarg" ${1+"$@"} + shift + ;; + -*);; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_need_defaults=false;; + esac + + case $1 in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion" + exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;; +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + shift + CONFIG_FILES="$CONFIG_FILES $1" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + shift + CONFIG_HEADERS="$CONFIG_HEADERS $1" + ac_need_defaults=false;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "stamp-h" ) CONFIG_FILES="$CONFIG_FILES stamp-h" ;; + "include/pupa/cpu" ) CONFIG_LINKS="$CONFIG_LINKS include/pupa/cpu:include/pupa/$host_cpu" ;; + "include/pupa/machine" ) CONFIG_LINKS="$CONFIG_LINKS include/pupa/machine:include/pupa/$host_cpu/$host_vendor" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links +fi + +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/cs$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@OBJCOPY@,$OBJCOPY,;t t +s,@ac_ct_OBJCOPY@,$ac_ct_OBJCOPY,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@NM@,$NM,;t t +s,@ac_ct_NM@,$ac_ct_NM,;t t +s,@RUBY@,$RUBY,;t t +s,@BUILD_CC@,$BUILD_CC,;t t +s,@CPP@,$CPP,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || + mkdir "$as_incr_dir" || + { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; } + ;; + esac +done; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + + # Run the commands associated with the file. + case $ac_file in + stamp-h ) echo timestamp > stamp-h ;; + esac +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if egrep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # egrep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if cmp -s $ac_file $tmp/config.h 2>/dev/null; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || + mkdir "$as_incr_dir" || + { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; } + ;; + esac +done; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_LINKS section. +# + +for ac_file in : $CONFIG_LINKS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + + { echo "$as_me:$LINENO: linking $srcdir/$ac_source to $ac_dest" >&5 +echo "$as_me: linking $srcdir/$ac_source to $ac_dest" >&6;} + + if test ! -r $srcdir/$ac_source; then + { { echo "$as_me:$LINENO: error: $srcdir/$ac_source: file not found" >&5 +echo "$as_me: error: $srcdir/$ac_source: file not found" >&2;} + { (exit 1); exit 1; }; } + fi + rm -f $ac_dest + + # Make relative symlinks. + ac_dest_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { case "$ac_dest_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dest_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || + mkdir "$as_incr_dir" || + { { echo "$as_me:$LINENO: error: cannot create \"$ac_dest_dir\"" >&5 +echo "$as_me: error: cannot create \"$ac_dest_dir\"" >&2;} + { (exit 1); exit 1; }; } + ;; + esac +done; } + + ac_builddir=. + +if test "$ac_dest_dir" != .; then + ac_dir_suffix=/`echo "$ac_dest_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dest_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dest_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dest_dir" && cd $ac_top_builddir && pwd` +ac_abs_srcdir=`cd "$ac_dest_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dest_dir" && cd $ac_top_srcdir && pwd` + + + case $srcdir in + [\\/$]* | ?:[\\/]* ) ac_rel_source=$srcdir/$ac_source ;; + *) ac_rel_source=$ac_top_builddir$srcdir/$ac_source ;; + esac + + # Make a symlink if possible; otherwise try a hard link. + ln -s $ac_rel_source $ac_dest 2>/dev/null || + ln $srcdir/$ac_source $ac_dest || + { { echo "$as_me:$LINENO: error: cannot link $ac_dest to $srcdir/$ac_source" >&5 +echo "$as_me: error: cannot link $ac_dest to $srcdir/$ac_source" >&2;} + { (exit 1); exit 1; }; } +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + exec 5>/dev/null + $SHELL $CONFIG_STATUS || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..524fc1420 --- /dev/null +++ b/configure.ac @@ -0,0 +1,124 @@ +# Process this file with autoconf to produce a configure script. + +# Copyright (C) 2002 Yoshinori K. Okuji +# +# This configure.ac is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +AC_INIT(PUPA, 0.6, [okuji@enbug.org]) +AC_PREREQ(2.53) +AC_CONFIG_SRCDIR([include/pupa/dl.h]) +AC_CONFIG_HEADER([config.h]) + +# Checks for build and host systems. +AC_CANONICAL_BUILD +AC_CANONICAL_HOST + +case "$host_cpu" in + i[[3456]]86) host_cpu=i386 ;; + *) AC_MSG_ERROR([unsupported CPU type]) ;; +esac + +case "$host_cpu"-"$host_vendor" in + i386-*) host_vendor=pc ;; + *) AC_MSG_ERROR([unsupported machine type]) ;; +esac + +AC_SUBST(host_cpu) +AC_SUBST(host_vendor) + +# Checks for programs. +if test "x$CFLAGS" = x; then + default_CFLAGS=yes +fi + +AC_PROG_CC + +# Must be GCC. +test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required]) + +if test "x$default_CFLAGS" = xyes; then + # debug flags. + tmp_CFLAGS="-Wall -W -g" + + # optimization flags. + AC_CACHE_CHECK([whether optimization for size works], size_flag, [ + CFLAGS=-Os + AC_TRY_COMPILE(, , size_flag=yes, size_flag=no) + ]) + if test "x$size_flag" = xyes; then + tmp_CFLAGS="$tmp_CFLAGS -Os" + else + tmp_CFLAGS="$tmp_CFLAGS -O2 -fno-strength-reduce -fno-unroll-loops" + fi + + # Force no alignment to save space on i386. + if test "x$host_cpu" = xi386; then + AC_CACHE_CHECK([whether -falign-loops works], [falign_loop_flag], [ + CFLAGS="-falign-loops=1" + AC_TRY_COMPILE(, , [falign_loop_flag=yes], [falign_loop_flag=no]) + ]) + + if test "x$falign_loop_flag" = xyes; then + tmp_CFLAGS="$tmp_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1" + else + tmp_CFLAGS="$tmp_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1" + fi + fi + + CFLAGS="$tmp_CFLAGS" +fi +AC_SUBST(CFLAGS) + +# Defined in aclocal.m4. +pupa_ASM_USCORE +pupa_CHECK_START_SYMBOL +pupa_CHECK_BSS_START_SYMBOL +pupa_CHECK_END_SYMBOL + +if test "x$host_cpu" = xi386; then + pupa_I386_ASM_PREFIX_REQUIREMENT + pupa_I386_ASM_ADDR32 + pupa_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK +fi + + +AC_PROG_INSTALL +AC_PROG_MAKE_SET +AC_CHECK_TOOL(OBJCOPY, objcopy) +pupa_PROG_OBJCOPY_ABSOLUTE +AC_CHECK_TOOL(STRIP, strip) +AC_CHECK_TOOL(NM, nm) + +# This is not a "must". +AC_PATH_PROG(RUBY, ruby) + +# For cross-compiling. +if test "x$build" = "x$host"; then + BUILD_CC="$CC" + AC_SUBST(BUILD_CC) +else + AC_CHECK_PROGS(BUILD_CC, [gcc egcs cc], + [AC_MSG_ERROR([none of gcc, egcs and cc is found. set BUILD_CC manually.])]) +fi + +# Test the C compiler for the build environment. +pupa_tmp_CC="$CC" +CC="$BUILD_CC" +AC_C_BIGENDIAN +AC_CHECK_SIZEOF(void *) +AC_CHECK_SIZEOF(long) +CC="$pupa_tmp_CC" + +# Output files. +AC_CONFIG_LINKS([include/pupa/cpu:include/pupa/$host_cpu + include/pupa/machine:include/pupa/$host_cpu/$host_vendor]) +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) +AC_OUTPUT diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c new file mode 100644 index 000000000..af14c10fa --- /dev/null +++ b/disk/i386/pc/biosdisk.c @@ -0,0 +1,335 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Drive Parameters. */ +struct pupa_biosdisk_drp +{ + pupa_uint16_t size; + pupa_uint16_t flags; + pupa_uint32_t cylinders; + pupa_uint32_t heads; + pupa_uint32_t sectors; + pupa_uint64_t total_sectors; + pupa_uint16_t bytes_per_sector; + /* ver 2.0 or higher */ + pupa_uint32_t EDD_configuration_parameters; + /* ver 3.0 or higher */ + pupa_uint16_t signature_dpi; + pupa_uint8_t length_dpi; + pupa_uint8_t reserved[3]; + pupa_uint8_t name_of_host_bus[4]; + pupa_uint8_t name_of_interface_type[8]; + pupa_uint8_t interface_path[8]; + pupa_uint8_t device_path[8]; + pupa_uint8_t reserved2; + pupa_uint8_t checksum; + + /* XXX: This is necessary, because the BIOS of Thinkpad X20 + writes a garbage to the tail of drive parameters, + regardless of a size specified in a caller. */ + pupa_uint8_t dummy[16]; +} __attribute__ ((packed)); + +/* Disk Address Packet. */ +struct pupa_biosdisk_dap +{ + pupa_uint8_t length; + pupa_uint8_t reserved; + pupa_uint16_t blocks; + pupa_uint32_t buffer; + pupa_uint64_t block; +} __attribute__ ((packed)); + + +static int +pupa_biosdisk_get_drive (const char *name) +{ + unsigned long drive; + + if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd') + goto fail; + + drive = pupa_strtoul (name + 2, 0, 10); + if (pupa_errno != PUPA_ERR_NONE) + goto fail; + + if (name[0] == 'h') + drive += 0x80; + + return (int) drive ; + + fail: + pupa_error (PUPA_ERR_UNKNOWN_DEVICE, "not a biosdisk"); + return -1; +} + +static int +pupa_biosdisk_call_hook (int (*hook) (const char *name), int drive) +{ + char name[4]; + + pupa_sprintf (name, (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); + return hook (name); +} + +static int +pupa_biosdisk_iterate (int (*hook) (const char *name)) +{ + int drive; + int num_floppies; + + /* For floppy disks, we can get the number safely. */ + num_floppies = pupa_biosdisk_get_num_floppies (); + for (drive = 0; drive < num_floppies; drive++) + if (pupa_biosdisk_call_hook (hook, drive)) + return 1; + + /* For hard disks, attempt to read the MBR. */ + for (drive = 0x80; drive < 0x88; drive++) + { + if (pupa_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1, + PUPA_MEMORY_MACHINE_SCRATCH_SEG) != 0) + break; + + if (pupa_biosdisk_call_hook (hook, drive)) + return 1; + } + + return 0; +} + +static pupa_err_t +pupa_biosdisk_open (const char *name, pupa_disk_t disk) +{ + unsigned long total_sectors = 0; + int drive; + struct pupa_biosdisk_data *data; + + drive = pupa_biosdisk_get_drive (name); + if (drive < 0) + return pupa_errno; + + disk->has_partitions = (drive & 0x80); + disk->id = drive; + + data = (struct pupa_biosdisk_data *) pupa_malloc (sizeof (*data)); + if (! data) + return pupa_errno; + + data->drive = drive; + data->flags = 0; + + if (drive & 0x80) + { + /* HDD */ + int version; + + version = pupa_biosdisk_check_int13_extensions (drive); + if (version) + { + struct pupa_biosdisk_drp *drp + = (struct pupa_biosdisk_drp *) PUPA_MEMORY_MACHINE_SCRATCH_ADDR; + + /* Clear out the DRP. */ + pupa_memset (drp, 0, sizeof (*drp)); + drp->size = sizeof (*drp); + if (pupa_biosdisk_get_diskinfo_int13_extensions (drive, drp)) + { + data->flags = PUPA_BIOSDISK_FLAG_LBA; + + /* FIXME: 2TB limit. */ + if (drp->total_sectors) + total_sectors = drp->total_sectors & ~0L; + else + /* Some buggy BIOSes doesn't return the total sectors + correctly but returns zero. So if it is zero, compute + it by C/H/S returned by the LBA BIOS call. */ + total_sectors = drp->cylinders * drp->heads * drp->sectors; + } + } + } + + if (pupa_biosdisk_get_diskinfo_standard (drive, + &data->cylinders, + &data->heads, + &data->sectors) != 0) + { + pupa_free (data); + return pupa_error (PUPA_ERR_BAD_DEVICE, "cannot get C/H/S values"); + } + + if (! total_sectors) + total_sectors = data->cylinders * data->heads * data->sectors; + + disk->total_sectors = total_sectors; + disk->data = data; + + return PUPA_ERR_NONE; +} + +static void +pupa_biosdisk_close (pupa_disk_t disk) +{ + pupa_free (disk->data); +} + +/* For readability. */ +#define PUPA_BIOSDISK_READ 0 +#define PUPA_BIOSDISK_WRITE 1 + +static pupa_err_t +pupa_biosdisk_rw (int cmd, pupa_disk_t disk, + unsigned long sector, unsigned long size, + unsigned segment) +{ + struct pupa_biosdisk_data *data = disk->data; + + if (data->flags & PUPA_BIOSDISK_FLAG_LBA) + { + struct pupa_biosdisk_dap *dap; + + dap = (struct pupa_biosdisk_dap *) (PUPA_MEMORY_MACHINE_SCRATCH_ADDR + + (data->sectors + << PUPA_DISK_SECTOR_BITS)); + dap->length = sizeof (*dap); + dap->reserved = 0; + dap->blocks = size; + dap->buffer = segment << 16; /* The format SEGMENT:ADDRESS. */ + dap->block = sector; + + if (pupa_biosdisk_rw_int13_extensions (cmd + 0x42, data->drive, dap)) + { + /* Fall back to the CHS mode. */ + data->flags &= ~PUPA_BIOSDISK_FLAG_LBA; + disk->total_sectors = data->cylinders * data->heads * data->sectors; + return pupa_biosdisk_rw (cmd, disk, sector, size, segment); + } + } + else + { + unsigned coff, hoff, soff; + unsigned head; + + soff = sector % data->sectors + 1; + head = sector / data->sectors; + hoff = head % data->heads; + coff = head / data->heads; + + if (coff >= data->cylinders) + return pupa_error (PUPA_ERR_OUT_OF_RANGE, "out of disk"); + + if (pupa_biosdisk_rw_standard (cmd + 0x02, data->drive, + coff, hoff, soff, size, segment)) + { + switch (cmd) + { + case PUPA_BIOSDISK_READ: + return pupa_error (PUPA_ERR_READ_ERROR, "biosdisk read error"); + case PUPA_BIOSDISK_WRITE: + return pupa_error (PUPA_ERR_WRITE_ERROR, "biosdisk write error"); + } + } + } + + return PUPA_ERR_NONE; +} + +static pupa_err_t +pupa_biosdisk_read (pupa_disk_t disk, unsigned long sector, + unsigned long size, char *buf) +{ + struct pupa_biosdisk_data *data = disk->data; + + while (size) + { + unsigned long len; + + len = data->sectors - (sector % data->sectors); + if (len > size) + len = size; + + if (pupa_biosdisk_rw (PUPA_BIOSDISK_READ, disk, sector, len, + PUPA_MEMORY_MACHINE_SCRATCH_SEG)) + return pupa_errno; + + pupa_memcpy (buf, (void *) PUPA_MEMORY_MACHINE_SCRATCH_ADDR, + len << PUPA_DISK_SECTOR_BITS); + buf += len << PUPA_DISK_SECTOR_BITS; + sector += len; + size -= len; + } + + return pupa_errno; +} + +static pupa_err_t +pupa_biosdisk_write (pupa_disk_t disk, unsigned long sector, + unsigned long size, const char *buf) +{ + struct pupa_biosdisk_data *data = disk->data; + + while (size) + { + unsigned long len; + + len = data->sectors - (sector % data->sectors); + if (len > size) + len = size; + + pupa_memcpy ((void *) PUPA_MEMORY_MACHINE_SCRATCH_ADDR, buf, + len << PUPA_DISK_SECTOR_BITS); + + if (pupa_biosdisk_rw (PUPA_BIOSDISK_WRITE, disk, sector, len, + PUPA_MEMORY_MACHINE_SCRATCH_SEG)) + return pupa_errno; + + buf += len << PUPA_DISK_SECTOR_BITS; + sector += len; + size -= len; + } + + return pupa_errno; +} + +static struct pupa_disk_dev pupa_biosdisk_dev = + { + .name = "biosdisk", + .iterate = pupa_biosdisk_iterate, + .open = pupa_biosdisk_open, + .close = pupa_biosdisk_close, + .read = pupa_biosdisk_read, + .write = pupa_biosdisk_write, + .next = 0 + }; + +void +pupa_biosdisk_init (void) +{ + pupa_disk_dev_register (&pupa_biosdisk_dev); +} diff --git a/disk/i386/pc/partition.c b/disk/i386/pc/partition.c new file mode 100644 index 000000000..ba0771b4c --- /dev/null +++ b/disk/i386/pc/partition.c @@ -0,0 +1,248 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +/* Parse the partition representation in STR and return a partition. */ +static pupa_partition_t +pupa_partition_parse (const char *str) +{ + pupa_partition_t p; + char *s = (char *) str; + + p = (pupa_partition_t) pupa_malloc (sizeof (*p)); + if (! p) + return 0; + + /* Initialize some of the fields with invalid values. */ + p->bsd_part = p->dos_type = p->bsd_type = p->index = -1; + + /* Get the DOS partition number. */ + p->dos_part = pupa_strtoul (s, &s, 0); + + if (pupa_errno) + { + /* Not found. Maybe only a BSD label is specified. */ + p->dos_part = -1; + pupa_errno = PUPA_ERR_NONE; + } + else if (*s == ',') + s++; + + if (*s) + { + if (*s >= 'a' && *s <= 'h') + { + p->bsd_part = *s - 'a'; + s++; + } + + if (*s) + goto fail; + } + + if (p->dos_part == -1 && p->bsd_part == -1) + goto fail; + + return p; + + fail: + pupa_free (p); + pupa_error (PUPA_ERR_BAD_FILENAME, "invalid partition"); + return 0; +} + +pupa_err_t +pupa_partition_iterate (pupa_disk_t disk, + int (*hook) (const pupa_partition_t partition)) +{ + struct pupa_partition p; + struct pupa_partition_mbr mbr; + struct pupa_partition_disk_label label; + struct pupa_disk raw; + + /* Enforce raw disk access. */ + raw = *disk; + raw.partition = 0; + + p.offset = 0; + p.ext_offset = 0; + p.dos_part = -1; + + while (1) + { + int i; + struct pupa_partition_entry *e; + + /* Read the MBR. */ + if (pupa_disk_read (&raw, p.offset, 0, sizeof (mbr), (char *) &mbr)) + goto finish; + + /* Check if it is valid. */ + if (mbr.signature != pupa_cpu_to_le16 (PUPA_PARTITION_SIGNATURE)) + return pupa_error (PUPA_ERR_BAD_PART_TABLE, "no signature"); + + /* Analyze DOS partitions. */ + for (p.index = 0; p.index < 4; p.index++) + { + e = mbr.entries + p.index; + + p.start = p.offset + pupa_le_to_cpu32 (e->start); + p.len = pupa_le_to_cpu32 (e->length); + p.bsd_part = -1; + p.dos_type = e->type; + p.bsd_type = -1; + + /* If this partition is a normal one, call the hook. */ + if (! pupa_partition_is_empty (e->type) + && ! pupa_partition_is_extended (e->type)) + { + p.dos_part++; + + if (hook (&p)) + goto finish; + + /* Check if this is a BSD partition. */ + if (pupa_partition_is_bsd (e->type)) + { + /* Check if the BSD label is within the DOS partition. */ + if (p.len <= PUPA_PARTITION_BSD_LABEL_SECTOR) + return pupa_error (PUPA_ERR_BAD_PART_TABLE, + "no space for disk label"); + + /* Read the BSD label. */ + if (pupa_disk_read (&raw, + (p.start + + PUPA_PARTITION_BSD_LABEL_SECTOR), + 0, + sizeof (label), + (char *) &label)) + goto finish; + + /* Check if it is valid. */ + if (label.magic + != pupa_cpu_to_le32 (PUPA_PARTITION_BSD_LABEL_MAGIC)) + return pupa_error (PUPA_ERR_BAD_PART_TABLE, + "invalid disk label magic"); + + for (p.bsd_part = 0; + p.bsd_part < pupa_cpu_to_le16 (label.num_partitions); + p.bsd_part++) + { + struct pupa_partition_bsd_entry *be + = label.entries + p.bsd_part; + + p.start = pupa_le_to_cpu32 (be->offset); + p.len = pupa_le_to_cpu32 (be->size); + p.bsd_type = be->fs_type; + + if (be->fs_type != PUPA_PARTITION_BSD_TYPE_UNUSED) + if (hook (&p)) + goto finish; + } + } + } + else if (p.dos_part < 4) + /* If this partition is a logical one, shouldn't increase the + partition number. */ + p.dos_part++; + } + + /* Find an extended partition. */ + for (i = 0; i < 4; i++) + { + e = mbr.entries + i; + + if (pupa_partition_is_extended (e->type)) + { + p.offset = p.ext_offset + pupa_le_to_cpu32 (e->start); + if (! p.ext_offset) + p.ext_offset = p.offset; + + break; + } + } + + /* If no extended partition, the end. */ + if (i == 4) + break; + } + + finish: + return pupa_errno; +} + +pupa_partition_t +pupa_partition_probe (pupa_disk_t disk, const char *str) +{ + pupa_partition_t p; + auto int find_func (const pupa_partition_t partition); + + int find_func (const pupa_partition_t partition) + { + if ((p->dos_part == partition->dos_part || p->dos_part == -1) + && p->bsd_part == partition->bsd_part) + { + pupa_memcpy (p, partition, sizeof (*p)); + return 1; + } + + return 0; + } + + p = pupa_partition_parse (str); + if (! p) + return 0; + + + if (pupa_partition_iterate (disk, find_func)) + goto fail; + + if (p->index < 0) + { + pupa_error (PUPA_ERR_BAD_DEVICE, "no such partition"); + goto fail; + } + + return p; + + fail: + pupa_free (p); + return 0; +} + +char * +pupa_partition_get_name (const pupa_partition_t p) +{ + char *name; + + name = pupa_malloc (13); + if (! name) + return 0; + + if (p->bsd_part < 0) + pupa_sprintf (name, "%d", p->dos_part); + else + pupa_sprintf (name, "%d,%c", p->dos_part, p->bsd_part + 'a'); + + return name; +} diff --git a/fs/fat.c b/fs/fat.c new file mode 100644 index 000000000..70abadcdb --- /dev/null +++ b/fs/fat.c @@ -0,0 +1,756 @@ +/* fat.c - FAT filesystem */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2000,2001 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#define PUPA_FAT_DIR_ENTRY_SIZE 32 + +#define PUPA_FAT_ATTR_READ_ONLY 0x01 +#define PUPA_FAT_ATTR_HIDDEN 0x02 +#define PUPA_FAT_ATTR_SYSTEM 0x04 +#define PUPA_FAT_ATTR_VOLUME_ID 0x08 +#define PUPA_FAT_ATTR_DIRECTORY 0x10 +#define PUPA_FAT_ATTR_ARCHIVE 0x20 + +#define PUPA_FAT_ATTR_LONG_NAME (PUPA_FAT_ATTR_READ_ONLY \ + | PUPA_FAT_ATTR_HIDDEN \ + | PUPA_FAT_ATTR_SYSTEM \ + | PUPA_FAT_ATTR_VOLUME_ID) +#define PUPA_FAT_ATTR_VALID (PUPA_FAT_ATTR_READ_ONLY \ + | PUPA_FAT_ATTR_HIDDEN \ + | PUPA_FAT_ATTR_SYSTEM \ + | PUPA_FAT_ATTR_DIRECTORY \ + | PUPA_FAT_ATTR_ARCHIVE) + +struct pupa_fat_bpb +{ + pupa_uint8_t jmp_boot[3]; + pupa_uint8_t oem_name[8]; + pupa_uint16_t bytes_per_sector; + pupa_uint8_t sectors_per_cluster; + pupa_uint16_t num_reserved_sectors; + pupa_uint8_t num_fats; + pupa_uint16_t num_root_entries; + pupa_uint16_t num_total_sectors_16; + pupa_uint8_t media; + pupa_uint16_t sectors_per_fat_16; + pupa_uint16_t sectors_per_track; + pupa_uint16_t num_heads; + pupa_uint32_t num_hidden_sectors; + pupa_uint32_t num_total_sectors_32; + + /* The following fields are only used by FAT32. */ + pupa_uint32_t sectors_per_fat_32; + pupa_uint16_t extended_flags; + pupa_uint16_t fs_version; + pupa_uint32_t root_cluster; + pupa_uint16_t fs_info; + pupa_uint16_t backup_boot_sector; +} __attribute__ ((packed)); + +struct pupa_fat_dir_entry +{ + pupa_uint8_t name[11]; + pupa_uint8_t attr; + pupa_uint8_t nt_reserved; + pupa_uint8_t c_time_tenth; + pupa_uint16_t c_time; + pupa_uint16_t c_date; + pupa_uint16_t a_date; + pupa_uint16_t first_cluster_high; + pupa_uint16_t w_time; + pupa_uint16_t w_date; + pupa_uint16_t first_cluster_low; + pupa_uint32_t file_size; +} __attribute__ ((packed)); + +struct pupa_fat_long_name_entry +{ + pupa_uint8_t id; + pupa_uint16_t name1[5]; + pupa_uint8_t attr; + pupa_uint8_t reserved; + pupa_uint8_t checksum; + pupa_uint16_t name2[6]; + pupa_uint16_t first_cluster; + pupa_uint16_t name3[2]; +} __attribute__ ((packed)); + +struct pupa_fat_data +{ + int logical_sector_bits; + pupa_uint32_t num_sectors; + + pupa_uint16_t fat_sector; + pupa_uint32_t sectors_per_fat; + int fat_size; + + pupa_uint32_t root_cluster; + pupa_uint32_t root_sector; + pupa_uint32_t num_root_sectors; + + int cluster_bits; + pupa_uint32_t cluster_eof_mark; + pupa_uint32_t cluster_sector; + pupa_uint32_t num_clusters; + + pupa_uint8_t attr; + pupa_ssize_t file_size; + pupa_uint32_t file_cluster; + pupa_uint32_t cur_cluster_num; + pupa_uint32_t cur_cluster; +}; + +static int +log2 (unsigned x) +{ + int i; + + if (x == 0) + return -1; + + for (i = 0; (x & 1) == 0; i++) + x >>= 1; + + if (x != 1) + return -1; + + return i; +} + +static struct pupa_fat_data * +pupa_fat_mount (pupa_disk_t disk) +{ + struct pupa_fat_bpb bpb; + struct pupa_fat_data *data = 0; + pupa_uint32_t first_fat, magic; + + if (! disk) + goto fail; + + data = (struct pupa_fat_data *) pupa_malloc (sizeof (*data)); + if (! data) + goto fail; + + /* Read the BPB. */ + if (pupa_disk_read (disk, 0, 0, sizeof (bpb), (char *) &bpb)) + goto fail; + + /* Get the sizes of logical sectors and clusters. */ + data->logical_sector_bits = log2 (pupa_le_to_cpu16 (bpb.bytes_per_sector)); + if (data->logical_sector_bits < PUPA_DISK_SECTOR_BITS) + goto fail; + data->logical_sector_bits -= PUPA_DISK_SECTOR_BITS; + + data->cluster_bits = log2 (bpb.sectors_per_cluster); + if (data->cluster_bits < 0) + goto fail; + data->cluster_bits += data->logical_sector_bits; + + /* Get information about FATs. */ + data->fat_sector = (pupa_le_to_cpu16 (bpb.num_reserved_sectors) + << data->logical_sector_bits); + if (data->fat_sector == 0) + goto fail; + + data->sectors_per_fat = ((bpb.sectors_per_fat_16 + ? pupa_le_to_cpu16 (bpb.sectors_per_fat_16) + : pupa_le_to_cpu32 (bpb.sectors_per_fat_32)) + << data->logical_sector_bits); + if (data->sectors_per_fat == 0) + goto fail; + + /* Get the number of sectors in this volume. */ + data->num_sectors = ((bpb.num_total_sectors_16 + ? pupa_le_to_cpu16 (bpb.num_total_sectors_16) + : pupa_le_to_cpu32 (bpb.num_total_sectors_32)) + << data->logical_sector_bits); + if (data->num_sectors == 0) + goto fail; + + /* Get information about the root directory. */ + if (bpb.num_fats == 0) + goto fail; + + data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat; + data->num_root_sectors + = ((((pupa_uint32_t) pupa_le_to_cpu16 (bpb.num_root_entries) + * PUPA_FAT_DIR_ENTRY_SIZE + + pupa_le_to_cpu16 (bpb.bytes_per_sector) - 1) + >> (data->logical_sector_bits + PUPA_DISK_SECTOR_BITS)) + << (data->logical_sector_bits)); + + data->cluster_sector = data->root_sector + data->num_root_sectors; + data->num_clusters = (((data->num_sectors - data->cluster_sector) + >> (data->cluster_bits + data->logical_sector_bits)) + + 2); + + if (data->num_clusters <= 2) + goto fail; + + if (! bpb.sectors_per_fat_16) + { + /* FAT32. */ + pupa_uint16_t flags = pupa_le_to_cpu16 (bpb.extended_flags); + + data->root_cluster = pupa_le_to_cpu32 (bpb.root_cluster); + data->fat_size = 32; + data->cluster_eof_mark = 0x0ffffff8; + + if (flags & 0x80) + { + /* Get an active FAT. */ + unsigned active_fat = flags & 0xf; + + if (active_fat > bpb.num_fats) + goto fail; + + data->fat_sector += active_fat * data->sectors_per_fat; + } + + if (bpb.num_root_entries != 0 || bpb.fs_version != 0) + goto fail; + } + else + { + /* FAT12 or FAT16. */ + data->root_cluster = ~0UL; + + if (data->num_clusters <= 4085 + 2) + { + /* FAT12. */ + data->fat_size = 12; + data->cluster_eof_mark = 0x0ff8; + } + else + { + /* FAT16. */ + data->fat_size = 16; + data->cluster_eof_mark = 0xfff8; + } + } + + /* More sanity checks. */ + if (data->num_sectors <= data->fat_sector) + goto fail; + + if (pupa_disk_read (disk, + data->fat_sector, + 0, + sizeof (first_fat), + (char *) &first_fat)) + goto fail; + + first_fat = pupa_le_to_cpu32 (first_fat); + + if (data->fat_size == 32) + { + first_fat &= 0x0fffffff; + magic = 0x0fffff00; + } + else if (data->fat_size == 16) + { + first_fat &= 0x0000ffff; + magic = 0xff00; + } + else + { + first_fat &= 0x00000fff; + magic = 0x0f00; + } + + if (first_fat != (magic | bpb.media)) + goto fail; + + /* Start from the root directory. */ + data->file_cluster = data->root_cluster; + data->cur_cluster_num = ~0UL; + data->attr = PUPA_FAT_ATTR_DIRECTORY; + return data; + + fail: + + pupa_free (data); + pupa_error (PUPA_ERR_BAD_FS, "not a fat filesystem"); + return 0; +} + +/* Convert UTF-16 (little endian) to UTF8. */ +static pupa_uint8_t * +pupa_fat_utf16_to_utf8 (pupa_uint8_t *dest, pupa_uint16_t *src, + pupa_size_t size) +{ + pupa_uint32_t code_high = 0; + + while (size--) + { + pupa_uint32_t code = pupa_le_to_cpu16 (*src++); + + if (code_high) + { + if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Surrogate pair. */ + code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; + + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + else + { + /* Error... */ + *dest++ = '?'; + } + + code_high = 0; + } + else + { + if (code <= 0x007F) + *dest++ = code; + else if (code <= 0x07FF) + { + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + } + else if (code >= 0xD800 && code <= 0xDBFF) + { + code_high = code; + continue; + } + else if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Error... */ + *dest++ = '?'; + } + else + { + *dest++ = (code >> 16) | 0xE0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + } + + return dest; +} + +static pupa_ssize_t +pupa_fat_read_data (pupa_disk_t disk, struct pupa_fat_data *data, + void (*read_hook) (unsigned long sector, + unsigned offset, unsigned length), + pupa_ssize_t offset, pupa_ssize_t len, char *buf) +{ + pupa_ssize_t size; + pupa_uint32_t logical_cluster; + unsigned logical_cluster_bits; + pupa_ssize_t ret = 0; + unsigned long sector; + + /* This is a special case. FAT12 and FAT16 doesn't have the root directory + in clusters. */ + if (data->file_cluster == ~0UL) + { + size = (data->num_root_sectors << PUPA_DISK_SECTOR_BITS) - offset; + if (size > len) + size = len; + + if (pupa_disk_read (disk, data->root_sector, offset, size, buf)) + return -1; + + return size; + } + + /* Calculate the logical cluster number and offset. */ + logical_cluster_bits = (data->cluster_bits + + data->logical_sector_bits + + PUPA_DISK_SECTOR_BITS); + logical_cluster = offset >> logical_cluster_bits; + offset &= (1 << logical_cluster_bits) - 1; + + if (logical_cluster < data->cur_cluster_num) + { + data->cur_cluster_num = 0; + data->cur_cluster = data->file_cluster; + } + + while (len) + { + while (logical_cluster > data->cur_cluster_num) + { + /* Find next cluster. */ + pupa_uint32_t next_cluster; + unsigned long fat_offset; + + switch (data->fat_size) + { + case 32: + fat_offset = data->cur_cluster << 2; + break; + case 16: + fat_offset = data->cur_cluster << 1; + break; + default: + /* case 12: */ + fat_offset = data->cur_cluster + (data->cur_cluster >> 1); + break; + } + + /* Read the FAT. */ + if (pupa_disk_read (disk, data->fat_sector, fat_offset, + (data->fat_size + 7) >> 3, + (char *) &next_cluster)) + return -1; + + next_cluster = pupa_le_to_cpu32 (next_cluster); + switch (data->fat_size) + { + case 16: + next_cluster &= 0xFFFF; + break; + case 12: + if (data->cur_cluster & 1) + next_cluster >>= 12; + + next_cluster &= 0x0FFF; + break; + } + + /* Check the end. */ + if (next_cluster >= data->cluster_eof_mark) + return ret; + + if (next_cluster < 2 || next_cluster >= data->num_clusters) + { + pupa_error (PUPA_ERR_BAD_FS, "invalid cluster"); + return -1; + } + + data->cur_cluster = next_cluster; + data->cur_cluster_num++; + } + + /* Read the data here. */ + sector = (data->cluster_sector + + ((data->cur_cluster - 2) + << (data->cluster_bits + data->logical_sector_bits))); + size = (1 << logical_cluster_bits) - offset; + if (size > len) + size = len; + + disk->read_hook = read_hook; + pupa_disk_read (disk, sector, offset, size, buf); + disk->read_hook = 0; + if (pupa_errno) + return -1; + + len -= size; + buf += size; + ret += size; + logical_cluster++; + offset = 0; + } + + return ret; +} + +/* Find the underlying directory or file in PATH and return the + next path. If there is no next path or an error occurs, return NULL. + If HOOK is specified, call it with each file name. */ +static char * +pupa_fat_find_dir (pupa_disk_t disk, struct pupa_fat_data *data, + const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct pupa_fat_dir_entry dir; + char *dirname, *dirp; + char *filename, *filep = 0; + pupa_uint16_t *unibuf; + int slot = -1, slots = -1; + int checksum = -1; + pupa_ssize_t offset = -sizeof(dir); + int call_hook; + + if (! (data->attr & PUPA_FAT_ATTR_DIRECTORY)) + { + pupa_error (PUPA_ERR_BAD_FILE_TYPE, "not a directory"); + return 0; + } + + /* Extract a directory name. */ + while (*path == '/') + path++; + + dirp = pupa_strchr (path, '/'); + if (dirp) + { + unsigned len = dirp - path; + + dirname = pupa_malloc (len + 1); + if (! dirname) + return 0; + + pupa_memcpy (dirname, path, len); + dirname[len] = '\0'; + } + else + /* This is actually a file. */ + dirname = pupa_strdup (path); + + call_hook = (! dirp && hook); + + /* Allocate space enough to hold a long name. */ + filename = pupa_malloc (0x40 * 13 * 4 + 1); + unibuf = (pupa_uint16_t *) pupa_malloc (0x40 * 13 * 2); + if (! filename || ! unibuf) + { + pupa_free (filename); + pupa_free (unibuf); + pupa_free (dirname); + return 0; + } + + while (1) + { + unsigned i; + + /* Adjust the offset. */ + offset += sizeof (dir); + + /* Read a directory entry. */ + if ((pupa_fat_read_data (disk, data, 0, + offset, sizeof (dir), (char *) &dir) + != sizeof (dir)) + || dir.name[0] == 0) + { + if (pupa_errno == PUPA_ERR_NONE && ! call_hook) + pupa_error (PUPA_ERR_FILE_NOT_FOUND, "file not found"); + + break; + } + + /* Handle long name entries. */ + if (dir.attr == PUPA_FAT_ATTR_LONG_NAME) + { + struct pupa_fat_long_name_entry *long_name + = (struct pupa_fat_long_name_entry *) &dir; + pupa_uint8_t id = long_name->id; + + if (id & 0x40) + { + id &= 0x3f; + slots = slot = id; + checksum = long_name->checksum; + } + + if (id != slot || slot == 0 || checksum != long_name->checksum) + { + checksum = -1; + continue; + } + + slot--; + pupa_memcpy (unibuf + slot * 13, long_name->name1, 5 * 2); + pupa_memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2); + pupa_memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2); + continue; + } + + /* Check if this entry is valid. */ + if (dir.name[0] == 0xe5 || (dir.attr & ~PUPA_FAT_ATTR_VALID)) + continue; + + /* This is a workaround for Japanese. */ + if (dir.name[0] == 0x05) + dir.name[0] = 0xe5; + + if (checksum != -1 && slot == 0) + { + pupa_uint8_t sum; + + for (sum = 0, i = 0; i < sizeof (dir.name); i++) + sum = ((sum >> 1) | (sum << 7)) + dir.name[i]; + + if (sum == checksum) + { + *pupa_fat_utf16_to_utf8 (filename, unibuf, slots * 13) = '\0'; + + if (*dirname == '\0' && call_hook) + { + if (hook (filename, dir.attr & PUPA_FAT_ATTR_DIRECTORY)) + break; + + checksum = -1; + continue; + } + + if (pupa_strcmp (dirname, filename) == 0) + { + if (call_hook) + hook (filename, dir.attr & PUPA_FAT_ATTR_DIRECTORY); + + break; + } + } + + checksum = -1; + } + + /* Convert the 8.3 file name. */ + filep = filename; + + for (i = 0; i < 8 && dir.name[i] && ! pupa_isspace (dir.name[i]); i++) + *filep++ = pupa_tolower (dir.name[i]); + + *filep = '.'; + + for (i = 8; i < 11 && dir.name[i] && ! pupa_isspace (dir.name[i]); i++) + *++filep = pupa_tolower (dir.name[i]); + + if (*filep != '.') + filep++; + + *filep = '\0'; + + if (*dirname == '\0' && call_hook) + { + if (hook (filename, dir.attr & PUPA_FAT_ATTR_DIRECTORY)) + break; + } + else if (pupa_strcmp (dirname, filename) == 0) + { + if (call_hook) + hook (filename, dir.attr & PUPA_FAT_ATTR_DIRECTORY); + + break; + } + } + + pupa_free (filename); + pupa_free (dirname); + + data->attr = dir.attr; + data->file_size = pupa_le_to_cpu32 (dir.file_size); + data->file_cluster = ((pupa_le_to_cpu16 (dir.first_cluster_high) << 16) + | pupa_le_to_cpu16 (dir.first_cluster_low)); + data->cur_cluster_num = ~0UL; + + return dirp; +} + +static pupa_err_t +pupa_fat_dir (pupa_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct pupa_fat_data *data; + pupa_disk_t disk = device->disk; + char *p = (char *) path; + + data = pupa_fat_mount (disk); + if (! data) + return pupa_errno; + + do + { + p = pupa_fat_find_dir (disk, data, p, hook); + } + while (p && pupa_errno == PUPA_ERR_NONE); + + pupa_free (data); + return pupa_errno; +} + +static pupa_err_t +pupa_fat_open (pupa_file_t file, const char *name) +{ + struct pupa_fat_data *data; + char *p = (char *) name; + + data = pupa_fat_mount (file->device->disk); + if (! data) + return pupa_errno; + + do + { + p = pupa_fat_find_dir (file->device->disk, data, p, 0); + if (pupa_errno != PUPA_ERR_NONE) + goto fail; + } + while (p); + + if (data->attr & PUPA_FAT_ATTR_DIRECTORY) + { + pupa_error (PUPA_ERR_BAD_FILE_TYPE, "not a file"); + goto fail; + } + + file->data = data; + file->size = data->file_size; + + return PUPA_ERR_NONE; + + fail: + pupa_free (data); + return pupa_errno; +} + +static pupa_ssize_t +pupa_fat_read (pupa_file_t file, char *buf, pupa_ssize_t len) +{ + return pupa_fat_read_data (file->device->disk, file->data, file->read_hook, + file->offset, len, buf); +} + +static pupa_err_t +pupa_fat_close (pupa_file_t file) +{ + pupa_free (file->data); + return pupa_errno; +} + +static struct pupa_fs pupa_fat_fs = + { + .name = "fat", + .dir = pupa_fat_dir, + .open = pupa_fat_open, + .read = pupa_fat_read, + .close = pupa_fat_close, + .next = 0 + }; + +PUPA_MOD_INIT +{ + pupa_fs_register (&pupa_fat_fs); +} + +PUPA_MOD_FINI +{ + pupa_fs_unregister (&pupa_fat_fs); +} diff --git a/genkernsyms.sh b/genkernsyms.sh new file mode 100644 index 000000000..0177ab3cf --- /dev/null +++ b/genkernsyms.sh @@ -0,0 +1,15 @@ +#! /bin/sh +# +# Copyright (C) 2002 Yoshinori K. Okuji +# +# This gensymlist.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +cat $* | grep -v '^#' | sed -n '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/\1 kernel/;p;}' +cat $* | grep -v '^#' | sed -n '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/\1 kernel/;p;}' diff --git a/genmk.rb b/genmk.rb new file mode 100644 index 000000000..7c621b970 --- /dev/null +++ b/genmk.rb @@ -0,0 +1,269 @@ +#! /usr/bin/ruby -w +# +# Copyright (C) 2002 Yoshinori K. Okuji +# +# This genmk.rb is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +module Enumerable + def collect_with_index + ret = [] + self.each_with_index do |item, index| + ret.push(yield(item, index)) + end + ret + end +end + +class String + def to_var + self.gsub(/[^a-zA-Z0-9_@]/, '_') + end + + def suffix(str) + self.sub(/\.[^\.]*$/, '') + '.' + str + end + + def to_obj + self.sub(/\.[^\.]*$/, '').to_var + '.o' + end +end + +class Image + def initialize(dir, name) + @dir = dir + @name = name + end + attr_reader :dir, :name + + def rule(sources) + prefix = @name.to_var + exe = @name.suffix('exec') + objs = sources.collect do |src| + raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src + prefix + '-' + src.to_obj + end + objs_str = objs.join(' ') + deps = objs.collect {|obj| obj.suffix('d')} + deps_str = deps.join(' ') + + "CLEANFILES += #{@name} #{exe} #{objs_str} +MOSTLYCLEANFILES += #{deps_str} + +#{@name}: #{exe} + $(OBJCOPY) -O binary -R .note -R .comment $< $@ + +#{exe}: #{objs_str} + $(CC) $(LDFLAGS) $(#{prefix}_LDFLAGS) -o $@ $^ + +" + objs.collect_with_index do |obj, i| + src = sources[i] + fake_obj = File.basename(src).suffix('o') + dep = deps[i] + flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end + extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end + dir = File.dirname(src) + + "#{obj}: #{src} + $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) #{extra_flags} $(#{flag}) $(#{prefix}_#{flag}) -c -o $@ $< + +#{dep}: #{src} + set -e; \ + $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) #{extra_flags} $(#{flag}) $(#{prefix}_#{flag}) -M $< \ + | sed 's,#{Regexp.quote(fake_obj)}[ :]*,#{obj} $@ : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + +-include #{dep} + +" + end.join('') + end +end + +# Use PModule instead Module, to avoid name conflicting. +class PModule + def initialize(dir, name) + @dir = dir + @name = name + end + attr_reader :dir, :name + + def rule(sources) + prefix = @name.to_var + objs = sources.collect do |src| + raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src + prefix + '-' + src.to_obj + end + objs_str = objs.join(' ') + deps = objs.collect {|obj| obj.suffix('d')} + deps_str = deps.join(' ') + pre_obj = 'pre-' + @name.suffix('o') + mod_src = 'mod-' + @name.suffix('c') + mod_obj = mod_src.suffix('o') + defsym = 'def-' + @name.suffix('lst') + undsym = 'und-' + @name.suffix('lst') + mod_name = File.basename(@name, '.mod') + + "CLEANFILES += #{@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{defsym} #{undsym} +MOSTLYCLEANFILES += #{deps_str} +DEFSYMFILES += #{defsym} +UNDSYMFILES += #{undsym} + +#{@name}: #{pre_obj} #{mod_obj} + -rm -f $@ + $(LD) -r -o $@ $^ + $(STRIP) --strip-unneeded -K pupa_mod_init -K pupa_mod_fini -R .note -R .comment $@ + +#{pre_obj}: #{objs_str} + -rm -f $@ + $(LD) -r -o $@ $^ + +#{mod_obj}: #{mod_src} + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + +#{mod_src}: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1) + +#{defsym}: #{pre_obj} + $(NM) -g --defined-only -P -p $< | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@ + +#{undsym}: #{pre_obj} + echo '#{mod_name}' > $@ + $(NM) -u -P -p $< >> $@ + +" + objs.collect_with_index do |obj, i| + src = sources[i] + fake_obj = File.basename(src).suffix('o') + dep = deps[i] + flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end + dir = File.dirname(src) + + "#{obj}: #{src} + $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(#{flag}) $(#{prefix}_#{flag}) -c -o $@ $< + +#{dep}: #{src} + set -e; \ + $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(#{flag}) $(#{prefix}_#{flag}) -M $< \ + | sed 's,#{Regexp.quote(fake_obj)}[ :]*,#{obj} $@ : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + +-include #{dep} + +" + end.join('') + end +end + +class Utility + def initialize(dir, name) + @dir = dir + @name = name + end + attr_reader :dir, :name + + def rule(sources) + prefix = @name.to_var + objs = sources.collect do |src| + raise "unknown source file `#{src}'" if /\.c$/ !~ src + prefix + '-' + src.to_obj + end + objs_str = objs.join(' '); + deps = objs.collect {|obj| obj.suffix('d')} + deps_str = deps.join(' '); + + "CLEANFILES += #{@name} #{objs_str} +MOSTLYCLEANFILES += #{deps_str} + +#{@name}: #{objs_str} + $(BUILD_CC) $(BUILD_LDFLAGS) $(#{prefix}_LDFLAGS) -o $@ $^ + +" + objs.collect_with_index do |obj, i| + src = sources[i] + fake_obj = File.basename(src).suffix('o') + dep = deps[i] + dir = File.dirname(src) + + "#{obj}: #{src} + $(BUILD_CC) -I#{dir} -I$(srcdir)/#{dir} $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(#{prefix}_CFLAGS) -c -o $@ $< + +#{dep}: #{src} + set -e; \ + $(BUILD_CC) -I#{dir} -I$(srcdir)/#{dir} $(BUILD_CPPFLAGS) -DPUPA_UTIL=1 $(#{prefix}_CFLAGS) -M $< \ + | sed 's,#{Regexp.quote(fake_obj)}[ :]*,#{obj} $@ : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + +-include #{dep} + +" + end.join('') + end +end + +images = [] +utils = [] +pmodules = [] + +cont = false +s = nil +while l = gets + if cont + s += l + else + s = l + end + + print l + cont = (/\\$/ =~ l) + unless cont + s.gsub!(/\\\n/, ' ') + + if /^([a-zA-Z0-9_]+)\s*=\s*(.*?)\s*$/ =~ s + var, args = $1, $2 + + if var =~ /^([a-zA-Z0-9_]+)_([A-Z]+)$/ + prefix, type = $1, $2 + + case type + when 'IMAGES' + images += args.split(/\s+/).collect do |img| + Image.new(prefix, img) + end + + when 'MODULES' + pmodules += args.split(/\s+/).collect do |pmod| + PModule.new(prefix, pmod) + end + + when 'UTILITIES' + utils += args.split(/\s+/).collect do |util| + Utility.new(prefix, util) + end + + when 'SOURCES' + if img = images.detect() {|i| i.name.to_var == prefix} + print img.rule(args.split(/\s+/)) + elsif pmod = pmodules.detect() {|m| m.name.to_var == prefix} + print pmod.rule(args.split(/\s+/)) + elsif util = utils.detect() {|u| u.name.to_var == prefix} + print util.rule(args.split(/\s+/)) + end + end + end + + end + + end + +end + +puts "CLEANFILES += moddep.lst" +puts "pkgdata_DATA += moddep.lst" +puts "moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep" +puts " cat $(DEFSYMFILES) /dev/null | ./genmoddep $(UNDSYMFILES) > $@ \\" +puts " || (rm -f $@; exit 1)" diff --git a/genmodsrc.sh b/genmodsrc.sh new file mode 100644 index 000000000..f02eb139d --- /dev/null +++ b/genmodsrc.sh @@ -0,0 +1,48 @@ +#! /bin/sh +# +# Copyright (C) 2002 Yoshinori K. Okuji +# +# This genmodsrc.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +set -e + +mod_name="$1" +deps="$2" + +cat < + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +EOF + +echo "PUPA_MOD_NAME(${mod_name});" + +for mod in `grep "^${mod_name}:" ${deps} | sed 's/^[^:]*://'`; do + echo "PUPA_MOD_DEP(${mod});" +done diff --git a/gensymlist.sh b/gensymlist.sh new file mode 100644 index 000000000..531ce1c21 --- /dev/null +++ b/gensymlist.sh @@ -0,0 +1,65 @@ +#! /bin/sh +# +# Copyright (C) 2002 Yoshinori K. Okuji +# +# This gensymlist.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +cat < + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +EOF + +for i in $*; do + echo "#include <$i>" +done + +cat <name; p++) + pupa_dl_register_symbol (p->name, p->addr, 0); +} +EOF diff --git a/include/grub/boot.h b/include/grub/boot.h new file mode 100644 index 000000000..bf897dbf2 --- /dev/null +++ b/include/grub/boot.h @@ -0,0 +1,28 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_BOOT_HEADER +#define PUPA_BOOT_HEADER 1 + +#define PUPA_BOOT_VERSION_MAJOR 4 +#define PUPA_BOOT_VERSION_MINOR 0 +#define PUPA_BOOT_VERSION ((PUPA_BOOT_VERSION_MINOR << 8) \ + | PUPA_BOOT_VERSION_MAJOR) + +#endif /* ! PUPA_BOOT_HEADER */ diff --git a/include/grub/device.h b/include/grub/device.h new file mode 100644 index 000000000..e8df53c5c --- /dev/null +++ b/include/grub/device.h @@ -0,0 +1,44 @@ +/* device.h - device manager */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_DEVICE_HEADER +#define PUPA_DEVICE_HEADER 1 + +#include +#include + +struct pupa_disk; +struct pupa_net; +struct pupa_fs; + +struct pupa_device +{ + struct pupa_disk *disk; + struct pupa_net *net; +}; +typedef struct pupa_device *pupa_device_t; + +pupa_device_t EXPORT_FUNC(pupa_device_open) (const char *name); +pupa_err_t EXPORT_FUNC(pupa_device_close) (pupa_device_t device); + +pupa_err_t EXPORT_FUNC(pupa_device_set_root) (const char *name); +const char *EXPORT_FUNC(pupa_device_get_root) (void); + +#endif /* ! PUPA_DEVICE_HEADER */ diff --git a/include/grub/disk.h b/include/grub/disk.h new file mode 100644 index 000000000..51bd5a64c --- /dev/null +++ b/include/grub/disk.h @@ -0,0 +1,119 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_DISK_HEADER +#define PUPA_DISK_HEADER 1 + +#include +#include +#include + +struct pupa_disk; + +/* Disk device. */ +struct pupa_disk_dev +{ + /* The device name. */ + const char *name; + + /* Call HOOK with each device name, until HOOK returns non-zero. */ + int (*iterate) (int (*hook) (const char *name)); + + /* Open the device named NAME, and set up DISK. */ + pupa_err_t (*open) (const char *name, struct pupa_disk *disk); + + /* Close the disk DISK. */ + void (*close) (struct pupa_disk *disk); + + /* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF. */ + pupa_err_t (*read) (struct pupa_disk *disk, unsigned long sector, + unsigned long size, char *buf); + + /* Write SIZE sectors from BUF into the sector SECTOR of the disk DISK. */ + pupa_err_t (*write) (struct pupa_disk *disk, unsigned long sector, + unsigned long size, const char *buf); + + /* The next disk device. */ + struct pupa_disk_dev *next; +}; +typedef struct pupa_disk_dev *pupa_disk_dev_t; + +struct pupa_partition; + +/* Disk. */ +struct pupa_disk +{ + /* The disk name. */ + const char *name; + + /* The underlying disk device. */ + pupa_disk_dev_t dev; + + /* The total number of sectors. */ + unsigned long total_sectors; + + /* If partitions can be stored. */ + int has_partitions; + + /* The id used by the disk cache manager. */ + unsigned long id; + + /* The partition information. This is machine-specific. */ + struct pupa_partition *partition; + + /* Called when a sector was read. */ + void (*read_hook) (unsigned long sector, unsigned offset, unsigned length); + + /* Device-specific data. */ + void *data; +}; +typedef struct pupa_disk *pupa_disk_t; + +/* The sector size. */ +#define PUPA_DISK_SECTOR_SIZE 0x200 +#define PUPA_DISK_SECTOR_BITS 9 + +/* The maximum number of disk caches. */ +#define PUPA_DISK_CACHE_NUM 1021 + +/* The size of a disk cache in sector units. */ +#define PUPA_DISK_CACHE_SIZE 8 +#define PUPA_DISK_CACHE_BITS 3 + +/* This is called from the memory manager. */ +void pupa_disk_cache_invalidate_all (void); + +void EXPORT_FUNC(pupa_disk_dev_register) (pupa_disk_dev_t dev); +void EXPORT_FUNC(pupa_disk_dev_unregister) (pupa_disk_dev_t dev); +void EXPORT_FUNC(pupa_disk_dev_iterate) (int (*hook) (const char *name)); + +pupa_disk_t EXPORT_FUNC(pupa_disk_open) (const char *name); +void EXPORT_FUNC(pupa_disk_close) (pupa_disk_t disk); +pupa_err_t EXPORT_FUNC(pupa_disk_read) (pupa_disk_t disk, + unsigned long sector, + unsigned long offset, + unsigned long size, + char *buf); +pupa_err_t EXPORT_FUNC(pupa_disk_write) (pupa_disk_t disk, + unsigned long sector, + unsigned long offset, + unsigned long size, + const char *buf); + +#endif /* ! PUPA_DISK_HEADER */ diff --git a/include/grub/dl.h b/include/grub/dl.h new file mode 100644 index 000000000..2763497ed --- /dev/null +++ b/include/grub/dl.h @@ -0,0 +1,86 @@ +/* dl.h - types and prototypes for loadable module support */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_DL_H +#define PUPA_DL_H 1 + +#include +#include +#include + +#define PUPA_MOD_INIT \ +static void pupa_mod_init (void) __attribute__ ((unused)); \ +static void \ +pupa_mod_init (void) + +#define PUPA_MOD_FINI \ +static void pupa_mod_fini (void) __attribute__ ((unused)); \ +static void \ +pupa_mod_fini (void) + +#define PUPA_MOD_NAME(name) \ +__asm__ (".section .modname,\"S\"\n.string \"" #name "\"\n.previous") + +#define PUPA_MOD_DEP(name) \ +__asm__ (".section .moddeps,\"S\"\n.string \"" #name "\"\n.previous") + +struct pupa_dl_segment +{ + struct pupa_dl_segment *next; + void *addr; + pupa_size_t size; + unsigned section; +}; +typedef struct pupa_dl_segment *pupa_dl_segment_t; + +struct pupa_dl; + +struct pupa_dl_dep +{ + struct pupa_dl_dep *next; + struct pupa_dl *mod; +}; +typedef struct pupa_dl_dep *pupa_dl_dep_t; + +struct pupa_dl +{ + char *name; + int ref_count; + pupa_dl_dep_t dep; + pupa_dl_segment_t segment; + void (*init) (void); + void (*fini) (void); +}; +typedef struct pupa_dl *pupa_dl_t; + +pupa_dl_t EXPORT_FUNC(pupa_dl_load_file) (const char *filename); +pupa_dl_t EXPORT_FUNC(pupa_dl_load) (const char *name); +pupa_dl_t pupa_dl_load_core (void *addr, pupa_size_t size); +void EXPORT_FUNC(pupa_dl_unload) (pupa_dl_t mod); +pupa_dl_t EXPORT_FUNC(pupa_dl_get) (const char *name); +pupa_err_t EXPORT_FUNC(pupa_dl_register_symbol) (const char *name, void *addr, + pupa_dl_t mod); +void *EXPORT_FUNC(pupa_dl_resolve_symbol) (const char *name); +void pupa_dl_init (const char *dir); + +int pupa_arch_dl_check_header (void *ehdr, pupa_size_t size); +pupa_err_t pupa_arch_dl_relocate_symbols (pupa_dl_t mod, void *ehdr); + +#endif /* ! PUPA_DL_H */ diff --git a/include/grub/elf.h b/include/grub/elf.h new file mode 100644 index 000000000..832e95042 --- /dev/null +++ b/include/grub/elf.h @@ -0,0 +1,2314 @@ +/* This file defines standard ELF types, structures, and macros. + Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 2002 Yoshinori K. Okuji + This file was part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef PUPA_ELF_H +#define PUPA_ELF_H 1 + +/* Standard ELF types. */ + +#include + +/* Type for a 16-bit quantity. */ +typedef pupa_uint16_t Elf32_Half; +typedef pupa_uint16_t Elf64_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef pupa_uint32_t Elf32_Word; +typedef pupa_int32_t Elf32_Sword; +typedef pupa_uint32_t Elf64_Word; +typedef pupa_int32_t Elf64_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef pupa_uint64_t Elf32_Xword; +typedef pupa_int64_t Elf32_Sxword; +typedef pupa_uint64_t Elf64_Xword; +typedef pupa_int64_t Elf64_Sxword; + +/* Type of addresses. */ +typedef pupa_uint32_t Elf32_Addr; +typedef pupa_uint64_t Elf64_Addr; + +/* Type of file offsets. */ +typedef pupa_uint32_t Elf32_Off; +typedef pupa_uint64_t Elf64_Off; + +/* Type for section indices, which are 16-bit quantities. */ +typedef pupa_uint16_t Elf32_Section; +typedef pupa_uint16_t Elf64_Section; + +/* Type for version symbol information. */ +typedef Elf32_Half Elf32_Versym; +typedef Elf64_Half Elf64_Versym; + + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +/* Fields in the e_ident array. The EI_* macros are indices into the + array. The macros under each EI_* macro are the values the byte + may have. */ + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +/* Conglomeration of the identification bytes, for easy testing as a word. */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ +#define ELFCLASSNUM 3 + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define ELFDATANUM 3 + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_SYSV 0 /* Alias. */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD. */ +#define ELFOSABI_LINUX 3 /* Linux. */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ +#define ELFOSABI_AIX 7 /* IBM AIX. */ +#define ELFOSABI_IRIX 8 /* SGI Irix. */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ + +/* Legal values for e_type (object file type). */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_NUM 5 /* Number of defined types */ +#define ET_LOOS 0xfe00 /* OS-specific range start */ +#define ET_HIOS 0xfeff /* OS-specific range end */ +#define ET_LOPROC 0xff00 /* Processor-specific range start */ +#define ET_HIPROC 0xffff /* Processor-specific range end */ + +/* Legal values for e_machine (architecture). */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ + +#define EM_PARISC 15 /* HPPA */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ + +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ + +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_AT19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_NUM 95 + +/* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the + chances of collision with official or non-GNU unofficial values. */ + +#define EM_ALPHA 0x9026 + +/* Legal values for e_version (version). */ + +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ +#define EV_NUM 2 + +/* Section header. */ + +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +} Elf32_Shdr; + +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +/* Special section indices. */ + +#define SHN_UNDEF 0 /* Undefined section */ +#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_HIPROC 0xff1f /* End of processor-specific */ +#define SHN_LOOS 0xff20 /* Start of OS-specific */ +#define SHN_HIOS 0xff3f /* End of OS-specific */ +#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +#define SHN_XINDEX 0xffff /* Index is in extra table. */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ + +/* Legal values for sh_type (section type). */ + +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_LOOS 0x60000000 /* Start OS-specific */ +#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ +#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ +#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ + +/* Legal values for sh_flags (section flags). */ + +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MERGE (1 << 4) /* Might be merged */ +#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ +#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ +#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ +#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling + required */ +#define SHF_GROUP (1 << 9) /* Section is member of a group. */ +#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Section group handling. */ +#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ + +/* Symbol table entry. */ + +typedef struct +{ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf32_Section st_shndx; /* Section index */ +} Elf32_Sym; + +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + +/* The syminfo section if available contains additional information about + every dynamic symbol. */ + +typedef struct +{ + Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf32_Half si_flags; /* Per symbol flags */ +} Elf32_Syminfo; + +typedef struct +{ + Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf64_Half si_flags; /* Per symbol flags */ +} Elf64_Syminfo; + +/* Possible values for si_boundto. */ +#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ + +/* Possible bitmasks for si_flags. */ +#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy + loaded */ +/* Syminfo version values. */ +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + + +/* How to extract and insert information held in the st_info field. */ + +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) + +/* Legal values for ST_BIND subfield of st_info (symbol binding). */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types. */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_COMMON 5 /* Symbol is a common data object */ +#define STT_TLS 6 /* Symbol is thread-local data object*/ +#define STT_NUM 7 /* Number of defined types. */ +#define STT_LOOS 10 /* Start of OS-specific */ +#define STT_HIOS 12 /* End of OS-specific */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ + + +/* Symbol table indices are found in the hash buckets and chain table + of a symbol hash table section. This special index value indicates + the end of a chain, meaning no further symbols are found in that bucket. */ + +#define STN_UNDEF 0 /* End of a chain. */ + + +/* How to extract and insert information held in the st_other field. */ + +#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) + +/* For ELF64 the definitions are the same. */ +#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) + +/* Symbol visibility specification encoded in the st_other field. */ +#define STV_DEFAULT 0 /* Default symbol visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Sym unavailable in other modules */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ + + +/* Relocation table entry without addend (in section of type SHT_REL). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +/* I have seen two different definitions of the Elf64_Rel and + Elf64_Rela structures, so we'll leave them out until Novell (or + whoever) gets their act together. */ +/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ +} Elf64_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Sword r_addend; /* Addend */ +} Elf32_Rela; + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Rela; + +/* How to extract and insert information held in the r_info field. */ + +#define ELF32_R_SYM(val) ((val) >> 8) +#define ELF32_R_TYPE(val) ((val) & 0xff) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) + +/* Program segment header. */ + +typedef struct +{ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +} Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + +/* Legal values for p_type (segment type). */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_TLS 7 /* Thread-local storage segment */ +#define PT_NUM 8 /* Number of defined types */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Legal values for p_flags (segment flags). */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKOS 0x0ff00000 /* OS-specific */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Legal values for note segment descriptor types for core files. */ + +#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ +#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ +#define NT_PRXREG 4 /* Contains copy of prxregset struct */ +#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ +#define NT_AUXV 6 /* Contains copy of auxv array */ +#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ +#define NT_ASRS 8 /* Contains copy of asrset struct */ +#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ +#define NT_PSINFO 13 /* Contains copy of psinfo struct */ +#define NT_PRCRED 14 /* Contains copy of prcred struct */ +#define NT_UTSNAME 15 /* Contains copy of utsname struct */ +#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ +#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ +#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct*/ + +/* Legal values for the note segment descriptor types for object files. */ + +#define NT_VERSION 1 /* Contains a version string. */ + + +/* Dynamic section entry. */ + +typedef struct +{ + Elf32_Sword d_tag; /* Dynamic entry type */ + union + { + Elf32_Word d_val; /* Integer value */ + Elf32_Addr d_ptr; /* Address value */ + } d_un; +} Elf32_Dyn; + +typedef struct +{ + Elf64_Sxword d_tag; /* Dynamic entry type */ + union + { + Elf64_Xword d_val; /* Integer value */ + Elf64_Addr d_ptr; /* Address value */ + } d_un; +} Elf64_Dyn; + +/* Legal values for d_tag (dynamic entry type). */ + +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path (deprecated) */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used */ +#define DT_LOOS 0x6000000d /* Start of OS-specific */ +#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ + +/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the + Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's + approach. */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ +#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ +#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ +#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting + the following DT_* entry. */ +#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +#define DT_VALRNGHI 0x6ffffdff +#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ +#define DT_VALNUM 12 + +/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + + If any adjustment is made to the ELF object after it has been + built these entries will need to be adjusted. */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ +#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ +#define DT_CONFIG 0x6ffffefa /* Configuration information. */ +#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ +#define DT_AUDIT 0x6ffffefc /* Object auditing. */ +#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ +#define DT_MOVETAB 0x6ffffefe /* Move table. */ +#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ +#define DT_ADDRNUM 10 + +/* The versioning entry types. The next are defined as part of the + GNU extension. */ +#define DT_VERSYM 0x6ffffff0 + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa + +/* These were chosen by Sun. */ +#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_VERSIONTAGNUM 16 + +/* Sun added these machine-independent extensions in the "processor-specific" + range. Be compatible. */ +#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 + +/* Values of `d_un.d_val' in the DT_FLAGS entry. */ +#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ +#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ + +/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 + entry in the dynamic section. */ +#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ +#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ +#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ +#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ +#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ +#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ +#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ +#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ +#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ +#define DF_1_TRANS 0x00000200 +#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ +#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ +#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ +#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ +#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ +#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ +#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ + +/* Flags for the feature selection in DT_FEATURE_1. */ +#define DTF_1_PARINIT 0x00000001 +#define DTF_1_CONFEXP 0x00000002 + +/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ +#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ +#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not + generally available. */ + +/* Version definition sections. */ + +typedef struct +{ + Elf32_Half vd_version; /* Version revision */ + Elf32_Half vd_flags; /* Version information */ + Elf32_Half vd_ndx; /* Version Index */ + Elf32_Half vd_cnt; /* Number of associated aux entries */ + Elf32_Word vd_hash; /* Version name hash value */ + Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf32_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf32_Verdef; + +typedef struct +{ + Elf64_Half vd_version; /* Version revision */ + Elf64_Half vd_flags; /* Version information */ + Elf64_Half vd_ndx; /* Version Index */ + Elf64_Half vd_cnt; /* Number of associated aux entries */ + Elf64_Word vd_hash; /* Version name hash value */ + Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf64_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf64_Verdef; + + +/* Legal values for vd_version (version revision). */ +#define VER_DEF_NONE 0 /* No version */ +#define VER_DEF_CURRENT 1 /* Current version */ +#define VER_DEF_NUM 2 /* Given version number */ + +/* Legal values for vd_flags (version information flags). */ +#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + +/* Versym symbol index values. */ +#define VER_NDX_LOCAL 0 /* Symbol is local. */ +#define VER_NDX_GLOBAL 1 /* Symbol is global. */ +#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ +#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ + +/* Auxialiary version information. */ + +typedef struct +{ + Elf32_Word vda_name; /* Version or dependency names */ + Elf32_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf32_Verdaux; + +typedef struct +{ + Elf64_Word vda_name; /* Version or dependency names */ + Elf64_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf64_Verdaux; + + +/* Version dependency section. */ + +typedef struct +{ + Elf32_Half vn_version; /* Version of structure */ + Elf32_Half vn_cnt; /* Number of associated aux entries */ + Elf32_Word vn_file; /* Offset of filename for this + dependency */ + Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf32_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf32_Verneed; + +typedef struct +{ + Elf64_Half vn_version; /* Version of structure */ + Elf64_Half vn_cnt; /* Number of associated aux entries */ + Elf64_Word vn_file; /* Offset of filename for this + dependency */ + Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf64_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf64_Verneed; + + +/* Legal values for vn_version (version revision). */ +#define VER_NEED_NONE 0 /* No version */ +#define VER_NEED_CURRENT 1 /* Current version */ +#define VER_NEED_NUM 2 /* Given version number */ + +/* Auxiliary needed version information. */ + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name */ + Elf32_Half vna_flags; /* Dependency specific information */ + Elf32_Half vna_other; /* Unused */ + Elf32_Word vna_name; /* Dependency name string offset */ + Elf32_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf32_Vernaux; + +typedef struct +{ + Elf64_Word vna_hash; /* Hash value of dependency name */ + Elf64_Half vna_flags; /* Dependency specific information */ + Elf64_Half vna_other; /* Unused */ + Elf64_Word vna_name; /* Dependency name string offset */ + Elf64_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf64_Vernaux; + + +/* Legal values for vna_flags. */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + + +/* Auxiliary vector. */ + +/* This vector is normally only used by the program interpreter. The + usual definition in an ABI supplement uses the name auxv_t. The + vector is not usually defined in a standard file, but it + can't hurt. We rename it to avoid conflicts. The sizes of these + types are an arrangement between the exec server and the program + interpreter, so we don't fully specify them here. */ + +typedef struct +{ + int a_type; /* Entry type */ + union + { + long int a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (void); /* Function pointer value */ + } a_un; +} Elf32_auxv_t; + +typedef struct +{ + long int a_type; /* Entry type */ + union + { + long int a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (void); /* Function pointer value */ + } a_un; +} Elf64_auxv_t; + +/* Legal values for a_type (entry type). */ + +#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 */ +#define AT_CLKTCK 17 /* Frequency of times() */ + +/* Some more special a_type values describing the hardware. */ +#define AT_PLATFORM 15 /* String identifying platform. */ +#define AT_HWCAP 16 /* Machine dependent hints about + processor capabilities. */ + +/* This entry gives some information about the FPU initialization + performed by the kernel. */ +#define AT_FPUCW 18 /* Used FPU control word. */ + +/* Cache block sizes. */ +#define AT_DCACHEBSIZE 19 /* Data cache block size. */ +#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ +#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ + +/* A special ignored value for PPC, used by the kernel to control the + interpretation of the AUXV. Must be > 16. */ +#define AT_IGNOREPPC 22 /* Entry should be ignored */ + + +/* Note section contents. Each entry in the note section begins with + a header of a fixed form. */ + +typedef struct +{ + Elf32_Word n_namesz; /* Length of the note's name. */ + Elf32_Word n_descsz; /* Length of the note's descriptor. */ + Elf32_Word n_type; /* Type of the note. */ +} Elf32_Nhdr; + +typedef struct +{ + Elf64_Word n_namesz; /* Length of the note's name. */ + Elf64_Word n_descsz; /* Length of the note's descriptor. */ + Elf64_Word n_type; /* Type of the note. */ +} Elf64_Nhdr; + +/* Known names of notes. */ + +/* Solaris entries in the note section have this name. */ +#define ELF_NOTE_SOLARIS "SUNW Solaris" + +/* Note entries for GNU systems have this name. */ +#define ELF_NOTE_GNU "GNU" + + +/* Defined types of notes for Solaris. */ + +/* Value of descriptor (one word) is desired pagesize for the binary. */ +#define ELF_NOTE_PAGESIZE_HINT 1 + + +/* Defined note types for GNU systems. */ + +/* ABI information. The descriptor consists of words: + word 0: OS descriptor + word 1: major version of the ABI + word 2: minor version of the ABI + word 3: subminor version of the ABI +*/ +#define ELF_NOTE_ABI 1 + +/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI + note section entry. */ +#define ELF_NOTE_OS_LINUX 0 +#define ELF_NOTE_OS_GNU 1 +#define ELF_NOTE_OS_SOLARIS2 2 + + +/* Move records. */ +typedef struct +{ + Elf32_Xword m_value; /* Symbol value. */ + Elf32_Word m_info; /* Size and index. */ + Elf32_Word m_poffset; /* Symbol offset. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Stride info. */ +} Elf32_Move; + +typedef struct +{ + Elf64_Xword m_value; /* Symbol value. */ + Elf64_Xword m_info; /* Size and index. */ + Elf64_Xword m_poffset; /* Symbol offset. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Stride info. */ +} Elf64_Move; + +/* Macro to construct move records. */ +#define ELF32_M_SYM(info) ((info) >> 8) +#define ELF32_M_SIZE(info) ((unsigned char) (info)) +#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) + +#define ELF64_M_SYM(info) ELF32_M_SYM (info) +#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) +#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) + + +/* Motorola 68k specific definitions. */ + +/* Values for Elf32_Ehdr.e_flags. */ +#define EF_CPU32 0x00810000 + +/* m68k relocs. */ + +#define R_68K_NONE 0 /* No reloc */ +#define R_68K_32 1 /* Direct 32 bit */ +#define R_68K_16 2 /* Direct 16 bit */ +#define R_68K_8 3 /* Direct 8 bit */ +#define R_68K_PC32 4 /* PC relative 32 bit */ +#define R_68K_PC16 5 /* PC relative 16 bit */ +#define R_68K_PC8 6 /* PC relative 8 bit */ +#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ +#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ +#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ +#define R_68K_GOT32O 10 /* 32 bit GOT offset */ +#define R_68K_GOT16O 11 /* 16 bit GOT offset */ +#define R_68K_GOT8O 12 /* 8 bit GOT offset */ +#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ +#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ +#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ +#define R_68K_PLT32O 16 /* 32 bit PLT offset */ +#define R_68K_PLT16O 17 /* 16 bit PLT offset */ +#define R_68K_PLT8O 18 /* 8 bit PLT offset */ +#define R_68K_COPY 19 /* Copy symbol at runtime */ +#define R_68K_GLOB_DAT 20 /* Create GOT entry */ +#define R_68K_JMP_SLOT 21 /* Create PLT entry */ +#define R_68K_RELATIVE 22 /* Adjust by program base */ +/* Keep this the last entry. */ +#define R_68K_NUM 23 + +/* Intel 80386 specific definitions. */ + +/* i386 relocs. */ + +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ +#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS + block offset */ +#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block + offset */ +#define R_386_TLS_LE 17 /* Offset relative to static TLS + block */ +#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of + general dynamic thread local data */ +#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of + local dynamic thread local data + in LE code */ +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic + thread local data */ +#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ +#define R_386_TLS_GD_CALL 26 /* Relocation for call to + __tls_get_addr() */ +#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ +#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic + thread local data in LE code */ +#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ +#define R_386_TLS_LDM_CALL 30 /* Relocation for call to + __tls_get_addr() in LDM code */ +#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ +#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ +#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS + block offset */ +#define R_386_TLS_LE_32 34 /* Negated offset relative to static + TLS block */ +#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ +#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ +#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +/* Keep this the last entry. */ +#define R_386_NUM 38 + +/* SUN SPARC specific definitions. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_REGISTER 13 /* Global register reserved to app. */ + +/* Values for Elf64_Ehdr.e_flags. */ + +#define EF_SPARCV9_MM 3 +#define EF_SPARCV9_TSO 0 +#define EF_SPARCV9_PSO 1 +#define EF_SPARCV9_RMO 2 +#define EF_SPARC_LEDATA 0x800000 /* little endian data */ +#define EF_SPARC_EXT_MASK 0xFFFF00 +#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ +#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ +#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ +#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ + +/* SPARC relocs. */ + +#define R_SPARC_NONE 0 /* No reloc */ +#define R_SPARC_8 1 /* Direct 8 bit */ +#define R_SPARC_16 2 /* Direct 16 bit */ +#define R_SPARC_32 3 /* Direct 32 bit */ +#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +#define R_SPARC_HI22 9 /* High 22 bit */ +#define R_SPARC_22 10 /* Direct 22 bit */ +#define R_SPARC_13 11 /* Direct 13 bit */ +#define R_SPARC_LO10 12 /* Truncated 10 bit */ +#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ + +/* Additional Sparc64 relocs. */ + +#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ +#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ +#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ +#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ +#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ +#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ +#define R_SPARC_10 30 /* Direct 10 bit */ +#define R_SPARC_11 31 /* Direct 11 bit */ +#define R_SPARC_64 32 /* Direct 64 bit */ +#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ +#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ +#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ +#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ +#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ +#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ +#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ +#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ +#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +#define R_SPARC_7 43 /* Direct 7 bit */ +#define R_SPARC_5 44 /* Direct 5 bit */ +#define R_SPARC_6 45 /* Direct 6 bit */ +#define R_SPARC_DISP64 46 /* PC relative 64 bit */ +#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ +#define R_SPARC_HIX22 48 /* High 22 bit complemented */ +#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ +#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ +#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ +#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ +#define R_SPARC_REGISTER 53 /* Global register usage */ +#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ +#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 +/* Keep this the last entry. */ +#define R_SPARC_NUM 80 + +/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ + +#define DT_SPARC_REGISTER 0x70000001 +#define DT_SPARC_NUM 2 + +/* Bits present in AT_HWCAP, primarily for Sparc32. */ + +#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */ +#define HWCAP_SPARC_ULTRA3 32 + +/* MIPS R3000 specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +#define EF_MIPS_PIC 2 /* Contains PIC code */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +#define EF_MIPS_XGOT 8 +#define EF_MIPS_64BIT_WHIRL 16 +#define EF_MIPS_ABI2 32 +#define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ + +/* Legal values for MIPS architecture level. */ + +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* The following are non-official names and should not be used. */ + +#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* Special section indices. */ + +#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ +#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ +#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ +#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ +#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ +#define SHT_MIPS_MSYM 0x70000001 +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ +#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ +#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ +#define SHT_MIPS_PACKAGE 0x70000007 +#define SHT_MIPS_PACKSYM 0x70000008 +#define SHT_MIPS_RELD 0x70000009 +#define SHT_MIPS_IFACE 0x7000000b +#define SHT_MIPS_CONTENT 0x7000000c +#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ +#define SHT_MIPS_SHDR 0x70000010 +#define SHT_MIPS_FDESC 0x70000011 +#define SHT_MIPS_EXTSYM 0x70000012 +#define SHT_MIPS_DENSE 0x70000013 +#define SHT_MIPS_PDESC 0x70000014 +#define SHT_MIPS_LOCSYM 0x70000015 +#define SHT_MIPS_AUXSYM 0x70000016 +#define SHT_MIPS_OPTSYM 0x70000017 +#define SHT_MIPS_LOCSTR 0x70000018 +#define SHT_MIPS_LINE 0x70000019 +#define SHT_MIPS_RFDESC 0x7000001a +#define SHT_MIPS_DELTASYM 0x7000001b +#define SHT_MIPS_DELTAINST 0x7000001c +#define SHT_MIPS_DELTACLASS 0x7000001d +#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ +#define SHT_MIPS_DELTADECL 0x7000001f +#define SHT_MIPS_SYMBOL_LIB 0x70000020 +#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +#define SHT_MIPS_TRANSLATE 0x70000022 +#define SHT_MIPS_PIXIE 0x70000023 +#define SHT_MIPS_XLATE 0x70000024 +#define SHT_MIPS_XLATE_DEBUG 0x70000025 +#define SHT_MIPS_WHIRL 0x70000026 +#define SHT_MIPS_EH_REGION 0x70000027 +#define SHT_MIPS_XLATE_OLD 0x70000028 +#define SHT_MIPS_PDR_EXCEPTION 0x70000029 + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ +#define SHF_MIPS_MERGE 0x20000000 +#define SHF_MIPS_ADDR 0x40000000 +#define SHF_MIPS_STRINGS 0x80000000 +#define SHF_MIPS_NOSTRIP 0x08000000 +#define SHF_MIPS_LOCAL 0x04000000 +#define SHF_MIPS_NAMES 0x02000000 +#define SHF_MIPS_NODUPE 0x01000000 + + +/* Symbol tables. */ + +/* MIPS specific values for `st_other'. */ +#define STO_MIPS_DEFAULT 0x0 +#define STO_MIPS_INTERNAL 0x1 +#define STO_MIPS_HIDDEN 0x2 +#define STO_MIPS_PROTECTED 0x3 +#define STO_MIPS_SC_ALIGN_UNUSED 0xff + +/* MIPS specific values for `st_info'. */ +#define STB_MIPS_SPLIT_COMMON 13 + +/* Entries found in sections of type SHT_MIPS_GPTAB. */ + +typedef union +{ + struct + { + Elf32_Word gt_current_g_value; /* -G value used for compilation */ + Elf32_Word gt_unused; /* Not used */ + } gt_header; /* First entry in section */ + struct + { + Elf32_Word gt_g_value; /* If this value were used for -G */ + Elf32_Word gt_bytes; /* This many bytes would be used */ + } gt_entry; /* Subsequent entries in section */ +} Elf32_gptab; + +/* Entry found in sections of type SHT_MIPS_REGINFO. */ + +typedef struct +{ + Elf32_Word ri_gprmask; /* General registers used */ + Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ + Elf32_Sword ri_gp_value; /* $gp register value */ +} Elf32_RegInfo; + +/* Entries found in sections of type SHT_MIPS_OPTIONS. */ + +typedef struct +{ + unsigned char kind; /* Determines interpretation of the + variable part of descriptor. */ + unsigned char size; /* Size of descriptor, including header. */ + Elf32_Section section; /* Section header index of section affected, + 0 for global options. */ + Elf32_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* Values for `kind' field in Elf_Options. */ + +#define ODK_NULL 0 /* Undefined. */ +#define ODK_REGINFO 1 /* Register usage information. */ +#define ODK_EXCEPTIONS 2 /* Exception processing options. */ +#define ODK_PAD 3 /* Section padding options. */ +#define ODK_HWPATCH 4 /* Hardware workarounds performed */ +#define ODK_FILL 5 /* record the fill value used by the linker. */ +#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ +#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ +#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ + +/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ + +#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ +#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ +#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ +#define OEX_SMM 0x20000 /* Force sequential memory mode? */ +#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ +#define OEX_PRECISEFP OEX_FPDBUG +#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ + +#define OEX_FPU_INVAL 0x10 +#define OEX_FPU_DIV0 0x08 +#define OEX_FPU_OFLO 0x04 +#define OEX_FPU_UFLO 0x02 +#define OEX_FPU_INEX 0x01 + +/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ + +#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ +#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ +#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ +#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ + +#define OPAD_PREFIX 0x1 +#define OPAD_POSTFIX 0x2 +#define OPAD_SYMBOL 0x4 + +/* Entry found in `.options' section. */ + +typedef struct +{ + Elf32_Word hwp_flags1; /* Extra flags. */ + Elf32_Word hwp_flags2; /* Extra flags. */ +} Elf_Options_Hw; + +/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ + +#define OHWA0_R4KEOP_CHECKED 0x00000001 +#define OHWA1_R4KEOP_CLEAN 0x00000002 + +/* MIPS relocs. */ + +#define R_MIPS_NONE 0 /* No reloc */ +#define R_MIPS_16 1 /* Direct 16 bit */ +#define R_MIPS_32 2 /* Direct 32 bit */ +#define R_MIPS_REL32 3 /* PC relative 32 bit */ +#define R_MIPS_26 4 /* Direct 26 bit shifted */ +#define R_MIPS_HI16 5 /* High 16 bit */ +#define R_MIPS_LO16 6 /* Low 16 bit */ +#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +#define R_MIPS_PC16 10 /* PC relative 16 bit */ +#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ + +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +#define R_MIPS_GOT_HI16 22 +#define R_MIPS_GOT_LO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_INSERT_A 25 +#define R_MIPS_INSERT_B 26 +#define R_MIPS_DELETE 27 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_CALL_HI16 30 +#define R_MIPS_CALL_LO16 31 +#define R_MIPS_SCN_DISP 32 +#define R_MIPS_REL16 33 +#define R_MIPS_ADD_IMMEDIATE 34 +#define R_MIPS_PJUMP 35 +#define R_MIPS_RELGOT 36 +#define R_MIPS_JALR 37 +/* Keep this the last entry. */ +#define R_MIPS_NUM 38 + +/* Legal values for p_type field of Elf32_Phdr. */ + +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_OPTIONS 0x70000002 + +/* Special program header types. */ + +#define PF_MIPS_LOCAL 0x10000000 + +/* Legal values for d_tag field of Elf32_Dyn. */ + +#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +#define DT_MIPS_MSYM 0x70000007 +#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ +#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ +#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ +#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in + DT_MIPS_DELTA_CLASS. */ +#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ +#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in + DT_MIPS_DELTA_INSTANCE. */ +#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ +#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in + DT_MIPS_DELTA_RELOC. */ +#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta + relocations refer to. */ +#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in + DT_MIPS_DELTA_SYM. */ +#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the + class declaration. */ +#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in + DT_MIPS_DELTA_CLASSSYM. */ +#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ +#define DT_MIPS_PIXIE_INIT 0x70000023 +#define DT_MIPS_SYMBOL_LIB 0x70000024 +#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 +#define DT_MIPS_LOCAL_GOTIDX 0x70000026 +#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 +#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 +#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ +#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ +#define DT_MIPS_DYNSTR_ALIGN 0x7000002b +#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ +#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve + function stored in GOT. */ +#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added + by rld on dlopen() calls. */ +#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ +#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ +#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ +#define DT_MIPS_NUM 0x32 + +/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ + +#define RHF_NONE 0 /* No flags */ +#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ +#define RHF_NO_MOVE (1 << 3) +#define RHF_SGI_ONLY (1 << 4) +#define RHF_GUARANTEE_INIT (1 << 5) +#define RHF_DELTA_C_PLUS_PLUS (1 << 6) +#define RHF_GUARANTEE_START_INIT (1 << 7) +#define RHF_PIXIE (1 << 8) +#define RHF_DEFAULT_DELAY_LOAD (1 << 9) +#define RHF_REQUICKSTART (1 << 10) +#define RHF_REQUICKSTARTED (1 << 11) +#define RHF_CORD (1 << 12) +#define RHF_NO_UNRES_UNDEF (1 << 13) +#define RHF_RLD_ORDER_SAFE (1 << 14) + +/* Entries found in sections of type SHT_MIPS_LIBLIST. */ + +typedef struct +{ + Elf32_Word l_name; /* Name (string table index) */ + Elf32_Word l_time_stamp; /* Timestamp */ + Elf32_Word l_checksum; /* Checksum */ + Elf32_Word l_version; /* Interface version */ + Elf32_Word l_flags; /* Flags */ +} Elf32_Lib; + +typedef struct +{ + Elf64_Word l_name; /* Name (string table index) */ + Elf64_Word l_time_stamp; /* Timestamp */ + Elf64_Word l_checksum; /* Checksum */ + Elf64_Word l_version; /* Interface version */ + Elf64_Word l_flags; /* Flags */ +} Elf64_Lib; + + +/* Legal values for l_flags. */ + +#define LL_NONE 0 +#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ +#define LL_REQUIRE_MINOR (1 << 2) +#define LL_EXPORTS (1 << 3) +#define LL_DELAY_LOAD (1 << 4) +#define LL_DELTA (1 << 5) + +/* Entries found in sections of type SHT_MIPS_CONFLICT. */ + +typedef Elf32_Addr Elf32_Conflict; + + +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch + prediction. */ +#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ + +/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ + +#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ + +/* Additional section indeces. */ + +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared + symbols in ANSI C. */ +#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +#define STT_HP_OPAQUE (STT_LOOS + 0x1) +#define STT_HP_STUB (STT_LOOS + 0x2) + +/* HPPA relocs. */ + +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LORESERVE 128 +#define R_PARISC_COPY 128 /* Copy relocation. */ +#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_HIRESERVE 255 + +/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ + +#define PT_HP_TLS (PT_LOOS + 0x0) +#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +#define PT_HP_PARALLEL (PT_LOOS + 0x10) +#define PT_HP_FASTBIND (PT_LOOS + 0x11) +#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +#define PT_HP_STACK (PT_LOOS + 0x14) + +#define PT_PARISC_ARCHEXT 0x70000000 +#define PT_PARISC_UNWIND 0x70000001 + +/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ + +#define PF_PARISC_SBP 0x08000000 + +#define PF_HP_PAGE_SIZE 0x00100000 +#define PF_HP_FAR_SHARED 0x00200000 +#define PF_HP_NEAR_SHARED 0x00400000 +#define PF_HP_CODE 0x01000000 +#define PF_HP_MODIFY 0x02000000 +#define PF_HP_LAZYSWAP 0x04000000 +#define PF_HP_SBP 0x08000000 + + +/* Alpha specific definitions. */ + +/* Legal values for e_flags field of Elf64_Ehdr. */ + +#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ + +/* Legal values for sh_type field of Elf64_Shdr. */ + +/* These two are primerily concerned with ECOFF debugging info. */ +#define SHT_ALPHA_DEBUG 0x70000001 +#define SHT_ALPHA_REGINFO 0x70000002 + +/* Legal values for sh_flags field of Elf64_Shdr. */ + +#define SHF_ALPHA_GPREL 0x10000000 + +/* Legal values for st_other field of Elf64_Sym. */ +#define STO_ALPHA_NOPV 0x80 /* No PV required. */ +#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ + +/* Alpha relocs. */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ +#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ +#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +#define R_ALPHA_TLS_GD_HI 28 +#define R_ALPHA_TLSGD 29 +#define R_ALPHA_TLS_LDM 30 +#define R_ALPHA_DTPMOD64 31 +#define R_ALPHA_GOTDTPREL 32 +#define R_ALPHA_DTPREL64 33 +#define R_ALPHA_DTPRELHI 34 +#define R_ALPHA_DTPRELLO 35 +#define R_ALPHA_DTPREL16 36 +#define R_ALPHA_GOTTPREL 37 +#define R_ALPHA_TPREL64 38 +#define R_ALPHA_TPRELHI 39 +#define R_ALPHA_TPRELLO 40 +#define R_ALPHA_TPREL16 41 +/* Keep this the last entry. */ +#define R_ALPHA_NUM 46 + +/* Magic values of the LITUSE relocation addend. */ +#define LITUSE_ALPHA_ADDR 0 +#define LITUSE_ALPHA_BASE 1 +#define LITUSE_ALPHA_BYTOFF 2 +#define LITUSE_ALPHA_JSR 3 +#define LITUSE_ALPHA_TLS_GD 4 +#define LITUSE_ALPHA_TLS_LDM 5 + + +/* PowerPC specific declarations */ + +/* Values for Elf32/64_Ehdr.e_flags. */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib + flag */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 +/* Keep this the last entry. */ +#define R_PPC_NUM 37 + +/* PowerPC64 relocations defined by the ABIs */ +#define R_PPC64_NONE R_PPC_NONE +#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address. */ +#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned. */ +#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address. */ +#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address. */ +#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */ +#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ +#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned. */ +#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN +#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN +#define R_PPC64_REL24 R_PPC_REL24 /* PC relative 26 bit, word aligned. */ +#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit. */ +#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN +#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN +#define R_PPC64_GOT16 R_PPC_GOT16 +#define R_PPC64_GOT16_LO R_PPC_GOT16_LO +#define R_PPC64_GOT16_HI R_PPC_GOT16_HI +#define R_PPC64_GOT16_HA R_PPC_GOT16_HA + +#define R_PPC64_COPY R_PPC_COPY +#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT +#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT +#define R_PPC64_RELATIVE R_PPC_RELATIVE + +#define R_PPC64_UADDR32 R_PPC_UADDR32 +#define R_PPC64_UADDR16 R_PPC_UADDR16 +#define R_PPC64_REL32 R_PPC_REL32 +#define R_PPC64_PLT32 R_PPC_PLT32 +#define R_PPC64_PLTREL32 R_PPC_PLTREL32 +#define R_PPC64_PLT16_LO R_PPC_PLT16_LO +#define R_PPC64_PLT16_HI R_PPC_PLT16_HI +#define R_PPC64_PLT16_HA R_PPC_PLT16_HA + +#define R_PPC64_SECTOFF R_PPC_SECTOFF +#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO +#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI +#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA +#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2. */ +#define R_PPC64_ADDR64 38 /* doubleword64 S + A. */ +#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A). */ +#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A). */ +#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A). */ +#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A). */ +#define R_PPC64_UADDR64 43 /* doubleword64 S + A. */ +#define R_PPC64_REL64 44 /* doubleword64 S + A - P. */ +#define R_PPC64_PLT64 45 /* doubleword64 L + A. */ +#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P. */ +#define R_PPC64_TOC16 47 /* half16* S + A - .TOC. */ +#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.). */ +#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.). */ +#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.). */ +#define R_PPC64_TOC 51 /* doubleword64 .TOC. */ +#define R_PPC64_PLTGOT16 52 /* half16* M + A. */ +#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A). */ +#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A). */ +#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A). */ + +#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2. */ +#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2. */ +#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2. */ +#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2. */ +#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2. */ +#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2. */ +#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2. */ +#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2. */ +#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2. */ +#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2. */ +#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2. */ +/* Keep this the last entry. */ +#define R_PPC64_NUM 67 + +/* The remaining relocs are from the Embedded ELF ABI, and are not + in the SVR4 ELF ABI. */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations. */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* This is a phony reloc to handle any old fashioned TOC16 references + that may still be in object files. */ +#define R_PPC_TOC16 255 + +/* PowerPC64 specific values for the Dyn d_tag field. */ +#define DT_PPC64_GLINK (DT_LOPROC + 0) +#define DT_PPC64_NUM 1 + +/* ARM specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_ARM_NEW_ABI 0x80 +#define EF_ARM_OLD_ABI 0x100 + +/* Other constants defined in the ARM ELF spec. version B-01. */ +/* NB. These conflict with values defined above. */ +#define EF_ARM_SYMSARESORTED 0x04 +#define EF_ARM_DYNSYMSUSESEGIDX 0x08 +#define EF_ARM_MAPSYMSFIRST 0x10 +#define EF_ARM_EABIMASK 0XFF000000 + +#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 + +/* Additional symbol types for Thumb */ +#define STT_ARM_TFUNC 0xd + +/* ARM-specific values for sh_flags */ +#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined + in the input to a link step */ + +/* ARM-specific program header flags */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base */ + +/* ARM relocs. */ +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_PC24 1 /* PC relative 26 bit branch */ +#define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_REL32 3 /* PC relative 32 bit */ +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 /* Direct 16 bit */ +#define R_ARM_ABS12 6 /* Direct 12 bit */ +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 /* Direct 8 bit */ +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_COPY 20 /* Copy symbol at runtime */ +#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ +#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_PLT32 27 /* 32 bit PLT address */ +#define R_ARM_ALU_PCREL_7_0 32 +#define R_ARM_ALU_PCREL_15_8 33 +#define R_ARM_ALU_PCREL_23_15 34 +#define R_ARM_LDR_SBREL_11_0 35 +#define R_ARM_ALU_SBREL_19_12 36 +#define R_ARM_ALU_SBREL_27_20 37 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +#define R_ARM_THM_PC9 103 /* thumb conditional branch */ +#define R_ARM_RXPC25 249 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS22 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 +/* Keep this the last entry. */ +#define R_ARM_NUM 256 + +/* IA-64 specific declarations. */ + +/* Processor specific flags for the Ehdr e_flags field. */ +#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ +#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ +#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ +#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ + +/* Processor specific flags for the Phdr p_flags field. */ +#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ +#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ + +/* Processor specific flags for the Shdr sh_flags field. */ +#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ +#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Dyn d_tag field. */ +#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) +#define DT_IA_64_NUM 1 + +/* IA-64 relocations. */ +#define R_IA64_NONE 0x00 /* none */ +#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ +#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ +#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ +#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ +#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ +#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ +#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ +#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ +#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ +#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ +#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ +#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ +#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ +#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ +#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ +#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ +#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ +#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ +#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ +#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ +#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ +#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ +#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ +#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ +#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ +#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ +#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ +#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ +#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ +#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ +#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ +#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ +#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ +#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ +#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ +#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ +#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ +#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ +#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ +#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ +#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ +#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ +#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ +#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ +#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ +#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ +#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ +#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ +#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ +#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ +#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ +#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ +#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ +#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ +#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ +#define R_IA64_COPY 0x84 /* copy relocation */ +#define R_IA64_SUB 0x85 /* Addend and symbol difference */ +#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ +#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ +#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ +#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ +#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ +#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ +#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ +#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ +#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ +#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ +#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ +#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ +#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ +#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ +#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ +#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ + +/* SH specific declarations */ + +/* SH relocs. */ +#define R_SH_NONE 0 +#define R_SH_DIR32 1 +#define R_SH_REL32 2 +#define R_SH_DIR8WPN 3 +#define R_SH_IND12W 4 +#define R_SH_DIR8WPL 5 +#define R_SH_DIR8WPZ 6 +#define R_SH_DIR8BP 7 +#define R_SH_DIR8W 8 +#define R_SH_DIR8L 9 +#define R_SH_SWITCH16 25 +#define R_SH_SWITCH32 26 +#define R_SH_USES 27 +#define R_SH_COUNT 28 +#define R_SH_ALIGN 29 +#define R_SH_CODE 30 +#define R_SH_DATA 31 +#define R_SH_LABEL 32 +#define R_SH_SWITCH8 33 +#define R_SH_GNU_VTINHERIT 34 +#define R_SH_GNU_VTENTRY 35 +#define R_SH_TLS_GD_32 144 +#define R_SH_TLS_LD_32 145 +#define R_SH_TLS_LDO_32 146 +#define R_SH_TLS_IE_32 147 +#define R_SH_TLS_LE_32 148 +#define R_SH_TLS_DTPMOD32 149 +#define R_SH_TLS_DTPOFF32 150 +#define R_SH_TLS_TPOFF32 151 +#define R_SH_TLS_GD_MOV 152 +#define R_SH_TLS_LDM_MOV 153 +#define R_SH_TLS_LDO_MOV 154 +#define R_SH_TLS_IE_MOV 155 +#define R_SH_TLS_LE_MOV 156 +#define R_SH_GOT32 160 +#define R_SH_PLT32 161 +#define R_SH_COPY 162 +#define R_SH_GLOB_DAT 163 +#define R_SH_JMP_SLOT 164 +#define R_SH_RELATIVE 165 +#define R_SH_GOTOFF 166 +#define R_SH_GOTPC 167 +/* Keep this the last entry. */ +#define R_SH_NUM 256 + +/* Additional s390 relocs */ + +#define R_390_NONE 0 /* No reloc. */ +#define R_390_8 1 /* Direct 8 bit. */ +#define R_390_12 2 /* Direct 12 bit. */ +#define R_390_16 3 /* Direct 16 bit. */ +#define R_390_32 4 /* Direct 32 bit. */ +#define R_390_PC32 5 /* PC relative 32 bit. */ +#define R_390_GOT12 6 /* 12 bit GOT offset. */ +#define R_390_GOT32 7 /* 32 bit GOT offset. */ +#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ +#define R_390_COPY 9 /* Copy symbol at runtime. */ +#define R_390_GLOB_DAT 10 /* Create GOT entry. */ +#define R_390_JMP_SLOT 11 /* Create PLT entry. */ +#define R_390_RELATIVE 12 /* Adjust by program base. */ +#define R_390_GOTOFF 13 /* 32 bit offset to GOT. */ +#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ +#define R_390_GOT16 15 /* 16 bit GOT offset. */ +#define R_390_PC16 16 /* PC relative 16 bit. */ +#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ +#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ +#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ +#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ +#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ +#define R_390_64 22 /* Direct 64 bit. */ +#define R_390_PC64 23 /* PC relative 64 bit. */ +#define R_390_GOT64 24 /* 64 bit GOT offset. */ +#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ +#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ + +/* Keep this the last entry. */ +#define R_390_NUM 27 + +/* CRIS relocations. */ +#define R_CRIS_NONE 0 +#define R_CRIS_8 1 +#define R_CRIS_16 2 +#define R_CRIS_32 3 +#define R_CRIS_8_PCREL 4 +#define R_CRIS_16_PCREL 5 +#define R_CRIS_32_PCREL 6 +#define R_CRIS_GNU_VTINHERIT 7 +#define R_CRIS_GNU_VTENTRY 8 +#define R_CRIS_COPY 9 +#define R_CRIS_GLOB_DAT 10 +#define R_CRIS_JUMP_SLOT 11 +#define R_CRIS_RELATIVE 12 +#define R_CRIS_16_GOT 13 +#define R_CRIS_32_GOT 14 +#define R_CRIS_16_GOTPLT 15 +#define R_CRIS_32_GOTPLT 16 +#define R_CRIS_32_GOTREL 17 +#define R_CRIS_32_PLT_GOTREL 18 +#define R_CRIS_32_PLT_PCREL 19 + +#define R_CRIS_NUM 20 + +/* AMD x86-64 relocations. */ +#define R_X86_64_NONE 0 /* No reloc */ +#define R_X86_64_64 1 /* Direct 64 bit */ +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative + offset to GOT */ +#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ +#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset + to two GOT entries for GD symbol */ +#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset + to two GOT entries for LD symbol */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define r_x86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset + to GOT entry for IE symbol */ +#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ + +#define R_X86_64_NUM 24 + +#endif /* ! PUPA_ELF_H */ diff --git a/include/grub/err.h b/include/grub/err.h new file mode 100644 index 000000000..4524fc13e --- /dev/null +++ b/include/grub/err.h @@ -0,0 +1,59 @@ +/* err.h - error numbers and prototypes */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_ERR_HEADER +#define PUPA_ERR_HEADER 1 + +#include + +typedef enum + { + PUPA_ERR_NONE = 0, + PUPA_ERR_BAD_MODULE, + PUPA_ERR_OUT_OF_MEMORY, + PUPA_ERR_BAD_FILE_TYPE, + PUPA_ERR_FILE_NOT_FOUND, + PUPA_ERR_FILE_READ_ERROR, + PUPA_ERR_BAD_FILENAME, + PUPA_ERR_UNKNOWN_FS, + PUPA_ERR_BAD_FS, + PUPA_ERR_BAD_NUMBER, + PUPA_ERR_OUT_OF_RANGE, + PUPA_ERR_UNKNOWN_DEVICE, + PUPA_ERR_BAD_DEVICE, + PUPA_ERR_READ_ERROR, + PUPA_ERR_WRITE_ERROR, + PUPA_ERR_BAD_ARGUMENT, + PUPA_ERR_BAD_PART_TABLE, + PUPA_ERR_UNKNOWN_OS, + PUPA_ERR_BAD_OS, + PUPA_ERR_NO_KERNEL, + PUPA_ERR_NOT_IMPLEMENTED_YET, + } +pupa_err_t; + +extern pupa_err_t EXPORT_VAR(pupa_errno); +extern char EXPORT_VAR(pupa_errmsg)[]; + +pupa_err_t EXPORT_FUNC(pupa_error) (pupa_err_t n, const char *fmt, ...); +void EXPORT_FUNC(pupa_fatal) (const char *fmt, ...) __attribute__ ((noreturn)); +void EXPORT_FUNC(pupa_print_error) (void); + +#endif /* ! PUPA_ERR_HEADER */ diff --git a/include/grub/file.h b/include/grub/file.h new file mode 100644 index 000000000..5e3a5e64f --- /dev/null +++ b/include/grub/file.h @@ -0,0 +1,73 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_FILE_HEADER +#define PUPA_FILE_HEADER 1 + +#include +#include +#include +#include + +/* File description. */ +struct pupa_file +{ + /* The underlying device. */ + pupa_device_t device; + + /* The underlying filesystem. */ + pupa_fs_t fs; + + /* The current offset. */ + pupa_ssize_t offset; + + /* The file size. */ + pupa_ssize_t size; + + /* Filesystem-specific data. */ + void *data; + + /* This is called when a sector is read. Used only for a disk device. */ + void (*read_hook) (unsigned long sector, unsigned offset, unsigned length); +}; +typedef struct pupa_file *pupa_file_t; + +/* Get a device name from NAME. */ +char *EXPORT_FUNC(pupa_file_get_device_name) (const char *name); + +pupa_file_t EXPORT_FUNC(pupa_file_open) (const char *name); +pupa_ssize_t EXPORT_FUNC(pupa_file_read) (pupa_file_t file, char *buf, + pupa_ssize_t len); +pupa_ssize_t EXPORT_FUNC(pupa_file_seek) (pupa_file_t file, + pupa_ssize_t offset); +pupa_err_t EXPORT_FUNC(pupa_file_close) (pupa_file_t file); + +static inline pupa_ssize_t +pupa_file_size (const pupa_file_t file) +{ + return file->size; +} + +static inline pupa_ssize_t +pupa_file_tell (const pupa_file_t file) +{ + return file->offset; +} + +#endif /* ! PUPA_FILE_HEADER */ diff --git a/include/grub/fs.h b/include/grub/fs.h new file mode 100644 index 000000000..079bb68a9 --- /dev/null +++ b/include/grub/fs.h @@ -0,0 +1,63 @@ +/* fs.h - filesystem manager */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_FS_HEADER +#define PUPA_FS_HEADER 1 + +#include +#include +#include + +/* Forward declaration is required, because of mutual reference. */ +struct pupa_file; + +/* Filesystem descriptor. */ +struct pupa_fs +{ + /* My name. */ + const char *name; + + /* Call HOOK with each file under DIR. */ + pupa_err_t (*dir) (pupa_device_t device, const char *path, + int (*hook) (const char *filename, int dir)); + + /* Open a file named NAME and initialize FILE. */ + pupa_err_t (*open) (struct pupa_file *file, const char *name); + + /* Read LEN bytes data from FILE into BUF. */ + pupa_ssize_t (*read) (struct pupa_file *file, char *buf, pupa_ssize_t len); + + /* Close the file FILE. */ + pupa_err_t (*close) (struct pupa_file *file); + + /* The next filesystem. */ + struct pupa_fs *next; +}; +typedef struct pupa_fs *pupa_fs_t; + +/* This is special, because block lists are not files in usual sense. */ +extern struct pupa_fs pupa_fs_blocklist; + +void EXPORT_FUNC(pupa_fs_register) (pupa_fs_t fs); +void EXPORT_FUNC(pupa_fs_unregister) (pupa_fs_t fs); +void EXPORT_FUNC(pupa_fs_iterate) (int (*hook) (const pupa_fs_t fs)); +pupa_fs_t EXPORT_FUNC(pupa_fs_probe) (pupa_device_t device); + +#endif /* ! PUPA_FS_HEADER */ diff --git a/include/grub/i386/pc/biosdisk.h b/include/grub/i386/pc/biosdisk.h new file mode 100644 index 000000000..0260b9654 --- /dev/null +++ b/include/grub/i386/pc/biosdisk.h @@ -0,0 +1,47 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_BIOSDISK_MACHINE_HEADER +#define PUPA_BIOSDISK_MACHINE_HEADER 1 + +#define PUPA_BIOSDISK_FLAG_LBA 1 + +struct pupa_biosdisk_data +{ + int drive; + unsigned long cylinders; + unsigned long heads; + unsigned long sectors; + unsigned long flags; +}; + +int pupa_biosdisk_rw_int13_extensions (int ah, int drive, void *dap); +int pupa_biosdisk_rw_standard (int ah, int drive, int coff, int hoff, + int soff, int nsec, int segment); +int pupa_biosdisk_check_int13_extensions (int drive); +int pupa_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp); +int pupa_biosdisk_get_diskinfo_standard (int drive, + unsigned long *cylinders, + unsigned long *heads, + unsigned long *sectors); +int pupa_biosdisk_get_num_floppies (void); + +void pupa_biosdisk_init (void); + +#endif /* ! PUPA_BIOSDISK_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h new file mode 100644 index 000000000..b269e72a0 --- /dev/null +++ b/include/grub/i386/pc/boot.h @@ -0,0 +1,83 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 1999, 2000 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_BOOT_MACHINE_HEADER +#define PUPA_BOOT_MACHINE_HEADER 1 + +/* The signature for bootloader. */ +#define PUPA_BOOT_MACHINE_SIGNATURE 0xaa55 + +/* The offset of the end of BPB (BIOS Parameter Block). */ +#define PUPA_BOOT_MACHINE_BPBEND 0x3e + +/* The offset of the major version. */ +#define PUPA_BOOT_MACHINE_VER_MAJ 0x3e + +/* The offset of BOOT_DRIVE. */ +#define PUPA_BOOT_MACHINE_BOOT_DRIVE 0x40 + +/* The offset of FORCE_LBA. */ +#define PUPA_BOOT_MACHINE_FORCE_LBA 0x41 + +/* The offset of KERNEL_ADDRESS. */ +#define PUPA_BOOT_MACHINE_KERNEL_ADDRESS 0x42 + +/* The offset of KERNEL_SECTOR. */ +#define PUPA_BOOT_MACHINE_KERNEL_SECTOR 0x44 + +/* The offset of KERNEL_SEGMENT. */ +#define PUPA_BOOT_MACHINE_KERNEL_SEGMENT 0x48 + +/* The offset of a magic number used by Windows NT. */ +#define PUPA_BOOT_MACHINE_WINDOWS_NT_MAGIC 0x1b8 + +/* The offset of the start of the partition table. */ +#define PUPA_BOOT_MACHINE_PART_START 0x1be + +/* The offset of the end of the partition table. */ +#define PUPA_BOOT_MACHINE_PART_END 0x1fe + +/* The stack segment. */ +#define PUPA_BOOT_MACHINE_STACK_SEG 0x2000 + +/* The segment of disk buffer. The disk buffer MUST be 32K long and + cannot straddle a 64K boundary. */ +#define PUPA_BOOT_MACHINE_BUFFER_SEG 0x7000 + +/* The address of drive parameters. */ +#define PUPA_BOOT_MACHINE_DRP_ADDR 0x7f00 + +/* The size of drive parameters. */ +#define PUPA_BOOT_MACHINE_DRP_SIZE 0x42 + +/* The flag for BIOS drive number to designate a hard disk vs. a + floppy. */ +#define PUPA_BOOT_MACHINE_BIOS_HD_FLAG 0x80 + +/* The segment where the kernel is loaded. */ +#define PUPA_BOOT_MACHINE_KERNEL_SEG 0x800 + +/* The address where the kernel is loaded. */ +#define PUPA_BOOT_MACHINE_KERNEL_ADDR (PUPA_BOOT_MACHINE_KERNEL_SEG << 4) + +/* The size of a block list used in the kernel startup code. */ +#define PUPA_BOOT_MACHINE_LIST_SIZE 8 + +#endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h new file mode 100644 index 000000000..69601e5d5 --- /dev/null +++ b/include/grub/i386/pc/console.h @@ -0,0 +1,55 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_CONSOLE_MACHINE_HEADER +#define PUPA_CONSOLE_MACHINE_HEADER 1 + +/* Define scan codes. */ +#define PUPA_CONSOLE_KEY_LEFT 0x4B00 +#define PUPA_CONSOLE_KEY_RIGHT 0x4D00 +#define PUPA_CONSOLE_KEY_UP 0x4800 +#define PUPA_CONSOLE_KEY_DOWN 0x5000 +#define PUPA_CONSOLE_KEY_IC 0x5200 +#define PUPA_CONSOLE_KEY_DC 0x5300 +#define PUPA_CONSOLE_KEY_BACKSPACE 0x0008 +#define PUPA_CONSOLE_KEY_HOME 0x4700 +#define PUPA_CONSOLE_KEY_END 0x4F00 +#define PUPA_CONSOLE_KEY_NPAGE 0x4900 +#define PUPA_CONSOLE_KEY_PPAGE 0x5100 + +#ifndef ASM_FILE + +#include + +/* These are global to share code between C and asm. */ +extern pupa_uint8_t pupa_console_cur_color; +void pupa_console_putchar (int c); +int pupa_console_checkkey (void); +int pupa_console_getkey (void); +pupa_uint16_t pupa_console_getxy (void); +void pupa_console_gotoxy (pupa_uint8_t x, pupa_uint8_t y); +void pupa_console_cls (void); +void pupa_console_setcursor (int on); + +/* Initialize the console system. */ +void pupa_console_init (void); + +#endif + +#endif /* ! PUPA_CONSOLE_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/init.h b/include/grub/i386/pc/init.h new file mode 100644 index 000000000..cb9128607 --- /dev/null +++ b/include/grub/i386/pc/init.h @@ -0,0 +1,50 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_INIT_MACHINE_HEADER +#define PUPA_INIT_MACHINE_HEADER 1 + +#include +#include + +/* Get the memory size in KB. If EXTENDED is zero, return conventional + memory, otherwise return extended memory. */ +pupa_uint16_t pupa_get_memsize (int extended); + +/* Get a packed EISA memory map. Lower 16 bits are between 1MB and 16MB + in 1KB parts, and upper 16 bits are above 16MB in 64KB parts. */ +pupa_uint32_t pupa_get_eisa_mmap (void); + +struct pupa_machine_mmap_entry +{ + pupa_uint32_t size; + pupa_uint64_t addr; + pupa_uint64_t len; + pupa_uint32_t type; +}; + +/* Get a memory map entry. Return next continuation value. Zero means + the end. */ +pupa_uint32_t pupa_get_mmap_entry (struct pupa_machine_mmap_entry *entry, + pupa_uint32_t cont); + +/* Turn on/off Gate A20. */ +void EXPORT_FUNC(pupa_gate_a20) (int on); + +#endif /* ! PUPA_INIT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h new file mode 100644 index 000000000..d6928d3c7 --- /dev/null +++ b/include/grub/i386/pc/kernel.h @@ -0,0 +1,29 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef KERNEL_MACHINE_HEADER +#define KERNEL_MACHINE_HEADER 1 + +/* The offset of PUPA_TOTAL_MODULE_SIZE. */ +#define PUPA_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 + +/* The offset of PUPA_KERNEL_IMAGE_SIZE. */ +#define PUPA_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc + +#endif /* ! KERNEL_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/loader.h b/include/grub/i386/pc/loader.h new file mode 100644 index 000000000..d2dcc9136 --- /dev/null +++ b/include/grub/i386/pc/loader.h @@ -0,0 +1,29 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_LOADER_MACHINE_HEADER +#define PUPA_LOADER_MACHINE_HEADER 1 + +#include +#include + +/* This is an asm part of the chainloader. */ +void EXPORT_FUNC(pupa_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn)); + +#endif /* ! PUPA_LOADER_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h new file mode 100644 index 000000000..d22f8b6cb --- /dev/null +++ b/include/grub/i386/pc/memory.h @@ -0,0 +1,67 @@ +/* memory.h - describe the memory map */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_MEMORY_MACHINE_HEADER +#define PUPA_MEMORY_MACHINE_HEADER 1 + +/* The scratch buffer used in real mode code. */ +#define PUPA_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 +#define PUPA_MEMORY_MACHINE_SCRATCH_SEG (PUPA_MEMORY_MACHINE_SCRATCH_ADDR >> 4) +#define PUPA_MEMORY_MACHINE_SCRATCH_SIZE 0x10000 + +/* The real mode stack. */ +#define PUPA_MEMORY_MACHINE_REAL_STACK (0x2000 - 0x10) + +/* The size of the protect mode stack. */ +#define PUPA_MEMORY_MACHINE_PROT_STACK_SIZE 0x8000 + +/* The protected mode stack. */ +#define PUPA_MEMORY_MACHINE_PROT_STACK \ + (PUPA_MEMORY_MACHINE_SCRATCH_ADDR + PUPA_MEMORY_MACHINE_SCRATCH_SIZE \ + + PUPA_MEMORY_MACHINE_PROT_STACK_SIZE - 0x10) + +/* The memory area where PUPA uses its own purpose. */ +#define PUPA_MEMORY_MACHINE_RESERVED_START \ + PUPA_MEMORY_MACHINE_SCRATCH_ADDR +#define PUPA_MEMORY_MACHINE_RESERVED_END \ + (PUPA_MEMORY_MACHINE_PROT_STACK + 0x10) + +/* The address of a partition table passed to another boot loader. */ +#define PUPA_MEMORY_MACHINE_PART_TABLE_ADDR 0x7be + +/* The address where another boot loader is loaded. */ +#define PUPA_MEMORY_MACHINE_BOOT_LOADER_ADDR 0x7c00 + +/* The flag for protected mode. */ +#define PUPA_MEMORY_MACHINE_CR0_PE_ON 0x1 + +/* The code segment of the protected mode. */ +#define PUPA_MEMORY_MACHINE_PROT_MODE_CSEG 0x8 + +/* The data segment of the protected mode. */ +#define PUPA_MEMORY_MACHINE_PROT_MODE_DSEG 0x10 + +/* The code segment of the pseudo real mode. */ +#define PUPA_MEMORY_MACHINE_PSEUDO_REAL_CSEG 0x18 + +/* The data segment of the pseudo real mode. */ +#define PUPA_MEMORY_MACHINE_PSEUDO_REAL_DSEG 0x20 + +#endif /* ! PUPA_MEMORY_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/partition.h b/include/grub/i386/pc/partition.h new file mode 100644 index 000000000..10113a438 --- /dev/null +++ b/include/grub/i386/pc/partition.h @@ -0,0 +1,243 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_PARTITION_HEADER +#define PUPA_PARTITION_HEADER 1 + +#include +#include +#include + +/* The signature. */ +#define PUPA_PARTITION_SIGNATURE 0xaa55 + +/* This is not a flag actually, but used as if it were a flag. */ +#define PUPA_PARTITION_TYPE_HIDDEN_FLAG 0x10 + +/* DOS partition types. */ +#define PUPA_PARTITION_TYPE_NONE 0 +#define PUPA_PARTITION_TYPE_FAT12 1 +#define PUPA_PARTITION_TYPE_FAT16_LT32M 4 +#define PUPA_PARTITION_TYPE_EXTENDED 5 +#define PUPA_PARTITION_TYPE_FAT16_GT32M 6 +#define PUPA_PARTITION_TYPE_FAT32 0xb +#define PUPA_PARTITION_TYPE_FAT32_LBA 0xc +#define PUPA_PARTITION_TYPE_FAT16_LBA 0xe +#define PUPA_PARTITION_TYPE_WIN95_EXTENDED 0xf +#define PUPA_PARTITION_TYPE_EZD 0x55 +#define PUPA_PARTITION_TYPE_MINIX 0x80 +#define PUPA_PARTITION_TYPE_LINUX_MINIX 0x81 +#define PUPA_PARTITION_TYPE_EXT2FS 0x83 +#define PUPA_PARTITION_TYPE_LINUX_EXTENDED 0x85 +#define PUPA_PARTITION_TYPE_VSTAFS 0x9e +#define PUPA_PARTITION_TYPE_FREEBSD 0xa5 +#define PUPA_PARTITION_TYPE_OPENBSD 0xa6 +#define PUPA_PARTITION_TYPE_NETBSD 0xa9 +#define PUPA_PARTITION_TYPE_LINUX_RAID 0xfd + +/* Constants for BSD disk label. */ +#define PUPA_PARTITION_BSD_LABEL_SECTOR 1 +#define PUPA_PARTITION_BSD_LABEL_MAGIC 0x82564557 +#define PUPA_PARTITION_BSD_MAX_ENTRIES 8 + +/* BSD partition types. */ +#define PUPA_PARTITION_BSD_TYPE_UNUSED 0 +#define PUPA_PARTITION_BSD_TYPE_SWAP 1 +#define PUPA_PARTITION_BSD_TYPE_V6 2 +#define PUPA_PARTITION_BSD_TYPE_V7 3 +#define PUPA_PARTITION_BSD_TYPE_SYSV 4 +#define PUPA_PARTITION_BSD_TYPE_V71K 5 +#define PUPA_PARTITION_BSD_TYPE_V8 6 +#define PUPA_PARTITION_BSD_TYPE_BSDFFS 7 +#define PUPA_PARTITION_BSD_TYPE_MSDOS 8 +#define PUPA_PARTITION_BSD_TYPE_BSDLFS 9 +#define PUPA_PARTITION_BSD_TYPE_OTHER 10 +#define PUPA_PARTITION_BSD_TYPE_HPFS 11 +#define PUPA_PARTITION_BSD_TYPE_ISO9660 12 +#define PUPA_PARTITION_BSD_TYPE_BOOT 13 + +/* FreeBSD-specific types. */ +#define PUPA_PARTITION_FREEBSD_TYPE_VINUM 14 +#define PUPA_PARTITION_FREEBSD_TYPE_RAID 15 +#define PUPA_PARTITION_FREEBSD_TYPE_JFS2 21 + +/* NetBSD-specific types. */ +#define PUPA_PARTITION_NETBSD_TYPE_ADOS 14 +#define PUPA_PARTITION_NETBSD_TYPE_HFS 15 +#define PUPA_PARTITION_NETBSD_TYPE_FILECORE 16 +#define PUPA_PARTITION_NETBSD_TYPE_EXT2FS 17 +#define PUPA_PARTITION_NETBSD_TYPE_NTFS 18 +#define PUPA_PARTITION_NETBSD_TYPE_RAID 19 +#define PUPA_PARTITION_NETBSD_TYPE_CCD 20 +#define PUPA_PARTITION_NETBSD_TYPE_JFS2 21 +#define PUPA_PARTITION_NETBSD_TYPE_APPLEUFS 22 + +/* OpenBSD-specific types. */ +#define PUPA_PARTITION_OPENBSD_TYPE_ADOS 14 +#define PUPA_PARTITION_OPENBSD_TYPE_HFS 15 +#define PUPA_PARTITION_OPENBSD_TYPE_FILECORE 16 +#define PUPA_PARTITION_OPENBSD_TYPE_EXT2FS 17 +#define PUPA_PARTITION_OPENBSD_TYPE_NTFS 18 +#define PUPA_PARTITION_OPENBSD_TYPE_RAID 19 + +/* The BSD partition entry. */ +struct pupa_partition_bsd_entry +{ + pupa_uint32_t size; + pupa_uint32_t offset; + pupa_uint32_t fragment_size; + pupa_uint8_t fs_type; + pupa_uint8_t fs_fragments; + pupa_uint16_t fs_cylinders; +} __attribute__ ((packed)); + +/* The BSD disk label. Only define members useful for PUPA. */ +struct pupa_partition_disk_label +{ + pupa_uint32_t magic; + pupa_uint8_t padding[128]; + pupa_uint32_t magic2; + pupa_uint16_t checksum; + pupa_uint16_t num_partitions; + pupa_uint32_t boot_size; + pupa_uint32_t superblock_size; + struct pupa_partition_bsd_entry entries[PUPA_PARTITION_BSD_MAX_ENTRIES]; +} __attribute__ ((packed)); + +/* The partition entry. */ +struct pupa_partition_entry +{ + /* If active, 0x80, otherwise, 0x00. */ + pupa_uint8_t flag; + + /* The head of the start. */ + pupa_uint8_t start_head; + + /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C + is the cylinder of the start. Note that S is counted from one. */ + pupa_uint8_t start_sector; + + /* (C & 0xFF) where C is the cylinder of the start. */ + pupa_uint8_t start_cylinder; + + /* The partition type. */ + pupa_uint8_t type; + + /* The end versions of start_head, start_sector and start_cylinder, + respectively. */ + pupa_uint8_t end_head; + pupa_uint8_t end_sector; + pupa_uint8_t end_cylinder; + + /* The start sector. Note that this is counted from zero. */ + pupa_uint32_t start; + + /* The length in sector units. */ + pupa_uint32_t length; +} __attribute__ ((packed)); + +/* The structure of MBR. */ +struct pupa_partition_mbr +{ + /* The code area (actually, including BPB). */ + pupa_uint8_t code[446]; + + /* Four partition entries. */ + struct pupa_partition_entry entries[4]; + + /* The signature 0xaa55. */ + pupa_uint16_t signature; +} __attribute__ ((packed)); + +/* Partition description. */ +struct pupa_partition +{ + /* The start sector. */ + unsigned long start; + + /* The length in sector units. */ + unsigned long len; + + /* The offset of the partition table. */ + unsigned long offset; + + /* The offset of the extended partition. */ + unsigned long ext_offset; + + /* The index of this partition in the partition table. */ + int index; + + /* The DOS partition number. */ + int dos_part; + + /* The BSD partition number (a == 0). */ + int bsd_part; + + /* The DOS partition type. */ + int dos_type; + + /* The BSD partition type. */ + int bsd_type; +}; +typedef struct pupa_partition *pupa_partition_t; + +struct pupa_disk; + +pupa_partition_t EXPORT_FUNC(pupa_partition_probe) (struct pupa_disk *disk, + const char *str); +pupa_err_t EXPORT_FUNC(pupa_partition_iterate) (struct pupa_disk *disk, + int (*hook) (const pupa_partition_t partition)); +char *EXPORT_FUNC(pupa_partition_get_name) (const pupa_partition_t partition); + +static inline unsigned long +pupa_partition_get_start (const pupa_partition_t p) +{ + return p->start; +} + +static inline unsigned long +pupa_partition_get_len (const pupa_partition_t p) +{ + return p->len; +} + +static inline int +pupa_partition_is_empty (int type) +{ + return (type == PUPA_PARTITION_TYPE_NONE); +} + +static inline int +pupa_partition_is_extended (int type) +{ + return (type == PUPA_PARTITION_TYPE_EXTENDED + || type == PUPA_PARTITION_TYPE_WIN95_EXTENDED + || type == PUPA_PARTITION_TYPE_LINUX_EXTENDED); +} + +static inline int +pupa_partition_is_bsd (int type) +{ + return (type == PUPA_PARTITION_TYPE_FREEBSD + || type == PUPA_PARTITION_TYPE_OPENBSD + || type == PUPA_PARTITION_TYPE_NETBSD); +} + +#endif /* ! PUPA_PARTITION_HEADER */ diff --git a/include/grub/i386/types.h b/include/grub/i386/types.h new file mode 100644 index 000000000..bc49cd6de --- /dev/null +++ b/include/grub/i386/types.h @@ -0,0 +1,32 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_TYPES_CPU_HEADER +#define PUPA_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define PUPA_HOST_SIZEOF_VOID_P 4 + +/* The size of long. */ +#define PUPA_HOST_SIZEOF_LONG 4 + +/* i386 is little-endian. */ +#undef PUPA_HOST_WORDS_BIGENDIAN + +#endif /* ! PUPA_TYPES_CPU_HEADER */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h new file mode 100644 index 000000000..4d5a06c90 --- /dev/null +++ b/include/grub/kernel.h @@ -0,0 +1,61 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_KERNEL_HEADER +#define PUPA_KERNEL_HEADER 1 + +#include + +/* The module header. */ +struct pupa_module_header +{ + /* The offset of object code. */ + pupa_off_t offset; + /* The size of object code plus this header. */ + pupa_size_t size; +}; + +/* The start address of the kernel. */ +extern pupa_addr_t pupa_start_addr; + +/* The end address of the kernel. */ +extern pupa_addr_t pupa_end_addr; + +/* The total size of modules including their headers. */ +extern pupa_size_t pupa_total_module_size; + +/* The size of the kernel image. */ +extern pupa_size_t pupa_kernel_image_size; + +/* The start point of the C code. */ +void pupa_main (void); + +/* The machine-specific initialization. This must initialize memory. */ +void pupa_machine_init (void); + +/* Return the end address of the core image. */ +pupa_addr_t pupa_get_end_addr (void); + +/* Register all the exported symbols. This is automatically generated. */ +void pupa_register_exported_symbols (void); + +/* Enter normal mode. */ +void pupa_enter_normal_mode (void); + +#endif /* ! PUPA_KERNEL_HEADER */ diff --git a/include/grub/loader.h b/include/grub/loader.h new file mode 100644 index 000000000..ea2d049cd --- /dev/null +++ b/include/grub/loader.h @@ -0,0 +1,37 @@ +/* loader.h - OS loaders */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_LOADER_HEADER +#define PUPA_LOADER_HEADER 1 + +#include +#include +#include +#include + +void EXPORT_FUNC(pupa_loader_set) (pupa_err_t (*load_module) (int argc, + char *argv[]), + pupa_err_t (*boot) (void), + pupa_err_t (*unload) (void)); + +pupa_err_t EXPORT_FUNC(pupa_loader_load_module) (int argc, char *argv[]); +pupa_err_t EXPORT_FUNC(pupa_loader_boot) (void); + +#endif /* ! PUPA_LOADER_HEADER */ diff --git a/include/grub/misc.h b/include/grub/misc.h new file mode 100644 index 000000000..fa2832245 --- /dev/null +++ b/include/grub/misc.h @@ -0,0 +1,47 @@ +/* misc.h - prototypes for misc functions */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_MISC_HEADER +#define PUPA_MISC_HEADER 1 + +#include +#include +#include + +void *EXPORT_FUNC(pupa_memcpy) (void *dest, const void *src, pupa_size_t n); +int EXPORT_FUNC(pupa_memcmp) (const void *s1, const void *s2, pupa_size_t n); +int EXPORT_FUNC(pupa_strcmp) (const char *s1, const char *s2); +char *EXPORT_FUNC(pupa_strchr) (const char *s, int c); +char *EXPORT_FUNC(pupa_strrchr) (const char *s, int c); +int EXPORT_FUNC(pupa_isspace) (int c); +int EXPORT_FUNC(pupa_isprint) (int c); +int EXPORT_FUNC(pupa_isalpha) (int c); +int EXPORT_FUNC(pupa_tolower) (int c); +unsigned long EXPORT_FUNC(pupa_strtoul) (const char *str, char **end, int base); +char *EXPORT_FUNC(pupa_strdup) (const char *s); +void *EXPORT_FUNC(pupa_memset) (void *s, int c, pupa_size_t n); +pupa_size_t EXPORT_FUNC(pupa_strlen) (const char *s); +int EXPORT_FUNC(pupa_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +int EXPORT_FUNC(pupa_vprintf) (const char *fmt, va_list args); +int EXPORT_FUNC(pupa_sprintf) (char *str, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +int EXPORT_FUNC(pupa_vsprintf) (char *str, const char *fmt, va_list args); +void EXPORT_FUNC(pupa_stop) (void) __attribute__ ((noreturn)); + +#endif /* ! PUPA_MISC_HEADER */ diff --git a/include/grub/mm.h b/include/grub/mm.h new file mode 100644 index 000000000..2033574dc --- /dev/null +++ b/include/grub/mm.h @@ -0,0 +1,39 @@ +/* mm.h - prototypes and declarations for memory manager */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_MM_H +#define PUPA_MM_H 1 + +#include +#include + +void pupa_mm_init_region (void *addr, unsigned size); +void *EXPORT_FUNC(pupa_malloc) (unsigned size); +void EXPORT_FUNC(pupa_free) (void *ptr); +void *EXPORT_FUNC(pupa_realloc) (void *ptr, unsigned size); +void *EXPORT_FUNC(pupa_memalign) (unsigned align, unsigned size); + +/* For debugging. */ +#define MM_DEBUG 1 +#if MM_DEBUG +void pupa_mm_dump (unsigned lineno); +#endif + +#endif /* ! PUPA_MM_H */ diff --git a/include/grub/net.h b/include/grub/net.h new file mode 100644 index 000000000..e7cbcb6d2 --- /dev/null +++ b/include/grub/net.h @@ -0,0 +1,73 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_NET_HEADER +#define PUPA_NET_HEADER 1 + +#include +#include +#include + +struct pupa_net; + +struct pupa_net_dev +{ + /* The device name. */ + const char *name; + + /* FIXME: Just a template. */ + int (*probe) (struct pupa_net *net, const void *addr); + void (*reset) (struct pupa_net *net); + int (*poll) (struct pupa_net *net); + void (*transmit) (struct pupa_net *net, const void *destip, + unsigned srcsock, unsigned destsock, const void *packet); + void (*disable) (struct pupa_net *net); + + /* The next net device. */ + struct pupa_net_dev *next; +}; +typedef struct pupa_net_dev *pupa_net_dev_t; + +struct pupa_fs; + +struct pupa_net +{ + /* The net name. */ + const char *name; + + /* The underlying disk device. */ + pupa_net_dev_t dev; + + /* The binding filesystem. */ + struct pupa_fs *fs; + + /* FIXME: More data would be required, such as an IP address, a mask, + a gateway, etc. */ + + /* Device-specific data. */ + void *data; +}; +typedef struct pupa_net *pupa_net_t; + +/* FIXME: How to abstract networks? More consideration is necessary. */ + +/* Note: Networks are very different from disks, because networks must + be initialized before used, and the status is persistent. */ + +#endif /* ! PUPA_NET_HEADER */ diff --git a/include/grub/rescue.h b/include/grub/rescue.h new file mode 100644 index 000000000..bf102678f --- /dev/null +++ b/include/grub/rescue.h @@ -0,0 +1,37 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_RESCUE_HEADER +#define PUPA_RESCUE_HEADER 1 + +#include + +/* Enter rescue mode. */ +void pupa_enter_rescue_mode (void); + +/* Register a rescue mode command. */ +void EXPORT_FUNC(pupa_rescue_register_command) (const char *name, + void (*func) (int argc, + char *argv[]), + const char *message); + +/* Unregister a rescue mode command. */ +void EXPORT_FUNC(pupa_rescue_unregister_command) (const char *name); + +#endif /* ! PUPA_RESCUE_HEADER */ diff --git a/include/grub/symbol.h b/include/grub/symbol.h new file mode 100644 index 000000000..c51df2600 --- /dev/null +++ b/include/grub/symbol.h @@ -0,0 +1,40 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_SYMBOL_HEADER +#define PUPA_SYMBOL_HEADER 1 + +#include + +/* Add an underscore to a C symbol in assembler code if needed. */ +#ifdef HAVE_ASM_USCORE +# define EXT_C(sym) _ ## sym +#else +# define EXT_C(sym) sym +#endif + +#define FUNCTION(x) .globl EXT_C(x) ; EXT_C(x): +#define VARIABLE(x) FUNCTION(x) + +/* Mark an exported symbol. */ +#define EXPORT_FUNC(x) x +#define EXPORT_VAR(x) x + +#endif /* ! PUPA_SYMBOL_HEADER */ diff --git a/include/grub/term.h b/include/grub/term.h new file mode 100644 index 000000000..87b285dec --- /dev/null +++ b/include/grub/term.h @@ -0,0 +1,120 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_TERM_HEADER +#define PUPA_TERM_HEADER 1 + +#include +#include + +/* These are used to represent the various color states we use. */ +typedef enum + { + /* The color used to display all text that does not use the + user defined colors below. */ + PUPA_TERM_COLOR_STANDARD, + /* The user defined colors for normal text. */ + PUPA_TERM_COLOR_NORMAL, + /* The user defined colors for highlighted text. */ + PUPA_TERM_COLOR_HIGHLIGHT + } +pupa_term_color_state; + +/* Flags for representing the capabilities of a terminal. */ +/* Some notes about the flags: + - These flags are used by higher-level functions but not terminals + themselves. + - If a terminal is dumb, you may assume that only putchar, getkey and + checkkey are called. + - Some fancy features (setcolorstate, setcolor and setcursor) can be set + to NULL. */ + +/* Set when input characters shouldn't be echoed back. */ +#define PUPA_TERM_NO_ECHO (1 << 0) +/* Set when the editing feature should be disabled. */ +#define PUPA_TERM_NO_EDIT (1 << 1) +/* Set when the terminal cannot do fancy things. */ +#define PUPA_TERM_DUMB (1 << 2) +/* Set when the terminal needs to be initialized. */ +#define PUPA_TERM_NEED_INIT (1 << 16) + +struct pupa_term +{ + /* The terminal name. */ + const char *name; + + /* Put a character. */ + void (*putchar) (int c); + + /* Check if any input character is available. */ + int (*checkkey) (void); + + /* Get a character. */ + int (*getkey) (void); + + /* Get the cursor position. The return value is ((X << 8) | Y). */ + pupa_uint16_t (*getxy) (void); + + /* Go to the position (X, Y). */ + void (*gotoxy) (pupa_uint8_t x, pupa_uint8_t y); + + /* Clear the screen. */ + void (*cls) (void); + + /* Set the current color to be used */ + void (*setcolorstate) (pupa_term_color_state state); + + /* Set the normal color and the highlight color. The format of each + color is VGA's. */ + void (*setcolor) (pupa_uint8_t normal_color, pupa_uint8_t highlight_color); + + /* Turn on/off the cursor. */ + void (*setcursor) (int on); + + /* The feature flags defined above. */ + pupa_uint32_t flags; + + /* The next terminal. */ + struct pupa_term *next; +}; +typedef struct pupa_term *pupa_term_t; + +void EXPORT_FUNC(pupa_term_register) (pupa_term_t term); +void EXPORT_FUNC(pupa_term_unregister) (pupa_term_t term); +void EXPORT_FUNC(pupa_term_iterate) (int (*hook) (pupa_term_t term)); + +void EXPORT_FUNC(pupa_term_set_current) (pupa_term_t term); +pupa_term_t EXPORT_FUNC(pupa_term_get_current) (void); + +void EXPORT_FUNC(pupa_putchar) (int c); +int EXPORT_FUNC(pupa_getkey) (void); +int EXPORT_FUNC(pupa_checkkey) (void); +pupa_uint16_t EXPORT_FUNC(pupa_getxy) (void); +void EXPORT_FUNC(pupa_gotoxy) (pupa_uint8_t x, pupa_uint8_t y); +void EXPORT_FUNC(pupa_cls) (void); +void EXPORT_FUNC(pupa_setcolorstate) (pupa_term_color_state state); +void EXPORT_FUNC(pupa_setcolor) (pupa_uint8_t normal_color, + pupa_uint8_t highlight_color); +int EXPORT_FUNC(pupa_setcursor) (int on); + +/* For convenience. */ +#define PUPA_TERM_ASCII_CHAR(c) ((c) & 0xff) + +#endif /* ! PUPA_TERM_HEADER */ diff --git a/include/grub/types.h b/include/grub/types.h new file mode 100644 index 000000000..0dda38486 --- /dev/null +++ b/include/grub/types.h @@ -0,0 +1,141 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + +#ifndef PUPA_TYPES_HEADER +#define PUPA_TYPES_HEADER 1 + +#include +#include + +#ifdef PUPA_UTIL +# define PUPA_CPU_SIZEOF_VOID_P SIZEOF_VOID_P +# define PUPA_CPU_SIZEOF_LONG SIZEOF_LONG +# ifdef WORDS_BIGENDIAN +# define PUPA_CPU_WORDS_BIGENDIAN 1 +# else +# undef PUPA_CPU_WORDS_BIGENDIAN +# endif +#else /* ! PUPA_UTIL */ +# define PUPA_CPU_SIZEOF_VOID_P PUPA_HOST_SIZEOF_VOID_P +# define PUPA_CPU_SIZEOF_LONG PUPA_HOST_SIZEOF_LONG +# ifdef PUPA_HOST_WORDS_BIGENDIAN +# define PUPA_CPU_WORDS_BIGENDIAN 1 +# else +# undef PUPA_CPU_WORDS_BIGENDIAN +# endif +#endif /* ! PUPA_UTIL */ + +#if PUPA_CPU_SIZEOF_VOID_P != PUPA_CPU_SIZEOF_LONG +# error "This architecture is not supported because sizeof(void *) != sizeof(long)" +#endif + +#if PUPA_CPU_SIZEOF_VOID_P != 4 && PUPA_CPU_SIZEOF_VOID_P != 8 +# error "This architecture is not supported because sizeof(void *) != 4 and sizeof(void *) != 8" +#endif + +/* Define various wide integers. */ +typedef signed char pupa_int8_t; +typedef short pupa_int16_t; +typedef int pupa_int32_t; +#if PUPA_CPU_SIZEOF_VOID_P == 8 +typedef long pupa_int64_t; +#else +typedef long long pupa_int64_t; +#endif + +typedef unsigned char pupa_uint8_t; +typedef unsigned short pupa_uint16_t; +typedef unsigned pupa_uint32_t; +#if PUPA_CPU_SIZEOF_VOID_P == 8 +typedef unsigned long pupa_uint64_t; +#else +typedef unsigned long long pupa_uint64_t; +#endif + +/* Misc types. */ +#if PUPA_HOST_SIZE_OF_VOID_P == 8 +typedef pupa_uint64_t pupa_addr_t; +typedef pupa_uint64_t pupa_off_t; +typedef pupa_uint64_t pupa_size_t; +typedef pupa_int64_t pupa_ssize_t; +#else +typedef pupa_uint32_t pupa_addr_t; +typedef pupa_uint32_t pupa_off_t; +typedef pupa_uint32_t pupa_size_t; +typedef pupa_int32_t pupa_ssize_t; +#endif + +/* Byte-orders. */ +#define pupa_swap_bytes16(x) \ +({ \ + pupa_uint16_t _x = (x); \ + (_x << 8) | (_x >> 8); \ +}) + +#define pupa_swap_bytes32(x) \ +({ \ + pupa_uint32_t _x = (x); \ + (pupa_uint32_t) ((_x << 24) \ + | ((_x & (pupa_uint32_t) 0xFF00UL) << 8) \ + | ((_x & (pupa_uint32_t) 0xFF0000UL) >> 8) \ + | (_x >> 24)); \ +}) + +#define pupa_swap_bytes64(x) \ +({ \ + pupa_uint64_t _x = (x); \ + (pupa_uint64_t) ((_x << 56) \ + | ((_x & (pupa_uint64_t) 0xFF00ULL) << 40) \ + | ((_x & (pupa_uint64_t) 0xFF0000ULL) << 24) \ + | ((_x & (pupa_uint64_t) 0xFF000000ULL) << 8) \ + | ((_x & (pupa_uint64_t) 0xFF00000000ULL) >> 8) \ + | ((_x & (pupa_uint64_t) 0xFF0000000000ULL) >> 24) \ + | ((_x & (pupa_uint64_t) 0xFF000000000000ULL) >> 40) \ + | (_x >> 56)); \ +}) + +#ifdef PUPA_CPU_WORDS_BIGENDIAN +# define pupa_cpu_to_le16(x) pupa_swap_bytes16(x) +# define pupa_cpu_to_le32(x) pupa_swap_bytes32(x) +# define pupa_cpu_to_le64(x) pupa_swap_bytes64(x) +# define pupa_le_to_cpu16(x) pupa_swap_bytes16(x) +# define pupa_le_to_cpu32(x) pupa_swap_bytes32(x) +# define pupa_le_to_cpu64(x) pupa_swap_bytes64(x) +# define pupa_cpu_to_be16(x) ((pupa_uint16_t) (x)) +# define pupa_cpu_to_be32(x) ((pupa_uint32_t) (x)) +# define pupa_cpu_to_be64(x) ((pupa_uint64_t) (x)) +# define pupa_be_to_cpu16(x) ((pupa_uint16_t) (x)) +# define pupa_be_to_cpu32(x) ((pupa_uint32_t) (x)) +# define pupa_be_to_cpu64(x) ((pupa_uint64_t) (x)) +#else /* ! WORDS_BIGENDIAN */ +# define pupa_cpu_to_le16(x) ((pupa_uint16_t) (x)) +# define pupa_cpu_to_le32(x) ((pupa_uint32_t) (x)) +# define pupa_cpu_to_le64(x) ((pupa_uint64_t) (x)) +# define pupa_le_to_cpu16(x) ((pupa_uint16_t) (x)) +# define pupa_le_to_cpu32(x) ((pupa_uint32_t) (x)) +# define pupa_le_to_cpu64(x) ((pupa_uint64_t) (x)) +# define pupa_cpu_to_be16(x) pupa_swap_bytes16(x) +# define pupa_cpu_to_be32(x) pupa_swap_bytes32(x) +# define pupa_cpu_to_be64(x) pupa_swap_bytes64(x) +# define pupa_be_to_cpu16(x) pupa_swap_bytes16(x) +# define pupa_be_to_cpu32(x) pupa_swap_bytes32(x) +# define pupa_be_to_cpu64(x) pupa_swap_bytes64(x) +#endif /* ! WORDS_BIGENDIAN */ + +#endif /* ! PUPA_TYPES_HEADER */ diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h new file mode 100644 index 000000000..48bf0e961 --- /dev/null +++ b/include/grub/util/misc.h @@ -0,0 +1,40 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_UTIL_MISC_HEADER +#define PUPA_UTIL_MISC_HEADER 1 + +#include +#include + +extern char *progname; +extern int verbosity; + +void pupa_util_info (const char *fmt, ...); +void pupa_util_error (const char *fmt, ...) __attribute__ ((noreturn)); + +void *xmalloc (size_t size); +char *xstrdup (const char *str); + +char *pupa_util_get_path (const char *dir, const char *file); +size_t pupa_util_get_image_size (const char *path); +char *pupa_util_read_image (const char *path); +void pupa_util_write_image (const char *img, size_t size, FILE *out); + +#endif /* ! PUPA_UTIL_MISC_HEADER */ diff --git a/include/grub/util/resolve.h b/include/grub/util/resolve.h new file mode 100644 index 000000000..35d2507d9 --- /dev/null +++ b/include/grub/util/resolve.h @@ -0,0 +1,36 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PUPA_UTIL_RESOLVE_HEADER +#define PUPA_UTIL_RESOLVE_HEADER 1 + +struct pupa_util_path_list +{ + const char *name; + struct pupa_util_path_list *next; +}; + +/* Resolve the dependencies of the modules MODULES using the information + in the file DEP_LIST_FILE. The directory PREFIX is used to find files. */ +struct pupa_util_path_list * +pupa_util_resolve_dependencies (const char *prefix, + const char *dep_list_file, + char *modules[]); + +#endif /* ! PUPA_UTIL_RESOLVE_HEADER */ diff --git a/install-sh b/install-sh new file mode 100644 index 000000000..e9de23842 --- /dev/null +++ b/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/kern/device.c b/kern/device.c new file mode 100644 index 000000000..2c37d936b --- /dev/null +++ b/kern/device.c @@ -0,0 +1,99 @@ +/* device.c - device manager */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +static char *pupa_device_root; + +pupa_err_t +pupa_device_set_root (const char *name) +{ + pupa_free (pupa_device_root); + pupa_device_root = pupa_strdup (name); + return pupa_errno; +} + +const char * +pupa_device_get_root (void) +{ + if (! pupa_device_root) + pupa_error (PUPA_ERR_BAD_DEVICE, "no root device"); + + return pupa_device_root; +} + +pupa_device_t +pupa_device_open (const char *name) +{ + pupa_disk_t disk = 0; + pupa_device_t dev = 0; + + if (! name) + { + if (! pupa_device_root) + { + pupa_error (PUPA_ERR_BAD_DEVICE, "no device is set"); + goto fail; + } + + name = pupa_device_root; + } + + dev = pupa_malloc (sizeof (*dev)); + if (! dev) + goto fail; + + /* Try to open a disk. */ + disk = pupa_disk_open (name); + if (! disk) + { + pupa_error (PUPA_ERR_BAD_DEVICE, "unknown device"); + goto fail; + } + + dev->disk = disk; + dev->net = 0; /* FIXME */ + + return dev; + + fail: + if (disk) + pupa_disk_close (disk); + + pupa_free (dev); + + return 0; +} + +pupa_err_t +pupa_device_close (pupa_device_t device) +{ + if (device->disk) + pupa_disk_close (device->disk); + + pupa_free (device); + + return pupa_errno; +} diff --git a/kern/disk.c b/kern/disk.c new file mode 100644 index 000000000..04e15432a --- /dev/null +++ b/kern/disk.c @@ -0,0 +1,474 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +/* Disk cache. */ +struct pupa_disk_cache +{ + unsigned long id; + unsigned long sector; + char *data; + int lock; +}; + +static struct pupa_disk_cache pupa_disk_cache_table[PUPA_DISK_CACHE_NUM]; + +#if 0 +static unsigned long pupa_disk_cache_hits; +static unsigned long pupa_disk_cache_misses; + +void +pupa_disk_cache_get_performance (unsigned long *hits, unsigned long *misses) +{ + *hits = pupa_disk_cache_hits; + *misses = pupa_disk_cache_misses; +} +#endif + +static unsigned +pupa_disk_cache_get_index (unsigned long id, unsigned long sector) +{ + return ((id * 2606459 + (sector >> PUPA_DISK_CACHE_BITS)) + % PUPA_DISK_CACHE_NUM); +} + +static void +pupa_disk_cache_invalidate (unsigned long id, unsigned long sector) +{ + unsigned index; + struct pupa_disk_cache *cache; + + sector &= ~(PUPA_DISK_CACHE_SIZE - 1); + index = pupa_disk_cache_get_index (id, sector); + cache = pupa_disk_cache_table + index; + + if (cache->id == id && cache->sector == sector && cache->data) + { + cache->lock = 1; + pupa_free (cache->data); + cache->data = 0; + cache->lock = 0; + } +} + +void +pupa_disk_cache_invalidate_all (void) +{ + unsigned i; + + for (i = 0; i < PUPA_DISK_CACHE_NUM; i++) + { + struct pupa_disk_cache *cache = pupa_disk_cache_table + i; + + if (cache->data && ! cache->lock) + { + pupa_free (cache->data); + cache->data = 0; + } + } +} + +static char * +pupa_disk_cache_fetch (unsigned long id, unsigned long sector) +{ + struct pupa_disk_cache *cache; + unsigned index; + + index = pupa_disk_cache_get_index (id, sector); + cache = pupa_disk_cache_table + index; + + if (cache->id == id && cache->sector == sector) + { + cache->lock = 1; +#if 0 + pupa_disk_cache_hits++; +#endif + return cache->data; + } + +#if 0 + pupa_disk_cache_misses++; +#endif + + return 0; +} + +static void +pupa_disk_cache_unlock (unsigned long id, unsigned long sector) +{ + struct pupa_disk_cache *cache; + unsigned index; + + index = pupa_disk_cache_get_index (id, sector); + cache = pupa_disk_cache_table + index; + + if (cache->id == id && cache->sector == sector) + cache->lock = 0; +} + +static pupa_err_t +pupa_disk_cache_store (unsigned long id, unsigned long sector, + const char *data) +{ + unsigned index; + struct pupa_disk_cache *cache; + + pupa_disk_cache_invalidate (id, sector); + + index = pupa_disk_cache_get_index (id, sector); + cache = pupa_disk_cache_table + index; + + cache->data = pupa_malloc (PUPA_DISK_SECTOR_SIZE << PUPA_DISK_CACHE_BITS); + if (! cache->data) + return pupa_errno; + + pupa_memcpy (cache->data, data, + PUPA_DISK_SECTOR_SIZE << PUPA_DISK_CACHE_BITS); + cache->id = id; + cache->sector = sector; + + return PUPA_ERR_NONE; +} + + + +static pupa_disk_dev_t pupa_disk_dev_list; + +void +pupa_disk_dev_register (pupa_disk_dev_t dev) +{ + dev->next = pupa_disk_dev_list; + pupa_disk_dev_list = dev; +} + +void +pupa_disk_dev_unregister (pupa_disk_dev_t dev) +{ + pupa_disk_dev_t *p, q; + + for (p = &pupa_disk_dev_list, q = *p; q; p = &(q->next), q = q->next) + if (q == dev) + { + *p = q->next; + break; + } +} + +void +pupa_disk_dev_iterate (int (*hook) (const char *name)) +{ + pupa_disk_dev_t p; + + for (p = pupa_disk_dev_list; p; p = p->next) + if ((p->iterate) (hook)) + break; +} + +pupa_disk_t +pupa_disk_open (const char *name) +{ + char *p; + pupa_disk_t disk; + pupa_disk_dev_t dev; + char *raw = (char *) name; + + disk = (pupa_disk_t) pupa_malloc (sizeof (*disk)); + if (! disk) + return 0; + + disk->dev = 0; + disk->read_hook = 0; + disk->partition = 0; + disk->data = 0; + disk->name = pupa_strdup (name); + if (! disk->name) + goto fail; + + p = pupa_strchr (name, ','); + if (p) + { + pupa_size_t len = p - name; + + raw = pupa_malloc (len + 1); + if (! raw) + goto fail; + + pupa_memcpy (raw, name, len); + raw[len] = '\0'; + } + + for (dev = pupa_disk_dev_list; dev; dev = dev->next) + { + if ((dev->open) (raw, disk) == PUPA_ERR_NONE) + break; + else if (pupa_errno == PUPA_ERR_UNKNOWN_DEVICE) + pupa_errno = PUPA_ERR_NONE; + else + goto fail; + } + + if (! dev) + { + pupa_error (PUPA_ERR_UNKNOWN_DEVICE, "no such disk"); + goto fail; + } + + if (p && ! disk->has_partitions) + { + pupa_error (PUPA_ERR_BAD_DEVICE, "no partition on this disk"); + goto fail; + } + + disk->dev = dev; + + if (p) + disk->partition = pupa_partition_probe (disk, p + 1); + + fail: + + if (raw && raw != name) + pupa_free (raw); + + if (pupa_errno != PUPA_ERR_NONE) + { + pupa_disk_close (disk); + return 0; + } + + return disk; +} + +void +pupa_disk_close (pupa_disk_t disk) +{ + if (disk->dev && disk->dev->close) + (disk->dev->close) (disk); + + pupa_free (disk->partition); + pupa_free ((void *) disk->name); + pupa_free (disk); +} + +static pupa_err_t +pupa_disk_check_range (pupa_disk_t disk, unsigned long *sector, + unsigned long *offset, pupa_ssize_t size) +{ + *sector += *offset >> PUPA_DISK_SECTOR_BITS; + *offset &= PUPA_DISK_SECTOR_SIZE - 1; + + if (disk->partition) + { + unsigned long start, len; + + start = pupa_partition_get_start (disk->partition); + len = pupa_partition_get_len (disk->partition); + + if (*sector >= len + || len - *sector < ((*offset + size + PUPA_DISK_SECTOR_SIZE - 1) + >> PUPA_DISK_SECTOR_BITS)) + return pupa_error (PUPA_ERR_OUT_OF_RANGE, "out of partition"); + + *sector += start; + } + + if (disk->total_sectors <= *sector + || ((*offset + size + PUPA_DISK_SECTOR_SIZE - 1) + >> PUPA_DISK_SECTOR_BITS) > disk->total_sectors - *sector) + return pupa_error (PUPA_ERR_OUT_OF_RANGE, "out of disk"); + + return PUPA_ERR_NONE; +} + +/* Read data from the disk. */ +pupa_err_t +pupa_disk_read (pupa_disk_t disk, unsigned long sector, + unsigned long offset, unsigned long size, char *buf) +{ + char *tmp_buf; + + /* First of all, check if the region is within the disk. */ + if (pupa_disk_check_range (disk, §or, &offset, size) != PUPA_ERR_NONE) + return pupa_errno; + + /* Allocate a temporary buffer. */ + tmp_buf = pupa_malloc (PUPA_DISK_SECTOR_SIZE << PUPA_DISK_CACHE_BITS); + if (! tmp_buf) + return pupa_errno; + + /* Until SIZE is zero... */ + while (size) + { + char *data; + unsigned long start_sector; + unsigned long len; + unsigned long pos; + + /* For reading bulk data. */ + start_sector = sector & ~(PUPA_DISK_CACHE_SIZE - 1); + pos = (sector - start_sector) << PUPA_DISK_SECTOR_BITS; + len = (PUPA_DISK_SECTOR_SIZE << PUPA_DISK_CACHE_BITS) - pos - offset; + if (len > size) + len = size; + + /* Fetch the cache. */ + data = pupa_disk_cache_fetch (disk->id, start_sector); + if (data) + { + /* Just copy it! */ + pupa_memcpy (buf, data + pos + offset, len); + pupa_disk_cache_unlock (disk->id, start_sector); + } + else + { + /* Otherwise read data from the disk actually. */ + if ((disk->dev->read) (disk, start_sector, + PUPA_DISK_CACHE_SIZE, tmp_buf) + != PUPA_ERR_NONE) + { + /* Uggh... Failed. Instead, just read necessary data. */ + unsigned num; + + /* If more data is required, no way. */ + if (pos + size + >= (PUPA_DISK_SECTOR_SIZE << PUPA_DISK_CACHE_BITS)) + goto finish; + + num = ((size + PUPA_DISK_SECTOR_SIZE - 1) + >> PUPA_DISK_SECTOR_BITS); + if ((disk->dev->read) (disk, sector, num, tmp_buf)) + goto finish; + + pupa_memcpy (buf, tmp_buf + offset, size); + + /* Call the read hook, if any. */ + if (disk->read_hook) + while (size) + { + (disk->read_hook) (sector, offset, + ((size > PUPA_DISK_SECTOR_SIZE) + ? PUPA_DISK_SECTOR_SIZE + : size)); + sector++; + size -= PUPA_DISK_SECTOR_SIZE - offset; + offset = 0; + } + + /* This must be the end. */ + goto finish; + } + + /* Copy it and store it in the disk cache. */ + pupa_memcpy (buf, tmp_buf + pos + offset, len); + pupa_disk_cache_store (disk->id, start_sector, tmp_buf); + } + + /* Call the read hook, if any. */ + if (disk->read_hook) + { + unsigned long s = sector; + unsigned long l = len; + + while (l) + { + (disk->read_hook) (s, offset, + ((l > PUPA_DISK_SECTOR_SIZE) + ? PUPA_DISK_SECTOR_SIZE + : l)); + s++; + l -= PUPA_DISK_SECTOR_SIZE - offset; + offset = 0; + } + } + + sector = start_sector + PUPA_DISK_CACHE_SIZE; + buf += len; + size -= len; + offset = 0; + } + + finish: + + pupa_free (tmp_buf); + + return pupa_errno; +} + +pupa_err_t +pupa_disk_write (pupa_disk_t disk, unsigned long sector, + unsigned long offset, unsigned long size, const char *buf) +{ + if (pupa_disk_check_range (disk, §or, &offset, size) != PUPA_ERR_NONE) + return -1; + + while (size) + { + if (offset != 0 || (size < PUPA_DISK_SECTOR_SIZE && size != 0)) + { + char tmp_buf[PUPA_DISK_SECTOR_SIZE]; + unsigned long len; + + if (pupa_disk_read (disk, sector, 0, PUPA_DISK_SECTOR_SIZE, tmp_buf) + != PUPA_ERR_NONE) + goto finish; + + len = PUPA_DISK_SECTOR_SIZE - offset; + if (len > size) + len = size; + + pupa_memcpy (tmp_buf + offset, buf, len); + + pupa_disk_cache_invalidate (disk->id, sector); + + if ((disk->dev->write) (disk, sector, 1, tmp_buf) != PUPA_ERR_NONE) + goto finish; + + sector++; + buf += len; + size -= len; + offset = 0; + } + else + { + unsigned long len; + unsigned long n; + + len = size & ~(PUPA_DISK_SECTOR_SIZE - 1); + n = size >> PUPA_DISK_SECTOR_BITS; + + if ((disk->dev->write) (disk, sector, n, buf) != PUPA_ERR_NONE) + goto finish; + + while (n--) + pupa_disk_cache_invalidate (disk->id, sector++); + + buf += len; + size -= len; + } + } + + finish: + + return pupa_errno; +} diff --git a/kern/dl.c b/kern/dl.c new file mode 100644 index 000000000..c22c98403 --- /dev/null +++ b/kern/dl.c @@ -0,0 +1,599 @@ +/* dl.c - loadable module support */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if PUPA_HOST_SIZEOF_VOID_P == 4 + +typedef Elf32_Word Elf_Word; +typedef Elf32_Addr Elf_Addr; +typedef Elf32_Ehdr Elf_Ehdr; +typedef Elf32_Shdr Elf_Shdr; +typedef Elf32_Sym Elf_Sym; + +# define ELF_ST_BIND(val) ELF32_ST_BIND (val) +# define ELF_ST_TYPE(val) ELF32_ST_TYPE (val) + +#elif PUPA_HOST_SIZEOF_VOID_P == 8 + +typedef Elf64_Word Elf_Word; +typedef Elf64_Addr Elf_Addr; +typedef Elf64_Ehdr Elf_Ehdr; +typedef Elf64_Shdr Elf_Shdr; +typedef Elf64_Sym Elf_Sym; + +# define ELF_ST_BIND(val) ELF64_ST_BIND (val) +# define ELF_ST_TYPE(val) ELF64_ST_TYPE (val) + +#endif + + + +struct pupa_dl_list +{ + struct pupa_dl_list *next; + pupa_dl_t mod; +}; +typedef struct pupa_dl_list *pupa_dl_list_t; + +static pupa_dl_list_t pupa_dl_head; + +static pupa_err_t +pupa_dl_add (pupa_dl_t mod) +{ + pupa_dl_list_t l; + + if (pupa_dl_get (mod->name)) + return pupa_error (PUPA_ERR_BAD_MODULE, + "`%s' is already loaded", mod->name); + + l = (pupa_dl_list_t) pupa_malloc (sizeof (*l)); + if (! l) + return pupa_errno; + + l->mod = mod; + l->next = pupa_dl_head; + pupa_dl_head = l; + + return PUPA_ERR_NONE; +} + +static void +pupa_dl_remove (pupa_dl_t mod) +{ + pupa_dl_list_t *p, q; + + for (p = &pupa_dl_head, q = *p; q; p = &q->next, q = *p) + if (q->mod == mod) + { + *p = q->next; + pupa_free (q); + return; + } +} + +pupa_dl_t +pupa_dl_get (const char *name) +{ + pupa_dl_list_t l; + + for (l = pupa_dl_head; l; l = l->next) + if (pupa_strcmp (name, l->mod->name) == 0) + return l->mod; + + return 0; +} + + + +struct pupa_symbol +{ + struct pupa_symbol *next; + const char *name; + void *addr; + pupa_dl_t mod; /* The module to which this symbol belongs. */ +}; +typedef struct pupa_symbol *pupa_symbol_t; + +/* The size of the symbol table. */ +#define PUPA_SYMTAB_SIZE 509 + +/* The symbol table (using an open-hash). */ +static struct pupa_symbol *pupa_symtab[PUPA_SYMTAB_SIZE]; + +/* Simple hash function. */ +static unsigned +pupa_symbol_hash (const char *s) +{ + unsigned key = 0; + + while (*s) + key = key * 65599 + *s++; + + return (key + (key >> 5)) % PUPA_SYMTAB_SIZE; +} + +/* Resolve the symbol name NAME and return the address. + Return NULL, if not found. */ +void * +pupa_dl_resolve_symbol (const char *name) +{ + pupa_symbol_t sym; + + for (sym = pupa_symtab[pupa_symbol_hash (name)]; sym; sym = sym->next) + if (pupa_strcmp (sym->name, name) == 0) + return sym->addr; + + return 0; +} + +/* Register a symbol with the name NAME and the address ADDR. */ +pupa_err_t +pupa_dl_register_symbol (const char *name, void *addr, pupa_dl_t mod) +{ + pupa_symbol_t sym; + unsigned k; + + sym = (pupa_symbol_t) pupa_malloc (sizeof (*sym)); + if (! sym) + return pupa_errno; + + if (mod) + { + sym->name = pupa_strdup (name); + if (! sym->name) + { + pupa_free (sym); + return pupa_errno; + } + } + else + sym->name = name; + + sym->addr = addr; + sym->mod = mod; + + k = pupa_symbol_hash (name); + sym->next = pupa_symtab[k]; + pupa_symtab[k] = sym; + + return PUPA_ERR_NONE; +} + +/* Unregister all the symbols defined in the module MOD. */ +static void +pupa_dl_unregister_symbols (pupa_dl_t mod) +{ + unsigned i; + + if (! mod) + pupa_fatal ("core symbols cannot be unregistered"); + + for (i = 0; i < PUPA_SYMTAB_SIZE; i++) + { + pupa_symbol_t sym, *p, q; + + for (p = &pupa_symtab[i], sym = *p; sym; sym = q) + { + q = sym->next; + if (sym->mod == mod) + { + *p = q; + pupa_free ((void *) sym->name); + pupa_free (sym); + } + else + p = &sym->next; + } + } +} + +/* Return the address of a section whose index is N. */ +static void * +pupa_dl_get_section_addr (pupa_dl_t mod, unsigned n) +{ + pupa_dl_segment_t seg; + + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == n) + return seg->addr; + + return 0; +} + +/* Load all segments from memory specified by E. */ +static pupa_err_t +pupa_dl_load_segments (pupa_dl_t mod, const Elf_Ehdr *e) +{ + unsigned i; + Elf_Shdr *s; + + for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize)) + { + if (s->sh_flags & SHF_ALLOC) + { + pupa_dl_segment_t seg; + + seg = (pupa_dl_segment_t) pupa_malloc (sizeof (*seg)); + if (! seg) + return pupa_errno; + + if (s->sh_size) + { + void *addr; + + addr = pupa_memalign (s->sh_addralign, s->sh_size); + if (! addr) + { + pupa_free (seg); + return pupa_errno; + } + + switch (s->sh_type) + { + case SHT_PROGBITS: + pupa_memcpy (addr, (char *) e + s->sh_offset, s->sh_size); + break; + case SHT_NOBITS: + pupa_memset (addr, 0, s->sh_size); + break; + } + + seg->addr = addr; + } + else + seg->addr = 0; + + seg->size = s->sh_size; + seg->section = i; + seg->next = mod->segment; + mod->segment = seg; + } + } + + return PUPA_ERR_NONE; +} + +static pupa_err_t +pupa_dl_resolve_symbols (pupa_dl_t mod, Elf_Ehdr *e) +{ + unsigned i; + Elf_Shdr *s; + Elf_Sym *sym; + const char *str; + Elf_Word size, entsize; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return pupa_error (PUPA_ERR_BAD_MODULE, "no symbol table"); + + sym = (Elf_Sym *) ((char *) e + s->sh_offset); + size = s->sh_size; + entsize = s->sh_entsize; + + s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link); + str = (char *) e + s->sh_offset; + + for (i = 0; + i < size / entsize; + i++, sym = (Elf_Sym *) ((char *) sym + entsize)) + { + unsigned char type = ELF_ST_TYPE (sym->st_info); + unsigned char bind = ELF_ST_BIND (sym->st_info); + const char *name = str + sym->st_name; + + switch (type) + { + case STT_NOTYPE: + /* Resolve a global symbol. */ + if (sym->st_name != 0 && sym->st_shndx == 0) + { + sym->st_value = (Elf_Addr) pupa_dl_resolve_symbol (name); + if (! sym->st_value) + return pupa_error (PUPA_ERR_BAD_MODULE, + "the symbol `%s' not found", name); + } + else + sym->st_value = 0; + break; + + case STT_OBJECT: + sym->st_value += (Elf_Addr) pupa_dl_get_section_addr (mod, + sym->st_shndx); + if (bind != STB_LOCAL) + if (pupa_dl_register_symbol (name, (void *) sym->st_value, mod)) + return pupa_errno; + break; + + case STT_FUNC: + sym->st_value += (Elf_Addr) pupa_dl_get_section_addr (mod, + sym->st_shndx); + if (bind != STB_LOCAL) + if (pupa_dl_register_symbol (name, (void *) sym->st_value, mod)) + return pupa_errno; + + if (pupa_strcmp (name, "pupa_mod_init") == 0) + mod->init = (void (*) ()) sym->st_value; + else if (pupa_strcmp (name, "pupa_mod_fini") == 0) + mod->fini = (void (*) ()) sym->st_value; + break; + + case STT_SECTION: + sym->st_value = (Elf_Addr) pupa_dl_get_section_addr (mod, + sym->st_shndx); + break; + + case STT_FILE: + sym->st_value = 0; + break; + + default: + return pupa_error (PUPA_ERR_BAD_MODULE, + "unknown symbol type `%d'", (int) type); + } + } + + return PUPA_ERR_NONE; +} + +static void +pupa_dl_call_init (pupa_dl_t mod) +{ + if (mod->init) + (mod->init) (); +} + +static pupa_err_t +pupa_dl_resolve_name (pupa_dl_t mod, Elf_Ehdr *e) +{ + Elf_Shdr *s; + const char *str; + unsigned i; + + s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); + str = (char *) e + s->sh_offset; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (pupa_strcmp (str + s->sh_name, ".modname") == 0) + { + mod->name = pupa_strdup ((char *) e + s->sh_offset); + if (! mod->name) + return pupa_errno; + break; + } + + if (i == e->e_shnum) + return pupa_error (PUPA_ERR_BAD_MODULE, "no module name found"); + + return PUPA_ERR_NONE; +} + +static pupa_err_t +pupa_dl_resolve_dependencies (pupa_dl_t mod, Elf_Ehdr *e) +{ + Elf_Shdr *s; + const char *str; + unsigned i; + + s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); + str = (char *) e + s->sh_offset; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (pupa_strcmp (str + s->sh_name, ".moddeps") == 0) + { + const char *name = (char *) e + s->sh_offset; + const char *max = name + s->sh_size; + + while (name < max) + { + pupa_dl_t m; + pupa_dl_dep_t dep; + + m = pupa_dl_load (name); + if (! m) + return pupa_errno; + + dep = (pupa_dl_dep_t) pupa_malloc (sizeof (*dep)); + if (! dep) + return pupa_errno; + + dep->mod = m; + dep->next = mod->dep; + mod->dep = dep; + + name += pupa_strlen (name) + 1; + } + } + + return PUPA_ERR_NONE; +} + +/* Load a module from core memory. */ +pupa_dl_t +pupa_dl_load_core (void *addr, pupa_size_t size) +{ + Elf_Ehdr *e; + pupa_dl_t mod; + + e = addr; + if (! pupa_arch_dl_check_header (e, size)) + { + pupa_error (PUPA_ERR_BAD_MODULE, "invalid ELF header"); + return 0; + } + + mod = (pupa_dl_t) pupa_malloc (sizeof (*mod)); + if (! mod) + return 0; + + mod->name = 0; + mod->ref_count = 1; + mod->dep = 0; + mod->segment = 0; + mod->init = 0; + mod->fini = 0; + + if (pupa_dl_resolve_name (mod, e) + || pupa_dl_resolve_dependencies (mod, e) + || pupa_dl_load_segments (mod, e) + || pupa_dl_resolve_symbols (mod, e) + || pupa_arch_dl_relocate_symbols (mod, e)) + { + mod->fini = 0; + pupa_dl_unload (mod); + return 0; + } + + pupa_dl_call_init (mod); + + if (pupa_dl_add (mod)) + { + pupa_dl_unload (mod); + return 0; + } + + return mod; +} + +/* Load a module from the file FILENAME. */ +pupa_dl_t +pupa_dl_load_file (const char *filename) +{ + pupa_file_t file; + pupa_ssize_t size; + void *core = 0; + pupa_dl_t mod = 0; + + file = pupa_file_open (filename); + if (! file) + return 0; + + size = pupa_file_size (file); + core = pupa_malloc (size); + if (! core) + goto failed; + + if (pupa_file_read (file, core, size) != (int) size) + goto failed; + + mod = pupa_dl_load_core (core, size); + + failed: + pupa_file_close (file); + pupa_free (core); + + return mod; +} + +static char *pupa_dl_dir; + +/* Load a module using a symbolic name. */ +pupa_dl_t +pupa_dl_load (const char *name) +{ + char *filename; + pupa_dl_t mod; + + mod = pupa_dl_get (name); + if (mod) + { + mod->ref_count++; + return mod; + } + + if (! pupa_dl_dir) + pupa_fatal ("module dir is not initialized yet"); + + filename = (char *) pupa_malloc (pupa_strlen (pupa_dl_dir) + 1 + + pupa_strlen (name) + 3); + if (! filename) + return 0; + + pupa_sprintf (filename, "%s/%s.o", pupa_dl_dir, name); + mod = pupa_dl_load_file (filename); + pupa_free (filename); + + if (! mod) + return 0; + + if (pupa_strcmp (mod->name, name) != 0) + pupa_error (PUPA_ERR_BAD_MODULE, "mismatched names"); + + return mod; +} + +/* Unload the module MOD. */ +void +pupa_dl_unload (pupa_dl_t mod) +{ + pupa_dl_dep_t dep, depn; + pupa_dl_segment_t seg, segn; + + if (--mod->ref_count > 0) + return; + + if (mod->fini) + (mod->fini) (); + + pupa_dl_remove (mod); + pupa_dl_unregister_symbols (mod); + + for (dep = mod->dep; dep; dep = depn) + { + depn = dep->next; + pupa_dl_unload (dep->mod); + pupa_free (dep); + } + + for (seg = mod->segment; seg; seg = segn) + { + segn = seg->next; + pupa_free (seg->addr); + pupa_free (seg); + } + + pupa_free (mod->name); + pupa_free (mod); +} + +void +pupa_dl_init (const char *dir) +{ + pupa_dl_dir = (char *) dir; +} diff --git a/kern/err.c b/kern/err.c new file mode 100644 index 000000000..7e2d103e4 --- /dev/null +++ b/kern/err.c @@ -0,0 +1,61 @@ +/* err.c - error handling routines */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#define PUPA_MAX_ERRMSG 256 + +pupa_err_t pupa_errno; +char pupa_errmsg[PUPA_MAX_ERRMSG]; + +pupa_err_t +pupa_error (pupa_err_t n, const char *fmt, ...) +{ + va_list ap; + + pupa_errno = n; + + va_start (ap, fmt); + pupa_vsprintf (pupa_errmsg, fmt, ap); + va_end (ap); + + return n; +} + +void +pupa_fatal (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + pupa_vprintf (fmt, ap); + va_end (ap); + + pupa_stop (); +} + +void +pupa_print_error (void) +{ + if (pupa_errno != PUPA_ERR_NONE) + pupa_printf ("error: %s\n", pupa_errmsg); +} diff --git a/kern/file.c b/kern/file.c new file mode 100644 index 000000000..7d95ba595 --- /dev/null +++ b/kern/file.c @@ -0,0 +1,158 @@ +/* file.c - file I/O functions */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +/* Get the device part of the filename NAME. It is enclosed by parentheses. */ +char * +pupa_file_get_device_name (const char *name) +{ + if (name[0] == '(') + { + char *p = pupa_strchr (name, ')'); + char *ret; + + if (! p) + { + pupa_error (PUPA_ERR_BAD_FILENAME, "missing `)'"); + return 0; + } + + ret = (char *) pupa_malloc (p - name); + if (! ret) + return 0; + + pupa_memcpy (ret, name + 1, p - name - 1); + ret[p - name - 1] = '\0'; + return ret; + } + + return 0; +} + +pupa_file_t +pupa_file_open (const char *name) +{ + pupa_device_t device; + pupa_file_t file = 0; + char *device_name; + char *file_name; + + device_name = pupa_file_get_device_name (name); + if (pupa_errno) + return 0; + + /* Get the file part of NAME. */ + file_name = pupa_strchr (name, ')'); + if (file_name) + file_name++; + else + file_name = (char *) name; + + device = pupa_device_open (device_name); + pupa_free (device_name); + if (! device) + goto fail; + + file = (pupa_file_t) pupa_malloc (sizeof (*file)); + if (! file) + goto fail; + + file->device = device; + file->offset = 0; + file->data = 0; + file->read_hook = 0; + + if (device->disk && file_name[0] != '/') + /* This is a block list. */ + file->fs = &pupa_fs_blocklist; + else + { + file->fs = pupa_fs_probe (device); + if (! file->fs) + goto fail; + } + + if ((file->fs->open) (file, file_name) != PUPA_ERR_NONE) + goto fail; + + return file; + + fail: + if (device) + pupa_device_close (device); + + /* if (net) pupa_net_close (net); */ + + pupa_free (file); + + return 0; +} + +pupa_ssize_t +pupa_file_read (pupa_file_t file, char *buf, pupa_ssize_t len) +{ + pupa_ssize_t res; + + if (len == 0 || len > file->size - file->offset) + len = file->size - file->offset; + + if (len == 0) + return 0; + + res = (file->fs->read) (file, buf, len); + if (res > 0) + file->offset += res; + + return res; +} + +pupa_err_t +pupa_file_close (pupa_file_t file) +{ + if (file->fs->close) + (file->fs->close) (file); + + pupa_device_close (file->device); + pupa_free (file); + return pupa_errno; +} + +pupa_ssize_t +pupa_file_seek (pupa_file_t file, pupa_ssize_t offset) +{ + pupa_ssize_t old; + + if (offset < 0 || offset >= file->size) + { + pupa_error (PUPA_ERR_OUT_OF_RANGE, + "attempt to seek outside of the file"); + return -1; + } + + old = file->offset; + file->offset = offset; + return old; +} diff --git a/kern/fs.c b/kern/fs.c new file mode 100644 index 000000000..652fc55b9 --- /dev/null +++ b/kern/fs.c @@ -0,0 +1,224 @@ +/* fs.c - filesystem manager */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static pupa_fs_t pupa_fs_list; + +void +pupa_fs_register (pupa_fs_t fs) +{ + fs->next = pupa_fs_list; + pupa_fs_list = fs; +} + +void +pupa_fs_unregister (pupa_fs_t fs) +{ + pupa_fs_t *p, q; + + for (p = &pupa_fs_list, q = *p; q; p = &(q->next), q = q->next) + if (q == fs) + { + *p = q->next; + break; + } +} + +void +pupa_fs_iterate (int (*hook) (const pupa_fs_t fs)) +{ + pupa_fs_t p; + + for (p = pupa_fs_list; p; p = p->next) + if (hook (p)) + break; +} + +pupa_fs_t +pupa_fs_probe (pupa_device_t device) +{ + pupa_fs_t p; + auto int dummy_func (const char *filename, int dir); + + int dummy_func (const char *filename __attribute__ ((unused)), + int dir __attribute__ ((unused))) + { + return 1; + } + + if (device->disk) + { + for (p = pupa_fs_list; p; p = p->next) + { + (p->dir) (device, "/", dummy_func); + if (pupa_errno == PUPA_ERR_NONE) + return p; + + if (pupa_errno != PUPA_ERR_BAD_FS) + return 0; + + pupa_errno = PUPA_ERR_NONE; + } + } + else if (device->net->fs) + return device->net->fs; + + pupa_error (PUPA_ERR_UNKNOWN_FS, "unknown filesystem"); + return 0; +} + + + +/* Block list support routines. */ + +struct pupa_fs_block +{ + unsigned long offset; + unsigned long length; +}; + +static pupa_err_t +pupa_fs_blocklist_open (pupa_file_t file, const char *name) +{ + char *p = (char *) name; + unsigned num = 0; + unsigned i; + pupa_disk_t disk = file->device->disk; + struct pupa_fs_block *blocks; + + /* First, count the number of blocks. */ + do + { + num++; + p = pupa_strchr (p, ','); + } + while (p); + + /* Allocate a block list. */ + blocks = pupa_malloc (sizeof (struct pupa_fs_block) * (num + 1)); + if (! blocks) + return 0; + + file->size = 0; + p = (char *) name; + for (i = 0; i < num; i++) + { + if (*p != '+') + { + blocks[i].offset = pupa_strtoul (p, &p, 0); + if (pupa_errno != PUPA_ERR_NONE || *p != '+') + { + pupa_error (PUPA_ERR_BAD_FILENAME, + "invalid file name `%s'", name); + goto fail; + } + } + else + blocks[i].offset = 0; + + p++; + blocks[i].length = pupa_strtoul (p, &p, 0); + if (pupa_errno != PUPA_ERR_NONE + || blocks[i].length == 0 + || (*p && *p != ',' && ! pupa_isspace (*p))) + { + pupa_error (PUPA_ERR_BAD_FILENAME, + "invalid file name `%s'", name); + goto fail; + } + + if (disk->total_sectors < blocks[i].offset + blocks[i].length) + { + pupa_error (PUPA_ERR_BAD_FILENAME, "beyond the total sectors"); + goto fail; + } + + file->size += (blocks[i].length << PUPA_DISK_SECTOR_BITS); + p++; + } + + blocks[i].length = 0; + file->data = blocks; + + return PUPA_ERR_NONE; + + fail: + pupa_free (blocks); + return pupa_errno; +} + +static pupa_ssize_t +pupa_fs_blocklist_read (pupa_file_t file, char *buf, pupa_ssize_t len) +{ + struct pupa_fs_block *p; + unsigned long sector; + unsigned long offset; + pupa_ssize_t ret = 0; + + if (len > file->size - file->offset) + len = file->size - file->offset; + + sector = (file->offset >> PUPA_DISK_SECTOR_BITS); + offset = (file->offset & (PUPA_DISK_SECTOR_SIZE - 1)); + for (p = file->data; p->length && len > 0; p++) + { + if (sector < p->length) + { + pupa_ssize_t size; + + size = len; + if (((size + offset + PUPA_DISK_SECTOR_SIZE - 1) + >> PUPA_DISK_SECTOR_BITS) > p->length - sector) + size = ((p->length - sector) << PUPA_DISK_SECTOR_BITS) - offset; + + if (pupa_disk_read (file->device->disk, p->offset + sector, offset, + size, buf) != PUPA_ERR_NONE) + return -1; + + ret += size; + len -= size; + sector -= ((size + offset) >> PUPA_DISK_SECTOR_BITS); + offset = ((size + offset) & (PUPA_DISK_SECTOR_SIZE - 1)); + } + else + sector -= p->length; + } + + return ret; +} + +struct pupa_fs pupa_fs_blocklist = + { + .name = "blocklist", + .dir = 0, + .open = pupa_fs_blocklist_open, + .read = pupa_fs_blocklist_read, + .close = 0, + .next = 0 + }; diff --git a/kern/i386/dl.c b/kern/i386/dl.c new file mode 100644 index 000000000..bdd6dd962 --- /dev/null +++ b/kern/i386/dl.c @@ -0,0 +1,126 @@ +/* dl-386.c - arch-dependent part of loadable module support */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +int +pupa_arch_dl_check_header (void *ehdr, unsigned size) +{ + Elf32_Ehdr *e = ehdr; + + /* Check the header size. */ + if (size < sizeof (Elf32_Ehdr)) + return 0; + + /* Check the magic numbers. */ + if (e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_version != EV_CURRENT + || e->e_ident[EI_CLASS] != ELFCLASS32 + || e->e_ident[EI_DATA] != ELFDATA2LSB + || e->e_machine != EM_386 + || e->e_type != ET_REL) + return 0; + + /* Make sure that every section is within the core. */ + if (size < e->e_shoff + e->e_shentsize * e->e_shnum) + return 0; + + return 1; +} + +/* Relocate symbols. */ +pupa_err_t +pupa_arch_dl_relocate_symbols (pupa_dl_t mod, void *ehdr) +{ + Elf32_Ehdr *e = ehdr; + Elf32_Shdr *s; + Elf32_Sym *symtab; + Elf32_Word entsize; + unsigned i; + + /* Find a symbol table. */ + for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return pupa_error (PUPA_ERR_BAD_MODULE, "no symtab found"); + + symtab = (Elf32_Sym *) ((char *) e + s->sh_offset); + entsize = s->sh_entsize; + + for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_REL) + { + pupa_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf32_Rel *rel, *max; + + for (rel = (Elf32_Rel *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + { + Elf32_Word *addr; + Elf32_Sym *sym; + + if (seg->size < rel->r_offset) + return pupa_error (PUPA_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf32_Sym *) ((char *) symtab + + entsize * ELF32_R_SYM (rel->r_info)); + + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_386_32: + *addr += sym->st_value; + break; + + case R_386_PC32: + *addr += (sym->st_value - (Elf32_Word) seg->addr + - rel->r_offset); + break; + } + } + } + } + + return PUPA_ERR_NONE; +} diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c new file mode 100644 index 000000000..589696e69 --- /dev/null +++ b/kern/i386/pc/init.c @@ -0,0 +1,114 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +void +pupa_machine_init (void) +{ + pupa_uint32_t cont; + struct pupa_machine_mmap_entry entry; + pupa_size_t lower_mem = (pupa_get_memsize (0) << 10); + pupa_addr_t end_addr = pupa_get_end_addr (); + + /* Initialize the console as early as possible. */ + pupa_console_init (); + + /* Sanity check. */ + if (lower_mem < PUPA_MEMORY_MACHINE_RESERVED_END) + pupa_fatal ("too small memory"); + + /* Turn on Gate A20 to access >1MB. */ + pupa_gate_a20 (1); + + /* Add the lower memory into free memory. */ + if (lower_mem >= PUPA_MEMORY_MACHINE_RESERVED_END) + pupa_mm_init_region ((void *) PUPA_MEMORY_MACHINE_RESERVED_END, + lower_mem - PUPA_MEMORY_MACHINE_RESERVED_END); + + pupa_mm_init_region ((void *) end_addr, + PUPA_MEMORY_MACHINE_RESERVED_START - end_addr); + + /* Check if pupa_get_mmap_entry works. */ + cont = pupa_get_mmap_entry (&entry, 0); + + if (entry.size) + do + { + /* Avoid the lower memory. */ + if (entry.addr < 0x100000) + { + if (entry.len <= 0x100000 - entry.addr) + goto next; + + entry.len -= 0x100000 - entry.addr; + entry.addr = 0x100000; + } + + /* Ignore >4GB. */ + if (entry.addr <= 0xFFFFFFFF && entry.type == 1) + { + pupa_addr_t addr; + pupa_size_t len; + + addr = (pupa_addr_t) entry.addr; + len = ((addr + entry.len > 0xFFFFFFFF) + ? 0xFFFFFFFF - addr + : (pupa_size_t) entry.len); + pupa_mm_init_region ((void *) addr, len); + } + + next: + if (! cont) + break; + + cont = pupa_get_mmap_entry (&entry, cont); + } + while (entry.size); + else + { + pupa_uint32_t eisa_mmap = pupa_get_eisa_mmap (); + + if (eisa_mmap) + { + if ((eisa_mmap & 0xFFFF) == 0x3C00) + pupa_mm_init_region ((void *) 0x100000, + (eisa_mmap << 16) + 0x100000 * 15); + else + { + pupa_mm_init_region ((void *) 0x100000, + (eisa_mmap & 0xFFFF) << 10); + pupa_mm_init_region ((void *) 0x1000000, eisa_mmap << 16); + } + } + else + pupa_mm_init_region ((void *) 0x100000, + (pupa_size_t) pupa_get_memsize (1) << 10); + } + + /* The memory system was initialized, thus register built-in devices. */ + pupa_biosdisk_init (); +} diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S new file mode 100644 index 000000000..ecc97f3f7 --- /dev/null +++ b/kern/i386/pc/startup.S @@ -0,0 +1,1377 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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. + */ + + +/* + * Note: These functions defined in this file may be called from C. + * Be careful of that you must not modify some registers. Quote + * from gcc-2.95.2/gcc/config/i386/i386.h: + + 1 for registers not available across function calls. + These must include the FIXED_REGISTERS and also any + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. + Aside from that, you can include as many other registers as you like. + + ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg +{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + */ + +#include +#include +#include +#include +#include +#include + +#define ABS(x) ((x) - EXT_C(start) + PUPA_BOOT_MACHINE_KERNEL_ADDR + 0x200) + + .file "startup.S" + + .text + + /* Tell GAS to generate 16-bit instructions so that this code works + in real mode. */ + .code16 + + .globl start, _start +start: +_start: + /* + * Guarantee that "main" is loaded at 0x0:0x8200. + */ + ljmp $0, $ABS(codestart) + + /* + * Compatibility version number + * + * These MUST be at byte offset 6 and 7 of the executable + * DO NOT MOVE !!! + */ + . = EXT_C(start) + 0x6 + .byte PUPA_BOOT_VERSION_MAJOR, PUPA_BOOT_VERSION_MINOR + + /* + * This is a special data area 8 bytes from the beginning. + */ + + . = EXT_C(start) + 0x8 + +VARIABLE(pupa_total_module_size) + .long 0 +VARIABLE(pupa_kernel_image_size) + .long 0 +VARIABLE(install_partition) + .long 0xFFFFFF +VARIABLE(version_string) + .string PACKAGE_VERSION +VARIABLE(config_file) + .string "/boot/pupa/puparc" + + /* + * Leave some breathing room for the config file name. + */ + + . = EXT_C(start) + 0x70 + +/* the real mode code continues... */ +codestart: + cli /* we're not safe here! */ + + /* set up %ds, %ss, and %es */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + movw %ax, %es + + /* set up the real mode/BIOS stack */ + movl $PUPA_MEMORY_MACHINE_REAL_STACK, %ebp + movl %ebp, %esp + + sti /* we're safe again */ + + /* save boot drive reference */ + ADDR32 movb %dl, EXT_C(pupa_boot_drive) + + /* reset disk system (%ah = 0) */ + int $0x13 + + /* transition to protected mode */ + DATA32 call real_to_prot + + /* The ".code32" directive takes GAS out of 16-bit mode. */ + .code32 + + /* copy modules before cleaning out the bss */ + movl EXT_C(pupa_total_module_size), %ecx + movl EXT_C(pupa_kernel_image_size), %esi + addl %ecx, %esi + addl $START_SYMBOL, %esi + decl %esi + movl $END_SYMBOL, %edi + addl %ecx, %edi + decl %edi + std + rep + movsb + + /* clean out the bss */ + movl $BSS_START_SYMBOL, %edi + + /* compute the bss length */ + movl $END_SYMBOL, %ecx + subl %edi, %ecx + + /* clean out */ + cld + rep + stosb + + /* + * Call the start of main body of C code. + */ + call EXT_C(pupa_main) + + +/* + * This call is special... it never returns... in fact it should simply + * hang at this point! + */ + +FUNCTION(pupa_stop) + call prot_to_real + + /* + * This next part is sort of evil. It takes advantage of the + * byte ordering on the x86 to work in either 16-bit or 32-bit + * mode, so think about it before changing it. + */ + +FUNCTION(pupa_hard_stop) + hlt + jmp EXT_C(pupa_hard_stop) + + +/* + * pupa_stop_floppy() + * + * Stop the floppy drive from spinning, so that other software is + * jumped to with a known state. + */ +FUNCTION(pupa_stop_floppy) + movw $0x3F2, %dx + xorb %al, %al + outb %al, %dx + ret + +/* + * pupa_reboot() + * + * Reboot the system. At the moment, rely on BIOS. + */ +FUNCTION(pupa_reboot) + call prot_to_real + .code16 + /* cold boot */ + movw $0x0472, %di + movw %ax, (%di) + ljmp $0xFFFF, $0x0000 + .code32 + +/* + * pupa_halt(int no_apm) + * + * Halt the system, using APM if possible. If NO_APM is true, don't use + * APM even if it is available. + */ +FUNCTION(pupa_halt) + /* get the argument */ + movl 4(%esp), %eax + + /* see if zero */ + testl %eax, %eax + jnz EXT_C(pupa_stop) + + call prot_to_real + .code16 + + /* detect APM */ + movw $0x5300, %ax + xorw %bx, %bx + int $0x15 + jc EXT_C(pupa_hard_stop) + /* don't check %bx for buggy BIOSes... */ + + /* disconnect APM first */ + movw $0x5304, %ax + xorw %bx, %bx + int $0x15 + + /* connect APM */ + movw $0x5301, %ax + xorw %bx, %bx + int $0x15 + jc EXT_C(pupa_hard_stop) + + /* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */ + movw $0x530E, %ax + xorw %bx, %bx + movw $0x0101, %cx + int $0x15 + jc EXT_C(pupa_hard_stop) + + /* set the power state to off */ + movw $0x5307, %ax + movw $1, %bx + movw $3, %cx + int $0x15 + + /* shouldn't reach here */ + jmp EXT_C(pupa_hard_stop) + .code32 + + +/* + * void pupa_chainloader_real_boot (int drive, void *part_addr) + * + * This starts another boot loader. + */ + +FUNCTION(pupa_chainloader_real_boot) + /* no need to save anything, just use %esp */ + + /* ESI must point to a partition table entry */ + movl 8(%esp), %esi + + /* set up to pass boot drive */ + movl 4(%esp), %edx + + /* Turn off Gate A20 */ + pushl $0 + call EXT_C(pupa_gate_a20) + + call prot_to_real + .code16 + ljmp $0, $PUPA_MEMORY_MACHINE_BOOT_LOADER_ADDR + .code32 + + +/* + * These next two routines, "real_to_prot" and "prot_to_real" are structured + * in a very specific way. Be very careful when changing them. + * + * NOTE: Use of either one messes up %eax and %ebp. + */ + +real_to_prot: + .code16 + cli + + /* load the GDT register */ + DATA32 ADDR32 lgdt gdtdesc + + /* turn on protected mode */ + movl %cr0, %eax + orl $PUPA_MEMORY_MACHINE_CR0_PE_ON, %eax + movl %eax, %cr0 + + /* jump to relocation, flush prefetch queue, and reload %cs */ + DATA32 ljmp $PUPA_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg + + .code32 +protcseg: + /* reload other segment registers */ + movw $PUPA_MEMORY_MACHINE_PROT_MODE_DSEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + /* put the return address in a known safe location */ + movl (%esp), %eax + movl %eax, PUPA_MEMORY_MACHINE_REAL_STACK + + /* get protected mode stack */ + movl protstack, %eax + movl %eax, %esp + movl %eax, %ebp + + /* get return address onto the right stack */ + movl PUPA_MEMORY_MACHINE_REAL_STACK, %eax + movl %eax, (%esp) + + /* zero %eax */ + xorl %eax, %eax + + /* return on the old (or initialized) stack! */ + ret + + +prot_to_real: + /* just in case, set GDT */ + lgdt gdtdesc + + /* save the protected mode stack */ + movl %esp, %eax + movl %eax, protstack + + /* get the return address */ + movl (%esp), %eax + movl %eax, PUPA_MEMORY_MACHINE_REAL_STACK + + /* set up new stack */ + movl $PUPA_MEMORY_MACHINE_REAL_STACK, %eax + movl %eax, %esp + movl %eax, %ebp + + /* set up segment limits */ + movw $PUPA_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + /* this might be an extra step */ + /* jump to a 16 bit segment */ + ljmp $PUPA_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg + +tmpcseg: + .code16 + + /* clear the PE bit of CR0 */ + movl %cr0, %eax + andl $(~PUPA_MEMORY_MACHINE_CR0_PE_ON), %eax + movl %eax, %cr0 + + /* flush prefetch queue, reload %cs */ + DATA32 ljmp $0, $realcseg + +realcseg: + /* we are in real mode now + * set up the real mode segment registers : DS, SS, ES + */ + /* zero %eax */ + xorl %eax, %eax + + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + /* restore interrupts */ + sti + + /* return on new stack! */ + DATA32 ret + + .code32 + + +/* + * int pupa_biosdisk_rw_int13_extensions (int ah, int drive, void *dap) + * + * Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP + * is passed for disk address packet. If an error occurs, return + * non-zero, otherwise zero. + */ + +FUNCTION(pupa_biosdisk_rw_int13_extensions) + pushl %ebp + movl %esp, %ebp + + pushl %esi + + /* compute the address of disk_address_packet */ + movl 0x10(%ebp), %eax + movw %ax, %si + xorw %ax, %ax + shrl $4, %eax + movw %ax, %cx /* save the segment to cx */ + + /* drive */ + movb 0xc(%ebp), %dl + /* ah */ + movb 0x8(%ebp), %dh + /* enter real mode */ + call prot_to_real + + .code16 + movb %dh, %ah + movw %cx, %ds + int $0x13 /* do the operation */ + movb %ah, %dl /* save return value */ + /* clear the data segment */ + xorw %ax, %ax + movw %ax, %ds + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + movb %dl, %al /* return value in %eax */ + + popl %esi + popl %ebp + + ret + +/* + * int pupa_biosdisk_rw_standard (int ah, int drive, int coff, int hoff, + * int soff, int nsec, int segment) + * + * Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write + * NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs, + * return non-zero, otherwise zero. + */ + +FUNCTION(pupa_biosdisk_rw_standard) + pushl %ebp + movl %esp, %ebp + + pushl %ebx + pushl %edi + pushl %esi + + /* set up CHS information */ + movl 0x10(%ebp), %eax + movb %al, %ch + movb 0x18(%ebp), %al + shlb $2, %al + shrw $2, %ax + movb %al, %cl + movb 0x14(%ebp), %dh + /* drive */ + movb 0xc(%ebp), %dl + /* segment */ + movw 0x20(%ebp), %bx + /* save nsec and ah to %di */ + movb 0x8(%ebp), %ah + movb 0x1c(%ebp), %al + movw %ax, %di + /* enter real mode */ + call prot_to_real + + .code16 + movw %bx, %es + xorw %bx, %bx + movw $3, %si /* attempt at least three times */ + +1: + movw %di, %ax + int $0x13 /* do the operation */ + jnc 2f /* check if successful */ + + movb %ah, %bl /* save return value */ + /* if fail, reset the disk system */ + xorw %ax, %ax + int $0x13 + + decw %si + cmpw $0, %si + je 2f + xorb %bl, %bl + jmp 1b /* retry */ +2: + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + movb %bl, %al /* return value in %eax */ + + popl %esi + popl %edi + popl %ebx + popl %ebp + + ret + + +/* + * int pupa_biosdisk_check_int13_extensions (int drive) + * + * Check if LBA is supported for DRIVE. If it is supported, then return + * the major version of extensions, otherwise zero. + */ + +FUNCTION(pupa_biosdisk_check_int13_extensions) + pushl %ebp + movl %esp, %ebp + + pushl %ebx + + /* drive */ + movb 0x8(%ebp), %dl + /* enter real mode */ + call prot_to_real + + .code16 + movb $0x41, %ah + movw $0x55aa, %bx + int $0x13 /* do the operation */ + + /* check the result */ + jc 1f + cmpw $0xaa55, %bx + jne 1f + + movb %ah, %bl /* save the major version into %bl */ + + /* check if AH=0x42 is supported */ + andw $1, %cx + jnz 2f + +1: + xorb %bl, %bl +2: + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + movb %bl, %al /* return value in %eax */ + + popl %ebx + popl %ebp + + ret + + +/* + * int pupa_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp) + * + * Return the geometry of DRIVE in a drive parameters, DRP. If an error + * occurs, then return non-zero, otherwise zero. + */ + +FUNCTION(pupa_biosdisk_get_diskinfo_int13_extensions) + pushl %ebp + movl %esp, %ebp + + pushl %ebx + pushl %esi + + /* compute the address of drive parameters */ + movl 0xc(%ebp), %eax + movw %ax, %si + xorw %ax, %ax + shrl $4, %eax + movw %ax, %bx /* save the segment into %bx */ + /* drive */ + movb 0x8(%ebp), %dl + /* enter real mode */ + call prot_to_real + + .code16 + movb $0x48, %ah + movw %bx, %ds + int $0x13 /* do the operation */ + movb %ah, %bl /* save return value in %bl */ + /* clear the data segment */ + xorw %ax, %ax + movw %ax, %ds + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + movb %bl, %al /* return value in %eax */ + + popl %esi + popl %ebx + popl %ebp + + ret + + +/* + * int pupa_biosdisk_get_diskinfo_standard (int drive, + * unsigned long *cylinders, + * unsigned long *heads, + * unsigned long *sectors) + * + * Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an + * error occurs, then return non-zero, otherwise zero. + */ + +FUNCTION(pupa_biosdisk_get_diskinfo_standard) + pushl %ebp + movl %esp, %ebp + + pushl %ebx + pushl %edi + + /* drive */ + movb 0x8(%ebp), %dl + /* enter real mode */ + call prot_to_real + + .code16 + movb $0x8, %ah + int $0x13 /* do the operation */ + /* check if successful */ + testb %ah, %ah + jnz 1f + /* bogus BIOSes may not return an error number */ + testb $0x3f, %cl /* 0 sectors means no disk */ + jnz 1f /* if non-zero, then succeed */ + /* XXX 0x60 is one of the unused error numbers */ + movb $0x60, %ah +1: + movb %ah, %bl /* save return value in %bl */ + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + /* restore %ebp */ + leal 0x8(%esp), %ebp + + /* heads */ + movb %dh, %al + incl %eax /* the number of heads is counted from zero */ + movl 0x10(%ebp), %edi + movl %eax, (%edi) + + /* sectors */ + xorl %eax, %eax + movb %cl, %al + andb $0x3f, %al + movl 0x14(%ebp), %edi + movl %eax, (%edi) + + /* cylinders */ + shrb $6, %cl + movb %cl, %ah + movb %ch, %al + incl %eax /* the number of cylinders is + counted from zero */ + movl 0xc(%ebp), %edi + movl %eax, (%edi) + + xorl %eax, %eax + movb %bl, %al /* return value in %eax */ + + popl %edi + popl %ebx + popl %ebp + + ret + + +/* + * int pupa_biosdisk_get_num_floppies (void) + */ +FUNCTION(pupa_biosdisk_get_num_floppies) + pushl %ebp + + xorl %edx, %edx + call prot_to_real + + .code16 + /* reset the disk system first */ + int $0x13 +1: + stc + + /* call GET DISK TYPE */ + movb $0x15, %ah + int $0x13 + + jc 2f + + /* check if this drive exists */ + testb $0x3, %ah + jz 2f + + incb %dl + cmpb $2, %dl + jne 1b +2: + DATA32 call real_to_prot + .code32 + + movl %edx, %eax + popl %ebp + ret + + +/* + * + * pupa_get_memsize(i) : return the memory size in KB. i == 0 for conventional + * memory, i == 1 for extended memory + * BIOS call "INT 12H" to get conventional memory size + * BIOS call "INT 15H, AH=88H" to get extended memory size + * Both have the return value in AX. + * + */ + +FUNCTION(pupa_get_memsize) + pushl %ebp + pushl %ebx + + movl 0xc(%esp), %ebx + + call prot_to_real /* enter real mode */ + .code16 + + testl %ebx, %ebx + jnz xext + + int $0x12 + jmp xdone + +xext: + movb $0x88, %ah + int $0x15 + +xdone: + movw %ax, %bx + + DATA32 call real_to_prot + .code32 + + movw %bx, %ax + popl %ebx + popl %ebp + ret + + +/* + * + * pupa_get_eisa_mmap() : return packed EISA memory map, lower 16 bits is + * memory between 1M and 16M in 1K parts, upper 16 bits is + * memory above 16M in 64K parts. If error, return zero. + * BIOS call "INT 15H, AH=E801H" to get EISA memory map, + * AX = memory between 1M and 16M in 1K parts. + * BX = memory above 16M in 64K parts. + * + */ + +FUNCTION(pupa_get_eisa_mmap) + pushl %ebp + pushl %ebx + + call prot_to_real /* enter real mode */ + .code16 + + movw $0xe801, %ax + int $0x15 + + shll $16, %ebx + movw %ax, %bx + + DATA32 call real_to_prot + .code32 + + cmpb $0x86, %bh + je xnoteisa + + movl %ebx, %eax + +xnoteisa: + popl %ebx + popl %ebp + ret + +/* + * + * pupa_get_mmap_entry(addr, cont) : address and old continuation value (zero to + * start), for the Query System Address Map BIOS call. + * + * Sets the first 4-byte int value of "addr" to the size returned by + * the call. If the call fails, sets it to zero. + * + * Returns: new (non-zero) continuation value, 0 if done. + */ + +FUNCTION(pupa_get_mmap_entry) + push %ebp + push %ebx + push %edi + push %esi + + /* place address (+4) in ES:DI */ + movl 0x14(%esp), %eax + addl $4, %eax + movl %eax, %edi + andl $0xf, %edi + shrl $4, %eax + movl %eax, %esi + + /* set continuation value */ + movl 0x18(%esp), %ebx + + /* set default maximum buffer size */ + movl $0x14, %ecx + + /* set EDX to 'SMAP' */ + movl $0x534d4150, %edx + + call prot_to_real /* enter real mode */ + .code16 + + movw %si, %es + movl $0xe820, %eax + int $0x15 + + DATA32 jc xnosmap + + cmpl $0x534d4150, %eax + jne xnosmap + + cmpl $0x14, %ecx + jl xnosmap + + cmpl $0x400, %ecx + jg xnosmap + + jmp xsmap + +xnosmap: + xorl %ecx, %ecx + +xsmap: + DATA32 call real_to_prot + .code32 + + /* write length of buffer (zero if error) into "addr" */ + movl 0x14(%esp), %eax + movl %ecx, (%eax) + + /* set return value to continuation */ + movl %ebx, %eax + + pop %esi + pop %edi + pop %ebx + pop %ebp + ret + + +/* + * pupa_gate_a20(int on) + * + * Gate address-line 20 for high memory. + * + * This routine is probably overconservative in what it does, but so what? + * + * It also eats any keystrokes in the keyboard buffer. :-( + */ + +FUNCTION(pupa_gate_a20) + pushl %eax + + call gloop1 + + movb $0xd1, %al + outb $0x64 + +gloopint1: + inb $0x64 + andb $0x02, %al + jnz gloopint1 + + movb $0xdd, %al + cmpb $0, 0x8(%esp) + jz gdoit + + orb $0x02, %al +gdoit: + outb $0x60 + + call gloop1 + + /* output a dummy command (USB keyboard hack) */ + movb $0xff, %al + outb $0x64 + call gloop1 + + popl %eax + ret + +gloop1: + inb $0x64 + andb $0x02, %al + jnz gloop1 + +gloop2: + inb $0x64 + andb $0x01, %al + jz gloop2ret + inb $0x60 + jmp gloop2 + +gloop2ret: + ret + + +/* + * void pupa_console_putchar (int c) + * + * Put the character C on the console. Because GRUB wants to write a + * character with an attribute, this implementation is a bit tricky. + * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh + * (TELETYPE OUTPUT). Otherwise, save the original position, put a space, + * save the current position, restore the original position, write the + * character and the attribute, and restore the current position. + * + * The reason why this is so complicated is that there is no easy way to + * get the height of the screen, and the TELETYPE OUPUT BIOS call doesn't + * support setting a background attribute. + */ +FUNCTION(pupa_console_putchar) + movl 0x4(%esp), %edx + pusha + movb EXT_C(pupa_console_cur_color), %bl + + call prot_to_real + .code16 + movb %dl, %al + xorb %bh, %bh + + /* use teletype output if control character */ + cmpb $0x7, %al + je 1f + cmpb $0x8, %al + je 1f + cmpb $0xa, %al + je 1f + cmpb $0xd, %al + je 1f + + /* save the character and the attribute on the stack */ + pushw %ax + pushw %bx + + /* get the current position */ + movb $0x3, %ah + int $0x10 + + /* check the column with the width */ + cmpb $79, %dl + jl 2f + + /* print CR and LF, if next write will exceed the width */ + movw $0x0e0d, %ax + int $0x10 + movb $0x0a, %al + int $0x10 + + /* get the current position */ + movb $0x3, %ah + int $0x10 + +2: + /* restore the character and the attribute */ + popw %bx + popw %ax + + /* write the character with the attribute */ + movb $0x9, %ah + movw $1, %cx + int $0x10 + + /* move the cursor forward */ + incb %dl + movb $0x2, %ah + int $0x10 + + jmp 3f + +1: movb $0x7, %bl + movb $0xe, %ah + int $0x10 + +3: DATA32 call real_to_prot + .code32 + + popa + ret + + +/* + * int pupa_console_getkey (void) + * BIOS call "INT 16H Function 00H" to read character from keyboard + * Call with %ah = 0x0 + * Return: %ah = keyboard scan code + * %al = ASCII character + */ + +FUNCTION(pupa_console_getkey) + pushl %ebp + + call prot_to_real + .code16 + + int $0x16 + + movw %ax, %dx /* real_to_prot uses %eax */ + + DATA32 call real_to_prot + .code32 + + movw %dx, %ax + + popl %ebp + ret + + +/* + * int pupa_console_checkkey (void) + * if there is a character pending, return it; otherwise return -1 + * BIOS call "INT 16H Function 01H" to check whether a character is pending + * Call with %ah = 0x1 + * Return: + * If key waiting to be input: + * %ah = keyboard scan code + * %al = ASCII character + * Zero flag = clear + * else + * Zero flag = set + */ +FUNCTION(pupa_console_checkkey) + pushl %ebp + xorl %edx, %edx + + call prot_to_real /* enter real mode */ + .code16 + + movb $0x1, %ah + int $0x16 + + jz notpending + + movw %ax, %dx + DATA32 jmp pending + +notpending: + decl %edx + +pending: + DATA32 call real_to_prot + .code32 + + movl %edx, %eax + + popl %ebp + ret + + +/* + * pupa_uint16_t pupa_console_getxy (void) + * BIOS call "INT 10H Function 03h" to get cursor position + * Call with %ah = 0x03 + * %bh = page + * Returns %ch = starting scan line + * %cl = ending scan line + * %dh = row (0 is top) + * %dl = column (0 is left) + */ + + +FUNCTION(pupa_console_getxy) + pushl %ebp + pushl %ebx /* save EBX */ + + call prot_to_real + .code16 + + xorb %bh, %bh /* set page to 0 */ + movb $0x3, %ah + int $0x10 /* get cursor position */ + + DATA32 call real_to_prot + .code32 + + movb %dl, %ah + movb %dh, %al + + popl %ebx + popl %ebp + ret + + +/* + * void pupa_console_gotoxy(pupa_uint8_t x, pupa_uint8_t y) + * BIOS call "INT 10H Function 02h" to set cursor position + * Call with %ah = 0x02 + * %bh = page + * %dh = row (0 is top) + * %dl = column (0 is left) + */ + + +FUNCTION(pupa_console_gotoxy) + pushl %ebp + pushl %ebx /* save EBX */ + + movb 0xc(%esp), %dl /* %dl = x */ + movb 0x10(%esp), %dh /* %dh = y */ + + call prot_to_real + .code16 + + xorb %bh, %bh /* set page to 0 */ + movb $0x2, %ah + int $0x10 /* set cursor position */ + + DATA32 call real_to_prot + .code32 + + popl %ebx + popl %ebp + ret + + +/* + * void pupa_console_cls (void) + * BIOS call "INT 10H Function 09h" to write character and attribute + * Call with %ah = 0x09 + * %al = (character) + * %bh = (page number) + * %bl = (attribute) + * %cx = (number of times) + */ + +FUNCTION(pupa_console_cls) + pushl %ebp + pushl %ebx /* save EBX */ + + call prot_to_real + .code16 + + /* move the cursor to the beginning */ + movb $0x02, %ah + xorb %bh, %bh + xorw %dx, %dx + int $0x10 + + /* write spaces to the entire screen */ + movw $0x0920, %ax + movw $0x07, %bx + movw $(80 * 25), %cx + int $0x10 + + /* move back the cursor */ + movb $0x02, %ah + int $0x10 + + DATA32 call real_to_prot + .code32 + + popl %ebx + popl %ebp + ret + + +/* + * void pupa_console_setcursor (int on) + * BIOS call "INT 10H Function 01h" to set cursor type + * Call with %ah = 0x01 + * %ch = cursor starting scanline + * %cl = cursor ending scanline + */ + +console_cursor_state: + .byte 1 +console_cursor_shape: + .word 0 + +FUNCTION(pupa_console_setcursor) + push %ebp + push %ebx + + /* check if the standard cursor shape has already been saved */ + movw console_cursor_shape, %ax + testw %ax, %ax + jne 1f + + call prot_to_real + .code16 + + movb $0x03, %ah + xorb %bh, %bh + int $0x10 + + DATA32 call real_to_prot + .code32 + + movw %cx, console_cursor_shape +1: + /* set %cx to the designated cursor shape */ + movw $0x2000, %cx + movl 0xc(%esp), %ebx + testl %ebx, %ebx + jz 2f + movw console_cursor_shape, %cx +2: + call prot_to_real + .code16 + + movb $0x1, %ah + int $0x10 + + DATA32 call real_to_prot + .code32 + + popl %ebx + popl %ebp + ret + +/* + * pupa_getrtsecs() + * if a seconds value can be read, read it and return it (BCD), + * otherwise return 0xFF + * BIOS call "INT 1AH Function 02H" to check whether a character is pending + * Call with %ah = 0x2 + * Return: + * If RT Clock can give correct values + * %ch = hour (BCD) + * %cl = minutes (BCD) + * %dh = seconds (BCD) + * %dl = daylight savings time (00h std, 01h daylight) + * Carry flag = clear + * else + * Carry flag = set + * (this indicates that the clock is updating, or + * that it isn't running) + */ +FUNCTION(pupa_getrtsecs) + push %ebp + + call prot_to_real /* enter real mode */ + .code16 + + clc + movb $0x2, %ah + int $0x1a + + DATA32 jnc gottime + movb $0xff, %dh + +gottime: + DATA32 call real_to_prot + .code32 + + movb %dh, %al + + pop %ebp + ret + + +/* + * pupa_currticks() + * return the real time in ticks, of which there are about + * 18-20 per second + */ +FUNCTION(pupa_currticks) + pushl %ebp + + call prot_to_real /* enter real mode */ + .code16 + + /* %ax is already zero */ + int $0x1a + + DATA32 call real_to_prot + .code32 + + movl %ecx, %eax + shll $16, %eax + movw %dx, %ax + + popl %ebp + ret + + +/* + * This is the area for all of the special variables. + */ + + .p2align 2 /* force 4-byte alignment */ + +protstack: + .long PUPA_MEMORY_MACHINE_PROT_STACK + +VARIABLE(pupa_boot_drive) + .long 0 + +VARIABLE(pupa_start_addr) + .long START_SYMBOL + +VARIABLE(pupa_end_addr) + .long END_SYMBOL + +VARIABLE(pupa_apm_bios_info) + .word 0 /* version */ + .word 0 /* cseg */ + .long 0 /* offset */ + .word 0 /* cseg_16 */ + .word 0 /* dseg_16 */ + .word 0 /* cseg_len */ + .word 0 /* cseg_16_len */ + .word 0 /* dseg_16_len */ + +/* + * This is the Global Descriptor Table + * + * An entry, a "Segment Descriptor", looks like this: + * + * 31 24 19 16 7 0 + * ------------------------------------------------------------ + * | | |B| |A| | | |1|0|E|W|A| | + * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL| TYPE | BASE 23:16 | + * | | |D| |L| 19..16| | |1|1|C|R|A| | + * ------------------------------------------------------------ + * | | | + * | BASE 15..0 | LIMIT 15..0 | + * | | | + * ------------------------------------------------------------ + * + * Note the ordering of the data items is reversed from the above + * description. + */ + + .p2align 2 /* force 4-byte alignment */ +gdt: + .word 0, 0 + .byte 0, 0, 0, 0 + + /* code segment */ + .word 0xFFFF, 0 + .byte 0, 0x9A, 0xCF, 0 + + /* data segment */ + .word 0xFFFF, 0 + .byte 0, 0x92, 0xCF, 0 + + /* 16 bit real mode CS */ + .word 0xFFFF, 0 + .byte 0, 0x9E, 0, 0 + + /* 16 bit real mode DS */ + .word 0xFFFF, 0 + .byte 0, 0x92, 0, 0 + + +/* this is the GDT descriptor */ +gdtdesc: + .word 0x27 /* limit */ + .long gdt /* addr */ diff --git a/kern/loader.c b/kern/loader.c new file mode 100644 index 000000000..f7d8ebc89 --- /dev/null +++ b/kern/loader.c @@ -0,0 +1,67 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +static pupa_err_t (*pupa_loader_load_module_func) (int argc, char *argv[]); +static pupa_err_t (*pupa_loader_boot_func) (void); +static pupa_err_t (*pupa_loader_unload_func) (void); + +static int pupa_loader_loaded; + +void +pupa_loader_set (pupa_err_t (*load_module) (int argc, char *argv[]), + pupa_err_t (*boot) (void), + pupa_err_t (*unload) (void)) +{ + if (pupa_loader_loaded && pupa_loader_unload_func) + if (pupa_loader_unload_func () != PUPA_ERR_NONE) + return; + + pupa_loader_load_module_func = load_module; + pupa_loader_boot_func = boot; + pupa_loader_unload_func = unload; + + pupa_loader_loaded = 1; +} + +pupa_err_t +pupa_loader_load_module (int argc, char *argv[]) +{ + if (! pupa_loader_loaded) + return pupa_error (PUPA_ERR_NO_KERNEL, "no loaded kernel"); + + if (! pupa_loader_load_module_func) + return pupa_error (PUPA_ERR_BAD_OS, "module not supported"); + + return pupa_loader_load_module_func (argc, argv); +} + +pupa_err_t +pupa_loader_boot (void) +{ + if (! pupa_loader_loaded) + return pupa_error (PUPA_ERR_NO_KERNEL, "no loaded kernel"); + + return (pupa_loader_boot_func) (); +} + diff --git a/kern/main.c b/kern/main.c new file mode 100644 index 000000000..2862e52cb --- /dev/null +++ b/kern/main.c @@ -0,0 +1,86 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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 +#include +#include +#include +#include +#include +#include + +/* Return the end of the core image. */ +pupa_addr_t +pupa_get_end_addr (void) +{ + return pupa_total_module_size + pupa_end_addr; +} + +/* Load all modules in core. */ +static void +pupa_load_modules (void) +{ + struct pupa_module_header *header; + + for (header = (struct pupa_module_header *) pupa_end_addr; + header < (struct pupa_module_header *) pupa_get_end_addr (); + header = (struct pupa_module_header *) ((char *) header + header->size)) + { + if (! pupa_dl_load_core ((char *) header + header->offset, + (header->size - header->offset))) + pupa_fatal ("%s", pupa_errmsg); + } +} + +/* Add the region where modules reside into dynamic memory. */ +static void +pupa_add_unused_region (void) +{ + if (pupa_total_module_size) + pupa_mm_init_region ((void *) pupa_end_addr, pupa_total_module_size); +} + +/* The main routine. */ +void +pupa_main (void) +{ + void (*normal_func) (void); + + /* First of all, initialize the machine. */ + pupa_machine_init (); + + /* Hello. */ + pupa_setcolorstate (PUPA_TERM_COLOR_HIGHLIGHT); + pupa_printf ("Welcome to PUPA!"); + pupa_setcolorstate (PUPA_TERM_COLOR_STANDARD); + pupa_printf ("\n\n"); + + pupa_register_exported_symbols (); + pupa_load_modules (); + pupa_add_unused_region (); + + /* If the function pupa_enter_normal_mode is present, call it. */ + normal_func = pupa_dl_resolve_symbol ("pupa_enter_normal_mode"); + if (normal_func) + (*normal_func) (); + + /* If pupa_enter_normal_mode fails or doesn't exist, enter rescue mode. */ + pupa_printf ("Entering into rescue mode...\n"); + pupa_enter_rescue_mode (); +} diff --git a/kern/misc.c b/kern/misc.c new file mode 100644 index 000000000..3ddd3aada --- /dev/null +++ b/kern/misc.c @@ -0,0 +1,377 @@ +/* misc.c - definitions of misc functions */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +void * +pupa_memcpy (void *dest, const void *src, pupa_size_t n) +{ + char *d = (char *) dest; + char *s = (char *) src; + + while (n--) + *d++ = *s++; + + return dest; +} + +int +pupa_printf (const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + ret = pupa_vprintf (fmt, ap); + va_end (ap); + + return ret; +} + +int +pupa_vprintf (const char *fmt, va_list args) +{ + return pupa_vsprintf (0, fmt, args); +} + +int +pupa_memcmp (const void *s1, const void *s2, pupa_size_t n) +{ + const char *t1 = s1; + const char *t2 = s2; + + while (n--) + { + if (*t1 != *t2) + return (int) *t1 - (int) *t2; + + t1++; + t2++; + } + + return 0; +} + +int +pupa_strcmp (const char *s1, const char *s2) +{ + while (*s1 && *s2) + { + if (*s1 != *s2) + return (int) *s1 - (int) *s2; + + s1++; + s2++; + } + + return (int) *s1 - (int) *s2; +} + +char * +pupa_strchr (const char *s, int c) +{ + while (*s) + { + if (*s == c) + return (char *) s; + s++; + } + + return 0; +} + +char * +pupa_strrchr (const char *s, int c) +{ + char *p = 0; + + while (*s) + { + if (*s == c) + p = (char *) s; + s++; + } + + return p; +} + +int +pupa_isspace (int c) +{ + return (c == '\n' || c == '\r' || c == ' ' || c == '\t'); +} + +int +pupa_isprint (int c) +{ + return (c >= ' ' && c <= '~'); +} + +int +pupa_isalpha (int c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +int +pupa_tolower (int c) +{ + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + + return c; +} + +unsigned long +pupa_strtoul (const char *str, char **end, int base) +{ + unsigned long num = 0; + int found = 0; + + /* Skip white spaces. */ + while (*str && pupa_isspace (*str)) + str++; + + /* Guess the base, if not specified. The prefix `0x' means 16, and + the prefix `0' means 8. */ + if (str[0] == '0') + { + if (str[1] == 'x') + { + if (base == 0 || base == 16) + { + base = 16; + str += 2; + } + } + else if (str[1] >= '0' && str[1] <= '7') + base = 8; + } + + if (base == 0) + base = 10; + + while (*str) + { + unsigned long digit; + + digit = pupa_tolower (*str) - '0'; + if (digit > 9) + { + digit += '0' - 'a' + 10; + if (digit >= (unsigned long) base) + break; + } + + found = 1; + + if (num > (~0UL - digit) / base) + { + pupa_error (PUPA_ERR_OUT_OF_RANGE, "overflow is detected"); + return 0; + } + + num += num * base + digit; + str++; + } + + if (! found) + { + pupa_error (PUPA_ERR_BAD_NUMBER, "unrecognized number"); + return 0; + } + + if (end) + *end = (char *) str; + + return num; +} + +char * +pupa_strdup (const char *s) +{ + pupa_size_t len; + char *p; + + len = pupa_strlen (s) + 1; + p = (char *) pupa_malloc (len); + if (! p) + return 0; + + return pupa_memcpy (p, s, len); +} + +void * +pupa_memset (void *s, int c, pupa_size_t n) +{ + unsigned char *p = (unsigned char *) s; + + while (n--) + *p++ = (unsigned char) c; + + return s; +} + +pupa_size_t +pupa_strlen (const char *s) +{ + char *p = (char *) s; + + while (*p) + p++; + + return p - s; +} + +static inline void +pupa_reverse (char *str) +{ + char *p = str + pupa_strlen (str) - 1; + + while (str < p) + { + char tmp; + + tmp = *str; + *str = *p; + *p = tmp; + str++; + p--; + } +} + +char * +pupa_itoa (char *str, int c, unsigned n) +{ + unsigned base = (c == 'x') ? 16 : 10; + char *p; + + if ((int) n < 0 && c == 'd') + { + n = (unsigned) (-((int) n)); + *str++ = '-'; + } + + p = str; + do + { + unsigned d = n % base; + *p++ = (d > 9) ? d + 'a' - 10 : d + '0'; + } + while (n /= base); + *p = 0; + + pupa_reverse (str); + return p; +} + +int +pupa_vsprintf (char *str, const char *fmt, va_list args) +{ + char c; + int count = 0; + auto void write_char (char c); + auto void write_str (const char *s); + + void write_char (char c) + { + if (str) + *str++ = c; + else + pupa_putchar (c); + + count++; + } + + void write_str (const char *s) + { + while (*s) + write_char (*s++); + } + + while ((c = *fmt++) != 0) + { + if (c != '%') + write_char (c); + else + { + char tmp[16]; + char *p; + int n; + + c = *fmt++; + + switch (c) + { + case 'p': + write_str ("0x"); + c = 'x'; + /* fall through */ + case 'x': + case 'u': + case 'd': + n = va_arg (args, int); + pupa_itoa (tmp, c, n); + write_str (tmp); + break; + + case 'c': + n = va_arg (args, int); + write_char (n); + break; + + case 's': + p = va_arg (args, char *); + if (p) + write_str (p); + else + write_str ("(null)"); + break; + + default: + write_char (c); + break; + } + } + } + + if (str) + *str = '\0'; + + return count; +} + +int +pupa_sprintf (char *str, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + ret = pupa_vsprintf (str, fmt, ap); + va_end (ap); + + return ret; +} diff --git a/kern/mm.c b/kern/mm.c new file mode 100644 index 000000000..9b888b62b --- /dev/null +++ b/kern/mm.c @@ -0,0 +1,352 @@ +/* mm.c - functions for memory manager */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +/* Magic words. */ +#define PUPA_MM_FREE_MAGIC 0x2d3c2808 +#define PUPA_MM_ALLOC_MAGIC 0x6db08fa4 + +typedef struct pupa_mm_header +{ + struct pupa_mm_header *next; + pupa_size_t size; + pupa_size_t magic; +#if PUPA_CPU_SIZEOF_VOID_P == 4 + char padding[4]; +#elif PUPA_CPU_SIZEOF_VOID_P == 8 + char padding[8]; +#else +# error "unknown word size" +#endif +} +*pupa_mm_header_t; + +#if PUPA_CPU_SIZEOF_VOID_P == 4 +# define PUPA_MM_ALIGN_LOG2 4 +#elif PUPA_CPU_SIZEOF_VOID_P == 8 +# define PUPA_MM_ALIGN_LOG2 8 +#endif + +#define PUPA_MM_ALIGN (1 << PUPA_MM_ALIGN_LOG2) + +typedef struct pupa_mm_region +{ + struct pupa_mm_header *first; + struct pupa_mm_region *next; + pupa_addr_t addr; + pupa_size_t size; +} +*pupa_mm_region_t; + + + +static pupa_mm_region_t base; + +/* Get a header from the pointer PTR, and set *P and *R to a pointer + to the header and a pointer to its region, respectively. PTR must + be allocated. */ +static void +get_header_from_pointer (void *ptr, pupa_mm_header_t *p, pupa_mm_region_t *r) +{ + if ((unsigned) ptr & (PUPA_MM_ALIGN - 1)) + pupa_fatal ("unaligned pointer %p", ptr); + + for (*r = base; *r; *r = (*r)->next) + if ((unsigned) ptr > (*r)->addr + && (unsigned) ptr <= (*r)->addr + (*r)->size) + break; + + if (! *r) + pupa_fatal ("out of range pointer %p", ptr); + + *p = (pupa_mm_header_t) ptr - 1; + if ((*p)->magic != PUPA_MM_ALLOC_MAGIC) + pupa_fatal ("alloc magic is broken at %p", *p); +} + +/* Initialize a region starting from ADDR and whose size is SIZE, + to use it as free space. */ +void +pupa_mm_init_region (void *addr, pupa_size_t size) +{ + pupa_mm_header_t h; + pupa_mm_region_t r, *p, q; + + /* If this region is too small, ignore it. */ + if (size < PUPA_MM_ALIGN * 2) + return; + + /* Allocate a region from the head. */ + r = (pupa_mm_region_t) (((pupa_addr_t) addr + PUPA_MM_ALIGN - 1) + & (~(PUPA_MM_ALIGN - 1))); + size -= (char *) r - (char *) addr + sizeof (*r); + + h = (pupa_mm_header_t) ((char *) r + PUPA_MM_ALIGN); + h->next = h; + h->magic = PUPA_MM_FREE_MAGIC; + h->size = (size >> PUPA_MM_ALIGN_LOG2); + + r->first = h; + r->addr = (pupa_addr_t) h; + r->size = (h->size << PUPA_MM_ALIGN_LOG2); + + /* Find where to insert this region. Put a smaller one before bigger ones, + to prevent fragmentations. */ + for (p = &base, q = *p; q; p = &(q->next), q = *p) + if (q->size > r->size) + break; + + *p = r; + r->next = q; +} + +/* Allocate the number of units N with the alignment ALIGN from the ring + buffer starting from *FIRST. ALIGN must be a power of two. Return a + non-NULL if successful, otherwise return NULL. */ +static void * +pupa_real_malloc (pupa_mm_header_t *first, pupa_size_t n, pupa_size_t align) +{ + pupa_mm_header_t p, q; + + if ((*first)->magic == PUPA_MM_ALLOC_MAGIC) + return 0; + + for (q = *first, p = q->next; ; q = p, p = p->next) + { + pupa_off_t extra; + + extra = ((pupa_addr_t) (p + 1) >> PUPA_MM_ALIGN_LOG2) % align; + if (extra) + extra = align - extra; + + if (! p) + pupa_fatal ("null in the ring"); + + if (p->magic != PUPA_MM_FREE_MAGIC) + pupa_fatal ("free magic is broken at %p", p); + + if (p->size >= n + extra) + { + if (extra == 0 && p->size == n) + { + q->next = p->next; + p->magic = PUPA_MM_ALLOC_MAGIC; + } + else if (extra == 0 || p->size == n + extra) + { + p->size -= n; + p += p->size; + p->size = n; + p->magic = PUPA_MM_ALLOC_MAGIC; + } + else + { + pupa_mm_header_t r; + + r = p + extra + n; + r->magic = PUPA_MM_FREE_MAGIC; + r->size = p->size - extra - n; + r->next = p->next; + + p->size = extra; + p->next = r; + p += extra; + p->size = n; + p->magic = PUPA_MM_ALLOC_MAGIC; + } + + *first = q; + return p + 1; + } + + if (p == *first) + break; + } + + return 0; +} + +/* Allocate SIZE bytes with the alignment ALIGN and return the pointer. */ +void * +pupa_memalign (pupa_size_t align, pupa_size_t size) +{ + pupa_mm_region_t r; + pupa_size_t n = ((size + PUPA_MM_ALIGN - 1) >> PUPA_MM_ALIGN_LOG2) + 1; + int first = 1; + + align = (align >> PUPA_MM_ALIGN_LOG2); + if (align == 0) + align = 1; + + again: + + for (r = base; r; r = r->next) + { + void *p; + + p = pupa_real_malloc (&(r->first), n, align); + if (p) + return p; + } + + /* If failed, invalidate disk caches to increase free memory. */ + if (first) + { + pupa_disk_cache_invalidate_all (); + first = 0; + goto again; + } + + pupa_error (PUPA_ERR_OUT_OF_MEMORY, "out of memory"); + return 0; +} + +/* Allocate SIZE bytes and return the pointer. */ +void * +pupa_malloc (pupa_size_t size) +{ + return pupa_memalign (0, size); +} + +/* Deallocate the pointer PTR. */ +void +pupa_free (void *ptr) +{ + pupa_mm_header_t p; + pupa_mm_region_t r; + + if (! ptr) + return; + + get_header_from_pointer (ptr, &p, &r); + + if (p == r->first) + { + p->magic = PUPA_MM_FREE_MAGIC; + p->next = p; + } + else + { + pupa_mm_header_t q; + + for (q = r->first; q >= p || q->next <= p; q = q->next) + { + if (q->magic != PUPA_MM_FREE_MAGIC) + pupa_fatal ("free magic is broken at %p", q); + + if (q >= q->next && (q < p || q->next > p)) + break; + } + + p->magic = PUPA_MM_FREE_MAGIC; + p->next = q->next; + q->next = p; + + if (p + p->size == p->next) + { + p->next->magic = 0; + p->size += p->next->size; + p->next = p->next->next; + } + + if (q + q->size == p) + { + p->magic = 0; + q->size += p->size; + q->next = p->next; + } + + r->first = q; + } +} + +/* Reallocate SIZE bytes and return the pointer. The contents will be + the same as that of PTR. */ +void * +pupa_realloc (void *ptr, pupa_size_t size) +{ + pupa_mm_header_t p; + pupa_mm_region_t r; + void *q; + pupa_size_t n; + + if (! ptr) + return pupa_malloc (size); + + if (! size) + { + pupa_free (ptr); + return 0; + } + + /* FIXME: Not optimal. */ + n = ((size + PUPA_MM_ALIGN - 1) >> PUPA_MM_ALIGN_LOG2) + 1; + get_header_from_pointer (ptr, &p, &r); + + if (p->size >= n) + return p; + + q = pupa_malloc (size); + if (! q) + return q; + + pupa_memcpy (q, ptr, size); + pupa_free (ptr); + return q; +} + +#if MM_DEBUG +void +pupa_mm_dump (unsigned lineno) +{ + pupa_mm_region_t r; + + pupa_printf ("called at line %u\n", lineno); + for (r = base; r; r = r->next) + { + pupa_mm_header_t p; + + for (p = (pupa_mm_header_t) ((r->addr + PUPA_MM_ALIGN - 1) + & (~(PUPA_MM_ALIGN - 1))); + (pupa_addr_t) p < r->addr + r->size; + p++) + { + switch (p->magic) + { + case PUPA_MM_FREE_MAGIC: + pupa_printf ("F:%p:%u:%p\n", + p, p->size << PUPA_MM_ALIGN_LOG2, p->next); + break; + case PUPA_MM_ALLOC_MAGIC: + pupa_printf ("A:%p:%u\n", p, p->size << PUPA_MM_ALIGN_LOG2); + break; + } + } + } + + pupa_printf ("\n"); +} +#endif /* MM_DEBUG */ diff --git a/kern/rescue.c b/kern/rescue.c new file mode 100644 index 000000000..29aecb8a7 --- /dev/null +++ b/kern/rescue.c @@ -0,0 +1,576 @@ +/* rescue.c - rescue mode */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#define PUPA_RESCUE_BUF_SIZE 256 +#define PUPA_RESCUE_MAX_ARGS 20 + +struct pupa_rescue_command +{ + const char *name; + void (*func) (int argc, char *argv[]); + const char *message; + struct pupa_rescue_command *next; +}; +typedef struct pupa_rescue_command *pupa_rescue_command_t; + +static char buf[PUPA_RESCUE_BUF_SIZE]; + +static pupa_rescue_command_t pupa_rescue_command_list; + +void +pupa_rescue_register_command (const char *name, + void (*func) (int argc, char *argv[]), + const char *message) +{ + pupa_rescue_command_t cmd; + + cmd = (pupa_rescue_command_t) pupa_malloc (sizeof (*cmd)); + if (! cmd) + return; + + cmd->name = name; + cmd->func = func; + cmd->message = message; + + cmd->next = pupa_rescue_command_list; + pupa_rescue_command_list = cmd; +} + +void +pupa_rescue_unregister_command (const char *name) +{ + pupa_rescue_command_t *p, q; + + for (p = &pupa_rescue_command_list, q = *p; q; p = &(q->next), q = q->next) + if (pupa_strcmp (name, q->name) == 0) + { + *p = q->next; + pupa_free (q); + break; + } +} + +/* Prompt to input a command and read the line. */ +static void +pupa_rescue_get_command_line (const char *prompt) +{ + int c; + int pos = 0; + + pupa_printf (prompt); + pupa_memset (buf, 0, PUPA_RESCUE_BUF_SIZE); + + while ((c = PUPA_TERM_ASCII_CHAR (pupa_getkey ())) != '\n' && c != '\r') + { + if (pupa_isprint (c)) + { + if (pos < PUPA_RESCUE_BUF_SIZE - 1) + { + buf[pos++] = c; + pupa_putchar (c); + } + } + else if (c == '\b') + { + if (pos > 0) + { + buf[--pos] = 0; + pupa_putchar (c); + pupa_putchar (' '); + pupa_putchar (c); + } + } + } + + pupa_putchar ('\n'); +} + +/* Get the next word in STR and return a next pointer. */ +static char * +next_word (char **str) +{ + char *word; + char *p = *str; + + /* Skip spaces. */ + while (*p && pupa_isspace (*p)) + p++; + + word = p; + + /* Find a space. */ + while (*p && ! pupa_isspace (*p)) + p++; + + *p = '\0'; + *str = p + 1; + + return word; +} + +/* boot */ +static void +pupa_rescue_cmd_boot (int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + pupa_loader_boot (); +} + +/* cat FILE */ +static void +pupa_rescue_cmd_cat (int argc, char *argv[]) +{ + pupa_file_t file; + char buf[PUPA_DISK_SECTOR_SIZE]; + pupa_ssize_t size; + + if (argc < 1) + { + pupa_error (PUPA_ERR_BAD_ARGUMENT, "no file specified"); + return; + } + + file = pupa_file_open (argv[0]); + if (! file) + return; + + while ((size = pupa_file_read (file, buf, sizeof (buf))) > 0) + { + int i; + + for (i = 0; i < size; i++) + { + unsigned char c = buf[i]; + + if (pupa_isprint (c) || pupa_isspace (c)) + pupa_putchar (c); + else + { + pupa_setcolorstate (PUPA_TERM_COLOR_HIGHLIGHT); + pupa_printf ("<%x>", (int) c); + pupa_setcolorstate (PUPA_TERM_COLOR_STANDARD); + } + } + } + + pupa_putchar ('\n'); + pupa_file_close (file); +} + +static int +pupa_rescue_print_disks (const char *name) +{ + pupa_device_t dev; + auto int print_partition (const pupa_partition_t p); + + int print_partition (const pupa_partition_t p) + { + char *pname = pupa_partition_get_name (p); + + if (pname) + { + pupa_printf ("(%s,%s) ", name, pname); + pupa_free (pname); + } + + return 0; + } + + dev = pupa_device_open (name); + pupa_errno = PUPA_ERR_NONE; + + if (dev) + { + pupa_printf ("(%s) ", name); + + if (dev->disk && dev->disk->has_partitions) + { + pupa_partition_iterate (dev->disk, print_partition); + pupa_errno = PUPA_ERR_NONE; + } + + pupa_device_close (dev); + } + + return 0; +} + +static int +pupa_rescue_print_files (const char *filename, int dir) +{ + pupa_printf ("%s%s ", filename, dir ? "/" : ""); + + return 0; +} + +/* ls [ARG] */ +static void +pupa_rescue_cmd_ls (int argc, char *argv[]) +{ + if (argc < 1) + { + pupa_disk_dev_iterate (pupa_rescue_print_disks); + pupa_putchar ('\n'); + } + else + { + char *device_name; + pupa_device_t dev; + pupa_fs_t fs; + char *path; + + device_name = pupa_file_get_device_name (argv[0]); + dev = pupa_device_open (device_name); + if (! dev) + goto fail; + + fs = pupa_fs_probe (dev); + path = pupa_strchr (argv[0], '/'); + + if (! path && ! device_name) + { + pupa_error (PUPA_ERR_BAD_ARGUMENT, "invalid argument"); + goto fail; + } + + if (! path) + { + if (pupa_errno == PUPA_ERR_UNKNOWN_FS) + pupa_errno = PUPA_ERR_NONE; + + pupa_printf ("(%s): Filesystem is %s.\n", + device_name, fs ? fs->name : "unknown"); + } + else if (fs) + { + (fs->dir) (dev, path, pupa_rescue_print_files); + pupa_putchar ('\n'); + } + + fail: + if (dev) + pupa_device_close (dev); + + pupa_free (device_name); + } +} + +/* help */ +static void +pupa_rescue_cmd_help (int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + pupa_rescue_command_t p, q; + + /* Sort the commands. This is not a good algorithm, but this is enough, + because rescue mode has a small number of commands. */ + for (p = pupa_rescue_command_list; p; p = p->next) + for (q = p->next; q; q = q->next) + if (pupa_strcmp (p->name, q->name) > 0) + { + struct pupa_rescue_command tmp; + + tmp.name = p->name; + tmp.func = p->func; + tmp.message = p->message; + + p->name = q->name; + p->func = q->func; + p->message = q->message; + + q->name = tmp.name; + q->func = tmp.func; + q->message = tmp.message; + } + + /* Print them. */ + for (p = pupa_rescue_command_list; p; p = p->next) + pupa_printf ("%s\t%s\n", p->name, p->message); +} + +#if 0 +static void +pupa_rescue_cmd_info (void) +{ + extern void pupa_disk_cache_get_performance (unsigned long *, + unsigned long *); + unsigned long hits, misses; + + pupa_disk_cache_get_performance (&hits, &misses); + pupa_printf ("Disk cache: hits = %u, misses = %u ", hits, misses); + if (hits + misses) + { + unsigned long ratio = hits * 10000 / (hits + misses); + pupa_printf ("(%u.%u%%)\n", ratio / 100, ratio % 100); + } + else + pupa_printf ("(N/A)\n"); +} +#endif + +/* (module|initrd) FILE [ARGS] */ +static void +pupa_rescue_cmd_module (int argc, char *argv[]) +{ + pupa_loader_load_module (argc, argv); +} + +/* root [DEVICE] */ +static void +pupa_rescue_cmd_root (int argc, char *argv[]) +{ + pupa_device_t dev; + pupa_fs_t fs; + + if (argc > 0) + { + char *device_name = pupa_file_get_device_name (argv[0]); + if (! device_name) + return; + + pupa_device_set_root (device_name); + pupa_free (device_name); + } + + dev = pupa_device_open (0); + if (! dev) + return; + + fs = pupa_fs_probe (dev); + if (pupa_errno == PUPA_ERR_UNKNOWN_FS) + pupa_errno = PUPA_ERR_NONE; + + pupa_printf ("(%s): Filesystem is %s.\n", + pupa_device_get_root (), fs ? fs->name : "unknown"); + + pupa_device_close (dev); +} + +#if 0 +static void +pupa_rescue_cmd_testload (int argc, char *argv[]) +{ + pupa_file_t file; + char *buf; + pupa_ssize_t size; + pupa_ssize_t pos; + auto void read_func (unsigned long sector, unsigned offset, unsigned len); + + void read_func (unsigned long sector __attribute__ ((unused)), + unsigned offset __attribute__ ((unused)), + unsigned len __attribute__ ((unused))) + { + pupa_putchar ('.'); + } + + if (argc < 1) + { + pupa_error (PUPA_ERR_BAD_ARGUMENT, "no file specified"); + return; + } + + file = pupa_file_open (argv[0]); + if (! file) + return; + + size = pupa_file_size (file) & ~(PUPA_DISK_SECTOR_SIZE - 1); + if (size == 0) + { + pupa_file_close (file); + return; + } + + buf = pupa_malloc (size); + if (! buf) + goto fail; + + pupa_printf ("Reading %s sequentially", argv[0]); + file->read_hook = read_func; + if (pupa_file_read (file, buf, size) != size) + goto fail; + pupa_printf (" Done.\n"); + + /* Read sequentially again. */ + pupa_printf ("Reading %s sequentially again", argv[0]); + if (pupa_file_seek (file, 0) < 0) + goto fail; + + for (pos = 0; pos < size; pos += PUPA_DISK_SECTOR_SIZE) + { + char sector[PUPA_DISK_SECTOR_SIZE]; + + if (pupa_file_read (file, sector, PUPA_DISK_SECTOR_SIZE) + != PUPA_DISK_SECTOR_SIZE) + goto fail; + + if (pupa_memcmp (sector, buf + pos, PUPA_DISK_SECTOR_SIZE) != 0) + { + pupa_printf ("\nDiffers in %d\n", pos); + goto fail; + } + } + pupa_printf (" Done.\n"); + + /* Read backwards and compare. */ + pupa_printf ("Reading %s backwards", argv[0]); + pos = size; + while (pos > 0) + { + char sector[PUPA_DISK_SECTOR_SIZE]; + + pos -= PUPA_DISK_SECTOR_SIZE; + + if (pupa_file_seek (file, pos) < 0) + goto fail; + + if (pupa_file_read (file, sector, PUPA_DISK_SECTOR_SIZE) + != PUPA_DISK_SECTOR_SIZE) + goto fail; + + if (pupa_memcmp (sector, buf + pos, PUPA_DISK_SECTOR_SIZE) != 0) + { + int i; + + pupa_printf ("\nDiffers in %d\n", pos); + + for (i = 0; i < PUPA_DISK_SECTOR_SIZE; i++) + pupa_putchar (buf[pos + i]); + + goto fail; + } + } + pupa_printf (" Done.\n"); + + fail: + + pupa_file_close (file); + pupa_free (buf); +} +#endif + +static void +pupa_rescue_cmd_dump (int argc, char *argv[]) +{ + pupa_uint8_t *addr; + pupa_size_t size = 4; + + if (argc == 0) + { + pupa_error (PUPA_ERR_BAD_ARGUMENT, "no address specified"); + return; + } + + addr = (pupa_uint8_t *) pupa_strtoul (argv[0], 0, 0); + if (pupa_errno) + return; + + if (argc > 1) + size = (pupa_size_t) pupa_strtoul (argv[1], 0, 0); + + while (size--) + { + pupa_printf ("%x%x ", *addr >> 4, *addr & 0xf); + addr++; + } +} + +/* Enter the rescue mode. */ +void +pupa_enter_rescue_mode (void) +{ + pupa_rescue_register_command ("boot", pupa_rescue_cmd_boot, + "boot an operating system"); + pupa_rescue_register_command ("cat", pupa_rescue_cmd_cat, + "show the contents of a file"); + pupa_rescue_register_command ("help", pupa_rescue_cmd_help, + "show this message"); + pupa_rescue_register_command ("initrd", pupa_rescue_cmd_module, + "load an initrd"); + pupa_rescue_register_command ("ls", pupa_rescue_cmd_ls, + "list devices or files"); + pupa_rescue_register_command ("module", pupa_rescue_cmd_module, + "load an OS module"); + pupa_rescue_register_command ("root", pupa_rescue_cmd_root, + "set a root device"); + pupa_rescue_register_command ("dump", pupa_rescue_cmd_dump, + "dump memory"); + + while (1) + { + char *line = buf; + char *name; + int n; + pupa_rescue_command_t cmd; + char *args[PUPA_RESCUE_MAX_ARGS + 1]; + + /* Get a command line. */ + pupa_rescue_get_command_line ("pupa rescue> "); + + /* Get the command name. */ + name = next_word (&line); + + /* If nothing is specified, restart. */ + if (*name == '\0') + continue; + + /* Get arguments. */ + for (n = 0; n <= PUPA_RESCUE_MAX_ARGS; n++) + { + char *arg = next_word (&line); + + if (*arg) + args[n] = arg; + else + break; + } + args[n] = 0; + + /* Find the command and execute it. */ + for (cmd = pupa_rescue_command_list; cmd; cmd = cmd->next) + { + if (pupa_strcmp (name, cmd->name) == 0) + { + (cmd->func) (n, args); + break; + } + } + + /* If not found, print an error message. */ + if (! cmd) + { + pupa_printf ("Unknown command `%s'\n", name); + pupa_printf ("Try `help' for usage\n"); + } + + /* Print an error, if any. */ + pupa_print_error (); + pupa_errno = PUPA_ERR_NONE; + } +} diff --git a/kern/term.c b/kern/term.c new file mode 100644 index 000000000..509e5c8e1 --- /dev/null +++ b/kern/term.c @@ -0,0 +1,153 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +/* The list of terminals. */ +static pupa_term_t pupa_term_list; + +/* The current terminal. */ +static pupa_term_t pupa_cur_term; + +void +pupa_term_register (pupa_term_t term) +{ + term->next = pupa_term_list; + pupa_term_list = term; +} + +void +pupa_term_unregister (pupa_term_t term) +{ + pupa_term_t *p, q; + + for (p = &pupa_term_list, q = *p; q; p = &(q->next), q = q->next) + if (q == term) + { + *p = q->next; + break; + } +} + +void +pupa_term_iterate (int (*hook) (pupa_term_t term)) +{ + pupa_term_t p; + + for (p = pupa_term_list; p; p = p->next) + if (hook (p)) + break; +} + +void +pupa_term_set_current (pupa_term_t term) +{ + pupa_cur_term = term; +} + +pupa_term_t +pupa_term_get_current (void) +{ + return pupa_cur_term; +} + +void +pupa_putchar (int c) +{ + if (c == '\n') + pupa_putchar ('\r'); + else if (c == '\t' && pupa_cur_term->getxy) + { + int n; + + n = 8 - ((pupa_getxy () >> 8) & 7); + while (n--) + pupa_putchar (' '); + + return; + } + + (pupa_cur_term->putchar) (c); +} + +int +pupa_getkey (void) +{ + return (pupa_cur_term->getkey) (); +} + +int +pupa_checkkey (void) +{ + return (pupa_cur_term->checkkey) (); +} + +pupa_uint16_t +pupa_getxy (void) +{ + return (pupa_cur_term->getxy) (); +} + +void +pupa_gotoxy (pupa_uint8_t x, pupa_uint8_t y) +{ + (pupa_cur_term->gotoxy) (x, y); +} + +void +pupa_cls (void) +{ + if (pupa_cur_term->flags & PUPA_TERM_DUMB) + pupa_putchar ('\n'); + else + (pupa_cur_term->cls) (); +} + +void +pupa_setcolorstate (pupa_term_color_state state) +{ + if (pupa_cur_term->setcolorstate) + (pupa_cur_term->setcolorstate) (state); +} + +void +pupa_setcolor (pupa_uint8_t normal_color, pupa_uint8_t highlight_color) +{ + if (pupa_cur_term->setcolor) + (pupa_cur_term->setcolor) (normal_color, highlight_color); +} + +int +pupa_setcursor (int on) +{ + static int prev = 1; + int ret = prev; + + if (pupa_cur_term->setcursor) + { + (pupa_cur_term->setcursor) (on); + prev = on; + } + + return ret; +} + diff --git a/loader/i386/pc/chainloader.c b/loader/i386/pc/chainloader.c new file mode 100644 index 000000000..911f795d9 --- /dev/null +++ b/loader/i386/pc/chainloader.c @@ -0,0 +1,137 @@ +/* chainloader.c - boot another boot loader */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Allocate space statically, because this is very small anyway. */ +static char pupa_chainloader_boot_sector[PUPA_DISK_SECTOR_SIZE]; + +static pupa_err_t +pupa_chainloader_boot (void) +{ + pupa_device_t dev; + int drive = -1; + void *part_addr = 0; + + /* Open the root device. */ + dev = pupa_device_open (0); + if (dev) + { + pupa_disk_t disk = dev->disk; + + if (disk) + { + pupa_partition_t p = disk->partition; + + /* In i386-pc, the id is equal to the BIOS drive number. */ + drive = (int) disk->id; + + if (p) + { + pupa_disk_read (disk, p->offset, 446, 64, + (char *) PUPA_MEMORY_MACHINE_PART_TABLE_ADDR); + + /* Ignore errors. Perhaps it's not fatal. */ + part_addr = (void *) (PUPA_MEMORY_MACHINE_PART_TABLE_ADDR + + (p->index << 4)); + } + } + + pupa_device_close (dev); + } + + pupa_chainloader_real_boot (drive, part_addr); + + /* Never reach here. */ + return PUPA_ERR_NONE; +} + +static void +pupa_rescue_cmd_chainloader (int argc, char *argv[]) +{ + pupa_file_t file; + pupa_uint16_t signature; + int force = 0; + + if (argc > 0 && pupa_strcmp (argv[0], "--force") == 0) + { + force = 1; + argc--; + argv++; + } + + if (argc == 0) + { + pupa_error (PUPA_ERR_BAD_ARGUMENT, "no file specified"); + return; + } + + file = pupa_file_open (argv[0]); + if (! file) + return; + + /* Read the first block. */ + if (pupa_file_read (file, pupa_chainloader_boot_sector, + PUPA_DISK_SECTOR_SIZE) != PUPA_DISK_SECTOR_SIZE) + { + if (pupa_errno == PUPA_ERR_NONE) + pupa_error (PUPA_ERR_BAD_OS, "too small"); + + pupa_file_close (file); + return; + } + + /* Check the signature. */ + signature = *((pupa_uint16_t *) (pupa_chainloader_boot_sector + + PUPA_DISK_SECTOR_SIZE - 2)); + if (signature != pupa_le_to_cpu16 (0xaa55) && ! force) + pupa_error (PUPA_ERR_BAD_OS, "invalid signature"); + + pupa_file_close (file); + + if (pupa_errno == PUPA_ERR_NONE) + pupa_loader_set (0, pupa_chainloader_boot, 0); +} + +static const char loader_name[] = "chainloader"; + +PUPA_MOD_INIT +{ + pupa_rescue_register_command (loader_name, + pupa_rescue_cmd_chainloader, + "load another boot loader"); +} + +PUPA_MOD_FINI +{ + pupa_rescue_unregister_command (loader_name); +} diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100644 index 000000000..6b3b5fc5d --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 000000000..9788f7023 --- /dev/null +++ b/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c new file mode 100644 index 000000000..b0a3b8868 --- /dev/null +++ b/term/i386/pc/console.c @@ -0,0 +1,76 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Free Software Foundation, Inc. + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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 +#include +#include + +pupa_uint8_t pupa_console_cur_color = 0x7; +static pupa_uint8_t pupa_console_standard_color = 0x7; +static pupa_uint8_t pupa_console_normal_color = 0x7; +static pupa_uint8_t pupa_console_highlight_color = 0x70; + +static void +pupa_console_setcolorstate (pupa_term_color_state state) +{ + switch (state) { + case PUPA_TERM_COLOR_STANDARD: + pupa_console_cur_color = pupa_console_standard_color; + break; + case PUPA_TERM_COLOR_NORMAL: + pupa_console_cur_color = pupa_console_normal_color; + break; + case PUPA_TERM_COLOR_HIGHLIGHT: + pupa_console_cur_color = pupa_console_highlight_color; + break; + default: + break; + } +} + +static void +pupa_console_setcolor (pupa_uint8_t normal_color, pupa_uint8_t highlight_color) +{ + pupa_console_normal_color = normal_color; + pupa_console_highlight_color = highlight_color; +} + +static struct pupa_term pupa_console_term = + { + .name = "console", + .putchar = pupa_console_putchar, + .checkkey = pupa_console_checkkey, + .getkey = pupa_console_getkey, + .getxy = pupa_console_getxy, + .gotoxy = pupa_console_gotoxy, + .cls = pupa_console_cls, + .setcolorstate = pupa_console_setcolorstate, + .setcolor = pupa_console_setcolor, + .setcursor = pupa_console_setcursor, + .flags = 0, + .next = 0 + }; + +void +pupa_console_init (void) +{ + pupa_term_register (&pupa_console_term); + pupa_term_set_current (&pupa_console_term); +} diff --git a/util/genmoddep.c b/util/genmoddep.c new file mode 100644 index 000000000..20da7a532 --- /dev/null +++ b/util/genmoddep.c @@ -0,0 +1,279 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * 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 +#include +#include +#include + +#define BUF_SIZE 1024 +#define SYMTAB_SIZE 509 + +struct symbol +{ + const char *name; + const char *mod; + struct symbol *next; +}; + +struct module +{ + const char *name; + struct module *next; +}; + +static char buf[BUF_SIZE]; +static struct symbol *symtab[SYMTAB_SIZE]; + +static void +err (const char *fmt, ...) +{ + va_list ap; + + fprintf (stderr, "genmoddep: error: "); + + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + + fputc ('\n', stderr); + exit (1); +} + +static void * +xmalloc (size_t size) +{ + void *p; + + p = malloc (size); + if (! p) + err ("out of memory"); + + return p; +} + +static char * +xstrdup (const char *str) +{ + char *s; + size_t len; + + len = strlen (str); + s = (char *) xmalloc (len + 1); + memcpy (s, str, len + 1); + + return s; +} + +static void +chomp (char *str) +{ + int end; + + end = strlen (str) - 1; + if (end < 0) + err ("empty string"); + + if (str[end] == '\n') + str[end] = '\0'; +} + +static unsigned +symbol_hash (const char *s) +{ + unsigned key = 0; + + while (*s) + key = key * 65599 + *s++; + + return (key + (key >> 5)) % SYMTAB_SIZE; +} + +static struct symbol * +get_symbol (const char *name) +{ + unsigned k; + struct symbol *sym; + + k = symbol_hash (name); + for (sym = symtab[k]; sym; sym = sym->next) + if (strcmp (sym->name, name) == 0) + return sym; + + return 0; +} + +static void +add_symbol (const char *name, const char *mod) +{ + unsigned k; + struct symbol *sym; + + if (get_symbol (name)) + err ("duplicated symbol: %s", name); + + sym = (struct symbol *) xmalloc (sizeof (*sym)); + sym->name = xstrdup (name); + sym->mod = xstrdup (mod); + + k = symbol_hash (name); + sym->next = symtab[k]; + symtab[k] = sym; +} + +static void +free_symbols (void) +{ + int i; + + for (i = 0; i < SYMTAB_SIZE; i++) + { + struct symbol *p, *q; + + p = symtab[i]; + while (p) + { + q = p->next; + free ((void *) p->name); + free ((void *) p->mod); + free (p); + p = q; + } + } +} + +static void +read_defined_symbols (FILE *fp) +{ + while (fgets (buf, sizeof (buf), fp)) + { + char *p; + + if (! *buf) + err ("empty symbol name: %s", buf); + + p = strchr (buf, ' '); + if (! p) + err ("invalid line format: %s", buf); + + p++; + + if (! *p) + err ("empty module name: %s", buf); + + *(p - 1) = '\0'; + chomp (p); + + add_symbol (buf, p); + } +} + +static void +add_module (struct module **head, const char *name) +{ + struct module *mod; + + for (mod = *head; mod; mod = mod->next) + if (strcmp (mod->name, name) == 0) + return; + + mod = (struct module *) xmalloc (sizeof (*mod)); + mod->name = xstrdup (name); + + mod->next = *head; + *head = mod; +} + +static void +free_modules (struct module *head) +{ + struct module *next; + + while (head) + { + next = head->next; + free ((void *) head->name); + free (head); + head = next; + } +} + +static void +find_dependencies (FILE *fp) +{ + char *mod_name; + struct module *mod_list = 0; + struct module *mod; + + if (! fgets (buf, sizeof (buf), fp) || buf[0] == '\n' || buf[0] == '\0') + err ("no module name"); + + chomp (buf); + mod_name = xstrdup (buf); + + while (fgets (buf, sizeof (buf), fp)) + { + struct symbol *sym; + + chomp (buf); + sym = get_symbol (buf); + if (! sym) + err ("%s in %s is not defined", buf, mod_name); + + add_module (&mod_list, sym->mod); + } + + printf ("%s:", mod_name); + + for (mod = mod_list; mod; mod = mod->next) + if (strcmp (mod->name, "kernel") != 0) + printf (" %s", mod->name); + + putchar ('\n'); + + free_modules (mod_list); +} + +int +main (int argc, char *argv[]) +{ + int i; + + /* First, get defined symbols. */ + read_defined_symbols (stdin); + + /* Second, find the dependecies. */ + for (i = 1; i < argc; i++) + { + FILE *fp; + + fp = fopen (argv[i], "r"); + if (! fp) + err ("cannot open %s", argv[i]); + + find_dependencies (fp); + + fclose (fp); + } + + /* Last, free memory. */ + free_symbols (); + + return 0; +} diff --git a/util/i386/pc/grub-mkimage.c b/util/i386/pc/grub-mkimage.c new file mode 100644 index 000000000..68a28c510 --- /dev/null +++ b/util/i386/pc/grub-mkimage.c @@ -0,0 +1,223 @@ +/* pupa-mkimage.c - make a bootable image */ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define _GNU_SOURCE 1 +#include + +static void +generate_image (const char *dir, FILE *out, char *mods[]) +{ + pupa_addr_t module_addr = 0; + char *kernel_img, *boot_img; + size_t kernel_size, boot_size, total_module_size; + char *kernel_path, *boot_path; + unsigned num; + struct pupa_util_path_list *path_list, *p, *next; + + path_list = pupa_util_resolve_dependencies (dir, "moddep.lst", mods); + + kernel_path = pupa_util_get_path (dir, "kernel.img"); + kernel_size = pupa_util_get_image_size (kernel_path); + + total_module_size = 0; + for (p = path_list; p; p = p->next) + total_module_size += (pupa_util_get_image_size (p->name) + + sizeof (struct pupa_module_header)); + + pupa_util_info ("the total module size is 0x%x", total_module_size); + + num = ((kernel_size + total_module_size + PUPA_DISK_SECTOR_SIZE - 1) + >> PUPA_DISK_SECTOR_BITS); + if (num > 0xffff) + pupa_util_error ("the core image is too big"); + + boot_path = pupa_util_get_path (dir, "diskboot.img"); + boot_size = pupa_util_get_image_size (boot_path); + if (boot_size != PUPA_DISK_SECTOR_SIZE) + pupa_util_error ("diskboot.img is not one sector size"); + + boot_img = pupa_util_read_image (boot_path); + + /* i386 is a little endian architecture. */ + *((pupa_uint16_t *) (boot_img + PUPA_DISK_SECTOR_SIZE + - PUPA_BOOT_MACHINE_LIST_SIZE + 4)) + = pupa_cpu_to_le16 (num); + + pupa_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + + kernel_img = pupa_util_read_image (kernel_path); + module_addr = (path_list + ? (PUPA_BOOT_MACHINE_KERNEL_ADDR + PUPA_DISK_SECTOR_SIZE + + kernel_size) + : 0); + + pupa_util_info ("the first module address is 0x%x", module_addr); + *((pupa_uint32_t *) (kernel_img + PUPA_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) + = pupa_cpu_to_le32 (total_module_size); + *((pupa_uint32_t *) (kernel_img + PUPA_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) + = pupa_cpu_to_le32 (kernel_size); + + pupa_util_write_image (kernel_img, kernel_size, out); + free (kernel_img); + free (kernel_path); + + while (path_list) + { + struct pupa_module_header header; + size_t mod_size; + char *mod_img; + + next = path_list->next; + + mod_size = pupa_util_get_image_size (path_list->name); + + header.offset = pupa_cpu_to_le32 (sizeof (header)); + header.size = pupa_cpu_to_le32 (mod_size + sizeof (header)); + + pupa_util_info ("offset=0x%x, size=0x%x", header.offset, header.size); + pupa_util_write_image ((char *) &header, sizeof (header), out); + + mod_img = pupa_util_read_image (path_list->name); + pupa_util_write_image (mod_img, mod_size, out); + free (mod_img); + + free ((void *) path_list->name); + free (path_list); + path_list = next; + } +} + + + +static struct option options[] = + { + {"directory", required_argument, 0, 'd'}, + {"output", required_argument, 0, 'o'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``pupa-mkimage --help'' for more information.\n"); + else + printf ("\ +Usage: pupa-mkimage [OPTION]... [MODULES]\n\ +\n\ +Make a bootable image of PUPA.\n\ +\n\ + -d, --directory=DIR use images and modules under DIR [default=%s]\n\ + -o, --output=FILE output a generated image to FILE [default=stdout]\n\ + -h, --help display this image and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to .\n\ +", PUPA_DATADIR); + + exit (status); +} + +int +main (int argc, char *argv[]) +{ + char *output = 0; + char *dir = 0; + FILE *fp = stdout; + + progname = "pupa-mkimage"; + + while (1) + { + int c = getopt_long (argc, argv, "d:o:hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'o': + if (output) + free (output); + + output = xstrdup (optarg); + break; + + case 'd': + if (dir) + free (dir); + + dir = xstrdup (optarg); + break; + + case 'h': + usage (0); + break; + + case 'V': + printf ("pupa-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + if (output) + { + fp = fopen (output, "wb"); + if (! fp) + pupa_util_error ("cannot open %s", output); + } + + generate_image (dir ? : PUPA_DATADIR, fp, argv + optind); + + fclose (fp); + + if (dir) + free (dir); + + return 0; +} diff --git a/util/misc.c b/util/misc.c new file mode 100644 index 000000000..6f65eb151 --- /dev/null +++ b/util/misc.c @@ -0,0 +1,137 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +char *progname = 0; +int verbosity = 0; + +void +pupa_util_info (const char *fmt, ...) +{ + if (verbosity > 0) + { + va_list ap; + + fprintf (stderr, "%s: info: ", progname); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fputc ('\n', stderr); + } +} + +void +pupa_util_error (const char *fmt, ...) +{ + va_list ap; + + fprintf (stderr, "%s: error: ", progname); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fputc ('\n', stderr); + exit (1); +} + +void * +xmalloc (size_t size) +{ + void *p; + + p = malloc (size); + if (! p) + pupa_util_error ("out of memory"); + + return p; +} + +char * +xstrdup (const char *str) +{ + size_t len; + char *dup; + + len = strlen (str); + dup = (char *) xmalloc (len + 1); + memcpy (dup, str, len + 1); + + return dup; +} + +char * +pupa_util_get_path (const char *dir, const char *file) +{ + char *path; + + path = (char *) xmalloc (strlen (dir) + 1 + strlen (file) + 1); + sprintf (path, "%s/%s", dir, file); + return path; +} + +size_t +pupa_util_get_image_size (const char *path) +{ + struct stat st; + + pupa_util_info ("getting the size of %s", path); + + if (stat (path, &st) == -1) + pupa_util_error ("cannot stat %s", path); + + return st.st_size; +} + +char * +pupa_util_read_image (const char *path) +{ + char *img; + FILE *fp; + size_t size; + + pupa_util_info ("reading %s", path); + + size = pupa_util_get_image_size (path); + img = (char *) xmalloc (size); + + fp = fopen (path, "rb"); + if (! fp) + pupa_util_error ("cannot open %s", path); + + if (fread (img, 1, size, fp) != size) + pupa_util_error ("cannot read %s", path); + + return img; +} + +void +pupa_util_write_image (const char *img, size_t size, FILE *out) +{ + pupa_util_info ("writing 0x%x bytes", size); + if (fwrite (img, 1, size, out) != size) + pupa_util_error ("write failed"); +} + diff --git a/util/resolve.c b/util/resolve.c new file mode 100644 index 000000000..8f985698e --- /dev/null +++ b/util/resolve.c @@ -0,0 +1,257 @@ +/* + * PUPA -- Preliminary Universal Programming Architecture for GRUB + * Copyright (C) 2002 Yoshinori K. Okuji + * + * PUPA 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 PUPA; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include + +/* Module. */ +struct mod_list +{ + const char *name; + struct mod_list *next; +}; + +/* Dependency. */ +struct dep_list +{ + const char *name; + struct mod_list *list; + struct dep_list *next; +}; + +static char buf[1024]; + +static void +free_mod_list (struct mod_list *head) +{ + while (head) + { + struct mod_list *next; + + next = head->next; + free ((void *) head->name); + free (head); + head = next; + } +} + +static void +free_dep_list (struct dep_list *head) +{ + while (head) + { + struct dep_list *next; + + next = head->next; + free ((void *) head->name); + free_mod_list (head->list); + free (head); + head = next; + } +} + +/* Read the list of dependencies. */ +static struct dep_list * +read_dep_list (FILE *fp) +{ + struct dep_list *dep_list = 0; + + while (fgets (buf, sizeof (buf), fp)) + { + char *p; + struct dep_list *dep; + + /* Get the target name. */ + p = strchr (buf, ':'); + if (! p) + pupa_util_error ("invalid line format: %s", buf); + + *p++ = '\0'; + + dep = xmalloc (sizeof (*dep)); + dep->name = xstrdup (buf); + dep->list = 0; + + dep->next = dep_list; + dep_list = dep; + + /* Add dependencies. */ + while (*p) + { + struct mod_list *mod; + char *name; + + /* Skip white spaces. */ + while (*p && isspace (*p)) + p++; + + if (! *p) + break; + + name = p; + + /* Skip non-WSPs. */ + while (*p && ! isspace (*p)) + p++; + + *p++ = '\0'; + + mod = (struct mod_list *) xmalloc (sizeof (*mod)); + mod->name = xstrdup (name); + mod->next = dep->list; + dep->list = mod; + } + } + + return dep_list; +} + +static char * +get_module_name (const char *str) +{ + char *base; + char *ext; + + base = strrchr (str, '/'); + if (! base) + base = (char *) str; + else + base++; + + ext = strrchr (base, '.'); + if (ext && strcmp (ext, ".mod") == 0) + { + char *name; + + name = xmalloc (ext - base + 1); + memcpy (name, base, ext - base); + name[ext - base] = '\0'; + return name; + } + + return xstrdup (base); +} + +static char * +get_module_path (const char *prefix, const char *str) +{ + char *dir; + char *base; + char *ext; + char *ret; + + ext = strrchr (str, '.'); + if (ext && strcmp (ext, ".mod") == 0) + base = xstrdup (str); + else + { + base = xmalloc (strlen (str) + 4 + 1); + sprintf (base, "%s.mod", str); + } + + dir = strchr (str, '/'); + if (dir) + return base; + + ret = pupa_util_get_path (prefix, base); + free (base); + return ret; +} + +static void +add_module (const char *dir, + struct dep_list *dep_list, + struct mod_list **mod_head, + struct pupa_util_path_list **path_head, + const char *name) +{ + char *mod_name; + struct pupa_util_path_list *path; + struct mod_list *mod; + struct dep_list *dep; + + mod_name = get_module_name (name); + + /* Check if the module has already been added. */ + for (mod = *mod_head; mod; mod = mod->next) + if (strcmp (mod->name, mod_name) == 0) + { + free (mod_name); + return; + } + + /* Resolve dependencies. */ + for (dep = dep_list; dep; dep = dep->next) + if (strcmp (dep->name, mod_name) == 0) + { + for (mod = dep->list; mod; mod = mod->next) + add_module (dir, dep_list, mod_head, path_head, mod->name); + + break; + } + + /* Add this module. */ + mod = (struct mod_list *) xmalloc (sizeof (*mod)); + mod->name = mod_name; + mod->next = *mod_head; + *mod_head = mod; + + /* Add this path. */ + path = (struct pupa_util_path_list *) xmalloc (sizeof (*path)); + path->name = get_module_path (dir, name); + path->next = *path_head; + *path_head = path; +} + +struct pupa_util_path_list * +pupa_util_resolve_dependencies (const char *prefix, + const char *dep_list_file, + char *modules[]) +{ + char *path; + FILE *fp; + struct dep_list *dep_list; + struct mod_list *mod_list = 0; + struct pupa_util_path_list *path_list = 0; + + path = pupa_util_get_path (prefix, dep_list_file); + fp = fopen (path, "r"); + if (! fp) + pupa_util_error ("cannot open %s", path); + + free (path); + dep_list = read_dep_list (fp); + fclose (fp); + + while (*modules) + { + add_module (prefix, dep_list, &mod_list, &path_list, *modules); + modules++; + } + + free_dep_list (dep_list); + free_mod_list (mod_list); + + return path_list; +}