--- /dev/null
+Makefile
+config.cache
+config.h
+config.log
+config.status
+stamp-h
+stamp-h1
+autom4te.cache
--- /dev/null
+Yoshinori K. Okuji designed and implemented everything.
--- /dev/null
+ 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.
+\f
+ 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.)
+\f
+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.
+\f
+ 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.
+\f
+ 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
+\f
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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.
--- /dev/null
+2002-12-27 Yoshinori K. Okuji <okuji@enbug.org>
+
+ * Changelog: New file.
+
--- /dev/null
+-*- 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.
--- /dev/null
+# -*- makefile -*-
+#
+# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
+# Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+#
+# 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:
--- /dev/null
+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.
--- /dev/null
+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 <http://www.nongnu.org/pupa/>.
+
+\f
+
+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 <http://bochs.sf.net/> than a real
+machine.
--- /dev/null
+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 <gniibe@m17n.org>
+Tsuneyoshi Yasuo <tuneyoshi@naic.co.jp>
+
+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.
--- /dev/null
+-*- 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 <pupa-devel@nongnu.org> 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. ?
--- /dev/null
+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
+])
--- /dev/null
+#! /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
--- /dev/null
+/* -*-Asm-*- */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/boot.h>
+#include <pupa/machine/boot.h>
+
+/*
+ * 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
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/machine/boot.h>
+
+/*
+ * 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!!! */
--- /dev/null
+# -*- 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)
--- /dev/null
+# -*- 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)
--- /dev/null
+#! /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 <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. 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 <config-patches@gnu.org>."
+
+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 <<EOF >$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 <stdio.h> /* 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 <sys/systemcfg.h>
+
+ 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 <stdlib.h>
+ #include <unistd.h>
+
+ 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 <unistd.h>
+ 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 <features.h>
+ #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' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/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 <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # 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 <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#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 <sys/param.h>
+ 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 <sys/param.h>
+# 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 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> 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:
--- /dev/null
+/* 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 <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> 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
--- /dev/null
+#! /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 <config-patches@gnu.org>. 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 <config-patches@gnu.org>."
+
+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:
--- /dev/null
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.53 for PUPA 0.6.
+#
+# Report bugs to <okuji@enbug.org>.
+#
+# 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 <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#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<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ 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 <okuji@enbug.org>.
+_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 </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&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 <stdlib.h>' \
+ '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 <stdlib.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
+ :
+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 <sys/types.h>
+#include <sys/param.h>
+
+#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 <sys/types.h>
+#include <sys/param.h>
+
+#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 <assert.h>
+ 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 <ac_nonexistent.h>
+_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 <assert.h>
+ 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 <ac_nonexistent.h>
+_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 <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+_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 <string.h>
+
+_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 <stdlib.h>
+
+_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 <ctype.h>
+#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 <stdio.h>
+#include <stdlib.h>
+#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 <stdio.h>
+#include <stdlib.h>
+#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 <bug-autoconf@gnu.org>."
+_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 <<CEOF' >>$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 <<CEOF' >>$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
+
--- /dev/null
+# Process this file with autoconf to produce a configure script.
+
+# Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+#
+# 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
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/machine/biosdisk.h>
+#include <pupa/machine/memory.h>
+#include <pupa/disk.h>
+#include <pupa/mm.h>
+#include <pupa/types.h>
+#include <pupa/misc.h>
+#include <pupa/err.h>
+#include <pupa/term.h>
+
+/* 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);
+}
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/machine/partition.h>
+#include <pupa/disk.h>
+#include <pupa/mm.h>
+#include <pupa/misc.h>
+
+/* 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;
+}
--- /dev/null
+/* 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 <okuji@enbug.org>
+ *
+ * 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 <pupa/fs.h>
+#include <pupa/disk.h>
+#include <pupa/file.h>
+#include <pupa/types.h>
+#include <pupa/misc.h>
+#include <pupa/mm.h>
+#include <pupa/err.h>
+#include <pupa/dl.h>
+
+#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);
+}
--- /dev/null
+#! /bin/sh
+#
+# Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+#
+# 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;}'
--- /dev/null
+#! /usr/bin/ruby -w
+#
+# Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+#
+# 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)"
--- /dev/null
+#! /bin/sh
+#
+# Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+#
+# 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 <<EOF
+/* This file is automatically generated by genmodsrc.sh. DO NOT EDIT! */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/dl.h>
+
+EOF
+
+echo "PUPA_MOD_NAME(${mod_name});"
+
+for mod in `grep "^${mod_name}:" ${deps} | sed 's/^[^:]*://'`; do
+ echo "PUPA_MOD_DEP(${mod});"
+done
--- /dev/null
+#! /bin/sh
+#
+# Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+#
+# 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 <<EOF
+/* This file is automatically generated by gensymlist.sh. DO NOT EDIT! */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <<EOF
+
+void
+pupa_register_exported_symbols (void)
+{
+EOF
+
+cat <<EOF
+ struct symtab { const char *name; void *addr; };
+ struct symtab *p;
+ static struct symtab tab[] =
+ {
+EOF
+
+cat $* | grep -v '^#' | sed -n '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/ {"\1", \1},/;p;}'
+cat $* | grep -v '^#' | sed -n '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/ {"\1", \&\1},/;p;}'
+
+cat <<EOF
+ {0, 0}
+ };
+
+ for (p = tab; p->name; p++)
+ pupa_dl_register_symbol (p->name, p->addr, 0);
+}
+EOF
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 */
--- /dev/null
+/* device.h - device manager */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/symbol.h>
+#include <pupa/err.h>
+
+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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/symbol.h>
+#include <pupa/err.h>
+#include <pupa/types.h>
+
+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 */
--- /dev/null
+/* dl.h - types and prototypes for loadable module support */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/symbol.h>
+#include <pupa/err.h>
+#include <pupa/types.h>
+
+#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 */
--- /dev/null
+/* 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 <okuji@enbug.org>
+ 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 <pupa/types.h>
+
+/* 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 <elf.h> 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 */
--- /dev/null
+/* err.h - error numbers and prototypes */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/symbol.h>
+
+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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/types.h>
+#include <pupa/err.h>
+#include <pupa/device.h>
+#include <pupa/fs.h>
+
+/* 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 */
--- /dev/null
+/* fs.h - filesystem manager */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/device.h>
+#include <pupa/symbol.h>
+#include <pupa/types.h>
+
+/* 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/types.h>
+
+/* 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/types.h>
+#include <pupa/symbol.h>
+
+/* 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/types.h>
+#include <pupa/symbol.h>
+
+/* 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 */
--- /dev/null
+/* memory.h - describe the memory map */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/symbol.h>
+#include <pupa/types.h>
+#include <pupa/err.h>
+
+/* 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/types.h>
+
+/* 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 */
--- /dev/null
+/* loader.h - OS loaders */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/file.h>
+#include <pupa/symbol.h>
+#include <pupa/err.h>
+#include <pupa/types.h>
+
+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 */
--- /dev/null
+/* misc.h - prototypes for misc functions */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <stdarg.h>
+#include <pupa/types.h>
+#include <pupa/symbol.h>
+
+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 */
--- /dev/null
+/* mm.h - prototypes and declarations for memory manager */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/types.h>
+#include <pupa/symbol.h>
+
+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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/symbol.h>
+#include <pupa/err.h>
+#include <pupa/types.h>
+
+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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/symbol.h>
+
+/* 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <config.h>
+
+/* 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/symbol.h>
+#include <pupa/types.h>
+
+/* 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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <config.h>
+#include <pupa/cpu/types.h>
+
+#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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+
+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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 */
--- /dev/null
+#!/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
--- /dev/null
+/* device.c - device manager */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/device.h>
+#include <pupa/disk.h>
+#include <pupa/net.h>
+#include <pupa/fs.h>
+#include <pupa/mm.h>
+#include <pupa/misc.h>
+
+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;
+}
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/disk.h>
+#include <pupa/err.h>
+#include <pupa/mm.h>
+#include <pupa/types.h>
+#include <pupa/machine/partition.h>
+#include <pupa/misc.h>
+
+/* 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;
+}
+
+\f
+
+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;
+}
--- /dev/null
+/* dl.c - loadable module support */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <config.h>
+#include <pupa/elf.h>
+#include <pupa/dl.h>
+#include <pupa/misc.h>
+#include <pupa/mm.h>
+#include <pupa/err.h>
+#include <pupa/types.h>
+#include <pupa/symbol.h>
+#include <pupa/file.h>
+
+#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
+
+\f
+
+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;
+}
+
+\f
+
+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;
+}
--- /dev/null
+/* err.c - error handling routines */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/err.h>
+#include <pupa/misc.h>
+#include <stdarg.h>
+
+#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);
+}
--- /dev/null
+/* file.c - file I/O functions */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/misc.h>
+#include <pupa/err.h>
+#include <pupa/file.h>
+#include <pupa/mm.h>
+#include <pupa/fs.h>
+#include <pupa/device.h>
+
+/* 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;
+}
--- /dev/null
+/* fs.c - filesystem manager */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/disk.h>
+#include <pupa/net.h>
+#include <pupa/fs.h>
+#include <pupa/file.h>
+#include <pupa/err.h>
+#include <pupa/misc.h>
+#include <pupa/types.h>
+#include <pupa/mm.h>
+#include <pupa/term.h>
+
+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;
+}
+
+\f
+
+/* 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
+ };
--- /dev/null
+/* dl-386.c - arch-dependent part of loadable module support */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/dl.h>
+#include <pupa/elf.h>
+#include <pupa/misc.h>
+#include <pupa/err.h>
+
+/* 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;
+}
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/kernel.h>
+#include <pupa/mm.h>
+#include <pupa/machine/init.h>
+#include <pupa/machine/memory.h>
+#include <pupa/machine/console.h>
+#include <pupa/machine/biosdisk.h>
+#include <pupa/types.h>
+#include <pupa/err.h>
+
+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 ();
+}
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <config.h>
+#include <pupa/symbol.h>
+#include <pupa/boot.h>
+#include <pupa/machine/boot.h>
+#include <pupa/machine/memory.h>
+#include <pupa/machine/console.h>
+
+#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 */
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/loader.h>
+#include <pupa/misc.h>
+#include <pupa/mm.h>
+#include <pupa/err.h>
+
+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) ();
+}
+
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/kernel.h>
+#include <pupa/misc.h>
+#include <pupa/mm.h>
+#include <pupa/symbol.h>
+#include <pupa/dl.h>
+#include <pupa/term.h>
+#include <pupa/rescue.h>
+
+/* 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 ();
+}
--- /dev/null
+/* 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 <okuji@enbug.org>
+ *
+ * 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 <pupa/misc.h>
+#include <pupa/err.h>
+#include <pupa/mm.h>
+#include <stdarg.h>
+#include <pupa/term.h>
+
+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;
+}
--- /dev/null
+/* mm.c - functions for memory manager */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <config.h>
+#include <pupa/mm.h>
+#include <pupa/misc.h>
+#include <pupa/err.h>
+#include <pupa/types.h>
+#include <pupa/disk.h>
+
+/* 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;
+
+\f
+
+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 */
--- /dev/null
+/* rescue.c - rescue mode */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/kernel.h>
+#include <pupa/term.h>
+#include <pupa/misc.h>
+#include <pupa/disk.h>
+#include <pupa/file.h>
+#include <pupa/mm.h>
+#include <pupa/err.h>
+#include <pupa/loader.h>
+#include <pupa/machine/partition.h>
+
+#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;
+ }
+}
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/term.h>
+#include <pupa/err.h>
+#include <pupa/mm.h>
+
+/* 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;
+}
+
--- /dev/null
+/* chainloader.c - boot another boot loader */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/loader.h>
+#include <pupa/machine/loader.h>
+#include <pupa/file.h>
+#include <pupa/err.h>
+#include <pupa/device.h>
+#include <pupa/disk.h>
+#include <pupa/misc.h>
+#include <pupa/types.h>
+#include <pupa/machine/init.h>
+#include <pupa/machine/partition.h>
+#include <pupa/machine/memory.h>
+#include <pupa/rescue.h>
+#include <pupa/dl.h>
+
+/* 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);
+}
--- /dev/null
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# 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
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <pupa/machine/console.h>
+#include <pupa/term.h>
+#include <pupa/types.h>
+
+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);
+}
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#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;
+}
--- /dev/null
+/* pupa-mkimage.c - make a bootable image */
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <config.h>
+#include <pupa/types.h>
+#include <pupa/machine/boot.h>
+#include <pupa/machine/kernel.h>
+#include <pupa/kernel.h>
+#include <pupa/disk.h>
+#include <pupa/util/misc.h>
+#include <pupa/util/resolve.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define _GNU_SOURCE 1
+#include <getopt.h>
+
+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;
+ }
+}
+
+\f
+
+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 <okuji@enbug.org>.\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;
+}
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <pupa/util/misc.h>
+
+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");
+}
+
--- /dev/null
+/*
+ * PUPA -- Preliminary Universal Programming Architecture for GRUB
+ * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <pupa/util/resolve.h>
+#include <pupa/util/misc.h>
+
+/* 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;
+}